Fast Fill

fast-fill — Live Mainnet Demo (CCTP, Base ⇄ Arbitrum)

This is a record of fast-fill running on Ethereum mainnet L2s with real USDC: the CctpAdapter deployed on Base and Arbitrum, three real $1 transfers, settled through Circle's real attestation service and MessageTransmitterV2. All amounts are in USDC base units (6 decimals; 1,000,000 = $1).

Prototype, unaudited. Run with ~$5 of USDC for demonstration only.

This historical demo predates CctpExecutor. It demonstrates the direct CCTP adapter settlement path that is still used when mintFee == 0. The executor-routed path (mintFee > 0) has since been deployed and smoke-tested; see DEPLOYMENTS.md.

Deployments

WhatAddress
CctpAdapter (Base)0xC4a956Ec34BF7C0B07e4c84B72232E83879Ce1c0
CctpAdapter (Arbitrum)0xA4a9CaC201a6A625C04552624d8D1b172B08fad9
User / relayer (EOA)0xA06Bf163BC51A457D99C6283e78897727c4fDdF2

Owner = the EOA. Wired bidirectionally: domains (Base 6, Arbitrum 3), remote adapters, and per-chain USDC (remoteUsdc).

Runs 1 & 2 — baseline path (no relayer)

A $1 transfer Base→Arbitrum with no optimistic fill: the recipient simply receives the funds when the CCTP message settles. Each delivered 999,870 (the 130-unit haircut is Circle's 1.3 bps fast-transfer fee). These also seeded USDC onto Arbitrum to use as relayer liquidity for Run 3.

StepChainTx
Run 1 — burn (initiateCCTP)Base0x1ac1f0d3…dde2d2
Run 1 — settleArbitrum0x4920e31c…dc405d
Run 2 — burnBase0x9119fa4b…43afe2
Run 2 — settleArbitrum0x71361a96…90c2c8

Run 3 — optimistic fill (the headline)

A $1 transfer Base→Arbitrum to a fresh recipient 0xb959…bE53, with a user-chosen premium that caps at the adapter's 0.5%. The relayer fronts the funds on Arbitrum before the bridge settles, then is reimbursed when it does.

StepChainTxEffect
initiate ($1, premium order)Base0x9d449485…573d09burns 1,000,000; outputAmount = 999,800
fill (relayer)Arbitrum0x7764c033…1625fderecipient +994,801 instantly
settleArbitrum0x1b6bc543…4614e3relayer +999,800; recipient +70 surplus

orderId 0x5711e377…8286af; final record filler = EOA, status = Settled.

Outcome

PartyResult
Recipient 0xb959…bE53994,871 total — of which 994,801 arrived at fill time, before the bridge settled
Relayer (EOA)net +4,999 (~$0.005) — the 0.5% premium earned for fronting capital over the bridge-latency window
Premium4,999 / 999,800 ≈ 0.5% (the adapter maxFeeRate cap)

The recipient got their money in seconds instead of waiting for CCTP, for a sub-cent premium; the relayer earned that premium. And Runs 1–2 show the fallback: if nobody fills, the recipient just gets the funds when CCTP settles, at no premium.

How it was reproduced

Note: this run predates the config-registry refactor and the CCTP Executor, so the deploy/wire steps below reflect the original per-instance setters. The current flow deploys one immutable FastFillConfig (CREATE2), then CctpExecutor, then the CCTP adapter with the executor address baked in — see README → Deploy. The direct mintFee == 0 fill/attest/settle mechanics are unchanged.

  1. Deploy CctpAdapter on each chain (forge create, constructor: owner, maxFeeRate, TokenMessengerV2, MessageTransmitterV2, USDC).
  2. Wire each: setDomain, setRemoteAdapter, setRemoteUsdc (addresses in script/config/Addresses.sol).
  3. Initiate on the source: approve the adapter, then initiateCCTP(dstChainId, recipient, amount, maxFee, mintFee, minFinalityThreshold, deliveryWindow, discountRate, baseFee, exec)mintFee = 0 uses the direct settle path shown here; mintFee > 0 routes settlement through CctpExecutor.execute. minFinalityThreshold is 1000 (fast) or 2000 (finalized); deliveryWindow is relative seconds; baseFee is the flat optimistic-fill fee (0 for none). (This historical run predated the relative-window + base-fee + destination-execution additions.)
  4. (optional) Fill on the destination before settlement: relayer approves the adapter and calls fill(order).
  5. Attest: poll Circle's API https://iris-api.circle.com/v2/messages/{srcDomain}?transactionHash={burnTx} until status == complete.
  6. Settle on the destination, direct path: settle(message, attestation) (wraps the real receiveMessage). Executor-routed orders instead call CctpExecutor.execute(message, attestation).

See docs/ARCHITECTURE.md for how the contracts work, and test/fork/CctpForkE2E.t.sol for the fork-based dry-run that validated the source + message parsing against the real CCTP contracts before any funds were spent.

Additional live coverage

The CctpExecutor-routed CCTP path has now been demonstrated with live USDC for both unfilled and optimistically filled orders; see DEPLOYMENTS.md. The OFT (LayerZero) path is proven in the local + mock harness and is wired the same way, but a live OFT demo additionally requires deploying a demo OFT on both chains and configuring the LayerZero peers + DVN/executor security stack. Tracked as follow-up work.