From f5f7eed8f57015890d6ba27c902c459ce6091ee0 Mon Sep 17 00:00:00 2001 From: dasichuan <0xdasichuan@gmail.com> Date: Fri, 25 Jun 2021 14:20:04 -0700 Subject: [PATCH] Add combined function --- token-lending/program/src/instruction.rs | 32 +++++++++++ token-lending/program/src/processor.rs | 71 +++++++++++++++++++++++- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/token-lending/program/src/instruction.rs b/token-lending/program/src/instruction.rs index 5857a11dec9..f9a732c22f8 100644 --- a/token-lending/program/src/instruction.rs +++ b/token-lending/program/src/instruction.rs @@ -309,6 +309,30 @@ pub enum LendingInstruction { /// The amount that is to be borrowed - u64::MAX for up to 100% of available liquidity amount: u64, }, + + // 14 + /// Combines DepositReserveLiquidity and DepositObligationCollateral + /// + /// Accounts expected by this instruction: + /// + /// 0. `[writable]` Source liquidity token account. + /// $authority can transfer $liquidity_amount. + /// 1. `[writable]` Destination collateral token account. + /// 2. `[writable]` Reserve account. + /// 3. `[writable]` Reserve liquidity supply SPL Token account. + /// 4. `[writable]` Reserve collateral SPL Token mint. + /// 5. `[]` Lending market account. + /// 6. `[]` Derived lending market authority. + /// 7. `[writable]` Destination deposit reserve collateral supply SPL Token account. + /// 8. `[writable]` Obligation account. + /// 9. `[signer]` Obligation owner. + /// 10. `[signer]` User transfer authority ($authority). + /// 11. `[]` Clock sysvar. + /// 12. `[]` Token program id. + DepositReserveLiquidityAndObligationCollateral { + /// Amount of liquidity to deposit in exchange + liquidity_amount: u64, + }, } impl LendingInstruction { @@ -395,6 +419,10 @@ impl LendingInstruction { let (amount, _rest) = Self::unpack_u64(rest)?; Self::FlashLoan { amount } } + 14 => { + let (liquidity_amount, _rest) = Self::unpack_u64(rest)?; + Self::DepositReserveLiquidityAndObligationCollateral { liquidity_amount } + } _ => { msg!("Instruction cannot be unpacked"); return Err(LendingError::InstructionUnpackError.into()); @@ -543,6 +571,10 @@ impl LendingInstruction { buf.push(13); buf.extend_from_slice(&amount.to_le_bytes()); } + Self::DepositReserveLiquidityAndObligationCollateral { liquidity_amount } => { + buf.push(14); + buf.extend_from_slice(&liquidity_amount.to_le_bytes()); + } } buf } diff --git a/token-lending/program/src/processor.rs b/token-lending/program/src/processor.rs index eba31553570..2fd875247f6 100644 --- a/token-lending/program/src/processor.rs +++ b/token-lending/program/src/processor.rs @@ -100,6 +100,14 @@ pub fn process_instruction( msg!("Instruction: Flash Loan"); process_flash_loan(program_id, amount, accounts) } + LendingInstruction::DepositReserveLiquidityAndObligationCollateral { liquidity_amount } => { + msg!("Instruction Deposit Reserve Liquidity and Obligation Collateral"); + process_deposit_reserve_liquidity_and_obligation_collateral( + program_id, + liquidity_amount, + accounts, + ) + } } } @@ -451,7 +459,7 @@ fn process_deposit_reserve_liquidity( let token_program_id = next_account_info(account_info_iter)?; // We don't care about the return value here, so just ignore it. - _process_deposit_reserve_liquidity( + _deposit_reserve_liquidity( program_id, liquidity_amount, source_liquidity_info, @@ -469,7 +477,7 @@ fn process_deposit_reserve_liquidity( } #[allow(clippy::too_many_arguments)] -fn _process_deposit_reserve_liquidity<'a>( +fn _deposit_reserve_liquidity<'a>( program_id: &Pubkey, liquidity_amount: u64, source_liquidity_info: &AccountInfo<'a>, @@ -836,7 +844,7 @@ fn process_deposit_obligation_collateral( collateral_amount: u64, accounts: &[AccountInfo], ) -> ProgramResult { - if collateral_amount == 0 { + if collateral_amount <= 0 { msg!("Collateral amount provided cannot be zero"); return Err(LendingError::InvalidAmount.into()); } @@ -970,6 +978,63 @@ fn _deposit_obligation_collateral<'a>( Ok(()) } +#[inline(never)] // avoid stack frame limit +fn process_deposit_reserve_liquidity_and_obligation_collateral( + 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 user_collateral_info = next_account_info(account_info_iter)?; + let reserve_info = next_account_info(account_info_iter)?; + let reserve_liquidity_supply_info = next_account_info(account_info_iter)?; + let reserve_collateral_mint_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 destination_collateral_info = next_account_info(account_info_iter)?; + let obligation_info = next_account_info(account_info_iter)?; + let obligation_owner_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)?; + + let collateral_amount = _deposit_reserve_liquidity( + program_id, + liquidity_amount, + source_liquidity_info, + user_collateral_info, + reserve_info, + reserve_liquidity_supply_info, + reserve_collateral_mint_info, + lending_market_info, + lending_market_authority_info, + user_transfer_authority_info, + clock, + token_program_id, + )?; + _deposit_obligation_collateral( + program_id, + collateral_amount, + user_collateral_info, + destination_collateral_info, + reserve_info, + obligation_info, + lending_market_info, + lending_market_authority_info, + obligation_owner_info, + user_transfer_authority_info, + clock, + token_program_id, + )?; + Ok(()) +} + #[inline(never)] // avoid stack frame limit fn process_withdraw_obligation_collateral( program_id: &Pubkey,