diff --git a/contracts/adapters/swap/astroport/README.md b/contracts/adapters/swap/astroport/README.md index a51ff5c9..0354b959 100644 --- a/contracts/adapters/swap/astroport/README.md +++ b/contracts/adapters/swap/astroport/README.md @@ -1,8 +1,8 @@ # Neutron Astroport Swap Adapter Contract The Neutron Astroport swap adapter contract is responsible for: -1. Taking the standardized entry point swap operations message format and converting it to the Astroport Router `SwapOperation` format. -2. Swapping by calling the Astroport router. +1. Taking the standardized entry point swap operations message format and converting it to Astroport pool swaps message format. +2. Swapping by dispatching swaps to Astroport pool contracts. 3. Providing query methods that can be called by the entry point contract (generally, to any external actor) to simulate multi-hop swaps that either specify an exact amount in (estimating how much would be received from the swap) or an exact amount out (estimating how much is required to get the specified amount out). Note: Swap adapter contracts expect to be called by an entry point contract that provides basic validation and minimum amount out safety guarantees for the caller. There are no slippage guarantees provided by swap adapter contracts. @@ -11,11 +11,11 @@ WARNING: Do not send funds directly to the contract without calling one of its f ## InstantiateMsg -Instantiates a new Neutron Astroport swap adapter contract using the Astroport router provided in the instantiation message. +Instantiates a new Neutron Astroport swap adapter contract using the Entrypoint contract address provided in the instantiation message. ``` json { - "router_contract_address": "neutron..." + "entry_point_contract_address": "neutron..." } ``` @@ -60,22 +60,6 @@ Note: This function can be called by anyone as the contract is assumed to have n ## QueryMsg -### `router_contract_address` - -Returns the Astroport router contract address set at instantiation. - -Query: -``` json -{ - "router_contract_address": {} -} -``` - -Response: -``` json -"neutron..." -``` - ### `simulate_swap_exact_coin_out` Returns the coin in required to receive the `coin_out` specified in the call (swapped through the `swap_operatons` provided) diff --git a/contracts/adapters/swap/astroport/src/bin/astroport-schema.rs b/contracts/adapters/swap/astroport/src/bin/astroport-schema.rs index 215b56dd..4f4733f0 100644 --- a/contracts/adapters/swap/astroport/src/bin/astroport-schema.rs +++ b/contracts/adapters/swap/astroport/src/bin/astroport-schema.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::write_api; -use skip::swap::{AstroportInstantiateMsg as InstantiateMsg, ExecuteMsg, QueryMsg}; +use skip::swap::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/adapters/swap/astroport/src/contract.rs b/contracts/adapters/swap/astroport/src/contract.rs index f19ac1ed..348531b7 100644 --- a/contracts/adapters/swap/astroport/src/contract.rs +++ b/contracts/adapters/swap/astroport/src/contract.rs @@ -1,27 +1,23 @@ use crate::{ error::{ContractError, ContractResult}, - state::{ENTRY_POINT_CONTRACT_ADDRESS, ROUTER_CONTRACT_ADDRESS}, + state::ENTRY_POINT_CONTRACT_ADDRESS, }; -use astroport::{ - pair::{ - QueryMsg as PairQueryMsg, ReverseSimulationResponse, SimulationResponse, - MAX_ALLOWED_SLIPPAGE, - }, - router::ExecuteMsg as RouterExecuteMsg, +use astroport::pair::{ + ExecuteMsg as PairExecuteMsg, QueryMsg as PairQueryMsg, ReverseSimulationResponse, + SimulationResponse, MAX_ALLOWED_SLIPPAGE, }; use cosmwasm_std::{ - entry_point, from_json, to_json_binary, Addr, Api, Binary, Decimal, Deps, DepsMut, Env, - MessageInfo, Response, Uint128, WasmMsg, + entry_point, from_json, to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, + Response, Uint128, WasmMsg, }; use cw2::set_contract_version; use cw20::{Cw20Coin, Cw20ReceiveMsg}; use cw_utils::one_coin; use skip::{ - asset::Asset, + asset::{get_current_asset_available, Asset}, swap::{ - execute_transfer_funds_back, AstroportInstantiateMsg as InstantiateMsg, Cw20HookMsg, - ExecuteMsg, MigrateMsg, QueryMsg, SimulateSwapExactAssetInResponse, - SimulateSwapExactAssetOutResponse, SwapOperation, + execute_transfer_funds_back, Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, + SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse, SwapOperation, }, }; @@ -59,21 +55,11 @@ pub fn instantiate( // Store the entry point contract address ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?; - // Validate router contract address - let checked_router_contract_address = deps.api.addr_validate(&msg.router_contract_address)?; - - // Store the router contract address - ROUTER_CONTRACT_ADDRESS.save(deps.storage, &checked_router_contract_address)?; - Ok(Response::new() .add_attribute("action", "instantiate") .add_attribute( "entry_point_contract_address", checked_entry_point_contract_address.to_string(), - ) - .add_attribute( - "router_contract_address", - checked_router_contract_address.to_string(), )) } @@ -100,7 +86,7 @@ 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, operations), + Cw20HookMsg::Swap { operations } => execute_swap(deps, env, info, operations), } } @@ -118,8 +104,8 @@ pub fn execute( match msg { ExecuteMsg::Receive(cw20_msg) => receive_cw20(deps, env, info, cw20_msg), ExecuteMsg::Swap { operations } => { - let sent_asset: Asset = one_coin(&info)?.into(); - execute_swap(deps, env, info, sent_asset, operations) + one_coin(&info)?; + execute_swap(deps, env, info, operations) } ExecuteMsg::TransferFundsBack { swapper, @@ -131,6 +117,9 @@ pub fn execute( swapper, return_denom, )?), + ExecuteMsg::AstroportPoolSwap { operation } => { + execute_astroport_pool_swap(deps, env, info, operation) + } } } @@ -138,7 +127,6 @@ fn execute_swap( deps: DepsMut, env: Env, info: MessageInfo, - sent_asset: Asset, operations: Vec, ) -> ContractResult { // Get entry point contract address from storage @@ -149,13 +137,20 @@ fn execute_swap( return Err(ContractError::Unauthorized); } - // Create the astroport swap message - let swap_msg = create_astroport_swap_msg( - deps.api, - ROUTER_CONTRACT_ADDRESS.load(deps.storage)?, - sent_asset, - &operations, - )?; + // Create a response object to return + let mut response: Response = Response::new().add_attribute("action", "execute_swap"); + + // Add an astroport pool swap message to the response for each swap operation + for operation in &operations { + let swap_msg = WasmMsg::Execute { + contract_addr: env.contract.address.to_string(), + msg: to_json_binary(&ExecuteMsg::AstroportPoolSwap { + operation: operation.clone(), + })?, + funds: vec![], + }; + response = response.add_message(swap_msg); + } let return_denom = match operations.last() { Some(last_op) => last_op.denom_out.clone(), @@ -172,44 +167,48 @@ fn execute_swap( funds: vec![], }; - Ok(Response::new() - .add_message(swap_msg) + Ok(response .add_message(transfer_funds_back_msg) - .add_attribute("action", "dispatch_swap_and_transfer_back")) + .add_attribute("action", "dispatch_swaps_and_transfer_back")) } -//////////////////////// -/// HELPER FUNCTIONS /// -//////////////////////// +fn execute_astroport_pool_swap( + deps: DepsMut, + env: Env, + info: MessageInfo, + operation: SwapOperation, +) -> ContractResult { + // Ensure the caller is the contract itself + if info.sender != env.contract.address { + return Err(ContractError::Unauthorized); + } + + // Get the current asset available on contract to swap in + let offer_asset = get_current_asset_available(&deps, &env, &operation.denom_in)?; -// Converts the swap operations to astroport AstroSwap operations -fn create_astroport_swap_msg( - api: &dyn Api, - router_contract_address: Addr, - asset_in: Asset, - swap_operations: &[SwapOperation], -) -> ContractResult { - // Convert the swap operations to astroport swap operations - let astroport_swap_operations = swap_operations - .iter() - .map(|swap_operation| swap_operation.into_astroport_swap_operation(api)) - .collect(); + // Error if the offer asset amount is zero + if offer_asset.amount().is_zero() { + return Err(ContractError::NoOfferAssetAmount); + } - // Create the astroport router execute message arguments - let astroport_router_msg_args = RouterExecuteMsg::ExecuteSwapOperations { - operations: astroport_swap_operations, - minimum_receive: None, - to: None, + // Create the astroport pool swap message args + let astroport_pool_swap_msg_args = PairExecuteMsg::Swap { + offer_asset: offer_asset.into_astroport_asset(deps.api)?, + ask_asset_info: None, + belief_price: None, max_spread: Some(MAX_ALLOWED_SLIPPAGE.parse::()?), + to: None, }; - // Create the astroport router swap message - let swap_msg = asset_in.into_wasm_msg( - router_contract_address.to_string(), - to_json_binary(&astroport_router_msg_args)?, + // Create the wasm astroport pool swap message + let swap_msg = offer_asset.into_wasm_msg( + operation.pool, + to_json_binary(&astroport_pool_swap_msg_args)?, )?; - Ok(swap_msg) + Ok(Response::new() + .add_message(swap_msg) + .add_attribute("action", "dispatch_astroport_pool_swap")) } ///////////// @@ -219,9 +218,6 @@ fn create_astroport_swap_msg( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> ContractResult { match msg { - QueryMsg::RouterContractAddress {} => { - to_json_binary(&ROUTER_CONTRACT_ADDRESS.load(deps.storage)?) - } QueryMsg::SimulateSwapExactAssetIn { asset_in, swap_operations, @@ -262,7 +258,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> ContractResult { .map_err(From::from) } -// Queries the astroport router contract to simulate a swap exact amount in +// Queries the astroport pool contracts to simulate a swap exact amount in fn query_simulate_swap_exact_asset_in( deps: Deps, asset_in: Asset, @@ -306,7 +302,7 @@ fn query_simulate_swap_exact_asset_out( Ok(asset_in) } -// Queries the astroport router contract to simulate a swap exact amount in with metadata +// Queries the astroport pool contracts to simulate a swap exact amount in with metadata fn query_simulate_swap_exact_asset_in_with_metadata( deps: Deps, asset_in: Asset, diff --git a/contracts/adapters/swap/astroport/src/error.rs b/contracts/adapters/swap/astroport/src/error.rs index bee2e197..84d8b0e9 100644 --- a/contracts/adapters/swap/astroport/src/error.rs +++ b/contracts/adapters/swap/astroport/src/error.rs @@ -32,4 +32,7 @@ pub enum ContractError { #[error("Operation exceeds max spread limit")] MaxSpreadAssertion, + + #[error("Contract has no balance of offer asset")] + NoOfferAssetAmount, } diff --git a/contracts/adapters/swap/astroport/src/state.rs b/contracts/adapters/swap/astroport/src/state.rs index bcb30c3f..a703dbbc 100644 --- a/contracts/adapters/swap/astroport/src/state.rs +++ b/contracts/adapters/swap/astroport/src/state.rs @@ -2,4 +2,3 @@ use cosmwasm_std::Addr; use cw_storage_plus::Item; pub const ENTRY_POINT_CONTRACT_ADDRESS: Item = Item::new("entry_point_contract_address"); -pub const ROUTER_CONTRACT_ADDRESS: Item = Item::new("router_contract_address"); diff --git a/contracts/adapters/swap/astroport/tests/test_execute_astroport_pool_swap.rs b/contracts/adapters/swap/astroport/tests/test_execute_astroport_pool_swap.rs new file mode 100644 index 00000000..2f3599fd --- /dev/null +++ b/contracts/adapters/swap/astroport/tests/test_execute_astroport_pool_swap.rs @@ -0,0 +1,234 @@ +use std::vec; + +use astroport::{ + asset::{Asset as AstroportAsset, AssetInfo}, + pair::ExecuteMsg as AstroportPairExecuteMsg, +}; +use cosmwasm_std::{ + testing::{mock_dependencies_with_balances, mock_env, mock_info}, + to_json_binary, Addr, Coin, Decimal, QuerierResult, + ReplyOn::Never, + SubMsg, SystemResult, Uint128, WasmMsg, WasmQuery, +}; +use cw20::{BalanceResponse, Cw20ExecuteMsg}; +use skip::swap::{ExecuteMsg, SwapOperation}; +use skip_api_swap_adapter_astroport::error::{ContractError, ContractResult}; +use test_case::test_case; + +/* +Test Cases: + +Expect Success + - Native Swap Operation + - Cw20 Swap Operation + +Expect Error + - No Native Offer Asset In Contract Balance To Swap + - No Cw20 Offer Asset In Contract Balance To Swap + - Unauthorized Caller + + */ + +// Define test parameters +struct Params { + caller: String, + contract_balance: Vec, + swap_operation: SwapOperation, + expected_message: Option, + expected_error: Option, +} + +// Test execute_swap +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![Coin::new(100, "os")], + swap_operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), + }, + expected_message: Some(SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "pool_1".to_string(), + msg: to_json_binary(&AstroportPairExecuteMsg::Swap { + offer_asset: AstroportAsset { + info: AssetInfo::NativeToken { + denom: "os".to_string(), + }, + amount: Uint128::new(100), + }, + ask_asset_info: None, + belief_price: None, + max_spread: Some(Decimal::percent(50)), + to: None, + })?, + funds: vec![Coin::new(100, "os")], + } + .into(), + gas_limit: None, + reply_on: Never, + }), + expected_error: None, + }; + "Native Swap Operation")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![], + swap_operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "neutron123".to_string(), + denom_out: "ua".to_string(), + }, + expected_message: Some(SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "neutron123".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: "pool_1".to_string(), + amount: Uint128::from(100u128), + msg: to_json_binary(&AstroportPairExecuteMsg::Swap { + offer_asset: AstroportAsset { + info: AssetInfo::Token { + contract_addr: Addr::unchecked("neutron123"), + }, + amount: Uint128::new(100), + }, + ask_asset_info: None, + belief_price: None, + max_spread: Some(Decimal::percent(50)), + to: None, + })?, + })?, + funds: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }), + expected_error: None, + }; + "Cw20 Swap Operation")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![], + swap_operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), + }, + expected_message: None, + expected_error: Some(ContractError::NoOfferAssetAmount), + }; + "No Native Offer Asset In Contract Balance To Swap")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![], + swap_operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "randomcw20".to_string(), + denom_out: "ua".to_string(), + }, + expected_message: None, + expected_error: Some(ContractError::NoOfferAssetAmount), + }; + "No Cw20 Offer Asset In Contract Balance To Swap")] +#[test_case( + Params { + caller: "random".to_string(), + contract_balance: vec![ + Coin::new(100, "un"), + ], + swap_operation: SwapOperation{ + pool: "".to_string(), + denom_in: "".to_string(), + denom_out: "".to_string(), + }, + expected_message: None, + expected_error: Some(ContractError::Unauthorized), + }; + "Unauthorized Caller - Expect Error")] +fn test_execute_astroport_pool_swap(params: Params) -> ContractResult<()> { + // Create mock dependencies + let mut deps = + mock_dependencies_with_balances(&[("swap_contract_address", ¶ms.contract_balance)]); + + // Create mock wasm handler to handle the cw20 balance queries + let wasm_handler = |query: &WasmQuery| -> QuerierResult { + match query { + WasmQuery::Smart { contract_addr, .. } => { + if contract_addr == "neutron123" { + SystemResult::Ok( + ContractResult::Ok( + to_json_binary(&BalanceResponse { + balance: Uint128::from(100u128), + }) + .unwrap(), + ) + .into(), + ) + } else { + SystemResult::Ok( + ContractResult::Ok( + to_json_binary(&BalanceResponse { + balance: Uint128::from(0u128), + }) + .unwrap(), + ) + .into(), + ) + } + } + _ => panic!("Unsupported query: {:?}", query), + } + }; + deps.querier.update_wasm(wasm_handler); + + // Create mock env + let mut env = mock_env(); + env.contract.address = Addr::unchecked("swap_contract_address"); + + // Create mock info + let info = mock_info(¶ms.caller, &[]); + + // Call execute_astroport_pool_swap with the given test parameters + let res = skip_api_swap_adapter_astroport::contract::execute( + deps.as_mut(), + env, + info, + ExecuteMsg::AstroportPoolSwap { + operation: params.swap_operation, + }, + ); + + // Assert the behavior is correct + match res { + Ok(res) => { + // Assert the test did not expect an error + assert!( + params.expected_error.is_none(), + "expected test to error with {:?}, but it succeeded", + params.expected_error + ); + + // Assert the messages are correct + assert_eq!(res.messages[0], params.expected_message.unwrap()); + } + Err(err) => { + // Assert the test expected an error + assert!( + params.expected_error.is_some(), + "expected test to succeed, but it errored with {:?}", + err + ); + + // Assert the error is correct + assert_eq!(err, params.expected_error.unwrap()); + } + } + + Ok(()) +} diff --git a/contracts/adapters/swap/astroport/tests/test_execute_receive.rs b/contracts/adapters/swap/astroport/tests/test_execute_receive.rs index ad73c15b..3e961006 100644 --- a/contracts/adapters/swap/astroport/tests/test_execute_receive.rs +++ b/contracts/adapters/swap/astroport/tests/test_execute_receive.rs @@ -1,15 +1,11 @@ -use astroport::{ - asset::AssetInfo, - router::{ExecuteMsg as RouterExecuteMsg, SwapOperation as AstroportSwapOperation}, -}; use core::panic; use cosmwasm_std::{ testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Coin, ContractResult as SystemContractResult, Decimal, QuerierResult, + to_json_binary, Addr, Coin, ContractResult as SystemContractResult, QuerierResult, ReplyOn::Never, SubMsg, SystemResult, Uint128, WasmMsg, WasmQuery, }; -use cw20::{BalanceResponse, Cw20Coin, Cw20ExecuteMsg, Cw20ReceiveMsg}; +use cw20::{BalanceResponse, Cw20Coin, Cw20ReceiveMsg}; use cw_utils::PaymentError::NonPayable; use skip::{ asset::Asset, @@ -18,7 +14,7 @@ use skip::{ }; use skip_api_swap_adapter_astroport::{ error::{ContractError, ContractResult}, - state::{ENTRY_POINT_CONTRACT_ADDRESS, ROUTER_CONTRACT_ADDRESS}, + state::ENTRY_POINT_CONTRACT_ADDRESS, }; use test_case::test_case; @@ -64,25 +60,13 @@ struct Params { SubMsg { id: 0, msg: WasmMsg::Execute { - contract_addr: "neutron123".to_string(), - msg: to_json_binary(&Cw20ExecuteMsg::Send { - contract: "router_contract".to_string(), - amount: Uint128::from(100u128), - msg: to_json_binary(&RouterExecuteMsg::ExecuteSwapOperations { - operations: vec![ - AstroportSwapOperation::AstroSwap { - offer_asset_info: AssetInfo::Token { - contract_addr: Addr::unchecked("neutron123"), - }, - ask_asset_info: AssetInfo::NativeToken { - denom: "ua".to_string(), - }, - } - ], - minimum_receive: None, - to: None, - max_spread: Some(Decimal::percent(50)), - })?, + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::AstroportPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "neutron123".to_string(), + denom_out: "ua".to_string(), + } })?, funds: vec![], }.into(), @@ -126,25 +110,13 @@ struct Params { SubMsg { id: 0, msg: WasmMsg::Execute { - contract_addr: "neutron123".to_string(), - msg: to_json_binary(&Cw20ExecuteMsg::Send { - contract: "router_contract".to_string(), - amount: Uint128::from(100u128), - msg: to_json_binary(&RouterExecuteMsg::ExecuteSwapOperations { - operations: vec![ - AstroportSwapOperation::AstroSwap { - offer_asset_info: AssetInfo::Token { - contract_addr: Addr::unchecked("neutron123"), - }, - ask_asset_info: AssetInfo::Token { - contract_addr: Addr::unchecked("neutron987"), - }, - } - ], - minimum_receive: None, - to: None, - max_spread: Some(Decimal::percent(50)), - })?, + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::AstroportPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "neutron123".to_string(), + denom_out: "neutron987".to_string(), + } })?, funds: vec![], }.into(), @@ -223,9 +195,6 @@ fn test_execute_swap(params: Params) -> ContractResult<()> { // Store the entry point contract address ENTRY_POINT_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("entry_point"))?; - // Store the router contract address - ROUTER_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("router_contract"))?; - // Call execute_swap with the given test parameters let res = skip_api_swap_adapter_astroport::contract::execute( deps.as_mut(), diff --git a/contracts/adapters/swap/astroport/tests/test_execute_swap.rs b/contracts/adapters/swap/astroport/tests/test_execute_swap.rs index 8552ab9b..c23d5ead 100644 --- a/contracts/adapters/swap/astroport/tests/test_execute_swap.rs +++ b/contracts/adapters/swap/astroport/tests/test_execute_swap.rs @@ -1,17 +1,13 @@ -use astroport::{ - asset::AssetInfo, - router::{ExecuteMsg as RouterExecuteMsg, SwapOperation as AstroportSwapOperation}, -}; use cosmwasm_std::{ testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Coin, Decimal, + to_json_binary, Addr, Coin, ReplyOn::Never, SubMsg, WasmMsg, }; use skip::swap::{ExecuteMsg, SwapOperation}; use skip_api_swap_adapter_astroport::{ error::{ContractError, ContractResult}, - state::{ENTRY_POINT_CONTRACT_ADDRESS, ROUTER_CONTRACT_ADDRESS}, + state::ENTRY_POINT_CONTRACT_ADDRESS, }; use test_case::test_case; @@ -21,7 +17,7 @@ Test Cases: Expect Success - One Swap Operation - Multiple Swap Operations - - No Swap Operations (This is prevented in the entry point contract; and will fail on Astroport router if attempted) + - No Swap Operations (This is prevented in the entry point contract; and will not add any swap messages to the response) Expect Error - Unauthorized Caller (Only the stored entry point contract can call this function) @@ -55,25 +51,16 @@ struct Params { SubMsg { id: 0, msg: WasmMsg::Execute { - contract_addr: "router_contract".to_string(), - msg: to_json_binary(&RouterExecuteMsg::ExecuteSwapOperations { - operations: vec![ - AstroportSwapOperation::AstroSwap { - offer_asset_info: AssetInfo::NativeToken { - denom: "os".to_string(), - }, - ask_asset_info: AssetInfo::NativeToken { - denom: "ua".to_string(), - }, - } - ], - minimum_receive: None, - to: None, - max_spread: Some(Decimal::percent(50)), + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::AstroportPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), + } })?, - funds: vec![Coin::new(100, "os")], - } - .into(), + funds: vec![], + }.into(), gas_limit: None, reply_on: Never, }, @@ -112,76 +99,35 @@ struct Params { } ], expected_messages: vec![ - SubMsg { - id: 0, - msg: WasmMsg::Execute { - contract_addr: "router_contract".to_string(), - msg: to_json_binary(&RouterExecuteMsg::ExecuteSwapOperations { - operations: vec![ - AstroportSwapOperation::AstroSwap { - offer_asset_info: AssetInfo::NativeToken { - denom: "os".to_string(), - }, - ask_asset_info: AssetInfo::NativeToken { - denom: "ua".to_string(), - }, - }, - AstroportSwapOperation::AstroSwap { - offer_asset_info: AssetInfo::NativeToken { - denom: "ua".to_string(), - }, - ask_asset_info: AssetInfo::NativeToken { - denom: "un".to_string(), - }, - } - ], - minimum_receive: None, - to: None, - max_spread: Some(Decimal::percent(50)), - })?, - funds: vec![Coin::new(100, "os")], - } - .into(), - gas_limit: None, - reply_on: Never, - }, SubMsg { id: 0, msg: WasmMsg::Execute { contract_addr: "swap_contract_address".to_string(), - msg: to_json_binary(&ExecuteMsg::TransferFundsBack { - return_denom: "un".to_string(), - swapper: Addr::unchecked("entry_point"), + msg: to_json_binary(&ExecuteMsg::AstroportPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), + } })?, funds: vec![], - } - .into(), + }.into(), gas_limit: None, reply_on: Never, }, - ], - expected_error: None, - }; - "Multiple Swap Operations")] -#[test_case( - Params { - caller: "entry_point".to_string(), - info_funds: vec![Coin::new(100, "os")], - swap_operations: vec![], - expected_messages: vec![ SubMsg { id: 0, msg: WasmMsg::Execute { - contract_addr: "router_contract".to_string(), - msg: to_json_binary(&RouterExecuteMsg::ExecuteSwapOperations { - operations: vec![], - minimum_receive: None, - to: None, - max_spread: Some(Decimal::percent(50)), + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::AstroportPoolSwap { + operation: SwapOperation { + pool: "pool_2".to_string(), + denom_in: "ua".to_string(), + denom_out: "un".to_string(), + } })?, - funds: vec![Coin::new(100, "os")], - } - .into(), + funds: vec![], + }.into(), gas_limit: None, reply_on: Never, }, @@ -190,7 +136,7 @@ struct Params { msg: WasmMsg::Execute { contract_addr: "swap_contract_address".to_string(), msg: to_json_binary(&ExecuteMsg::TransferFundsBack { - return_denom: "ua".to_string(), + return_denom: "un".to_string(), swapper: Addr::unchecked("entry_point"), })?, funds: vec![], @@ -200,6 +146,15 @@ struct Params { reply_on: Never, }, ], + expected_error: None, + }; + "Multiple Swap Operations")] +#[test_case( + Params { + caller: "entry_point".to_string(), + info_funds: vec![Coin::new(100, "os")], + swap_operations: vec![], + expected_messages: vec![], expected_error: Some(ContractError::SwapOperationsEmpty), }; "No Swap Operations")] @@ -252,9 +207,6 @@ fn test_execute_swap(params: Params) -> ContractResult<()> { // Store the entry point contract address ENTRY_POINT_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("entry_point"))?; - // Store the router contract address - ROUTER_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("router_contract"))?; - // Call execute_swap with the given test parameters let res = skip_api_swap_adapter_astroport::contract::execute( deps.as_mut(), diff --git a/contracts/adapters/swap/lido-satellite/src/contract.rs b/contracts/adapters/swap/lido-satellite/src/contract.rs index 23491428..1c5400fe 100644 --- a/contracts/adapters/swap/lido-satellite/src/contract.rs +++ b/contracts/adapters/swap/lido-satellite/src/contract.rs @@ -237,9 +237,6 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> ContractResult { spot_price, }) } - _ => { - unimplemented!() - } } .map_err(From::from) } diff --git a/contracts/adapters/swap/lido-satellite/tests/test_execute_swap.rs b/contracts/adapters/swap/lido-satellite/tests/test_execute_swap.rs index bf85a9ac..6f980eab 100644 --- a/contracts/adapters/swap/lido-satellite/tests/test_execute_swap.rs +++ b/contracts/adapters/swap/lido-satellite/tests/test_execute_swap.rs @@ -169,7 +169,7 @@ fn test_execute_swap(params: Params) -> ContractResult<()> { // Store the entry point contract address ENTRY_POINT_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("entry_point"))?; - // Store the router contract address + // Store the lido satellite contract address LIDO_SATELLITE_CONTRACT_ADDRESS.save( deps.as_mut().storage, &Addr::unchecked("lido_satellite_contract"), diff --git a/contracts/adapters/swap/osmosis-poolmanager/src/bin/osmosis-poolmanager-schema.rs b/contracts/adapters/swap/osmosis-poolmanager/src/bin/osmosis-poolmanager-schema.rs index 71102730..4f4733f0 100644 --- a/contracts/adapters/swap/osmosis-poolmanager/src/bin/osmosis-poolmanager-schema.rs +++ b/contracts/adapters/swap/osmosis-poolmanager/src/bin/osmosis-poolmanager-schema.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::write_api; -use skip::swap::{ExecuteMsg, OsmosisInstantiateMsg as InstantiateMsg, QueryMsg}; +use skip::swap::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/adapters/swap/osmosis-poolmanager/src/contract.rs b/contracts/adapters/swap/osmosis-poolmanager/src/contract.rs index 82070c71..4fea5a98 100644 --- a/contracts/adapters/swap/osmosis-poolmanager/src/contract.rs +++ b/contracts/adapters/swap/osmosis-poolmanager/src/contract.rs @@ -16,9 +16,9 @@ use skip::{ asset::Asset, proto_coin::ProtoCoin, swap::{ - convert_swap_operations, execute_transfer_funds_back, ExecuteMsg, MigrateMsg, - OsmosisInstantiateMsg as InstantiateMsg, QueryMsg, SimulateSwapExactAssetInResponse, - SimulateSwapExactAssetOutResponse, SwapOperation, + convert_swap_operations, execute_transfer_funds_back, ExecuteMsg, InstantiateMsg, + MigrateMsg, QueryMsg, SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse, + SwapOperation, }, }; use std::str::FromStr; @@ -210,9 +210,6 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> ContractResult { swap_operations, include_spot_price, )?), - _ => { - unimplemented!() - } } .map_err(From::from) } diff --git a/packages/skip/src/swap.rs b/packages/skip/src/swap.rs index 70d71e80..a127caac 100644 --- a/packages/skip/src/swap.rs +++ b/packages/skip/src/swap.rs @@ -23,21 +23,13 @@ pub struct MigrateMsg {} /// INSTANTIATE /// /////////////////// -// The OsmosisInstantiateMsg struct defines the initialization parameters for the -// Osmosis Poolmanager swap adapter contract. +// The InstantiateMsg struct defines the initialization parameters for the +// Osmosis Poolmanager and Astroport swap adapter contracts. #[cw_serde] -pub struct OsmosisInstantiateMsg { +pub struct InstantiateMsg { pub entry_point_contract_address: String, } -// The NeutronInstantiateMsg struct defines the initialization parameters for the -// Neutron Astroport swap adapter contract. -#[cw_serde] -pub struct AstroportInstantiateMsg { - pub entry_point_contract_address: String, - pub router_contract_address: String, -} - #[cw_serde] pub struct LidoSatelliteInstantiateMsg { pub entry_point_contract_address: String, @@ -55,6 +47,7 @@ pub enum ExecuteMsg { Receive(Cw20ReceiveMsg), Swap { operations: Vec }, TransferFundsBack { swapper: Addr, return_denom: String }, + AstroportPoolSwap { operation: SwapOperation }, // Only used for the astroport swap adapter contract } #[cw_serde] @@ -67,13 +60,9 @@ pub enum Cw20HookMsg { ///////////////////////// // The QueryMsg enum defines the queries the swap adapter contracts provide. -// RouterContractAddress is only implemented for Astroport swap adapter contracts. #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - // RouterContractAddress returns the address of the router contract - #[returns(Addr)] - RouterContractAddress {}, // SimulateSwapExactAssetOut returns the asset in necessary to receive the specified asset out #[returns(Asset)] SimulateSwapExactAssetOut { diff --git a/scripts/configs/neutron.toml b/scripts/configs/neutron.toml index adbca842..d1cf0531 100644 --- a/scripts/configs/neutron.toml +++ b/scripts/configs/neutron.toml @@ -31,7 +31,6 @@ ENTRY_POINT_PRE_GENERATED_ADDRESS = "
"
 
 [[swap_venues]]
 name = "neutron-astroport"
-router_contract_address = "neutron1eeyntmsq448c68ez06jsy6h2mtjke5tpuplnwtjfwcdznqmw72kswnlmm0"
 swap_adapter_path = "../artifacts/skip_api_swap_adapter_astroport-aarch64.wasm"
 
 [[swap_venues]]
@@ -41,7 +40,6 @@ swap_adapter_path = "../artifacts/skip_api_swap_adapter_lido_satellite-aarch64.w
 
 [[testnet_swap_venues]]
 name = "testnet-neutron-astroport"
-router_contract_address = "neutron12jm24l9lr9cupufqjuxpdjnnweana4h66tsx5cl800mke26td26sq7m05p"
 swap_adapter_path = "../artifacts/skip_api_swap_adapter_astroport-aarch64.wasm"
 
 [[testnet_swap_venues]]
diff --git a/scripts/configs/terra.toml b/scripts/configs/terra.toml
index f1e5d314..31697c6d 100644
--- a/scripts/configs/terra.toml
+++ b/scripts/configs/terra.toml
@@ -31,10 +31,8 @@ ENTRY_POINT_PRE_GENERATED_ADDRESS = "
"
 
 [[swap_venues]]
 name = "terra-astroport"
-router_contract_address = "terra1j8hayvehh3yy02c2vtw5fdhz9f4drhtee8p5n5rguvg3nyd6m83qd2y90a"
 swap_adapter_path = "../artifacts/skip_api_swap_adapter_astroport-aarch64.wasm"
 
 [[testnet_swap_venues]]
 name = "testnet-terra-astroport"
-router_contract_address = "terra1na348k6rvwxje9jj6ftpsapfeyaejxjeq6tuzdmzysps20l6z23smnlv64"
 swap_adapter_path = "../artifacts/skip_api_swap_adapter_astroport-aarch64.wasm"
\ No newline at end of file
diff --git a/scripts/deploy.ipynb b/scripts/deploy.ipynb
index c9fda7a0..b2e6d872 100644
--- a/scripts/deploy.ipynb
+++ b/scripts/deploy.ipynb
@@ -115,16 +115,9 @@
     "    entry_point_contract_code_id = store_contract(client, wallet, ENTRY_POINT_CONTRACT_PATH, \"entry_point\", PERMISSIONED_UPLOADER_ADDRESS)\n",
     "    \n",
     "    # Intantiate contracts\n",
-    "    if \"router_contract_address\" in config[\"swap_venues\"][0]:\n",
-    "        router_contract_address = config[\"swap_venues\"][0][\"router_contract_address\"]\n",
-    "        swap_adapter_args = {\n",
-    "            \"router_contract_address\": router_contract_address,\n",
-    "            \"entry_point_contract_address\": ENTRY_POINT_PRE_GENERATED_ADDRESS,\n",
-    "            }\n",
-    "    else:\n",
-    "        swap_adapter_args = {\n",
-    "            \"entry_point_contract_address\": ENTRY_POINT_PRE_GENERATED_ADDRESS\n",
-    "            }\n",
+    "    swap_adapter_args = {\n",
+    "        \"entry_point_contract_address\": ENTRY_POINT_PRE_GENERATED_ADDRESS\n",
+    "        }\n",
     "    swap_adapter_contract_address = instantiate_contract(\n",
     "        client, \n",
     "        wallet, \n",
diff --git a/scripts/deploy.py b/scripts/deploy.py
index 50870b82..82fe6423 100644
--- a/scripts/deploy.py
+++ b/scripts/deploy.py
@@ -151,8 +151,6 @@ def main():
         swap_adapter_instantiate_args = {
             "entry_point_contract_address": ENTRY_POINT_PRE_GENERATED_ADDRESS
         }
-        if "router_contract_address" in venue:
-            swap_adapter_instantiate_args["router_contract_address"] = venue["router_contract_address"]
         if "lido_satellite_contract_address" in venue:
             swap_adapter_instantiate_args["lido_satellite_contract_address"] = venue["lido_satellite_contract_address"]