Skip to main content
Available on Testnet today. Mainnet contract addresses and final timing parameters are published at Mainnet launch.

Overview

Whitechain settles on Ethereum via the OP Stack canonical bridge. Assets and arbitrary messages move between L1 (Ethereum) and L2 (Whitechain) through Optimism-standard bridge contracts. Deposits arrive on L2 in about 2 minutes. Withdrawals back to L1 complete after a mandatory dispute-resolution period: minimum 7 days on mainnet, about 1 hour on testnet (see Timing parameters).

Ethereum to Whitechain

Deposits (L1 to L2)

A deposit takes about 2 minutes. You initiate the deposit on L1 and the op-node automatically finalizes it on L2. No further action is required on L2 once the deposit is confirmed. Example depositERC20 parameters: After ~2 minutes, verify the balance with balanceOf on the L2 token contract.

Withdrawals (L2 to L1)

A withdrawal takes about an hour on testnet. On mainnet it takes minimum 7 days. The wait for a qualifying output proposal adds to that minimum, and so does re-proving against a new game if the initial dispute game is successfully challenged (see Timing parameters for exact figures). The flow has six steps:
  1. Initiate on L2 call L2StandardBridge.bridgeERC20 for ERC20 tokens, L2ERC721Bridge.bridgeERC721 for L1-origin NFTs, or L2CrossDomainMessenger.sendMessage for arbitrary messages. Tokens are burned for L1-origin tokens and escrowed for L2-native tokens. L2-native NFTs cannot be withdrawn (see When NOT to use the canonical bridge). The canonical bridge does not handle native WBT withdrawals; use the Portal bridge for that.
  2. Wait for an output proposal the op-proposer publishes an output root on L1 via the DisputeGameFactory at a fixed interval (every 30 minutes on testnet). Your withdrawal can only be proven against a dispute game whose l2BlockNumber is greater than or equal to the L2 block of your withdrawal transaction. To find a suitable game and its gameIndex, monitor the create transactions on the DisputeGameFactory contract in the explorer.
  3. Prove the withdrawal on L1 call OptimismPortal.proveWithdrawalTransaction with the gameIndex and a Merkle proof from L2 storage. Tools such as viem OP Stack actions or op-withdrawer compute the proof for you (see Programmatic bridging).
  4. Resolve the dispute game the game must resolve as DEFENDER_WINS before you can finalize. If it still has IN_PROGRESS status after its challenge clock expires, anyone can call resolveClaim on the game contract to resolve it. This step is permissionless and is typically handled by an off-chain service. If the game instead resolves as CHALLENGER_WINS, your proof is invalidated but your funds are not lost. Re-prove against a different, honest game; the delay countdown restarts from the new prove transaction.
  5. Wait for the dispute-resolution delays two independent delays must elapse before finalization is allowed. proofMaturityDelaySeconds is the minimum time since your prove transaction. disputeGameFinalityDelaySeconds is the minimum time since the game resolved in favor of the defender. See Timing parameters for current values on each network.
  6. Finalize on L1 call OptimismPortal.finalizeWithdrawalTransaction to release the funds to L1.
The dispute-resolution delay on mainnet (minimum 7 days) is enforced by the protocol and cannot be skipped. Plan treasury operations and time-sensitive flows accordingly. Testnet delays are intentionally shortened and do not reflect mainnet behavior. For urgent exits, see When NOT to use the canonical bridge.

Timing parameters

The full testnet cycle is longer than the two delays combined (15 + 5 minutes) because of discrete service intervals. A withdrawal can only be proven once a dispute game covers its L2 block. If the latest game predates your transaction, you wait for the next one: an observed wait of up to ~45 minutes within a measured 64-minute cycle. In the worst case, when batcher and proposer intervals align unfavorably across stages, the full cycle reaches about 3 hours. Testnet delays are intentionally shortened to allow end-to-end testing. Do not assume testnet timings apply to mainnet. Mainnet values follow the OP Stack default consensus parameters (see specs.optimism.io, section Configurability, Consensus parameters).

Programmatic bridging

Common paths for interacting with the bridge contracts directly: The @eth-optimism/sdk package is deprecated and is no longer maintained. Use viem OP Stack actions instead. Withdrawals still require the prove and finalize steps described above, regardless of which tool you use. No tool triggers them automatically. Proof generation additionally requires an archive-capable L2 RPC endpoint, since eth_getProof needs historical state access beyond the default pruning window. Without this step, funds remain locked in the L1 bridge escrow.

Contract addresses

Contract addresses below are for testnet. Mainnet addresses will be added once mainnet is live.

Testnet

L2 addresses below fall in the 0x4200... predeploy range. They are identical across every OP Stack environment: devnet, testnet, and mainnet. L1 addresses are specific to this testnet deployment and will change if the deployment is ever redone. When verifying addresses, focus on the L1 side; the 0x4200... L2 predeploys are fixed by the protocol and never change. OptimismPortal2 is the current implementation contract behind the OptimismPortal address above; use the name OptimismPortal when referring to it.

When NOT to use the canonical bridge

The canonical bridge is the safest and most trust-minimized path between L1 and L2, but it does not fit every use case.

For token issuers

To make an L1 ERC20 bridgeable to Whitechain, deploy an OptimismMintableERC20 on L2 that mirrors the L1 token. Use the OptimismMintableERC20Factory.createOptimismMintableERC20WithDecimals function with the L1 token address, the name and symbol you want on L2, and the decimals. Before creating a new pairing, confirm the token doesn’t already have an official Whitechain representation (see When NOT to use the canonical bridge). A second wrapped version of an already-represented token fragments liquidity. Example createOptimismMintableERC20WithDecimals parameters: The resulting L2 token grants mint and burn rights exclusively to the L2StandardBridge. Verify the pairing before sending real value: L1StandardBridge.deposits(l1Token, l2Token) must return a non-zero value, or query the factory to confirm the L2 contract was created. Tokens with transfer fees, rebasing logic, blocklists, or pausable transfers are not compatible with the standard bridge. Use a custom bridge solution for those cases.

Disclaimer

  • Always test with a small amount before bridging large balances.
  • Verify every contract address against this page or the official Whitechain Explorer before submitting a transaction.
  • Withdrawals are non-reversible once finalized on L1.