Cross chain interoperability
| This document is better viewed at https://docs.openzeppelin.com/contracts/api/crosschain |
This directory contains contracts for sending and receiving cross chain messages that follows the ERC-7786 standard.
-
CrosschainLinked: helper to facilitate communication between a contract on one chain and counterparts on remote chains through ERC-7786 gateways. -
ERC7786Recipient: generic ERC-7786 crosschain contract that receives messages from a trusted gateway.
Additionally there are multiple bridge constructions:
-
BridgeERC20Core: Core bridging logic for crosschain ERC-20 transfer. Used byBridgeERC20,BridgeERC7802andERC20Crosschain, -
BridgeERC20: Standalone bridge contract to connect an ERC-20 token contract with counterparts on remote chains, -
BridgeERC7802: Standalone bridge contract to connect an ERC-7802 token contract with counterparts on remote chains.
Helpers
CrosschainLinked
import "@openzeppelin/contracts/crosschain/CrosschainLinked.sol";
Core bridging mechanism.
This contract contains the logic to register and send messages to counterparts on remote chains using ERC-7786
gateways. It ensure received messages originate from a counterpart. This is the base of token bridges such as
BridgeERC20Core.
Contracts that inherit from this contract can use the internal _sendMessageToCounterpart to send messages to their
counterpart on a foreign chain. They must override the {_processMessage} function to handle messages that have
been verified.
getLink(bytes chain) → address gateway, bytes counterpart public
Returns the ERC-7786 gateway used for sending and receiving cross-chain messages to a given chain.
Note: The chain parameter is a "chain-only" InteroperableAddress (empty address) and the counterpart returns
the full InteroperableAddress (chain ref + address) that is on chain.
_setLink(address gateway, bytes counterpart, bool allowOverride) internal
Internal setter to change the ERC-7786 gateway and counterpart for a given chain. Called at construction.
Note: The counterpart parameter is the full InteroperableAddress (chain ref + address).
_sendMessageToCounterpart(bytes chain, bytes payload, bytes[] attributes) → bytes32 internal
Internal messaging function
Note: The chain parameter is a "chain-only" InteroperableAddress (empty address).
_isAuthorizedGateway(address instance, bytes sender) → bool internal
Virtual getter that returns whether an address is a valid ERC-7786 gateway for a given sender.
The sender parameter is an interoperable address that include the source chain. The chain part can be
extracted using the InteroperableAddress library to selectively authorize gateways based on the origin chain
of a message.
ERC7786Recipient
import "@openzeppelin/contracts/crosschain/ERC7786Recipient.sol";
Base implementation of an ERC-7786 compliant cross-chain message receiver.
This abstract contract exposes the receiveMessage function that is used for communication with (one or multiple)
destination gateways. This contract leaves two functions unimplemented:
-
_isAuthorizedGateway, an internal getter used to verify whether an address is recognised by the contract as a valid ERC-7786 destination gateway. One or multiple gateway can be supported. Note that any malicious address for which this function returns true would be able to impersonate any account on any other chain sending any message. -
_processMessage, the internal function that will be called with any message that has been validated.
This contract implements replay protection, meaning that if two messages are received from the same gateway with the
same receiveId, then the second one will NOT be executed, regardless of the result of _isAuthorizedGateway.
receiveMessage(bytes32 receiveId, bytes sender, bytes payload) → bytes4 external
Endpoint for receiving cross-chain message.
This function may be called directly by the gateway.
_isAuthorizedGateway(address gateway, bytes sender) → bool internal
Virtual getter that returns whether an address is a valid ERC-7786 gateway for a given sender.
The sender parameter is an interoperable address that include the source chain. The chain part can be
extracted using the InteroperableAddress library to selectively authorize gateways based on the origin chain
of a message.
Bridges
BridgeERC20Core
import "@openzeppelin/contracts/crosschain/bridges/BridgeERC20Core.sol";
Base contract for bridging ERC-20 between chains using an ERC-7786 gateway.
In order to use this contract, two functions must be implemented to link it to the token:
* _onSend: called when a crosschain transfer is going out. Must take the sender tokens or revert.
* _onReceive: called when a crosschain transfer is coming in. Must give tokens to the receiver.
This base contract is used by the BridgeERC20, which interfaces with legacy ERC-20 tokens, and BridgeERC7802,
which interface with ERC-7802 to provide an approve-free user experience. It is also used by the ERC20Crosschain
extension, which embeds the bridge logic directly in the token contract.
crosschainTransfer(bytes to, uint256 amount) → bytes32 public
Transfer amount tokens to a crosschain receiver.
Note: The to parameter is the full InteroperableAddress (chain ref + address).
_crosschainTransfer(address from, bytes to, uint256 amount) → bytes32 internal
Internal crosschain transfer function.
Note: The to parameter is the full InteroperableAddress (chain ref + address).
_processMessage(address, bytes32 receiveId, bytes, bytes payload) internal
Virtual function that should contain the logic to execute when a cross-chain message is received.
_onSend(address from, uint256 amount) internal
Virtual function: implementation is required to handle token being burnt or locked on the source chain.
_onReceive(address to, uint256 amount) internal
Virtual function: implementation is required to handle token being minted or unlocked on the destination chain.
BridgeERC20
import "@openzeppelin/contracts/crosschain/bridges/BridgeERC20.sol";
This is a variant of BridgeERC20Core that implements the bridge logic for ERC-20 tokens that do not expose a
crosschain mint and burn mechanism. Instead, it takes custody of bridged assets.
BridgeERC7802
import "@openzeppelin/contracts/crosschain/bridges/BridgeERC7802.sol";
This is a variant of BridgeERC20Core that implements the bridge logic for ERC-7802 compliant tokens.