Cross Chain Awareness

This document is better viewed at https://docs.openzeppelin.com/contracts/api/crosschain

This directory provides building blocks to improve cross-chain awareness of smart contracts.

  • CrossChainEnabled is an abstraction that contains accessors and modifiers to control the execution flow when receiving cross-chain messages.

CrossChainEnabled specializations

The following specializations of CrossChainEnabled provide implementations of the CrossChainEnabled abstraction for specific bridges. This can be used to complex cross-chain aware components such as AccessControlCrossChain.

CrossChainEnabledAMB

import "@openzeppelin/contracts/crosschain/amb/CrossChainEnabledAMB.sol";

AMB specialization or the CrossChainEnabled abstraction.

As of february 2020, AMB bridges are available between the following chains:

Available since v4.6.

constructor(address bridge) public

_isCrossChain() → bool internal

_crossChainSender() → address internal

CrossChainEnabledArbitrumL1

import "@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol";

Arbitrum specialization or the CrossChainEnabled abstraction the L1 side (mainnet).

This version should only be deployed on L1 to process cross-chain messages originating from L2. For the other side, use CrossChainEnabledArbitrumL2.

The bridge contract is provided and maintained by the arbitrum team. You can find the address of this contract on the rinkeby testnet in Arbitrum’s developer documentation.

Available since v4.6.

constructor(address bridge) internal

_isCrossChain() → bool internal

_crossChainSender() → address internal

CrossChainEnabledArbitrumL2

import "@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol";

Arbitrum specialization or the CrossChainEnabled abstraction the L2 side (arbitrum).

This version should only be deployed on L2 to process cross-chain messages originating from L1. For the other side, use CrossChainEnabledArbitrumL1.

Arbitrum L2 includes the ArbSys contract at a fixed address. Therefore, this specialization of CrossChainEnabled does not include a constructor.

Available since v4.6.

There is currently a bug in Arbitrum that causes this contract to fail to detect cross-chain calls when deployed behind a proxy. This will be fixed when the network is upgraded to Arbitrum Nitro, currently scheduled for August 31st 2022.

_isCrossChain() → bool internal

_crossChainSender() → address internal

CrossChainEnabledOptimism

import "@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol";

Optimism specialization or the CrossChainEnabled abstraction.

The messenger (CrossDomainMessenger) contract is provided and maintained by the optimism team. You can find the address of this contract on mainnet and kovan in the deployments section of Optimism monorepo.

Available since v4.6.

constructor(address messenger) internal

_isCrossChain() → bool internal

_crossChainSender() → address internal

CrossChainEnabledPolygonChild

import "@openzeppelin/contracts/crosschain/polygon/CrossChainEnabledPolygonChild.sol";

Polygon specialization or the CrossChainEnabled abstraction the child side (polygon/mumbai).

This version should only be deployed on child chain to process cross-chain messages originating from the parent chain.

The fxChild contract is provided and maintained by the polygon team. You can find the address of this contract polygon and mumbai in Polygon’s Fx-Portal documentation.

Available since v4.6.

constructor(address fxChild) internal

_isCrossChain() → bool internal

_crossChainSender() → address internal

processMessageFromRoot(uint256, address rootMessageSender, bytes data) external

External entry point to receive and relay messages originating from the fxChild.

Non-reentrancy is crucial to avoid a cross-chain call being able to impersonate anyone by just looping through this with user-defined arguments.

Note: if _fxChild calls any other function that does a delegate-call, then security could be compromised.

Libraries for cross-chain

In addition to the CrossChainEnabled abstraction, cross-chain awareness is also available through libraries. These libraries can be used to build complex designs such as contracts with the ability to interact with multiple bridges.

LibAMB

import "@openzeppelin/contracts/crosschain/amb/LibAMB.sol";

Primitives for cross-chain aware contracts using the AMB family of bridges.

isCrossChain(address bridge) → bool internal

Returns whether the current function call is the result of a cross-chain message relayed by bridge.

crossChainSender(address bridge) → address internal

Returns the address of the sender that triggered the current cross-chain message through bridge.

isCrossChain should be checked before trying to recover the sender, as it will revert with NotCrossChainCall if the current function call is not the result of a cross-chain message.

LibArbitrumL1

import "@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL1.sol";

Primitives for cross-chain aware contracts for Arbitrum.

This version should only be used on L1 to process cross-chain messages originating from L2. For the other side, use LibArbitrumL2.

isCrossChain(address bridge) → bool internal

Returns whether the current function call is the result of a cross-chain message relayed by the bridge.

crossChainSender(address bridge) → address internal

Returns the address of the sender that triggered the current cross-chain message through the bridge.

isCrossChain should be checked before trying to recover the sender, as it will revert with NotCrossChainCall if the current function call is not the result of a cross-chain message.

LibArbitrumL2

import "@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL2.sol";

Primitives for cross-chain aware contracts for Arbitrum.

This version should only be used on L2 to process cross-chain messages originating from L1. For the other side, use LibArbitrumL1.

There is currently a bug in Arbitrum that causes this contract to fail to detect cross-chain calls when deployed behind a proxy. This will be fixed when the network is upgraded to Arbitrum Nitro, currently scheduled for August 31st 2022.

isCrossChain(address arbsys) → bool internal

crossChainSender(address arbsys) → address internal

Returns the address of the sender that triggered the current cross-chain message through arbsys.

isCrossChain should be checked before trying to recover the sender, as it will revert with NotCrossChainCall if the current function call is not the result of a cross-chain message.

LibOptimism

import "@openzeppelin/contracts/crosschain/optimism/LibOptimism.sol";

Primitives for cross-chain aware contracts for Optimism. See the documentation for the functionality used here.

isCrossChain(address messenger) → bool internal

Returns whether the current function call is the result of a cross-chain message relayed by messenger.

crossChainSender(address messenger) → address internal

Returns the address of the sender that triggered the current cross-chain message through messenger.

isCrossChain should be checked before trying to recover the sender, as it will revert with NotCrossChainCall if the current function call is not the result of a cross-chain message.