From 6fa3cb0151a4f3a32f92afedb691847b24ba1390 Mon Sep 17 00:00:00 2001 From: Anshudhar Kumar Singh Date: Thu, 19 Dec 2024 14:12:08 +0530 Subject: [PATCH] fix: slippage calulation and added tests --- contracts/hub/vlp/src/query.rs | 13 ++++++-- contracts/hub/vlp/src/tests.rs | 54 +++++++++++++++++++++++++++++++++- packages/euclid/src/error.rs | 9 ++++-- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/contracts/hub/vlp/src/query.rs b/contracts/hub/vlp/src/query.rs index 180fcffc..5e08f9fe 100644 --- a/contracts/hub/vlp/src/query.rs +++ b/contracts/hub/vlp/src/query.rs @@ -221,11 +221,20 @@ pub fn assert_slippage_tolerance( pool_ratio: Decimal256, slippage_tolerance_bps: u64, ) -> Result { - let slippage = pool_ratio.abs_diff(ratio); + let slippage = ratio + .abs_diff(pool_ratio) + .checked_div(pool_ratio) + .map_err(|err| ContractError::Generic { + err: err.to_string(), + })?; + let slippage_tolerance = Decimal256::bps(slippage_tolerance_bps); ensure!( slippage.le(&slippage_tolerance), - ContractError::LiquiditySlippageExceeded {} + ContractError::LiquiditySlippageExceeded { + expected: slippage, + received: slippage_tolerance, + } ); Ok(true) } diff --git a/contracts/hub/vlp/src/tests.rs b/contracts/hub/vlp/src/tests.rs index a7d58e91..78a09445 100644 --- a/contracts/hub/vlp/src/tests.rs +++ b/contracts/hub/vlp/src/tests.rs @@ -2,9 +2,10 @@ #[cfg(test)] mod tests { use crate::contract::{execute, instantiate}; + use crate::query::{calculate_lp_allocation, calculate_lp_allocation_for_liquidity}; use crate::state::{State, BALANCES, CHAIN_LP_TOKENS, STATE}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{coins, DepsMut, Response, Uint128}; + use cosmwasm_std::{coins, Decimal256, DepsMut, Response, Uint128}; use euclid::chain::{ChainUid, CrossChainUser}; use euclid::error::ContractError; use euclid::fee::{DenomFees, Fee, TotalFees}; @@ -181,4 +182,55 @@ mod tests { ContractError::new("Euclid Fee cannot exceed maximum limit") ); } + + #[test] + fn test_calculate_lp_allocation_for_liquidity() { + let token_1_liquidity = Uint128::new(800); + let token_2_liquidity = Uint128::new(1000); + let total_reserve_1 = Uint128::new(10000); + let total_reserve_2 = Uint128::new(10000); + let total_lp_tokens = Uint128::new(100); + let slippage_tolerance_bps = Some(2000); // 1% slippage tolerance + + // Call the function to test + let lp_allocation = calculate_lp_allocation_for_liquidity( + token_1_liquidity, + token_2_liquidity, + total_reserve_1, + total_reserve_2, + total_lp_tokens, + slippage_tolerance_bps, + ) + .unwrap(); + + // Assert the expected LP allocation + let expected_allocation = Uint128::new(8); // This value should be calculated based on the logic + assert_eq!(lp_allocation, expected_allocation); + } + + #[test] + fn test_calculate_lp_allocation_for_liquidity_exceeded_slippage() { + let token_1_liquidity = Uint128::new(100); + let token_2_liquidity = Uint128::new(99); + let total_reserve_1 = Uint128::new(100); + let total_reserve_2 = Uint128::new(100); + let total_lp_tokens = Uint128::new(100); + let slippage_tolerance_bps = Some(0); // 0% slippage tolerance to force failure + + // Call the function to test and expect an error + let err = calculate_lp_allocation_for_liquidity( + token_1_liquidity, + token_2_liquidity, + total_reserve_1, + total_reserve_2, + total_lp_tokens, + slippage_tolerance_bps, + ) + .unwrap_err(); + + match err { + ContractError::LiquiditySlippageExceeded { .. } => (), + _ => panic!("Expected slippage exceeded error, got {:?}", err), + } + } } diff --git a/packages/euclid/src/error.rs b/packages/euclid/src/error.rs index 07141a65..6d65441b 100644 --- a/packages/euclid/src/error.rs +++ b/packages/euclid/src/error.rs @@ -1,7 +1,7 @@ use std::num::ParseIntError; use cosmwasm_std::{ - Addr, CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, + Addr, CheckedMultiplyFractionError, CheckedMultiplyRatioError, Decimal256, DivideByZeroError, OverflowError, StdError, Uint128, }; use cw20_base::ContractError as Cw20ContractError; @@ -194,8 +194,11 @@ pub enum ContractError { #[error("Liquity already exist in state for the sender")] LiquidityTxAlreadyExist {}, - #[error("Slippage has been exceeded when providing liquidity.")] - LiquiditySlippageExceeded {}, + #[error("Slippage has been exceeded when providing liquidity. Expected: {expected}, Received: {received}")] + LiquiditySlippageExceeded { + expected: Decimal256, + received: Decimal256, + }, #[error("Pool Instantiate Failed {err}")] PoolInstantiateFailed { err: String },