Skip to content

Commit

Permalink
fix: add fix for checking for correct messageId in OPL2ToL1Ism and …
Browse files Browse the repository at this point in the history
…`ArbL2ToL1Ism` via external call (hyperlane-xyz#4437)

### Description

- In agreement with Chainlight team's recommendation, added a second
isVerified() check after portal call to make sure an arbitrary call
which passes the check for metadata length and messageId cannot be
verified without calling is verifyMessageId(messageId) in `OPL2ToL1Ism`
and `ArbL2ToL1`

### Drive-by changes

None

### Related issues

- fixes https://github.com/chainlight-io/2024-08-hyperlane/issues/2

### Backward compatibility

No, but the contracts aren't deployed anywhere

### Testing

Unit testing
  • Loading branch information
aroralanuk authored and tiendn committed Oct 25, 2024
1 parent 147491c commit 62e632d
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-singers-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hyperlane-xyz/core': patch
---

Patched OPL2ToL1Ism to check for correct messageId for external call in verify
1 change: 1 addition & 0 deletions solidity/contracts/isms/hook/ArbL2ToL1Ism.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ contract ArbL2ToL1Ism is
) external override returns (bool) {
if (!isVerified(message)) {
_verifyWithOutboxCall(metadata, message);
require(isVerified(message), "ArbL2ToL1Ism: message not verified");
}
releaseValueToRecipient(message);
return true;
Expand Down
4 changes: 2 additions & 2 deletions solidity/contracts/isms/hook/OPL2ToL1Ism.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ contract OPL2ToL1Ism is
bytes calldata metadata,
bytes calldata message
) external override returns (bool) {
bool verified = isVerified(message);
if (!verified) {
if (!isVerified(message)) {
_verifyWithPortalCall(metadata, message);
require(isVerified(message), "OPL2ToL1Ism: message not verified");
}
releaseValueToRecipient(message);
return true;
Expand Down
2 changes: 2 additions & 0 deletions solidity/test/isms/ERC5164ISM.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ contract ERC5164IsmTest is ExternalBridgeTest {

function test_verify_valueAlreadyClaimed(uint256) public override {}

function test_verify_false_arbitraryCall() public override {}

/* ============ helper functions ============ */

function _externalBridgeDestinationCall(
Expand Down
20 changes: 18 additions & 2 deletions solidity/test/isms/ExternalBridgeTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,14 @@ abstract contract ExternalBridgeTest is Test {
1 ether,
messageId
);
ism.verify(externalCalldata, encodedMessage);
assertTrue(ism.verify(externalCalldata, encodedMessage));
assertEq(address(testRecipient).balance, 1 ether);
}

function test_verify_revertsWhen_invalidIsm() public virtual {
bytes memory externalCalldata = _encodeExternalDestinationBridgeCall(
address(hook),
address(this),
address(hook),
0,
messageId
);
Expand Down Expand Up @@ -217,6 +217,19 @@ abstract contract ExternalBridgeTest is Test {
assertEq(address(testRecipient).balance, _msgValue);
}

function test_verify_false_arbitraryCall() public virtual {
bytes memory incorrectCalldata = _encodeExternalDestinationBridgeCall(
address(hook),
address(this),
0,
messageId
);

vm.expectRevert();
ism.verify(incorrectCalldata, encodedMessage);
assertFalse(ism.isVerified(encodedMessage));
}

/* ============ helper functions ============ */

function _encodeTestMessage() internal view returns (bytes memory) {
Expand Down Expand Up @@ -265,4 +278,7 @@ abstract contract ExternalBridgeTest is Test {
function _setExternalOriginSender(
address _sender
) internal virtual returns (bytes memory) {}

// meant to mock an arbitrary successful call made by the external bridge
function verifyMessageId(bytes32 /*messageId*/) public payable {}
}
10 changes: 6 additions & 4 deletions solidity/test/isms/OPStackIsm.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ contract OPStackIsmTest is ExternalBridgeTest {
}

function _encodeExternalDestinationBridgeCall(
address _from,
address _to,
uint256 _msgValue,
bytes32 _messageId
address /*_from*/,
address /*_to*/,
uint256 /*_msgValue*/,
bytes32 /*_messageId*/
) internal pure override returns (bytes memory) {
return new bytes(0);
}
Expand All @@ -148,6 +148,8 @@ contract OPStackIsmTest is ExternalBridgeTest {

function test_verify_revertsWhen_invalidIsm() public override {}

function test_verify_false_arbitraryCall() public override {}

/* ============ ISM.verifyMessageId ============ */

function test_verify_revertsWhen_notAuthorizedHook() public override {
Expand Down

0 comments on commit 62e632d

Please sign in to comment.