From 7316ed75e1eb455f01a7be57e0343c7df76ed02c Mon Sep 17 00:00:00 2001 From: afsardo Date: Tue, 14 Nov 2023 13:16:49 +0000 Subject: [PATCH] feat: upgrade pcl swap to include oracle price on spread calc --- src/astroport/pair_concentrated/swap.rs | 22 ++++++++++++++-------- src/lib.rs | 5 +++++ test/index.ts | 7 +++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/astroport/pair_concentrated/swap.rs b/src/astroport/pair_concentrated/swap.rs index c54a58e..80f8a08 100644 --- a/src/astroport/pair_concentrated/swap.rs +++ b/src/astroport/pair_concentrated/swap.rs @@ -24,6 +24,7 @@ pub fn simulate( ask_asset_prec: u32, asset_amounts: &[Decimal256], maker_fee_share: Decimal256, + oracle_price: Decimal256, price_scale: Decimal256, fee_gamma: Decimal256, mid_fee: Decimal256, @@ -55,6 +56,7 @@ pub fn simulate( offer_amount, ask_ind, maker_fee_share, + oracle_price, price_scale, fee_gamma, mid_fee, @@ -91,6 +93,7 @@ fn compute_swap( offer_amount: Decimal256, ask_ind: usize, maker_fee_share: Decimal256, + oracle_price: Decimal256, price_scale: Decimal256, fee_gamma: Decimal256, mid_fee: Decimal256, @@ -120,13 +123,11 @@ fn compute_swap( let d = calc_d(&ixs, &_gamma)?; - let offer_amount = if offer_ind == 1 { - offer_amount * price_scale + if offer_ind == 1 { + ixs[offer_ind] += offer_amount * price_scale; } else { - offer_amount - }; - - ixs[offer_ind] += offer_amount; + ixs[offer_ind] += offer_amount; + } let new_y = calc_y(&ixs, d, &_gamma, ask_ind)?; let mut dy = ixs[ask_ind] - new_y; @@ -139,8 +140,13 @@ fn compute_swap( price_scale }; - // Since price_scale moves slower than real price spread fee may become negative - let spread_fee = (offer_amount * price).saturating_sub(dy); + // Derive spread using oracle price + let spread_fee = if ask_ind == 1 { + dy /= price_scale; + (offer_amount / oracle_price).saturating_sub(dy) + } else { + offer_amount.saturating_sub(dy / oracle_price) + }; let fee_rate = fee(&ixs, fee_gamma, mid_fee, out_fee); let total_fee = fee_rate * dy; diff --git a/src/lib.rs b/src/lib.rs index b584795..297f0ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ pub fn concentrated_swap( ask_asset_prec: &str, asset_amounts: &str, maker_fee_share: &str, + oracle_price: &str, price_scale: &str, fee_gamma: &str, mid_fee: &str, @@ -48,6 +49,9 @@ pub fn concentrated_swap( let maker_fee_share = Decimal256::from_str(maker_fee_share) .map_err(|e| JsValue::from_str(&format!("Invalid maker_fee_share: {}", e)))?; + let oracle_price = Decimal256::from_str(oracle_price) + .map_err(|e| JsValue::from_str(&format!("Invalid oracle_price: {}", e)))?; + let price_scale = Decimal256::from_str(price_scale) .map_err(|e| JsValue::from_str(&format!("Invalid price_scale: {}", e)))?; @@ -91,6 +95,7 @@ pub fn concentrated_swap( ask_asset_prec, &asset_amounts, maker_fee_share, + oracle_price, price_scale, fee_gamma, mid_fee, diff --git a/test/index.ts b/test/index.ts index eb8f1ca..0c525f2 100644 --- a/test/index.ts +++ b/test/index.ts @@ -83,7 +83,12 @@ type PCLPoolRawConfig = { future_time: number; initial_time: number; price_state: { + oracle_price: string; + last_price: string; price_scale: string; + last_price_update: string; + xcp_profit: string; + xcp_profit_real: string; }; }; }; @@ -384,6 +389,7 @@ async function concentrated_swap_test(client: CosmWasmClient) { Buffer.from(rawConfig).toString() ); + const oracle_price = pool_config.pool_state.price_state.oracle_price; const price_scale = pool_config.pool_state.price_state.price_scale; const fee_gamma = pool_config.pool_params.fee_gamma; const mid_fee = pool_config.pool_params.mid_fee; @@ -425,6 +431,7 @@ async function concentrated_swap_test(client: CosmWasmClient) { "6", // ask_asset_prec, JSON.stringify(asset_amounts), PCL_FEE, + oracle_price, price_scale, fee_gamma, mid_fee,