DEV Community

Cover image for Intent-based vs on-chain routing: do you need UniswapX?
BlazePhoenix
BlazePhoenix

Posted on

Intent-based vs on-chain routing: do you need UniswapX?

TL;DR: UniswapX makes you sign an outcome and lets fillers compete to deliver it. On-chain routing makes you send a transaction whose route is computed where it settles. They trade different things: gas and failure cost on one side, verifiability and composability on the other.
This is a neutral read of both designs from their own documentation (consulted 2026-10-29). I'm on the team that builds the second one, so every claim about UniswapX below links to Uniswap's docs and every claim about ours links to code you can read.

Two swap flows side by side: a UniswapX signed order settled by fillers, and an on-chain route solved inside one transaction

What does UniswapX actually do?

Per the UniswapX overview, swappers sign orders that specify the outputs they want, and fillers compete to satisfy them. You don't submit the order on-chain yourself: you sign a message using Permit2, it is broadcast, and any filler can settle it when it is economically viable. The docs list gas-free swapping and no cost for failed transactions among the properties.

The auction itself, from Auction Types:

  • On Ethereum the flow is RFQ plus an exclusive Dutch auction. Uniswap Labs asks a set of quoters for a price; the docs say that set is permissioned and known to Labs. The winner gets a short exclusivity window (about 24 seconds, 2 blocks), then the order decays in an open Dutch auction down to the minimum you signed.
  • Base, Arbitrum and Robinhood Chain (among others) use the same model with timing counted in blocks (the DutchV3 reactor). As of my reading, Optimism does not appear in that table.
  • Gas is wrapped into the final price and paid by the filler.
  • Cosigners adjust auction parameters inside your signed limits; the docs say the Uniswap Interface and API currently set the cosigner to Uniswap Labs.

One more detail from AMM vs UniswapX Routing: through the Uniswap API, UniswapX is included when the order is worth more than 300 USDC equivalent, or when it improves on the AMM route by at least 0.2%, and UniswapX quotes "may be unavailable when solvers cannot or choose not to fill".

What does on-chain routing do instead?

In BlazePhoenix the quote is a free eth_call to a Quoter contract (previewPlan is a view function). The 2.0.0 Router source also has an entry point, swapBestExactIn, that takes no route at all: it calls the Solver inside the same transaction and then executes against the same block state. The contract comment says it plainly, "solve and execution read the same block state, atomically", and also says what it does not fix: "in-tx solving removes plan staleness, not sandwich exposure". That is why userMinOut is mandatory there, and zero reverts.

Status, so nobody is misled: the deployment registry lists 2.0.0 as pending (its addresses are zero today). What is deployed is 1.0.0, where the Quoter works as described but the route travels as calldata. The protocol is pre-launch and an independent external audit is scheduled.

Here is everything a user commits to in that entry point. It runs offline:

import { decodeFunctionData, parseUnits, size, type Address } from 'viem';
import { ROUTER_ABI, encodeSwapBestExactIn } from '@blazephoenix/sdk';

const WETH: Address = '0x4200000000000000000000000000000000000006';
const USDC: Address = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const me: Address = '0x000000000000000000000000000000000000dEaD';

const data = encodeSwapBestExactIn(
  WETH, USDC, parseUnits('0.5', 18),
  1_000_000_000n,                                   // userMinOut: 1,000 USDC (6 decimals), YOUR number
  me, BigInt(Math.floor(Date.now() / 1000) + 120),  // recipient, deadline
);

const { functionName, args } = decodeFunctionData({ abi: ROUTER_ABI, data });
console.log(functionName, `(${size(data)} bytes)`);
['tokenIn', 'tokenOut', 'amountIn', 'userMinOut', 'recipient', 'deadline'].forEach((n, i) =>
  console.log(' ', n.padEnd(10), String((args as readonly unknown[])[i])));
Enter fullscreen mode Exit fullscreen mode
swapBestExactIn (196 bytes)
  tokenIn    0x4200000000000000000000000000000000000006
  tokenOut   0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  amountIn   500000000000000000
  userMinOut 1000000000
  recipient  0x000000000000000000000000000000000000dEaD
  deadline   1793236722
Enter fullscreen mode Exit fullscreen mode

(npm i @blazephoenix/sdk viem tsx, save as order.mts, run npx tsx order.mts. The deadline is "now + 120 s", so yours will differ.)

Decoded swapBestExactIn calldata: tokenIn, tokenOut, amountIn, userMinOut, recipient, deadline

Who do you trust in each design?

UniswapX (per its docs) On-chain routing (BlazePhoenix source)
What you sign A Permit2 order with outputs and auction parameters A transaction with six arguments
Who finds the price Quoters (permissioned) and fillers, in an auction A Solver contract, in your transaction
Who pays gas The filler, priced into the order You
Cost of a failed swap None (per the docs) The gas of the reverted transaction
Who settles Any filler, after the exclusivity window You, in your own transaction
What you can replay The signed order and the on-chain fill The quote, at any block, with eth_call on your RPC
Services in the default path Uniswap Labs' API, cosigner and quoter set Your RPC node
Status Documented for many chains Pre-launch; audit scheduled, not done

Table of what you trust and what you can verify in each design

Where does UniswapX win?

Be honest about this, because it is a lot:

  • Gasless for the swapper, and failed attempts cost nothing. On-chain routing offers neither.
  • Fillers can bring their own liquidity and "their own filling strategies" (overview), not only what sits in public pools.
  • Competition over price is the point of the auction. If your priority is the last basis point on a large order, measure both designs on your trade; don't take either side's word.
  • It is documented by Uniswap Labs for many chains, with filler tooling and an orders API.

Where does on-chain routing win?

  • Composability. swapBestExactIn is an ordinary external function, so a contract can call it and use the result in the same transaction. A signed order that some filler settles later is not something you can await mid-call. (This follows from the function signature; I have not built that integration for this article.)
  • Nothing off-chain to trust for the price. Quote and execution are the same bytecode; anyone can recompute a quote on their own node, with no key and no signup.
  • Predictable failure. userMinOut is yours; below it, the transaction reverts. The cost is gas, which is the price of that guarantee.
  • Fewer moving parts for scripts and agents, which need an RPC URL rather than an order pipeline.

So, do you actually need UniswapX?

Use it if most of these are true:

  1. Your users should not need the chain's gas token.
  2. A failed swap must cost them nothing.
  3. Your orders are large enough that filler inventory could beat pool prices, and you will measure that.
  4. You are fine with Uniswap Labs' services being in the default path.

Use on-chain routing if most of these are true:

  1. A contract of yours must perform the swap and continue in the same transaction.
  2. You want to re-derive the quote yourself, at a block of your choice.
  3. Your caller is a script or an agent that holds a key and an RPC, not a UI.
  4. You accept paying gas for a bounded, verifiable outcome, and you accept an unaudited, pre-launch protocol.

They are not mutually exclusive: nothing stops an application from offering both and letting the user choose.

FAQ

Is UniswapX gasless?
For the swapper, per the docs: gas is wrapped into the price and paid by the filler, and failed swaps incur no fees.

Can I quote a swap without an API key?
With BlazePhoenix, yes: the quote is an eth_call on your own RPC. The Uniswap API examples in the docs send an x-api-key header.

Does in-transaction solving prevent sandwiches?
No. The source says so itself: it removes stale plans, not ordering risk, which is why userMinOut is mandatory.

Is BlazePhoenix on-chain routing available today?
The Quoter (previewPlan) is readable on the deployed 1.0.0. swapBestExactIn is in the 2.0.0 source, listed as pending. The protocol is pre-launch.

Verify it yourself

Read the UniswapX pages linked above (consulted 2026-10-29; docs change), then compare with the Router source and the longer intents vs on-chain routing note. The design is specified in the whitepaper (DOI 10.5281/zenodo.23084091).

Try the read side: connect an agent to the MCP server (no key) and call prepare_quote, or run the snippet above. Tell me in the comments which of your swaps needs gasless and which needs composability.

I'm on the BlazePhoenix team. BlazePhoenix is pre-launch; an independent external audit is scheduled before launch. UniswapX is a product of Uniswap Labs; this is an architectural comparison, not a price or security ranking, and not advice.

Top comments (0)