use anchor_lang::Result;
use fix::prelude::*;
use crate::error::CoreError::InvalidFees;
use crate::fee_controller::FeeExtract;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct LstSwapConfig {
pub fee: UFix64<N4>,
}
impl LstSwapConfig {
pub fn new(serialized_fee: UFixValue64) -> Result<LstSwapConfig> {
let fee = serialized_fee.try_into()?;
Self::validate_fee(fee)?;
Ok(LstSwapConfig { fee })
}
pub fn apply_fee<Exp>(&self, amount: UFix64<Exp>) -> Result<FeeExtract<Exp>> {
FeeExtract::new(self.fee, amount)
}
fn validate_fee(fee: UFix64<N4>) -> Result<()> {
if fee > UFix64::zero() && fee < UFix64::one() {
Ok(())
} else {
Err(InvalidFees.into())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn apply_fee() -> Result<()> {
let config = LstSwapConfig::new(UFixValue64::new(50, -4))?;
let amount = UFix64::<N9>::new(1_000_000_000);
let result = config.apply_fee(amount)?;
assert_eq!(result.fees_extracted, UFix64::new(5_000_000));
assert_eq!(result.amount_remaining, UFix64::new(995_000_000));
Ok(())
}
#[test]
fn reject_out_of_range_fee() {
let zero = LstSwapConfig::new(UFixValue64::new(0, -4));
let one = LstSwapConfig::new(UFixValue64::new(10000, -4));
assert!(zero.is_err());
assert!(one.is_err());
}
#[test]
fn reject_wrong_exp() {
let result = LstSwapConfig::new(UFixValue64::new(200, -2));
assert!(result.is_err());
}
}