Skip to content

[DO NOT MERGE] mock PropAMM pool to size underbid opportunity - #365

Open
tamaralipows wants to merge 12 commits into
mainfrom
fynd-propamm/tnl/testing
Open

[DO NOT MERGE] mock PropAMM pool to size underbid opportunity#365
tamaralipows wants to merge 12 commits into
mainfrom
fynd-propamm/tnl/testing

Conversation

@tamaralipows

@tamaralipows tamaralipows commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Measures what a dynamic-underbidding PropAMM pool would win, before the pool exists. ENG-6157.

Based on hindsight/tnl/report, not main — it extends that branch's HTML report. Retarget once it lands.

Screenshot 2026-07-28 at 22 18 47

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:

the pool is priced it must
worse than the best route never be chosen
equal to the best route only be chosen for cheaper gas, and then charge no fee
better than the best route be chosen, and charge no more than the gap

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)

  • All conclusive cases pass. A pool priced below the market is never chosen; priced above it, it is chosen and charges within the gap, measured to two decimal places of the configured amount.
  • The pool does not improve Fynd's quotes. Win rate and savings are flat, which is expected, since all suplus is given to the LPs.

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

@tamaralipows
tamaralipows force-pushed the hindsight/tnl/report branch from 6ca8170 to eed6558 Compare July 28, 2026 20:24
Base automatically changed from hindsight/tnl/report to main July 28, 2026 20:27
@tamaralipows tamaralipows changed the title feat(hindsight): mock PropAMM pool to size underbid opportunity [DO NOT MERGE] feat(hindsight): mock PropAMM pool to size underbid opportunity Jul 28, 2026
@tamaralipows tamaralipows changed the title [DO NOT MERGE] feat(hindsight): mock PropAMM pool to size underbid opportunity [DO NOT MERGE] mock PropAMM pool to size underbid opportunity Jul 28, 2026
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
tamaralipows force-pushed the fynd-propamm/tnl/testing branch from 6fa57eb to 3e36c06 Compare July 29, 2026 18:06
@tamaralipows
tamaralipows changed the base branch from main to fynd-propamm/tnl/ENG6280-buffer July 29, 2026 18:06
@tamaralipows
tamaralipows force-pushed the fynd-propamm/tnl/ENG6280-buffer branch from b8ae1db to cdad338 Compare July 30, 2026 16:54
@tamaralipows
tamaralipows force-pushed the fynd-propamm/tnl/ENG6280-buffer branch from cdad338 to 7beabb1 Compare August 3, 2026 16:19
Base automatically changed from fynd-propamm/tnl/ENG6280-buffer to main August 3, 2026 17:18
@tamaralipows tamaralipows self-assigned this Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant