add polygon hook and ism (#3038)
### Description - Add native polygon bridge hook and isms ### Related issues - Fixes #2847 - Documented with https://github.com/hyperlane-xyz/v3-docs/pull/31 ### Backward compatibility Yes ### Testing Unit Tests --------- Co-authored-by: NOOMA-42 <suncloud2203357667@gmail.com>kunal/avs-contract-deployment
parent
cc8731985b
commit
c9c5d37bab
@ -1,3 +1,6 @@ |
|||||||
[submodule "solidity/lib/forge-std"] |
[submodule "solidity/lib/forge-std"] |
||||||
path = solidity/lib/forge-std |
path = solidity/lib/forge-std |
||||||
url = https://github.com/foundry-rs/forge-std |
url = https://github.com/foundry-rs/forge-std |
||||||
|
[submodule "solidity/lib/fx-portal"] |
||||||
|
path = solidity/lib/fx-portal |
||||||
|
url = https://github.com/0xPolygon/fx-portal |
||||||
|
@ -0,0 +1,83 @@ |
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||||
|
pragma solidity >=0.8.0; |
||||||
|
|
||||||
|
/*@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||||
|
@@@@@ HYPERLANE @@@@@@@ |
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@*/ |
||||||
|
|
||||||
|
// ============ Internal Imports ============ |
||||||
|
import {AbstractMessageIdAuthHook} from "./libs/AbstractMessageIdAuthHook.sol"; |
||||||
|
import {StandardHookMetadata} from "./libs/StandardHookMetadata.sol"; |
||||||
|
import {TypeCasts} from "../libs/TypeCasts.sol"; |
||||||
|
import {Message} from "../libs/Message.sol"; |
||||||
|
import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol"; |
||||||
|
|
||||||
|
// ============ External Imports ============ |
||||||
|
import {FxBaseRootTunnel} from "fx-portal/contracts/tunnel/FxBaseRootTunnel.sol"; |
||||||
|
import {Address} from "@openzeppelin/contracts/utils/Address.sol"; |
||||||
|
|
||||||
|
/** |
||||||
|
* @title PolygonPosHook |
||||||
|
* @notice Message hook to inform the PolygonPosIsm of messages published through |
||||||
|
* the native PoS bridge. |
||||||
|
*/ |
||||||
|
contract PolygonPosHook is AbstractMessageIdAuthHook, FxBaseRootTunnel { |
||||||
|
using StandardHookMetadata for bytes; |
||||||
|
|
||||||
|
// ============ Constructor ============ |
||||||
|
|
||||||
|
constructor( |
||||||
|
address _mailbox, |
||||||
|
uint32 _destinationDomain, |
||||||
|
bytes32 _ism, |
||||||
|
address _cpManager, |
||||||
|
address _fxRoot |
||||||
|
) |
||||||
|
AbstractMessageIdAuthHook(_mailbox, _destinationDomain, _ism) |
||||||
|
FxBaseRootTunnel(_cpManager, _fxRoot) |
||||||
|
{ |
||||||
|
require( |
||||||
|
Address.isContract(_cpManager), |
||||||
|
"PolygonPosHook: invalid cpManager contract" |
||||||
|
); |
||||||
|
require( |
||||||
|
Address.isContract(_fxRoot), |
||||||
|
"PolygonPosHook: invalid fxRoot contract" |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// ============ Internal functions ============ |
||||||
|
function _quoteDispatch( |
||||||
|
bytes calldata, |
||||||
|
bytes calldata |
||||||
|
) internal pure override returns (uint256) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/// @inheritdoc AbstractMessageIdAuthHook |
||||||
|
function _sendMessageId( |
||||||
|
bytes calldata metadata, |
||||||
|
bytes memory payload |
||||||
|
) internal override { |
||||||
|
require( |
||||||
|
metadata.msgValue(0) == 0, |
||||||
|
"PolygonPosHook: does not support msgValue" |
||||||
|
); |
||||||
|
require(msg.value == 0, "PolygonPosHook: does not support msgValue"); |
||||||
|
_sendMessageToChild(payload); |
||||||
|
} |
||||||
|
|
||||||
|
bytes public latestData; |
||||||
|
|
||||||
|
function _processMessageFromChild(bytes memory data) internal override { |
||||||
|
latestData = data; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0 |
||||||
|
pragma solidity >=0.8.0; |
||||||
|
|
||||||
|
/*@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||||
|
@@@@@ HYPERLANE @@@@@@@ |
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@@ |
||||||
|
@@@@@@@@@ @@@@@@@@*/ |
||||||
|
|
||||||
|
// ============ Internal Imports ============ |
||||||
|
|
||||||
|
import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol"; |
||||||
|
import {Message} from "../../libs/Message.sol"; |
||||||
|
import {TypeCasts} from "../../libs/TypeCasts.sol"; |
||||||
|
import {AbstractMessageIdAuthorizedIsm} from "./AbstractMessageIdAuthorizedIsm.sol"; |
||||||
|
|
||||||
|
// ============ External Imports ============ |
||||||
|
import {CrossChainEnabledPolygonChild} from "@openzeppelin/contracts/crosschain/polygon/CrossChainEnabledPolygonChild.sol"; |
||||||
|
import {Address} from "@openzeppelin/contracts/utils/Address.sol"; |
||||||
|
|
||||||
|
/** |
||||||
|
* @title PolygonPosIsm |
||||||
|
* @notice Uses the native Polygon Pos Fx Portal Bridge to verify interchain messages. |
||||||
|
*/ |
||||||
|
contract PolygonPosIsm is |
||||||
|
CrossChainEnabledPolygonChild, |
||||||
|
AbstractMessageIdAuthorizedIsm |
||||||
|
{ |
||||||
|
// ============ Constants ============ |
||||||
|
|
||||||
|
uint8 public constant moduleType = |
||||||
|
uint8(IInterchainSecurityModule.Types.NULL); |
||||||
|
|
||||||
|
// ============ Constructor ============ |
||||||
|
|
||||||
|
constructor(address _fxChild) CrossChainEnabledPolygonChild(_fxChild) { |
||||||
|
require( |
||||||
|
Address.isContract(_fxChild), |
||||||
|
"PolygonPosIsm: invalid FxChild contract" |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// ============ Internal function ============ |
||||||
|
|
||||||
|
/** |
||||||
|
* @notice Check if sender is authorized to message `verifyMessageId`. |
||||||
|
*/ |
||||||
|
function _isAuthorized() internal view override returns (bool) { |
||||||
|
return |
||||||
|
_crossChainSender() == TypeCasts.bytes32ToAddress(authorizedHook); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit ebd046507d76cd03fa2b2559257091471a259ed7 |
@ -0,0 +1,367 @@ |
|||||||
|
// SPDX-License-Identifier: MIT or Apache-2.0 |
||||||
|
pragma solidity ^0.8.13; |
||||||
|
|
||||||
|
import {Test} from "forge-std/Test.sol"; |
||||||
|
|
||||||
|
import {LibBit} from "../../contracts/libs/LibBit.sol"; |
||||||
|
import {TypeCasts} from "../../contracts/libs/TypeCasts.sol"; |
||||||
|
import {StandardHookMetadata} from "../../contracts/hooks/libs/StandardHookMetadata.sol"; |
||||||
|
import {StandardHookMetadata} from "../../contracts/hooks/libs/StandardHookMetadata.sol"; |
||||||
|
import {AbstractMessageIdAuthorizedIsm} from "../../contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol"; |
||||||
|
import {TestMailbox} from "../../contracts/test/TestMailbox.sol"; |
||||||
|
import {Message} from "../../contracts/libs/Message.sol"; |
||||||
|
import {MessageUtils} from "./IsmTestUtils.sol"; |
||||||
|
import {PolygonPosIsm} from "../../contracts/isms/hook/PolygonPosIsm.sol"; |
||||||
|
import {PolygonPosHook} from "../../contracts/hooks/PolygonPosHook.sol"; |
||||||
|
import {TestRecipient} from "../../contracts/test/TestRecipient.sol"; |
||||||
|
|
||||||
|
import {NotCrossChainCall} from "@openzeppelin/contracts/crosschain/errors.sol"; |
||||||
|
|
||||||
|
interface IStateSender { |
||||||
|
function counter() external view returns (uint256); |
||||||
|
} |
||||||
|
|
||||||
|
interface FxChild { |
||||||
|
function onStateReceive(uint256 stateId, bytes calldata data) external; |
||||||
|
} |
||||||
|
|
||||||
|
contract PolygonPosIsmTest is Test { |
||||||
|
using LibBit for uint256; |
||||||
|
using TypeCasts for address; |
||||||
|
using MessageUtils for bytes; |
||||||
|
|
||||||
|
uint256 internal mainnetFork; |
||||||
|
uint256 internal polygonPosFork; |
||||||
|
|
||||||
|
address internal constant POLYGON_CROSSCHAIN_SYSTEM_ADDR = |
||||||
|
0x0000000000000000000000000000000000001001; |
||||||
|
|
||||||
|
address internal constant MUMBAI_FX_CHILD = |
||||||
|
0xCf73231F28B7331BBe3124B907840A94851f9f11; |
||||||
|
address internal constant GOERLI_CHECKPOINT_MANAGER = |
||||||
|
0x2890bA17EfE978480615e330ecB65333b880928e; |
||||||
|
address internal constant GOERLI_FX_ROOT = |
||||||
|
0x3d1d3E34f7fB6D26245E6640E1c50710eFFf15bA; |
||||||
|
|
||||||
|
address internal constant MAINNET_FX_CHILD = |
||||||
|
0x8397259c983751DAf40400790063935a11afa28a; |
||||||
|
address internal constant MAINNET_CHECKPOINT_MANAGER = |
||||||
|
0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287; |
||||||
|
address internal constant MAINNET_FX_ROOT = |
||||||
|
0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2; |
||||||
|
address internal constant MAINNET_STATE_SENDER = |
||||||
|
0x28e4F3a7f651294B9564800b2D01f35189A5bFbE; |
||||||
|
|
||||||
|
uint8 internal constant POLYGON_POS_VERSION = 0; |
||||||
|
uint8 internal constant HYPERLANE_VERSION = 1; |
||||||
|
|
||||||
|
TestMailbox internal l1Mailbox; |
||||||
|
PolygonPosIsm internal polygonPosISM; |
||||||
|
PolygonPosHook internal polygonPosHook; |
||||||
|
FxChild internal fxChild; |
||||||
|
|
||||||
|
TestRecipient internal testRecipient; |
||||||
|
bytes internal testMessage = |
||||||
|
abi.encodePacked("Hello from the other chain!"); |
||||||
|
bytes internal testMetadata = |
||||||
|
StandardHookMetadata.overrideRefundAddress(address(this)); |
||||||
|
|
||||||
|
bytes internal encodedMessage; |
||||||
|
bytes32 internal messageId; |
||||||
|
|
||||||
|
uint32 internal constant MAINNET_DOMAIN = 1; |
||||||
|
uint32 internal constant POLYGON_POS_DOMAIN = 137; |
||||||
|
|
||||||
|
event StateSynced( |
||||||
|
uint256 indexed id, |
||||||
|
address indexed contractAddress, |
||||||
|
bytes data |
||||||
|
); |
||||||
|
|
||||||
|
event ReceivedMessage(bytes32 indexed messageId); |
||||||
|
|
||||||
|
function setUp() public { |
||||||
|
// block numbers to fork from, chain data is cached to ../../forge-cache/ |
||||||
|
mainnetFork = vm.createFork(vm.rpcUrl("mainnet"), 18_718_401); |
||||||
|
polygonPosFork = vm.createFork(vm.rpcUrl("polygon"), 50_760_479); |
||||||
|
|
||||||
|
testRecipient = new TestRecipient(); |
||||||
|
|
||||||
|
encodedMessage = _encodeTestMessage(); |
||||||
|
messageId = Message.id(encodedMessage); |
||||||
|
} |
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////// |
||||||
|
/// SETUP /// |
||||||
|
/////////////////////////////////////////////////////////////////// |
||||||
|
|
||||||
|
function deployPolygonPosHook() public { |
||||||
|
vm.selectFork(mainnetFork); |
||||||
|
|
||||||
|
l1Mailbox = new TestMailbox(MAINNET_DOMAIN); |
||||||
|
|
||||||
|
polygonPosHook = new PolygonPosHook( |
||||||
|
address(l1Mailbox), |
||||||
|
POLYGON_POS_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosISM)), |
||||||
|
MAINNET_CHECKPOINT_MANAGER, |
||||||
|
MAINNET_FX_ROOT |
||||||
|
); |
||||||
|
|
||||||
|
polygonPosHook.setFxChildTunnel(address(polygonPosISM)); |
||||||
|
|
||||||
|
vm.makePersistent(address(polygonPosHook)); |
||||||
|
} |
||||||
|
|
||||||
|
function deployPolygonPosIsm() public { |
||||||
|
vm.selectFork(polygonPosFork); |
||||||
|
|
||||||
|
fxChild = FxChild(MAINNET_FX_CHILD); |
||||||
|
polygonPosISM = new PolygonPosIsm(MAINNET_FX_CHILD); |
||||||
|
|
||||||
|
vm.makePersistent(address(polygonPosISM)); |
||||||
|
} |
||||||
|
|
||||||
|
function deployAll() public { |
||||||
|
deployPolygonPosIsm(); |
||||||
|
deployPolygonPosHook(); |
||||||
|
|
||||||
|
vm.selectFork(polygonPosFork); |
||||||
|
|
||||||
|
polygonPosISM.setAuthorizedHook( |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosHook)) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////// |
||||||
|
/// FORK TESTS /// |
||||||
|
/////////////////////////////////////////////////////////////////// |
||||||
|
|
||||||
|
/* ============ hook.quoteDispatch ============ */ |
||||||
|
|
||||||
|
function testFork_quoteDispatch() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(mainnetFork); |
||||||
|
|
||||||
|
assertEq(polygonPosHook.quoteDispatch(testMetadata, encodedMessage), 0); |
||||||
|
} |
||||||
|
|
||||||
|
/* ============ hook.postDispatch ============ */ |
||||||
|
|
||||||
|
function testFork_postDispatch() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(mainnetFork); |
||||||
|
|
||||||
|
bytes memory encodedHookData = abi.encodeCall( |
||||||
|
AbstractMessageIdAuthorizedIsm.verifyMessageId, |
||||||
|
(messageId) |
||||||
|
); |
||||||
|
|
||||||
|
l1Mailbox.updateLatestDispatchedId(messageId); |
||||||
|
|
||||||
|
IStateSender stateSender = IStateSender(MAINNET_STATE_SENDER); |
||||||
|
|
||||||
|
vm.expectEmit(true, false, false, true); |
||||||
|
emit StateSynced( |
||||||
|
(stateSender.counter() + 1), |
||||||
|
MAINNET_FX_CHILD, |
||||||
|
abi.encode( |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosHook)), |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosISM)), |
||||||
|
encodedHookData |
||||||
|
) |
||||||
|
); |
||||||
|
polygonPosHook.postDispatch(testMetadata, encodedMessage); |
||||||
|
} |
||||||
|
|
||||||
|
function testFork_postDispatch_RevertWhen_ChainIDNotSupported() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(mainnetFork); |
||||||
|
|
||||||
|
bytes memory message = MessageUtils.formatMessage( |
||||||
|
POLYGON_POS_VERSION, |
||||||
|
uint32(0), |
||||||
|
MAINNET_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(this)), |
||||||
|
11, // wrong domain |
||||||
|
TypeCasts.addressToBytes32(address(testRecipient)), |
||||||
|
testMessage |
||||||
|
); |
||||||
|
|
||||||
|
l1Mailbox.updateLatestDispatchedId(Message.id(message)); |
||||||
|
vm.expectRevert( |
||||||
|
"AbstractMessageIdAuthHook: invalid destination domain" |
||||||
|
); |
||||||
|
polygonPosHook.postDispatch(testMetadata, message); |
||||||
|
} |
||||||
|
|
||||||
|
function testFork_postDispatch_RevertWhen_TooMuchValue() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(mainnetFork); |
||||||
|
|
||||||
|
// assign any value should revert |
||||||
|
vm.deal(address(this), uint256(2 ** 255)); |
||||||
|
bytes memory excessValueMetadata = StandardHookMetadata |
||||||
|
.overrideMsgValue(uint256(2 ** 255)); |
||||||
|
|
||||||
|
l1Mailbox.updateLatestDispatchedId(messageId); |
||||||
|
vm.expectRevert( |
||||||
|
"AbstractMessageIdAuthHook: msgValue must be less than 2 ** 255" |
||||||
|
); |
||||||
|
polygonPosHook.postDispatch(excessValueMetadata, encodedMessage); |
||||||
|
} |
||||||
|
|
||||||
|
function testFork_postDispatch_RevertWhen_NotLastDispatchedMessage() |
||||||
|
public |
||||||
|
{ |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(mainnetFork); |
||||||
|
|
||||||
|
vm.expectRevert( |
||||||
|
"AbstractMessageIdAuthHook: message not latest dispatched" |
||||||
|
); |
||||||
|
polygonPosHook.postDispatch(testMetadata, encodedMessage); |
||||||
|
} |
||||||
|
|
||||||
|
/* ============ ISM.verifyMessageId ============ */ |
||||||
|
|
||||||
|
function testFork_verifyMessageId() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(polygonPosFork); |
||||||
|
|
||||||
|
bytes memory encodedHookData = abi.encodeCall( |
||||||
|
AbstractMessageIdAuthorizedIsm.verifyMessageId, |
||||||
|
(messageId) |
||||||
|
); |
||||||
|
|
||||||
|
vm.startPrank(POLYGON_CROSSCHAIN_SYSTEM_ADDR); |
||||||
|
|
||||||
|
vm.expectEmit(true, false, false, false, address(polygonPosISM)); |
||||||
|
emit ReceivedMessage(messageId); |
||||||
|
// FIX: expect other events |
||||||
|
|
||||||
|
fxChild.onStateReceive( |
||||||
|
0, |
||||||
|
abi.encode( |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosHook)), |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosISM)), |
||||||
|
encodedHookData |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
assertTrue(polygonPosISM.verifiedMessages(messageId).isBitSet(255)); |
||||||
|
vm.stopPrank(); |
||||||
|
} |
||||||
|
|
||||||
|
function testFork_verifyMessageId_RevertWhen_NotAuthorized() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(polygonPosFork); |
||||||
|
|
||||||
|
// needs to be called by the fxchild on Polygon |
||||||
|
vm.expectRevert(NotCrossChainCall.selector); |
||||||
|
polygonPosISM.verifyMessageId(messageId); |
||||||
|
|
||||||
|
vm.startPrank(MAINNET_FX_CHILD); |
||||||
|
|
||||||
|
// needs to be called by the authorized hook contract on Ethereum |
||||||
|
vm.expectRevert( |
||||||
|
"AbstractMessageIdAuthorizedIsm: sender is not the hook" |
||||||
|
); |
||||||
|
polygonPosISM.verifyMessageId(messageId); |
||||||
|
} |
||||||
|
|
||||||
|
/* ============ ISM.verify ============ */ |
||||||
|
|
||||||
|
function testFork_verify() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
vm.selectFork(polygonPosFork); |
||||||
|
|
||||||
|
orchestrateRelayMessage(messageId); |
||||||
|
|
||||||
|
bool verified = polygonPosISM.verify(new bytes(0), encodedMessage); |
||||||
|
assertTrue(verified); |
||||||
|
} |
||||||
|
|
||||||
|
// sending over invalid message |
||||||
|
function testFork_verify_RevertWhen_HyperlaneInvalidMessage() public { |
||||||
|
deployAll(); |
||||||
|
|
||||||
|
orchestrateRelayMessage(messageId); |
||||||
|
|
||||||
|
bytes memory invalidMessage = MessageUtils.formatMessage( |
||||||
|
HYPERLANE_VERSION, |
||||||
|
uint8(0), |
||||||
|
MAINNET_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(this)), |
||||||
|
POLYGON_POS_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(this)), // wrong recipient |
||||||
|
testMessage |
||||||
|
); |
||||||
|
bool verified = polygonPosISM.verify(new bytes(0), invalidMessage); |
||||||
|
assertFalse(verified); |
||||||
|
} |
||||||
|
|
||||||
|
// invalid messageID in postDispatch |
||||||
|
function testFork_verify_RevertWhen_InvalidPolygonPosMessageID() public { |
||||||
|
deployAll(); |
||||||
|
vm.selectFork(polygonPosFork); |
||||||
|
|
||||||
|
bytes memory invalidMessage = MessageUtils.formatMessage( |
||||||
|
HYPERLANE_VERSION, |
||||||
|
uint8(0), |
||||||
|
MAINNET_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(this)), |
||||||
|
POLYGON_POS_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(this)), |
||||||
|
testMessage |
||||||
|
); |
||||||
|
bytes32 _messageId = Message.id(invalidMessage); |
||||||
|
orchestrateRelayMessage(_messageId); |
||||||
|
|
||||||
|
bool verified = polygonPosISM.verify(new bytes(0), encodedMessage); |
||||||
|
assertFalse(verified); |
||||||
|
} |
||||||
|
|
||||||
|
/* ============ helper functions ============ */ |
||||||
|
|
||||||
|
function _encodeTestMessage() internal view returns (bytes memory) { |
||||||
|
return |
||||||
|
MessageUtils.formatMessage( |
||||||
|
HYPERLANE_VERSION, |
||||||
|
uint32(0), |
||||||
|
MAINNET_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(this)), |
||||||
|
POLYGON_POS_DOMAIN, |
||||||
|
TypeCasts.addressToBytes32(address(testRecipient)), |
||||||
|
testMessage |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
function orchestrateRelayMessage(bytes32 _messageId) internal { |
||||||
|
vm.selectFork(polygonPosFork); |
||||||
|
|
||||||
|
bytes memory encodedHookData = abi.encodeCall( |
||||||
|
AbstractMessageIdAuthorizedIsm.verifyMessageId, |
||||||
|
(_messageId) |
||||||
|
); |
||||||
|
|
||||||
|
vm.prank(POLYGON_CROSSCHAIN_SYSTEM_ADDR); |
||||||
|
|
||||||
|
fxChild.onStateReceive( |
||||||
|
0, |
||||||
|
abi.encode( |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosHook)), |
||||||
|
TypeCasts.addressToBytes32(address(polygonPosISM)), |
||||||
|
encodedHookData |
||||||
|
) |
||||||
|
); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue