Skip to content

Commit 049a483

Browse files
committed
reduced duplicated code
1 parent aa9f2f7 commit 049a483

11 files changed

+377
-405
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

programs/dynamic-fee-sharing/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static_assertions = "1.1.0"
2727
const-crypto = "0.3.0"
2828
damm-v2 = { path = "../../libs/damm-v2" }
2929
dynamic-bonding-curve = { path = "../../libs/dynamic-bonding-curve" }
30+
anchor_patches = { git = "https://github.com/MeteoraAg/anchor-patches", rev = "24d5113905983a7b89496afe67c9067293b8bd99" }
3031

3132
[dev-dependencies]
3233
proptest = "1.2.0"

programs/dynamic-fee-sharing/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@ pub enum FeeVaultError {
3737

3838
#[msg("Invalid signer")]
3939
InvalidSigner,
40+
41+
#[msg("Invalid funding type")]
42+
InvalidFundingType,
4043
}
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
use crate::{
2+
error::FeeVaultError,
3+
event::EvtFundFee,
4+
math::SafeMath,
5+
state::{FeeVault, FundingType},
6+
};
7+
use anchor_lang::prelude::*;
8+
use anchor_spl::token_interface::TokenAccount;
9+
use damm_v2::accounts::Pool;
10+
use dynamic_bonding_curve::accounts::{PoolConfig, VirtualPool};
11+
12+
#[allow(clippy::too_many_arguments)]
13+
pub fn handle_funding_fee<'c: 'info, 'info>(
14+
signer: &Pubkey,
15+
fee_vault_account: &AccountLoader<'info, FeeVault>,
16+
pool: &'info AccountInfo<'info>,
17+
pool_authority: &AccountInfo<'info>,
18+
token_b_account: &mut Box<InterfaceAccount<'info, TokenAccount>>,
19+
token_b_vault: &AccountInfo<'info>,
20+
token_b_mint: &AccountInfo<'info>,
21+
token_b_program: &AccountInfo<'info>,
22+
event_authority: &AccountInfo<'info>,
23+
program: &AccountInfo<'info>,
24+
funding_type: FundingType,
25+
token_a_account: Option<&AccountInfo<'info>>,
26+
token_a_vault: Option<&AccountInfo<'info>>,
27+
token_a_mint: Option<&AccountInfo<'info>>,
28+
token_a_program: Option<&AccountInfo<'info>>,
29+
position: Option<&AccountInfo<'info>>,
30+
position_nft_account: Option<&AccountInfo<'info>>,
31+
config: Option<&'c AccountInfo<'info>>,
32+
) -> Result<()> {
33+
let fee_vault = fee_vault_account.load()?;
34+
35+
require!(
36+
fee_vault.is_share_holder(signer),
37+
FeeVaultError::InvalidSigner
38+
);
39+
40+
require!(
41+
fee_vault.token_vault.eq(&token_b_account.key())
42+
&& fee_vault.token_mint.eq(&token_b_mint.key()),
43+
FeeVaultError::InvalidFeeVault
44+
);
45+
46+
// support fee vault type is pda account
47+
require!(
48+
fee_vault.fee_vault_type == 1,
49+
FeeVaultError::InvalidFeeVault
50+
);
51+
52+
let signer_seeds = fee_vault_seeds!(
53+
fee_vault.base,
54+
fee_vault.token_mint,
55+
fee_vault.fee_vault_bump
56+
);
57+
58+
let before_token_vault_balance = token_b_account.amount;
59+
60+
match funding_type {
61+
FundingType::ClaimDammV2 => {
62+
let pool_state: AccountLoader<'_, Pool> = AccountLoader::try_from(&pool)?;
63+
let pool_state = pool_state.load()?;
64+
// support collect fee mode is 1 (only token B)
65+
require!(
66+
pool_state.collect_fee_mode == 1,
67+
FeeVaultError::InvalidDammv2Pool
68+
);
69+
70+
damm_v2::cpi::claim_position_fee(CpiContext::new_with_signer(
71+
program.to_account_info(),
72+
damm_v2::cpi::accounts::ClaimPositionFee {
73+
pool_authority: pool_authority.to_account_info(),
74+
pool: pool.to_account_info(),
75+
position: position.unwrap().to_account_info(),
76+
token_a_account: token_a_account.unwrap().to_account_info(),
77+
token_b_account: token_b_account.to_account_info(),
78+
token_a_vault: token_a_vault.unwrap().to_account_info(),
79+
token_b_vault: token_b_vault.to_account_info(),
80+
token_a_program: token_a_program.unwrap().to_account_info(),
81+
token_b_program: token_b_program.to_account_info(),
82+
token_a_mint: token_a_mint.unwrap().to_account_info(),
83+
token_b_mint: token_b_mint.to_account_info(),
84+
position_nft_account: position_nft_account.unwrap().to_account_info(),
85+
owner: fee_vault_account.to_account_info(),
86+
event_authority: event_authority.to_account_info(),
87+
program: program.to_account_info(),
88+
},
89+
&[signer_seeds],
90+
))?;
91+
}
92+
FundingType::ClaimDbcCreatorSurplus => {
93+
let virtual_pool_state: AccountLoader<'_, VirtualPool> =
94+
AccountLoader::try_from(&pool)?;
95+
let virtual_pool_state = virtual_pool_state.load()?;
96+
97+
// creator surplus has been withdraw
98+
if virtual_pool_state.is_creator_withdraw_surplus == 1 {
99+
return Ok(());
100+
}
101+
102+
drop(virtual_pool_state);
103+
104+
dynamic_bonding_curve::cpi::creator_withdraw_surplus(CpiContext::new_with_signer(
105+
program.to_account_info(),
106+
dynamic_bonding_curve::cpi::accounts::CreatorWithdrawSurplus {
107+
pool_authority: pool_authority.to_account_info(),
108+
config: config.unwrap().to_account_info(),
109+
virtual_pool: pool.to_account_info(),
110+
token_quote_account: token_b_account.to_account_info(),
111+
quote_vault: token_b_vault.to_account_info(),
112+
quote_mint: token_b_mint.to_account_info(),
113+
creator: fee_vault_account.to_account_info(),
114+
token_quote_program: token_b_program.to_account_info(),
115+
event_authority: event_authority.to_account_info(),
116+
program: program.to_account_info(),
117+
},
118+
&[signer_seeds],
119+
))?;
120+
}
121+
FundingType::ClaimDbcCreatorTradingFee => {
122+
let config_state: AccountLoader<'_, PoolConfig> =
123+
AccountLoader::try_from(&config.unwrap())?;
124+
let config_state = config_state.load()?;
125+
// support collect fee mode is 0 (only quote token)
126+
require!(
127+
config_state.collect_fee_mode == 0,
128+
FeeVaultError::InvalidDbcPool
129+
);
130+
131+
dynamic_bonding_curve::cpi::claim_creator_trading_fee(
132+
CpiContext::new_with_signer(
133+
program.to_account_info(),
134+
dynamic_bonding_curve::cpi::accounts::ClaimCreatorTradingFee {
135+
pool_authority: pool_authority.to_account_info(),
136+
pool: pool.to_account_info(),
137+
token_a_account: token_a_account.unwrap().to_account_info(),
138+
token_b_account: token_b_account.to_account_info(),
139+
base_vault: token_a_vault.unwrap().to_account_info(),
140+
quote_vault: token_b_vault.to_account_info(),
141+
base_mint: token_a_mint.unwrap().to_account_info(),
142+
quote_mint: token_b_mint.to_account_info(),
143+
creator: fee_vault_account.to_account_info(),
144+
token_base_program: token_a_program.unwrap().to_account_info(),
145+
token_quote_program: token_b_program.to_account_info(),
146+
event_authority: event_authority.to_account_info(),
147+
program: program.to_account_info(),
148+
},
149+
&[signer_seeds],
150+
),
151+
0, // max base amount,
152+
u64::MAX, // max quote amount,
153+
)?;
154+
}
155+
FundingType::ClaimDbcPartnerSurplus => {
156+
let virtual_pool_state: AccountLoader<'_, VirtualPool> =
157+
AccountLoader::try_from(&pool)?;
158+
let virtual_pool_state = virtual_pool_state.load()?;
159+
160+
// creator surplus has been withdraw
161+
if virtual_pool_state.is_partner_withdraw_surplus == 1 {
162+
return Ok(());
163+
}
164+
165+
drop(virtual_pool_state);
166+
167+
dynamic_bonding_curve::cpi::partner_withdraw_surplus(CpiContext::new_with_signer(
168+
program.to_account_info(),
169+
dynamic_bonding_curve::cpi::accounts::PartnerWithdrawSurplus {
170+
pool_authority: pool_authority.to_account_info(),
171+
config: config.unwrap().to_account_info(),
172+
virtual_pool: pool.to_account_info(),
173+
token_quote_account: token_b_account.to_account_info(),
174+
quote_vault: token_b_vault.to_account_info(),
175+
quote_mint: token_b_mint.to_account_info(),
176+
fee_claimer: fee_vault_account.to_account_info(),
177+
token_quote_program: token_b_program.to_account_info(),
178+
event_authority: event_authority.to_account_info(),
179+
program: program.to_account_info(),
180+
},
181+
&[signer_seeds],
182+
))?;
183+
}
184+
FundingType::ClaimDbcPartnerTradingFee => {
185+
let config_state: AccountLoader<'_, PoolConfig> =
186+
AccountLoader::try_from(&config.unwrap())?;
187+
let config_state = config_state.load()?;
188+
// support collect fee mode is 0 (only quote token)
189+
require!(
190+
config_state.collect_fee_mode == 0,
191+
FeeVaultError::InvalidDbcPool
192+
);
193+
194+
dynamic_bonding_curve::cpi::claim_trading_fee(
195+
CpiContext::new_with_signer(
196+
program.to_account_info(),
197+
dynamic_bonding_curve::cpi::accounts::ClaimTradingFee {
198+
pool_authority: pool_authority.to_account_info(),
199+
config: config.unwrap().to_account_info(),
200+
pool: pool.to_account_info(),
201+
token_a_account: token_a_account.unwrap().to_account_info(),
202+
token_b_account: token_b_account.to_account_info(),
203+
base_vault: token_a_vault.unwrap().to_account_info(),
204+
quote_vault: token_b_vault.to_account_info(),
205+
base_mint: token_a_mint.unwrap().to_account_info(),
206+
quote_mint: token_b_mint.to_account_info(),
207+
fee_claimer: fee_vault_account.to_account_info(),
208+
token_base_program: token_a_program.unwrap().to_account_info(),
209+
token_quote_program: token_b_program.to_account_info(),
210+
event_authority: event_authority.to_account_info(),
211+
program: program.to_account_info(),
212+
},
213+
&[signer_seeds],
214+
),
215+
0, // max_amount_a, fee only token b
216+
u64::MAX, // max_amount_b,
217+
)?;
218+
}
219+
_ => Err(FeeVaultError::InvalidFundingType)?,
220+
}
221+
222+
token_b_account.reload()?;
223+
224+
let after_token_vault_balance = token_b_account.amount;
225+
226+
let claimed_amount = after_token_vault_balance.safe_sub(before_token_vault_balance)?;
227+
228+
drop(fee_vault);
229+
230+
if claimed_amount > 0 {
231+
let mut fee_vault = fee_vault_account.load_mut()?;
232+
fee_vault.fund_fee(claimed_amount)?;
233+
234+
emit!(EvtFundFee {
235+
funding_type,
236+
fee_vault: fee_vault_account.key(),
237+
funder: pool.key(),
238+
funded_amount: claimed_amount,
239+
fee_per_share: fee_vault.fee_per_share,
240+
})
241+
}
242+
Ok(())
243+
}

0 commit comments

Comments
 (0)