Skip to content

Instantly share code, notes, and snippets.

@zrbecker

zrbecker/idea.rs Secret

Created December 5, 2023 14:56
Show Gist options
  • Save zrbecker/dccb56a2a81f4fc0be6ab4fb9d931d09 to your computer and use it in GitHub Desktop.
Save zrbecker/dccb56a2a81f4fc0be6ab4fb9d931d09 to your computer and use it in GitHub Desktop.
fn query_simulate_swap_exact_asset_in_alternative(
deps: Deps,
asset_in: Asset,
swap_operations: Vec<SwapOperation>,
) -> ContractResult<Asset> {
let (asset_out, _) = simulate_swap_exact_asset_in(deps, &asset_in, &swap_operations, false)?;
Ok(asset_out)
}
fn query_simulate_swap_exact_asset_in_with_metadata_alternative(
deps: Deps,
asset_in: Asset,
swap_operations: Vec<SwapOperation>,
) -> ContractResult<SimulateSwapExactAssetInResponse> {
let (_, simulation_responses) =
simulate_swap_exact_asset_in(deps, &asset_in, &swap_operations, true)?;
let (asset_out, spot_price) = simulation_responses.iter().zip(swap_operations).try_fold(
(asset_in, Decimal::one()),
|(asset_out, curr_spot_price), (response, operation)| -> Result<_, ContractError> {
let amount_out_without_slippage = response
.return_amount
.checked_add(response.spread_amount)?
.checked_add(response.commission_amount)?;
Ok((
Asset::new(deps.api, &operation.denom_out, response.return_amount),
curr_spot_price.checked_mul(Decimal::from_ratio(
amount_out_without_slippage,
asset_out.amount(),
))?,
))
},
)?;
Ok(SimulateSwapExactAssetInResponse {
asset_out,
spot_price,
})
}
// just function stub
fn simulate_swap_exact_asset_in(
deps: Deps,
asset_in: &Asset,
swap_operations: &Vec<SwapOperation>,
include_simulation_responses: bool, // you can use this to not collect the array if you don't need to
) -> Result<(Asset, Vec<SimulationResponse>), ContractError> {
// Error if swap operations is empty
let Some(first_op) = swap_operations.first() else {
return Err(ContractError::SwapOperationsEmpty);
};
// Ensure asset_in's denom is the same as the first swap operation's denom in
if asset_in.denom() != first_op.denom_in {
return Err(ContractError::CoinInDenomMismatch);
}
// Iterate through the swap operations, querying the astroport pool contracts to get the asset out
// for each swap operation, and then updating the asset out for the next swap operation until the
// asset out for the last swap operation is found.
let (asset_out, simulation_responses) = swap_operations.iter().try_fold(
(asset_in.clone(), vec![]),
|(asset_out, mut responses), operation| -> Result<_, ContractError> {
// Get the astroport offer asset type
let astroport_offer_asset = asset_out.into_astroport_asset(deps.api)?;
// Query the astroport pool contract to get the coin out for the swap operation
let res: SimulationResponse = deps.querier.query_wasm_smart(
&operation.pool,
&PairQueryMsg::Simulation {
offer_asset: astroport_offer_asset,
ask_asset_info: None,
},
)?;
// Assert the operation does not exceed the max spread limit
assert_max_spread(res.return_amount, res.spread_amount)?;
if include_simulation_responses {
responses.push(res.clone());
}
Ok((
Asset::new(deps.api, &operation.denom_out, res.return_amount),
responses,
))
},
)?;
// Return the asset out
Ok((asset_out, simulation_responses))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment