Minor internal review remediation 1 (#2748)

dan/v3-e2e
Kunal Arora 1 year ago committed by GitHub
parent f783c4e96f
commit 03c92e1e34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      solidity/contracts/GasRouter.sol
  2. 4
      solidity/contracts/Router.sol
  3. 4
      solidity/contracts/hooks/AbstractMessageIdAuthHook.sol
  4. 6
      solidity/contracts/hooks/AbstractPostDispatchHook.sol
  5. 4
      solidity/contracts/hooks/ConfigFallbackDomainRoutingHook.sol
  6. 61
      solidity/contracts/hooks/DefaultHook.sol
  7. 4
      solidity/contracts/hooks/DomainRoutingHook.sol
  8. 4
      solidity/contracts/hooks/MerkleTreeHook.sol
  9. 13
      solidity/contracts/hooks/OPStackHook.sol
  10. 4
      solidity/contracts/hooks/PausableHook.sol
  11. 7
      solidity/contracts/hooks/StaticProtocolFee.sol
  12. 4
      solidity/contracts/hooks/aggregation/StaticAggregationHook.sol
  13. 6
      solidity/contracts/igps/InterchainGasPaymaster.sol
  14. 24
      solidity/contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol
  15. 6
      solidity/contracts/isms/hook/ERC5164ISM.sol
  16. 2
      solidity/contracts/isms/hook/OPStackIsm.sol
  17. 2
      solidity/contracts/libs/hooks/StandardHookMetadata.sol
  18. 4
      solidity/contracts/test/TestPostDispatchHook.sol
  19. 8
      solidity/test/Mailbox.t.sol
  20. 12
      solidity/test/hooks/AggregationHook.t.sol
  21. 52
      solidity/test/hooks/FallbackDomainRoutingHook.t.sol
  22. 4
      solidity/test/hooks/StaticProtocolFee.t.sol
  23. 37
      solidity/test/igps/InterchainGasPaymaster.t.sol
  24. 24
      solidity/test/isms/ERC5164ISM.t.sol
  25. 8
      solidity/test/isms/OPStackIsm.t.sol

@ -2,7 +2,7 @@
pragma solidity >=0.6.11;
import {Router} from "./Router.sol";
import {GlobalHookMetadata} from "./libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "./libs/hooks/StandardHookMetadata.sol";
abstract contract GasRouter is Router {
// ============ Mutable Storage ============
@ -50,7 +50,7 @@ abstract contract GasRouter is Router {
_destinationDomain,
_mustHaveRemoteRouter(_destinationDomain),
"",
GlobalHookMetadata.formatMetadata(
StandardHookMetadata.formatMetadata(
0,
destinationGas[_destinationDomain],
address(this),

@ -7,7 +7,7 @@ import {IInterchainGasPaymaster} from "./interfaces/IInterchainGasPaymaster.sol"
import {IMessageRecipient} from "./interfaces/IMessageRecipient.sol";
import {IMailbox} from "./interfaces/IMailbox.sol";
import {EnumerableMapExtended} from "./libs/EnumerableMapExtended.sol";
import {GlobalHookMetadata} from "./libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "./libs/hooks/StandardHookMetadata.sol";
abstract contract Router is HyperlaneConnectionClient, IMessageRecipient {
using EnumerableMapExtended for EnumerableMapExtended.UintToBytes32Map;
@ -204,7 +204,7 @@ abstract contract Router is HyperlaneConnectionClient, IMessageRecipient {
) internal returns (bytes32 _messageId) {
// Ensure that destination chain has an enrolled router.
bytes32 _router = _mustHaveRemoteRouter(_destinationDomain);
bytes memory metadata = GlobalHookMetadata.formatMetadata(
bytes memory metadata = StandardHookMetadata.formatMetadata(
0,
_gasAmount,
_gasPaymentRefundAddress,

@ -18,7 +18,7 @@ import {AbstractMessageIdAuthorizedIsm} from "../isms/hook/AbstractMessageIdAuth
import {AbstractPostDispatchHook} from "./AbstractPostDispatchHook.sol";
import {TypeCasts} from "../libs/TypeCasts.sol";
import {Message} from "../libs/Message.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {MailboxClient} from "../client/MailboxClient.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
@ -32,7 +32,7 @@ abstract contract AbstractMessageIdAuthHook is
AbstractPostDispatchHook,
MailboxClient
{
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
using Message for bytes;
// ============ Constants ============

@ -14,7 +14,7 @@ pragma solidity >=0.8.0;
@@@@@@@@@ @@@@@@@@*/
// ============ Internal Imports ============
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {MailboxClient} from "../client/MailboxClient.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
@ -23,7 +23,7 @@ import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
* @notice Abstract post dispatch hook supporting the current global hook metadata variant.
*/
abstract contract AbstractPostDispatchHook is IPostDispatchHook {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// ============ External functions ============
@ -36,7 +36,7 @@ abstract contract AbstractPostDispatchHook is IPostDispatchHook {
{
return
metadata.length == 0 ||
metadata.variant() == GlobalHookMetadata.VARIANT;
metadata.variant() == StandardHookMetadata.VARIANT;
}
/// @inheritdoc IPostDispatchHook

@ -14,7 +14,7 @@ pragma solidity >=0.8.0;
@@@@@@@@@ @@@@@@@@*/
import {Message} from "../libs/Message.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {AbstractPostDispatchHook} from "./AbstractPostDispatchHook.sol";
import {MailboxClient} from "../client/MailboxClient.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
@ -25,7 +25,7 @@ contract ConfigFallbackDomainRoutingHook is
MailboxClient
{
using Message for bytes;
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// ============ Public Storage ============

@ -1,61 +0,0 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;
/*@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@ HYPERLANE @@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
import {Message} from "../libs/Message.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
import {DomainRoutingHook} from "./DomainRoutingHook.sol";
contract ConfigurableDomainRoutingHook is DomainRoutingHook {
using Message for bytes;
/// @notice mapping of destination domain and recipient to custom hook
mapping(bytes32 => address) public customHooks;
constructor(address mailbox, address owner)
DomainRoutingHook(mailbox, owner)
{}
function _postDispatch(bytes calldata metadata, bytes calldata message)
internal
override
{
bytes32 hookKey = keccak256(
abi.encodePacked(message.destination(), message.recipient())
);
address customHookPreset = customHooks[hookKey];
if (customHookPreset != address(0)) {
IPostDispatchHook(customHookPreset).postDispatch{value: msg.value}(
metadata,
message
);
} else {
super._postDispatch(metadata, message);
}
}
// TODO: need to restrict sender
function configCustomHook(
uint32 destinationDomain,
bytes32 recipient,
address hook
) external {
bytes32 hookKey = keccak256(
abi.encodePacked(destinationDomain, recipient)
);
require(customHooks[hookKey] == address(0), "hook already set");
customHooks[hookKey] = hook;
}
}

@ -15,7 +15,7 @@ pragma solidity >=0.8.0;
// ============ Internal Imports ============
import {Message} from "../libs/Message.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {MailboxClient} from "../client/MailboxClient.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
import {AbstractPostDispatchHook} from "./AbstractPostDispatchHook.sol";
@ -24,7 +24,7 @@ import {AbstractPostDispatchHook} from "./AbstractPostDispatchHook.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
contract DomainRoutingHook is AbstractPostDispatchHook, MailboxClient, Ownable {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
using Message for bytes;
struct HookConfig {

@ -18,12 +18,12 @@ import {Message} from "../libs/Message.sol";
import {MailboxClient} from "../client/MailboxClient.sol";
import {Indexed} from "../Indexed.sol";
import {AbstractPostDispatchHook} from "./AbstractPostDispatchHook.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
contract MerkleTreeHook is AbstractPostDispatchHook, MailboxClient, Indexed {
using Message for bytes;
using MerkleLib for MerkleLib.Tree;
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// An incremental merkle tree used to store outbound message IDs.
MerkleLib.Tree internal _tree;

@ -17,7 +17,7 @@ pragma solidity >=0.8.0;
import {AbstractMessageIdAuthHook} from "./AbstractMessageIdAuthHook.sol";
import {TypeCasts} from "../libs/TypeCasts.sol";
import {Message} from "../libs/Message.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
// ============ External Imports ============
@ -26,11 +26,12 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
/**
* @title OPStackHook
* @notice Message hook to inform the OPStackISM of messages published through
* @notice Message hook to inform the OPStackIsm of messages published through
* the native OPStack bridge.
* @notice This works only for L1 -> L2 messages.
*/
contract OPStackHook is AbstractMessageIdAuthHook {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// ============ Constants ============
@ -48,13 +49,13 @@ contract OPStackHook is AbstractMessageIdAuthHook {
address _mailbox,
uint32 _destinationDomain,
address _ism,
address _messenger
address _l1Messenger
) AbstractMessageIdAuthHook(_mailbox, _destinationDomain, _ism) {
require(
Address.isContract(_messenger),
Address.isContract(_l1Messenger),
"OPStackHook: invalid messenger"
);
l1Messenger = ICrossDomainMessenger(_messenger);
l1Messenger = ICrossDomainMessenger(_l1Messenger);
}
// ============ External functions ============

@ -13,14 +13,14 @@ pragma solidity >=0.8.0;
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {AbstractPostDispatchHook} from "./AbstractPostDispatchHook.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
contract PausableHook is AbstractPostDispatchHook, Ownable, Pausable {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// ============ External functions ============

@ -15,7 +15,7 @@ pragma solidity >=0.8.0;
// ============ Internal Imports ============
import {Message} from "../libs/Message.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {AbstractPostDispatchHook} from "./AbstractPostDispatchHook.sol";
// ============ External Imports ============
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
@ -27,7 +27,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
* @dev V3 WIP
*/
contract StaticProtocolFee is AbstractPostDispatchHook, Ownable {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
using Address for address payable;
using Message for bytes;
@ -95,10 +95,11 @@ contract StaticProtocolFee is AbstractPostDispatchHook, Ownable {
);
uint256 refund = msg.value - protocolFee;
if (refund > 0)
if (refund > 0) {
payable(metadata.refundAddress(message.senderAddress())).sendValue(
refund
);
}
}
/// @inheritdoc AbstractPostDispatchHook

@ -13,13 +13,13 @@ pragma solidity >=0.8.0;
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
import {GlobalHookMetadata} from "../../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../../libs/hooks/StandardHookMetadata.sol";
import {IPostDispatchHook} from "../../interfaces/hooks/IPostDispatchHook.sol";
import {AbstractPostDispatchHook} from "../AbstractPostDispatchHook.sol";
import {MetaProxy} from "../../libs/MetaProxy.sol";
contract StaticAggregationHook is AbstractPostDispatchHook {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// ============ External functions ============

@ -15,8 +15,8 @@ pragma solidity >=0.8.0;
// ============ Internal Imports ============
import {Message} from "../libs/Message.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
import {IGasOracle} from "../interfaces/IGasOracle.sol";
import {IInterchainGasPaymaster} from "../interfaces/IInterchainGasPaymaster.sol";
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol";
@ -42,7 +42,7 @@ contract InterchainGasPaymaster is
{
using Address for address payable;
using Message for bytes;
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// ============ Constants ============
/// @notice The scale of gas oracle token exchange rates.

@ -27,11 +27,8 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
/**
* @title ArbtractNativeISM
* @notice Uses the native bridges to verify interchain messages.
* @dev In the future, the hook might be moved inside the Mailbox which doesn't require storage mappings for senders.
* for more details see https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/2381
* @dev V3 WIP
* @title AbstractMessageIdAuthorizedIsm
* @notice Uses external verfication options to verify interchain messages which need a authorized caller
*/
abstract contract AbstractMessageIdAuthorizedIsm is
IInterchainSecurityModule,
@ -46,10 +43,11 @@ abstract contract AbstractMessageIdAuthorizedIsm is
/// first bit is boolean for verification
/// rest of bits is the amount to send to the recipient
/// @dev bc of the bit packing, we can only send up to 2^255 wei
/// @dev the first bit is reserved for verification and the rest 255 bits are for the msg.value
mapping(bytes32 => uint256) public verifiedMessages;
/// @notice Index of verification bit in verifiedMessages
uint256 public constant MASK_INDEX = 255;
/// @notice Address for Hook on L1 responsible for sending message via the Optimism bridge
/// @notice Address for the authorized hook
address public authorizedHook;
// ============ Events ============
@ -63,7 +61,7 @@ abstract contract AbstractMessageIdAuthorizedIsm is
function setAuthorizedHook(address _hook) external initializer {
require(
_hook != address(0),
"AbstractNativeISM: invalid authorized hook"
"AbstractMessageIdAuthorizedIsm: invalid authorized hook"
);
authorizedHook = _hook;
}
@ -75,22 +73,26 @@ abstract contract AbstractMessageIdAuthorizedIsm is
* @param message Message to verify.
*/
function verify(
bytes calldata, /*_metadata*/
bytes calldata,
/*_metadata*/
bytes calldata message
) external returns (bool) {
bytes32 messageId = message.id();
// check for the first bit (used for verification)
bool verified = verifiedMessages[messageId].isBitSet(MASK_INDEX);
if (verified)
// rest 255 bits contains the msg.value passed from the hook
if (verified) {
payable(message.recipientAddress()).sendValue(
verifiedMessages[messageId].clearBit(MASK_INDEX)
);
}
return verified;
}
/**
* @notice Receive a message from the L2 messenger.
* @dev Only callable by the L2 messenger.
* @notice Receive a message from the AbstractMessageIdAuthHook
* @dev Only callable by the authorized hook.
* @param messageId Hyperlane Id of the message.
*/
function verifyMessageId(bytes32 messageId) external payable virtual {

@ -25,10 +25,10 @@ import {AbstractMessageIdAuthorizedIsm} from "./AbstractMessageIdAuthorizedIsm.s
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
/**
* @title ERC5164ISM
* @title Erc5164Ism
* @notice Uses the generic eip-5164 standard to verify interchain messages.
*/
contract ERC5164ISM is AbstractMessageIdAuthorizedIsm {
contract Erc5164Ism is AbstractMessageIdAuthorizedIsm {
// ============ Constants ============
uint8 public constant moduleType =
@ -39,7 +39,7 @@ contract ERC5164ISM is AbstractMessageIdAuthorizedIsm {
// ============ Constructor ============
constructor(address _executor) {
require(Address.isContract(_executor), "ERC5164ISM: invalid executor");
require(Address.isContract(_executor), "Erc5164Ism: invalid executor");
executor = _executor;
}

@ -26,7 +26,7 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
/**
* @title OPStackIsm
* @notice Uses the native Optimism bridge to verify interchain messages.
* @notice Uses the native OPStack bridge to verify interchain messages.
* @dev V3 WIP
*/
contract OPStackIsm is

@ -22,7 +22,7 @@ pragma solidity >=0.8.0;
* [66:85] Refund address for message (IGP)
* [86:] Custom metadata
*/
library GlobalHookMetadata {
library StandardHookMetadata {
uint8 private constant VARIANT_OFFSET = 0;
uint8 private constant MSG_VALUE_OFFSET = 2;
uint8 private constant GAS_LIMIT_OFFSET = 34;

@ -2,10 +2,10 @@
pragma solidity >=0.8.0;
import {AbstractPostDispatchHook} from "../hooks/AbstractPostDispatchHook.sol";
import {GlobalHookMetadata} from "../libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../libs/hooks/StandardHookMetadata.sol";
contract TestPostDispatchHook is AbstractPostDispatchHook {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
// ============ Public Storage ============

@ -10,11 +10,11 @@ import "../contracts/test/TestIsm.sol";
import "../contracts/test/TestRecipient.sol";
import "../contracts/hooks/MerkleTreeHook.sol";
import {GlobalHookMetadata} from "../contracts/libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../contracts/libs/hooks/StandardHookMetadata.sol";
import {TypeCasts} from "../contracts/libs/TypeCasts.sol";
contract MailboxTest is Test, Versioned {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
using TypeCasts for address;
using Message for bytes;
@ -177,7 +177,7 @@ contract MailboxTest is Test, Versioned {
bytes calldata metadata
) public {
bytes memory prefixedMetadata = abi.encodePacked(
GlobalHookMetadata.VARIANT,
StandardHookMetadata.VARIANT,
metadata
);
vm.assume(
@ -262,7 +262,7 @@ contract MailboxTest is Test, Versioned {
bytes calldata metadata
) public {
bytes memory prefixedMetadata = abi.encodePacked(
GlobalHookMetadata.VARIANT,
StandardHookMetadata.VARIANT,
metadata
);
bytes calldata defaultMetadata = metadata[0:0];

@ -11,6 +11,8 @@ contract AggregationHookTest is Test {
StaticAggregationHookFactory internal factory;
StaticAggregationHook internal hook;
uint256 internal constant PER_HOOK_GAS_AMOUNT = 25000;
function setUp() public {
factory = new StaticAggregationHookFactory();
}
@ -27,13 +29,13 @@ contract AggregationHookTest is Test {
function testPostDispatch(uint8 _hooks) public {
address[] memory hooksDeployed = deployHooks(_hooks);
uint256 _msgValue = hooksDeployed.length * 25000;
uint256 _msgValue = hooksDeployed.length * PER_HOOK_GAS_AMOUNT;
bytes memory message = abi.encodePacked("hello world");
for (uint256 i = 0; i < hooksDeployed.length; i++) {
vm.expectCall(
hooksDeployed[i],
25000,
PER_HOOK_GAS_AMOUNT,
abi.encodeCall(
TestPostDispatchHook(hooksDeployed[i]).postDispatch,
("", "hello world")
@ -46,13 +48,13 @@ contract AggregationHookTest is Test {
function testPostDispatch_reverts_outOfFund(uint8 _hooks, uint8 k) public {
address[] memory hooksDeployed = deployHooks(_hooks);
vm.assume(k < hooksDeployed.length);
uint256 _msgValue = uint256(k) * 25000;
uint256 _msgValue = uint256(k) * PER_HOOK_GAS_AMOUNT;
bytes memory message = abi.encodePacked("hello world");
for (uint256 i = 0; i < k; i++) {
vm.expectCall(
hooksDeployed[i],
25000,
PER_HOOK_GAS_AMOUNT,
abi.encodeCall(
TestPostDispatchHook(hooksDeployed[i]).postDispatch,
("", "hello world")
@ -65,7 +67,7 @@ contract AggregationHookTest is Test {
function testQuoteDispatch(uint8 _hooks) public {
address[] memory hooksDeployed = deployHooks(_hooks);
uint256 _msgValue = hooksDeployed.length * 25000;
uint256 _msgValue = hooksDeployed.length * PER_HOOK_GAS_AMOUNT;
bytes memory message = abi.encodePacked("hello world");
uint256 totalQuote = hook.quoteDispatch("", message);

@ -12,6 +12,7 @@ import {TestRecipient} from "../../contracts/test/TestRecipient.sol";
contract FallbackDomainRoutingHookTest is Test {
using TypeCasts for address;
ConfigFallbackDomainRoutingHook internal fallbackHook;
TestPostDispatchHook internal configuredTestPostDispatchHook;
TestPostDispatchHook internal mailboxDefaultHook;
@ -30,15 +31,27 @@ contract FallbackDomainRoutingHookTest is Test {
mailboxDefaultHook = new TestPostDispatchHook();
testRecipient = new TestRecipient();
fallbackHook = new ConfigFallbackDomainRoutingHook(address(mailbox));
testMessage = _encodeTestMessage();
mailbox.setDefaultHook(address(mailboxDefaultHook));
}
function _setUpTestMessage(uint32 originDomain, uint32 destinationDomain)
public
{
// vm.assume(originDomain != 0 && destinationDomain != 0);
testMessage = _encodeTestMessage(originDomain, destinationDomain);
}
/* ============ hook.quoteDispatch ============ */
function test_quoteDispatchHook_configured() public {
function test_quoteDispatchHook_configured(
uint32 originDomain,
uint32 destinationDomain
) public {
testMessage = _encodeTestMessage(originDomain, destinationDomain);
fallbackHook.setHook(
TEST_DESTINATION_DOMAIN,
destinationDomain,
address(testRecipient).addressToBytes32(),
configuredTestPostDispatchHook
);
@ -53,7 +66,12 @@ contract FallbackDomainRoutingHookTest is Test {
assertEq(fallbackHook.quoteDispatch("", testMessage), 25000);
}
function test_quoteDispatch_default() public payable {
function test_quoteDispatch_default(
uint32 originDomain,
uint32 destinationDomain
) public payable {
testMessage = _encodeTestMessage(originDomain, destinationDomain);
vm.expectCall(
address(mailboxDefaultHook),
abi.encodeCall(mailboxDefaultHook.quoteDispatch, ("", testMessage))
@ -63,9 +81,14 @@ contract FallbackDomainRoutingHookTest is Test {
/* ============ hook.postDispatch ============ */
function test_postDispatchHook_configured() public payable {
function test_postDispatchHook_configured(
uint32 originDomain,
uint32 destinationDomain
) public payable {
testMessage = _encodeTestMessage(originDomain, destinationDomain);
fallbackHook.setHook(
TEST_DESTINATION_DOMAIN,
destinationDomain,
address(testRecipient).addressToBytes32(),
configuredTestPostDispatchHook
);
@ -80,7 +103,12 @@ contract FallbackDomainRoutingHookTest is Test {
fallbackHook.postDispatch{value: msg.value}("", testMessage);
}
function test_postDispatch_default() public payable {
function test_postDispatch_default(
uint32 originDomain,
uint32 destinationDomain
) public payable {
testMessage = _encodeTestMessage(originDomain, destinationDomain);
vm.expectCall(
address(mailboxDefaultHook),
abi.encodeCall(mailboxDefaultHook.postDispatch, ("", testMessage))
@ -89,14 +117,18 @@ contract FallbackDomainRoutingHookTest is Test {
fallbackHook.postDispatch{value: msg.value}("", testMessage);
}
function _encodeTestMessage() internal view returns (bytes memory) {
function _encodeTestMessage(uint32 originDomain, uint32 destinationDomain)
internal
view
returns (bytes memory)
{
return
MessageUtils.formatMessage(
uint8(0), // version
uint32(1), // nonce
TEST_ORIGIN_DOMAIN,
originDomain,
address(this).addressToBytes32(),
TEST_DESTINATION_DOMAIN,
destinationDomain,
address(testRecipient).addressToBytes32(),
abi.encodePacked("Hello from the other chain!")
);

@ -4,7 +4,7 @@ pragma solidity ^0.8.13;
import {Test} from "forge-std/Test.sol";
import {TypeCasts} from "../../contracts/libs/TypeCasts.sol";
import {MessageUtils} from "../isms/IsmTestUtils.sol";
import {GlobalHookMetadata} from "../../contracts/libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../../contracts/libs/hooks/StandardHookMetadata.sol";
import {StaticProtocolFee} from "../../contracts/hooks/StaticProtocolFee.sol";
@ -114,7 +114,7 @@ contract StaticProtocolFeeTest is Test {
uint256 feeRequired,
uint256 feeSent
) public {
bytes memory metadata = GlobalHookMetadata.formatMetadata(
bytes memory metadata = StandardHookMetadata.formatMetadata(
0,
0,
bob,

@ -3,7 +3,7 @@ pragma solidity ^0.8.13;
import {Test} from "forge-std/Test.sol";
import {GlobalHookMetadata} from "../../contracts/libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../../contracts/libs/hooks/StandardHookMetadata.sol";
import {Message} from "../../contracts/libs/Message.sol";
import {MessageUtils} from "../isms/IsmTestUtils.sol";
import {TypeCasts} from "../../contracts/libs/TypeCasts.sol";
@ -12,7 +12,7 @@ import {StorageGasOracle} from "../../contracts/igps/gas-oracles/StorageGasOracl
import {IGasOracle} from "../../contracts/interfaces/IGasOracle.sol";
contract InterchainGasPaymasterTest is Test {
using GlobalHookMetadata for bytes;
using StandardHookMetadata for bytes;
using TypeCasts for address;
using MessageUtils for bytes;
@ -24,6 +24,8 @@ contract InterchainGasPaymasterTest is Test {
uint32 constant testOriginDomain = 22222;
uint32 constant testDestinationDomain = 11111;
uint256 constant testGasAmount = 300000;
uint128 constant TEST_EXCHANGE_RATE = 1e10; // 1.0 exchange rate (remote token has exact same value as local)
uint128 constant TEST_GAS_PRICE = 150; // 150 wei gas price
bytes constant testMessage = "hello world";
bytes32 constant testMessageId =
0x6ae9a99190641b9ed0c07143340612dde0e9cb7deaa5fe07597858ae9ba5fd7f;
@ -75,22 +77,22 @@ contract InterchainGasPaymasterTest is Test {
function testQuoteDispatch_defaultGasLimit() public {
setRemoteGasData(
testDestinationDomain,
1 * 1e10, // 1.0 exchange rate (remote token has exact same value as local)
150 // 1 wei gas price
1 * TEST_EXCHANGE_RATE,
TEST_GAS_PRICE
);
// 150 * 69_420 = 10_413_000
// 150 (gas_price) * 69_420 (default_gas_limit) = 10_413_000
assertEq(igp.quoteDispatch("", testEncodedMessage), 10_413_000);
}
function testQuoteDispatch_customWithMetadata() public {
setRemoteGasData(
testDestinationDomain,
1 * 1e10, // 1.0 exchange rate (remote token has exact same value as local)
150 // 1 wei gas price
1 * TEST_EXCHANGE_RATE,
TEST_GAS_PRICE
);
bytes memory metadata = GlobalHookMetadata.formatMetadata(
bytes memory metadata = StandardHookMetadata.formatMetadata(
0,
uint256(testGasAmount), // gas limit
testRefundAddress, // refund address,
@ -105,7 +107,7 @@ contract InterchainGasPaymasterTest is Test {
function testPostDispatch_defaultGasLimit() public {
setRemoteGasData(
testDestinationDomain,
1 * 1e10, // 1.0 exchange rate (remote token has exact same value as local)
1 * TEST_EXCHANGE_RATE,
1 // 1 wei gas price
);
@ -129,7 +131,7 @@ contract InterchainGasPaymasterTest is Test {
function testPostDispatch_customWithMetadata() public {
setRemoteGasData(
testDestinationDomain,
1 * 1e10, // 1.0 exchange rate (remote token has exact same value as local)
1 * TEST_EXCHANGE_RATE,
1 // 1 wei gas price
);
@ -141,7 +143,7 @@ contract InterchainGasPaymasterTest is Test {
);
uint256 _overpayment = 25000;
bytes memory metadata = GlobalHookMetadata.formatMetadata(
bytes memory metadata = StandardHookMetadata.formatMetadata(
0,
uint256(testGasAmount), // gas limit
testRefundAddress, // refund address
@ -166,7 +168,7 @@ contract InterchainGasPaymasterTest is Test {
function testPayForGas() public {
setRemoteGasData(
testDestinationDomain,
1 * 1e10, // 1.0 exchange rate (remote token has exact same value as local)
1 * TEST_EXCHANGE_RATE,
1 // 1 wei gas price
);
@ -207,7 +209,7 @@ contract InterchainGasPaymasterTest is Test {
function testPayForGasRevertsIfPaymentInsufficient() public {
setRemoteGasData(
testDestinationDomain,
1 * 1e10, // 1.0 exchange rate (remote token has exact same value as local)
1 * TEST_EXCHANGE_RATE,
1 // 1 wei gas price
);
@ -228,7 +230,7 @@ contract InterchainGasPaymasterTest is Test {
setRemoteGasData(
testDestinationDomain,
2 * 1e9, // 0.2 exchange rate (remote token less valuable)
150 * 1e9 // 150 gwei gas price
TEST_GAS_PRICE * 1e9 // 150 gwei gas price
);
// 300,000 destination gas
@ -247,7 +249,7 @@ contract InterchainGasPaymasterTest is Test {
// Testing when the remote token is much more valuable & there's a super high gas price
setRemoteGasData(
testDestinationDomain,
5000 * 1e10, // 5000 exchange rate (remote token much more valuable)
5000 * TEST_EXCHANGE_RATE,
1500 * 1e9 // 1500 gwei gas price
);
@ -338,7 +340,7 @@ contract InterchainGasPaymasterTest is Test {
function testClaim() public {
setRemoteGasData(
testDestinationDomain,
1 * 1e10, // 1.0 exchange rate (remote token has exact same value as local)
1 * TEST_EXCHANGE_RATE,
1 // 1 wei gas price
);
// Pay some funds into the IGP
@ -364,8 +366,7 @@ contract InterchainGasPaymasterTest is Test {
// ============ getExchangeRateAndGasPrice ============
function testGetExchangeRateAndGasPrice() public {
// 1.0 exchange rate (remote token has exact same value as local)
uint128 _tokenExchangeRate = 1 * 1e10;
uint128 _tokenExchangeRate = 1 * TEST_EXCHANGE_RATE;
// 1 wei gas price
uint128 _gasPrice = 1;
setRemoteGasData(testDestinationDomain, _tokenExchangeRate, _gasPrice);

@ -11,12 +11,12 @@ import {TypeCasts} from "../../contracts/libs/TypeCasts.sol";
import {IMessageDispatcher} from "../../contracts/interfaces/hooks/IMessageDispatcher.sol";
import {ERC5164Hook} from "../../contracts/hooks/ERC5164Hook.sol";
import {AbstractMessageIdAuthorizedIsm} from "../../contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol";
import {ERC5164ISM} from "../../contracts/isms/hook/ERC5164ISM.sol";
import {Erc5164Ism} from "../../contracts/isms/hook/Erc5164Ism.sol";
import {TestMailbox} from "../../contracts/test/TestMailbox.sol";
import {TestRecipient} from "../../contracts/test/TestRecipient.sol";
import {MockMessageDispatcher, MockMessageExecutor} from "../../contracts/mock/MockERC5164.sol";
contract ERC5164ISMTest is Test {
contract Erc5164IsmTest is Test {
using LibBit for uint256;
using TypeCasts for address;
using Message for bytes;
@ -26,8 +26,8 @@ contract ERC5164ISMTest is Test {
MockMessageExecutor internal executor;
ERC5164Hook internal hook;
ERC5164ISM internal ism;
TestMailbox internal srcMailbox;
Erc5164Ism internal ism;
TestMailbox internal originMailbox;
TestRecipient internal testRecipient;
uint32 internal constant TEST1_DOMAIN = 1;
@ -61,10 +61,10 @@ contract ERC5164ISMTest is Test {
}
function deployContracts() public {
srcMailbox = new TestMailbox(TEST1_DOMAIN);
ism = new ERC5164ISM(address(executor));
originMailbox = new TestMailbox(TEST1_DOMAIN);
ism = new Erc5164Ism(address(executor));
hook = new ERC5164Hook(
address(srcMailbox),
address(originMailbox),
TEST2_DOMAIN,
address(ism),
address(dispatcher)
@ -77,8 +77,8 @@ contract ERC5164ISMTest is Test {
///////////////////////////////////////////////////////////////////
function test_constructor() public {
vm.expectRevert("ERC5164ISM: invalid executor");
ism = new ERC5164ISM(alice);
vm.expectRevert("Erc5164Ism: invalid executor");
ism = new Erc5164Ism(alice);
vm.expectRevert("MailboxClient: invalid mailbox");
hook = new ERC5164Hook(
@ -122,7 +122,7 @@ contract ERC5164ISMTest is Test {
AbstractMessageIdAuthorizedIsm.verifyMessageId,
(messageId)
);
srcMailbox.updateLatestDispatchedId(messageId);
originMailbox.updateLatestDispatchedId(messageId);
// note: not checking for messageId since this is implementation dependent on each vendor
vm.expectEmit(false, true, true, true, address(dispatcher));
@ -149,7 +149,7 @@ contract ERC5164ISMTest is Test {
TypeCasts.addressToBytes32(address(testRecipient)),
testMessage
);
srcMailbox.updateLatestDispatchedId(Message.id(encodedMessage));
originMailbox.updateLatestDispatchedId(Message.id(encodedMessage));
vm.expectRevert(
"AbstractMessageIdAuthHook: invalid destination domain"
@ -160,7 +160,7 @@ contract ERC5164ISMTest is Test {
function test_postDispatch_RevertWhen_msgValueNotAllowed() public payable {
deployContracts();
srcMailbox.updateLatestDispatchedId(messageId);
originMailbox.updateLatestDispatchedId(messageId);
vm.expectRevert("ERC5164Hook: no value allowed");
hook.postDispatch{value: 1}(bytes(""), encodedMessage);

@ -5,8 +5,8 @@ import {Test} from "forge-std/Test.sol";
import {LibBit} from "../../contracts/libs/LibBit.sol";
import {TypeCasts} from "../../contracts/libs/TypeCasts.sol";
import {GlobalHookMetadata} from "../../contracts/libs/hooks/GlobalHookMetadata.sol";
import {GlobalHookMetadata} from "../../contracts/libs/hooks/GlobalHookMetadata.sol";
import {StandardHookMetadata} from "../../contracts/libs/hooks/StandardHookMetadata.sol";
import {StandardHookMetadata} from "../../contracts/libs/hooks/StandardHookMetadata.sol";
import {AbstractMessageIdAuthorizedIsm} from "../../contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol";
import {TestMailbox} from "../../contracts/test/TestMailbox.sol";
import {Message} from "../../contracts/libs/Message.sol";
@ -51,7 +51,7 @@ contract OPStackIsmTest is Test {
bytes internal testMessage =
abi.encodePacked("Hello from the other chain!");
bytes internal testMetadata =
GlobalHookMetadata.formatMetadata(0, 0, address(this), "");
StandardHookMetadata.formatMetadata(0, 0, address(this), "");
bytes internal encodedMessage;
bytes32 internal messageId;
@ -195,7 +195,7 @@ contract OPStackIsmTest is Test {
vm.selectFork(mainnetFork);
vm.deal(address(this), uint256(2**255 + 1));
bytes memory excessValueMetadata = GlobalHookMetadata.formatMetadata(
bytes memory excessValueMetadata = StandardHookMetadata.formatMetadata(
uint256(2**255 + 1),
DEFAULT_GAS_LIMIT,
address(this),

Loading…
Cancel
Save