Skip to content

Commit

Permalink
Merges WithdrawObligationCollateral and
Browse files Browse the repository at this point in the history
RedeemReserveCollateral
  • Loading branch information
DaSichuan committed Jul 11, 2021
1 parent 3b70835 commit 5ba8238
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 3 deletions.
34 changes: 33 additions & 1 deletion token-lending/program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub enum LendingInstruction {
/// 0. `[writable]` Source collateral token account.
/// $authority can transfer $collateral_amount.
/// 1. `[writable]` Destination liquidity token account.
/// 2. `[writable]` Reserve account.
/// 2. `[writable]` Reserve account. - refreshed
/// 3. `[writable]` Reserve collateral SPL Token mint.
/// 4. `[writable]` Reserve liquidity supply SPL Token account.
/// 5. `[]` Lending market account.
Expand Down Expand Up @@ -338,6 +338,30 @@ pub enum LendingInstruction {
/// Amount of liquidity to deposit in exchange
liquidity_amount: u64,
},

// 15
/// Combines WithdrawObligationCollateral and RedeemReserveCollateral
///
/// Accounts expected by this instruction:
///
/// 0. `[writable]` Source withdraw reserve collateral supply SPL Token account.
/// 1. `[writable]` Destination collateral token account.
/// Minted by withdraw reserve collateral mint.
/// 2. `[]` Withdraw reserve account - refreshed.
/// 3. `[writable]` Obligation account - refreshed.
/// 4. `[]` Lending market account.
/// 5. `[]` Derived lending market authority.
/// 6. `[writable]` User liquidity token account.
/// 7. `[writable]` Reserve collateral SPL Token mint.
/// 8. `[writable]` Reserve liquidity supply SPL Token account.
/// 9. `[signer]` Obligation owner
/// 10 `[signer]` User transfer authority ($authority).
/// 11. `[]` Clock sysvar.
/// 12. `[]` Token program id.
WithdrawObligationCollateralAndRedeemReserveCollateral {
/// liquidity_amount is the amount of collateral tokens to withdraw
collateral_amount: u64,
},
}

impl LendingInstruction {
Expand Down Expand Up @@ -428,6 +452,10 @@ impl LendingInstruction {
let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
Self::DepositReserveLiquidityAndObligationCollateral { liquidity_amount }
}
15 => {
let (collateral_amount, _rest) = Self::unpack_u64(rest)?;
Self::WithdrawObligationCollateralAndRedeemReserveCollateral { collateral_amount }
}
_ => {
msg!("Instruction cannot be unpacked");
return Err(LendingError::InstructionUnpackError.into());
Expand Down Expand Up @@ -580,6 +608,10 @@ impl LendingInstruction {
buf.push(14);
buf.extend_from_slice(&liquidity_amount.to_le_bytes());
}
Self::WithdrawObligationCollateralAndRedeemReserveCollateral { collateral_amount } => {
buf.push(15);
buf.extend_from_slice(&collateral_amount.to_le_bytes());
}
}
buf
}
Expand Down
124 changes: 122 additions & 2 deletions token-lending/program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,23 @@ pub fn process_instruction(
process_flash_loan(program_id, amount, accounts)
}
LendingInstruction::DepositReserveLiquidityAndObligationCollateral { liquidity_amount } => {
msg!("Instruction Deposit Reserve Liquidity and Obligation Collateral");
msg!("Instruction: Deposit Reserve Liquidity and Obligation Collateral");
process_deposit_reserve_liquidity_and_obligation_collateral(
program_id,
liquidity_amount,
accounts,
)
}
LendingInstruction::WithdrawObligationCollateralAndRedeemReserveCollateral {
collateral_amount,
} => {
msg!("Instruction: Withdraw Obligation Collateral and Redeem Reserve Collateral ");
process_withdraw_obligation_collateral_and_redeem_reserve_liquidity(
program_id,
collateral_amount,
accounts,
)
}
}
}

Expand Down Expand Up @@ -626,7 +636,37 @@ fn process_redeem_reserve_collateral(
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)?;
_redeem_reserve_collateral(
program_id,
collateral_amount,
source_collateral_info,
destination_liquidity_info,
reserve_info,
reserve_collateral_mint_info,
reserve_liquidity_supply_info,
lending_market_info,
lending_market_authority_info,
user_transfer_authority_info,
clock,
token_program_id,
)
}

#[allow(clippy::too_many_arguments)]
fn _redeem_reserve_collateral<'a>(
program_id: &Pubkey,
collateral_amount: u64,
source_collateral_info: &AccountInfo<'a>,
destination_liquidity_info: &AccountInfo<'a>,
reserve_info: &AccountInfo<'a>,
reserve_collateral_mint_info: &AccountInfo<'a>,
reserve_liquidity_supply_info: &AccountInfo<'a>,
lending_market_info: &AccountInfo<'a>,
lending_market_authority_info: &AccountInfo<'a>,
user_transfer_authority_info: &AccountInfo<'a>,
clock: &Clock,
token_program_id: &AccountInfo<'a>,
) -> ProgramResult {
let lending_market = LendingMarket::unpack(&lending_market_info.data.borrow())?;
if lending_market_info.owner != program_id {
msg!("Lending market provided is not owned by the lending program");
Expand Down Expand Up @@ -1099,7 +1139,36 @@ fn process_withdraw_obligation_collateral(
let obligation_owner_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)?;
_withdraw_obligation_collateral(
program_id,
collateral_amount,
source_collateral_info,
destination_collateral_info,
withdraw_reserve_info,
obligation_info,
lending_market_info,
lending_market_authority_info,
obligation_owner_info,
clock,
token_program_id,
)?;
Ok(())
}

#[allow(clippy::too_many_arguments)]
fn _withdraw_obligation_collateral<'a>(
program_id: &Pubkey,
collateral_amount: u64,
source_collateral_info: &AccountInfo<'a>,
destination_collateral_info: &AccountInfo<'a>,
withdraw_reserve_info: &AccountInfo<'a>,
obligation_info: &AccountInfo<'a>,
lending_market_info: &AccountInfo<'a>,
lending_market_authority_info: &AccountInfo<'a>,
obligation_owner_info: &AccountInfo<'a>,
clock: &Clock,
token_program_id: &AccountInfo<'a>,
) -> Result<u64, ProgramError> {
let lending_market = LendingMarket::unpack(&lending_market_info.data.borrow())?;
if lending_market_info.owner != program_id {
msg!("Lending market provided is not owned by the lending program");
Expand Down Expand Up @@ -1228,7 +1297,7 @@ fn process_withdraw_obligation_collateral(
token_program: token_program_id.clone(),
})?;

Ok(())
Ok(withdraw_amount)
}

#[inline(never)] // avoid stack frame limit
Expand Down Expand Up @@ -1874,6 +1943,57 @@ fn process_flash_loan(
Ok(())
}

#[inline(never)] // avoid stack frame limit
fn process_withdraw_obligation_collateral_and_redeem_reserve_liquidity(
program_id: &Pubkey,
collateral_amount: u64,
accounts: &[AccountInfo],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let reserve_collateral_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 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_liquidity_info = next_account_info(account_info_iter)?;
let reserve_collateral_mint_info = next_account_info(account_info_iter)?;
let reserve_liquidity_supply_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 liquidity_amount = _withdraw_obligation_collateral(
program_id,
collateral_amount,
reserve_collateral_info,
user_collateral_info,
reserve_info,
obligation_info,
lending_market_info,
lending_market_authority_info,
obligation_owner_info,
clock,
token_program_id,
)?;

_redeem_reserve_collateral(
program_id,
liquidity_amount,
user_collateral_info,
user_liquidity_info,
reserve_info,
reserve_collateral_mint_info,
reserve_liquidity_supply_info,
lending_market_info,
lending_market_authority_info,
user_transfer_authority_info,
clock,
token_program_id,
)
}

fn assert_rent_exempt(rent: &Rent, account_info: &AccountInfo) -> ProgramResult {
if !rent.is_exempt(account_info.lamports(), account_info.data_len()) {
msg!(
Expand Down

0 comments on commit 5ba8238

Please sign in to comment.