balancer_maths_rust/pools/stable/
stable_pool.rs1use crate::common::errors::PoolError;
2use crate::common::maths::mul_up_fixed;
3use crate::common::pool_base::PoolBase;
4use crate::common::types::{Rounding, SwapKind, SwapParams};
5use crate::pools::stable::stable_data::StableMutable;
6use crate::pools::stable::stable_math::{
7 compute_balance, compute_in_given_exact_out, compute_invariant, compute_out_given_exact_in,
8 _MAX_INVARIANT_RATIO, _MIN_INVARIANT_RATIO,
9};
10use alloy_primitives::U256;
11
12pub struct StablePool {
14 pub amp: U256,
15}
16
17impl StablePool {
18 pub fn new(pool_state: StableMutable) -> Self {
20 Self {
21 amp: pool_state.amp,
22 }
23 }
24}
25
26impl PoolBase for StablePool {
27 fn get_maximum_invariant_ratio(&self) -> U256 {
28 U256::from(_MAX_INVARIANT_RATIO)
29 }
30
31 fn get_minimum_invariant_ratio(&self) -> U256 {
32 U256::from(_MIN_INVARIANT_RATIO)
33 }
34
35 fn on_swap(&self, swap_params: &SwapParams) -> Result<U256, PoolError> {
36 let invariant = compute_invariant(&self.amp, &swap_params.balances_live_scaled_18)?;
37
38 let result = match swap_params.swap_kind {
39 SwapKind::GivenIn => compute_out_given_exact_in(
40 &self.amp,
41 &swap_params.balances_live_scaled_18,
42 swap_params.token_in_index,
43 swap_params.token_out_index,
44 &swap_params.amount_scaled_18,
45 &invariant,
46 )?,
47 SwapKind::GivenOut => compute_in_given_exact_out(
48 &self.amp,
49 &swap_params.balances_live_scaled_18,
50 swap_params.token_in_index,
51 swap_params.token_out_index,
52 &swap_params.amount_scaled_18,
53 &invariant,
54 )?,
55 };
56
57 Ok(result)
58 }
59
60 fn compute_invariant(
61 &self,
62 balances_live_scaled18: &[U256],
63 rounding: Rounding,
64 ) -> Result<U256, PoolError> {
65 let mut invariant = compute_invariant(&self.amp, balances_live_scaled18)?;
66
67 if invariant > U256::ZERO {
68 match rounding {
69 Rounding::RoundDown => {}
70 Rounding::RoundUp => {
71 invariant += U256::ONE;
72 }
73 }
74 }
75
76 Ok(invariant)
77 }
78
79 fn compute_balance(
80 &self,
81 balances_live_scaled18: &[U256],
82 token_in_index: usize,
83 invariant_ratio: &U256,
84 ) -> Result<U256, PoolError> {
85 let invariant = self.compute_invariant(balances_live_scaled18, Rounding::RoundUp)?;
86 let scaled_invariant = mul_up_fixed(&invariant, invariant_ratio)?;
87
88 compute_balance(
89 &self.amp,
90 balances_live_scaled18,
91 &scaled_invariant,
92 token_in_index,
93 )
94 }
95}