Fill an order
A solver fills an intent by calling IntentSettlerV3.fill with the signed
order, its authorization envelope, a solver address, and opaque routerData.
The solver address must implement IIntentFiller.
The code below is illustrative. It shows the protocol boundary and call order; it is not a working routing implementation.
1. Screen with IntentLensV3
Section titled “1. Screen with IntentLensV3”Call IntentLensV3.preview(order) or batch orders with previewMany. The result
is an observation stamped with observedAt and observedBlock:
| Field | Meaning |
|---|---|
id |
keccak256(abi.encode(order)) |
cancelled |
cancelled[id] on the settler |
filled |
filled[id] on the settler |
nonceSpent |
The owner’s proxy nonce bit; not applicable until the proxy is deployed |
killedByOwner |
Whether the owner killed this order on their proxy |
proxyDeployed |
Whether the owner’s proxy exists |
inWindow |
now <= endTime; V6 orders may fill before startTime |
exclusiveWindow |
now <= startTime; the system filler can use the floor, outsiders pay the override |
decayComplete |
now >= decayEndTime |
floorNow |
recipient floor for a system fill at the observation time; 0 outside the window |
feeNow |
3 bps of the applicable floor, paid by the filler on top |
requiredNow |
floorNow + feeNow, the gross system-filler callback requirement |
floorForOutsider |
recipient floor for an outsider, including the 25 bps pre-start override |
requiredForOutsider |
floorForOutsider plus its 3 bps fee, the gross outsider requirement |
ownerBalance |
owner’s tokenIn balance |
ownerProxyAllowance |
owner’s tokenIn allowance to their proxy |
proxy |
the owner’s deployed proxy, or zero |
observedAt / observedBlock |
timestamp and block for the observation |
IntentLensV3 deliberately has no fillable boolean. Balance, allowance,
nonce state, time, solver inventory, and venue liquidity can change before a
transaction is included. Treat the lens as screening data, not a verdict.
nonceSpent is the owner’s proxy bitmap and an owner can also invalidate it
directly. Use filled[id] or a matching IntentFilled event to identify
settlement.
2. Implement the filler callback
Section titled “2. Implement the filler callback”The settler transfers order.amountIn of order.tokenIn to solver, then
calls this callback. The callback must return at least the gross requiredOut
of order.tokenOut to msg.sender, which is the settler. The fee is paid by
the filler on top of the owner’s floor and sent to FeeVault.
// Illustrative interface boundary from IIntentFiller.sol.interface IIntentFiller { function fillIntentCallback( IntentOrder calldata order, uint256 requiredOut, bytes calldata data ) external;}An implementation uses data as its routing input and must return the output
token to the callback caller before returning:
// Illustrative pseudocode. The venue route is solver-specific.function fillIntentCallback( IntentOrder calldata order, uint256 requiredOut, bytes calldata data) external { // Use order.amountIn of order.tokenIn and data to execute a route. // Transfer at least requiredOut of order.tokenOut to msg.sender.}Returning exactly requiredOut is the expected behavior. requiredOut is the
applicable floor plus the 3 bps fee; for an outsider inside the exclusive window
it also includes the 25 bps floor override. The solver keeps its margin by not
sending it to the settler. Any amount above the gross requirement that does
arrive is delivered to order.recipient; it is not refunded to the solver.
3. Dry-run the exact fill
Section titled “3. Dry-run the exact fill”A valid announcement is only authorization admission. Before spending gas, execute
the exact fill(order, auth, solver, routerData) as an eth_call at the
current chain state:
// Illustrative RPC shape; use your ABI encoder and provider.const result = await provider.request({ method: 'eth_call', params: [{ to: intentSettler, data: encodeFillCall(order, auth, solver, routerData), }, 'latest'],});The dry-run should cover the current time window, the exclusive caller terms,
proxy authorization and nonce,
owner balance and proxy allowance, callback behavior, route liquidity, and exact
recipient delivery. A successful observation from IntentLensV3 cannot replace
this call.
4. Submit the fill
Section titled “4. Submit the fill”If the dry-run succeeds, submit the same calldata as a transaction. fill is
permissionless; the transaction caller need not be the order owner. The settler
then validates the order, computes the current required output, asks the owner’s
proxy to pull the input, invokes the callback, measures receivedOut, and transfers
everything received to the signed recipient.
The transaction reverts if the order is cancelled, past its end time, or has a zero solver; if the proxy cannot pull the exact input; if the callback returns less than the gross requirement; if fee or recipient delivery is inexact; or if the settler’s token balances are not conserved. See settlement execution and the ABI reference.