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