{"credit":"Taylor (gtmcknight), github.com/gtmcknight/amm-sim@4812a6382311624e1506aca131ca35c378f930d9 research/solved (policy, filter, tables); BASE TellMinLookup is a port of Taylor's solved policy","item":"e02-gas-paths/copy-b","base":{"name":"TellMinLookup","source_sha256":"99d031f41074ea872c78fa7dec5db33d9f20f3251e29bdbb4682c92791334b72","runtime_bytes":21055,"compiled_here_runtime_bytes":21055},"ready":true,"coverage":{"replica_seeds":[60000,60001,60002,60003,60004,60005,60006,60007],"callbacks":90802,"callbacks_in_table":90802,"gate":"replica_gate.py 60000 8 alpha=0.35 reproduced: every seed max |contract-shadow| <= 4.6e-7 bps, guard_shifts 0; probe build fees equal BASE fees on every callback"},"gas_measure":"afterSwap execution gas only (no 21,000 base, no calldata), engine-equivalent: each callback with cold, clean storage. pyrevm 0.3.7 message_call keeps the contract's slots warm and dirty between calls (SLOAD 100, SSTORE 100), so its raw numbers (gas_pyrevm_warm) are 21,800-24,000 too low; the per-callback correction is exact EIP-2929/2200 accounting from recorded slot changes: +2,000 per cold SLOAD (slots 0-4 on first callbacks, 0-2 on later), +2,800 per changed slot written clean, +2,100 per cold write of slots 3,4 on later callbacks. Check: corrected replica transaction mean 130,380 vs engine 130,725 on its own seeds (raw warm 107,333).","paths":[{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"13+","n":2,"gas":{"min":180598,"mean":182158.5,"p99":183719,"max":183719},"gas_pyrevm_warm":{"min":156598,"mean":158158.5,"p99":159719,"max":159719}},{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"7-12","n":16,"gas":{"min":158170,"mean":162580.1,"p99":181548,"max":181548},"gas_pyrevm_warm":{"min":134170,"mean":138580.1,"p99":157548,"max":157548}},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"13+","n":3,"gas":{"min":179164,"mean":179572.0,"p99":179973,"max":179973},"gas_pyrevm_warm":{"min":155164,"mean":155572.0,"p99":155973,"max":155973}},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"7-12","n":131,"gas":{"min":147925,"mean":157099.1,"p99":171384,"max":176559},"gas_pyrevm_warm":{"min":123925,"mean":133099.1,"p99":147384,"max":152559}},{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"2-6","n":1258,"gas":{"min":134193,"mean":141888.0,"p99":155975,"max":156644},"gas_pyrevm_warm":{"min":110193,"mean":117888.0,"p99":131975,"max":132644}},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"2-6","n":8969,"gas":{"min":126262,"mean":135437.6,"p99":150138,"max":153275},"gas_pyrevm_warm":{"min":102262,"mean":111437.6,"p99":126138,"max":129275}},{"first":true,"arb_read":true,"rival_update":"neither","gap_bucket":"7-12","n":37,"gas":{"min":135219,"mean":141491.4,"p99":151815,"max":151815},"gas_pyrevm_warm":{"min":111219,"mean":117491.4,"p99":127815,"max":127815}},{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"1","n":1669,"gas":{"min":130051,"mean":134455.5,"p99":135739,"max":136269},"gas_pyrevm_warm":{"min":106051,"mean":110455.5,"p99":111739,"max":112269}},{"first":true,"arb_read":true,"rival_update":"neither","gap_bucket":"2-6","n":2860,"gas":{"min":113309,"mean":119385.9,"p99":133333,"max":136007},"gas_pyrevm_warm":{"min":89309,"mean":95385.9,"p99":109333,"max":112007}},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"1","n":14467,"gas":{"min":122014,"mean":128392.5,"p99":130685,"max":132495},"gas_pyrevm_warm":{"min":98014,"mean":104392.5,"p99":106685,"max":108495}},{"first":true,"arb_read":true,"rival_update":"neither","gap_bucket":"1","n":28095,"gas":{"min":108714,"mean":112530.5,"p99":113996,"max":115831},"gas_pyrevm_warm":{"min":84714,"mean":88530.5,"p99":89996,"max":91831}},{"first":false,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"same_step","n":4525,"gas":{"min":85637,"mean":89487.1,"p99":91845,"max":93223},"gas_pyrevm_warm":{"min":64237,"mean":68087.1,"p99":70445,"max":71823}},{"first":false,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"same_step","n":28770,"gas":{"min":79918,"mean":83720.5,"p99":87458,"max":90090},"gas_pyrevm_warm":{"min":58518,"mean":62320.5,"p99":66058,"max":68690}}],"peak":{"gas":183719,"path":{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"13+"},"seed":60002,"step":4833,"steps_since_prev":15,"parts":{"isArb":22632,"belief":70028,"pull":5616,"lookup":58081,"storage":14659,"other":12703},"detail":{"isArb_only":22576,"chance_ulpOverGrid":56,"belief_silent_steps_loop":48837,"belief_observation_update":21191,"ln_s_and_ln_r_for_lookup_inputs":5233,"guardFee":178,"sload_slots0_2":6317,"sstore_slots3_4":5820,"sstore_slots0_2":8839,"probe_total_minus_exec_warm":187,"warm_measure":{"exec":159719,"sload_corr":10000,"sstore_corr":14000}},"peak_path_part_means":{"isArb":22642.5,"belief":68382.5,"belief_silent":47255.0,"pull":5616.0,"lookup":58155.5,"storage":14659.0},"notes":"isArb includes ulpOverGridWad (chance, 56) and the cold loads of slots 3,4 (4,000); belief = whole update(): silent-step loop (capped at 12 trunc steps, ~4,070 each, so 13+ is the bounded worst) + observation update; pull = ln(r), ln(c), exp; lookup = fees() (two surf() evaluations + 2 exp); storage = all SSTOREs; other = cold SLOAD of slots 0-2 (6,317), ln(s)/ln(r) for lookup inputs (5,233), guardFee (178), ABI decode/dispatch and arithmetic. Parts from gasleft() probes in a probe build (probe total minus BASE exec <= 187 gas)."},"isArb_gas":{"min":17282,"mean":21910.6,"max":24142,"scope":"first callbacks only (isArb runs only there), incl. chance and cold slot 3,4 loads; pyrevm warm values min 10,259 mean 16,202 max 20,086"},"engine":{"seeds":[10000456,10000457,10000458,10000459,10000460,10000461,10000462,10000463],"calls":88351,"mean_gas":130725.2,"peak_gas":202178,"out_of_gas":0,"failures":0,"measure":"engine gas_stats are transaction gas (afterInitialize 137,205 equals pyrevm's transaction gas_used for the same call); one run_batch(BASE, VanillaStrategy, 8 configs, 8) block, gas_stats reset before, read after; configs from the kit's engine_eval._config (bootstrap.smoke_engine.config_for); edges {\"10000456\": 513.617, \"10000457\": 480.834, \"10000458\": 623.736, \"10000459\": 568.33, \"10000460\": 505.388, \"10000461\": 610.905, \"10000462\": 516.561, \"10000463\": 635.724}"},"offset":{"value":22252,"min":22168,"mean":22221.9,"max":22252,"meaning":"engine/transaction gas minus afterSwap execution gas = 21,000 + afterSwap calldata (4 B selector + 192 B), no refunds observed on any callback"},"headroom":{"limit":245000,"offset_used":22252,"per_path":[{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"13+","n":2,"max":183719,"headroom":39029},{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"7-12","n":16,"max":181548,"headroom":41200},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"13+","n":3,"max":179973,"headroom":42775},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"7-12","n":131,"max":176559,"headroom":46189},{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"2-6","n":1258,"max":156644,"headroom":66104},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"2-6","n":8969,"max":153275,"headroom":69473},{"first":true,"arb_read":true,"rival_update":"neither","gap_bucket":"7-12","n":37,"max":151815,"headroom":70933},{"first":true,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"1","n":1669,"max":136269,"headroom":86479},{"first":true,"arb_read":true,"rival_update":"neither","gap_bucket":"2-6","n":2860,"max":136007,"headroom":86741},{"first":true,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"1","n":14467,"max":132495,"headroom":90253},{"first":true,"arb_read":true,"rival_update":"neither","gap_bucket":"1","n":28095,"max":115831,"headroom":106917},{"first":false,"arb_read":false,"rival_update":"pull_fired","gap_bucket":"same_step","n":4525,"max":93223,"headroom":129525},{"first":false,"arb_read":false,"rival_update":"bound_binding","gap_bucket":"same_step","n":28770,"max":90090,"headroom":132658}],"engine_observed_peak_headroom":42822,"note":"headroom = 245,000 - path max (replica, engine-equivalent) - offset; 8 seeds, rare paths (13+, n=2-3) have few samples; replica corrected transaction peak 205,935 vs engine peak 202,178 here and 207,569 on BASE's own lease"},"free_gas_reading":{"carry_20k":["first/nonarb/pull_fired/13+","first/nonarb/pull_fired/7-12","first/nonarb/bound_binding/13+","first/nonarb/bound_binding/7-12","first/nonarb/pull_fired/2-6","first/nonarb/bound_binding/2-6","first/arb/neither/7-12","first/nonarb/pull_fired/1","first/arb/neither/2-6","first/nonarb/bound_binding/1","first/arb/neither/1","later/nonarb/pull_fired/same_step","later/nonarb/bound_binding/same_step"],"carry_40k":["first/nonarb/pull_fired/7-12","first/nonarb/bound_binding/13+","first/nonarb/bound_binding/7-12","first/nonarb/pull_fired/2-6","first/nonarb/bound_binding/2-6","first/arb/neither/7-12","first/nonarb/pull_fired/1","first/arb/neither/2-6","first/nonarb/bound_binding/1","first/arb/neither/1","later/nonarb/pull_fired/same_step","later/nonarb/bound_binding/same_step"],"carry_80k":["first/nonarb/pull_fired/1","first/arb/neither/2-6","first/nonarb/bound_binding/1","first/arb/neither/1","later/nonarb/pull_fired/same_step","later/nonarb/bound_binding/same_step"],"reading":"Every path carries 20k. 40k fits every path except first/non-arb/pull_fired/13+ (headroom 39,029; n=2), with 7-12 and 13+ non-arb paths at 41-46k, so a flat +40k is right at the cap only after long silent gaps. 80k fits only first callbacks with gap 1 (86-107k headroom), first arb reads with gap 2-6 (86.7k), and later-in-step callbacks (129-133k). The 2-6 non-arb paths (66-69k) and all 7+ gap paths cannot carry 80k. Later-in-step callbacks (33,295 of 90,802 = 37%) skip isArb and update(), so work placed there is nearly free. On first callbacks the cost grows with the silent-step loop (~4,070 gas per step, capped at 12 steps). Any added per-step cost multiplies by up to 12, so it is the dangerous kind."},"method":"Decoded BASE (sha256 checked) and the harness bundle (lookup-u1 bundle overlaid by BASE's bundle); compiled with prepare.py (solc 0.8.24, opt 200, viaIR, paris; runtime 21,055 B). prof_gate.py = replica_gate.py plus: per callback, the BASE afterSwap transaction gas, refund and calldata cost; a probe build of the same source (gasleft() checkpoints in memory, one event at the end) called with identical inputs on its own EVM for path flags and part splits; fees asserted equal. Path: first = timestamp > stored timestamp (t=0 callbacks count as later: 9 of them); arb_read = update()'s arb flag; rival_update = bound_binding (c beyond r, r=c) / pull_fired (else-if c!=r, ln/exp pull) / neither (arb read); gap = steps since previous own callback (dt), later-in-step callbacks bucketed same_step. Kit setup_fast.sh at 45e7563d (pyrevm 0.3.7, py-solc-x 2.1.0, amm_sim_rs 0.1.0.post1).","ledger":{"lease":[10000456,10000457,10000458,10000459,10000460,10000461,10000462,10000463],"run":[10000456,10000457,10000458,10000459,10000460,10000461,10000462,10000463],"burnt":[],"replica_seeds_used":[60000,60001,60002,60003,60004,60005,60006,60007],"replica_runs":"each replica seed run 3 times (1 + 7 first pass; 8 again to record slot changes); replica seeds are not leased"},"not_done":["No stub-one-part runs: parts come from gasleft() probes only.","Engine gives only aggregate afterSwap gas (no per-path split); per-path numbers are replica, corrected to cold/clean storage analytically, not measured on the engine.","Rare paths (13+ gap: n=2 and 3; arb 13+ never seen) are thin; their max may be exceeded on other seeds, though the silent-step loop is capped at 12.","No score or edge claim; engine edges are recorded only."]}