> ## Documentation Index
> Fetch the complete documentation index at: https://docs.route.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# quotes and execution

> How quotes, wallet approval and onchain swaps work.

## Review before signing

The swap page shows a compact route graph alongside the quote (below it on narrow screens). Curved connections link the input token through up to five assessed provider candidates to the output token. The graph explains the comparison. Clicking a node does not choose the transaction. Failed, expired and unverified assessments have explicit status labels; a displayed price does not mean that route can execute.

Upstream coverage is not a direct Route integration. “Best route” means the highest-ranked simulated candidate within this comparison, not every available pool or a guaranteed best price. A lone checked candidate or an unverified fallback is labeled separately.

Transaction progress is tied to wallet and receipt events. Approval and wallet-confirmation stages pulse without implying a swap was sent. A moving signal begins only once the swap has a transaction hash. A successful onchain receipt triggers the arrival checkmark; reverts or cancellations never show success. A timeout or unavailable receipt shows confirmation unavailable and keeps the transaction link.

Check it before retrying. Gas-only repricing follows the replacement hash; a cancellation or replacement with changed transaction contents does not count as a confirmed swap. The animation shows transaction progress, not live movement through each pool. It respects your reduced-motion setting.

The progress graph retains a display-only snapshot while quotes expire or refresh, switching to the final route checked before signing. Its output remains labelled quoted output, not a measured receipt amount. Completed progress can be dismissed, and editing the order resets it; the snapshot is never reused for signing. The compact header uses the official Robinhood feather as a network indicator, with slippage at the top right. Route still charges no platform fee. Provider fees and gas still apply.

`GET /api/v2/quote` includes display-only `comparison` evidence: candidate-local IDs, provider/variant, status, eligibility, selection, original versus simulated output, and common-model gas-adjusted output when available. Rejected, expired and unverified candidates have null simulated/gas/net values. Failed quote/build requests before assessment and merged identical quotes are counted separately; they are not invented route lanes. The map reuses existing assessment work and does not send extra routing requests. These summaries contain no executable calldata and must not be submitted as swap plans. Gas-adjusted values exclude separate approval gas; unavailable gas conversion is disclosed.

Entering a valid positive amount starts the first quote request immediately; leading decimals such as `.01` are accepted without floating-point rounding. Zero, incomplete or overprecision inputs do not request a quote. During an in-flight quote, editing the pair or amount immediately invalidates the old UI result and keeps only the latest unsent order queued.

The already-started HTTP request drains, with a 27-second browser deadline, before the latest order starts; obsolete results never reinstall themselves. Hidden tabs remove queued work and stop polling, while an already-started request may drain. This prevents rapid edits from flooding the server; it does not eliminate upstream latency.

No completed quote is cached for later signing. BUSY responses carry a cooldown honored across input edits and automatic retries.

The API bounds expensive responses to 25 seconds and retains read-only work for cleanup after a disconnect using the Worker's bounded lifetime extension. Abandoned admission and shared-search ownership expire after 60 seconds; this is recovery protection, not additional execution capacity or a price guarantee. Genuine overload may still return 429. Signing, approval and transaction submission are never queued or retried by this quote mechanism.

Wallet connection uses Dynamic in connect-only mode. Its picker loads on the first connect click, independently of quoting, and supports external EVM wallets; no app login signature or embedded wallet creation is required. Route retains its own transaction-binding checks, exact approvals and wallet simulation. A disconnected or replaced session cannot continue a pending swap. Dynamic connection is not server-side proof of wallet ownership and does not bypass the hosted site's access restrictions.

The swap button shows an opening animation while loading the wallet picker module. The account pill/checkmark appears only when an account is reported, including restored or changed accounts; this is connection feedback, not a transaction confirmation. Token selection keeps keyboard search/navigation and highlights the selected token. Curated contract addresses are shortened visually with the complete address available in accessible text and on hover; imported addresses remain fully visible with an unverified warning. Menu and connection transitions respect reduced-motion preferences.

The swap graph shows up to five assessments: the selected route first, other ranked candidates in one-based backend `rank` order, then remaining assessments in their original order. Excluded candidates have a null rank. The full API evidence remains available even when the graph's five-path cap hides a candidate. This changes presentation, not the routing search or transaction selection.

ETH, WETH and USDG use curated address-bound artwork. Imported-token images are looked up independently through Dexscreener, matching Robinhood Chain and the exact base-token address. Missing or failed images keep a neutral fallback. No image is chosen by symbol alone, and a logo does not verify the token. Imported tokens show a red “Unverified Token Selected” warning; check the full address in the picker. The contracts remain unaudited regardless of the interface wording.

The pay field offers **50%** and **Max** using integer token units, not a rounded displayed balance. Half rounds down to the smallest token unit. ERC20 Max uses the full balance; native ETH Max reserves the larger of 0.0002 ETH and twice the current quoted gas estimate. This is a convenience buffer, not a guarantee that the final transaction has enough gas. These controls only edit the input; they never sign or submit.

Quotes expire within 30 seconds and refresh approximately every 15 seconds in the browser. Direct quotes include their pricing block; upstream quotes expose a reference block and `blockPinned: false`. V2 rejects network blocks more than 30 seconds old. Quotes do not reserve liquidity.

The UI offers 0.1%, 0.5% and 1% slippage. It reviews `execution.amountOut` when simulation succeeds, otherwise the original `amountOut`; neither includes a Route fee because Route charges zero. Minimum received is `floor(reviewedOutput * (10000 - slippageBps) / 10000)`. Zero is rejected. This user minimum remains fixed through approval even when the route is refreshed.

1. Review the token addresses, input, expected output, estimated gas and minimum.
2. Approve only the exact input to the executor for the selected provider, if necessary. An insufficient existing nonzero allowance is reset first.
3. Refresh the selected provider after approval. All active providers have different executors. Switching to any other provider requires a fresh user review and approval check. The original input, recipient and minimum stay fixed.
4. Request an unsigned transaction and decode its chain, target, amount, minimum, recipient and deadline.
5. Simulate the complete swap from the signing wallet. If preparation or simulation fails, the app may try another provider sharing the reviewed executor. There is no automatic cross-executor fallback. Both server and wallet preflight use an 8,000,000-gas diagnostic ceiling; it is not sent as the transaction gas limit. Only then let the wallet estimate gas and request the signature.
6. Check the receipt before declaring success.

The app checks the selected wallet account and chain before each signing step. Its deadline is five minutes after the latest block. The API permits deadlines within 20 minutes and minimums within 5% of its fresh estimate. The contracts enforce the signed minimum and deadline independently of the API.

## Direct execution

### Output-specific Kyber execution

Kyber swaps that output native ETH keep the existing guard, preserving contract recipients that forward received ETH immediately. ERC20 outputs, including WETH, use `RouteLeanMetaExecutor` at `0x70656A2B4A401DeF17c55687c19C536C0FAD4DB1`, deployed and smoke-tested on September 6. It measures output delivered directly to the recipient, removing one intermediate token transfer.

Configuration exposes `executors` for native output and `tokenOutputExecutors` for ERC20 output. A changed spender requires a fresh wallet review: a saved quote or existing approval does not authorize the new address. Exact input, recipient, minimum, deadline and full simulation remain required. These contracts remain unaudited.

The September 6, 17:18–17:26 UTC original-18 local-fork run had nine successful pairs with identical output: eight token-output cases used 3,523–8,817 less gas and one native-output case was unchanged. Nine cases failed on both guards and standalone Kyber; none counts as a win. Independently built opaque plans prevent attributing the entire difference to the contract alone.

A separate 0.0001 ETH→CHUMP mainnet smoke succeeded. This is not a full-provider comparison, mainnet fee comparison, quote-speed result or a claim of better results for every trade.

The current V2 flow refreshes routes **before signing**; Route's own V2 executor does not rerun route selection during execution. DFlow's [JIT routing](https://pond.dflow.net/spot/jit-routing) instead reevaluates supported prop-AMM legs onchain. The legacy V1 router's bounded onchain search is separate and is not used by the current UI.

An **undeployed research prototype**, `RouteJitV2Executor`, can choose between two caller-authorized paths inside execution through one verified 0.30%-fee Uniswap V2 factory. It keeps the input, output token, recipient, minimum and deadline fixed, and requires an output-unit improvement threshold before replacing a viable first path. Checking alternatives adds gas even when no switch occurs. This is not enabled in the app or API, does not cover prop AMMs, and is not DFlow feature parity. Positive-output alternative quotes alone do not establish competitive liquidity or net savings.

Upstream providers can have their own adaptive execution. Kyber documents [Smart Settlement](https://github.com/KyberNetwork/kyberswap-documentation/blob/main/developer-guide/start-here/foundational-solutions/smart-settlement-better-swap-output-with-lower-slippage.md), which compares candidate pools during execution, but currently limits rollout to selected client IDs. Route has not verified its eligibility or observed activation, so this is not advertised as an enabled Route feature. Outer recipient, minimum and deadline protections remain independent of upstream routing choices.

The app calls `RoutePoolExecutor.swap`, which executes supplied disjoint branches through canonical V2 pairs, authenticated canonical Uniswap V3 pool callbacks, fixed Ramses routing and immutable allowed adapter fallbacks. The V3 callback is restricted to the active canonical pool and exact required payment; it does not repeat an onchain route search.

Each branch may cross venues; native ETH is wrapped/unwrapped at the boundary, with special handling for V4 native pools. No fee wrapper is used. The direct spender changed; old approvals do not transfer and a previously reviewed target cannot silently change during preparation.

The executor verifies exact input consumption and actual balance changes, enforces the user's minimum and pays all combined output to the recipient. No Route treasury receives any part of the swap. Temporary approvals are cleared. Partial fills, output below the minimum, unsupported transfers and expired deadlines revert; reverted transactions still consume gas but retain no Route fee.

## Upstream execution

For native ETH output, `RouteMetaExecutor.swap` receives upstream output, measures it and pays the recipient. For ERC20 output, `RouteLeanMetaExecutor.swap` instead measures output delivered directly to the actual recipient. Both enforce the outer exact input, user minimum, recipient and deadline, call only the fixed Kyber router and swap selector, and prohibit arbitrary outer targets or delegated execution.

0x uses a separate deployment of RouteMetaExecutor, fixed to AllowanceHolder and its `exec` selector. The server checks the full input, native value, token pair, executor receiver and output minimum in both ABI envelopes. The inner Settler must be the registry's latest or active previous taker deployment; a paused or unavailable registry fails closed. The wallet approves its Route executor, and that executor temporarily approves only AllowanceHolder, not Settler.

For 0x, `txOrigin` must identify the signing EOA; quotes are rebuilt for it before signing. The current wallet flow does not support a relayer/bundler using a different origin. Opaque actions and the provider's inner 0.5% minimum are not rewritten. The outer user minimum and deadline remain enforced; a stricter inner minimum can still cause a revert when the user's tolerance is looser.

Only the caller's exact input is transferred or temporarily approved. The executor independently verifies input consumption and gross output. For Kyber, the server also validates the inner payload's fee settings and supported flags, and raises its inner minimum to the signed user minimum when necessary. A changed upstream plan cannot lower the signed user outer minimum. The outer deadline remains independently enforced.

Active `RoutePoolExecutor`, `RouteMetaExecutor` and `RouteLeanMetaExecutor` contracts have no owner, fee recipient, fee-rate setter, upgrade or rescue-withdrawal function. Adapters and upstream bindings are immutable. Legacy contracts remain deployed and unchanged. Upstream contracts can have their own administrative controls and risks. Restricting the target and enforcing a minimum output does not make those protocols audited.

## Read-only candidate checks

Quote assessment uses `eth_call` and `eth_estimateGas` with a synthetic caller. For ERC-20 input it locates and rechecks balance/allowance storage by observing the real token's getters under per-call overrides. Token bytecode is never replaced with a mock. Real pools and output-token state are retained; unsupported layouts remain unverified. The block hash is rechecked before returning.

These test balances and allowances do not prove that your wallet has enough funds or that a token behaves the same for every address. Address-dependent restrictions, changing liquidity, gas conditions and RPC failures can still prevent execution. Always simulate again from the actual signing wallet after approval. A simulated result is a check at one block, not a future guarantee.

## Tokens, gas and risk

Address import verifies basic contract metadata, not token legitimacy, sellability or value. Symbols can be spoofed. Fee-on-transfer and rebasing tokens are unsupported; unusual tokens may fail simulation or execution. Do not send tokens directly to Route contracts: there is no recovery function.

Displayed gas and net output are estimates. Route's price-impact estimate compares with a smaller route quote and is not an independent price oracle; upstream impact is currently unavailable. Slippage bounds your quote-relative output, not a fair-market price. There is no MEV-protection guarantee.

Rejecting the swap after approving leaves that wallet allowance in place. Revoke it if no longer needed. A confirmation timeout does not prove failure: inspect the transaction hash before retrying. Successful receipts are not irreversible chain finality.

## Gas prices and failed checks

When assessment is unavailable, `execution.failure` reports a closed `stage` and `reason` category rather than raw RPC error text. Stages distinguish the execution call, gas estimate, fixture work and unknown origin. Reasons can identify rate/access limits, timeouts, resource limits, gas-price rejection, missing state, unsupported methods, rejected requests or network failures.

`layout-unverified` can mean missing or failed storage probes; it does not prove the token is unsupported. These categories help explain a failure, but do not prove its cause. No failure is retried or treated as executable because of its category, and a successful alternative still takes priority.

Full-transaction checks use an explicit positive gas price shared by `eth_call`, `estimateGas` and the gas-cost ranking model. The price is at least the checked block's base fee: concurrent block and suggested-price reads can describe adjacent fee states. `execution.gasPrice` records the attempted wei-per-gas value, including failed RPC checks; it is null when fixture checks prevented execution.

An unavailable result remains unverified and its gas-cost fields remain heuristic even when the attempted price is recorded. Omitting gas price can make a hook evaluate a zero-price simulation differently from a paid transaction. Original upstream `amountOut` remains indicative; assessed output and minimum checks determine eligibility.

Before requesting a swap signature, the website refreshes the latest block and uncached suggested gas price. On EIP-1559 chains, the maximum fee is twice the observed base fee plus the suggested priority fee; the priority fee is the positive difference between the suggested gas price and base fee, or zero. The cap is a ceiling, not the amount automatically charged.

The website re-simulates the reviewed transaction with those same fee fields, then requests the signature while leaving the gas-limit estimate to the wallet. Chains without a base fee retain legacy pricing. No transaction is automatically resubmitted. This buffer does not guarantee inclusion after an extended wallet delay, prevent wallet fee edits, or freeze fee-sensitive hook behavior.

The contract still enforces the original minimum output, recipient and expiry. Route charges no integrator fee; network gas, LP and hook fees remain separate.
