Skip to content

Commit

Permalink
fix: stable slippage assertion
Browse files Browse the repository at this point in the history
  • Loading branch information
mantricjavier authored Feb 24, 2025
1 parent a965cd0 commit feb37c9
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 4 deletions.
6 changes: 2 additions & 4 deletions contracts/pool-manager/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,9 @@ pub fn assert_slippage_tolerance(

let pool_ratio = Decimal256::from_ratio(pools_total, total_share);
let deposit_ratio = Decimal256::from_ratio(deposits_total, share);
let difference = pool_ratio.abs_diff(deposit_ratio);

// the slippage tolerance for the stableswap can't use a simple ratio for calculating
// slippage when adding liquidity. Due to the math behind the stableswap, the amp factor
// needs to be in as well, much like when swaps are done
if pool_ratio * one_minus_slippage_tolerance > deposit_ratio {
if pool_ratio * one_minus_slippage_tolerance > difference {
return Err(ContractError::MaxSlippageAssertion);
}
}
Expand Down
111 changes: 111 additions & 0 deletions contracts/pool-manager/src/tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::cell::RefCell;

use cosmwasm_std::{coin, Addr, Coin, Decimal, Uint128};
use mantra_common_testing::multi_test::stargate_mock::StargateMock;
use mantra_dex_std::fee::Fee;
Expand Down Expand Up @@ -6866,6 +6868,115 @@ mod provide_liquidity {
},
);
}

#[test]
fn provide_liquidity_stable_invalid_slippage_check() {
let mut suite = TestingSuite::default_with_balances(
vec![
coin(1_000_000_000_000u128, "uwhale".to_string()),
coin(1_000_000_000_000u128, "uluna".to_string()),
coin(1_000_000_000_000u128, "uosmo".to_string()),
coin(1_000_000_000_000u128, "uusd".to_string()),
coin(
200_000_000_000_000_000000000000000000000u128,
"uusdc".to_string(),
),
coin(
200_000_000_000_000_000000000000000000u128,
"ausdy".to_string(),
),
coin(150_000_000_000_000_000000u128, "uom".to_string()),
],
StargateMock::new(vec![coin(8888u128, "uom".to_string())]),
);
let creator = suite.creator();
let bob = suite.senders[1].clone();
// Asset infos with uwhale and uluna

let asset_infos = vec!["uwhale".to_string(), "uluna".to_string()];

let pool_fees = PoolFee {
protocol_fee: Fee {
share: Decimal::zero(),
},
swap_fee: Fee {
share: Decimal::permille(30),
},
burn_fee: Fee {
share: Decimal::zero(),
},
extra_fees: vec![],
};

// Create a pool
suite.instantiate_default().add_one_epoch().create_pool(
&creator,
asset_infos,
vec![6u8, 6u8],
pool_fees,
PoolType::StableSwap { amp: 10 },
Some("whale.uluna".to_string()),
vec![coin(1000, "uusd"), coin(8888, "uom")],
|result| {
result.unwrap();
},
);

// set the pool state
suite.provide_liquidity(
&creator,
"o.whale.uluna".to_string(),
None,
None,
None,
None,
None,
vec![
Coin {
denom: "uwhale".to_string(),
amount: Uint128::from(1000000u128),
},
Coin {
denom: "uluna".to_string(),
amount: Uint128::from(1000000u128),
},
],
|result| {
result.unwrap();
},
);

//user sets 0.01% strict slippage tolerance, should fail
let slippage: Decimal = Decimal::bps(1);
suite.provide_liquidity(
&bob,
"o.whale.uluna".to_string(),
None,
None,
Some(slippage),
None,
None,
vec![
Coin {
denom: "uwhale".to_string(),
amount: Uint128::from(1000000u128),
},
Coin {
denom: "uluna".to_string(),
amount: Uint128::from(200000u128),
},
],
|result| {
let err = result.unwrap_err().downcast::<ContractError>().unwrap();
match err {
ContractError::MaxSlippageAssertion => {}
_ => panic!(
"Wrong error type, should return ContractError::MaxSlippageAssertion"
),
}
},
);
}
}

mod multiple_pools {
Expand Down

0 comments on commit feb37c9

Please sign in to comment.