Skip to content

Commit

Permalink
donate to reserve function
Browse files Browse the repository at this point in the history
  • Loading branch information
nope-finance committed Sep 23, 2024
1 parent dc26dd7 commit f6c6ecb
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
57 changes: 57 additions & 0 deletions token-lending/program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ pub fn process_instruction(
msg!("Instruction: Mark Obligation As Closable");
process_set_obligation_closeability_status(program_id, closeable, accounts)
}
LendingInstruction::DonateToReserve { liquidity_amount } => {
msg!("Instruction: Donate To Reserve");
process_donate_to_reserve(program_id, liquidity_amount, accounts)
}
}
}

Expand Down Expand Up @@ -3187,6 +3191,59 @@ pub fn process_set_obligation_closeability_status(
Ok(())
}

/// process donate to reserve
pub fn process_donate_to_reserve(
program_id: &Pubkey,
liquidity_amount: u64,
accounts: &[AccountInfo],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let source_liquidity_info = next_account_info(account_info_iter)?;
let destination_liquidity_info = next_account_info(account_info_iter)?;
let reserve_info = next_account_info(account_info_iter)?;
let lending_market_info = next_account_info(account_info_iter)?;
let user_transfer_authority_info = next_account_info(account_info_iter)?;
let token_program_id = next_account_info(account_info_iter)?;

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");
return Err(LendingError::InvalidAccountOwner.into());
}
if &lending_market.token_program_id != token_program_id.key {
msg!("Lending market token program does not match the token program provided");
return Err(LendingError::InvalidTokenProgram.into());
}

if reserve_info.owner != program_id {
msg!("Lending market provided is not owned by the lending program");
return Err(LendingError::InvalidAccountOwner.into());
}

let mut reserve = Box::new(Reserve::unpack(&reserve_info.data.borrow())?);
if &reserve.lending_market != lending_market_info.key {
msg!("Reserve lending market does not match the lending market provided");
return Err(LendingError::InvalidAccountInput.into());
}

if &reserve.liquidity.supply_pubkey != destination_liquidity_info.key {
msg!("Reserve liquidity supply does not match the reserve liquidity supply provided");
return Err(LendingError::InvalidAccountInput.into());
}

reserve.liquidity.donate(liquidity_amount)?;
spl_token_transfer(TokenTransferParams {
source: source_liquidity_info.clone(),
destination: destination_liquidity_info.clone(),
amount: liquidity_amount,
authority: user_transfer_authority_info.clone(),
authority_signer_seeds: &[],
token_program: token_program_id.clone(),
})?;

Ok(())
}

fn assert_uninitialized<T: Pack + IsInitialized>(
account_info: &AccountInfo,
) -> Result<T, ProgramError> {
Expand Down
44 changes: 44 additions & 0 deletions token-lending/sdk/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,22 @@ pub enum LendingInstruction {
/// Obligation is closable
closeable: bool,
},

// 24
/// DonateToReserve
///
/// 0. `[writable]` Source liquidity token account.
/// Minted by repay reserve liquidity mint.
/// $authority can transfer $liquidity_amount.
/// 1. `[writable]` Destination reserve liquidity supply SPL Token account.
/// 2. `[writable]` Repay reserve account - refreshed.
/// 3. `[]` Lending market account.
/// 4. `[signer]` User transfer authority ($authority).
/// 5. `[]` Token program id.
DonateToReserve {
/// amount to donate
liquidity_amount: u64,
},
}

impl LendingInstruction {
Expand Down Expand Up @@ -1061,6 +1077,10 @@ impl LendingInstruction {
buf.push(23);
buf.extend_from_slice(&(closeable as u8).to_le_bytes());
}
Self::DonateToReserve { liquidity_amount } => {
buf.push(24);
buf.extend_from_slice(&liquidity_amount.to_le_bytes());
}
}
buf
}
Expand Down Expand Up @@ -1849,6 +1869,30 @@ pub fn set_obligation_closeability_status(
}
}

/// Creates a `DonateToReserve` instruction
pub fn donate_to_reserve(
program_id: Pubkey,
liquidity_amount: u64,
source_liquidity_pubkey: Pubkey,
destination_liquidity_pubkey: Pubkey,
reserve_pubkey: Pubkey,
lending_market_pubkey: Pubkey,
user_transfer_authority_pubkey: Pubkey,
) -> Instruction {
Instruction {
program_id,
accounts: vec![
AccountMeta::new(source_liquidity_pubkey, false),
AccountMeta::new(destination_liquidity_pubkey, false),
AccountMeta::new(reserve_pubkey, false),
AccountMeta::new_readonly(lending_market_pubkey, false),
AccountMeta::new_readonly(user_transfer_authority_pubkey, true),
AccountMeta::new_readonly(spl_token::id(), false),
],
data: LendingInstruction::DonateToReserve { liquidity_amount }.pack(),
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
9 changes: 9 additions & 0 deletions token-lending/sdk/src/state/reserve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,15 @@ impl ReserveLiquidity {
Ok(())
}

/// Add donate_amount to available liquidity and subtract settle amount from total borrows
pub fn donate(&mut self, donate_amount: u64) -> ProgramResult {
self.available_amount = self
.available_amount
.checked_add(donate_amount)
.ok_or(LendingError::MathOverflow)?;
Ok(())
}

/// Subtract settle amount from accumulated_protocol_fees_wads and withdraw_amount from available liquidity
pub fn redeem_fees(&mut self, withdraw_amount: u64) -> ProgramResult {
self.available_amount = self
Expand Down

0 comments on commit f6c6ecb

Please sign in to comment.