fix(mempool): make backrun arbs executable + edge quarantine + multi-venue pools#186
Open
Pablosinyores wants to merge 4 commits into
Open
fix(mempool): make backrun arbs executable + edge quarantine + multi-venue pools#186Pablosinyores wants to merge 4 commits into
Pablosinyores wants to merge 4 commits into
Conversation
Add three mempool-backrun observability metrics and a funnel dashboard
section (⑥) so detection-vs-simulation discrepancy is measurable:
- aether_mempool_backrun_profit_ratio (histogram): revm-actual net /
optimizer-expected net; clusters at ~1.0 when detection-state matches
sim-state, a fat left tail signals a stale-snapshot discrepancy.
- aether_mempool_post_sim_gate_bypassed_total: backruns published with no
detector-vs-revm cross-check (optimizer fell back, expected_net == 0).
- aether_mempool_backrun_calldata_built_total{protocol}: proves the
executor receives non-empty step.data per hop.
The backrun path left every SwapStep.calldata empty, so the executor's pool.call(step.data) reverted (SwapFailed) and every sim was a false negative. Build the protocol-specific inner swap calldata (V2/V3/Sushi) after sizing; drop hops whose protocol has no builder (Curve/Balancer/ Bancor) with a distinct reject reason instead of publishing a reverting bundle. Also correct the profit accounting that suppressed real arbs: - simulate with tipBps=0 so the recipient delta is the FULL profit, not the ~10% left after a 90% coinbase tip; publish the real-tip calldata separately and net = gross - gas. - align gate_post_sim units (subtract sim gas from revm gross so both sides are net) to stop dropping marginal arbs as revm_contradicts. - route step selection on the post-victim graph the cycle was scored on. - pin the detection-time post-state replay fork to the snapshot block (gated on AETHER_BACKRUN_FORK_LATEST), matching the validating sim.
Add PriceEdge.last_update_block and PriceGraph::quarantine_stale_edges, wired into the engine detection cycle (and reserve-update batch). Filtered edges are skipped by Bellman-Ford, killing the placeholder rate=1.0 phantom-cycle source before detection. Placeholder edges (never updated, zero reserves) are always quarantined. Raw edge age is an opt-in, off-by-default backstop (AETHER_EDGE_MAX_AGE_ BLOCKS): for an AMM a quiet pool's reserves stay exact between trades, so age alone is not a corruption signal and must not drop valid quiet pools. Quarantine is additive and self-heals on the next reserve update.
Add 7 UniswapV2/V3 pools (all verified on-chain: getCode + token0/token1 + fee) so the most-traded pairs have >=2 executable venues for cross-DEX cycles. USDC/USDT gains a cross-AMM venue (was UniV3 tiers only); WETH/USDT, DAI/USDC, WBTC/WETH, wstETH/WETH gain a tier; DAI/USDT added on two venues. Only V2/V3/Sushi venues are added, since the backrun path can only build calldata for those today.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes the live mempool-backrun path actually produce executable, profitable arbs, fixes the discrepancy/staleness sources that suppressed real candidates, and adds the observability + venue coverage to see and act on them. Findings came from an adversarial audit (file:line proof, skeptic-verified); each confirmed defect is fixed with tests.
Commits
aether_mempool_backrun_profit_ratio(revm-actual ÷ optimizer-expected net; the discrepancy gauge, ~1.0 = consistent),…_calldata_built_total{protocol},…_post_sim_gate_bypassed_total.SwapStep.calldata(dominant "publishes 0" cause): the executor runspool.call(step.data)verbatim, so empty data reverted (SwapFailed) and every sim was a false negative. Now builds V2/V3/Sushi inner calldata after sizing; drops Curve/Balancer/Bancor hops (no builder yet) with reasonunsupported_protocol_calldatainstead of publishing a reverting bundle.tipBps=0so the recipient delta is the full profit (was the ~10% left after a 90% coinbase tip); publish the real-tip calldata separately;net = gross − gas.gate_post_simunits: subtract sim gas from revm gross so both sides are net (was net-vs-gross →frac_diff≈0.9→ dropped marginal arbs asrevm_contradicts).AETHER_BACKRUN_FORK_LATEST), matching the validating sim.quarantine_stale_edges— never-updated placeholder edges (zero reserves, the rate=1.0 phantom-cycle source) are filtered out of Bellman-Ford. Raw edge age is an opt-in, off-by-default backstop (AETHER_EDGE_MAX_AGE_BLOCKS): for an AMM a quiet pool's reserves stay exact between trades, so age alone isn't a corruption signal and must not drop valid quiet pools.Verification
cargo build/clippy(grpc-server + state): clean, zero warnings.aether-state64 pass (incl. 4 new quarantine tests);aether-grpc-server78 pass (incl. 3 new calldata tests). The one failing test (provider::test_provider_run_with_shutdown) is a pre-existing timing flake that fails identically on the base branch.castat block ~25.24M;pools.tomlparses (135 pools, no dup addresses).Known follow-ups (out of scope here)
unsupported_protocol_calldata) rather than backrun.Notes
Rebased onto
develop(was developed against an older base); merges cleanly.AETHER_EDGE_MAX_AGE_BLOCKSdefaults to 0 (placeholder-only quarantine); set >0 only as a missed-event backstop.