-
Notifications
You must be signed in to change notification settings - Fork 93
/
collect_fund_fee.rs
122 lines (107 loc) · 4.24 KB
/
collect_fund_fee.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::error::ErrorCode;
use crate::states::*;
use crate::utils::token::*;
use anchor_lang::prelude::*;
use anchor_spl::token::Token;
use anchor_spl::token_interface::Mint;
use anchor_spl::token_interface::Token2022;
use anchor_spl::token_interface::TokenAccount;
#[derive(Accounts)]
pub struct CollectFundFee<'info> {
/// Only admin or fund_owner can collect fee now
#[account(constraint = (owner.key() == amm_config.fund_owner || owner.key() == crate::admin::id()) @ ErrorCode::InvalidOwner)]
pub owner: Signer<'info>,
/// CHECK: pool vault and lp mint authority
#[account(
seeds = [
crate::AUTH_SEED.as_bytes(),
],
bump,
)]
pub authority: UncheckedAccount<'info>,
/// Pool state stores accumulated protocol fee amount
#[account(mut)]
pub pool_state: AccountLoader<'info, PoolState>,
/// Amm config account stores fund_owner
#[account(address = pool_state.load()?.amm_config)]
pub amm_config: Account<'info, AmmConfig>,
/// The address that holds pool tokens for token_0
#[account(
mut,
constraint = token_0_vault.key() == pool_state.load()?.token_0_vault
)]
pub token_0_vault: Box<InterfaceAccount<'info, TokenAccount>>,
/// The address that holds pool tokens for token_1
#[account(
mut,
constraint = token_1_vault.key() == pool_state.load()?.token_1_vault
)]
pub token_1_vault: Box<InterfaceAccount<'info, TokenAccount>>,
/// The mint of token_0 vault
#[account(
address = token_0_vault.mint
)]
pub vault_0_mint: Box<InterfaceAccount<'info, Mint>>,
/// The mint of token_1 vault
#[account(
address = token_1_vault.mint
)]
pub vault_1_mint: Box<InterfaceAccount<'info, Mint>>,
/// The address that receives the collected token_0 fund fees
#[account(mut)]
pub recipient_token_0_account: Box<InterfaceAccount<'info, TokenAccount>>,
/// The address that receives the collected token_1 fund fees
#[account(mut)]
pub recipient_token_1_account: Box<InterfaceAccount<'info, TokenAccount>>,
/// The SPL program to perform token transfers
pub token_program: Program<'info, Token>,
/// The SPL program 2022 to perform token transfers
pub token_program_2022: Program<'info, Token2022>,
}
pub fn collect_fund_fee(
ctx: Context<CollectFundFee>,
amount_0_requested: u64,
amount_1_requested: u64,
) -> Result<()> {
let amount_0: u64;
let amount_1: u64;
let auth_bump: u8;
{
let mut pool_state = ctx.accounts.pool_state.load_mut()?;
amount_0 = amount_0_requested.min(pool_state.fund_fees_token_0);
amount_1 = amount_1_requested.min(pool_state.fund_fees_token_1);
pool_state.fund_fees_token_0 = pool_state.fund_fees_token_0.checked_sub(amount_0).unwrap();
pool_state.fund_fees_token_1 = pool_state.fund_fees_token_1.checked_sub(amount_1).unwrap();
auth_bump = pool_state.auth_bump;
pool_state.recent_epoch = Clock::get()?.epoch;
}
transfer_from_pool_vault_to_user(
ctx.accounts.authority.to_account_info(),
ctx.accounts.token_0_vault.to_account_info(),
ctx.accounts.recipient_token_0_account.to_account_info(),
ctx.accounts.vault_0_mint.to_account_info(),
if ctx.accounts.vault_0_mint.to_account_info().owner == ctx.accounts.token_program.key {
ctx.accounts.token_program.to_account_info()
} else {
ctx.accounts.token_program_2022.to_account_info()
},
amount_0,
ctx.accounts.vault_0_mint.decimals,
&[&[crate::AUTH_SEED.as_bytes(), &[auth_bump]]],
)?;
transfer_from_pool_vault_to_user(
ctx.accounts.authority.to_account_info(),
ctx.accounts.token_1_vault.to_account_info(),
ctx.accounts.recipient_token_1_account.to_account_info(),
ctx.accounts.vault_1_mint.to_account_info(),
if ctx.accounts.vault_1_mint.to_account_info().owner == ctx.accounts.token_program.key {
ctx.accounts.token_program.to_account_info()
} else {
ctx.accounts.token_program_2022.to_account_info()
},
amount_1,
ctx.accounts.vault_1_mint.decimals,
&[&[crate::AUTH_SEED.as_bytes(), &[auth_bump]]],
)?;
Ok(())
}