Antler by Autoflux

Bridging & Settlement

Message passing across the trust boundary: deposits, withdrawals, output roots, and the fault-proof settlement flow.

Path: bridging-or-settlement

Third-party documentation. This is independently authored analysis of the public Optimism (OP Stack) codebase — not the official docs, and not reviewed or endorsed by the Optimism (OP Stack) team.

Bridging & Settlement

Moving assets or messages between L1 and L2 crosses a trust boundary: state on the L2 is not automatically accepted by L1. This module explains the message-passing machinery, the deposit/withdrawal flows, and how fault proofs changed settlement.

The two roles

  • Deposits (L1 → L2) — an L1 transaction that creates a message. The portal emits a deposit event; op-node folds it into the next L2 block as a deposit transaction. The L2 then executes it.
  • Withdrawals (L2 → L1) — an L2 transaction that emits a message. L1 does not trust L2 state, so the withdrawal must be proven against an output root and finalized only after a challenge window.

The contracts

  • OptimismPortal — the entry point. Holds deposited ETH, accepts deposit transactions, and is where withdrawals are proved and finalized.
  • CrossDomainMessenger — the general message layer. It hashes messages, guards against replay, and provides sendMessage/relayMessage. The token bridges sit on top of it, and so do most cross-chain applications.
  • L1StandardBridge / L2StandardBridge — token-specific convenience: depositERC20, withdrawERC20, plus the ETH wrapper.
  • SystemConfig — stores the addresses of the operator components (batcher, sequencer, proposer) and chain parameters; updates are events on L1 that op-node reads.
  • DisputeGameFactory — creates the dispute games used to settle output roots (see below).

Withdrawal lifecycle (three phases)

  1. Initiate — call the bridge/messenger on L2. The message is recorded in L2 state and emitted as an event.
  2. Prove — after the initiating L2 block has an output root posted to L1, submit a Merkle proof that the message is in that block's state, to the portal. This asserts "L1 can now verify the withdrawal is real."
  3. Finalize — after the challenge window (7 days on OP Mainnet) passes without the output root being successfully disputed, call finalizeWithdrawalTransaction to execute the message on L1.

Output roots and fault proofs

The linchpin is the output root — a commitment to the L2 state at a given block, posted by op-proposer. Historically these were accepted optimistically after the window. Since the fault-proof upgrades, a posted root is contested inside a dispute game:

  • Any challenger who believes a posted output root is wrong can start a game via the DisputeGameFactory.
  • The game executes op-program inside Cannon, a small MIPS/WASM VM running on L1, to deterministically recompute the L2 state transition from L1 data. The two sides bisect the instruction trace until the disagreement is pinned to a single instruction; the L1 bridge then rules on that instruction.
  • A root that survives the game (or is never challenged) becomes final and enables the corresponding withdrawals.

This converts the "optimistic" assumption from a social one (nobody challenged) into a cryptographically checkable one (if the root is wrong, someone can profitably prove it wrong on L1).

What builders actually touch

  • The bridges — deposit/withdraw tokens and ETH (use the SDK, see the SDK module).
  • The CrossDomainMessenger — for general cross-chain contract calls (a message to a contract on the other chain).
  • Slot the message with a unique nonce — every message has a globally unique nonce derived from the sender and a counter, so replay across chains is impossible.

Edge cases

  • A withdrawal cannot be proven before its block's output root is posted — builders must wait for the root, which is why SDKs expose a "ready to prove" status.
  • If an output root is successfully disputed, withdrawals proven against it must be re-proven against a valid root; funds are not lost, but the flow restarts.
  • Deposits to an address without a funded L2 balance for gas still succeed as L1 transactions — the message is simply not delivered until someone (or the deposit's own gas budget) covers execution.
  • Native ETH is not bridged by minting on L2; the portal holds the L1 ETH and mirrors the balance in the L2's ETH system account — always treat bridged ETH as a claim on the portal's holdings.

Interface

Interface
solidity
// OptimismPortal — the single entry point for deposits and withdrawals.
contract OptimismPortal {
function depositTransaction(
address _to,
uint256 _value,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
) public payable;
 
function proveWithdrawalTransaction(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
) public;
 
function finalizeWithdrawalTransaction(
Types.WithdrawalTransaction memory _tx
) public;
 
// Dispute game / fault-proof flavored accessors
function disputeGameFactory() public view returns (IDisputeGameFactory);
}
 
STATUSinterface