Part I stopped at the quote layer: route legs, output amounts, API-reported priceImpact, and blockNumber. It recorded what the router proposed. At larger sizes, that proposal became a spread of pools and intermediate hops, not a single price.
A desk sizing an exit acts on that quote; so does a risk pipeline that reads priceImpactas a risk number. On a centralized venue, a mistake there usually stays inside an operator’s scope: an order cancelled, a fill refunded, a replacement issued. Once the quote becomes calldata, there is no venue operator between the user and pool execution, and the failure boundary moves from router proposal to encoded constraints. The quote alone cannot tell whether the next problem is invalid transaction construction, wallet authorization, gas estimation, state drift, ordering, or the final fill.
Part I sliced the quote layer; this post slices one execution layer: build the transaction from the quote, replay it against pinned mainnet state, and check whether the proposal survives, and where the route’s complexity ends up. A valid quote does not mean valid calldata; a successful same-state replay does not mean a mined receipt.
A /quote response can show expected output, minimumAmount, route structure, and blockNumber, but none of those fields execute by themselves. The trade becomes executable only when /swap returns a TransactionRequest: to, data, value, gasLimit, and encoded router instructions.
The chain enforces only what the transaction encodes-most importantly the minimum output condition. Expected output and priceImpact are display fields, not the bytes the Universal Router will run.
Fig. 1. Quote evidence vs transaction evidence. The quote records what the router proposed; `/swap` materializes calldata; fork replay tests that calldata against pinned state. Ordering, MEV, fee payment, and inclusion sit outside this article.The replay is a same-state execution check for the /swap artifact, not a live fill. Fork setup and measured fields are in the run section below.
Uniswap’s Trading API exposes this directly by separating from :
POST /quote
→ POST /swap with the returned quote
→ save TransactionRequest
→ fork at quote.blockNumber
→ seed wallet balance and approvals
→ send API-native calldata
→ measure output-token delta, minimumAmount, and gas
Shell references: quote_to_swap.shand replay_swap.sh.
Run ID: 20260619Tpart2v1
I collected nine cells: USDC → WETH, AAVE, and MKR at $100, $10k, and $1M. Routing was Uniswap classic ( CLASSIC); protocols V2/V3/V4 via BEST_PRICE; UniswapX excluded.
For each cell I POSTed /quote, then POSTed /swap with the returned quote object and archived both responses. /swap used allowance-based calldata from the Trading API-not SDK reconstruction from route JSON. API simulateTransaction succeeded on all nine cells.
Each cell was replayed on a fresh Anvil mainnet fork at that cell’s quote.blockNumber (blocks 25,350,126-25,350,128), with archive RPC state. I seeded a fixed test wallet with ETH for gas, USDC via anvil_setStorageAt, and USDC → Permit2 → Universal Router approvals. Replay sent exact API-native /swap calldata to the router at 0x66a989...8Af.
A signed-permit collection ( 20260619Tpart2v0) failed fork replay when permit sigDeadline preceded the pinned quote-block timestamp. That comparison run is archived; the primary evidence is the allowance path above.
Measured per row: fork_status, fork_output_amount, fork_vs_quote_bps, fork_meets_minimum, fork_gas_used, and api_simulation_status.
All nine cells replayed at pinned state, cleared minimumAmount, and matched the quote at 0 bps: the expected baseline for same block, same pool state, same calldata.
Fig. 2. Fork replay panel: WETH / AAVE / MKR × $100 / $10k / $1M. Each cell reports fork status, fork vs quote (bps), `minimumAmount` pass/fail, and gas used. Run `20260619Tpart2v1`; same-state replay matched the quote at 0 bps.WETH $100 routed through a single V3 hop. Fork gas was 140,975-the simple control.
MKR $1M showed quote-layer output deterioration in Part I. Its seven-hop transaction still replayed at 0 bps and cleared the minimum.
Part I flagged AAVE for route fragmentation and summary-field ambiguity. At $1M the quote carried 13 pool legs across five parallel paths (V2/V3/V4 mix). /swap returned 14,366 bytes of calldata. Fork gas was 2,386,700-roughly 17× the WETH $100 control.
Fig. 3. USDC → AAVE at $1M: five parallel paths, 13 pool legs, V2/V3/V4 mix. Side panel: quote block 25,350,127, quoted output, `minimumAmount`, fork status. The route looked fragmented at quote time; it did not become a deterministic same-state failure.The nine-cell replay is a controlled check, but it is too small to say much about route stress more generally. I therefore ran a pilot panel over 28 snapshot labels, 10 assets, and five input sizes: 1,400 intended cells. This was a pipeline pilot, not a historical backtest.
The pilot produced 977 successful /quote + /swap rows. The strongest pattern was payload size: hop count versus calldata bytes had a Pearson correlation of 0.935; path count versus calldata bytes was 0.917.
Fig. 4. Pilot panel: 1,400 intended cells; 977 successful `/quote` + `/swap` rows plotted. Hop count versus calldata bytes (Pearson r = 0.935). Marker size is USDC input size; descriptive, not causal.From that panel I selected 118 stress rows for fork replay. Ninety replayed successfully at pinned state. The remaining 28-all high-complexity SHIB rows-stopped at eth_estimateGas.
Three of those I direct-sent on fresh pinned forks with a 12M gas cap; all three executed at roughly 7M gas and cleared minimumAmount. The timeout was an estimator artifact, not an EVM failure-but that check covers only 3 rows. The remaining 25 still need the same follow-up.
The first all-green table raised a scope question: was this evidence, or only a same-state sanity check? Treating replay as one test stopped working once the non-receipts came from different layers.
Fig. 5. Where the evidence stopped across 118 selected stress-row replays. CRV stopped at configuration, COMP/LDO at quote availability, the signed-permit path at wallet authorization, SHIB at gas estimation before direct-send replay, and AAVE at same-state EVM fork execution. A single pass/fail column would erase those distinctions.A non-receipt is not one failure class. Configuration, authorization, estimation, and EVM execution fail at different boundaries.
Part I stopped at the quote. Here, same-state replay held, route complexity showed up in calldata size, and three SHIB estimator timeouts became roughly 7M-gas executions on bounded forks.
The harder part is keeping the labels straight: estimator timeout, authorization failure, configuration error, and EVM execution are different boundaries, even when all of them produce no mined receipt.
The next falsifiable check is narrow: direct-send the remaining 25 SHIB rows with bounded gas on pinned forks. Inclusion, ordering, MEV, state drift, and realized fill still need receipt-level evidence.
This post was originally published on my personal blog: https://egpivo.github.io/2026/06/30/when-the-quote-becomes-a-transaction.html
When the Quote Becomes Calldata. The Fork Tests Whether It Holds. was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.

