Skip to main content

balancer_maths_rust/pools/fixed_price_lbp/
fixed_price_lbp_pool.rs

1//! FixedPriceLBP pool implementation
2
3use crate::common::errors::PoolError;
4use crate::common::maths::{div_down_fixed, mul_down_fixed, mul_up_fixed};
5use crate::common::pool_base::PoolBase;
6use crate::common::types::{Rounding, SwapKind, SwapParams};
7use crate::pools::fixed_price_lbp::fixed_price_lbp_data::FixedPriceLBPState;
8use alloy_primitives::U256;
9
10/// FixedPriceLBP pool implementation
11pub struct FixedPriceLBPPool {
12    project_token_index: usize,
13    reserve_token_index: usize,
14    project_token_rate: U256,
15    is_swap_enabled: bool,
16}
17
18impl PoolBase for FixedPriceLBPPool {
19    fn on_swap(&self, swap_params: &SwapParams) -> Result<U256, PoolError> {
20        if !self.is_swap_enabled {
21            return Err(PoolError::InvalidSwapParameters);
22        }
23
24        if swap_params.token_in_index == self.project_token_index {
25            return Err(PoolError::InvalidSwapParameters);
26        }
27
28        match swap_params.swap_kind {
29            SwapKind::GivenIn => {
30                // Reserve tokens in, project tokens out: amountOut = amountIn / rate
31                div_down_fixed(&swap_params.amount_scaled_18, &self.project_token_rate)
32            }
33            SwapKind::GivenOut => {
34                // ExactOut: amountIn = amountOut * rate
35                mul_up_fixed(&swap_params.amount_scaled_18, &self.project_token_rate)
36            }
37        }
38    }
39
40    fn compute_invariant(
41        &self,
42        balances_live_scaled_18: &[U256],
43        rounding: Rounding,
44    ) -> Result<U256, PoolError> {
45        // inv = projectBalance * rate + reserveBalance
46        let project_token_value = match rounding {
47            Rounding::RoundUp => mul_up_fixed(
48                &balances_live_scaled_18[self.project_token_index],
49                &self.project_token_rate,
50            )?,
51            Rounding::RoundDown => mul_down_fixed(
52                &balances_live_scaled_18[self.project_token_index],
53                &self.project_token_rate,
54            )?,
55        };
56
57        Ok(project_token_value + balances_live_scaled_18[self.reserve_token_index])
58    }
59
60    fn compute_balance(
61        &self,
62        _balances_live_scaled_18: &[U256],
63        _token_in_index: usize,
64        _invariant_ratio: &U256,
65    ) -> Result<U256, PoolError> {
66        Err(PoolError::Custom("UnsupportedOperation".to_string()))
67    }
68
69    fn get_maximum_invariant_ratio(&self) -> U256 {
70        U256::MAX
71    }
72
73    fn get_minimum_invariant_ratio(&self) -> U256 {
74        U256::ZERO
75    }
76}
77
78impl From<FixedPriceLBPState> for FixedPriceLBPPool {
79    fn from(state: FixedPriceLBPState) -> Self {
80        Self {
81            project_token_index: state.immutable.project_token_index,
82            reserve_token_index: state.immutable.reserve_token_index,
83            project_token_rate: state.immutable.project_token_rate,
84            is_swap_enabled: state.mutable.is_swap_enabled,
85        }
86    }
87}