// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; // ============ External Imports ============ import { IMessageRecipient } from "@celo-org/optics-sol/interfaces/IMessageRecipient.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; abstract contract Router is Ownable, IMessageRecipient { // ============ Mutable Storage ============ mapping(uint32 => bytes32) internal remotes; // ============ Modifiers ============ /** * @notice Only accept messages from a remote Router contract * @param _origin The domain the message is coming from * @param _router The address the message is coming from */ modifier onlyRemoteRouter(uint32 _origin, bytes32 _router) { require(_isRemoteRouter(_origin, _router), "!remote router"); _; } // ============ External functions ============ /** * @notice Register the address of a Router contract for the same xApp on a remote chain * @param _domain The domain of the remote xApp Router * @param _router The address of the remote xApp Router */ function enrollRemoteRouter(uint32 _domain, bytes32 _router) external onlyOwner { remotes[_domain] = _router; } // ============ Virtual functions ============ function handle( uint32 _origin, bytes32 _sender, bytes memory _message ) external virtual override returns (bytes memory); // ============ Internal functions ============ /** * @notice Return true if the given domain / router is the address of a remote xApp Router * @param _domain The domain of the potential remote xApp Router * @param _router The address of the potential remote xApp Router */ function _isRemoteRouter(uint32 _domain, bytes32 _router) internal view returns (bool) { return remotes[_domain] == _router; } /** * @notice Assert that the given domain has a xApp Router registered and return its address * @param _domain The domain of the chain for which to get the xApp Router * @return _remote The address of the remote xApp Router on _domain */ function _mustHaveRemote(uint32 _domain) internal view returns (bytes32 _remote) { _remote = remotes[_domain]; require(_remote != bytes32(0), "!remote"); } }