solana_central/meteora/calculate_dynamic_fee_numerator.rs
1use crate::types::meteora_dammv2_pool::MeteoraDammV2Pool;
2use std::cmp;
3
4impl MeteoraDammV2Pool {
5 /// Calculate the dynamic fee numerator based on volatility
6 ///
7 /// The dynamic fee increases with volatility according to the formula:
8 /// `((volatility_accumulator * bin_step)^2 * variable_fee_control + 99_999_999_999) / 100_000_000_000`
9 ///
10 /// Returns 0 if dynamic fees are not initialized or variable fee control is disabled.
11 pub fn calculate_dynamic_fee_numerator(&self) -> u64 {
12 // If dynamic fee is not initialized or variable fee control is 0, return 0
13 if self.initialized == 0 || self.variable_fee_control == 0 {
14 return 0;
15 }
16
17 // dynamic_fee_numerator = ((volatility_accumulator * bin_step)^2 * variable_fee_control + 99_999_999_999) / 100_000_000_000
18 let volatility_bin_product = self.volatility_accumulator * self.bin_step as u128;
19 let square_vfa_bin = volatility_bin_product * volatility_bin_product;
20
21 // Handle potential overflow by using saturating operations
22 let v_fee = square_vfa_bin.saturating_mul(self.variable_fee_control as u128);
23 let dynamic_fee_numerator = (v_fee + 99_999_999_999) / 100_000_000_000;
24
25 // Convert to u64, capping at max value if necessary
26 cmp::min(dynamic_fee_numerator, u64::MAX as u128) as u64
27 }
28}