From 4ac5422478fddbe05e6b0175acb01fa077eaa669 Mon Sep 17 00:00:00 2001 From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:19:09 -0700 Subject: [PATCH 1/2] fix clippy errors --- contracts/adapters/swap/dexter/src/contract.rs | 10 ++++++---- .../adapters/swap/dexter/tests/integration_test.rs | 2 +- contracts/adapters/swap/dexter/tests/utils/mod.rs | 6 ++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contracts/adapters/swap/dexter/src/contract.rs b/contracts/adapters/swap/dexter/src/contract.rs index a0f667b9..f441bd9b 100644 --- a/contracts/adapters/swap/dexter/src/contract.rs +++ b/contracts/adapters/swap/dexter/src/contract.rs @@ -420,10 +420,11 @@ fn simulate_swap_exact_asset_in( }); // Return the asset out and optionally the simulation responses - return Ok(asset_out); + Ok(asset_out) } else { // TODO: Fix this - return Err(ContractError::SwapOperationsEmpty); + // @NotJeremyLiu: Look into the above todo left by the original author + Err(ContractError::SwapOperationsEmpty) } } @@ -472,10 +473,11 @@ fn simulate_swap_exact_asset_out( }); // Return the asset out and optionally the simulation responses - return Ok(asset_in); + Ok(asset_in) } else { // TODO: Fix this - return Err(ContractError::SwapOperationsEmpty); + // @NotJeremyLiu: Look into the above todo left by the original author + Err(ContractError::SwapOperationsEmpty) } } diff --git a/contracts/adapters/swap/dexter/tests/integration_test.rs b/contracts/adapters/swap/dexter/tests/integration_test.rs index d866e4c7..f9432724 100644 --- a/contracts/adapters/swap/dexter/tests/integration_test.rs +++ b/contracts/adapters/swap/dexter/tests/integration_test.rs @@ -365,7 +365,7 @@ pub fn test_swap() { app.send_tokens( app.api().addr_make("owner"), entrypoint_dummy.clone(), - &vec![Coin::new(2_000_000u128, "uxprt")] + &[Coin::new(2_000_000u128, "uxprt")] ).unwrap(); // execute the swap without funds diff --git a/contracts/adapters/swap/dexter/tests/utils/mod.rs b/contracts/adapters/swap/dexter/tests/utils/mod.rs index 6c2c1a48..dd576a55 100644 --- a/contracts/adapters/swap/dexter/tests/utils/mod.rs +++ b/contracts/adapters/swap/dexter/tests/utils/mod.rs @@ -116,16 +116,14 @@ pub fn instantiate_dexter_swap_adapter_contract( dexter_router_contract_address: dexter_router_addr.to_string(), }; - let address = app.instantiate_contract( + app.instantiate_contract( dexter_swap_adapter_code_id, owner.to_owned(), &dexter_swap_adapter_init_msg, &[], "skip_swap_adapter:dexter", None, - ).unwrap(); - - address + ).unwrap() } pub fn instantiate_dexter_contracts_and_pools( From 7eed454cb3a9f14fff95177625731e4c4405a4b5 Mon Sep 17 00:00:00 2001 From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:04:28 -0700 Subject: [PATCH 2/2] fix fmt errors --- .../adapters/swap/dexter/src/contract.rs | 140 ++++--- .../swap/dexter/tests/integration_test.rs | 377 ++++++++++-------- .../swap/dexter/tests/test_execute_swap.rs | 38 +- .../adapters/swap/dexter/tests/utils/mod.rs | 42 +- packages/skip/src/swap.rs | 2 +- 5 files changed, 324 insertions(+), 275 deletions(-) diff --git a/contracts/adapters/swap/dexter/src/contract.rs b/contracts/adapters/swap/dexter/src/contract.rs index f441bd9b..e8baec99 100644 --- a/contracts/adapters/swap/dexter/src/contract.rs +++ b/contracts/adapters/swap/dexter/src/contract.rs @@ -4,19 +4,24 @@ use crate::{ error::{ContractError, ContractResult}, state::{DEXTER_ROUTER_ADDRESS, DEXTER_VAULT_ADDRESS, ENTRY_POINT_CONTRACT_ADDRESS}, }; -use dexter::{ - pool::{self, ResponseType, SpotPrice}, router::{ExecuteMsg as RouterExecuteMsg, HopSwapRequest, QueryMsg as RouterQueryMsg}, vault::{PoolInfoResponse, QueryMsg as VaultQueryMsg} -}; use cosmwasm_std::{ - entry_point, from_json, to_json_binary, Binary, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg + entry_point, from_json, to_json_binary, Binary, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, + Response, Uint128, WasmMsg, }; use cw2::set_contract_version; use cw20::{Cw20Coin, Cw20ReceiveMsg}; use cw_utils::one_coin; +use dexter::{ + pool::{self, ResponseType, SpotPrice}, + router::{ExecuteMsg as RouterExecuteMsg, HopSwapRequest, QueryMsg as RouterQueryMsg}, + vault::{PoolInfoResponse, QueryMsg as VaultQueryMsg}, +}; use skip::{ asset::Asset, swap::{ - execute_transfer_funds_back, Cw20HookMsg, DexterAdapterInstantiateMsg, ExecuteMsg, MigrateMsg, QueryMsg, SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse, SwapOperation + execute_transfer_funds_back, Cw20HookMsg, DexterAdapterInstantiateMsg, ExecuteMsg, + MigrateMsg, QueryMsg, SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse, + SwapOperation, }, }; @@ -54,8 +59,11 @@ pub fn instantiate( let checked_entry_point_contract_address = deps.api.addr_validate(&msg.entry_point_contract_address)?; - let dexter_vault_contract_address = deps.api.addr_validate(&msg.dexter_vault_contract_address)?; - let dexter_router_contract_address = deps.api.addr_validate(&msg.dexter_router_contract_address)?; + let dexter_vault_contract_address = + deps.api.addr_validate(&msg.dexter_vault_contract_address)?; + let dexter_router_contract_address = deps + .api + .addr_validate(&msg.dexter_router_contract_address)?; // Store the entry point contract address ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?; @@ -93,8 +101,9 @@ pub fn receive_cw20( info.sender = deps.api.addr_validate(&cw20_msg.sender)?; match from_json(&cw20_msg.msg)? { - - Cw20HookMsg::Swap { operations } => execute_swap(deps, env, info,sent_asset.amount(), operations), + Cw20HookMsg::Swap { operations } => { + execute_swap(deps, env, info, sent_asset.amount(), operations) + } } } @@ -156,20 +165,23 @@ fn execute_swap( let response: Response = Response::new().add_attribute("action", "execute_swap"); let mut hop_swap_requests = vec![]; - - for operation in &operations { - let pool_id: u64 = operation.pool.parse() + for operation in &operations { + let pool_id: u64 = operation + .pool + .parse() .map_err(|_| ContractError::PoolIdParseError)?; let pool_id_u128 = Uint128::from(pool_id); - hop_swap_requests.push(HopSwapRequest { pool_id: pool_id_u128, asset_in: dexter::asset::AssetInfo::native_token(operation.denom_in.clone()), asset_out: dexter::asset::AssetInfo::native_token(operation.denom_out.clone()), - max_spread: Some(Decimal::from_ratio(Uint128::from(5u64), Uint128::from(100u64))), - belief_price: None + max_spread: Some(Decimal::from_ratio( + Uint128::from(5u64), + Uint128::from(100u64), + )), + belief_price: None, }); } @@ -186,7 +198,10 @@ fn execute_swap( let dexter_router_wasm_msg = WasmMsg::Execute { contract_addr: dexter_router_contract_address.to_string(), msg: to_json_binary(&dexter_router_msg)?, - funds: vec![Coin { denom: denom_in, amount: amount_in }], + funds: vec![Coin { + denom: denom_in, + amount: amount_in, + }], }; let return_denom = match operations.last() { @@ -315,11 +330,7 @@ fn query_simulate_swap_exact_asset_in_with_metadata( } // Simulate the swap exact amount in - let asset_out = simulate_swap_exact_asset_in( - deps, - asset_in.clone(), - swap_operations.clone(), - )?; + let asset_out = simulate_swap_exact_asset_in(deps, asset_in.clone(), swap_operations.clone())?; // Create the response let mut response = SimulateSwapExactAssetInResponse { @@ -354,11 +365,7 @@ fn query_simulate_swap_exact_asset_out_with_metadata( } // Simulate the swap exact amount out - let asset_in = simulate_swap_exact_asset_out( - deps, - asset_out.clone(), - swap_operations.clone() - )?; + let asset_in = simulate_swap_exact_asset_out(deps, asset_out.clone(), swap_operations.clone())?; // Create the response let mut response = SimulateSwapExactAssetOutResponse { @@ -379,36 +386,36 @@ fn query_simulate_swap_exact_asset_out_with_metadata( fn simulate_swap_exact_asset_in( deps: Deps, asset_in: Asset, - swap_operations: Vec + swap_operations: Vec, ) -> ContractResult { - let dexter_router_address = DEXTER_ROUTER_ADDRESS.load(deps.storage)?; - let mut hop_swap_requests: Vec = vec![]; + let mut hop_swap_requests: Vec = vec![]; for operation in &swap_operations { - let pool_id: u64 = operation.pool.parse().unwrap(); let pool_id_u128 = Uint128::from(pool_id); - + hop_swap_requests.push(HopSwapRequest { pool_id: pool_id_u128, asset_in: dexter::asset::AssetInfo::native_token(operation.denom_in.clone()), asset_out: dexter::asset::AssetInfo::native_token(operation.denom_out.clone()), - max_spread: Some(Decimal::from_ratio(Uint128::from(5u64), Uint128::from(100u64))), - belief_price: None + max_spread: Some(Decimal::from_ratio( + Uint128::from(5u64), + Uint128::from(100u64), + )), + belief_price: None, }); } - let dexter_router_query = RouterQueryMsg::SimulateMultihopSwap { - multiswap_request: hop_swap_requests, - swap_type: dexter::vault::SwapType::GiveIn {}, - amount: asset_in.amount() + let dexter_router_query = RouterQueryMsg::SimulateMultihopSwap { + multiswap_request: hop_swap_requests, + swap_type: dexter::vault::SwapType::GiveIn {}, + amount: asset_in.amount(), }; - let dexter_router_response: dexter::router::SimulateMultiHopResponse = deps.querier.query_wasm_smart( - dexter_router_address, - &dexter_router_query, - )?; + let dexter_router_response: dexter::router::SimulateMultiHopResponse = deps + .querier + .query_wasm_smart(dexter_router_address, &dexter_router_query)?; if let ResponseType::Success {} = dexter_router_response.response { // Get the asset out @@ -432,36 +439,36 @@ fn simulate_swap_exact_asset_in( fn simulate_swap_exact_asset_out( deps: Deps, asset_out: Asset, - swap_operations: Vec + swap_operations: Vec, ) -> ContractResult { - let dexter_router_address = DEXTER_ROUTER_ADDRESS.load(deps.storage)?; - let mut hop_swap_requests: Vec = vec![]; + let mut hop_swap_requests: Vec = vec![]; for operation in &swap_operations { - let pool_id: u64 = operation.pool.parse().unwrap(); let pool_id_u128 = Uint128::from(pool_id); - + hop_swap_requests.push(HopSwapRequest { pool_id: pool_id_u128, asset_in: dexter::asset::AssetInfo::native_token(operation.denom_in.clone()), asset_out: dexter::asset::AssetInfo::native_token(operation.denom_out.clone()), - max_spread: Some(Decimal::from_ratio(Uint128::from(5u64), Uint128::from(100u64))), - belief_price: None + max_spread: Some(Decimal::from_ratio( + Uint128::from(5u64), + Uint128::from(100u64), + )), + belief_price: None, }); } - let dexter_router_query = RouterQueryMsg::SimulateMultihopSwap { - multiswap_request: hop_swap_requests, - swap_type: dexter::vault::SwapType::GiveOut {}, - amount: asset_out.amount() + let dexter_router_query = RouterQueryMsg::SimulateMultihopSwap { + multiswap_request: hop_swap_requests, + swap_type: dexter::vault::SwapType::GiveOut {}, + amount: asset_out.amount(), }; - let dexter_router_response: dexter::router::SimulateMultiHopResponse = deps.querier.query_wasm_smart( - dexter_router_address, - &dexter_router_query, - )?; + let dexter_router_response: dexter::router::SimulateMultiHopResponse = deps + .querier + .query_wasm_smart(dexter_router_address, &dexter_router_query)?; if let ResponseType::Success {} = dexter_router_response.response { // Get the asset out @@ -484,30 +491,33 @@ fn simulate_swap_exact_asset_out( // find spot prices for all the pools in the swap operations fn calculate_spot_price( deps: Deps, - swap_operations: Vec + swap_operations: Vec, ) -> ContractResult { - let dexter_vault_address = DEXTER_VAULT_ADDRESS.load(deps.storage)?; let mut final_price = Decimal::one(); for operation in &swap_operations { let pool_id: u64 = operation.pool.parse().unwrap(); let pool_id_u128 = Uint128::from(pool_id); - let pool_info: PoolInfoResponse = deps.querier.query_wasm_smart( + let pool_info: PoolInfoResponse = deps.querier.query_wasm_smart( dexter_vault_address.clone(), - &VaultQueryMsg::GetPoolById { pool_id: pool_id_u128 }, + &VaultQueryMsg::GetPoolById { + pool_id: pool_id_u128, + }, )?; let spot_price: SpotPrice = deps.querier.query_wasm_smart( pool_info.pool_addr, - &pool::QueryMsg::SpotPrice { + &pool::QueryMsg::SpotPrice { offer_asset: dexter::asset::AssetInfo::native_token(operation.denom_in.clone()), - ask_asset: dexter::asset::AssetInfo::native_token(operation.denom_out.clone()) - } + ask_asset: dexter::asset::AssetInfo::native_token(operation.denom_out.clone()), + }, )?; - final_price = final_price.checked_mul(Decimal::from_str(&spot_price.price_including_fee.to_string()).unwrap()).unwrap(); + final_price = final_price + .checked_mul(Decimal::from_str(&spot_price.price_including_fee.to_string()).unwrap()) + .unwrap(); } Ok(final_price) -} \ No newline at end of file +} diff --git a/contracts/adapters/swap/dexter/tests/integration_test.rs b/contracts/adapters/swap/dexter/tests/integration_test.rs index f9432724..fcfd3758 100644 --- a/contracts/adapters/swap/dexter/tests/integration_test.rs +++ b/contracts/adapters/swap/dexter/tests/integration_test.rs @@ -2,17 +2,23 @@ use std::str::FromStr; use cosmwasm_std::{to_json_binary, Addr, Coin, Decimal, Decimal256, Uint128}; use cw_multi_test::{addons::MockApiBech32, App, BankKeeper, Executor}; -use dexter::{asset::{Asset as DexterAsset, AssetInfo as DexterAssetInfo}, vault::{self, FeeInfo, NativeAssetPrecisionInfo}}; +use dexter::{ + asset::{Asset as DexterAsset, AssetInfo as DexterAssetInfo}, + vault::{self, FeeInfo, NativeAssetPrecisionInfo}, +}; use dexter_stable_pool::state::{AssetScalingFactor, StablePoolParams}; use skip::{asset::Asset, swap::SwapOperation}; -use utils::{instantiate_dexter_contracts_and_pools, instantiate_dexter_swap_adapter_contract, DexterInstantiateResponse}; +use utils::{ + instantiate_dexter_contracts_and_pools, instantiate_dexter_swap_adapter_contract, + DexterInstantiateResponse, +}; mod utils; pub struct SetupResponse { pub app: App, pub skip_swap_adapter_contract: Addr, - pub dexter_init_response: DexterInstantiateResponse + pub dexter_init_response: DexterInstantiateResponse, } pub fn setup() -> SetupResponse { @@ -25,38 +31,35 @@ pub fn setup() -> SetupResponse { Coin::new(100_000_000_000, "stk/uatom"), ]; - let mut app = utils::mock_app( - owner.clone(), - coins - ); + let mut app = utils::mock_app(owner.clone(), coins); - let fee_info = FeeInfo { + let fee_info = FeeInfo { total_fee_bps: 30, protocol_fee_percent: 30, }; let pool_instantiate_msgs = vec![ - dexter::vault::ExecuteMsg::CreatePoolInstance { - pool_type: vault::PoolType::StableSwap {}, + dexter::vault::ExecuteMsg::CreatePoolInstance { + pool_type: vault::PoolType::StableSwap {}, asset_infos: vec![ DexterAssetInfo::native_token("uxprt".to_string()), DexterAssetInfo::native_token("stk/uxprt".to_string()), ], native_asset_precisions: vec![ NativeAssetPrecisionInfo { - precision:6, - denom: "uxprt".to_string() + precision: 6, + denom: "uxprt".to_string(), }, NativeAssetPrecisionInfo { - precision:6, - denom: "stk/uxprt".to_string() + precision: 6, + denom: "stk/uxprt".to_string(), }, ], fee_info: None, - init_params: Some(to_json_binary( - &StablePoolParams { - amp: 50, - max_allowed_spread: Decimal::from_str("0.2").unwrap(), + init_params: Some( + to_json_binary(&StablePoolParams { + amp: 50, + max_allowed_spread: Decimal::from_str("0.2").unwrap(), supports_scaling_factors_update: false, scaling_factors: vec![ AssetScalingFactor { @@ -67,12 +70,13 @@ pub fn setup() -> SetupResponse { asset_info: DexterAssetInfo::native_token("stk/uxprt".to_string()), scaling_factor: Decimal256::one(), }, - ], - scaling_factor_manager: None - } - ).unwrap()) + ], + scaling_factor_manager: None, + }) + .unwrap(), + ), }, - dexter::vault::ExecuteMsg::CreatePoolInstance { + dexter::vault::ExecuteMsg::CreatePoolInstance { pool_type: vault::PoolType::Weighted {}, asset_infos: vec![ DexterAssetInfo::native_token("stk/uxprt".to_string()), @@ -80,51 +84,60 @@ pub fn setup() -> SetupResponse { ], native_asset_precisions: vec![ NativeAssetPrecisionInfo { - precision:6, - denom: "stk/uxprt".to_string() + precision: 6, + denom: "stk/uxprt".to_string(), }, NativeAssetPrecisionInfo { - precision:6, - denom: "stk/uatom".to_string() + precision: 6, + denom: "stk/uatom".to_string(), }, ], fee_info: None, - init_params: Some(to_json_binary( - &dexter_weighted_pool::state::WeightedParams { + init_params: Some( + to_json_binary(&dexter_weighted_pool::state::WeightedParams { weights: vec![ - DexterAsset::new(DexterAssetInfo::native_token("stk/uxprt".to_string()), Uint128::from(1u128)), - DexterAsset::new(DexterAssetInfo::native_token("stk/uatom".to_string()), Uint128::from(1u128)), - ], - exit_fee: None - } - ).unwrap()) + DexterAsset::new( + DexterAssetInfo::native_token("stk/uxprt".to_string()), + Uint128::from(1u128), + ), + DexterAsset::new( + DexterAssetInfo::native_token("stk/uatom".to_string()), + Uint128::from(1u128), + ), + ], + exit_fee: None, + }) + .unwrap(), + ), }, ]; - let dexter_init_response = instantiate_dexter_contracts_and_pools( - &mut app, - &owner, - fee_info, - pool_instantiate_msgs - ); + let dexter_init_response = + instantiate_dexter_contracts_and_pools(&mut app, &owner, fee_info, pool_instantiate_msgs); let skip_swap_adapter_contract = instantiate_dexter_swap_adapter_contract( &mut app, &owner, &mock_api.addr_make("entry_point"), &dexter_init_response.dexter_vault_addr, - &dexter_init_response.dexter_router_addr + &dexter_init_response.dexter_router_addr, ); let join_pool_msg_1 = dexter::vault::ExecuteMsg::JoinPool { - pool_id:Uint128::from(1u128), + pool_id: Uint128::from(1u128), assets: Some(vec![ - DexterAsset::new(DexterAssetInfo::native_token("stk/uxprt".to_string()),Uint128::from(100_000_000u128)), - DexterAsset::new(DexterAssetInfo::native_token("uxprt".to_string()), Uint128::from(100_000_000u128)), + DexterAsset::new( + DexterAssetInfo::native_token("stk/uxprt".to_string()), + Uint128::from(100_000_000u128), + ), + DexterAsset::new( + DexterAssetInfo::native_token("uxprt".to_string()), + Uint128::from(100_000_000u128), + ), ]), recipient: None, min_lp_to_receive: None, - auto_stake: None + auto_stake: None, }; app.execute_contract( @@ -134,18 +147,25 @@ pub fn setup() -> SetupResponse { &[ Coin::new(100_000_000u128, "stk/uxprt"), Coin::new(100_000_000u128, "uxprt"), - ] - ).unwrap(); + ], + ) + .unwrap(); let join_pool_msg_2 = dexter::vault::ExecuteMsg::JoinPool { - pool_id:Uint128::from(2u128), + pool_id: Uint128::from(2u128), assets: Some(vec![ - DexterAsset::new(DexterAssetInfo::native_token("stk/uatom".to_string()),Uint128::from(100_000_000u128)), - DexterAsset::new(DexterAssetInfo::native_token("stk/uxprt".to_string()), Uint128::from(100_000_000u128)), + DexterAsset::new( + DexterAssetInfo::native_token("stk/uatom".to_string()), + Uint128::from(100_000_000u128), + ), + DexterAsset::new( + DexterAssetInfo::native_token("stk/uxprt".to_string()), + Uint128::from(100_000_000u128), + ), ]), recipient: None, min_lp_to_receive: None, - auto_stake: None + auto_stake: None, }; app.execute_contract( @@ -155,190 +175,198 @@ pub fn setup() -> SetupResponse { &[ Coin::new(100_000_000u128, "stk/uatom"), Coin::new(100_000_000u128, "stk/uxprt"), - ] - ).unwrap(); + ], + ) + .unwrap(); SetupResponse { app, skip_swap_adapter_contract, - dexter_init_response + dexter_init_response, } } #[test] pub fn test_swap_simulation() { - - let SetupResponse { app, skip_swap_adapter_contract, dexter_init_response: _ } = setup(); + let SetupResponse { + app, + skip_swap_adapter_contract, + dexter_init_response: _, + } = setup(); // simulate swap of 1 uxprt to stk/uxprt via 1 pool - let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { + let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { asset_in: skip::asset::Asset::Native(Coin { denom: "uxprt".to_string(), - amount: Uint128::from(1_000_000u128) + amount: Uint128::from(1_000_000u128), }), - swap_operations: vec![ - SwapOperation { - pool: "1".to_string(), - denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), - } - ], + swap_operations: vec![SwapOperation { + pool: "1".to_string(), + denom_in: "uxprt".to_string(), + denom_out: "stk/uxprt".to_string(), + }], include_spot_price: true, }; - let simulation_result: skip::swap::SimulateSwapExactAssetInResponse = app.wrap() - .query_wasm_smart( - skip_swap_adapter_contract.clone(), - &swap_simulation_msg - ).unwrap(); + let simulation_result: skip::swap::SimulateSwapExactAssetInResponse = app + .wrap() + .query_wasm_smart(skip_swap_adapter_contract.clone(), &swap_simulation_msg) + .unwrap(); // assert output - assert_eq!(simulation_result.asset_out, Asset::Native(Coin { - denom: "stk/uxprt".to_string(), - amount: Uint128::from(996806u128) - })); + assert_eq!( + simulation_result.asset_out, + Asset::Native(Coin { + denom: "stk/uxprt".to_string(), + amount: Uint128::from(996806u128) + }) + ); // assert spot price - assert_eq!(simulation_result.spot_price.unwrap(), Decimal::from_str("0.996999805096313").unwrap()); + assert_eq!( + simulation_result.spot_price.unwrap(), + Decimal::from_str("0.996999805096313").unwrap() + ); // simulate swap of 1 uxprt to stk/uatom via 2 pools - let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { + let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { asset_in: skip::asset::Asset::Native(Coin { denom: "uxprt".to_string(), - amount: Uint128::from(1_000_000u128) + amount: Uint128::from(1_000_000u128), }), swap_operations: vec![ - SwapOperation { + SwapOperation { pool: "1".to_string(), denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), + denom_out: "stk/uxprt".to_string(), }, - SwapOperation { + SwapOperation { pool: "2".to_string(), denom_in: "stk/uxprt".to_string(), - denom_out: "stk/uatom".to_string(), - } + denom_out: "stk/uatom".to_string(), + }, ], include_spot_price: true, }; - let simulation_result: skip::swap::SimulateSwapExactAssetInResponse = app.wrap() - .query_wasm_smart( - skip_swap_adapter_contract.clone(), - &swap_simulation_msg - ).unwrap(); + let simulation_result: skip::swap::SimulateSwapExactAssetInResponse = app + .wrap() + .query_wasm_smart(skip_swap_adapter_contract.clone(), &swap_simulation_msg) + .unwrap(); - // assert output - assert_eq!(simulation_result.asset_out, Asset::Native(Coin { - denom: "stk/uatom".to_string(), - amount: Uint128::from(984036u128) - })); + assert_eq!( + simulation_result.asset_out, + Asset::Native(Coin { + denom: "stk/uatom".to_string(), + amount: Uint128::from(984036u128) + }) + ); // assert spot price - assert_eq!(simulation_result.spot_price.unwrap(), Decimal::from_str("0.994008805681024061").unwrap()); - + assert_eq!( + simulation_result.spot_price.unwrap(), + Decimal::from_str("0.994008805681024061").unwrap() + ); // do a reverse simulation and validate the output - let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetOutWithMetadata { + let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetOutWithMetadata { asset_out: skip::asset::Asset::Native(Coin { denom: "stk/uatom".to_string(), - amount: Uint128::from(1_000_000u128) + amount: Uint128::from(1_000_000u128), }), swap_operations: vec![ - SwapOperation { + SwapOperation { pool: "1".to_string(), denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), + denom_out: "stk/uxprt".to_string(), }, - SwapOperation { + SwapOperation { pool: "2".to_string(), denom_in: "stk/uxprt".to_string(), - denom_out: "stk/uatom".to_string(), + denom_out: "stk/uatom".to_string(), }, ], include_spot_price: true, }; - let simulation_result: skip::swap::SimulateSwapExactAssetOutResponse = app.wrap() - .query_wasm_smart( - skip_swap_adapter_contract.clone(), - &swap_simulation_msg - ).unwrap(); + let simulation_result: skip::swap::SimulateSwapExactAssetOutResponse = app + .wrap() + .query_wasm_smart(skip_swap_adapter_contract.clone(), &swap_simulation_msg) + .unwrap(); // assert output - assert_eq!(simulation_result.asset_in, Asset::Native(Coin { - denom: "uxprt".to_string(), - amount: Uint128::from(1016390u128) - })); + assert_eq!( + simulation_result.asset_in, + Asset::Native(Coin { + denom: "uxprt".to_string(), + amount: Uint128::from(1016390u128) + }) + ); // assert spot price. point to note that this spot price is same as in the previous case meaning that the spot price across a route is consistent in both simulations - assert_eq!(simulation_result.spot_price.unwrap(), Decimal::from_str("0.994008805681024061").unwrap()); - + assert_eq!( + simulation_result.spot_price.unwrap(), + Decimal::from_str("0.994008805681024061").unwrap() + ); // Let's simulate a swap with a route that doesn't exist - let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { + let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { asset_in: skip::asset::Asset::Native(Coin { denom: "uxprt".to_string(), - amount: Uint128::from(1_000_000u128) + amount: Uint128::from(1_000_000u128), }), swap_operations: vec![ - SwapOperation { + SwapOperation { pool: "1".to_string(), denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), + denom_out: "stk/uxprt".to_string(), }, - SwapOperation { + SwapOperation { pool: "2".to_string(), denom_in: "stk/uxprt".to_string(), - denom_out: "uatom".to_string(), - } + denom_out: "uatom".to_string(), + }, ], include_spot_price: true, }; - let simulation_result: Result = app.wrap() - .query_wasm_smart( - skip_swap_adapter_contract.clone(), - &swap_simulation_msg - ); + let simulation_result: Result = app + .wrap() + .query_wasm_smart(skip_swap_adapter_contract.clone(), &swap_simulation_msg); // error type is weird, for now we'll just check if there's an error assert!(simulation_result.is_err()); - // Let's try to send an invalid swap operation - let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { + let swap_simulation_msg = skip::swap::QueryMsg::SimulateSwapExactAssetInWithMetadata { asset_in: skip::asset::Asset::Native(Coin { denom: "uxprt".to_string(), - amount: Uint128::from(1_000_000u128) + amount: Uint128::from(1_000_000u128), }), swap_operations: vec![ - SwapOperation { + SwapOperation { pool: "1".to_string(), denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), + denom_out: "stk/uxprt".to_string(), }, - SwapOperation { + SwapOperation { pool: "2".to_string(), denom_in: "stk/uxprt".to_string(), - denom_out: "stk/uatom".to_string(), + denom_out: "stk/uatom".to_string(), }, - SwapOperation { + SwapOperation { pool: "3".to_string(), denom_in: "stk/uatom".to_string(), - denom_out: "uatom".to_string(), - } + denom_out: "uatom".to_string(), + }, ], include_spot_price: true, }; - - let simulation_result: Result = app.wrap() - .query_wasm_smart( - skip_swap_adapter_contract.clone(), - &swap_simulation_msg - ); + let simulation_result: Result = app + .wrap() + .query_wasm_smart(skip_swap_adapter_contract.clone(), &swap_simulation_msg); // error type is weird, for now we'll just check if there's an error assert!(simulation_result.is_err()); @@ -346,18 +374,19 @@ pub fn test_swap_simulation() { #[test] pub fn test_swap() { - - let SetupResponse { mut app, skip_swap_adapter_contract, dexter_init_response: _ } = setup(); + let SetupResponse { + mut app, + skip_swap_adapter_contract, + dexter_init_response: _, + } = setup(); // simulate swap of 1 uxprt to stk/uxprt via 1 pool - let swap_msg = skip::swap::ExecuteMsg::Swap { - operations: vec![ - SwapOperation { - pool: "1".to_string(), - denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), - } - ], + let swap_msg = skip::swap::ExecuteMsg::Swap { + operations: vec![SwapOperation { + pool: "1".to_string(), + denom_in: "uxprt".to_string(), + denom_out: "stk/uxprt".to_string(), + }], }; // create a new user and fund them with some uxprt @@ -365,15 +394,16 @@ pub fn test_swap() { app.send_tokens( app.api().addr_make("owner"), entrypoint_dummy.clone(), - &[Coin::new(2_000_000u128, "uxprt")] - ).unwrap(); + &[Coin::new(2_000_000u128, "uxprt")], + ) + .unwrap(); // execute the swap without funds let res = app.execute_contract( entrypoint_dummy.clone(), skip_swap_adapter_contract.clone(), &swap_msg, - &[] + &[], ); // swap without funds should fail @@ -385,29 +415,31 @@ pub fn test_swap() { entrypoint_dummy.clone(), skip_swap_adapter_contract.clone(), &swap_msg, - &[ - Coin::new(1_000_000u128, "uxprt") - ] - ).unwrap(); + &[Coin::new(1_000_000u128, "uxprt")], + ) + .unwrap(); // assert that the user has received the output asset - let user_balance: Uint128 = app.wrap().query_balance(entrypoint_dummy.clone(), "stk/uxprt").unwrap().amount; + let user_balance: Uint128 = app + .wrap() + .query_balance(entrypoint_dummy.clone(), "stk/uxprt") + .unwrap() + .amount; assert_eq!(user_balance, Uint128::from(996806u128)); - // perform a swap with multiple pools - let swap_msg = skip::swap::ExecuteMsg::Swap { + let swap_msg = skip::swap::ExecuteMsg::Swap { operations: vec![ - SwapOperation { + SwapOperation { pool: "1".to_string(), denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), + denom_out: "stk/uxprt".to_string(), }, - SwapOperation { + SwapOperation { pool: "2".to_string(), denom_in: "stk/uxprt".to_string(), - denom_out: "stk/uatom".to_string(), - } + denom_out: "stk/uatom".to_string(), + }, ], }; @@ -416,12 +448,15 @@ pub fn test_swap() { entrypoint_dummy.clone(), skip_swap_adapter_contract.clone(), &swap_msg, - &[ - Coin::new(1_000_000u128, "uxprt") - ] - ).unwrap(); + &[Coin::new(1_000_000u128, "uxprt")], + ) + .unwrap(); // assert that the user has received the output asset - let user_balance: Uint128 = app.wrap().query_balance(entrypoint_dummy.clone(), "stk/uatom").unwrap().amount; + let user_balance: Uint128 = app + .wrap() + .query_balance(entrypoint_dummy.clone(), "stk/uatom") + .unwrap() + .amount; assert_eq!(user_balance, Uint128::from(983654u128)); -} \ No newline at end of file +} diff --git a/contracts/adapters/swap/dexter/tests/test_execute_swap.rs b/contracts/adapters/swap/dexter/tests/test_execute_swap.rs index e35c8757..10c806b0 100644 --- a/contracts/adapters/swap/dexter/tests/test_execute_swap.rs +++ b/contracts/adapters/swap/dexter/tests/test_execute_swap.rs @@ -1,14 +1,18 @@ use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, to_json_binary, Addr, Coin, ReplyOn::Never, SubMsg, Uint128, WasmMsg + testing::{mock_dependencies, mock_env, mock_info}, + to_json_binary, Addr, Coin, + ReplyOn::Never, + SubMsg, Uint128, WasmMsg, }; use skip::swap::{ExecuteMsg, SwapOperation}; use skip_api_swap_adapter_dexter::{ - error::ContractResult, state::{DEXTER_ROUTER_ADDRESS, DEXTER_VAULT_ADDRESS, ENTRY_POINT_CONTRACT_ADDRESS}, + error::ContractResult, + state::{DEXTER_ROUTER_ADDRESS, DEXTER_VAULT_ADDRESS, ENTRY_POINT_CONTRACT_ADDRESS}, }; use cosmwasm_std::Decimal; -use std::str::FromStr; use dexter::asset::AssetInfo as DexterAssetInfo; +use std::str::FromStr; use dexter::router::{ExecuteMsg as DexterRouterExecuteMsg, HopSwapRequest}; use test_case::test_case; @@ -55,18 +59,18 @@ struct Params { id: 0, msg: WasmMsg::Execute { contract_addr: "dexter_router".to_string(), - msg: to_json_binary(& DexterRouterExecuteMsg::ExecuteMultihopSwap { + msg: to_json_binary(& DexterRouterExecuteMsg::ExecuteMultihopSwap { requests: vec![ - HopSwapRequest { + HopSwapRequest { pool_id: Uint128::from(1u128), - asset_in: DexterAssetInfo::NativeToken { + asset_in: DexterAssetInfo::NativeToken { denom: "uxprt".to_string() }, - asset_out: DexterAssetInfo::NativeToken { + asset_out: DexterAssetInfo::NativeToken { denom: "stk/uxprt".to_string() }, max_spread: Some(Decimal::from_str("0.05").unwrap()), - belief_price: None + belief_price: None } ], offer_amount: Uint128::from(100u128), @@ -120,29 +124,29 @@ struct Params { id: 0, msg: WasmMsg::Execute { contract_addr: "dexter_router".to_string(), - msg: to_json_binary(& DexterRouterExecuteMsg::ExecuteMultihopSwap { + msg: to_json_binary(& DexterRouterExecuteMsg::ExecuteMultihopSwap { requests: vec![ - HopSwapRequest { + HopSwapRequest { pool_id: Uint128::from(1u128), - asset_in: DexterAssetInfo::NativeToken { + asset_in: DexterAssetInfo::NativeToken { denom: "os".to_string() }, - asset_out: DexterAssetInfo::NativeToken { + asset_out: DexterAssetInfo::NativeToken { denom: "uatom".to_string() }, max_spread: Some(Decimal::from_str("0.05").unwrap()), - belief_price: None + belief_price: None }, - HopSwapRequest { + HopSwapRequest { pool_id: Uint128::from(2u128), - asset_in: DexterAssetInfo::NativeToken { + asset_in: DexterAssetInfo::NativeToken { denom: "uatom".to_string() }, - asset_out: DexterAssetInfo::NativeToken { + asset_out: DexterAssetInfo::NativeToken { denom: "untrn".to_string() }, max_spread: Some(Decimal::from_str("0.05").unwrap()), - belief_price: None + belief_price: None } ], offer_amount: Uint128::from(100u128), diff --git a/contracts/adapters/swap/dexter/tests/utils/mod.rs b/contracts/adapters/swap/dexter/tests/utils/mod.rs index dd576a55..75ab98a0 100644 --- a/contracts/adapters/swap/dexter/tests/utils/mod.rs +++ b/contracts/adapters/swap/dexter/tests/utils/mod.rs @@ -5,16 +5,14 @@ use cw_multi_test::addons::{MockAddressGenerator, MockApiBech32}; use cw_multi_test::{App, AppBuilder, BankKeeper, ContractWrapper, Executor, WasmKeeper}; use dexter::vault::{ - ExecuteMsg as VaultExecuteMsg, FeeInfo, InstantiateMsg as VaultInstantiateMsg, - PauseInfo, PoolCreationFee, PoolInfo, PoolType, PoolTypeConfig, - QueryMsg as VaultQueryMsg + ExecuteMsg as VaultExecuteMsg, FeeInfo, InstantiateMsg as VaultInstantiateMsg, PauseInfo, + PoolCreationFee, PoolInfo, PoolType, PoolTypeConfig, QueryMsg as VaultQueryMsg, }; use skip::swap::DexterAdapterInstantiateMsg; pub const EPOCH_START: u64 = 1_000_000; - pub fn mock_app(owner: Addr, coins: Vec) -> App { let mut env = mock_env(); env.block.time = Timestamp::from_seconds(EPOCH_START); @@ -29,7 +27,6 @@ pub fn mock_app(owner: Addr, coins: Vec) -> App // let mut app = App::new - app.set_block(env.block); app } @@ -91,15 +88,13 @@ pub fn store_dexter_swap_adapter_code(app: &mut App) app.store_code(dexter_swap_adapter_contract) } - pub struct DexterInstantiateResponse { pub dexter_vault_addr: Addr, pub dexter_router_addr: Addr, // expected that the order of the pool_info is the same as the order of the pool_instantiate_msgs - pub pool_info: Vec + pub pool_info: Vec, } - pub fn instantiate_dexter_swap_adapter_contract( app: &mut App, owner: &Addr, @@ -107,7 +102,6 @@ pub fn instantiate_dexter_swap_adapter_contract( dexter_vault_addr: &Addr, dexter_router_addr: &Addr, ) -> Addr { - let dexter_swap_adapter_code_id = store_dexter_swap_adapter_code(app); let dexter_swap_adapter_init_msg = DexterAdapterInstantiateMsg { @@ -123,16 +117,16 @@ pub fn instantiate_dexter_swap_adapter_contract( &[], "skip_swap_adapter:dexter", None, - ).unwrap() + ) + .unwrap() } pub fn instantiate_dexter_contracts_and_pools( app: &mut App, owner: &Addr, fee_info: FeeInfo, - pool_instantiate_msgs: Vec + pool_instantiate_msgs: Vec, ) -> DexterInstantiateResponse { - let stable5pool_code_id = store_stable_pool_code(app); let weighted_pool_code_id = store_weighted_pool_code(app); let vault_code_id = store_vault_code(app); @@ -153,7 +147,7 @@ pub fn instantiate_dexter_contracts_and_pools( default_fee_info: fee_info.clone(), allow_instantiation: dexter::vault::AllowPoolInstantiation::Everyone, paused: PauseInfo::default(), - } + }, ]; let vault_init_msg = VaultInstantiateMsg { @@ -181,8 +175,8 @@ pub fn instantiate_dexter_contracts_and_pools( dexter_vault: vault_instance.to_string(), }; - let dexter_router_instance = app. - instantiate_contract( + let dexter_router_instance = app + .instantiate_contract( router_code_id, owner.to_owned(), &router_instantiate_msg, @@ -192,17 +186,23 @@ pub fn instantiate_dexter_contracts_and_pools( ) .unwrap(); - let mut pool_infos = vec![]; for msg in pool_instantiate_msgs { let res = app .execute_contract(owner.clone(), vault_instance.clone(), &msg, &[]) .unwrap(); - // get event by type - let event = res.events.iter().find(|e| e.ty == "wasm-dexter-vault::reply::pool_init").unwrap(); - let attribute = event.attributes.iter().find(|a| a.key == "pool_id").unwrap(); + let event = res + .events + .iter() + .find(|e| e.ty == "wasm-dexter-vault::reply::pool_init") + .unwrap(); + let attribute = event + .attributes + .iter() + .find(|a| a.key == "pool_id") + .unwrap(); // get pool id from the event let pool_id = attribute.value.parse::().unwrap(); @@ -223,6 +223,6 @@ pub fn instantiate_dexter_contracts_and_pools( DexterInstantiateResponse { dexter_vault_addr: vault_instance, dexter_router_addr: dexter_router_instance, - pool_info: pool_infos + pool_info: pool_infos, } -} \ No newline at end of file +} diff --git a/packages/skip/src/swap.rs b/packages/skip/src/swap.rs index 272dccd0..be4c7600 100644 --- a/packages/skip/src/swap.rs +++ b/packages/skip/src/swap.rs @@ -29,7 +29,7 @@ pub struct MigrateMsg { // Osmosis Poolmanager and Astroport swap adapter contracts. #[cw_serde] pub struct InstantiateMsg { - pub entry_point_contract_address: String + pub entry_point_contract_address: String, } #[cw_serde]