Add slippage constraint to borrow instruction (#3423)
* Add slippage limit to instruction * Add slippage error * Return error if below slippage limit * Add tests * Remove TODO * Split instruction * Fix test name * Test limit case * Update test * Revert "Split instruction" This reverts commit 3eba4942bd51f2402bf112edb514882636f0e401. # Conflicts: # token-lending/program/tests/borrow_obligation_liquidity.rs * Allow missing slippage_limit * Fix limits * Remove assertion
This commit is contained in:
parent
e8bafb4b3f
commit
8d88fb6c88
|
@ -160,6 +160,9 @@ pub enum LendingError {
|
|||
#[error("Not enough liquidity after flash loan")]
|
||||
NotEnoughLiquidityAfterFlashLoan,
|
||||
// 45
|
||||
/// Lending instruction exceeds desired slippage limit
|
||||
#[error("Amount smaller than desired slippage limit")]
|
||||
ExceededSlippage,
|
||||
}
|
||||
|
||||
impl From<LendingError> for ProgramError {
|
||||
|
|
|
@ -219,7 +219,8 @@ pub enum LendingInstruction {
|
|||
BorrowObligationLiquidity {
|
||||
/// Amount of liquidity to borrow - u64::MAX for 100% of borrowing power
|
||||
liquidity_amount: u64,
|
||||
// @TODO: slippage constraint - https://git.io/JmV67
|
||||
/// Minimum amount of liquidity to receive, if borrowing 100% of borrowing power
|
||||
slippage_limit: u64,
|
||||
},
|
||||
|
||||
// 11
|
||||
|
@ -370,8 +371,12 @@ impl LendingInstruction {
|
|||
Self::WithdrawObligationCollateral { collateral_amount }
|
||||
}
|
||||
10 => {
|
||||
let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
|
||||
Self::BorrowObligationLiquidity { liquidity_amount }
|
||||
let (liquidity_amount, rest) = Self::unpack_u64(rest)?;
|
||||
let (slippage_limit, _rest) = Self::unpack_u64(rest).unwrap_or((0, &[]));
|
||||
Self::BorrowObligationLiquidity {
|
||||
liquidity_amount,
|
||||
slippage_limit,
|
||||
}
|
||||
}
|
||||
11 => {
|
||||
let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
|
||||
|
@ -525,9 +530,13 @@ impl LendingInstruction {
|
|||
buf.push(9);
|
||||
buf.extend_from_slice(&collateral_amount.to_le_bytes());
|
||||
}
|
||||
Self::BorrowObligationLiquidity { liquidity_amount } => {
|
||||
Self::BorrowObligationLiquidity {
|
||||
liquidity_amount,
|
||||
slippage_limit,
|
||||
} => {
|
||||
buf.push(10);
|
||||
buf.extend_from_slice(&liquidity_amount.to_le_bytes());
|
||||
buf.extend_from_slice(&slippage_limit.to_le_bytes());
|
||||
}
|
||||
Self::RepayObligationLiquidity { liquidity_amount } => {
|
||||
buf.push(11);
|
||||
|
@ -860,6 +869,7 @@ pub fn withdraw_obligation_collateral(
|
|||
pub fn borrow_obligation_liquidity(
|
||||
program_id: Pubkey,
|
||||
liquidity_amount: u64,
|
||||
slippage_limit: Option<u64>,
|
||||
source_liquidity_pubkey: Pubkey,
|
||||
destination_liquidity_pubkey: Pubkey,
|
||||
borrow_reserve_pubkey: Pubkey,
|
||||
|
@ -888,10 +898,15 @@ pub fn borrow_obligation_liquidity(
|
|||
if let Some(host_fee_receiver_pubkey) = host_fee_receiver_pubkey {
|
||||
accounts.push(AccountMeta::new(host_fee_receiver_pubkey, false));
|
||||
}
|
||||
let slippage_limit = slippage_limit.unwrap_or(0);
|
||||
Instruction {
|
||||
program_id,
|
||||
accounts,
|
||||
data: LendingInstruction::BorrowObligationLiquidity { liquidity_amount }.pack(),
|
||||
data: LendingInstruction::BorrowObligationLiquidity {
|
||||
liquidity_amount,
|
||||
slippage_limit,
|
||||
}
|
||||
.pack(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1309,6 +1324,7 @@ mod tests {
|
|||
let instruction = borrow_obligation_liquidity(
|
||||
program_id,
|
||||
liquidity_amount,
|
||||
None,
|
||||
source_liquidity_pubkey,
|
||||
destination_liquidity_pubkey,
|
||||
borrow_reserve_pubkey,
|
||||
|
@ -1322,7 +1338,11 @@ mod tests {
|
|||
assert_eq!(instruction.accounts.len(), 11);
|
||||
assert_eq!(
|
||||
instruction.data,
|
||||
LendingInstruction::BorrowObligationLiquidity { liquidity_amount }.pack()
|
||||
LendingInstruction::BorrowObligationLiquidity {
|
||||
liquidity_amount,
|
||||
slippage_limit: 0
|
||||
}
|
||||
.pack()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,9 +83,17 @@ pub fn process_instruction(
|
|||
msg!("Instruction: Withdraw Obligation Collateral");
|
||||
process_withdraw_obligation_collateral(program_id, collateral_amount, accounts)
|
||||
}
|
||||
LendingInstruction::BorrowObligationLiquidity { liquidity_amount } => {
|
||||
LendingInstruction::BorrowObligationLiquidity {
|
||||
liquidity_amount,
|
||||
slippage_limit,
|
||||
} => {
|
||||
msg!("Instruction: Borrow Obligation Liquidity");
|
||||
process_borrow_obligation_liquidity(program_id, liquidity_amount, accounts)
|
||||
process_borrow_obligation_liquidity(
|
||||
program_id,
|
||||
liquidity_amount,
|
||||
slippage_limit,
|
||||
accounts,
|
||||
)
|
||||
}
|
||||
LendingInstruction::RepayObligationLiquidity { liquidity_amount } => {
|
||||
msg!("Instruction: Repay Obligation Liquidity");
|
||||
|
@ -1023,6 +1031,7 @@ fn process_withdraw_obligation_collateral(
|
|||
fn process_borrow_obligation_liquidity(
|
||||
program_id: &Pubkey,
|
||||
liquidity_amount: u64,
|
||||
slippage_limit: u64,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
if liquidity_amount == 0 {
|
||||
|
@ -1141,6 +1150,11 @@ fn process_borrow_obligation_liquidity(
|
|||
return Err(LendingError::BorrowTooSmall.into());
|
||||
}
|
||||
|
||||
if liquidity_amount == u64::MAX && receive_amount < slippage_limit {
|
||||
msg!("Received liquidity would be smaller than the desired slippage limit");
|
||||
return Err(LendingError::ExceededSlippage.into());
|
||||
}
|
||||
|
||||
borrow_reserve.liquidity.borrow(borrow_amount)?;
|
||||
borrow_reserve.last_update.mark_stale();
|
||||
Reserve::pack(borrow_reserve, &mut borrow_reserve_info.data.borrow_mut())?;
|
||||
|
|
|
@ -102,6 +102,7 @@ async fn test_borrow_usdc_fixed_amount() {
|
|||
borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
USDC_BORROW_AMOUNT_FRACTIONAL,
|
||||
None,
|
||||
usdc_test_reserve.liquidity_supply_pubkey,
|
||||
usdc_test_reserve.user_liquidity_pubkey,
|
||||
usdc_test_reserve.pubkey,
|
||||
|
@ -249,6 +250,7 @@ async fn test_borrow_sol_max_amount() {
|
|||
borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
u64::MAX,
|
||||
None,
|
||||
sol_test_reserve.liquidity_supply_pubkey,
|
||||
sol_test_reserve.user_liquidity_pubkey,
|
||||
sol_test_reserve.pubkey,
|
||||
|
@ -380,6 +382,7 @@ async fn test_borrow_too_large() {
|
|||
borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
USDC_BORROW_AMOUNT_FRACTIONAL,
|
||||
None,
|
||||
usdc_test_reserve.liquidity_supply_pubkey,
|
||||
usdc_test_reserve.user_liquidity_pubkey,
|
||||
usdc_test_reserve.pubkey,
|
||||
|
@ -408,3 +411,353 @@ async fn test_borrow_too_large() {
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_borrow_max_receive_minimum() {
|
||||
let mut test = ProgramTest::new(
|
||||
"spl_token_lending",
|
||||
spl_token_lending::id(),
|
||||
processor!(process_instruction),
|
||||
);
|
||||
|
||||
// limit to track compute unit increase
|
||||
test.set_compute_max_units(60_000);
|
||||
|
||||
const FEE_AMOUNT: u64 = 5000;
|
||||
const HOST_FEE_AMOUNT: u64 = 1000;
|
||||
|
||||
const USDC_DEPOSIT_AMOUNT_FRACTIONAL: u64 =
|
||||
2_000 * FRACTIONAL_TO_USDC * INITIAL_COLLATERAL_RATIO;
|
||||
const SOL_BORROW_AMOUNT_LAMPORTS: u64 = 50 * LAMPORTS_TO_SOL;
|
||||
const USDC_RESERVE_COLLATERAL_FRACTIONAL: u64 = 2 * USDC_DEPOSIT_AMOUNT_FRACTIONAL;
|
||||
const SOL_RESERVE_LIQUIDITY_LAMPORTS: u64 = 2 * SOL_BORROW_AMOUNT_LAMPORTS;
|
||||
const SLIPPAGE_LIMIT: u64 = SOL_BORROW_AMOUNT_LAMPORTS - FEE_AMOUNT;
|
||||
|
||||
let user_accounts_owner = Keypair::new();
|
||||
let lending_market = add_lending_market(&mut test);
|
||||
|
||||
let mut reserve_config = TEST_RESERVE_CONFIG;
|
||||
reserve_config.loan_to_value_ratio = 50;
|
||||
|
||||
let usdc_mint = add_usdc_mint(&mut test);
|
||||
let usdc_oracle = add_usdc_oracle(&mut test);
|
||||
let usdc_test_reserve = add_reserve(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&usdc_oracle,
|
||||
&user_accounts_owner,
|
||||
AddReserveArgs {
|
||||
liquidity_amount: USDC_RESERVE_COLLATERAL_FRACTIONAL,
|
||||
liquidity_mint_pubkey: usdc_mint.pubkey,
|
||||
liquidity_mint_decimals: usdc_mint.decimals,
|
||||
config: reserve_config,
|
||||
mark_fresh: true,
|
||||
..AddReserveArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let sol_oracle = add_sol_oracle(&mut test);
|
||||
let sol_test_reserve = add_reserve(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&sol_oracle,
|
||||
&user_accounts_owner,
|
||||
AddReserveArgs {
|
||||
liquidity_amount: SOL_RESERVE_LIQUIDITY_LAMPORTS,
|
||||
liquidity_mint_pubkey: spl_token::native_mint::id(),
|
||||
liquidity_mint_decimals: 9,
|
||||
config: reserve_config,
|
||||
mark_fresh: true,
|
||||
..AddReserveArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let test_obligation = add_obligation(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&user_accounts_owner,
|
||||
AddObligationArgs {
|
||||
deposits: &[(&usdc_test_reserve, USDC_DEPOSIT_AMOUNT_FRACTIONAL)],
|
||||
..AddObligationArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let (mut banks_client, payer, recent_blockhash) = test.start().await;
|
||||
|
||||
let initial_liquidity_supply =
|
||||
get_token_balance(&mut banks_client, sol_test_reserve.liquidity_supply_pubkey).await;
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[
|
||||
refresh_obligation(
|
||||
spl_token_lending::id(),
|
||||
test_obligation.pubkey,
|
||||
vec![usdc_test_reserve.pubkey],
|
||||
),
|
||||
borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
u64::MAX,
|
||||
Some(SLIPPAGE_LIMIT),
|
||||
sol_test_reserve.liquidity_supply_pubkey,
|
||||
sol_test_reserve.user_liquidity_pubkey,
|
||||
sol_test_reserve.pubkey,
|
||||
sol_test_reserve.liquidity_fee_receiver_pubkey,
|
||||
test_obligation.pubkey,
|
||||
lending_market.pubkey,
|
||||
test_obligation.owner,
|
||||
Some(sol_test_reserve.liquidity_host_pubkey),
|
||||
),
|
||||
],
|
||||
Some(&payer.pubkey()),
|
||||
);
|
||||
|
||||
transaction.sign(&[&payer, &user_accounts_owner], recent_blockhash);
|
||||
assert!(banks_client.process_transaction(transaction).await.is_ok());
|
||||
|
||||
let sol_reserve = sol_test_reserve.get_state(&mut banks_client).await;
|
||||
let obligation = test_obligation.get_state(&mut banks_client).await;
|
||||
|
||||
let (total_fee, host_fee) = sol_reserve
|
||||
.config
|
||||
.fees
|
||||
.calculate_borrow_fees(SOL_BORROW_AMOUNT_LAMPORTS.into(), FeeCalculation::Inclusive)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(total_fee, FEE_AMOUNT);
|
||||
assert_eq!(host_fee, HOST_FEE_AMOUNT);
|
||||
|
||||
let borrow_amount =
|
||||
get_token_balance(&mut banks_client, sol_test_reserve.user_liquidity_pubkey).await;
|
||||
assert_eq!(borrow_amount, SOL_BORROW_AMOUNT_LAMPORTS - FEE_AMOUNT);
|
||||
|
||||
let liquidity = &obligation.borrows[0];
|
||||
assert_eq!(
|
||||
liquidity.borrowed_amount_wads,
|
||||
Decimal::from(SOL_BORROW_AMOUNT_LAMPORTS)
|
||||
);
|
||||
|
||||
let liquidity_supply =
|
||||
get_token_balance(&mut banks_client, sol_test_reserve.liquidity_supply_pubkey).await;
|
||||
assert_eq!(
|
||||
liquidity_supply,
|
||||
initial_liquidity_supply - SOL_BORROW_AMOUNT_LAMPORTS
|
||||
);
|
||||
|
||||
let fee_balance = get_token_balance(
|
||||
&mut banks_client,
|
||||
sol_test_reserve.liquidity_fee_receiver_pubkey,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(fee_balance, FEE_AMOUNT - HOST_FEE_AMOUNT);
|
||||
|
||||
let host_fee_balance =
|
||||
get_token_balance(&mut banks_client, sol_test_reserve.liquidity_host_pubkey).await;
|
||||
assert_eq!(host_fee_balance, HOST_FEE_AMOUNT);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_borrow_max_receive_less_than_slippage() {
|
||||
let mut test = ProgramTest::new(
|
||||
"spl_token_lending",
|
||||
spl_token_lending::id(),
|
||||
processor!(process_instruction),
|
||||
);
|
||||
|
||||
// limit to track compute unit increase
|
||||
test.set_compute_max_units(60_000);
|
||||
|
||||
const FEE_AMOUNT: u64 = 5000;
|
||||
|
||||
const USDC_DEPOSIT_AMOUNT_FRACTIONAL: u64 =
|
||||
2_000 * FRACTIONAL_TO_USDC * INITIAL_COLLATERAL_RATIO;
|
||||
const SOL_BORROW_AMOUNT_LAMPORTS: u64 = 50 * LAMPORTS_TO_SOL;
|
||||
const USDC_RESERVE_COLLATERAL_FRACTIONAL: u64 = 2 * USDC_DEPOSIT_AMOUNT_FRACTIONAL;
|
||||
const SOL_RESERVE_LIQUIDITY_LAMPORTS: u64 = 2 * SOL_BORROW_AMOUNT_LAMPORTS;
|
||||
const SLIPPAGE_LIMIT: u64 = SOL_BORROW_AMOUNT_LAMPORTS - FEE_AMOUNT + 1;
|
||||
|
||||
let user_accounts_owner = Keypair::new();
|
||||
let lending_market = add_lending_market(&mut test);
|
||||
|
||||
let mut reserve_config = TEST_RESERVE_CONFIG;
|
||||
reserve_config.loan_to_value_ratio = 50;
|
||||
|
||||
let usdc_mint = add_usdc_mint(&mut test);
|
||||
let usdc_oracle = add_usdc_oracle(&mut test);
|
||||
let usdc_test_reserve = add_reserve(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&usdc_oracle,
|
||||
&user_accounts_owner,
|
||||
AddReserveArgs {
|
||||
liquidity_amount: USDC_RESERVE_COLLATERAL_FRACTIONAL,
|
||||
liquidity_mint_pubkey: usdc_mint.pubkey,
|
||||
liquidity_mint_decimals: usdc_mint.decimals,
|
||||
config: reserve_config,
|
||||
mark_fresh: true,
|
||||
..AddReserveArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let sol_oracle = add_sol_oracle(&mut test);
|
||||
let sol_test_reserve = add_reserve(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&sol_oracle,
|
||||
&user_accounts_owner,
|
||||
AddReserveArgs {
|
||||
liquidity_amount: SOL_RESERVE_LIQUIDITY_LAMPORTS,
|
||||
liquidity_mint_pubkey: spl_token::native_mint::id(),
|
||||
liquidity_mint_decimals: 9,
|
||||
config: reserve_config,
|
||||
mark_fresh: true,
|
||||
..AddReserveArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let test_obligation = add_obligation(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&user_accounts_owner,
|
||||
AddObligationArgs {
|
||||
deposits: &[(&usdc_test_reserve, USDC_DEPOSIT_AMOUNT_FRACTIONAL)],
|
||||
..AddObligationArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let (mut banks_client, payer, recent_blockhash) = test.start().await;
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[
|
||||
refresh_obligation(
|
||||
spl_token_lending::id(),
|
||||
test_obligation.pubkey,
|
||||
vec![usdc_test_reserve.pubkey],
|
||||
),
|
||||
borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
u64::MAX,
|
||||
Some(SLIPPAGE_LIMIT),
|
||||
sol_test_reserve.liquidity_supply_pubkey,
|
||||
sol_test_reserve.user_liquidity_pubkey,
|
||||
sol_test_reserve.pubkey,
|
||||
sol_test_reserve.liquidity_fee_receiver_pubkey,
|
||||
test_obligation.pubkey,
|
||||
lending_market.pubkey,
|
||||
test_obligation.owner,
|
||||
Some(sol_test_reserve.liquidity_host_pubkey),
|
||||
),
|
||||
],
|
||||
Some(&payer.pubkey()),
|
||||
);
|
||||
|
||||
transaction.sign(&[&payer, &user_accounts_owner], recent_blockhash);
|
||||
assert_eq!(
|
||||
banks_client
|
||||
.process_transaction(transaction)
|
||||
.await
|
||||
.unwrap_err()
|
||||
.unwrap(),
|
||||
TransactionError::InstructionError(
|
||||
1,
|
||||
InstructionError::Custom(LendingError::ExceededSlippage as u32)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_borrow_less_than_max_with_slippage() {
|
||||
let mut test = ProgramTest::new(
|
||||
"spl_token_lending",
|
||||
spl_token_lending::id(),
|
||||
processor!(process_instruction),
|
||||
);
|
||||
|
||||
const USDC_TOTAL_BORROW_FRACTIONAL: u64 = 1_000 * FRACTIONAL_TO_USDC;
|
||||
const FEE_AMOUNT: u64 = 100;
|
||||
|
||||
const SOL_DEPOSIT_AMOUNT_LAMPORTS: u64 = 100 * LAMPORTS_TO_SOL * INITIAL_COLLATERAL_RATIO;
|
||||
const USDC_BORROW_AMOUNT_FRACTIONAL: u64 = USDC_TOTAL_BORROW_FRACTIONAL - FEE_AMOUNT;
|
||||
const SOL_RESERVE_COLLATERAL_LAMPORTS: u64 = 2 * SOL_DEPOSIT_AMOUNT_LAMPORTS;
|
||||
const USDC_RESERVE_LIQUIDITY_FRACTIONAL: u64 = 2 * USDC_TOTAL_BORROW_FRACTIONAL;
|
||||
const SLIPPAGE_LIMIT: u64 = u64::MAX;
|
||||
|
||||
let user_accounts_owner = Keypair::new();
|
||||
let lending_market = add_lending_market(&mut test);
|
||||
|
||||
let mut reserve_config = TEST_RESERVE_CONFIG;
|
||||
reserve_config.loan_to_value_ratio = 50;
|
||||
|
||||
let sol_oracle = add_sol_oracle(&mut test);
|
||||
let sol_test_reserve = add_reserve(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&sol_oracle,
|
||||
&user_accounts_owner,
|
||||
AddReserveArgs {
|
||||
collateral_amount: SOL_RESERVE_COLLATERAL_LAMPORTS,
|
||||
liquidity_mint_pubkey: spl_token::native_mint::id(),
|
||||
liquidity_mint_decimals: 9,
|
||||
config: reserve_config,
|
||||
mark_fresh: true,
|
||||
..AddReserveArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let usdc_mint = add_usdc_mint(&mut test);
|
||||
let usdc_oracle = add_usdc_oracle(&mut test);
|
||||
let usdc_test_reserve = add_reserve(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&usdc_oracle,
|
||||
&user_accounts_owner,
|
||||
AddReserveArgs {
|
||||
liquidity_amount: USDC_RESERVE_LIQUIDITY_FRACTIONAL,
|
||||
liquidity_mint_pubkey: usdc_mint.pubkey,
|
||||
liquidity_mint_decimals: usdc_mint.decimals,
|
||||
config: reserve_config,
|
||||
mark_fresh: true,
|
||||
..AddReserveArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let test_obligation = add_obligation(
|
||||
&mut test,
|
||||
&lending_market,
|
||||
&user_accounts_owner,
|
||||
AddObligationArgs {
|
||||
deposits: &[(&sol_test_reserve, SOL_DEPOSIT_AMOUNT_LAMPORTS)],
|
||||
..AddObligationArgs::default()
|
||||
},
|
||||
);
|
||||
|
||||
let (mut banks_client, payer, recent_blockhash) = test.start().await;
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[
|
||||
refresh_obligation(
|
||||
spl_token_lending::id(),
|
||||
test_obligation.pubkey,
|
||||
vec![sol_test_reserve.pubkey],
|
||||
),
|
||||
borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
USDC_BORROW_AMOUNT_FRACTIONAL,
|
||||
Some(SLIPPAGE_LIMIT),
|
||||
usdc_test_reserve.liquidity_supply_pubkey,
|
||||
usdc_test_reserve.user_liquidity_pubkey,
|
||||
usdc_test_reserve.pubkey,
|
||||
usdc_test_reserve.liquidity_fee_receiver_pubkey,
|
||||
test_obligation.pubkey,
|
||||
lending_market.pubkey,
|
||||
test_obligation.owner,
|
||||
Some(usdc_test_reserve.liquidity_host_pubkey),
|
||||
),
|
||||
],
|
||||
Some(&payer.pubkey()),
|
||||
);
|
||||
|
||||
transaction.sign(&[&payer, &user_accounts_owner], recent_blockhash);
|
||||
|
||||
// check that transaction succeeds
|
||||
banks_client.process_transaction(transaction).await.unwrap();
|
||||
}
|
||||
|
|
|
@ -651,6 +651,7 @@ impl TestLendingMarket {
|
|||
&[borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
liquidity_amount,
|
||||
None,
|
||||
borrow_reserve.liquidity_supply_pubkey,
|
||||
borrow_reserve.user_liquidity_pubkey,
|
||||
borrow_reserve.pubkey,
|
||||
|
|
|
@ -165,6 +165,7 @@ async fn test_success() {
|
|||
borrow_obligation_liquidity(
|
||||
spl_token_lending::id(),
|
||||
USDC_BORROW_AMOUNT_FRACTIONAL,
|
||||
None,
|
||||
usdc_test_reserve.liquidity_supply_pubkey,
|
||||
usdc_test_reserve.user_liquidity_pubkey,
|
||||
usdc_test_reserve.pubkey,
|
||||
|
|
Loading…
Reference in New Issue