-
Notifications
You must be signed in to change notification settings - Fork 39
Description
Hi,
We're running tycho-simulation and have been experiencing a couple of errors.
- A problem with
state.get_amount_out- this appears whenstate.get_amount_out()call fails (returns an error) for a specific pool - A problem with
swap_math.rsfor uniswap-v4
Filtering out v4 pools with hooks, helped reduce the frequency of each of these.
But we are still receiving intermittent issues and occasionally unable to retrieve state for components which we have received.
Below is the code I am using for setting up and filtering our streams and also some reference information.
Please let me know if I have something misconfigured, or if there any best practices on retries or error handling I should put in place.
🙏 💙 🙏
Stream creation and filtering
Creation
use tycho_simulation::tycho_client::feed::component_tracker::ComponentFilter;
use tycho_simulation::{
evm::{
protocol::{
uniswap_v2::state::UniswapV2State, uniswap_v3::state::UniswapV3State,
uniswap_v4::state::UniswapV4State,
},
stream::ProtocolStreamBuilder,
},
protocol::models::{ProtocolComponent, Update},
tycho_common::models::Chain,
};Filtering
let tvl_filter = ComponentFilter::with_tvl_range(min_tvl, max_tvl);
let mut protocol_stream = ProtocolStreamBuilder::new(hostname, self.chain)
.exchange::<UniswapV2State>("uniswap_v2", tvl_filter.clone(), None)
.exchange::<UniswapV3State>("uniswap_v3", tvl_filter.clone(), None)
.exchange::<UniswapV4State>(
"uniswap_v4",
tvl_filter.clone(),
// None, // Remove hook filter for now
Some(uniswap_v4_pool_with_hook_filter),
)
.auth_key(Some(self.auth_key.clone()))
.skip_state_decode_failures(true)
.set_tokens(self.all_tokens.clone())
.await
.build()
.await?;Reference Information
Analysis of state.get_amount_out
This occurs when the state.get_amount_out() call fails (returns an error) for a specific pool. This is different from the V4 overflow panic - this is when the ProtocolSim state exists but the get_amount_out method itself fails.
When it happens: When there's a valid ProtocolSim state for the pool, but calling state.get_amount_out() returns an error (not a panic). The system then falls back to using the home-grown Self::get_amount() calculation instead.
Impact on Route Evaluation:
- 703 V4 OVERFLOW PROTECTION: These routes are completely skipped because V4 pools are disabled. This means 703 potential routes cannot be evaluated at all.
- 13 Failed state.get_amount_out: These routes are still evaluated, but using the fallback calculation method instead of the ProtocolSim state. This means the routes are processed but may have less accurate calculations.
The high number of V4 OVERFLOW PROTECTION messages (703) suggests that the V4 overflow issue is the primary blocker preventing route evaluation, while the Failed state.get_amount_out (13) is a much smaller issue affecting specific pools.
get_amount_code
let amount_out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
state.get_amount_out(BigUint::from(adjusted_amount), &token_in, &token_out)
}))Analysis on Overflow Panic
Root Cause of V4 Overflow Panic:
The V4 overflow panic occurs in this sequence:
- Route Evaluation Process: When evaluating a route, the system calls evaluate_route in route_analyzer.rs
- ProtocolSim State Retrieval: The system calls
pool_store.get_pool_state(&edge.pool_id).await?to get the V4 pool state from the database - get_amount_out Call: For V4 pools, it calls
state.get_amount_out(BigUint::from(adjusted_amount), &token_in, &token_out)wherestateis aUniswapV4State - V4 Swap Execution: The get_amount_out method calls self.swap(zero_for_one, amount_specified, None)?
- Swap Math Calculation: The swap method iterates through tick ranges and calls compute_swap_step from swap_math.rs
- The Overflow Point: In compute_swap_step, at line 130, when calculating the fee amount:
safe_sub_u256(amount_remaining.abs().into_raw(), amount_in)?This subtraction operation amount_remaining - amount_in causes a u64 overflow when:
- The input amount is very large
- The pool has small reserves
- The token values are vastly different (e.g., $0.001 token vs $130,000 token)
- Panic Propagation: The safe_sub_u256 function panics with "attempt to subtract with overflow" when the subtraction would result in a negative number, but the function expects unsigned integers.
What Triggers the Overflow:
- Large Input Amounts: When the input amount exceeds what the pool can handle
- Small Pool Reserves: V4 pools with low liquidity
- Token Value Mismatch: Swapping between tokens with vastly different values
- Precision Issues: The V4 implementation uses u64 internally, which can overflow with large amounts
The system has safety measures (amount limiting) but they're not sufficient for all edge cases, leading to these overflow panics during route evaluation.
The swap_math.rs file is located at `lib/tycho-simulation/src/evm/protocol/utils/uniswap/swap_math.rs
This is part of the tycho-simulation library, not the main solver project. It's in the lib/tycho-simulation/ directory which contains the simulation engine that the solver uses for calculating swap amounts and simulating transactions.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status