Skip to main content

klend_interface/helpers/
flash.rs

1use solana_instruction::Instruction;
2use solana_pubkey::Pubkey;
3
4use super::info::ReserveInfo;
5use crate::{
6    instructions::flash::{
7        flash_borrow_reserve_liquidity, flash_repay_reserve_liquidity,
8        FlashBorrowReserveLiquidityAccounts, FlashRepayReserveLiquidityAccounts,
9    },
10    pda::{self, ReservePdas},
11    KLEND_PROGRAM_ID,
12};
13
14/// Build instructions for a flash loan (borrow + repay pair).
15///
16/// The returned instructions must be placed in a single transaction. The caller
17/// can insert arbitrary instructions between the borrow and repay.
18///
19/// `borrow_instruction_index` is the index of the flash-borrow instruction
20/// within the final transaction (typically 0 when no other instructions precede it).
21///
22/// Returns: `(borrow_ix, repay_ix)` — a `flash_borrow` instruction and a
23/// `flash_repay` instruction to append after user logic.
24pub fn flash_loan(
25    user: Pubkey,
26    reserve: &ReserveInfo,
27    user_source_liquidity: Pubkey,
28    user_destination_liquidity: Pubkey,
29    liquidity_amount: u64,
30    borrow_instruction_index: u8,
31    referrer: Option<Pubkey>,
32) -> (Instruction, Instruction) {
33    let pdas = ReservePdas::derive(&KLEND_PROGRAM_ID, &reserve.address);
34    let (lma, _) = pda::lending_market_authority(&KLEND_PROGRAM_ID, &reserve.lending_market);
35
36    let referrer_token_state =
37        referrer.map(|r| pda::referrer_token_state(&KLEND_PROGRAM_ID, &r, &reserve.address).0);
38
39    let borrow_ix = flash_borrow_reserve_liquidity(
40        FlashBorrowReserveLiquidityAccounts {
41            user_transfer_authority: user,
42            lending_market_authority: lma,
43            lending_market: reserve.lending_market,
44            reserve: reserve.address,
45            reserve_liquidity_mint: reserve.liquidity_mint,
46            reserve_source_liquidity: pdas.liquidity_supply_vault,
47            user_destination_liquidity,
48            reserve_liquidity_fee_receiver: pdas.fee_vault,
49            referrer_token_state,
50            referrer_account: referrer,
51            token_program: reserve.liquidity_token_program,
52        },
53        liquidity_amount,
54    );
55
56    let repay_ix = flash_repay_reserve_liquidity(
57        FlashRepayReserveLiquidityAccounts {
58            user_transfer_authority: user,
59            lending_market_authority: lma,
60            lending_market: reserve.lending_market,
61            reserve: reserve.address,
62            reserve_liquidity_mint: reserve.liquidity_mint,
63            reserve_destination_liquidity: pdas.liquidity_supply_vault,
64            user_source_liquidity,
65            reserve_liquidity_fee_receiver: pdas.fee_vault,
66            referrer_token_state,
67            referrer_account: referrer,
68            token_program: reserve.liquidity_token_program,
69        },
70        liquidity_amount,
71        borrow_instruction_index,
72    );
73
74    (borrow_ix, repay_ix)
75}