From 09012bc5e239667ddef384778a8b82979bca9164 Mon Sep 17 00:00:00 2001 From: Filip Bielejec Date: Thu, 17 Nov 2022 14:46:58 +0100 Subject: [PATCH] check liquidity in swaps only (#736) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * check liqui in swaps * refactor tests too * cleanup * check swap fail due to not enoigh liqui * Update e2e-tests/src/test/button_game/mod.rs Co-authored-by: Paweł Obrok * ugh fmt Co-authored-by: Paweł Obrok --- contracts/simple_dex/lib.rs | 24 +++++++++------------ e2e-tests/src/test/button_game/contracts.rs | 2 -- e2e-tests/src/test/button_game/mod.rs | 9 ++++---- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/contracts/simple_dex/lib.rs b/contracts/simple_dex/lib.rs index c5a2df20f1..c848b08eb1 100644 --- a/contracts/simple_dex/lib.rs +++ b/contracts/simple_dex/lib.rs @@ -153,6 +153,12 @@ mod simple_dex { let this = self.env().account_id(); let caller = self.env().caller(); + let balance_token_out = self.balance_of(token_out, this)?; + if balance_token_out < min_amount_token_out { + // throw early if we cannot support this swap anyway due to liquidity being too low + return Err(DexError::NotEnoughLiquidityOf(token_out)); + } + let swap_pair = SwapPair::new(token_in, token_out); if !self.swap_pairs.contains(&swap_pair) { return Err(DexError::UnsupportedSwapPair(swap_pair)); @@ -163,12 +169,7 @@ mod simple_dex { return Err(DexError::InsufficientAllowanceOf(token_in)); } - let amount_token_out = self.out_given_in( - token_in, - token_out, - amount_token_in, - Some(min_amount_token_out), - )?; + let amount_token_out = self.out_given_in(token_in, token_out, amount_token_in)?; if amount_token_out < min_amount_token_out { // thrown if too much slippage occured before this tx gets executed @@ -360,25 +361,20 @@ mod simple_dex { /// Swap trade output given a curve with equal token weights /// - /// swap_fee_percentage (integer) is a percentage of the trade that goes towards the pool - /// B_0 - (100 * B_0 * B_i) / (100 * (B_i + A_i) -A_i * fee) + /// B_0 - (100 * B_0 * B_i) / (100 * (B_i + A_i) - A_i * swap_fee) + /// where swap_fee (integer) is a percentage of the trade that goes towards the pool + /// and is used to pay the liquidity providers #[ink(message)] pub fn out_given_in( &self, token_in: AccountId, token_out: AccountId, amount_token_in: Balance, - min_amount_token_out: Option, ) -> Result { let this = self.env().account_id(); let balance_token_in = self.balance_of(token_in, this)?; let balance_token_out = self.balance_of(token_out, this)?; - if min_amount_token_out.map_or(false, |x| balance_token_out < x) { - // throw early if we cannot support this swap anyway due to liquidity being too low - return Err(DexError::NotEnoughLiquidityOf(token_out)); - } - let op0 = amount_token_in .checked_mul(self.swap_fee_percentage) .ok_or(DexError::Arithmethic)?; diff --git a/e2e-tests/src/test/button_game/contracts.rs b/e2e-tests/src/test/button_game/contracts.rs index 8dc6188840..247945ce4a 100644 --- a/e2e-tests/src/test/button_game/contracts.rs +++ b/e2e-tests/src/test/button_game/contracts.rs @@ -78,7 +78,6 @@ impl SimpleDexInstance { token_in: &PSP22TokenInstance, token_out: &PSP22TokenInstance, amount_token_in: Balance, - min_amount_token_out: Option, ) -> Result { let token_in: AccountId = token_in.into(); let token_out: AccountId = token_out.into(); @@ -91,7 +90,6 @@ impl SimpleDexInstance { token_in.to_string(), token_out.to_string(), amount_token_in.to_string(), - min_amount_token_out.map_or("None".to_string(), |x| format!("Some({:})", x)), ], )? .try_into()? diff --git a/e2e-tests/src/test/button_game/mod.rs b/e2e-tests/src/test/button_game/mod.rs index 38919df53f..4ffc399750 100644 --- a/e2e-tests/src/test/button_game/mod.rs +++ b/e2e-tests/src/test/button_game/mod.rs @@ -72,13 +72,12 @@ pub fn simple_dex(config: &Config) -> Result<()> { )?; let more_than_liquidity = mega(1_000_000); - assert!(dex - .out_given_in(account_conn, token1, token2, 100, Some(more_than_liquidity)) - .is_err()); + dex.swap(account_conn, token1, 100, token2, more_than_liquidity)?; + refute_recv_id(&mut events, "Swapped"); let initial_amount = mega(100); token1.mint(authority_conn, &account.public().into(), initial_amount)?; - let expected_output = dex.out_given_in(account_conn, token1, token2, initial_amount, None)?; + let expected_output = dex.out_given_in(account_conn, token1, token2, initial_amount)?; assert!(expected_output > 0); let at_most_10_percent_slippage = expected_output * 9 / 10; @@ -100,7 +99,7 @@ pub fn simple_dex(config: &Config) -> Result<()> { let balance_after = token1.balance_of(&conn, &account.public().into())?; assert!(initial_amount.abs_diff(balance_after) <= 1); assert!( - dex.out_given_in(account_conn, token1, token2, initial_amount, None)? + dex.out_given_in(account_conn, token1, token2, initial_amount)? .abs_diff(expected_output) <= 1 );