Skip to content
Writing

Introducing fast-fill: instant cross-chain transfers on the bridge you already trust

25 min readKai Aldag

A thin optimistic-fill layer on Circle CCTP v2 and LayerZero OFT: funds in seconds when a relayer fronts them, and never worse than the bridge if no one does. No escrow, no liquidity pool, no new trust assumption. Proven on mainnet.


Fast Fill

TL;DR

Canonical, message-based bridges — Circle’s CCTP and LayerZero’s OFT — are the safest way to move assets across chains, because the destination only ever mints against a cryptographically verified message. The catch is latency: you wait for source-chain finality and off-chain attestation before the funds appear. That’s seconds in the best case and many minutes in the worst.

The usual fix — a “fast bridge” with its own liquidity pools, escrow contracts, and solver inventory — buys speed by adding a whole new system to trust, and can leave you worse off than the bridge if it fails.

fast-fill takes a different route. It rides the bridge’s own authenticated channel and lets an external relayer pre-pay your transfer on the destination chain before the bridge message is verified, for a small, user-priced premium. When the bridge finally settles, the in-flight bridged funds reimburse the relayer. The relayer never holds your money in escrow; the transfer either arrives early (a relayer filled it) or on time (the bridge delivers it) — never late, never for more than you agreed.

  • Best case: funds in ~1.5 seconds.
  • 🛟 Worst case: identical to using the bridge directly — same arrival time, zero premium.
  • 🔒 No escrow, no pool: the bridged funds are the relayer’s reimbursement.
  • 🧾 Trustless & permissionless filling: a relayer that fills a fake order can only lose its own money.
  • Live on mainnet: real USDC and real Circle attestations — the headline optimistic fill proven on Base → Arbitrum, with the executor-routed path live across Base, Optimism, and Arbitrum.

This post goes deep: the problem, the mechanism, the economics (with numbers), the security model, and the mainnet transaction record.


The problem: you shouldn’t have to choose between fast and trustless

Moving a dollar of USDC from Base to Arbitrum sounds simple. Under the hood, a canonical bridge does something careful:

  1. Burn (or lock) the token on the source chain.
  2. Wait for the source chain to reach a finality threshold so the burn can’t be reorged away.
  3. An off-chain attestation service (Circle’s Iris for CCTP, the DVN set for LayerZero) signs off on the message.
  4. Someone submits the verified message on the destination, which mints (or unlocks) the token.

Every step of that is what makes it safe — the destination mints only against a message it can cryptographically verify. But steps 2 and 3 are also why it’s slow. Depending on the route and the finality mode you pick, “slow” ranges from ~15 seconds to well over ten minutes.

The industry’s answer has been the fast bridge / intent-solver model: liquidity providers pre-position inventory on every chain, an escrow contract holds your input, and a solver network competes to front you the output. It’s fast — but look at what you took on:

  • A new liquidity pool to trust (and to be drained if there’s a bug).
  • An escrow contract holding your funds mid-flight.
  • A solver’s promise — and a failure mode where a solver front-runs, grief-fails, or vanishes, potentially leaving you worse off than if you’d just used the bridge.

The insight behind fast-fill is that you don’t need any of that to go fast. The canonical bridge is already delivering your funds to the destination — reliably, on its own authenticated rails. All that’s missing is someone willing to advance you the money for the few seconds or minutes until it lands. If you can pay that person a small premium and make it impossible for them to steal or strand your funds, you get bridge-grade safety at solver-grade speed.


The idea: an optimistic fill on the bridge’s own rails

Here is the entire mechanism in one sequence. The user initiates a normal bridge transfer, but the destination recipient is set to the fast-fill adapter, and the transfer’s hookData (CCTP) or composeMsg (OFT) carries an encoded Order. A relayer watching for OrderCreated events can then fill the order on the destination before the bridge verifies anything.

The two outcomes are worth stating precisely, because the worst case is the whole point:

  • Best case (a relayer fills): the recipient is paid outputAmount − fee in seconds. When the bridge message later settles, the arrived funds reimburse the relayer exactly outputAmount, and any surplus goes to the recipient.
  • Worst case (no one fills): the bridge settles as it always would, and the recipient receives the full arrived amount — at the same time, and for the same cost, as if fast-fill weren’t in the path at all.

There is no third outcome where the user is late and out-of-pocket. fast-fill can only make a transfer faster or leave it unchanged.


The load-bearing invariant: why filling is trustless

Everything rests on one line:

orderId = keccak256(abi.encode(order))

The same orderId is computed in three places: when the source encodes the order into the bridge payload, when a relayer fills, and when the destination settles the authenticated message.

Because the order data settles through the bridge’s authenticated channel — a Circle-attested message or a LayerZero-verified compose — a relayer that fills against a fabricated order computes an orderId that no settling message will ever reproduce. That relayer is simply never reimbursed.

This flips the usual trust model on its head. A careless or malicious filler can only ever lose its own funds — never the recipient’s, never the protocol’s, never another filler’s. There is nothing to steal by filling a bogus order; you’d just be gifting money to a stranger. That’s exactly why fast-fill makes filling permissionless by default: there’s no allowlist, no staking, no reputation system, because the economics are self-punishing.


How it works, mechanically

The Order

An order is a plain struct, encoded verbatim into the bridge’s hook payload. Transport identifiers (CCTP domains, LayerZero endpoint ids) are deliberately not in it — they’re resolved at the contract edges — so the orderId stays stable and a relayer only needs the emitted order to reconstruct the hash.

struct Order {
    uint8   bridgeType;           // 0 = CCTP, 1 = OFT
    uint32  srcChainId;
    uint32  dstChainId;
    bytes32 sender;               // user on the source chain
    bytes32 recipient;            // final recipient (canonical address.toBytes32())
    bytes32 inputToken;           // pulled from the user on the source
    bytes32 outputToken;          // delivered on the destination
    uint256 inputAmount;          // pulled from the user (pre bridge fee)
    uint256 outputAmount;         // deterministic worst-case arriving amount the filler is owed
    uint64  nonce;                // per-source-adapter monotonic counter
    uint64  startTime;            // absolute source timestamp — pricing baseline
    uint64  expectedDeliveryTime; // premium decays to 0 at/after this point
    uint256 discountRate;         // WAD/second — user-chosen time-premium accrual
    uint256 baseFee;              // flat fee (output-token units) owed on any fill
    uint64  callbackGasLimit;     // gas forwarded to the recipient's onFastFill hook
    bytes   hookData;             // optional destination-execution payload
}

The order lifecycle

Every order moves through a single-slot status machine. The record packs into one storage slot (address filler; FillStatus status; uint40 fillTime), so the hot path is cheap.

  • fill requires status == None (rejects double-fills and fill-after-settle).
  • settle requires status != Settled — the bridge’s own nonce is the first, independent replay guard; this is defense-in-depth.
  • Settled is terminal. The destination contract’s balance is the reimbursement pool, and every order settles exactly once.

Settlement authentication

The subtle part is making sure that only a genuine, bridge-verified message can settle an order — and that nobody can forge a burn to our adapter to poison a real order’s id. fast-fill solves this with CREATE2-deterministic addresses: each adapter’s counterpart on every chain is literally the same address, address(this).

For CCTP’s direct path (mintFee == 0), the source sets mintRecipient = destinationCaller = address(this), so only this adapter can call receiveMessage. After it mints and consumes the CCTP nonce, it additionally requires that the burn’s messageSender == address(this):

Anyone can craft their own CCTP burn to our adapter with a fabricated order in hookData — but they can’t make the burn’s messageSender be our adapter address, so such a burn can never settle here. That’s the check that stops an attacker from pre-settling a real order’s id and stranding the genuine transfer.

The OFT path enforces the analogous property with three gates on lzCompose: the caller must be the LayerZero endpoint, the local from OFT must be the one in the registry, and the embedded composeFrom must equal address(this).

Settlement itself is deliberately boring and safe:

owed    = min(arrived, order.outputAmount);
surplus = arrived - owed;
if (filled) { payout(filler, owed); payout(recipient, surplus); }
else        { payout(recipient, arrived); }
status = Settled;

_payout is a return-value-checked transfer. If a push fails — say the recipient is USDC-blacklisted or reverts — it credits a claimable[account][token] ledger instead of reverting, so a hostile recipient can never brick settlement. Effects (status) are written before any external transfer, and every state-changing entrypoint is nonReentrant.


The economics

fast-fill’s pricing is intentionally simple on-chain and factual off-chain. The contract enforces a small signed fee curve; the demo and relayers choose sane default values from live market data (gas benchmarks, destination gas price, ETH/USD, Circle’s own fee API).

The premium curve

The fee owed to a filler has two additive parts: an optional flat baseFee (a fixed price for the service, owed on any fill) and a time premium that is largest right after the order’s startTime — when the relayer must front capital the longest — and decays linearly to zero at expectedDeliveryTime. A late or never-filled order costs the user nothing beyond the bridge.

timeSaved = max(0, expectedDeliveryTime − max(fillTime, startTime))
rate      = min(discountRate · timeSaved, maxFeeRate)          [WAD]
timeFee   = outputAmount · rate / 1e18
fee       = min(baseFee + timeFee, outputAmount)
payout    = outputAmount − fee        (paid to the recipient at fill)

The optimistic-fill premium decays to zero at the bridge's delivery time

The chart shows all three regimes on an illustrative $1,000 transfer with a 60-second delivery window:

  • The cap plateau (left). maxFeeRate is a per-adapter governance ceiling on the rate (deployed at 0.5%). A user can request an aggressive premium, but the adapter clamps it. In the live Base→Arbitrum run below, the user’s premium saturated exactly this 0.5% cap.
  • The linear decay (middle). As the bridge’s expected delivery time approaches, the relayer would be fronting capital for less and less time — so the premium it can earn shrinks proportionally.
  • The flat floor (right). After the delivery window, only the flat baseFee remains (here $0.05, a stand-in for the fill’s gas). Beyond that, the premium is zero — filling late earns nothing but the base fee.

Both baseFee and discountRate are per-order, user-chosen. Set baseFee = 0 for a pure time curve, or discountRate = 0 for a flat fee. Timing is derived on-chain: startTime = block.timestamp, and the user signs a relative deliveryWindow, so expectedDeliveryTime = block.timestamp + deliveryWindow. Signing a relative window (rather than an absolute timestamp) means the window a user agreed to holds no matter when a sponsoring relayer actually submits.

Where a fast-fill fee actually comes from

It’s fair to ask: what does going fast actually cost me? The demo derives every signed value from factual inputs, so we can decompose a real quote. For a $1,000 fast CCTP transfer to Arbitrum with Circle’s Relay Mint enabled:

Anatomy of a fast-fill fee — the relayer's own cut is sub-cent

The headline: everything fast-fill itself adds is a few cents. The largest line item, the Circle protocol fee, is the bridge’s — you’d pay it going direct too. The mint-relay fee (which pays whoever submits the destination mint), the fill’s gas floor, and the actual speed premium together come to about three cents on $1,000. The time premium in particular is tiny by design: it prices the relayer’s capital at a 10% APR opportunity cost over the seconds it fronts the money, and 10% APR for a few seconds rounds to almost nothing. Users see all of these signed values before they submit, and relayers independently recompute and reject stale or underpriced quotes.

The overhead of a thin wrapper

Because fast-fill rides the bridge’s own message rather than adding a second one, its gas overhead is modest. Measured against a byte-identical in-EVM mock bridge (so the bridge’s own cost cancels in the subtraction), here is what fast-fill itself adds per operation:

What the thin wrapper costs: fast-fill's gas overhead per operation

For context, a real CCTP burn through the adapter costs ≈167,638 gas end-to-end on an Ethereum-mainnet fork, of which the bridge is the large majority. fast-fill never adds an escrow write or a second cross-chain message — it threads its order through the payload the bridge was already carrying. (On the L2s where it’s deployed, the dollar cost of all of this is a fraction of a cent.)

Speed: who actually waits

This is the part that matters to a user. When a relayer fills, the user has usable funds in about 1.5 seconds — regardless of how slow the underlying bridge is. The relayer, not the user, absorbs the bridge’s settlement latency, and is paid the premium precisely for taking on that wait and that capital risk.

When a relayer fills, the user waits ~1.5s — not for the bridge

(Bridge settlement times are approximate and route/finality-dependent; the point is the order-of-magnitude gap.)

The relayer’s business

A fast-fill relayer earns from two independent roles, and neither requires a liquidity pool:

  1. Optimistic filling. When it holds destination inventory and a fill clears its gas-backed profitability floor, it calls fill(order), pays the recipient instantly, and is reimbursed outputAmount at settlement — pocketing the premium. Its capital is tied up only for the bridge-latency window (seconds to minutes), which is exactly what the time premium prices.
  2. CCTP mint relaying. For orders that opt into Circle’s Relay Mint (mintFee > 0), the relayer polls Circle’s attestation and calls CctpExecutor.execute(...), which mints the USDC, pays it the mintFee, and forwards the rest to the adapter. This needs only gas — no inventory — and can be done even for orders it didn’t fill.

Crucially, there’s no relayer liquidity pool and no protocol escrow. The in-flight bridged funds are the reimbursement. That makes the capital model dramatically simpler than a solver network: a relayer needs enough working inventory to cover the fills in flight during a bridge-latency window, and nothing more.


CctpExecutor: a standalone public good

CCTP has a rough edge: after a burn, someone has to submit the destination mint, and Circle’s own forwarding service is a paid, centralized convenience. fast-fill ships a generic, permissionless replacement — CctpExecutor — that knows about CCTP messages and USDC but nothing about fast-fill orders. Any CCTP integrator can use it.

A source burn sets mintRecipient = destinationCaller = CctpExecutor and puts an envelope in hookData:

struct ExecHook {
    uint256 mintFee;  // USDC paid to whoever calls execute()
    bytes32 target;   // forward recipient OR hook receiver contract
    uint64  gasLimit; // 0 => forward-only, >0 => call target.onCctpExecute(...)
    bytes32 refundTo; // claimant if hook execution fails
    bytes   payload;  // integrator-defined data
}

On the destination, anyone calls execute(message, attestation): the executor mints the USDC to itself, pays mintFee to the caller, and either forwards the remainder to target (forward-only mode) or calls target.onCctpExecute(...) in the same atomic frame (hook mode). For a fast-fill order, the hook is what settles it.

The accounting for a routed fast-fill order is unchanged — mintFee cancels out because it’s reserved on the source side:

forward − outputAmount
  = (inputAmount − feeExecuted − mintFee) − (inputAmount − maxFee − mintFee)
  = maxFee − feeExecuted ≥ 0

so the filler is still reimbursed exactly outputAmount, and the recipient still gets the maxFee − feeExecuted surplus.

Batching and directed fees. CCTP v2 has no on-chain batch mint, so a relayer amortizes the per-transaction base cost by batching the calls: executeBatch(messages[], attestations[], feeRecipient) relays many messages in one transaction with partial success — each item runs in its own try/catch under a single reentrancy guard, so an item that reverts (already relayed, stale attestation) is skipped and its CCTP nonce stays redeemable, rather than aborting the batch. FastFillBase has the symmetric fillBatch. Both also support directed payout (executeTo / fillTo) so a hot wallet can relay while a treasury collects — but these only ever move the relayer’s own fee/reimbursement; the user-signed recipient and the source-attested delivery target stay authoritative.


Destination executions: act on funds the instant they arrive

An order can carry hookData and a user-signed callbackGasLimit (capped at 5,000,000 gas). When the funds are delivered — whether by an optimistic fill or by the bridge settling — a recipient contract receives an onFastFill(orderId, token, amount, hookData) callback in the same atomic frame as the transfer. This is how you bridge-and-do-something in one shot: deposit into Aave, swap on Uniswap, fund a smart account.

The failure policy is governed by the receiver’s own revert data, and it’s designed so funds are never stranded:

onFastFill succeeds            → funds delivered, execution ran
reverts RedirectFunds(dest)    → funds delivered to dest instead
reverts anything else / OOG    → funds credited to claimable[recipient] (recover via claim())

This mirrors CCTP v2’s atomic-hook semantics but is strictly safer: because the transfer and callback share one revertable frame, a deterministically-failing hook can never strand the bridged funds. The demo ships two validated hooks — a Uniswap V3 swap and an Aave V3 deposit — both deployed on Base, Optimism, and Arbitrum, each leaning on the revert-to-redirect rule so a failed action degrades to a plain transfer of the original token to the user.

The hardening here is meticulous. The callback is gas-capped and return-bomb-safe. The forwarded gas budget is guaranteed by an exact in-frame check that accounts for both nested EIP-150 63/64 deductions — so a relayer that under-funds the transaction reverts the whole fill (forcing a retry) rather than quietly starving the callback. And it all runs behind the existing nonReentrant guard with effects written first, so a hostile receiver can’t re-enter or claw back funds it wasn’t owed.


Gasless and sponsored transfers

Neither users nor relayers should have to hold gas on every chain just to sign. Both adapters support signature-based funding:

  • EIP-2612 single-tx — batch a selfPermit before the action via multicall([selfPermit(token, …), initiateCCTP(…)]), so approval and bridge land in one transaction. Works for USDC and USD₮0.
  • Permit2 sponsored intent (initiate*For / fillFor) — a user signs an off-chain order intent; a relayer submits it and pays the gas, while funds are pulled from the signer via Permit2. The signature commits to a witness binding the recipient, amounts, timing, pricing, the destination execution, and the bridge mode (CCTP fast-vs-finalized + executor routing, or OFT executor options). So a submitting relayer can’t re-price, re-time, re-route, or change the destination action of a signed intent. This is proven against the real Permit2 in a fork test, including rejected attempts to tamper with the recipient and to flip the transfer speed.

Configuration: one immutable registry, deterministic addresses everywhere

All chain-specific data — CCTP/LayerZero addresses, domains, endpoint ids, per-chain USDC, and each OFT’s per-chain (oft, token) pair — lives in a single immutable FastFillConfig contract, deployed once via CREATE2 so it lands at the same address on every chain.

The payoff is that there is no per-counterpart wiring to get wrong. Because the registry, the executor address, the owner, and the fee cap are identical across chains, every adapter is itself CREATE2-deterministic — so the counterpart adapter on the far chain is simply address(this), which is exactly the property the settlement-authentication checks rely on. There are no owner setters for addresses, domains, or counterparts; those are read from the registry at call time. And on every use, the adapter cross-checks its local domain / endpoint id / token against the live bridge contracts and reverts on any mismatch — a wrong constant can’t silently ship. The owner-gated surface is tiny: setMaxFeeRate and setPaused.

Many tokens, one code path

OftAdapter is generic — parameterized by an oftId — and OftAdapterFactory stamps out one instance per token at a deterministic, cross-chain-stable address. Onboarding a new OFT (USDe, sUSDe, ENA, USDtb, …) is purely additive: add the per-chain rows to the registry, assign an id, and call deploy(oftId). No new adapter code. Because each token gets its own deployment, every token’s reimbursement pool is physically isolated — a decode or auth bug in one adapter can never reach another’s funds.

One honest caveat: a deployed adapter is just an address on our side — it doesn’t guarantee the token issuer’s live OFT has enabled peers for a given route. The USD₮0, USDe, sUSDe, and ENA adapters are deployed on all three chains; USDtb is defined in the registry but not yet stamped out by the factory; and some Ethena routes (e.g. USDe Arbitrum ⇄ Base) currently revert NoPeer because the issuer hasn’t wired those peers yet. The adapter framework is ready; peer availability is the token issuer’s to enable.


Proven on mainnet

fast-fill isn’t a testnet demo. The CCTP path has been run end-to-end on Ethereum-mainnet L2s with real USDC and Circle’s real attestation service.

The headline run: $1, Base → Arbitrum, filled before settlement

A $1 transfer to a fresh recipient, with a user-chosen premium that capped at the adapter’s 0.5%. The relayer fronted the funds on Arbitrum before the bridge settled, then was reimbursed when it did.

Live on mainnet: a $1 Base→Arbitrum transfer, filled before the bridge settled

Reading the waterfall (all figures are the real on-chain record, in USDC):

PartyResult
Recipient$0.994871 total — of which $0.994801 arrived at fill time, in ≈1.5 seconds, before CCTP settled
Relayernet +$0.004999 — the 0.5% premium earned for fronting capital across the bridge-latency window
Bridge$0.000200 reserved as maxFee; the unspent surplus ($0.000070) flowed to the recipient at settlement

And the fallback was demonstrated too: two baseline runs with no relayer simply delivered the funds when CCTP settled — the recipient received 999,870 units on a $1 transfer (the 130-unit haircut is Circle’s fast-transfer fee), at no premium. That’s the worst case, and it’s exactly the bridge.

The executor path, live

The newer CctpExecutor-routed path has since been deployed on Base, Optimism, and Arbitrum and smoke-tested with live USDC for both unfilled and optimistically filled orders. One routed Optimism→Arbitrum fill, for example, paid the recipient at fill time, then at settlement had the executor pay the mint relayer its mintFee, reimburse the filler, and route the surplus to the recipient — all in the accounting described above, on-chain, with real money.

The OFT path, de-risked on forks

The LayerZero path targets USD₮0 and the Ethena OFT suite (USDe, sUSDe, ENA). It’s proven against the real USD₮0 OFT and LayerZero endpoint on an Optimism fork — driving the real mint and the real compose to settle an order — plus live fact-checks of every OFT’s on-chain configuration across four chains. A live USD₮0 source transfer has been broadcast Optimism→Arbitrum (pending the pathway’s source confirmations at the time of writing, not yet confirmed delivered); a full public OFT demo is the next milestone.

Deployed addresses

All contracts are CREATE2-deterministic — the same address on Base, Optimism, and Arbitrum — from a single deployer, with maxFeeRate = 0.5%:

ContractAddress
FastFillConfig0xaec766479DB174110958Bc45D141A2C5eF693DF5
CctpExecutor0xAFc7bBc0B5fD7A4d9b936349cfE991e5bC6E2a80
CctpAdapter (executor-enabled)0x9FA37faBfA1Fd31Afe5A5F93e1c4Cd986b27bA75
OftAdapterFactory0x84Bb5d3142024da8d61CBEE0A4c722a1650fbFcb
OftAdapter (USD₮0 / USDe / sUSDe / ENA)one deterministic address per token

The demo hooks (UniswapSwapHook, AaveDepositHook) are deployed and source-verified on all three chains as well.


The security model, at a glance

fast-fill’s threat model is small because its trust surface is small. A condensed version of the full table:

VectorDefense
Double-fill / fill-after-settlefill requires status == None.
Replay of a bridge messageThe bridge consumes its own nonce; plus a status != Settled app guard.
Fake-order fillNon-matching orderId ⇒ filler is never reimbursed (self-punishing).
Forged CCTP burn to our adaptermessageSender == address(this) rejects burns not initiated by our same-address adapter.
Routed CCTP nonce griefingdestinationCaller = CctpExecutor; only the executor can consume the message.
Caller redirecting bridged fundsexecuteTo/fillTo redirect only the relayer’s own fee; recipient & delivery target stay authoritative.
Forged OFT composeThree gates: endpoint caller, local OFT, composeFrom == address(this).
Misconfigured registryLocal domain/eid/token cross-checked live against the bridge contracts at construction; a mismatch reverts the deploy.
Sponsor altering a signed intentPermit2 witness binds the intent and the bridge mode; tampering recovers a different signer and reverts.
Hostile destination receiveronFastFill is gas-capped, return-bomb-safe, nonReentrant; any failure routes to redirect/claimable.
Recipient/filler revert (e.g. blacklist)_payout falls back to a claimable ledger; settlement still completes.

The contracts ship with 141 tests — pure-library fuzzing of the pricing curve, full CCTP and OFT lifecycles, the executor’s routed/forward/hook modes, factory pool-isolation, adversarial races, 16k+-call invariants, gasless flows, destination-execution edge cases (reentrancy, return-bomb, gas-budget, atomic claw-back), gas benchmarks, and mainnet-fork checks against the real CCTP, USD₮0, Uniswap, Aave, and Permit2 contracts.


Status & what’s next

This is a prototype. It is not audited. It’s deployed for demonstration with tight caps on transfer size, and the backend relayer holds a hot key — so the live demo runs on tiny amounts. With that said, the design is intentionally close to production-shaped, and the iteration points are known:

  • Circle Gateway relayer funding — a designed-but-unbuilt path that lets a relayer keep a single unified USDC balance and mint destination inventory just-in-time before filling, eliminating pre-positioned inventory entirely. The design is front-run-safe by construction (the mint is bound to the relayer, and the fill pulls from msg.sender, so a copycat’s transaction reverts and rolls back the mint).
  • Surplus routing — currently always to the recipient; an intended point of flexibility.
  • More tokens and chains — additive for OFTs (assign an id, add rows, deploy); a new chain means publishing a new registry version.
  • A live OFT demo and, ultimately, an audit.

The philosophy won’t change, though. fast-fill is a thin, honest layer: it makes a cross-chain transfer faster when someone’s willing to help, it makes that help trustless and permissionless, and when no one helps it gets out of the way and lets the bridge do exactly what it always would. Speed when you can get it; safety, always.


Try it and dig in

  • Interactive demo — connect a wallet on Arbitrum / Optimism / Base, send a real (capped) transfer, and watch a relayer fill it in seconds.
  • docs/ARCHITECTURE.md — the full design deep-dive, with every authentication flow and the complete security table.
  • docs/PRICING.md & docs/GAS.md — the off-chain quote model and the gas methodology behind the charts above.
  • DEMO.md — the complete mainnet transaction record for the run charted here.
  • relayer/ — the autonomous Rust relayer bot, if you want to run one yourself.

fast-fill — instant when it can be, never worse than the bridge.

Written by

Kai Aldag

I build and write about crypto, cryptography, and distributed systems. Egg Tech is my one-person company — the home for what I ship and the notes I keep along the way.

Related writing