-
-
Save zrbecker/dccb56a2a81f4fc0be6ab4fb9d931d09 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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