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}