The Fee Module is the core fee calculation engine of the Ferra DAMM protocol. It combines two independent fee mechanisms — Fee Scheduler (time-based base fee) and Dynamic Fee (volatility-based variable fee) — to determine the total fee for each swap.
Validation: reduction_factor must be > 0 and < 10000 (basis_point_max)
get_current_number_period
Calculates which period we are currently in.
Logic:
Before activation: returns number_of_period (maximum penalty = cliff fee)
After activation: period = (elapsed_time + period_frequency - 1) / period_frequency
Capped at number_of_period
Fee Scheduler Query Functions
Function
Returns
Description
is_fee_scheduler_enabled(params)
bool
Whether fee scheduler is active
get_cliff_fee_numerator(params)
u64
Initial cliff fee
get_scheduler_number_of_period(params)
u16
Total periods
get_scheduler_period_frequency(params)
u64
Period duration (ms)
get_scheduler_reduction_factor(params)
u64
Reduction per period
get_activation_timestamp(params)
u64
Activation time (ms)
get_fee_scheduler_mode(params)
u8
0 = Linear, 1 = Exponential
Dynamic Fee (Variable Fee)
The Dynamic Fee mechanism automatically adjusts fees based on real-time market volatility. During high volatility (large price movements), fees increase to protect LPs. During calm markets, fees decay back to zero.
How It Works
Each swap updates the volatility accumulator based on price movement
Variable fee is calculated from the volatility accumulator
After filter_period, the reference volatility decays by reduction_factor
After decay_period, volatility reference resets to zero
get_variable_fee
Calculates the current variable fee from volatility state.
public fun get_delta_id(
params: &PairParameters,
active_id: I32,
): u32
public fun validate_dynamic_fee_parameters(
filter_period: u16,
decay_period: u16,
reduction_factor: u16,
variable_fee_control: u32,
max_volatility_accumulator: u32,
)
public fun validate_base_fee(
fee_rate: u64,
fee_scheduler_mode: u8,
cliff_fee_numerator: u64,
number_of_period: u16,
period_frequency: u64,
reduction_factor: u64,
)
public fun get_fee_amount_inclusive(
amount_with_fees: u64,
total_fee_rate: u64,
): u64
public fun get_fee_amount_exclusive(
amount_without_fees: u64,
total_fee_rate: u64,
): u64
public fun get_composition_fee(
amount_with_fees: u64,
total_fee_rate: u64,
): u64
public fun get_protocol_fee_amount(
fee_amount: u64,
protocol_share: u64,
): u64
// Get total fee rate at current time
let total_fee = pool::get_total_fee_rate<USDC, TOKEN>(&pool, current_timestamp);
// Get pair parameters for detailed inspection
let params = pool::get_pair_parameters<USDC, TOKEN>(&pool);
let base_fee = pair_parameter_helper::get_base_fee(¶ms, current_timestamp);
let variable_fee = pair_parameter_helper::get_variable_fee(¶ms, tick_spacing);
let vol_acc = pair_parameter_helper::get_volatility_accumulator(¶ms);