Skip to content

turn on liquidation fees and deprecate old liquidation instruction #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions token-lending/program/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ pub enum LendingError {
/// Insufficent protocol fees to redeem or no liquidity availible to process redeem
#[error("Insufficent protocol fees to claim or no liquidity availible")]
InsufficientProtocolFeesToRedeem,
/// Deprecated instruction
#[error("Instruction is deprecated")]
DeprecatedInstruction,
}

impl From<LendingError> for ProgramError {
Expand Down
44 changes: 5 additions & 39 deletions token-lending/program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1584,46 +1584,12 @@ fn process_repay_obligation_liquidity(

#[inline(never)] // avoid stack frame limit
fn process_liquidate_obligation(
program_id: &Pubkey,
liquidity_amount: u64,
accounts: &[AccountInfo],
_program_id: &Pubkey,
_liquidity_amount: u64,
_accounts: &[AccountInfo],
) -> ProgramResult {
if liquidity_amount == 0 {
msg!("Liquidity amount provided cannot be zero");
return Err(LendingError::InvalidAmount.into());
}

let account_info_iter = &mut accounts.iter();
let source_liquidity_info = next_account_info(account_info_iter)?;
let destination_collateral_info = next_account_info(account_info_iter)?;
let repay_reserve_info = next_account_info(account_info_iter)?;
let repay_reserve_liquidity_supply_info = next_account_info(account_info_iter)?;
let withdraw_reserve_info = next_account_info(account_info_iter)?;
let withdraw_reserve_collateral_supply_info = next_account_info(account_info_iter)?;
let obligation_info = next_account_info(account_info_iter)?;
let lending_market_info = next_account_info(account_info_iter)?;
let lending_market_authority_info = next_account_info(account_info_iter)?;
let user_transfer_authority_info = next_account_info(account_info_iter)?;
let clock = &Clock::from_account_info(next_account_info(account_info_iter)?)?;
let token_program_id = next_account_info(account_info_iter)?;

_liquidate_obligation(
program_id,
liquidity_amount,
source_liquidity_info,
destination_collateral_info,
repay_reserve_info,
repay_reserve_liquidity_supply_info,
withdraw_reserve_info,
withdraw_reserve_collateral_supply_info,
obligation_info,
lending_market_info,
lending_market_authority_info,
user_transfer_authority_info,
clock,
token_program_id,
)?;
Ok(())
msg!("method deprecated, please migrate to Liquidate Obligation and Redeem Reserve Collateral");
Err(LendingError::DeprecatedInstruction.into())
}

#[allow(clippy::too_many_arguments)]
Expand Down
8 changes: 6 additions & 2 deletions token-lending/program/src/state/reserve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,12 @@ impl Reserve {
let bonus = amount_liquidated_wads.try_sub(amount_liquidated_wads.try_div(bonus_rate)?)?;

// After deploying must update all reserves to set liquidation fee then redeploy with this line instead of hardcode
// let protocol_fee = max(bonus.try_mul(Rate::from_percent(self.config.protocol_liquidation_fee))?.try_ceil_u64()?, 1);
let protocol_fee = std::cmp::max(bonus.try_mul(Rate::from_percent(0))?.try_ceil_u64()?, 1);
let protocol_fee = std::cmp::max(
bonus
.try_mul(Rate::from_percent(self.config.protocol_liquidation_fee))?
.try_ceil_u64()?,
1,
);
Ok(protocol_fee)
}

Expand Down
55 changes: 4 additions & 51 deletions token-lending/program/tests/liquidate_obligation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use solend_program::{
use spl_token::instruction::approve;

#[tokio::test]
async fn test_success() {
async fn test_fail_deprecated() {
let mut test = ProgramTest::new(
"solend_program",
solend_program::id(),
Expand All @@ -35,8 +35,8 @@ async fn test_success() {
const USDC_LIQUIDATION_AMOUNT_FRACTIONAL: u64 =
USDC_BORROW_AMOUNT_FRACTIONAL * (LIQUIDATION_CLOSE_FACTOR as u64) / 100;
// 320 USDC / 20 USDC per SOL -> 16 SOL + 10% bonus -> 17.6 SOL (88/5)
const SOL_LIQUIDATION_AMOUNT_LAMPORTS: u64 =
LAMPORTS_TO_SOL * INITIAL_COLLATERAL_RATIO * 88 * (LIQUIDATION_CLOSE_FACTOR as u64) / 100;
// const SOL_LIQUIDATION_AMOUNT_LAMPORTS: u64 =
// LAMPORTS_TO_SOL * INITIAL_COLLATERAL_RATIO * 88 * (LIQUIDATION_CLOSE_FACTOR as u64) / 100;

const SOL_RESERVE_COLLATERAL_LAMPORTS: u64 = 2 * SOL_DEPOSIT_AMOUNT_LAMPORTS;
const USDC_RESERVE_LIQUIDITY_FRACTIONAL: u64 = 2 * USDC_BORROW_AMOUNT_FRACTIONAL;
Expand Down Expand Up @@ -98,15 +98,6 @@ async fn test_success() {

let (mut banks_client, payer, recent_blockhash) = test.start().await;

let initial_user_liquidity_balance =
get_token_balance(&mut banks_client, usdc_test_reserve.user_liquidity_pubkey).await;
let initial_liquidity_supply_balance =
get_token_balance(&mut banks_client, usdc_test_reserve.liquidity_supply_pubkey).await;
let initial_user_collateral_balance =
get_token_balance(&mut banks_client, sol_test_reserve.user_collateral_pubkey).await;
let initial_collateral_supply_balance =
get_token_balance(&mut banks_client, sol_test_reserve.collateral_supply_pubkey).await;

let mut transaction = Transaction::new_with_payer(
&[
approve(
Expand Down Expand Up @@ -144,43 +135,5 @@ async fn test_success() {
&[&payer, &user_accounts_owner, &user_transfer_authority],
recent_blockhash,
);
assert!(banks_client.process_transaction(transaction).await.is_ok());

let user_liquidity_balance =
get_token_balance(&mut banks_client, usdc_test_reserve.user_liquidity_pubkey).await;
assert_eq!(
user_liquidity_balance,
initial_user_liquidity_balance - USDC_LIQUIDATION_AMOUNT_FRACTIONAL
);

let liquidity_supply_balance =
get_token_balance(&mut banks_client, usdc_test_reserve.liquidity_supply_pubkey).await;
assert_eq!(
liquidity_supply_balance,
initial_liquidity_supply_balance + USDC_LIQUIDATION_AMOUNT_FRACTIONAL
);

let user_collateral_balance =
get_token_balance(&mut banks_client, sol_test_reserve.user_collateral_pubkey).await;
assert_eq!(
user_collateral_balance,
initial_user_collateral_balance + SOL_LIQUIDATION_AMOUNT_LAMPORTS
);

let collateral_supply_balance =
get_token_balance(&mut banks_client, sol_test_reserve.collateral_supply_pubkey).await;
assert_eq!(
collateral_supply_balance,
initial_collateral_supply_balance - SOL_LIQUIDATION_AMOUNT_LAMPORTS
);

let obligation = test_obligation.get_state(&mut banks_client).await;
assert_eq!(
obligation.deposits[0].deposited_amount,
SOL_DEPOSIT_AMOUNT_LAMPORTS - SOL_LIQUIDATION_AMOUNT_LAMPORTS
);
assert_eq!(
obligation.borrows[0].borrowed_amount_wads,
(USDC_BORROW_AMOUNT_FRACTIONAL - USDC_LIQUIDATION_AMOUNT_FRACTIONAL).into()
)
assert!(banks_client.process_transaction(transaction).await.is_err());
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,7 @@ async fn test_success() {

assert_eq!(
// 30% of the bonus
// SOL_LIQUIDATION_AMOUNT_LAMPORTS * 3 / 10 / 11,
// 0 % min 1 for now
max(SOL_LIQUIDATION_AMOUNT_LAMPORTS * 0 / 10 / 11, 1),
max(SOL_LIQUIDATION_AMOUNT_LAMPORTS * 3 / 10 / 11, 1),
(fee_receiver_withdraw_liquidity_balance - initial_fee_receiver_withdraw_liquidity_balance)
);

Expand Down Expand Up @@ -367,11 +365,9 @@ async fn test_success_insufficent_liquidity() {
);

assert_eq!(
// 30% of the bonus (math looks stupid because i need to divide but round up so x/y -> (x-1)/y+1 )
// max((min(SOL_LIQUIDATION_AMOUNT_LAMPORTS, AVAILABLE_SOL_LIQUIDITY) * 3 - 1 ) / (10 * 11) + 1, 1),
// 0 % min 1 for now
// 30% of the bonus (math looks stupid because need to divide but round up so x/y -> (x-1)/y+1 )
max(
(min(SOL_LIQUIDATION_AMOUNT_LAMPORTS, AVAILABLE_SOL_LIQUIDITY) * 0) / (10 * 11),
(min(SOL_LIQUIDATION_AMOUNT_LAMPORTS, AVAILABLE_SOL_LIQUIDITY) * 3 - 1) / (10 * 11) + 1,
1
),
(fee_reciever_withdraw_liquidity_balance - initial_fee_reciever_withdraw_liquidity_balance)
Expand Down