feat: Rust testing SDK - implement get_amount_out simulation
This commit is contained in:
2
protocol-testing/Cargo.lock
generated
2
protocol-testing/Cargo.lock
generated
@@ -5429,6 +5429,8 @@ dependencies = [
|
||||
"glob",
|
||||
"hex",
|
||||
"miette",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"postgres",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -14,6 +14,8 @@ tycho-client = "0.82.0"
|
||||
tycho-simulation = { git = "https://github.com/propeller-heads/tycho-simulation.git", tag = "0.156.0", features = ["evm"] }
|
||||
## TODO: for local development
|
||||
#tycho-simulation = { path = "../../tycho-simulation" }
|
||||
num-bigint = "0.4"
|
||||
num-traits = "0.2"
|
||||
# EVM dependencies
|
||||
alloy = { version = "1.0.27", features = ["arbitrary", "json", "dyn-abi", "sol-types", "contract", "provider-http"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
@@ -6,6 +6,8 @@ use figment::{
|
||||
Figment,
|
||||
};
|
||||
use miette::{miette, IntoDiagnostic, WrapErr};
|
||||
use num_bigint::BigUint;
|
||||
use num_traits::Zero;
|
||||
use postgres::{Client, Error, NoTls};
|
||||
use tokio::runtime::Runtime;
|
||||
use tracing::{debug, error, info};
|
||||
@@ -406,18 +408,54 @@ fn validate_state(
|
||||
.map(|price| info!("Spot price {:?}: {:?}", formatted_token_str, price))
|
||||
.map_err(|e| info!("Error calculating spot price for Pool {:?}: {:?}", id, e))
|
||||
.ok();
|
||||
// let amount_in =
|
||||
// BigUint::from(1u32) * BigUint::from(10u32).pow(tokens[0].decimals as u32);
|
||||
// state
|
||||
// .get_amount_out(amount_in, &tokens[0], &tokens[1])
|
||||
// .map(|result| {
|
||||
// println!(
|
||||
// "Amount out for trading 1 {:?} -> {:?}: {:?} (takes {:?} gas)",
|
||||
// &tokens[0].symbol, &tokens[1].symbol, result.amount, result.gas
|
||||
// )
|
||||
// })
|
||||
// .map_err(|e| eprintln!("Error calculating amount out for Pool {:?}: {:?}", id,
|
||||
// e)) .ok();
|
||||
|
||||
// Test get_amount_out with different percentages of limits. The reserves or limits are
|
||||
// relevant because we need to know how much to test with. We don’t know if a pool is
|
||||
// going to revert with 10 or 10 million USDC, for example, so by using the limits we
|
||||
// can use “safe values” where the sim shouldn’t break.
|
||||
let percentages = [0.001, 0.01, 0.1];
|
||||
for percentage in &percentages {
|
||||
// Get limits for this token pair
|
||||
let limits = state
|
||||
.get_limits(tokens[0].address.clone(), tokens[1].address.clone())
|
||||
.map_err(|e| info!("Error getting limits for Pool {:?}: {:?}", id, e))
|
||||
.ok();
|
||||
|
||||
if let Some((max_input, _max_output)) = limits {
|
||||
// Calculate test amount as percentage of max input
|
||||
let percentage_biguint = BigUint::from((percentage * 1000.0) as u32);
|
||||
let thousand = BigUint::from(1000u32);
|
||||
let amount_in = (&max_input * &percentage_biguint) / &thousand;
|
||||
|
||||
// Skip if amount is zero
|
||||
if amount_in.is_zero() {
|
||||
continue;
|
||||
}
|
||||
|
||||
state
|
||||
.get_amount_out(amount_in.clone(), &tokens[0], &tokens[1])
|
||||
.map(|result| {
|
||||
info!(
|
||||
"Amount out for trading {:.1}% of max ({} -> {}): {} {} (gas: {})",
|
||||
percentage * 100.0,
|
||||
&tokens[0].symbol,
|
||||
&tokens[1].symbol,
|
||||
result.amount,
|
||||
&tokens[1].symbol,
|
||||
result.gas
|
||||
)
|
||||
})
|
||||
.map_err(|e| {
|
||||
info!(
|
||||
"Error calculating amount out for Pool {:?} at {:.1}%: {:?}",
|
||||
id,
|
||||
percentage * 100.0,
|
||||
e
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user