[DO NOT MERGE] mock PropAMM pool to size underbid opportunity - #365
Open
tamaralipows wants to merge 12 commits into
Open
[DO NOT MERGE] mock PropAMM pool to size underbid opportunity#365tamaralipows wants to merge 12 commits into
tamaralipows wants to merge 12 commits into
Conversation
tamaralipows
force-pushed
the
hindsight/tnl/report
branch
from
July 28, 2026 20:24
6ca8170 to
eed6558
Compare
Exclusive-access routes are quoted only when their output net of gas clears the public reference by a configurable margin, EXCLUSIVE_ROUTE_IMPROVEMENT_BPS, floored at one atomic unit. The margin is added to the commitment, so it goes to the user and surplus capture starts above it. A route that clears the margin exactly is quoted with zero surplus.
A harness that writes synthetic components into MarketData must also announce them, or workers never add the edge to their local graph. Gated behind the experimental feature, alongside BlockStepController.
Mirrors the best real pool for a token pair onto a synthetic exclusive component at a configurable fee-free price, hidden from the public worker pools and visible to an exclusive-access twin of each. Each re-solved order then reports whether the PropAMM route won and how much fee it could have charged on top and still won.
Splits the two quantities: --propamm-price-pct sets the pool's fee-free price as a percentage of the best real pool's, and the fee it could charge on top is measured from the router's surplus. Each outcome rides in the comparisons JSONL, so the offline report renders a section with the run winrate, captured flow, and a per-order-pair breakdown.
A solve that never produced a quote was skipped, so the positional join onto the block's comparison records shifted every later observation onto the wrong trade and dropped the block's outcomes entirely. Record on all paths; only successful quotes count toward the winrate.
Only wins carried a record, so the report's denominator was wins-only and every run rendered a 100% win rate. Losses now carry a record too; unsolved solves stay absent, since the pool never had a chance at those.
Each order on the mirrored pair is now solved twice: once with the mock neutralised, giving the route Fynd would otherwise have quoted, then again with the mock rescaled to land a configured offset off that output. So an offset means what it says, and every calibrated order becomes an assertion rather than a data point. --propamm-offsets-bps replaces --propamm-price-pct. Orders cycle through the ladder, and the report judges each group against the behaviour its price implies: below market must never be selected, at market can only win on gas and must take no fee, above market must not take more fee than the offset.
The two-pass calibration already solves both worlds, so keeping the neutralised pass's amounts turns every calibrated order into a controlled A/B: same order, same block state, the mock's presence the only difference. The report shows win rate, quoted output and captured fee side by side, plus a verdict per offset group rather than only overall.
The hero now shows Fynd's savings, win rate and median savings bps twice, once per world, with the deltas attached to the 'with' column and the LP capture beside them. Both worlds are computed on the same basis the headline already used: a win is gross output above settled, and the bps figure is net of each side's own gas. Drops the per-pair table and the prose in favour of the numbers, and gives each offset group its own verdict alongside the overall one.
Names each test by the pool's price against the best public route rather than by a basis-point offset, states the rule and what happened as two sentences beside each other, and puts one TESTS PASSED verdict above the three cards.
The with side read the trade's verdict, which excludes sandwiched trades, while the without side compared amounts directly. One sandwiched order therefore counted as a win in one world and a loss in the other, showing a win-rate drop and a $3.79 loss that neither world had. Restrict the comparison to scored trades, matching the savings headline it sits beside.
tamaralipows
force-pushed
the
fynd-propamm/tnl/testing
branch
from
July 29, 2026 18:06
6fa57eb to
3e36c06
Compare
tamaralipows
changed the base branch from
main
to
fynd-propamm/tnl/ENG6280-buffer
July 29, 2026 18:06
tamaralipows
force-pushed
the
fynd-propamm/tnl/ENG6280-buffer
branch
from
July 30, 2026 16:54
b8ae1db to
cdad338
Compare
tamaralipows
force-pushed
the
fynd-propamm/tnl/ENG6280-buffer
branch
from
August 3, 2026 16:19
cdad338 to
7beabb1
Compare
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.
Measures what a dynamic-underbidding PropAMM pool would win, before the pool exists. ENG-6157.
Based on
hindsight/tnl/report, notmain— it extends that branch's HTML report. Retarget once it lands.What we're testing
A mock PropAMM pool is injected into a live Fynd solver and hidden from the public worker pools, so only an exclusive-access pool can route through it. Its price is set per order, relative to the route Fynd would otherwise have quoted. Three cases, each an assertion:
Orders cycle through the three, so one run fills all of them.
Roughly how
Each order on the pool's token pair is solved twice. First with the mock priced out of contention — that gives the public best route, the thing to underbid. Then with the mock repriced to sit a set number of basis points off that number, and solved again.
Findings so far (200 blocks)
Running it
Needs a chain RPC, a Tycho key, and any throwaway signing key (nothing is executed, but quotes through the pool are rejected unsigned). Point it at a token pair, optionally restrict the run to that pair so the cases fill faster, and write comparisons to a directory. A second offline command turns that directory into the HTML report.
Full flags, environment variables and the two traps that cost me a run each are in the tool's docs.
Not for production
The pool does not exist on chain, so nothing it quotes is executable. Off unless explicitly enabled, and an ordinary run's output is unchanged.
🤖 Generated with Claude Code