Skip to content

Commit

Permalink
remove max spread check for stableswap pool (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
betterclever authored Apr 29, 2024
2 parents ead2662 + d91162d commit 05a52c5
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 75 deletions.
30 changes: 7 additions & 23 deletions contracts/pools/stable_pool/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,17 +509,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
offer_asset,
ask_asset,
amount,
max_spread,
belief_price,
max_spread: _,
belief_price: _,
} => to_json_binary(&query_on_swap(
deps,
env,
swap_type,
offer_asset,
ask_asset,
amount,
max_spread,
belief_price,

)?),
QueryMsg::CumulativePrice {
offer_asset,
Expand Down Expand Up @@ -934,8 +933,6 @@ pub fn query_on_swap(
offer_asset_info: AssetInfo,
ask_asset_info: AssetInfo,
amount: Uint128,
max_spread: Option<Decimal>,
belief_price: Option<Decimal>,
) -> StdResult<SwapResponse> {
// Load the config and math config from the storage
let config: Config = CONFIG.load(deps.storage)?;
Expand Down Expand Up @@ -970,7 +967,7 @@ pub fn query_on_swap(

let offer_asset: Asset;
let ask_asset: Asset;
let (calc_amount, spread_amount): (Uint128, Uint128);
let calc_amount: Uint128;
let total_fee: Uint128;

let ask_asset_scaling_factor = scaling_factors
Expand Down Expand Up @@ -1001,7 +998,7 @@ pub fn query_on_swap(
.to_scaled_decimal_asset(offer_precision, offer_asset_scaling_factor)?;

// Calculate the number of ask_asset tokens to be transferred to the recipient from the Vault contract
(calc_amount, spread_amount) = match compute_swap(
calc_amount = match compute_swap(
deps.storage,
&env,
&math_config,
Expand Down Expand Up @@ -1038,7 +1035,7 @@ pub fn query_on_swap(
.to_scaled_decimal_asset(ask_precision, ask_asset_scaling_factor)?;

// Calculate the number of offer_asset tokens to be transferred from the trader from the Vault contract
(calc_amount, spread_amount, total_fee) = match compute_offer_amount(
(calc_amount, total_fee) = match compute_offer_amount(
deps.storage,
&env,
&math_config,
Expand Down Expand Up @@ -1077,24 +1074,11 @@ pub fn query_on_swap(
));
}

// Check the max spread limit (if it was specified)
let spread_check = assert_max_spread(
stableswap_config.max_allowed_spread,
belief_price,
max_spread,
offer_asset.amount - total_fee,
ask_asset.amount,
spread_amount,
);
if !spread_check.is_success() {
return Ok(return_swap_failure(spread_check.to_string()));
}

Ok(SwapResponse {
trade_params: Trade {
amount_in: offer_asset.amount,
amount_out: ask_asset.amount,
spread: spread_amount,
spread: Uint128::zero(),
},
response: ResponseType::Success {},
fee: Some(Asset {
Expand Down
34 changes: 6 additions & 28 deletions contracts/pools/stable_pool/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub(crate) fn compute_swap(
ask_pool: &DecimalAsset,
pools: &[DecimalAsset],
ask_asset_scaling_factor: Decimal256,
) -> StdResult<(Uint128, Uint128)> {
) -> StdResult<Uint128> {
// get ask asset precision
let ask_asset_precision = get_precision(storage, &ask_pool.info)?;

Expand All @@ -49,19 +49,7 @@ pub(crate) fn compute_swap(
.without_scaling_factor(ask_asset_scaling_factor)?
.to_uint128_with_precision(ask_asset_precision)?;

let offer_asset_amount = offer_asset
.amount
.to_uint128_with_precision(ask_asset_precision)?;

// We consider swap rate 1:1 in stable swap thus any difference is considered as spread.
let spread_amount = offer_asset_amount.saturating_sub(return_amount);

// Spread amount must be scaled by the scaling factor of the ask asset to get the actual spread amount in the ask asset terms.
let spread_amount_without_scaling_factor = Decimal256::with_precision(spread_amount, ask_asset_precision as u32)?
.without_scaling_factor(ask_asset_scaling_factor)?
.to_uint128_with_precision(ask_asset_precision)?;

Ok((return_amount_without_scaling_factor, spread_amount_without_scaling_factor))
Ok(return_amount_without_scaling_factor)
}

/// ## Description
Expand All @@ -82,11 +70,10 @@ pub(crate) fn compute_offer_amount(
ask_pool: &DecimalAsset,
pools: &[DecimalAsset],
commission_rate: u16,
ask_asset_scaling_factor: Decimal256,
_ask_asset_scaling_factor: Decimal256,
offer_asset_scaling_factor: Decimal256,
) -> StdResult<(Uint128, Uint128, Uint128)> {
) -> StdResult<(Uint128, Uint128)> {
let offer_precision = get_precision(storage, &offer_pool.info)?;
let ask_precision = get_precision(storage, &ask_asset.info)?;

let one_minus_commission = Decimal256::one()
- decimal2decimal256(Decimal::from_ratio(commission_rate, FEE_PRECISION))?;
Expand Down Expand Up @@ -121,16 +108,7 @@ pub(crate) fn compute_offer_amount(
let fee = offer_amount_including_fee - offer_amount_without_scaling_factor;
let fee_uint128 = fee.to_uint128_with_precision(offer_precision)?;

// We assume the assets should stay in a 1:1 ratio, so the true exchange rate is 1. Any exchange rate < 1 could be considered the spread
let ask_asset_with_scaling_factor_gp = ask_asset.amount.to_uint128_with_precision(Decimal256::DECIMAL_PLACES)?;
let offer_amount_with_scaling_factor_excluding_fee_gp = offer_amount_with_scaling_factor_gp;
let spread_amount_gp = offer_amount_with_scaling_factor_excluding_fee_gp.saturating_sub(ask_asset_with_scaling_factor_gp);

let spread_amount_without_scaling_factor = Decimal256::with_precision(spread_amount_gp, Decimal256::DECIMAL_PLACES as u32)?
.without_scaling_factor(ask_asset_scaling_factor)?
.to_uint128_with_precision(ask_precision)?;

Ok((offer_amount_including_fee_uint128, spread_amount_without_scaling_factor, fee_uint128))
Ok((offer_amount_including_fee_uint128, fee_uint128))
}

// --------x--------x--------x--------x--------x--------x--------
Expand Down Expand Up @@ -216,7 +194,7 @@ pub fn accumulate_prices(
let offer_asset_scaled = offer_asset.with_scaling_factor(offer_asset_scaling_factor)?;

let (offer_pool, ask_pool) = select_pools(from, to, pools).unwrap();
let (return_amount, _) = compute_swap(
let return_amount = compute_swap(
deps.storage,
&env,
&math_config,
Expand Down
38 changes: 22 additions & 16 deletions contracts/pools/stable_pool/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use cosmwasm_std::{from_json, to_json_binary, Addr, Coin, Decimal, Timestamp, Ui
use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg};
use cw_multi_test::Executor;

use dexter::asset::{Asset, AssetExchangeRate, AssetInfo};
use dexter::asset::{native_asset_info, Asset, AssetExchangeRate, AssetInfo};
use dexter::pool::{AfterExitResponse, AfterJoinResponse, ConfigResponse, CumulativePricesResponse, ExecuteMsg, ExitType, QueryMsg, ResponseType, SwapResponse};
use dexter::vault;
use dexter::vault::{
Expand Down Expand Up @@ -1896,7 +1896,7 @@ fn test_swap() {
);
assert_eq!(
swap_offer_asset_res.trade_params.spread,
Uint128::from(5u128)
Uint128::from(0u128)
);
assert_eq!(
swap_offer_asset_res.fee.clone().unwrap().info,
Expand Down Expand Up @@ -1965,7 +1965,7 @@ fn test_swap() {
);
assert_eq!(
swap_offer_asset_res.trade_params.spread,
Uint128::from(5341176u128)
Uint128::from(0u128)
);
assert_eq!(
swap_offer_asset_res.fee.clone().unwrap().info,
Expand Down Expand Up @@ -1998,25 +1998,30 @@ fn test_swap() {
},
)
.unwrap();

// Success: since the max_spread field is ignored
assert_eq!(
swap_offer_asset_res.response,
ResponseType::Failure(
"error : Operation exceeds max spread limit. Current spread = 0.066984666048109965".to_string()
)
ResponseType::Success {}
);
assert_eq!(
swap_offer_asset_res.trade_params.amount_in,
Uint128::from(0u128)
Uint128::from(30000_000000u128)
);
assert_eq!(
swap_offer_asset_res.trade_params.amount_out,
Uint128::from(0u128)
Uint128::from(27150_746218u128)
);
assert_eq!(
swap_offer_asset_res.trade_params.spread,
Uint128::from(0u128)
);
assert_eq!(swap_offer_asset_res.fee.clone(), None);
assert_eq!(swap_offer_asset_res.fee.clone(), Some(Asset {
info: AssetInfo::NativeToken {
denom: "axlusd".to_string()
},
amount: Uint128::from(900_000000u128)
}));

// SwapType::GiveOut {},
let swap_offer_asset_res: SwapResponse = app
Expand All @@ -2037,26 +2042,27 @@ fn test_swap() {
},
)
.unwrap();
// Success: since we removed the check
assert_eq!(
swap_offer_asset_res.response,
ResponseType::Failure(
"error : Operation exceeds max spread limit. Current spread = 0.187679712517183249"
.to_string()
)
ResponseType::Success { }
);
assert_eq!(
swap_offer_asset_res.trade_params.amount_in,
Uint128::from(0u128)
Uint128::from(63455_748363u128)
);
assert_eq!(
swap_offer_asset_res.trade_params.amount_out,
Uint128::from(0u128)
Uint128::from(50000_000000u128)
);
assert_eq!(
swap_offer_asset_res.trade_params.spread,
Uint128::from(0u128)
);
assert_eq!(swap_offer_asset_res.fee.clone(), None);
assert_eq!(swap_offer_asset_res.fee.clone(), Some(Asset {
info: native_asset_info("axlusd".to_string()),
amount: Uint128::from(1903_672450u128)
}));

//// -----x----- Check #3 :: EXECUTE Success ::: -----x----- ////

Expand Down
16 changes: 8 additions & 8 deletions contracts/pools/stable_pool/tests/test_scaling_factor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ fn test_swap() {
},
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(1_017_336_487u128),
Uint128::from(10_451u128),
Uint128::from(0u128),
Asset {
info: AssetInfo::NativeToken {
denom: "ustkatom".to_string(),
Expand Down Expand Up @@ -405,7 +405,7 @@ fn test_swap() {
},
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(982_978_603u128),
Uint128::from(30_273u128),
Uint128::from(0u128),
Asset {
info: AssetInfo::NativeToken {
denom: "ustkatom".to_string(),
Expand Down Expand Up @@ -533,7 +533,7 @@ fn test_swap_different_precision() {
},
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(1_017_336_487u128),
Uint128::from(10_451u128),
Uint128::from(0u128),
Asset {
info: AssetInfo::NativeToken {
denom: "ustkatom".to_string(),
Expand Down Expand Up @@ -561,7 +561,7 @@ fn test_swap_different_precision() {
},
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(982_978_603_388u128),
Uint128::from(30_273u128),
Uint128::from(0u128),
Asset {
info: AssetInfo::NativeToken {
denom: "ustkatom".to_string(),
Expand Down Expand Up @@ -755,7 +755,7 @@ fn test_swap_different_lsd_assets() {
},
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(976_643_026u128),
Uint128::from(10_033u128),
Uint128::from(0u128),
Asset {
info: AssetInfo::NativeToken {
denom: "ustkatom".to_string(),
Expand Down Expand Up @@ -805,7 +805,7 @@ fn test_swap_different_lsd_assets() {
},
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(1_023_936_467_628u128),
Uint128::from(30_685u128),
Uint128::from(0u128),
Asset {
info: AssetInfo::NativeToken {
denom: "ustkatom".to_string(),
Expand Down Expand Up @@ -984,7 +984,7 @@ fn test_5_asset_lsd_pool_with_different_precisions() {
atom_asset.clone(),
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(1_038_125u128),
Uint128::from(416u128),
Uint128::from(0u128),
Asset {
info: statom_asset.clone(),
amount: Uint128::from(3_000u128),
Expand All @@ -1009,7 +1009,7 @@ fn test_5_asset_lsd_pool_with_different_precisions() {
qatom_asset.clone(),
Some(Decimal::from_ratio(20u64, 100u64)),
Uint128::from(10_277_441_665_935_813u128),
Uint128::from(4_120_834_064_186u128),
Uint128::from(0u128),
Asset {
info: statom_asset.clone(),
amount: Uint128::from(30_000_000u128),
Expand Down
2 changes: 2 additions & 0 deletions packages/dexter/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ pub enum QueryMsg {
offer_asset: AssetInfo,
ask_asset: AssetInfo,
amount: Uint128,
// DEPRECATED: not used in any pool type. use min received for slippage protection
max_spread: Option<Decimal>,
// DEPRECATED: not used in any pool type. use min received for slippage protection
belief_price: Option<Decimal>,
},
/// ## Description - Returns information about the cumulative price of the asset in a [`CumulativePriceResponse`] object.
Expand Down

0 comments on commit 05a52c5

Please sign in to comment.