-
Notifications
You must be signed in to change notification settings - Fork 2
/
dlmm_swap.rs
101 lines (88 loc) · 3.52 KB
/
dlmm_swap.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use anchor_lang::prelude::*;
#[derive(Accounts)]
pub struct DlmmSwap<'info> {
#[account(mut)]
/// CHECK: The pool account
pub lb_pair: UncheckedAccount<'info>,
/// CHECK: Bin array extension account of the pool
pub bin_array_bitmap_extension: Option<UncheckedAccount<'info>>,
#[account(mut)]
/// CHECK: Reserve account of token X
pub reserve_x: UncheckedAccount<'info>,
#[account(mut)]
/// CHECK: Reserve account of token Y
pub reserve_y: UncheckedAccount<'info>,
#[account(mut)]
/// CHECK: User token account to sell token
pub user_token_in: UncheckedAccount<'info>,
#[account(mut)]
/// CHECK: User token account to buy token
pub user_token_out: UncheckedAccount<'info>,
/// CHECK: Mint account of token X
pub token_x_mint: UncheckedAccount<'info>,
/// CHECK: Mint account of token Y
pub token_y_mint: UncheckedAccount<'info>,
#[account(mut)]
/// CHECK: Oracle account of the pool
pub oracle: UncheckedAccount<'info>,
#[account(mut)]
/// CHECK: Referral fee account
pub host_fee_in: Option<UncheckedAccount<'info>>,
/// CHECK: User who's executing the swap
pub user: Signer<'info>,
#[account(address = dlmm::ID)]
/// CHECK: DLMM program
pub dlmm_program: UncheckedAccount<'info>,
/// CHECK: DLMM program event authority for event CPI
pub event_authority: UncheckedAccount<'info>,
/// CHECK: Token program of mint X
pub token_x_program: UncheckedAccount<'info>,
/// CHECK: Token program of mint Y
pub token_y_program: UncheckedAccount<'info>,
// Bin arrays need to be passed using remaining accounts
}
/// Executes a DLMM swap
///
/// # Arguments
///
/// * `ctx` - The context containing accounts and programs.
/// * `amount_in` - The amount of input tokens to be swapped.
/// * `min_amount_out` - The minimum amount of output tokens expected a.k.a slippage
///
/// # Returns
///
/// Returns a `Result` indicating success or failure.
pub fn handle_dlmm_swap<'a, 'b, 'c, 'info>(
ctx: Context<'a, 'b, 'c, 'info, DlmmSwap<'info>>,
amount_in: u64,
min_amount_out: u64,
) -> Result<()> {
let accounts = dlmm::cpi::accounts::Swap {
lb_pair: ctx.accounts.lb_pair.to_account_info(),
bin_array_bitmap_extension: ctx
.accounts
.bin_array_bitmap_extension
.as_ref()
.map(|account| account.to_account_info()),
reserve_x: ctx.accounts.reserve_x.to_account_info(),
reserve_y: ctx.accounts.reserve_y.to_account_info(),
user_token_in: ctx.accounts.user_token_in.to_account_info(),
user_token_out: ctx.accounts.user_token_out.to_account_info(),
token_x_mint: ctx.accounts.token_x_mint.to_account_info(),
token_y_mint: ctx.accounts.token_y_mint.to_account_info(),
oracle: ctx.accounts.oracle.to_account_info(),
host_fee_in: ctx
.accounts
.host_fee_in
.as_ref()
.map(|account| account.to_account_info()),
user: ctx.accounts.user.to_account_info(),
token_x_program: ctx.accounts.token_x_program.to_account_info(),
token_y_program: ctx.accounts.token_y_program.to_account_info(),
event_authority: ctx.accounts.event_authority.to_account_info(),
program: ctx.accounts.dlmm_program.to_account_info(),
};
let cpi_context = CpiContext::new(ctx.accounts.dlmm_program.to_account_info(), accounts)
.with_remaining_accounts(ctx.remaining_accounts.to_vec());
dlmm::cpi::swap(cpi_context, amount_in, min_amount_out)
}