The home for Hyperlane core contracts, sdk packages, and other infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hyperlane-monorepo/solidity/contracts/isms/routing/DomainRoutingIsm.sol

106 lines
3.4 KiB

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;
// ============ External Imports ============
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
// ============ Internal Imports ============
import {AbstractRoutingIsm} from "./AbstractRoutingIsm.sol";
import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol";
import {Message} from "../../libs/Message.sol";
/**
* @title DomainRoutingIsm
*/
contract DomainRoutingIsm is AbstractRoutingIsm, OwnableUpgradeable {
// ============ Public Storage ============
mapping(uint32 => IInterchainSecurityModule) public modules;
// ============ Events ============
/**
* @notice Emitted when a module is set for a domain
* @param domain The origin domain.
* @param module The ISM to use.
*/
event ModuleSet(uint32 indexed domain, IInterchainSecurityModule module);
// ============ External Functions ============
/**
* @param _owner The owner of the contract.
*/
function initialize(address _owner) public initializer {
__Ownable_init();
_transferOwnership(_owner);
}
/**
* @notice Sets the ISMs to be used for the specified origin domains
* @param _owner The owner of the contract.
* @param _domains The origin domains
* @param _modules The ISMs to use to verify messages
*/
function initialize(
address _owner,
uint32[] calldata _domains,
IInterchainSecurityModule[] calldata _modules
) public initializer {
__Ownable_init();
require(_domains.length == _modules.length, "length mismatch");
uint256 _length = _domains.length;
for (uint256 i = 0; i < _length; ++i) {
_set(_domains[i], _modules[i]);
}
_transferOwnership(_owner);
}
/**
* @notice Sets the ISM to be used for the specified origin domain
* @param _domain The origin domain
* @param _module The ISM to use to verify messages
*/
function set(uint32 _domain, IInterchainSecurityModule _module)
external
onlyOwner
{
_set(_domain, _module);
}
// ============ Public Functions ============
/**
* @notice Returns the ISM responsible for verifying _message
* @dev Can change based on the content of _message
* @param _message Formatted Hyperlane message (see Message.sol).
* @return module The ISM to use to verify _message
*/
function route(bytes calldata _message)
public
view
virtual
override
returns (IInterchainSecurityModule)
{
IInterchainSecurityModule module = modules[Message.origin(_message)];
require(
address(module) != address(0),
"No ISM found for origin domain"
);
return module;
}
// ============ Internal Functions ============
/**
* @notice Sets the ISM to be used for the specified origin domain
* @param _domain The origin domain
* @param _module The ISM to use to verify messages
*/
function _set(uint32 _domain, IInterchainSecurityModule _module) internal {
require(Address.isContract(address(_module)), "!contract");
modules[_domain] = _module;
emit ModuleSet(_domain, _module);
}
}