Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove max spread check for stableswap pool #91

Merged
merged 2 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading