Skip to main content

balancer_maths_rust/pools/reclamm/
reclamm_pool.rs

1use crate::common::errors::PoolError;
2use crate::common::pool_base::PoolBase;
3use crate::common::types::{Rounding, SwapKind, SwapParams};
4use crate::pools::reclamm::reclamm_data::ReClammState;
5use crate::pools::reclamm::reclamm_math::{
6    compute_current_virtual_balances, compute_in_given_out, compute_out_given_in,
7};
8use alloy_primitives::U256;
9
10/// ReClamm pool implementation
11pub struct ReClammPool {
12    re_clamm_state: ReClammState,
13}
14
15impl ReClammPool {
16    /// Create a new ReClamm pool
17    pub fn new(pool_state: ReClammState) -> Self {
18        Self {
19            re_clamm_state: pool_state,
20        }
21    }
22
23    /// Compute current virtual balances
24    fn _compute_current_virtual_balances(&self, balances_scaled_18: &[U256]) -> (U256, U256, bool) {
25        compute_current_virtual_balances(
26            &self.re_clamm_state.mutable.current_timestamp,
27            balances_scaled_18,
28            &self.re_clamm_state.mutable.last_virtual_balances[0],
29            &self.re_clamm_state.mutable.last_virtual_balances[1],
30            &self.re_clamm_state.mutable.daily_price_shift_base,
31            &self.re_clamm_state.mutable.last_timestamp,
32            &self.re_clamm_state.mutable.centeredness_margin,
33            &self.re_clamm_state.mutable.start_fourth_root_price_ratio,
34            &self.re_clamm_state.mutable.end_fourth_root_price_ratio,
35            &self.re_clamm_state.mutable.price_ratio_update_start_time,
36            &self.re_clamm_state.mutable.price_ratio_update_end_time,
37        )
38    }
39}
40
41impl PoolBase for ReClammPool {
42    fn get_maximum_invariant_ratio(&self) -> U256 {
43        // The invariant ratio bounds are required by `IBasePool`, but are unused in this pool type, as liquidity can
44        // only be added or removed proportionally.
45        U256::ZERO
46    }
47
48    fn get_minimum_invariant_ratio(&self) -> U256 {
49        // The invariant ratio bounds are required by `IBasePool`, but are unused in this pool type, as liquidity can
50        // only be added or removed proportionally.
51        U256::ZERO
52    }
53
54    fn on_swap(&self, swap_params: &SwapParams) -> Result<U256, PoolError> {
55        let compute_result =
56            self._compute_current_virtual_balances(&swap_params.balances_live_scaled_18);
57
58        match swap_params.swap_kind {
59            SwapKind::GivenIn => {
60                let amount_calculated_scaled_18 = compute_out_given_in(
61                    &swap_params.balances_live_scaled_18,
62                    &compute_result.0, // current_virtual_balance_a
63                    &compute_result.1, // current_virtual_balance_b
64                    swap_params.token_in_index,
65                    swap_params.token_out_index,
66                    &swap_params.amount_scaled_18,
67                )
68                .map_err(|_| PoolError::InvalidSwapParameters)?;
69
70                Ok(amount_calculated_scaled_18)
71            }
72            SwapKind::GivenOut => {
73                let amount_calculated_scaled_18 = compute_in_given_out(
74                    &swap_params.balances_live_scaled_18,
75                    &compute_result.0, // current_virtual_balance_a
76                    &compute_result.1, // current_virtual_balance_b
77                    swap_params.token_in_index,
78                    swap_params.token_out_index,
79                    &swap_params.amount_scaled_18,
80                )
81                .map_err(|_| PoolError::InvalidSwapParameters)?;
82
83                Ok(amount_calculated_scaled_18)
84            }
85        }
86    }
87
88    fn compute_invariant(
89        &self,
90        _balances_live_scaled18: &[U256],
91        _rounding: Rounding,
92    ) -> Result<U256, PoolError> {
93        // Only needed for unbalanced liquidity and thats not possible in this pool
94        Ok(U256::ZERO)
95    }
96
97    fn compute_balance(
98        &self,
99        _balances_live_scaled18: &[U256],
100        _token_in_index: usize,
101        _invariant_ratio: &U256,
102    ) -> Result<U256, PoolError> {
103        // Only needed for unbalanced liquidity and thats not possible in this pool
104        Ok(U256::ZERO)
105    }
106}