LLMs.txt: agent-readable Markdown index of this site at /llms.txt

Filler FAQ

Resolve UniswapX filler and quoter issues, including native ETH input, RFQ behavior, and order execution errors.

Getting Started

How do I get orders?

Fillers should start with polling for orders and rate limit at 6 RPS.

Are webhooks still supported?

Webhooks were deprecated on UniswapX due to degraded performance, and we are no longer onboarding new webhook integrations. Existing webhook integrations will continue to work, but new fillers should start with polling orders on the API and rate limit at 6 RPS. We are exploring WebSocket connections going forward.

Which IPs do I need to whitelist to receive quote requests?

Whitelist the UniswapX quote-request source IPs so your quoting server can receive RFQ requests.

  • Beta test environment: 3.135.148.114
  • Production environment: 3.138.88.28
Why don't I get quote requests for all chains?

UniswapX uses RFQ to parameterize orders across supported chains. You receive quote requests for the chains where you are onboarded as a quoter. Use the tokenInChainId field to filter, and respond with HTTP status code 204 for chains you do not quote.

If a hard quote does not come back better than the threshold, the order skips exclusivity and goes straight to the open Dutch auction (see "Why do some orders not have exclusive fillers?").

See the Choose Your Integration Path table for the auction type and reactor used on each chain.

How do I know which chain I need to quote on?

Quote requests include the tokenInChainId field, which identifies the chain of the intent. If you are not interested in quoting for a given chain, respond with HTTP status code 204.

How quickly do I need to quote?

Quote responses must be returned within 500ms on Ethereum, or 250ms on any other chain, to be considered.

What's the expected RPS for quoting on Ethereum?

1 RPS.

Which tokens are supported in RFQ?

All tokens are supported, except those on the unsupported token list.

Technical Issues

I'm getting 404, no quotes available?

There are several reasons why you might receive this error:

  • Price Impact: UniswapX has filters that route trades to the AMM when direct AMM execution would be superior. If the price impact is too high or the benefit of routing through UniswapX isn't significant enough, no quote will be returned for this pair.

  • Order Size: Very small orders may not be economical to fill through UniswapX due to gas costs. Similarly, extremely large orders might exceed available liquidity from quoters.

  • Response Latency: If your filler responds but takes longer than 500ms on Ethereum, or 250ms on any other chain, your quote will be rejected. Ensure your infrastructure can consistently respond within this latency requirement. The quote server is located in AWS US-EAST-2 if you wish to co-locate to reduce latency.

The transaction is reverting for a certain reason (e.g. DeadlineReached). What does this mean?

UniswapX reactors revert with custom errors such as DeadlineReached, InvalidCosignerInput, and InvalidCosignerOutput. Look up the revert selector against the reactor and base contracts in the UniswapX repository to find the cause.

Custom errors defined under src/v4 (for example IntentAlreadyCancelled and ChunkSizeBelowMin) belong to the v4 DCA hook, not the production Dutch reactors. Do not confuse them with live order reverts.

Why did my server stop receiving quote requests?

Your server may be temporarily blocked due to the fade-rate monitor. If you win an RFQ but don't fill the order, this counts as a "fade." After too many fades, RFQ requests are temporarily paused.

You'll know you're blocked when quote requests include a blockUntilTimestamp field indicating when you'll start receiving requests again.

Handle this field in your code so your service backs off until the block clears, and log it so you can detect and debug circuit breaker events.

Why does my fill transaction fail the Permit2 nonce check?

A Permit2 nonce check failure typically means:

  • The order has already been filled by another filler
  • The user cancelled the order
  • The signature has expired

Before attempting to fill, verify the order is still valid. See: "How do I know if an order is still fillable?"

Order Mechanics

How do I know if an order is still fillable?

The simulation using UniswapXOrderQuoter will tell you whether the order is still fillable.

How is orderHash generated? Is it guaranteed to be unique?

orderHash values are generated from the hash of the witness information from the order and are thus guaranteed to be cryptographically unique.

Why do I receive inverse requests for every quote (e.g. USDC<>ETH and ETH<>USDC)?

Two quote requests are performed per actual quote to obfuscate the swapper's actual request and reduce the chances of front-running.

How long is the exclusivity period after a winning quote? Is it fixed or dynamic?

The exclusivity period on mainnet is currently 24 seconds (2 blocks) and is set by the cosigner when it cosigns the order. It is not a fixed protocol constant and could change in the future.

On chains that use the DutchV3 reactor (Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, and Unichain), the exclusivity window is measured in block numbers rather than seconds and is currently about 2 to 4 seconds, likewise set by the cosigner per order. Block times on these chains are roughly 1 second.

Why do some orders not have exclusive fillers?

The Order Service gets a soft quote to decide between UniswapX and Classic routing. If UniswapX is chosen and the hard quote comes back a certain amount lower than the soft quote, the Order Service cannot assign exclusivity. We call this missing exclusivity. The order then goes straight to decay.

Native ETH Input

What is ERC20ETH?

ERC20ETH is a minimal ERC-20 wrapper that exposes transfer, approve, transferFrom, and permit for native ETH. It lets EIP-7702 delegated accounts use native ETH inside ERC-20-based flows such as UniswapX and Permit2.

UniswapX relies on Permit2 allowances to pull a swapper's input token when an order is filled. Native ETH cannot grant a standard ERC-20 allowance, so native ETH input historically required wrapping ETH to WETH before the trade. With EIP-7702 and ERC-7914, ERC20ETH lets compatible smart wallets grant a native ETH allowance to a spender and move ETH through the standard ERC-20 transfer interface.

How does ERC20ETH work?

ERC20ETH is built on Solady's ERC-20 implementation. It supports EIP-2612 permit and automatically gives Permit2 an infinite allowance.

The contract does not keep internal balances. It relies on actual native ETH balances, and balanceOf intentionally reverts to prevent double-entry-point balance-check bugs.

On transfer and transferFrom, ERC20ETH calls ERC-7914's transferFromNative on the sender, which must implement ERC-7914. The contract pulls native ETH from the sender, immediately forwards that ETH to the recipient, and emits standard ERC-20 Transfer or Approval events for tooling compatibility.

ERC20ETH was audited by OpenZeppelin.

How do fillers handle orders with ERC20ETH as the input token?

Fillers may see UniswapX orders where inputTokenAddress is the ERC20ETH deployment address, 0x00000000e20E49e6dCeE6e8283A0C090578F0fb9.

There are no ERC20ETH liquidity pools. Special-case this address in routing logic and treat the input as native ETH.

Onchain filler call flow:

  1. The UniswapX order's inputTokenAddress is ERC20ETH.
  2. The reactor treats it like any other ERC-20 and calls permitWitnessTransferFrom.
  3. Permit2 pulls the input through ERC20ETH, which delivers actual native ETH, not an ERC20ETH token balance, to the filler's EOA or contract.
  4. In the filler's callback, route that ETH through the AMM to produce the requested output token. Any leftover ETH remains with the filler.
What setup does a swapper need before using native ETH input?

The swapper needs an EIP-7702 wallet with ERC-7914 support. The wallet grants a one-time native ETH allowance to ERC20ETH, which can be bundled into the initial EIP-7702 delegation.

After that setup, the swapper signs the normal offchain Permit2 EIP-712 message for each swap. They do not need to wrap ETH to WETH before every trade.

Where is ERC20ETH deployed?

ERC20ETH is deployed at 0x00000000e20E49e6dCeE6e8283A0C090578F0fb9. The address is the same across supported chains through deterministic CREATE2 deployment and a mined vanity address.

References:

Fade Mechanics

What counts as a fade?

A fade occurs when a quoter wins exclusivity on an order through the RFQ process but does not fill it before the exclusivity window expires. Fading triggers the circuit breaker, which temporarily disables the quoter from receiving new RFQ requests.

Only quoters who win exclusivity can fade. Non-exclusive fillers never hold exclusivity, so they cannot fade and are never subject to the circuit breaker.

Does it count as a fade if another filler overrides my exclusivity?

No. On mainnet, orders may use soft exclusivity (exclusivityOverrideBps > 0), which allows non-exclusive fillers to fill during the exclusivity window by paying an override penalty, which means extra tokens to the swapper.

This is not considered a fade. The system explicitly allows it to balance honoring exclusivity with getting the swapper the best possible price. A fade is only counted when the exclusivity window expires without any filler (including the exclusive filler) settling the order.

What happens if the order is filled after the exclusivity window by a different filler?

Once the exclusivity window ends (at decayStartBlock on the DutchV3 chains, decayStartTime on Ethereum), all fillers compete equally in the Dutch auction. If the original filler, or another filler, fills the order during the decay period, the filler who faded the order is still penalized.

How does the cooldown work after a fade?

After a fade, the circuit breaker disables the quoter for a cooldown period that uses exponential backoff:

cooldown = 15 min × 1.5^(fades - 1) × 2^(consecutiveOffenses)
  • First fade, first offense: 15 minutes
  • 2 fades in one period, first offense: ~22 minutes
  • 1 fade, second consecutive offense: 30 minutes
  • 2 fades, second consecutive offense: ~45 minutes

The system periodically checks for new fades. If no new fades are detected in a check, the consecutive offense count resets to 0. The full policy is available in the source code.

Beyond the timed cooldown, a quoter whose fade rate stays above the program threshold (about 10%) can be removed from the quoter set entirely.

Do simulation failures count as fades?

No. Fades are only counted when a quoter wins exclusivity but fails to fill the order onchain before the exclusivity window expires. Offchain simulation failures (e.g. quote validation or gas estimation) do not trigger the circuit breaker.

Support

How do I submit a ticket?

Use the UniswapX filler help form to reach the team without leaving this page.

How do I stay up to date?

Subscribe to the Telegram channel for UniswapX announcements.