use serde::{Deserialize, Serialize};
use std::collections::HashSet;
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct DlmmFeeParams {
pub base_factor: f64,
pub bin_step_bps: f64,
pub variable_fee_control: f64,
pub max_fee_rate: f64,
}
impl DlmmFeeParams {
#[inline]
fn s_dec(&self) -> f64 {
self.bin_step_bps / 10_000.0
}
pub fn base_fee_rate(&self) -> f64 {
self.base_factor * self.s_dec()
}
pub fn variable_fee_rate(&self, volatility_accumulator: f64) -> f64 {
let s = self.s_dec();
self.variable_fee_control * (volatility_accumulator * s).powi(2)
}
pub fn total_fee_rate(&self, va: f64) -> f64 {
let cap = self.max_fee_rate.max(0.0);
(self.base_fee_rate() + self.variable_fee_rate(va)).min(cap)
}
pub fn min_price_sell_x_for_y(spot_price: f64, max_price_impact_bps: f64) -> f64 {
spot_price * 10_000.0 / (10_000.0 - max_price_impact_bps)
}
pub fn min_price_sell_y_for_x(spot_price: f64, max_price_impact_bps: f64) -> f64 {
spot_price * (10_000.0 - max_price_impact_bps) / 10_000.0
}
}
#[derive(Default, Clone, Debug)]
pub struct LaunchPhasePolicy {
pub allowlist: HashSet<String>,
pub tau_start_pct: f64,
pub tau_end_pct: f64,
pub ramp_secs: f64,
}
impl LaunchPhasePolicy {
#[allow(dead_code)] pub fn is_allowed(&self, addr: &str) -> bool {
self.allowlist.contains(addr)
}
pub fn tau(&self, seconds_since_launch: f64) -> f64 {
if seconds_since_launch <= 0.0 {
return self.tau_start_pct.max(self.tau_end_pct);
}
if seconds_since_launch >= self.ramp_secs {
return self.tau_end_pct;
}
let t = seconds_since_launch / self.ramp_secs;
self.tau_start_pct + t * (self.tau_end_pct - self.tau_start_pct)
}
}