Skip to content

Commit

Permalink
Update contract types to support route splitting (#98)
Browse files Browse the repository at this point in the history
* update contract types to support route splitting

* fmt

* update schema

* convert routes to single operations vector and error if more than one route

* convert routes to single operations vector and error if more than one route

* remove useless import

* fix test
  • Loading branch information
thal0x committed Apr 18, 2024
1 parent eb37618 commit ec1fd57
Show file tree
Hide file tree
Showing 24 changed files with 1,451 additions and 705 deletions.
20 changes: 18 additions & 2 deletions contracts/adapters/swap/astroport/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use cw20::{Cw20Coin, Cw20ReceiveMsg};
use cw_utils::one_coin;
use skip::{
asset::{get_current_asset_available, Asset},
error::SkipError,
swap::{
execute_transfer_funds_back, Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg,
SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse, SwapOperation,
Expand Down Expand Up @@ -101,7 +102,15 @@ 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, operations),
Cw20HookMsg::Swap { routes } => {
if routes.len() != 1 {
return Err(ContractError::Skip(SkipError::MustBeSingleRoute));
}

let operations = routes.first().unwrap().operations.clone();

execute_swap(deps, env, info, operations)
}
}
}

Expand All @@ -118,8 +127,15 @@ pub fn execute(
) -> ContractResult<Response> {
match msg {
ExecuteMsg::Receive(cw20_msg) => receive_cw20(deps, env, info, cw20_msg),
ExecuteMsg::Swap { operations } => {
ExecuteMsg::Swap { routes } => {
one_coin(&info)?;

if routes.len() != 1 {
return Err(ContractError::Skip(SkipError::MustBeSingleRoute));
}

let operations = routes.first().unwrap().operations.clone();

execute_swap(deps, env, info, operations)
}
ExecuteMsg::TransferFundsBack {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::vec;

use astroport::{
asset::{Asset as AstroportAsset, AssetInfo},
pair::{Cw20HookMsg as AstroportPairCw20HookMsg, ExecuteMsg as AstroportPairExecuteMsg},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use cw_utils::PaymentError::NonPayable;
use skip::{
asset::Asset,
error::SkipError::Payment,
swap::{ExecuteMsg, SwapOperation},
swap::{ExecuteMsg, Route, SwapOperation},
};
use skip_api_swap_adapter_astroport::{
error::{ContractError, ContractResult},
Expand Down Expand Up @@ -208,7 +208,10 @@ fn test_execute_swap(params: Params) -> ContractResult<()> {
sender: params.caller,
amount: params.sent_asset.amount(),
msg: to_json_binary(&ExecuteMsg::Swap {
operations: params.swap_operations,
routes: vec![Route {
offer_asset: params.sent_asset,
operations: params.swap_operations,
}],
})
.unwrap(),
}),
Expand Down
18 changes: 16 additions & 2 deletions contracts/adapters/swap/astroport/tests/test_execute_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use cosmwasm_std::{
ReplyOn::Never,
SubMsg, WasmMsg,
};
use skip::swap::{ExecuteMsg, SwapOperation};
use skip::{
asset::Asset,
swap::{ExecuteMsg, Route, SwapOperation},
};
use skip_api_swap_adapter_astroport::{
error::{ContractError, ContractResult},
state::ENTRY_POINT_CONTRACT_ADDRESS,
Expand All @@ -30,6 +33,7 @@ Expect Error
struct Params {
caller: String,
info_funds: Vec<Coin>,
offer_asset: Asset,
swap_operations: Vec<SwapOperation>,
expected_messages: Vec<SubMsg>,
expected_error: Option<ContractError>,
Expand All @@ -39,6 +43,7 @@ struct Params {
#[test_case(
Params {
caller: "entry_point".to_string(),
offer_asset: Asset::Native(Coin::new(100, "os")),
info_funds: vec![Coin::new(100, "os")],
swap_operations: vec![
SwapOperation {
Expand Down Expand Up @@ -88,6 +93,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![Coin::new(100, "os")],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![
SwapOperation {
pool: "pool_1".to_string(),
Expand Down Expand Up @@ -159,6 +165,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![Coin::new(100, "os")],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![],
expected_messages: vec![],
expected_error: Some(ContractError::SwapOperationsEmpty),
Expand All @@ -168,6 +175,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![],
expected_messages: vec![],
expected_error: Some(ContractError::Payment(cw_utils::PaymentError::NoFunds{})),
Expand All @@ -180,6 +188,7 @@ struct Params {
Coin::new(100, "un"),
Coin::new(100, "os"),
],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![],
expected_messages: vec![],
expected_error: Some(ContractError::Payment(cw_utils::PaymentError::MultipleDenoms{})),
Expand All @@ -191,6 +200,7 @@ struct Params {
info_funds: vec![
Coin::new(100, "un"),
],
offer_asset: Asset::Native(Coin::new(100, "un")),
swap_operations: vec![],
expected_messages: vec![],
expected_error: Some(ContractError::Unauthorized),
Expand Down Expand Up @@ -219,7 +229,11 @@ fn test_execute_swap(params: Params) -> ContractResult<()> {
env,
info,
ExecuteMsg::Swap {
operations: params.swap_operations.clone(),
// operations: params.swap_operations.clone(),
routes: vec![Route {
offer_asset: params.offer_asset,
operations: params.swap_operations,
}],
},
);

Expand Down
17 changes: 15 additions & 2 deletions contracts/adapters/swap/dexter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use dexter::{
};
use skip::{
asset::Asset,
error::SkipError,
swap::{
execute_transfer_funds_back, Cw20HookMsg, DexterAdapterInstantiateMsg, ExecuteMsg,
MigrateMsg, QueryMsg, SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse,
Expand Down Expand Up @@ -101,7 +102,13 @@ pub fn receive_cw20(
info.sender = deps.api.addr_validate(&cw20_msg.sender)?;

match from_json(&cw20_msg.msg)? {
Cw20HookMsg::Swap { operations } => {
Cw20HookMsg::Swap { routes } => {
if routes.len() != 1 {
return Err(ContractError::Skip(SkipError::MustBeSingleRoute));
}

let operations = routes.first().unwrap().operations.clone();

execute_swap(deps, env, info, sent_asset.amount(), operations)
}
}
Expand All @@ -120,7 +127,13 @@ pub fn execute(
) -> ContractResult<Response> {
match msg {
ExecuteMsg::Receive(cw20_msg) => receive_cw20(deps, env, info, cw20_msg),
ExecuteMsg::Swap { operations } => {
ExecuteMsg::Swap { routes } => {
if routes.len() != 1 {
return Err(ContractError::Skip(SkipError::MustBeSingleRoute));
}

let operations = routes.first().unwrap().operations.clone();

// validate that there's at least one swap operation
if operations.is_empty() {
return Err(ContractError::SwapOperationsEmpty);
Expand Down
55 changes: 35 additions & 20 deletions contracts/adapters/swap/dexter/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use dexter::{
vault::{self, FeeInfo, NativeAssetPrecisionInfo},
};
use dexter_stable_pool::state::{AssetScalingFactor, StablePoolParams};
use skip::{asset::Asset, swap::SwapOperation};
use skip::{
asset::Asset,
swap::{Route, SwapOperation},
};
use utils::{
instantiate_dexter_contracts_and_pools, instantiate_dexter_swap_adapter_contract,
DexterInstantiateResponse,
Expand Down Expand Up @@ -391,11 +394,17 @@ pub fn test_swap() {

// 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(),
interface: None,
routes: vec![Route {
offer_asset: Asset::Native(Coin {
denom: "uxprt".to_string(),
amount: Uint128::from(1_000_000u128),
}),
operations: vec![SwapOperation {
pool: "1".to_string(),
denom_in: "uxprt".to_string(),
denom_out: "stk/uxprt".to_string(),
interface: None,
}],
}],
};

Expand Down Expand Up @@ -439,20 +448,26 @@ pub fn test_swap() {

// perform a swap with multiple pools
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(),
interface: None,
},
SwapOperation {
pool: "2".to_string(),
denom_in: "stk/uxprt".to_string(),
denom_out: "stk/uatom".to_string(),
interface: None,
},
],
routes: vec![Route {
offer_asset: Asset::Native(Coin {
denom: "uxprt".to_string(),
amount: Uint128::from(1_000_000u128),
}),
operations: vec![
SwapOperation {
pool: "1".to_string(),
denom_in: "uxprt".to_string(),
denom_out: "stk/uxprt".to_string(),
interface: None,
},
SwapOperation {
pool: "2".to_string(),
denom_in: "stk/uxprt".to_string(),
denom_out: "stk/uatom".to_string(),
interface: None,
},
],
}],
};

// execute the swap
Expand Down
18 changes: 16 additions & 2 deletions contracts/adapters/swap/dexter/tests/test_execute_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use cosmwasm_std::{
ReplyOn::Never,
SubMsg, Uint128, WasmMsg,
};
use skip::swap::{ExecuteMsg, SwapOperation};
use skip::{
asset::Asset,
swap::{ExecuteMsg, Route, SwapOperation},
};
use skip_api_swap_adapter_dexter::{
error::ContractResult,
state::{DEXTER_ROUTER_ADDRESS, DEXTER_VAULT_ADDRESS, ENTRY_POINT_CONTRACT_ADDRESS},
Expand Down Expand Up @@ -35,6 +38,7 @@ Expect Error
struct Params {
caller: String,
info_funds: Vec<Coin>,
offer_asset: Asset,
swap_operations: Vec<SwapOperation>,
expected_messages: Vec<SubMsg>,
expected_error_string: String,
Expand All @@ -45,6 +49,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![Coin::new(100, "uxprt")],
offer_asset: Asset::Native(Coin::new(100, "uxprt")),
swap_operations: vec![
SwapOperation {
pool: "1".to_string(),
Expand Down Expand Up @@ -104,6 +109,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![Coin::new(100, "os")],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![
SwapOperation {
pool: "1".to_string(),
Expand Down Expand Up @@ -178,6 +184,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![Coin::new(100, "os")],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![],
expected_messages: vec![
SubMsg {
Expand Down Expand Up @@ -216,6 +223,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![
SwapOperation {
pool: "1".to_string(),
Expand All @@ -235,6 +243,7 @@ struct Params {
Coin::new(100, "os"),
Coin::new(100, "uatom"),
],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![
SwapOperation {
pool: "1".to_string(),
Expand All @@ -251,6 +260,7 @@ struct Params {
Params {
caller: "entry_point".to_string(),
info_funds: vec![Coin::new(100, "os")],
offer_asset: Asset::Native(Coin::new(100, "os")),
swap_operations: vec![
SwapOperation {
pool: "pool_1".to_string(),
Expand All @@ -270,6 +280,7 @@ struct Params {
Coin::new(100, "uxprt"),
// Coin::new(100, "os"),
],
offer_asset: Asset::Native(Coin::new(100, "uxprt")),
swap_operations: vec![
SwapOperation {
pool: "1".to_string(),
Expand Down Expand Up @@ -307,7 +318,10 @@ fn test_execute_swap(params: Params) -> ContractResult<()> {
env,
info,
ExecuteMsg::Swap {
operations: params.swap_operations.clone(),
routes: vec![Route {
offer_asset: params.offer_asset,
operations: params.swap_operations.clone(),
}],
},
);

Expand Down
11 changes: 10 additions & 1 deletion contracts/adapters/swap/lido-satellite/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use cw2::set_contract_version;
use cw_utils::one_coin;
use skip::{
asset::Asset,
error::SkipError,
swap::{
execute_transfer_funds_back, ExecuteMsg, LidoSatelliteInstantiateMsg as InstantiateMsg,
MigrateMsg, QueryMsg, SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse,
Expand Down Expand Up @@ -95,7 +96,15 @@ pub fn execute(
msg: ExecuteMsg,
) -> ContractResult<Response> {
match msg {
ExecuteMsg::Swap { operations } => execute_swap(deps, env, info, operations),
ExecuteMsg::Swap { routes } => {
if routes.len() != 1 {
return Err(ContractError::Skip(SkipError::MustBeSingleRoute));
}

let operations = routes.first().unwrap().operations.clone();

execute_swap(deps, env, info, operations)
}
ExecuteMsg::TransferFundsBack {
swapper,
return_denom,
Expand Down
Loading

0 comments on commit ec1fd57

Please sign in to comment.