Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
assert max spread in simulate swap in query
Browse files Browse the repository at this point in the history
- can't use router any more and instead query the pools directly
NotJeremyLiu committed Nov 10, 2023
1 parent bb89b41 commit 755e391
Showing 1 changed file with 30 additions and 21 deletions.
51 changes: 30 additions & 21 deletions contracts/adapters/swap/astroport/src/contract.rs
Original file line number Diff line number Diff line change
@@ -4,10 +4,11 @@ use crate::{
};
use astroport::{
asset::{Asset, AssetInfo},
pair::{QueryMsg as PairQueryMsg, ReverseSimulationResponse, MAX_ALLOWED_SLIPPAGE},
router::{
ExecuteMsg as RouterExecuteMsg, QueryMsg as RouterQueryMsg, SimulateSwapOperationsResponse,
pair::{
QueryMsg as PairQueryMsg, ReverseSimulationResponse, SimulationResponse,
MAX_ALLOWED_SLIPPAGE,
},
router::ExecuteMsg as RouterExecuteMsg,
};
use cosmwasm_std::{
entry_point, to_binary, Addr, Binary, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, Response,
@@ -181,7 +182,7 @@ fn query_simulate_swap_exact_coin_in(
swap_operations: Vec<SwapOperation>,
) -> ContractResult<Coin> {
// Error if swap operations is empty
let (Some(first_op), Some(last_op)) = (swap_operations.first(), swap_operations.last()) else {
let Some(first_op) = swap_operations.first() else {
return Err(ContractError::SwapOperationsEmpty);
};

@@ -190,29 +191,37 @@ fn query_simulate_swap_exact_coin_in(
return Err(ContractError::CoinInDenomMismatch);
}

// Get the router contract address
let router_contract_address = ROUTER_CONTRACT_ADDRESS.load(deps.storage)?;

// Get denom out from last swap operation
let denom_out = last_op.denom_out.clone();
// Iterate through the swap operations, querying the astroport pool contracts to get the coin out
// for each swap operation, and then updating the coin out for the next swap operation until the
// coin out for the last swap operation is found.
let coin_out = swap_operations.iter().try_fold(
coin_in,
|coin_out, operation| -> Result<_, ContractError> {
let res: SimulationResponse = deps.querier.query_wasm_smart(
&operation.pool,
&PairQueryMsg::Simulation {
offer_asset: Asset {
info: AssetInfo::NativeToken {
denom: coin_out.denom,
},
amount: coin_out.amount,
},
ask_asset_info: None,
},
)?;

// Convert the swap operations to astroport swap operations
let astroport_swap_operations = swap_operations.into_iter().map(From::from).collect();
// Assert the operation does not exceed the max spread limit
assert_max_spread(res.return_amount, res.spread_amount)?;

// Query the astroport router contract to simulate the swap operations
let res: SimulateSwapOperationsResponse = deps.querier.query_wasm_smart(
router_contract_address,
&RouterQueryMsg::SimulateSwapOperations {
offer_amount: coin_in.amount,
operations: astroport_swap_operations,
Ok(Coin {
denom: operation.denom_out.clone(),
amount: res.return_amount,
})
},
)?;

// Return the coin out
Ok(Coin {
denom: denom_out,
amount: res.amount,
})
Ok(coin_out)
}

// Queries the astroport pool contracts to simulate a multi-hop swap exact amount out

0 comments on commit 755e391

Please sign in to comment.