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/hooks/routing/DomainRoutingHook.sol

102 lines
3.0 KiB

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/*@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@ HYPERLANE @@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
// ============ Internal Imports ============
import {AbstractPostDispatchHook} from "../libs/AbstractPostDispatchHook.sol";
import {MailboxClient} from "../../client/MailboxClient.sol";
import {Message} from "../../libs/Message.sol";
import {IPostDispatchHook} from "../../interfaces/hooks/IPostDispatchHook.sol";
// ============ External Imports ============
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
/**
* @title DomainRoutingHook
* @notice Delegates to a hook based on the destination domain of the message.
*/
contract DomainRoutingHook is AbstractPostDispatchHook, MailboxClient {
using Strings for uint32;
using Message for bytes;
struct HookConfig {
uint32 destination;
address hook;
}
mapping(uint32 => IPostDispatchHook) public hooks;
constructor(address _mailbox, address _owner) MailboxClient(_mailbox) {
_transferOwnership(_owner);
}
// ============ External Functions ============
/// @inheritdoc IPostDispatchHook
function hookType() external pure virtual override returns (uint8) {
return uint8(IPostDispatchHook.Types.ROUTING);
}
function setHook(uint32 _destination, address _hook) public onlyOwner {
hooks[_destination] = IPostDispatchHook(_hook);
}
function setHooks(HookConfig[] calldata configs) external onlyOwner {
for (uint256 i = 0; i < configs.length; i++) {
setHook(configs[i].destination, configs[i].hook);
}
}
function supportsMetadata(
bytes calldata
) public pure virtual override returns (bool) {
// routing hook does not care about metadata shape
return true;
}
// ============ Internal Functions ============
/// @inheritdoc AbstractPostDispatchHook
function _postDispatch(
bytes calldata metadata,
bytes calldata message
) internal virtual override {
_getConfiguredHook(message).postDispatch{value: msg.value}(
metadata,
message
);
}
/// @inheritdoc AbstractPostDispatchHook
function _quoteDispatch(
bytes calldata metadata,
bytes calldata message
) internal view virtual override returns (uint256) {
return _getConfiguredHook(message).quoteDispatch(metadata, message);
}
function _getConfiguredHook(
bytes calldata message
) internal view virtual returns (IPostDispatchHook hook) {
hook = hooks[message.destination()];
require(
address(hook) != address(0),
string.concat(
"No hook configured for destination: ",
message.destination().toString()
)
);
}
}