An AMM-backed RFQ quoter for UniswapX on Base

daemonfill, an independent developer project · 19 September 2026

Status: running on Base and applying to the UniswapX quoter beta. There is no live Uniswap RFQ traffic and there are no live fills yet; every result below is simulated or measured by us.

Abstract

We quote UniswapX RFQ requests on Base from on-chain AMM liquidity, and fill the orders we win atomically through the reactor callback. The swapper's input pays for the route, so we hold no inventory. We evaluate this two ways. A live shadow test replays fresh Base orders to our quote server and executes our quoted route at the block where the winning market maker filled. A retrospective simulation does the same over 300 maker-won orders. At a 5 bps margin, every would-be win executed in both (43 of 43, and 57 of 57). Our routes land a median of about 2 bps from the winning quotes, so we compete mainly on orders under $1,000; large orders stay with inventory-backed market makers. We also describe how the fill engine handles failures, the sources of failed fills we found and removed, and the limits of this evidence.

1. System

An order passes through five steps; we operate steps 2 and 4.

  1. Uniswap sends an RFQ price request.
  2. Our quote server re-prices the pair's pre-loaded AMM routes on the latest block (one call, raced across several nodes) and answers with the best route's output, less a 5 bps margin and the fill's gas, within a 350 ms deadline. Routes cover Uniswap v2/v3, hookless v4, Aerodrome, PancakeSwap and others. It declines with an empty 204 when it can't quote, including whenever the fill engine can't take another fill.
  3. Uniswap's auction picks the best quote. The winner has an exclusivity window of about two blocks.
  4. Our fill engine handles each won order on its own thread. It simulates the exact transaction on the in-progress block, records it with its worst-case gas reserved, and only then sends it. It replaces a fill that gets no receipt within the window, and after a restart it resumes anything still unsettled.
  5. The UniswapX reactor calls back our fill contract, which swaps the swapper's input along the route and pays the outputs. It reverts unless the route itself produces everything the reactor takes, so a fill can never draw on funds the contract already holds. Our worst case on a failed fill is its gas.

2. Method

We never use route quotes as evidence. Every number below comes from executing the fill through the real UniswapX reactor at a real gas price. Our executor's code is placed at the winning maker's address, so the reactor demands exactly what the maker was owed. When our route falls short, the revert reports how much it produced.

Live shadow test. Fresh Base orders seen by our collector (within 5 s) are sent to our quote server as the RFQ they came from. After the winning maker fills, we execute our quoted route at that block. A quote counts only if our response completed before the fill; 24 later ones were excluded.

Retrospective simulation. We took 300 randomly sampled Base orders won by existing quoters. For each, our server's rules are applied at the block where the order was created: routes ranked by their quotes, hooked v4 pools skipped, gas set aside with the server's fixed allowance. The chosen route is then executed at the fill block.

3. Results

The margin is the main lever. A lower margin wins more orders, but leaves less room for the price to move between quote and fill.

MarginWould-be winsExecutedFill rateWins/dayEst. P&L/day
0 bps736184%121$0
2 bps595695%98$31
5 bps (ours)5757100%95$79
10 bps5252100%86$52
20 bps3131100%51$28

Table 1. Retrospective simulation over 300 maker-won Base orders. Per-day figures are scaled estimates, not earnings. About 72% of the profit at 5 bps comes from its five largest wins.

(a) Would-be wins (b) Est. P&L per day, USD 020 4060 80 84%95% 100%100% 100% 02 510 20 margin (bps) executed would have faded 020 4060 80 031 7952 28 02 510 20 margin (bps)

Figure 1. The margin trade-off (Table 1). Below 5 bps, wins start to fade (the route no longer covers the quote at fill time); above 5 bps, fewer orders are won. Our setting is the dark bar.

Live shadow test. Of 206 orders judged, our quote at 5 bps would have beaten the winning quote on 43, and all 43 routes executed for the full amount (37 of 37 at 10 bps). Eleven orders couldn't be judged, because no quoter won them or nobody filled them.

Order sizeOrdersOur quote would have wonShare
under $1,000342368%
$1,000 – $5,000941011%
$5,000 – $20,0005600%
over $20,000900%

Table 2. Share of orders our quote would have won, by order size (live shadow test, 10 bps margin, 19 September). How much of each day's flow is small orders largely decides our volume.

Response time. Measured end to end through the public URL from our server (US East), in runs of about 100 requests: p50 45–100 ms and p99 180–366 ms, with none over the 500 ms budget. The slowest run was taken during an external review. Server-side processing: p50 about 40 ms, p99 about 260 ms.

4. Findings

4.1 A quote is not an execution: hooked v4 pools

Some Uniswap v4 pools have hooks that quote normally but behave differently on a real swap. On Base, a cbBTC/USDC pool's hook rejects swaps from contracts like ours; it accounted for every miss in an earlier run of our simulation. On Robinhood Chain we found hooks that quote a good price but charge about 2.4% on real swaps, even through Uniswap's own router. We now skip every v4 pool with a hook. None of the roughly 1,000 quotes served before that change used one.

4.2 Where on-chain routes can compete

Our raw route lands a median of about 2 bps from the winning quote (95 of 126 orders within ±10 bps), so the margin decides most outcomes. Splitting orders across two routes gained a median of 0.1 bps over the same orders. On large orders, inventory-backed makers quote better than an AMM route can at that size.

4.3 Racing the open auction does not pay

Before quoting, we tested racing to fill orders once their exclusivity ends. Simulated at the real gas price, the edge on Base was about zero. Apparent profits on Robinhood Chain came from the hooks in 4.1.

5. Failure handling

A fade, winning an order and then not filling it, is the costly failure for a quoter. The design avoids or bounds it as follows:

We tested each of these on a local Base fork with real orders: an exclusive fill, a replaced fill, a crash with a lost transaction, a two-output order, and a route that falls short. The design went through five rounds of external review before we applied.

6. Limitations

7. Deployment and contact

ChainBase (8453)
Fill contract0x01c2a3482a4b51da150681dd74a13336e73626ad
Orders quotedExact-input Dutch V3. Other chains and exact-output requests get a 204.
Margin5 bps, plus the fill's gas
Response deadline350 ms internally (Uniswap's limit is 500 ms)
Contact[email protected]

Methods and scripts are available on request.