L1ERC721Bridge
Table of Contents
Overview
The L1ERC721Bridge enables trustless transfer of ERC721 tokens between Ethereum L1 and Optimism L2 by escrowing tokens on L1 during deposits and releasing them upon withdrawal finalization.
Definitions
Bridge Pair
A specific combination of L1 token address and L2 token address that represents the same logical ERC721 collection across both chains.
Correct Deposit
A successful deposit initiation on L1 via bridgeERC721 or bridgeERC721To that meets all function preconditions and completes, resulting in a message to L2 for the specified Bridge Pair and token ID.
Eligible Withdrawal
A withdrawal initiated by the L2ERC721Bridge that corresponds to an escrowed token and whose message has been delivered to L1 and is eligible for finalization according to the bridge protocol.
Bridge Flow
The deposit and withdrawal processes mediated by the CrossDomainMessenger between the L1 and L2 ERC721 bridges.
Assumptions
a01-001: CrossDomainMessenger delivers messages reliably
The CrossDomainMessenger contract correctly delivers cross-chain messages between L1 and L2 without loss or corruption.
Mitigations
- CrossDomainMessenger is a core protocol contract with extensive testing and auditing
- Message delivery is secured by L1 data availability and fault proof system
a01-002: L2ERC721Bridge validates withdrawals correctly
The L2ERC721Bridge contract on L2 only initiates withdrawal messages for tokens that were legitimately deposited from L1.
Mitigations
- L2ERC721Bridge is a protocol-controlled predeploy contract
- Withdrawal validation logic is part of the core protocol specification
a01-003: ProxyAdmin owner operates within governance constraints
The ProxyAdmin owner (governance) acts honestly when initializing or upgrading the contract.
Mitigations
- ProxyAdmin owner is typically a multisig or governance contract
- Upgrades follow established governance processes with time delays
Invariants
i01-001: L2 delivery for Correct Deposits
Any Correct Deposit MUST eventually result, after the corresponding message is delivered and processed on L2, in the designated recipient owning the same token ID of the corresponding remote token for the same Bridge Pair.
Impact
Severity: High
If violated, users can lose access to their asset (locked on L1 without L2 delivery), creating stuck funds and loss of availability. This liveness property depends on correct message delivery and the L2 bridge's behavior.
i01-002: L1 delivery for Eligible Withdrawals
Any Eligible Withdrawal MUST be able to be finalized on L1 when the bridge is not paused, resulting in the designated recipient receiving the exact token ID of the local token for the same Bridge Pair.
Impact
Severity: High
If violated, users cannot reclaim assets that were withdrawn on L2, leading to stuck assets in escrow. This liveness property depends on correct message delivery and protocol withdrawal eligibility.
i01-003: No bypass of the Bridge Flow
It MUST be impossible for any address to receive an ERC721 token via the bridge on either chain except through the Bridge Flow. Ownership changes across chains MUST only occur via deposits (L1→L2) and withdrawals (L2→L1) processed through the respective bridges and the CrossDomainMessenger.
Impact
Severity: Critical
If violated, an attacker could obtain assets without performing a valid deposit/withdrawal, enabling theft or duplication independent of external assumptions.
Function Specification
initialize
Initializes the L1ERC721Bridge contract with the CrossDomainMessenger and SystemConfig addresses.
Parameters:
_messenger: Address of the CrossDomainMessenger contract on L1_systemConfig: Address of the SystemConfig contract on L1
Behavior:
- MUST revert if caller is not the ProxyAdmin or ProxyAdmin owner
- MUST revert if already initialized at the current initialization version
- MUST set the systemConfig state variable to
_systemConfig - MUST set the messenger state variable to
_messenger - MUST set the otherBridge state variable to the L2ERC721Bridge predeploy address (0x4200000000000000000000000000000000000014)
- MUST emit an Initialized event
bridgeERC721
Initiates a bridge transfer of an ERC721 token to the caller's address on L2.
Parameters:
_localToken: Address of the ERC721 token contract on L1_remoteToken: Address of the corresponding ERC721 token contract on L2_tokenId: Token ID to bridge_minGasLimit: Minimum gas limit for the L2 transaction_extraData: Optional additional data forwarded to L2 (not used for execution, only emitted)
Behavior:
- MUST revert if caller is not an externally owned account (EOA)
- MUST revert if
_remoteTokenis address(0) - MUST revert if the caller has not approved this contract to transfer the token
- MUST set
deposits[_localToken][_remoteToken][_tokenId]to true - MUST transfer the token from caller to this contract using transferFrom
- MUST send a cross-chain message to L2ERC721Bridge calling finalizeBridgeERC721
- MUST emit ERC721BridgeInitiated event with caller as both _from and_to addresses
bridgeERC721To
Initiates a bridge transfer of an ERC721 token to a specified recipient address on L2.
Parameters:
_localToken: Address of the ERC721 token contract on L1_remoteToken: Address of the corresponding ERC721 token contract on L2_to: Address to receive the token on L2_tokenId: Token ID to bridge_minGasLimit: Minimum gas limit for the L2 transaction_extraData: Optional additional data forwarded to L2 (not used for execution, only emitted)
Behavior:
- MUST revert if
_tois address(0) - MUST revert if
_remoteTokenis address(0) - MUST revert if the caller has not approved this contract to transfer the token
- MUST set
deposits[_localToken][_remoteToken][_tokenId]to true - MUST transfer the token from caller to this contract using transferFrom
- MUST send a cross-chain message to L2ERC721Bridge calling finalizeBridgeERC721 with
_toas recipient - MUST emit ERC721BridgeInitiated event with caller as _from and
_toas recipient
finalizeBridgeERC721
Completes an ERC721 bridge withdrawal from L2 by releasing the escrowed token to the recipient on L1.
Parameters:
_localToken: Address of the ERC721 token contract on L1_remoteToken: Address of the ERC721 token contract on L2_from: Address that initiated the withdrawal on L2_to: Address to receive the token on L1_tokenId: Token ID being withdrawn_extraData: Optional additional data (not used for execution, only emitted)
Behavior:
- MUST revert if caller is not the CrossDomainMessenger
- MUST revert if the CrossDomainMessenger's xDomainMessageSender is not the L2ERC721Bridge
- MUST revert if the contract is paused
- MUST revert if
_localTokenis the address of this contract - MUST revert if
deposits[_localToken][_remoteToken][_tokenId]is false - MUST set
deposits[_localToken][_remoteToken][_tokenId]to false - MUST transfer the token from this contract to
_tousing safeTransferFrom - MUST emit ERC721BridgeFinalized event
paused
Returns whether the bridge is currently paused.
Behavior:
- MUST return the paused status from the SystemConfig's SuperchainConfig contract
- MUST NOT revert under any circumstances
superchainConfig
Returns the SuperchainConfig contract address.
Behavior:
- MUST return the SuperchainConfig address from the SystemConfig contract
- MUST NOT revert under any circumstances
proxyAdmin
Returns the ProxyAdmin contract that controls this proxy.
Behavior:
- MUST return the ProxyAdmin contract address that controls this proxy
- MUST revert if no ProxyAdmin is discoverable
proxyAdminOwner
Returns the owner of the ProxyAdmin contract.
Behavior:
- MUST return the owner address of the ProxyAdmin that controls this proxy
- MUST revert if the ProxyAdmin cannot be determined
MESSENGER
Legacy getter for the messenger contract address.
Behavior:
- MUST return the messenger state variable
- MUST NOT revert under any circumstances
OTHER_BRIDGE
Legacy getter for the other bridge contract address.
Behavior:
- MUST return the otherBridge state variable
- MUST NOT revert under any circumstances