From 872cb789c6314ecbc96e98be1eb447a10a780ba8 Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Fri, 5 Jul 2024 09:55:17 +0200 Subject: [PATCH 01/12] fix updating rates --- amm/contracts/stable_pool/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 38dbdb6..48b9b25 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -287,7 +287,7 @@ pub mod stable_pool { let current_time = self.env().block_timestamp(); let mut rate_changed = false; for rate in self.pool.token_rates.iter_mut() { - rate_changed = rate_changed || rate.update_rate(current_time); + rate_changed = rate_changed | rate.update_rate(current_time); } if rate_changed { Self::env().emit_event(RatesUpdated { @@ -718,7 +718,7 @@ pub mod stable_pool { let current_time = self.env().block_timestamp(); let mut rate_changed = false; for rate in self.pool.token_rates.iter_mut() { - rate_changed = rate_changed || rate.update_rate_no_cache(current_time); + rate_changed = rate_changed | rate.update_rate_no_cache(current_time); } if rate_changed { Self::env().emit_event(RatesUpdated { From 8d8983a882c7f2a3898ace0d55862386f2331c24 Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Fri, 5 Jul 2024 12:19:59 +0200 Subject: [PATCH 02/12] D calculation --- helpers/math.rs | 1 + helpers/stable_swap_math/mod.rs | 91 ++++++++++++--------------------- 2 files changed, 33 insertions(+), 59 deletions(-) diff --git a/helpers/math.rs b/helpers/math.rs index aad8abd..343c263 100644 --- a/helpers/math.rs +++ b/helpers/math.rs @@ -12,4 +12,5 @@ pub enum MathError { DivByZero(u8), MulOverflow(u8), SubUnderflow(u8), + Precision(u8), } diff --git a/helpers/stable_swap_math/mod.rs b/helpers/stable_swap_math/mod.rs index 767cfbf..6711d29 100644 --- a/helpers/stable_swap_math/mod.rs +++ b/helpers/stable_swap_math/mod.rs @@ -9,7 +9,7 @@ use primitive_types::U256; use fees::Fees; -/// Max number of iterations for curve computation using Newton–Raphson method +/// Max number of iterations performed in Newton–Raphson method const MAX_ITERATIONS: u8 = 255; fn amount_to_rated(amount: u128, scaled_rate: u128) -> Result { @@ -47,11 +47,10 @@ fn compute_d(amounts: &Vec, amp_coef: u128) -> Result { Ok(0.into()) } else { let n = amounts.len() as u32; + // n^n + let nn = n.checked_pow(n).ok_or(MathError::MulOverflow(1))?; // A * n^n - let ann: U256 = casted_mul( - amp_coef, - n.checked_pow(n).ok_or(MathError::MulOverflow(1))?.into(), - ); + let ann: U256 = casted_mul(amp_coef, nn.into()); // A * n^n * SUM{x_i} let ann_sum = ann .checked_mul(amount_sum) @@ -65,43 +64,37 @@ fn compute_d(amounts: &Vec, amp_coef: u128) -> Result { let mut d = amount_sum; // Computes next D unitl satisfying precision is reached for _ in 0..MAX_ITERATIONS { - let d_next = compute_d_next(d, n, amounts, ann_sum, ann_sub_one, n_add_one)?; - if d_next > d { - if d_next.checked_sub(d).ok_or(MathError::SubUnderflow(2))? <= 1.into() { - return Ok(d); - } - } else if d.checked_sub(d_next).ok_or(MathError::SubUnderflow(3))? <= 1.into() { + let d_next = compute_d_next(d, n, nn, amounts, ann_sum, ann_sub_one, n_add_one)?; + if d_next.abs_diff(d) <= 1.into() { return Ok(d); } d = d_next; } - Ok(d) + Err(MathError::Precision(1)) } } +/// Computes next step's approximation of D in Newton-Raphson method. +/// Returns d_next, or error if any math error occurred. fn compute_d_next( d_prev: U256, n: u32, + nn: u32, amounts: &Vec, ann_sum: U256, ann_sub_one: U256, n_add_one: u32, ) -> Result { let mut d_prod = d_prev; - // d_prod = ... * [d_prev / (x_(i) * n)] * ... - // where i in (0,n) - for amount in amounts { + // d_prod = d_prev^(n+1) / (n^n * Prod{amounts_i}) + for &amount in amounts { d_prod = d_prod .checked_mul(d_prev) .ok_or(MathError::MulOverflow(3))? - .checked_div( - amount - .checked_mul(n.into()) - .ok_or(MathError::MulOverflow(4))? - .into(), - ) + .checked_div(amount.into()) .ok_or(MathError::DivByZero(1))?; } + d_prod = d_prod.checked_div(nn.into()).unwrap(); let numerator = d_prev .checked_mul( d_prod @@ -128,7 +121,7 @@ fn compute_d_next( /// Returns new reserve of `y` tokens /// given new reserve of `x` tokens /// -/// NOTICE: it does not check if `token_x_id` != `token_y_id` and if tokens' `id`s are out of bounds +/// NOTE: it does not check if `token_x_id` != `token_y_id` and if tokens' `id`s are out of bounds fn compute_y( new_reserve_x: u128, reserves: &Vec, @@ -181,19 +174,14 @@ fn compute_y( .ok_or(MathError::AddOverflow(6))?; // d will be subtracted later let mut y_prev = d; - let mut y = y_prev; for _ in 0..MAX_ITERATIONS { - y = compute_y_next(y_prev, b, c, d)?; - if y > y_prev { - if y.checked_sub(y_prev).ok_or(MathError::SubUnderflow(4))? <= 1.into() { - return Ok(y.as_u128()); - } - } else if y_prev.checked_sub(y).ok_or(MathError::SubUnderflow(5))? <= 1.into() { - return Ok(y.as_u128()); + let y = compute_y_next(y_prev, b, c, d)?; + if y.abs_diff(y_prev) <= 1.into() { + return Ok(y.try_into().map_err(|_| MathError::CastOverflow(11))?); } y_prev = y; } - Ok(y.as_u128()) + Err(MathError::Precision(2)) } fn compute_y_next(y_prev: U256, b: U256, c: U256, d: U256) -> Result { @@ -382,15 +370,7 @@ fn compute_lp_amount_for_deposit( .ok_or(MathError::DivByZero(9))? .try_into() .map_err(|_| MathError::CastOverflow(2))?; - let difference = if ideal_reserve > new_reserves[i] { - ideal_reserve - .checked_sub(new_reserves[i]) - .ok_or(MathError::SubUnderflow(16))? - } else { - new_reserves[i] - .checked_sub(ideal_reserve) - .ok_or(MathError::SubUnderflow(17))? - }; + let difference = ideal_reserve.abs_diff(new_reserves[i]); let fee = _fees.normalized_trade_fee(n_coins, difference)?; new_reserves[i] = new_reserves[i] .checked_sub(fee) @@ -471,9 +451,7 @@ pub fn compute_amounts_given_lp( let mut amounts = Vec::with_capacity(reserves.len()); for &reserve in reserves { amounts.push( - U256::from(reserve) - .checked_mul(lp_amount.into()) - .ok_or(MathError::MulOverflow(21))? + casted_mul(reserve, lp_amount) .checked_div(pool_token_supply.into()) .ok_or(MathError::DivByZero(13))? .try_into() @@ -512,23 +490,16 @@ fn compute_lp_amount_for_withdraw( // Recalculate the invariant accounting for fees if let Some(_fees) = fees { for i in 0..new_reserves.len() { - let ideal_u128 = d_1 + let ideal_reserve: u128 = d_1 .checked_mul(old_reserves[i].into()) .ok_or(MathError::MulOverflow(22))? .checked_div(d_0) .ok_or(MathError::DivByZero(14))? - .as_u128(); - let difference = if ideal_u128 > new_reserves[i] { - ideal_u128 - .checked_sub(new_reserves[i]) - .ok_or(MathError::SubUnderflow(25))? - } else { - new_reserves[i] - .checked_sub(ideal_u128) - .ok_or(MathError::SubUnderflow(26))? - }; + .try_into() + .map_err(|_| MathError::CastOverflow(7))?; + let difference = ideal_reserve.abs_diff(new_reserves[i]); let fee = _fees.normalized_trade_fee(n_coins, difference)?; - // new_u128 is for calculation D2, the one with fee charged + // new_reserves is for calculation D2, the one with fee charged new_reserves[i] = new_reserves[i] .checked_sub(fee) .ok_or(MathError::SubUnderflow(27))?; @@ -545,14 +516,15 @@ fn compute_lp_amount_for_withdraw( .ok_or(MathError::MulOverflow(23))? .checked_div(d_0) .ok_or(MathError::DivByZero(15))? - .as_u128(); + .try_into() + .map_err(|_| MathError::CastOverflow(8))?; let diff_shares = U256::from(pool_token_supply) .checked_mul(d_0.checked_sub(d_1).ok_or(MathError::SubUnderflow(29))?) .ok_or(MathError::MulOverflow(24))? .checked_div(d_0) .ok_or(MathError::DivByZero(16))? - .as_u128(); - + .try_into() + .map_err(|_| MathError::CastOverflow(9))?; Ok(( burn_shares, burn_shares @@ -565,7 +537,8 @@ fn compute_lp_amount_for_withdraw( .ok_or(MathError::MulOverflow(25))? .checked_div(d_0) .ok_or(MathError::DivByZero(17))? - .as_u128(); + .try_into() + .map_err(|_| MathError::CastOverflow(10))?; Ok((burn_shares, 0)) } } From fc8c9108aabe940e5862f2e660637743c183feb8 Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Fri, 5 Jul 2024 12:22:13 +0200 Subject: [PATCH 03/12] rate update logic --- amm/contracts/stable_pool/token_rate.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/amm/contracts/stable_pool/token_rate.rs b/amm/contracts/stable_pool/token_rate.rs index 8b39cf3..d60d226 100644 --- a/amm/contracts/stable_pool/token_rate.rs +++ b/amm/contracts/stable_pool/token_rate.rs @@ -37,7 +37,9 @@ impl TokenRate { rate } - // To make sure the rate is up-to-date, the caller should call `update_rate` before calling this method. + /// Returns cached rate. + /// + /// NOTE: To make sure the rate is up-to-date, the caller should call `update_rate` before calling this method. pub fn get_rate(&self) -> u128 { match self { Self::Constant(rate) => *rate, @@ -45,17 +47,23 @@ impl TokenRate { } } + /// Update rate. + /// + /// Returns `true` if the rate was expired and value of the new rate is different than the previous. pub fn update_rate(&mut self, current_time: u64) -> bool { match self { Self::External(external) => external.update_rate(current_time), - _ => false, + Self::Constant(_) => false, } } + /// Update rate without expiry check. + /// + /// Returns `true` if value of the new rate is different than the previous. pub fn update_rate_no_cache(&mut self, current_time: u64) -> bool { match self { Self::External(external) => external.update_rate_no_cache(current_time), - _ => false, + Self::Constant(_) => false, } } } @@ -102,8 +110,9 @@ impl ExternalTokenRate { } fn update(&mut self, current_time: u64) -> bool { + let old_rate = self.cached_token_rate; self.cached_token_rate = Self::query_rate(self.token_rate_contract); self.last_token_rate_update_ts = current_time; - true + old_rate != self.cached_token_rate } } From c5b53a9710250276ee7bd78808cbdbb757479080 Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Fri, 5 Jul 2024 12:22:58 +0200 Subject: [PATCH 04/12] wip --- amm/contracts/stable_pool/lib.rs | 31 +++++++++++++------------------ amm/traits/stable_pool.rs | 12 ++++++------ 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 48b9b25..274236d 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -300,9 +300,10 @@ pub mod stable_pool { self.pool.fee_receiver } - /// Scaled rates are rates multiplied by precision. They are assumed to fit in u128. - /// If TOKEN_TARGET_DECIMALS is 18 and RATE_DECIMALS is 12, then rates not exceeding ~340282366 should fit. - /// That's because if precision <= 10^18 and rate <= 10^12 * 340282366, then rate * precision < 2^128. + // Scaled rates are rates multiplied by precision. They are assumed to fit in u128. + // If TOKEN_TARGET_DECIMALS is 18 and RATE_DECIMALS is 12, then rates not exceeding ~340282366 should fit. + // That's because if precision <= 10^18 and rate <= 10^12 * 340282366, then rate * precision < 2^128. + // NOTE: Rates should be updated prior ro calling this function fn get_scaled_rates(&self) -> Result, MathError> { self.pool .token_rates @@ -344,7 +345,8 @@ pub mod stable_pool { let token_out_id = self.token_id(token_out)?; Ok((token_in_id, token_out_id)) } - + /// Calculates lpt equivalent of the protocol fee and mints it to the `fee_to` if one is set. + /// NOTE: Rates should be updated prior ro calling this function fn mint_protocol_fee(&mut self, fee: u128, token_id: usize) -> Result<(), StablePoolError> { if let Some(fee_to) = self.fee_to() { let protocol_fee = self.pool.fees.protocol_trade_fee(fee)?; @@ -394,13 +396,6 @@ pub mod stable_pool { Ok(()) } - /// This method is for internal use only - /// - calculates token_out amount - /// - calculates swap fee - /// - mints protocol fee - /// - updates reserves - /// It assumes that rates have been updated. - /// Returns (token_out_amount, swap_fee) fn _swap_exact_in( &mut self, token_in: AccountId, @@ -460,13 +455,6 @@ pub mod stable_pool { Ok((token_out_amount, fee)) } - /// This method is for internal use only - /// - calculates token_in amount - /// - calculates swap fee - /// - mints protocol fee - /// - updates reserves - /// It assumes that rates have been updated. - /// Returns (token_in_amount, swap_fee) fn _swap_exact_out( &mut self, token_in: AccountId, @@ -533,6 +521,13 @@ pub mod stable_pool { Ok((token_in_amount, fee)) } + /// Handles PSP22 token transfer, + /// + /// If `amount` is `Some(amount)`, transfer this amount of `token_id` + /// from the caller to this contract. + /// + /// If `amount` of `None`, calculate the difference between + /// this contract balance and recorded reserve of `token_id`. fn _transfer_in( &self, token_id: usize, diff --git a/amm/traits/stable_pool.rs b/amm/traits/stable_pool.rs index 4bac840..12e4e3f 100644 --- a/amm/traits/stable_pool.rs +++ b/amm/traits/stable_pool.rs @@ -29,9 +29,9 @@ pub trait StablePoolView { fn token_rates(&mut self) -> Vec; /// Calculate swap amount of token_out - /// given token_in amount + /// given token_in amount. /// Returns (amount_out, fee) - /// fee is applied to token_out + /// NOTE: fee is applied to token_out #[ink(message)] fn get_swap_amount_out( &mut self, @@ -96,7 +96,7 @@ pub trait StablePool { /// for this contract. /// Returns an error if the minted LP tokens amount is less /// than `min_share_amount`. - /// Returns (minted_shares, fee_part) + /// Returns (minted_share_amount, fee_part) #[ink(message)] fn add_liquidity( &mut self, @@ -118,7 +118,7 @@ pub trait StablePool { /// Burns LP tokens and withdraws underlying tokens in balanced amounts to `to` account. /// Fails if any of the amounts received is less than in `min_amounts`. - /// Returns ([amounts_by_tokens], fee_part) + /// Returns (amounts_out, fee_part) #[ink(message)] fn remove_liquidity_by_shares( &mut self, @@ -150,6 +150,7 @@ pub trait StablePool { /// for this contract. /// Returns an error if to get token_out_amount of token_out it is required /// to spend more than `max_token_in_amount` of token_in. + /// NOTE: Fee is applied to `token_out`. /// Returns (token_in_amount, fee_amount) #[ink(message)] fn swap_exact_out( @@ -162,9 +163,8 @@ pub trait StablePool { ) -> Result<(u128, u128), StablePoolError>; /// Swaps excess reserve balance of `token_in` to `token_out`. - /// /// Swapped tokens are transferred to the `to` account. - /// Returns (amount_out, fees) + /// Returns (token_out_amount, fee_amount) #[ink(message)] fn swap_received( &mut self, From 5443bb535e38a8e1c5c1069af373e263ed38c119 Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Fri, 5 Jul 2024 20:23:38 +0200 Subject: [PATCH 05/12] contract description --- amm/contracts/stable_pool/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 274236d..4ff9920 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -1,6 +1,14 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] mod token_rate; - +/// Stabelswap implementation based on the CurveFi stableswap model. +/// +/// This pool contract supports PSP22 tokens which value increases at some +/// on-chain discoverable rate in terms of some other token, e.g. AZERO x sAZERO. +/// The rate oracle contract must implement [`RateProvider`](trait@traits::RateProvider). +/// +/// IMPORTANT: +/// This stableswap implementation is meant for yield-bearing assets which adjusts +/// its total supply to try and maintain a stable price a.k.a. rebasing tokens. #[ink::contract] pub mod stable_pool { use crate::token_rate::TokenRate; From e33abce26761469f3dc5bc6e03f8727aa2663dc4 Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Fri, 5 Jul 2024 20:24:08 +0200 Subject: [PATCH 06/12] typo --- amm/contracts/stable_pool/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 4ff9920..be94792 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -7,7 +7,7 @@ mod token_rate; /// The rate oracle contract must implement [`RateProvider`](trait@traits::RateProvider). /// /// IMPORTANT: -/// This stableswap implementation is meant for yield-bearing assets which adjusts +/// This stableswap implementation is NOT meant for yield-bearing assets which adjusts /// its total supply to try and maintain a stable price a.k.a. rebasing tokens. #[ink::contract] pub mod stable_pool { From 73b7395c2a0d29854ff26779caf7fede5226a4da Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Mon, 8 Jul 2024 09:07:04 +0200 Subject: [PATCH 07/12] fix returned error --- helpers/stable_swap_math/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/stable_swap_math/mod.rs b/helpers/stable_swap_math/mod.rs index 6711d29..fae4070 100644 --- a/helpers/stable_swap_math/mod.rs +++ b/helpers/stable_swap_math/mod.rs @@ -482,7 +482,7 @@ fn compute_lp_amount_for_withdraw( .map(|(reserve, &amount)| { reserve .checked_sub(amount) - .ok_or(MathError::AddOverflow(14)) + .ok_or(MathError::SubUnderflow(14)) }) .collect::, MathError>>()?; let d_1 = compute_d(&new_reserves, amp_coef)?; From 29dbc270e3f5b5ff5e2446c2f435472f1d111abe Mon Sep 17 00:00:00 2001 From: Jan Kuczma <63134918+JanKuczma@users.noreply.github.com> Date: Mon, 8 Jul 2024 09:47:48 +0200 Subject: [PATCH 08/12] Update amm/contracts/stable_pool/lib.rs Co-authored-by: deuszx <95355183+deuszx@users.noreply.github.com> --- amm/contracts/stable_pool/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index be94792..71658b2 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] mod token_rate; -/// Stabelswap implementation based on the CurveFi stableswap model. +/// StableSwap implementation based on the CurveFi stableswap model. /// /// This pool contract supports PSP22 tokens which value increases at some /// on-chain discoverable rate in terms of some other token, e.g. AZERO x sAZERO. From cf57c2ae6f7316038fd86ecc50c8172c115e0b8b Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Mon, 8 Jul 2024 09:51:43 +0200 Subject: [PATCH 09/12] fix rate update: change order of elements --- amm/contracts/stable_pool/lib.rs | 16 ++++++++-------- amm/contracts/stable_pool/token_rate.rs | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 71658b2..339a5d1 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -1,11 +1,11 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] mod token_rate; -/// StableSwap implementation based on the CurveFi stableswap model. -/// +/// Stabelswap implementation based on the CurveFi stableswap model. +/// /// This pool contract supports PSP22 tokens which value increases at some /// on-chain discoverable rate in terms of some other token, e.g. AZERO x sAZERO. /// The rate oracle contract must implement [`RateProvider`](trait@traits::RateProvider). -/// +/// /// IMPORTANT: /// This stableswap implementation is NOT meant for yield-bearing assets which adjusts /// its total supply to try and maintain a stable price a.k.a. rebasing tokens. @@ -295,7 +295,7 @@ pub mod stable_pool { let current_time = self.env().block_timestamp(); let mut rate_changed = false; for rate in self.pool.token_rates.iter_mut() { - rate_changed = rate_changed | rate.update_rate(current_time); + rate_changed = rate.update_rate(current_time) || rate_changed; } if rate_changed { Self::env().emit_event(RatesUpdated { @@ -530,10 +530,10 @@ pub mod stable_pool { } /// Handles PSP22 token transfer, - /// - /// If `amount` is `Some(amount)`, transfer this amount of `token_id` + /// + /// If `amount` is `Some(amount)`, transfer this amount of `token_id` /// from the caller to this contract. - /// + /// /// If `amount` of `None`, calculate the difference between /// this contract balance and recorded reserve of `token_id`. fn _transfer_in( @@ -721,7 +721,7 @@ pub mod stable_pool { let current_time = self.env().block_timestamp(); let mut rate_changed = false; for rate in self.pool.token_rates.iter_mut() { - rate_changed = rate_changed | rate.update_rate_no_cache(current_time); + rate_changed = rate.update_rate_no_cache(current_time) || rate_changed; } if rate_changed { Self::env().emit_event(RatesUpdated { diff --git a/amm/contracts/stable_pool/token_rate.rs b/amm/contracts/stable_pool/token_rate.rs index d60d226..ae2bc18 100644 --- a/amm/contracts/stable_pool/token_rate.rs +++ b/amm/contracts/stable_pool/token_rate.rs @@ -38,7 +38,7 @@ impl TokenRate { } /// Returns cached rate. - /// + /// /// NOTE: To make sure the rate is up-to-date, the caller should call `update_rate` before calling this method. pub fn get_rate(&self) -> u128 { match self { @@ -48,7 +48,7 @@ impl TokenRate { } /// Update rate. - /// + /// /// Returns `true` if the rate was expired and value of the new rate is different than the previous. pub fn update_rate(&mut self, current_time: u64) -> bool { match self { @@ -58,7 +58,7 @@ impl TokenRate { } /// Update rate without expiry check. - /// + /// /// Returns `true` if value of the new rate is different than the previous. pub fn update_rate_no_cache(&mut self, current_time: u64) -> bool { match self { From c13c2b7f3dfcca1ba67fbe8aef38ad2949debb6f Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Mon, 8 Jul 2024 11:30:38 +0200 Subject: [PATCH 10/12] typo --- amm/contracts/stable_pool/lib.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 339a5d1..d0f9bb6 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -308,10 +308,11 @@ pub mod stable_pool { self.pool.fee_receiver } - // Scaled rates are rates multiplied by precision. They are assumed to fit in u128. - // If TOKEN_TARGET_DECIMALS is 18 and RATE_DECIMALS is 12, then rates not exceeding ~340282366 should fit. - // That's because if precision <= 10^18 and rate <= 10^12 * 340282366, then rate * precision < 2^128. - // NOTE: Rates should be updated prior ro calling this function + /// Scaled rates are rates multiplied by precision. They are assumed to fit in u128. + /// If TOKEN_TARGET_DECIMALS is 18 and RATE_DECIMALS is 12, then rates not exceeding ~340282366 should fit. + /// That's because if precision <= 10^18 and rate <= 10^12 * 340282366, then rate * precision < 2^128. + /// + /// NOTE: Rates should be updated prior to calling this function fn get_scaled_rates(&self) -> Result, MathError> { self.pool .token_rates @@ -354,7 +355,8 @@ pub mod stable_pool { Ok((token_in_id, token_out_id)) } /// Calculates lpt equivalent of the protocol fee and mints it to the `fee_to` if one is set. - /// NOTE: Rates should be updated prior ro calling this function + /// + /// NOTE: Rates should be updated prior to calling this function fn mint_protocol_fee(&mut self, fee: u128, token_id: usize) -> Result<(), StablePoolError> { if let Some(fee_to) = self.fee_to() { let protocol_fee = self.pool.fees.protocol_trade_fee(fee)?; From 540c18bff900559d6b7ed5ec201d409fcbb1469b Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Mon, 8 Jul 2024 11:31:14 +0200 Subject: [PATCH 11/12] remove obsolete comment --- amm/contracts/stable_pool/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index d0f9bb6..17e0a6d 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -355,7 +355,7 @@ pub mod stable_pool { Ok((token_in_id, token_out_id)) } /// Calculates lpt equivalent of the protocol fee and mints it to the `fee_to` if one is set. - /// + /// /// NOTE: Rates should be updated prior to calling this function fn mint_protocol_fee(&mut self, fee: u128, token_id: usize) -> Result<(), StablePoolError> { if let Some(fee_to) = self.fee_to() { @@ -834,8 +834,6 @@ pub mod stable_pool { self.pool.tokens.clone() } - // This can output values lower than the actual balances of these tokens, which stems from roundings. - // However an invariant holds that each balance is at least the value returned by this function. #[ink(message)] fn reserves(&self) -> Vec { self.pool.reserves.clone() From 9c3996599a1ae976ac04451cfdfff368679ddcc2 Mon Sep 17 00:00:00 2001 From: JanKuczma Date: Mon, 8 Jul 2024 13:55:07 +0200 Subject: [PATCH 12/12] bitwise or --- amm/contracts/stable_pool/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 17e0a6d..5ef3c61 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -295,7 +295,7 @@ pub mod stable_pool { let current_time = self.env().block_timestamp(); let mut rate_changed = false; for rate in self.pool.token_rates.iter_mut() { - rate_changed = rate.update_rate(current_time) || rate_changed; + rate_changed = rate.update_rate(current_time) | rate_changed; } if rate_changed { Self::env().emit_event(RatesUpdated { @@ -723,7 +723,7 @@ pub mod stable_pool { let current_time = self.env().block_timestamp(); let mut rate_changed = false; for rate in self.pool.token_rates.iter_mut() { - rate_changed = rate.update_rate_no_cache(current_time) || rate_changed; + rate_changed = rate.update_rate_no_cache(current_time) | rate_changed; } if rate_changed { Self::env().emit_event(RatesUpdated {