Skip to content

GuidesBuild and execute

Swaps

Build and execute

Everything about turning a quote into a mined swap.

The flow

  1. Quote: GET /v1/quote?in&out&amount&recipient[&sender][&slippageBps].
  2. Approve if approval is not null (ERC20 input), then re-quote. Or use Permit2.
  3. Check simulation.ok and warnings.
  4. Sign and send tx unchanged.
  5. Confirm: the receipt's status, and the Executor's Swapped event for the exact amountOut and fee.

Parameters that shape the transaction

ParameterDefaultEffect
amountrequiredExact input. The router finds the best output for it (exact-in only; there is no exact-out mode)
recipientrequiredReceives the output. Can differ from the signer
senderrecipientWho signs and pays. Used for the balance, allowance and gas simulation
slippageBps50 (0.5%)minOut = amountOut × (10,000 − slippageBps) / 10,000. Range 0–5000

Set by the API, inside tx.data:

ValueRule
minOutFrom slippageBps, applied to the output after fee and measured taxes
deadlineQuote time + 300 s. After it, the swap reverts with Expired()
wrappedNativeThe WHYPE used to wrap/unwrap native HYPE on this route
splitsThe legs and hops of the route (encoding)

Slippage, minOut and deadline

SituationWhat happens
Price moves in your favorYou receive more than amountOut. All of it goes to recipient (minus the fee on the larger amount)
Price moves against you, within slippageYou receive between minOut and amountOut
Price moves beyond slippageRevert InsufficientOutput(amountOut, minOut). Nothing moves except gas
Sent after the deadlineRevert Expired()
A pool can't absorb the whole input (price limit reached)Revert PartialFill()

minOut is checked on what the recipient actually receives (its balance difference), so a token that taxes transfers to the recipient can't sneak under the floor.

Choosing slippage: 0.3–0.5% for liquid pairs; 1–3% for small caps; more for taxed tokens only if taxBps doesn't already cover the tax (it's already deducted from amountOut).

Auto slippage

slippageBps=auto applies the recommendation the quote always returns in slippage.recommendedBps:

Partbps
Floor (normal drift between quote and inclusion)30
Price impact of the trade+ half of it
Each swap beyond the first+ 20
A taxed token in the trade+ 100
A hooked v4 pool on the route (dynamic fees)+ 50
Range30 – 1500
Launchpad bonding curve300

What the quote tells the user

UI elementField
"+$4.12 vs one pool"savings.usd (and savings.vsBestSinglePool in tokens): our output minus the exact quote of the best route through a single pool
"37 pools scanned"scanned.pools
Output in dollarsamountOutUsd

Approvals

The spender is always the Executor (or Permit2 on the Permit2 path; the OrderBook for orders; the launchpad router for venue: "launchpad"). approval is pre-built with the right spender and the exact amount:

"approval": { "to": "0xTokenIn…", "data": "0x095ea7b3…" }

Send it with value 0, wait for it to be mined, then quote again. The API approves the exact amount, not unlimited. If you want an unlimited approval, build it yourself (approve(executor, 2^256-1)).

Native HYPE

DirectionHow
HYPE inin=HYPE. tx.value = amount. The Executor wraps it into wrappedNative
HYPE outout=HYPE. The Executor unwraps at the end and sends HYPE to recipient
HYPE → WHYPE, or WHYPE → WHYPERouted as a wrap/rewrap hop at 1:1

wrappedNative in the response says which WHYPE the route used. Elysium has several, and the router tries all the allow-listed ones.

Splits and multi-hop routes

splits is a list of legs. Each leg takes part of amountIn and follows its own route of 1–3 swaps (plus an optional rewrap):

"splits": [
  { "amountIn": "600000000000000000", "route": [ { "protocol": "v3", … } ] },
  { "amountIn": "400000000000000000", "route": [ { "protocol": "v2", … }, { "protocol": "v3", … } ] }
]
  • Legs share no pool (so one leg's price impact doesn't distort another's quote) and end in the same tokenOut.
  • The fee and minOut apply once, to the total output.
  • protocol is v2, v3, v4, wrap (WHYPE↔WHYPE rewrap) or launchpad.

Simulation

The API never returns an unchecked transaction:

simulationMeaningWhat to do
{ ok: true, gas }The exact tx succeeds from sender at the current blockSend. Use gas (+ a margin) as the gas limit if you like
{ ok: false, error: "insufficient allowance: …" }approval must be sent firstSend approval, re-quote
{ ok: false, error: "insufficient balance" }sender doesn't hold amount—
{ ok: false, error: "<revert reason>" }The swap would revert (blocked token, hook, …)Don't send. tx.warning is also set

sender must be the address that will really sign; with the default (recipient), make sure that is the case.

Launchpad tokens

Before graduating, some tokens can only be bought or sold through their launchpad's bonding curve (their transfers block contracts). When that curve pays more than the aggregator, the quote comes back with:

  • venue: "launchpad", feeBps: 0 (no router fee; the curve takes its own 1% tax),
  • tx.to = the launchpad router, and approval toward it,
  • a warning launchpad token (pre-graduation)….

Everything else (simulation, minOut, deadline) works the same.

Confirming the result

The Executor emits, on every swap:

event Swapped(address indexed sender, address indexed recipient, address tokenIn, address tokenOut,
              uint256 amountIn, uint256 amountOut, uint256 fee);

amountOut is what the recipient received; fee is the router fee taken. GET /v1/history?owner= lists them.

Next: Permit2

lane.markets · Make the most of every move.