@@ -379,6 +379,35 @@ pub enum LendingInstruction {
379
379
/// Reserve config to update to
380
380
config : ReserveConfig ,
381
381
} ,
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
+ } ,
382
411
}
383
412
384
413
impl LendingInstruction {
@@ -414,7 +443,8 @@ impl LendingInstruction {
414
443
let ( host_fee_percentage, rest) = Self :: unpack_u8 ( rest) ?;
415
444
let ( deposit_limit, rest) = Self :: unpack_u64 ( rest) ?;
416
445
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) ?;
418
448
Self :: InitReserve {
419
449
liquidity_amount,
420
450
config : ReserveConfig {
@@ -433,6 +463,7 @@ impl LendingInstruction {
433
463
deposit_limit,
434
464
borrow_limit,
435
465
fee_receiver,
466
+ protocol_liquidation_fee,
436
467
} ,
437
468
}
438
469
}
@@ -480,20 +511,20 @@ impl LendingInstruction {
480
511
Self :: WithdrawObligationCollateralAndRedeemReserveCollateral { collateral_amount }
481
512
}
482
513
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 ) ? ;
497
528
Self :: UpdateReserveConfig {
498
529
config : ReserveConfig {
499
530
optimal_utilization_rate,
@@ -511,9 +542,14 @@ impl LendingInstruction {
511
542
deposit_limit,
512
543
borrow_limit,
513
544
fee_receiver,
545
+ protocol_liquidation_fee,
514
546
} ,
515
547
}
516
548
}
549
+ 17 => {
550
+ let ( liquidity_amount, _rest) = Self :: unpack_u64 ( rest) ?;
551
+ Self :: LiquidateObligationAndRedeemReserveCollateral { liquidity_amount }
552
+ }
517
553
_ => {
518
554
msg ! ( "Instruction cannot be unpacked" ) ;
519
555
return Err ( LendingError :: InstructionUnpackError . into ( ) ) ;
@@ -609,6 +645,7 @@ impl LendingInstruction {
609
645
deposit_limit,
610
646
borrow_limit,
611
647
fee_receiver,
648
+ protocol_liquidation_fee,
612
649
} ,
613
650
} => {
614
651
buf. push ( 2 ) ;
@@ -626,6 +663,7 @@ impl LendingInstruction {
626
663
buf. extend_from_slice ( & deposit_limit. to_le_bytes ( ) ) ;
627
664
buf. extend_from_slice ( & borrow_limit. to_le_bytes ( ) ) ;
628
665
buf. extend_from_slice ( & fee_receiver. to_bytes ( ) ) ;
666
+ buf. extend_from_slice ( & protocol_liquidation_fee. to_le_bytes ( ) ) ;
629
667
}
630
668
Self :: RefreshReserve => {
631
669
buf. push ( 3 ) ;
@@ -691,6 +729,11 @@ impl LendingInstruction {
691
729
buf. extend_from_slice ( & config. deposit_limit . to_le_bytes ( ) ) ;
692
730
buf. extend_from_slice ( & config. borrow_limit . to_le_bytes ( ) ) ;
693
731
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 ( ) ) ;
694
737
}
695
738
}
696
739
buf
@@ -1216,3 +1259,52 @@ pub fn update_reserve_config(
1216
1259
data : LendingInstruction :: UpdateReserveConfig { config } . pack ( ) ,
1217
1260
}
1218
1261
}
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