@@ -379,6 +379,35 @@ pub enum LendingInstruction {
379379 /// Reserve config to update to
380380 config : ReserveConfig ,
381381 } ,
382+
383+ // 17
384+ /// Repay borrowed liquidity to a reserve to receive collateral at a discount from an unhealthy
385+ /// obligation. Requires a refreshed obligation and reserves.
386+ ///
387+ /// Accounts expected by this instruction:
388+ ///
389+ /// 0. `[writable]` Source liquidity token account.
390+ /// Minted by repay reserve liquidity mint.
391+ /// $authority can transfer $liquidity_amount.
392+ /// 1. `[writable]` Destination collateral token account.
393+ /// Minted by withdraw reserve collateral mint.
394+ /// 2. `[writable]` Destination liquidity token account.
395+ /// 3. `[writable]` Repay reserve account - refreshed.
396+ /// 4. `[writable]` Repay reserve liquidity supply SPL Token account.
397+ /// 5. `[writable]` Withdraw reserve account - refreshed.
398+ /// 6. `[writable]` Withdraw reserve collateral SPL Token mint.
399+ /// 7. `[writable]` Withdraw reserve collateral supply SPL Token account.
400+ /// 8. `[writable]` Withdraw reserve liquidity supply SPL Token account.
401+ /// 9. `[writable]` Withdraw reserve liquidity fee receiver account.
402+ /// 10 `[writable]` Obligation account - refreshed.
403+ /// 11 `[]` Lending market account.
404+ /// 12 `[]` Derived lending market authority.
405+ /// 13 `[signer]` User transfer authority ($authority).
406+ /// 14 `[]` Token program id.
407+ LiquidateObligationAndRedeemReserveCollateral {
408+ /// Amount of liquidity to repay - u64::MAX for up to 100% of borrowed amount
409+ liquidity_amount : u64 ,
410+ } ,
382411}
383412
384413impl LendingInstruction {
@@ -414,7 +443,8 @@ impl LendingInstruction {
414443 let ( host_fee_percentage, rest) = Self :: unpack_u8 ( rest) ?;
415444 let ( deposit_limit, rest) = Self :: unpack_u64 ( rest) ?;
416445 let ( borrow_limit, rest) = Self :: unpack_u64 ( rest) ?;
417- let ( fee_receiver, _) = Self :: unpack_pubkey ( rest) ?;
446+ let ( fee_receiver, rest) = Self :: unpack_pubkey ( rest) ?;
447+ let ( protocol_liquidation_fee, _rest) = Self :: unpack_u8 ( rest) ?;
418448 Self :: InitReserve {
419449 liquidity_amount,
420450 config : ReserveConfig {
@@ -433,6 +463,7 @@ impl LendingInstruction {
433463 deposit_limit,
434464 borrow_limit,
435465 fee_receiver,
466+ protocol_liquidation_fee,
436467 } ,
437468 }
438469 }
@@ -480,20 +511,20 @@ impl LendingInstruction {
480511 Self :: WithdrawObligationCollateralAndRedeemReserveCollateral { collateral_amount }
481512 }
482513 16 => {
483- let ( optimal_utilization_rate, _rest ) = Self :: unpack_u8 ( rest) ?;
484- let ( loan_to_value_ratio, _rest ) = Self :: unpack_u8 ( _rest ) ?;
485- let ( liquidation_bonus, _rest ) = Self :: unpack_u8 ( _rest ) ?;
486- let ( liquidation_threshold, _rest ) = Self :: unpack_u8 ( _rest ) ?;
487- let ( min_borrow_rate, _rest ) = Self :: unpack_u8 ( _rest ) ?;
488- let ( optimal_borrow_rate, _rest ) = Self :: unpack_u8 ( _rest ) ?;
489- let ( max_borrow_rate, _rest ) = Self :: unpack_u8 ( _rest ) ?;
490- let ( borrow_fee_wad, _rest ) = Self :: unpack_u64 ( _rest ) ?;
491- let ( flash_loan_fee_wad, _rest ) = Self :: unpack_u64 ( _rest ) ?;
492- let ( host_fee_percentage, _rest ) = Self :: unpack_u8 ( _rest ) ?;
493- let ( deposit_limit, _rest ) = Self :: unpack_u64 ( _rest ) ?;
494- let ( borrow_limit, _rest ) = Self :: unpack_u64 ( _rest ) ?;
495- let ( fee_receiver, _ ) = Self :: unpack_pubkey ( _rest ) ?;
496-
514+ let ( optimal_utilization_rate, rest ) = Self :: unpack_u8 ( rest) ?;
515+ let ( loan_to_value_ratio, rest ) = Self :: unpack_u8 ( rest ) ?;
516+ let ( liquidation_bonus, rest ) = Self :: unpack_u8 ( rest ) ?;
517+ let ( liquidation_threshold, rest ) = Self :: unpack_u8 ( rest ) ?;
518+ let ( min_borrow_rate, rest ) = Self :: unpack_u8 ( rest ) ?;
519+ let ( optimal_borrow_rate, rest ) = Self :: unpack_u8 ( rest ) ?;
520+ let ( max_borrow_rate, rest ) = Self :: unpack_u8 ( rest ) ?;
521+ let ( borrow_fee_wad, rest ) = Self :: unpack_u64 ( rest ) ?;
522+ let ( flash_loan_fee_wad, rest ) = Self :: unpack_u64 ( rest ) ?;
523+ let ( host_fee_percentage, rest ) = Self :: unpack_u8 ( rest ) ?;
524+ let ( deposit_limit, rest ) = Self :: unpack_u64 ( rest ) ?;
525+ let ( borrow_limit, rest ) = Self :: unpack_u64 ( rest ) ?;
526+ let ( fee_receiver, rest ) = Self :: unpack_pubkey ( rest ) ?;
527+ let ( protocol_liquidation_fee , _rest ) = Self :: unpack_u8 ( rest ) ? ;
497528 Self :: UpdateReserveConfig {
498529 config : ReserveConfig {
499530 optimal_utilization_rate,
@@ -511,9 +542,14 @@ impl LendingInstruction {
511542 deposit_limit,
512543 borrow_limit,
513544 fee_receiver,
545+ protocol_liquidation_fee,
514546 } ,
515547 }
516548 }
549+ 17 => {
550+ let ( liquidity_amount, _rest) = Self :: unpack_u64 ( rest) ?;
551+ Self :: LiquidateObligationAndRedeemReserveCollateral { liquidity_amount }
552+ }
517553 _ => {
518554 msg ! ( "Instruction cannot be unpacked" ) ;
519555 return Err ( LendingError :: InstructionUnpackError . into ( ) ) ;
@@ -609,6 +645,7 @@ impl LendingInstruction {
609645 deposit_limit,
610646 borrow_limit,
611647 fee_receiver,
648+ protocol_liquidation_fee,
612649 } ,
613650 } => {
614651 buf. push ( 2 ) ;
@@ -626,6 +663,7 @@ impl LendingInstruction {
626663 buf. extend_from_slice ( & deposit_limit. to_le_bytes ( ) ) ;
627664 buf. extend_from_slice ( & borrow_limit. to_le_bytes ( ) ) ;
628665 buf. extend_from_slice ( & fee_receiver. to_bytes ( ) ) ;
666+ buf. extend_from_slice ( & protocol_liquidation_fee. to_le_bytes ( ) ) ;
629667 }
630668 Self :: RefreshReserve => {
631669 buf. push ( 3 ) ;
@@ -691,6 +729,11 @@ impl LendingInstruction {
691729 buf. extend_from_slice ( & config. deposit_limit . to_le_bytes ( ) ) ;
692730 buf. extend_from_slice ( & config. borrow_limit . to_le_bytes ( ) ) ;
693731 buf. extend_from_slice ( & config. fee_receiver . to_bytes ( ) ) ;
732+ buf. extend_from_slice ( & config. protocol_liquidation_fee . to_le_bytes ( ) ) ;
733+ }
734+ Self :: LiquidateObligationAndRedeemReserveCollateral { liquidity_amount } => {
735+ buf. push ( 17 ) ;
736+ buf. extend_from_slice ( & liquidity_amount. to_le_bytes ( ) ) ;
694737 }
695738 }
696739 buf
@@ -1216,3 +1259,52 @@ pub fn update_reserve_config(
12161259 data : LendingInstruction :: UpdateReserveConfig { config } . pack ( ) ,
12171260 }
12181261}
1262+
1263+ /// Creates a `LiquidateObligationAndRedeemReserveCollateral` instruction
1264+ #[ allow( clippy:: too_many_arguments) ]
1265+ pub fn liquidate_obligation_and_redeem_reserve_collateral (
1266+ program_id : Pubkey ,
1267+ liquidity_amount : u64 ,
1268+ source_liquidity_pubkey : Pubkey ,
1269+ destination_collateral_pubkey : Pubkey ,
1270+ destination_liquidity_pubkey : Pubkey ,
1271+ repay_reserve_pubkey : Pubkey ,
1272+ repay_reserve_liquidity_supply_pubkey : Pubkey ,
1273+ withdraw_reserve_pubkey : Pubkey ,
1274+ withdraw_reserve_collateral_mint_pubkey : Pubkey ,
1275+ withdraw_reserve_collateral_supply_pubkey : Pubkey ,
1276+ withdraw_reserve_liquidity_supply_pubkey : Pubkey ,
1277+ withdraw_reserve_liquidity_fee_receiver_pubkey : Pubkey ,
1278+ obligation_pubkey : Pubkey ,
1279+ lending_market_pubkey : Pubkey ,
1280+ user_transfer_authority_pubkey : Pubkey ,
1281+ ) -> Instruction {
1282+ let ( lending_market_authority_pubkey, _bump_seed) = Pubkey :: find_program_address (
1283+ & [ & lending_market_pubkey. to_bytes ( ) [ ..PUBKEY_BYTES ] ] ,
1284+ & program_id,
1285+ ) ;
1286+ Instruction {
1287+ program_id,
1288+ accounts : vec ! [
1289+ AccountMeta :: new( source_liquidity_pubkey, false ) ,
1290+ AccountMeta :: new( destination_collateral_pubkey, false ) ,
1291+ AccountMeta :: new( destination_liquidity_pubkey, false ) ,
1292+ AccountMeta :: new( repay_reserve_pubkey, false ) ,
1293+ AccountMeta :: new( repay_reserve_liquidity_supply_pubkey, false ) ,
1294+ AccountMeta :: new( withdraw_reserve_pubkey, false ) ,
1295+ AccountMeta :: new( withdraw_reserve_collateral_mint_pubkey, false ) ,
1296+ AccountMeta :: new( withdraw_reserve_collateral_supply_pubkey, false ) ,
1297+ AccountMeta :: new( withdraw_reserve_liquidity_supply_pubkey, false ) ,
1298+ AccountMeta :: new( withdraw_reserve_liquidity_fee_receiver_pubkey, false ) ,
1299+ AccountMeta :: new( obligation_pubkey, false ) ,
1300+ AccountMeta :: new_readonly( lending_market_pubkey, false ) ,
1301+ AccountMeta :: new_readonly( lending_market_authority_pubkey, false ) ,
1302+ AccountMeta :: new_readonly( user_transfer_authority_pubkey, true ) ,
1303+ AccountMeta :: new_readonly( spl_token:: id( ) , false ) ,
1304+ ] ,
1305+ data : LendingInstruction :: LiquidateObligationAndRedeemReserveCollateral {
1306+ liquidity_amount,
1307+ }
1308+ . pack ( ) ,
1309+ }
1310+ }
0 commit comments