OptimismPortal Interop

Table of Contents

Overview

The OptimismPortal contract is integrated with the ETHLockbox for managing unified ETH liquidity. This liquidity consists of every ETH balance migrated from each OptimismPortal when joining the op-governed dependency set.

It is possible to upgrade to this version without being part of the op-governed dependency set. In this case, the corresponding chain would need to deploy and manage its own ETHLockbox.

The OptimismPortal also moves onto shared dispute game contracts when a chain joins the op-governed dependency set. Each chain keeps its own SystemConfig and OptimismPortal. The chains in the set share one ETHLockbox, one DisputeGameFactory and one AnchorStateRegistry. A chain outside the op-governed dependency set keeps its own copy of each of these contracts.

Integrating ETHLockbox

The integration with the ETHLockbox involves locking ETH when executing deposit transactions and unlocking ETH when finalizing withdrawal transactions, without altering other aspects of the current OptimismPortal implementation.

Interface and properties

ETH Management

migrateLiquidity

Migrates the ETH liquidity to the ETHLockbox. This function will only be called once by the ProxyAdmin owner when updating the OptimismPortal contract.

function migrateLiquidity() external;
  • MUST only be callable by the ProxyAdmin owner
  • MUST transfer all ETH balance to the ETHLockbox
  • MUST emit an ETHMigrated event with the amount transferred

proxyAdminOwner

Returns the ProxyAdmin owner that manages the ETHLockbox.

function proxyAdminOwner() external view returns (address);

Dispute Game Management

migrateToSharedDisputeGame

Moves the OptimismPortal onto the shared dispute game contracts of the op-governed dependency set. It points the portal at the shared ETHLockbox and the shared AnchorStateRegistry. The shared AnchorStateRegistry selects the shared DisputeGameFactory that the portal respects.

function migrateToSharedDisputeGame(
    IETHLockbox _newLockbox,
    IAnchorStateRegistry _newAnchorStateRegistry
) external;
  • MUST only be callable by the ProxyAdmin owner
  • MUST revert if the SystemConfig does not have the interop feature enabled
  • MUST revert if the system is paused
  • MUST revert if the new AnchorStateRegistry is the same as the current one
  • MUST revert if either address is zero
  • MUST revert if the new ETHLockbox has not authorized this portal
  • MUST emit a PortalMigrated event with the old and new ETHLockbox and AnchorStateRegistry
  • SHOULD be called atomically with ETHLockbox.migrateLiquidity in the same transaction, or the portal may not be able to unlock enough ETH to finalize withdrawals

migrateToSharedDisputeGame is designed for a one-time migration. Chain operators are expected to call it exactly once when joining the op-governed dependency set. Although the function permits repeated calls, it is not designed for repeated migration. Switching to the shared DisputeGameFactory invalidates withdrawal proofs against games from the previous factory, so users MUST prove those withdrawals again.

Internal ETH functionality

Locking ETH

Called during deposit transactions to handle ETH locking.

if (msg.value > 0) ethLockbox.lockETH{ value: msg.value }();
  • MUST be invoked during depositTransaction when there is ETH value
  • MUST lock any ETH value in the ETHLockbox

Unlocking ETH

Called during withdrawal finalization to handle ETH unlocking.

if (_tx.value > 0) ethLockbox.unlockETH(_tx.value);
  • MUST be invoked during withdrawal finalization when there is ETH value
  • MUST unlock the withdrawal value from the ETHLockbox
  • MUST revert if withdrawal target is the ETHLockbox

Events

ETHMigrated

MUST be triggered when the ETH liquidity is migrated to the ETHLockbox.

event ETHMigrated(uint256 amount);

PortalMigrated

MUST be triggered when the OptimismPortal migrates to a new ETHLockbox and AnchorStateRegistry.

event PortalMigrated(
    IETHLockbox oldLockbox,
    IETHLockbox newLockbox,
    IAnchorStateRegistry oldAnchorStateRegistry,
    IAnchorStateRegistry newAnchorStateRegistry
);

Invariants

  • Deposits MUST lock the ETH in the ETHLockbox

  • Withdrawals MUST unlock the ETH from the ETHLockbox and forward it to the withdrawal target

  • The contract MUST NOT hold any ETH balance from deposits or withdrawals

  • The contract MUST be able to handle zero ETH value operations

  • The contract MUST NOT allow withdrawals to target the ETHLockbox address