Skip to content

Commit

Permalink
check liquidity in swaps only (#736)
Browse files Browse the repository at this point in the history
* 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 <pawel.obrok@cardinals.cc>

* ugh fmt

Co-authored-by: Paweł Obrok <pawel.obrok@cardinals.cc>
  • Loading branch information
fbielejec and obrok committed Nov 17, 2022
1 parent 2b95430 commit 09012bc
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 21 deletions.
24 changes: 10 additions & 14 deletions contracts/simple_dex/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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
Expand Down Expand Up @@ -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<Balance>,
) -> Result<Balance, DexError> {
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)?;
Expand Down
2 changes: 0 additions & 2 deletions e2e-tests/src/test/button_game/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ impl SimpleDexInstance {
token_in: &PSP22TokenInstance,
token_out: &PSP22TokenInstance,
amount_token_in: Balance,
min_amount_token_out: Option<Balance>,
) -> Result<Balance> {
let token_in: AccountId = token_in.into();
let token_out: AccountId = token_out.into();
Expand All @@ -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()?
Expand Down
9 changes: 4 additions & 5 deletions e2e-tests/src/test/button_game/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
);
Expand Down

0 comments on commit 09012bc

Please sign in to comment.