From 6abdc31b5dfe4111d8c7312f80ee7c7ce5815368 Mon Sep 17 00:00:00 2001 From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com> Date: Thu, 4 Jan 2024 12:26:43 -0700 Subject: [PATCH 1/6] remove use of router contract, swap directly on pools --- .../adapters/swap/astroport/src/contract.rs | 120 ++++++++---------- .../adapters/swap/astroport/src/state.rs | 1 - .../swap/lido-satellite/src/contract.rs | 3 - .../swap/osmosis-poolmanager/src/contract.rs | 3 - packages/skip/src/swap.rs | 4 +- 5 files changed, 57 insertions(+), 74 deletions(-) diff --git a/contracts/adapters/swap/astroport/src/contract.rs b/contracts/adapters/swap/astroport/src/contract.rs index f19ac1ed..bf3d5e2c 100644 --- a/contracts/adapters/swap/astroport/src/contract.rs +++ b/contracts/adapters/swap/astroport/src/contract.rs @@ -1,23 +1,20 @@ 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, @@ -59,21 +56,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 +87,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 +105,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 +118,9 @@ pub fn execute( swapper, return_denom, )?), + ExecuteMsg::AstroportPoolSwap { operation } => { + execute_astroport_pool_swap(deps, env, info, operation) + } } } @@ -138,7 +128,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 +138,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 +168,43 @@ 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); + } -// 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(); + // Get the current asset available on contract to swap in + let offer_asset = get_current_asset_available(&deps, &env, &operation.denom_in)?; - // 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 +214,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 +254,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 +298,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/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/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/osmosis-poolmanager/src/contract.rs b/contracts/adapters/swap/osmosis-poolmanager/src/contract.rs index 82070c71..0ea4d23c 100644 --- a/contracts/adapters/swap/osmosis-poolmanager/src/contract.rs +++ b/contracts/adapters/swap/osmosis-poolmanager/src/contract.rs @@ -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..f5ec7b16 100644 --- a/packages/skip/src/swap.rs +++ b/packages/skip/src/swap.rs @@ -55,6 +55,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] @@ -71,9 +72,6 @@ pub enum Cw20HookMsg { #[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 { From b4a5115596f856a839f268ca7a7323ac6243e695 Mon Sep 17 00:00:00 2001 From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:29:25 -0700 Subject: [PATCH 2/6] update existing tests --- .../astroport/tests/test_execute_receive.rs | 65 +++------ .../swap/astroport/tests/test_execute_swap.rs | 124 ++++++------------ 2 files changed, 55 insertions(+), 134 deletions(-) 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(), From db40d13353d008d3cc027ecbb9f9d2205da13320 Mon Sep 17 00:00:00 2001 From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:35:55 -0700 Subject: [PATCH 3/6] remove router contract from deploy script and configs --- scripts/configs/neutron.toml | 2 -- scripts/configs/terra.toml | 2 -- scripts/deploy.py | 2 -- 3 files changed, 6 deletions(-) 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.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"]
         

From 20f94b80baf1f632f5906875b87b1f89424c413a Mon Sep 17 00:00:00 2001
From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com>
Date: Thu, 4 Jan 2024 15:11:25 -0700
Subject: [PATCH 4/6] add unit tests for ExecuteMsg::AstroportPoolSwap

---
 .../adapters/swap/astroport/src/contract.rs   |   5 +
 .../adapters/swap/astroport/src/error.rs      |   3 +
 .../tests/test_execute_astroport_pool_swap.rs | 234 ++++++++++++++++++
 3 files changed, 242 insertions(+)
 create mode 100644 contracts/adapters/swap/astroport/tests/test_execute_astroport_pool_swap.rs

diff --git a/contracts/adapters/swap/astroport/src/contract.rs b/contracts/adapters/swap/astroport/src/contract.rs
index bf3d5e2c..2353e8dc 100644
--- a/contracts/adapters/swap/astroport/src/contract.rs
+++ b/contracts/adapters/swap/astroport/src/contract.rs
@@ -187,6 +187,11 @@ fn execute_astroport_pool_swap(
     // Get the current asset available on contract to swap in
     let offer_asset = get_current_asset_available(&deps, &env, &operation.denom_in)?;
 
+    // Error if the offer asset amount is zero
+    if offer_asset.amount().is_zero() {
+        return Err(ContractError::NoOfferAssetAmount);
+    }
+
     // Create the astroport pool swap message args
     let astroport_pool_swap_msg_args = PairExecuteMsg::Swap {
         offer_asset: offer_asset.into_astroport_asset(deps.api)?,
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/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(())
+}

From 75f570849d22904f872c88a7aaeee71957cde930 Mon Sep 17 00:00:00 2001
From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com>
Date: Fri, 5 Jan 2024 08:43:44 -0700
Subject: [PATCH 5/6] remove router in code comments

---
 contracts/adapters/swap/astroport/README.md   | 24 ++++---------------
 .../lido-satellite/tests/test_execute_swap.rs |  2 +-
 scripts/deploy.ipynb                          | 13 +++-------
 3 files changed, 8 insertions(+), 31 deletions(-)

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/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/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",

From f3ec78caa19d5cd1a3fb4845dc05d01515064eec Mon Sep 17 00:00:00 2001
From: Jeremy Liu <31809888+NotJeremyLiu@users.noreply.github.com>
Date: Fri, 5 Jan 2024 08:44:17 -0700
Subject: [PATCH 6/6] remove router from instantiate message and consolidate
 InstantiateMsg

---
 .../swap/astroport/src/bin/astroport-schema.rs    |  2 +-
 contracts/adapters/swap/astroport/src/contract.rs |  5 ++---
 .../src/bin/osmosis-poolmanager-schema.rs         |  2 +-
 .../swap/osmosis-poolmanager/src/contract.rs      |  6 +++---
 packages/skip/src/swap.rs                         | 15 +++------------
 5 files changed, 10 insertions(+), 20 deletions(-)

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 2353e8dc..348531b7 100644
--- a/contracts/adapters/swap/astroport/src/contract.rs
+++ b/contracts/adapters/swap/astroport/src/contract.rs
@@ -16,9 +16,8 @@ use cw_utils::one_coin;
 use skip::{
     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,
     },
 };
 
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 0ea4d23c..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;
diff --git a/packages/skip/src/swap.rs b/packages/skip/src/swap.rs
index f5ec7b16..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,
@@ -68,7 +60,6 @@ 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 {