Skip to main content

klend_interface/helpers/
compound.rs

1use solana_instruction::Instruction;
2use solana_pubkey::Pubkey;
3
4use super::{
5    common::{
6        build_deposit_reserves_remaining, build_refresh_all_obligation_reserves,
7        build_refresh_obligation, build_refresh_reserve,
8    },
9    info::{FarmsAccounts, ObligationInfo, ReserveInfo},
10};
11use crate::{
12    pda::{self, ReservePdas},
13    KLEND_PROGRAM_ID,
14};
15
16/// Build instructions to atomically deposit to one reserve and withdraw from
17/// another within the same obligation (rebalancing).
18///
19/// `obligation_reserves` should contain [`ReserveInfo`] for every deposit and
20/// borrow reserve on the obligation.
21///
22/// Returns: `[refresh_other_reserves..., refresh_deposit_reserve, refresh_withdraw_reserve,
23///            refresh_obligation, deposit_and_withdraw]`
24#[allow(clippy::too_many_arguments)]
25pub fn deposit_and_withdraw(
26    owner: Pubkey,
27    deposit_reserve: &ReserveInfo,
28    withdraw_reserve: &ReserveInfo,
29    obligation: &ObligationInfo,
30    obligation_reserves: &[ReserveInfo],
31    user_source_liquidity: Pubkey,
32    user_destination_liquidity: Pubkey,
33    deposit_liquidity_amount: u64,
34    withdraw_collateral_amount: u64,
35    deposit_farms: Option<&FarmsAccounts>,
36    withdraw_farms: Option<&FarmsAccounts>,
37) -> Vec<Instruction> {
38    let (lma, _) =
39        pda::lending_market_authority(&KLEND_PROGRAM_ID, &deposit_reserve.lending_market);
40    let deposit_pdas = ReservePdas::derive(&KLEND_PROGRAM_ID, &deposit_reserve.address);
41    let withdraw_pdas = ReservePdas::derive(&KLEND_PROGRAM_ID, &withdraw_reserve.address);
42    let (withdraw_lma, _) =
43        pda::lending_market_authority(&KLEND_PROGRAM_ID, &withdraw_reserve.lending_market);
44
45    let remaining = build_deposit_reserves_remaining(obligation);
46
47    let mut ixs = build_refresh_all_obligation_reserves(
48        obligation,
49        obligation_reserves,
50        &[deposit_reserve.address, withdraw_reserve.address],
51    );
52    ixs.push(build_refresh_reserve(deposit_reserve));
53    ixs.push(build_refresh_reserve(withdraw_reserve));
54    ixs.push(build_refresh_obligation(
55        &deposit_reserve.lending_market,
56        obligation,
57    ));
58    ixs.push(crate::instructions::compound::deposit_and_withdraw(
59        crate::instructions::compound::DepositAndWithdrawAccounts {
60            owner,
61            obligation: obligation.address,
62            lending_market: deposit_reserve.lending_market,
63            lending_market_authority: lma,
64            reserve: deposit_reserve.address,
65            reserve_liquidity_mint: deposit_reserve.liquidity_mint,
66            reserve_liquidity_supply: deposit_pdas.liquidity_supply_vault,
67            reserve_collateral_mint: deposit_pdas.collateral_mint,
68            reserve_destination_deposit_collateral: deposit_pdas.collateral_supply_vault,
69            user_source_liquidity,
70            placeholder_user_destination_collateral: None,
71            liquidity_token_program: deposit_reserve.liquidity_token_program,
72            withdraw_owner: owner,
73            withdraw_obligation: obligation.address,
74            withdraw_lending_market: withdraw_reserve.lending_market,
75            withdraw_lending_market_authority: withdraw_lma,
76            withdraw_reserve: withdraw_reserve.address,
77            withdraw_reserve_liquidity_mint: withdraw_reserve.liquidity_mint,
78            withdraw_reserve_source_collateral: withdraw_pdas.collateral_supply_vault,
79            withdraw_reserve_collateral_mint: withdraw_pdas.collateral_mint,
80            withdraw_reserve_liquidity_supply: withdraw_pdas.liquidity_supply_vault,
81            withdraw_user_destination_liquidity: user_destination_liquidity,
82            withdraw_placeholder_user_destination_collateral: None,
83            withdraw_liquidity_token_program: withdraw_reserve.liquidity_token_program,
84            deposit_obligation_farm_user_state: deposit_farms.map(|f| f.obligation_farm_user_state),
85            deposit_reserve_farm_state: deposit_farms.map(|f| f.reserve_farm_state),
86            withdraw_obligation_farm_user_state: withdraw_farms
87                .map(|f| f.obligation_farm_user_state),
88            withdraw_reserve_farm_state: withdraw_farms.map(|f| f.reserve_farm_state),
89        },
90        deposit_liquidity_amount,
91        withdraw_collateral_amount,
92        remaining,
93    ));
94
95    ixs
96}