Overview
How Lane works
A swap goes through five stages. The first one runs continuously in the background. The other four run inside a single GET /v1/quote request, typically in under a second.
flowchart LR
A[1. Index<br/>every block] --> B[2. Route<br/>in memory]
B --> C[3. Quote<br/>1 eth_call]
C --> D[4. Build<br/>calldata]
D --> E[5. Simulate<br/>eth_estimateGas]
E --> F[tx + approval<br/>returned to the caller]1. Index (continuous)
The indexer keeps a copy of every pool's state in memory.
- Discovery. At start-up it backfills
PoolCreated(V3),PairCreated(V2) and v4Initializeevents from the configured factories and PoolManagers, plus the Solidly, Slipstream and Algebra creation events. Any other contract emitting those events is checked too: a V3 factory must expose the standard interface, and a V2 factory's swap fee is read from its pair bytecode. Unknown fee formulas are rejected rather than guessed. - State. It reads
slot0/liquidity(V3),getReserves(V2) orextsload(V4) in large multicalls. For V3 it also loads the initialized ticks around the current price (±16 bitmap words) so the estimator can simulate tick crossings. - Updates. Each block it reads the
Swap,Sync,Mint,Burnand v4ModifyLiquiditylogs. Most state comes straight from the log, with no extra call. A WebSocket RPC (WS_URL) triggers a sync as soon as a block lands; otherwise it polls everyPOLL_MS. - Reorgs. It remembers the block hash at each tip. On a mismatch it walks back to the common ancestor, re-reads the pools touched since, and replays.
- Cold start. Quoting is available as soon as V2/V3 pools are loaded (~20–40 s). The rest loads in the background, one step at a time (token metadata first, then other factories, v4 pools, which can take ~15 min, and V3 ticks); a failing step is retried a minute later without blocking the others.
- Snapshots. State is saved atomically to
api/data/snapshot.json(or Redis) every 60 s, so a restart replays only the missed blocks (~4 s instead of a full backfill).
Details: Routing engine → Indexer.
2. Route (in memory, no RPC)
The pathfinder runs a depth-first search over the live pool graph:
- Up to 3 swaps, mixing V2, V3 and V4 pools.
- Plus one free rewrap between allow-listed WHYPEs (unwrap one, wrap the other, 1:1). This connects pools that use different WHYPE contracts, e.g.
PERPME → WHYPE_A ⇄ WHYPE_B → USDC. - Native HYPE is tried through every WHYPE.
- The last hop only considers pools that contain
tokenOut, and enumeration is capped at 5,000 paths.
Each path gets an estimate: exact for V2 (x·y=k), tick-by-tick for V3, constant-liquidity for V4. The estimate is net of the gas the route costs. The top 20 go to the next stage.
3. Quote (one eth_call)
The 20 candidates are quoted exactly by Executor.quote(Split[]), all in a single Multicall3 eth_call. quote runs the real swaps against real pool state; the swap callback reverts with the amounts (the QuoterV2 technique), so no balance or approval is needed and tick crossings, hooks and dynamic fees are all accounted for.
Then the router tries splitting: it takes the best route plus up to 2 routes that share no pool with it (and use the same WHYPE), quotes each at 5%, 10%, … 95% of the amount (one more multicall), and searches every allocation in 5% steps (231 allocations for 3 legs). The split is kept only if it beats the best single route after the gas of the extra legs, and the final split is re-quoted exactly.
Example on testnet, HYPE→USDC: 0.01 HYPE uses one route; 1 HYPE splits 70/30; 20 HYPE splits 60/40.
4. Build
The API encodes Executor.swap(tokenIn, tokenOut, amountIn, minOut, recipient, wrappedNative, deadline, splits):
minOut = amountOut × (1 − slippageBps / 10,000), withamountOutalready net of the router fee and of measured token taxes.deadline = now + 300 s.- With
permit2=trueit buildsswapWithPermit2(...)and returns the EIP-712 data to sign instead. See Permit2.
If a pre-graduation launchpad token pays more on its bonding curve than through the aggregator, the API builds a call to the launchpad's router instead (venue: "launchpad").
5. Simulate
Before anything is returned:
- Balance and allowance of
senderare read. If the allowance is short,approvalholds theapprovetransaction to send first. - The exact transaction is passed to
eth_estimateGasfromsender. A revert (balance, hook, blocked transfer, anything) makessimulation.ok = falseand adds awarningtotx.
The caller gets tx, approval, simulation, and the full route breakdown. See Build and execute.
On-chain execution
When the user sends tx:
- The Executor pulls
tokenIn(or wraps the HYPE sent asvalue). - For each split leg, it runs its hops. V2: transfer to the pair, compute the output from reserves and the amount actually received, call
swap. V3: callpool.swap; the pool calls backuniswapV3SwapCallbackand the Executor pays exactly what is owed. V4:unlock→swap→settle/takeinsideunlockCallback. Rewrap:withdrawthendeposit. - It measures what it actually received at every step (so fee-on-transfer tokens work), takes
feeBpson the total output, forwards it, and sends the rest torecipient. - It checks that the recipient's balance grew by at least
minOut. If not, everything reverts.
Next: Architecture