Math Calculation

Bonding Curve Progress

bondingCurveProgress = poolState.quoteReserve / poolConfigState.migration_quote_threshold

Question: Is there any way to infer poolState.quoteReserve from nextSqrtPrice that can be fetched from CPI Logs?

You can also refer to this and replace sqrt_migration_price with next_sqrt_price:

https://github.com/MeteoraAg/dynamic-bonding-curve/blob/23998ff41ba4a1dbb207da448096be16fda30fef/programs/dynamic-bonding-curve/src/params/liquidity_distribution.rs#L36

pub fn get_quote_token_from_sqrt_price(next_sqrt_price: u128, config: &PoolConfig) -> Result<U256> {
    let mut total_amount = U256::ZERO;
    for i in 0..MAX_CURVE_POINT {
        let lower_sqrt_price = if i == 0 {
            config.sqrt_start_price
        } else {
            config.curve[i - 1].sqrt_price
        };
        if next_sqrt_price > lower_sqrt_price {
            let upper_sqrt_price = if next_sqrt_price < config.curve[i + 1].sqrt_price {
                next_sqrt_price
            } else {
                config.curve[i + 1].sqrt_price
            };
            let max_amount_in = get_delta_amount_quote_unsigned_256(
                lower_sqrt_price,
                upper_sqrt_price,
                config.curve[i].liquidity,
                Rounding::Up,
            )?;

            total_amount = total_amount.safe_add(max_amount_in)?;
        }
    }

    Ok(total_amount)
}

Total Fees

totalFees = baseFees + dynamicFees

Base Fees

Base Fees includes Fee Scheduler and Rate Limiter. BaseFeeMode can only be enums 0, 1, or 2.

Fee Scheduler:

type base_fee = {
    cliff_fee_numerator: BN
    first_factor: number // numberOfPeriod
    second_factor: BN // periodFrequency
    third_factor: BN // reductionFactor
    base_fee_mode: BaseFeeMode // 0 or 1
}
when in Linear (0) baseFeeMode: 
fee = cliff_fee_numerator - (period * reduction_factor)

when in Exponential (1) baseFeeMode:
fee = cliff_fee_numerator * (1 - reduction_factor/10_000)^period

Rate Limiter:

type base_fee = {
    cliff_fee_numerator: BN
    first_factor: number //feeIncrementBps
    second_factor: BN // maxLimiterDuration
    third_factor: BN // referenceAmount
    base_fee_mode: BaseFeeMode // 2
}
when in RateLimiter (2) baseFeeMode:

For input_amount ≤ reference_amount:
fee = input_amount * cliff_fee_numerator

For input_amount > reference_amount:

-> Let x0 = reference_amount
-> Let c = cliff_fee_numerator
-> Let i = fee_increment
-> Let a = (input_amount - reference_amount) / reference_amount
-> Let b = (input_amount - reference_amount) % reference_amount

If a < max_index:
fee = x0 * (c + c*a + i*a*(a+1)/2) + b * (c + i*(a+1))

If a ≥ max_index:
fee = x0 * (c + c*max_index + i*max_index*(max_index+1)/2) + (d*x0 + b) * MAX_FEE

where:
-> d = a - max_index
-> MAX_FEE is the maximum allowed fee (99%)

NOTE: the Fee Scheduler and Rate Limiter depends on the poolState.activationType.