-
Notifications
You must be signed in to change notification settings - Fork 10
Test MessageRelayer #142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nikeshnazareth
wants to merge
34
commits into
main
Choose a base branch
from
tests/message-relayer
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Test MessageRelayer #142
Changes from 6 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
b8d8acd
Create initial state
nikeshnazareth a60d464
Create default message
nikeshnazareth d2aed97
Create message recipient
nikeshnazareth 6b84dba
Create DepositRecipientScenarios
nikeshnazareth 6205519
Create TipRecipientScenarios
nikeshnazareth c67ec39
Test claimDeposit path
nikeshnazareth 9074f4d
add more scenarios
LeoPatOZ fa42d46
made scripts easier to work with
LeoPatOZ cc68261
reentrancy test
LeoPatOZ f0ee2db
remove uneeded counter
LeoPatOZ ffd4e33
fix scenarios
LeoPatOZ ac4471c
add more test scenarios
LeoPatOZ a3de214
better testing scenario
LeoPatOZ bd61c84
transient storage test
LeoPatOZ 443b9e2
Merge branch 'main' into tests/message-relayer
LeoPatOZ f781997
update scenario
LeoPatOZ 5347332
name
LeoPatOZ 521fd25
Merge branch 'main' into tests/message-relayer
LeoPatOZ 4608dc8
Create ifTxSucceeds modifier
nikeshnazareth 28fb7bd
Remove InitialStateTest
nikeshnazareth d093a79
Use ifTxSucceeds so UserSetInvalidTipRecipient can inherit DepositRec…
nikeshnazareth 0800551
Expand TipRecipientScenarios using the ifRelaySucceeds mechanism
nikeshnazareth 0b1c6e7
Move shouldRevert checks to the InitialState contract
nikeshnazareth 3b60423
Migrate FundAmountScenarios to the new structure
nikeshnazareth df1457e
Remove unused TIP_RECIPIENT_SLOT
nikeshnazareth 9fb7b06
Test GasLimitScenarios
nikeshnazareth a0fed52
Migrate RelayRecipientScenarios to new structure
nikeshnazareth 240c6d9
Create default scenarios for better encapsulation
nikeshnazareth 4794e23
Fix InsufficientValue comment
nikeshnazareth 7e30320
Run forge fmt
nikeshnazareth bac25c5
Increase OOG_INSIDE_RECIPIENT
nikeshnazareth d77e2ae
typo
LeoPatOZ 0c38142
Merge branch 'main' into tests/message-relayer
nikeshnazareth 9ff57d2
Set signalService to verify all signals
nikeshnazareth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.28; | ||
|
|
||
| import {GenericRecipient} from "./GenericRecipient.t.sol"; | ||
| import {InitialState} from "./InitialState.t.sol"; | ||
| import {IMessageRelayer} from "src/protocol/IMessageRelayer.sol"; | ||
|
|
||
| // This is a concrete class because if we are not using the MessageRelayer, | ||
| // we do not need to investigate any other properties of the message | ||
| contract DepositRecipientIsNotMessageRelayer is InitialState { | ||
| function setUp() public override { | ||
| super.setUp(); | ||
| // bypass the relayer and send the message directly to the recipient | ||
| // do not bother changing the default message encoding (to a `receiveMessage` function) | ||
| // because the recipient handles any message | ||
| ethDeposit.to = address(to); | ||
| } | ||
|
|
||
| function test_DepositRecipientIsNotMessageRelayer_relayMessage_shouldInvokeRecipient() public { | ||
| vm.expectEmit(); | ||
| emit GenericRecipient.FunctionCalled(); | ||
| _relayMessage(); | ||
| } | ||
|
|
||
| function test_DepositRecipientIsNotMessageRelayer_relayMessage_shouldNotInvokeReceiveMessage() public { | ||
| vm.expectCall(address(messageRelayer), ethDeposit.data, 0); | ||
| _relayMessage(); | ||
| } | ||
| } | ||
|
|
||
| abstract contract DepositRecipientIsMessageRelayer is InitialState { | ||
| function test_DepositRecipientIsMessageRelayer_relayMessage_shouldInvokeReceiveMessage() public { | ||
| vm.expectCall(address(messageRelayer), ethDeposit.data); | ||
| _relayMessage(); | ||
| } | ||
|
|
||
| function test_DepositRecipientIsMessageRelayer_claimDeposit_shouldInvokeReceiveMessage() public { | ||
| vm.expectCall(address(messageRelayer), ethDeposit.data); | ||
| messageRelayer.ethBridge().claimDeposit(ethDeposit, height, proof); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.28; | ||
|
|
||
| contract GenericRecipient { | ||
| bool private callWillSucceed = true; | ||
|
|
||
| error CallFailed(); | ||
|
|
||
| event FunctionCalled(); | ||
|
|
||
| function setSuccess(bool _callWillSucceed) external { | ||
| callWillSucceed = _callWillSucceed; | ||
| } | ||
|
|
||
| fallback() external payable { | ||
| _simulateFunctionCall(); | ||
| } | ||
|
|
||
| receive() external payable { | ||
| _simulateFunctionCall(); | ||
| } | ||
|
|
||
| function _simulateFunctionCall() internal { | ||
| require(callWillSucceed, CallFailed()); | ||
| emit FunctionCalled(); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.28; | ||
|
|
||
| import "forge-std/Test.sol"; | ||
|
|
||
| import {ETHBridge} from "src/protocol/ETHBridge.sol"; | ||
| import {IETHBridge} from "src/protocol/IETHBridge.sol"; | ||
|
|
||
| import {GenericRecipient} from "./GenericRecipient.t.sol"; | ||
| import {IMessageRelayer} from "src/protocol/IMessageRelayer.sol"; | ||
| import {MessageRelayer} from "src/protocol/taiko_alethia/MessageRelayer.sol"; | ||
| import {MockSignalService} from "test/mocks/MockSignalService.sol"; | ||
|
|
||
| abstract contract InitialState is Test { | ||
| MessageRelayer messageRelayer; | ||
|
|
||
| // Default message parameters | ||
| IETHBridge.ETHDeposit ethDeposit; | ||
| uint256 height = 0; | ||
| bytes proof = "0x"; | ||
| GenericRecipient to; | ||
| uint256 amount = 2 ether; | ||
| uint256 tip = 0.1 ether; | ||
| GenericRecipient relayerSelectedTipRecipient; | ||
| GenericRecipient userSelectedTipRecipient; | ||
| uint256 gasLimit = 0; | ||
| bytes data = "0x"; | ||
|
|
||
| function setUp() public virtual { | ||
| MockSignalService signalService = new MockSignalService(); | ||
| address trustedCommitmentPublisher = _randomAddress("trustedCommitmentPublisher"); | ||
| address counterpart = _randomAddress("counterpart"); | ||
| to = new GenericRecipient(); | ||
| relayerSelectedTipRecipient = new GenericRecipient(); | ||
| userSelectedTipRecipient = new GenericRecipient(); | ||
| ETHBridge bridge = new ETHBridge(address(signalService), trustedCommitmentPublisher, counterpart); | ||
| vm.deal(address(bridge), amount); | ||
|
|
||
| messageRelayer = new MessageRelayer(address(bridge)); | ||
|
|
||
| ethDeposit = IETHBridge.ETHDeposit({ | ||
| nonce: 0, | ||
| from: _randomAddress("from"), | ||
| to: address(messageRelayer), | ||
| amount: 2 ether, | ||
| data: "", | ||
| context: "", | ||
| canceler: address(0) | ||
| }); | ||
| _encodeReceiveCall(); | ||
| } | ||
|
|
||
| function _encodeReceiveCall() internal { | ||
| ethDeposit.data = abi.encodeCall( | ||
| IMessageRelayer.receiveMessage, (address(to), tip, address(userSelectedTipRecipient), gasLimit, data) | ||
| ); | ||
| } | ||
|
|
||
| function _relayMessage() internal { | ||
| messageRelayer.relayMessage(ethDeposit, height, proof, address(relayerSelectedTipRecipient)); | ||
| } | ||
|
|
||
| function _randomAddress(string memory name) internal pure returns (address) { | ||
| return address(uint160(uint256(keccak256(abi.encode(_domainSeparator(), name))))); | ||
| } | ||
|
|
||
| function _domainSeparator() internal pure returns (bytes32) { | ||
| return keccak256("MessageRelayer"); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.28; | ||
|
|
||
| import {DepositRecipientIsMessageRelayer} from "./DepositRecipientScenarios.t.sol"; | ||
| import {GenericRecipient} from "./GenericRecipient.t.sol"; | ||
|
|
||
| import {InitialState} from "./InitialState.t.sol"; | ||
| import {IETHBridge} from "src/protocol/IETHBridge.sol"; | ||
|
|
||
| contract UserSetValidTipRecipient is DepositRecipientIsMessageRelayer { | ||
| function test_UserSetValidTipRecipient_relayMessage_shouldTipUserSelectedRecipient() public { | ||
| uint256 balanceBefore = address(userSelectedTipRecipient).balance; | ||
| _relayMessage(); | ||
| assertEq(address(userSelectedTipRecipient).balance, balanceBefore + tip, "tip recipient balance mismatch"); | ||
| } | ||
|
|
||
| function test_UserSetValidTipRecipient_relayMessage_shouldNotTipRelayerSelectedRecipient() public { | ||
| uint256 balanceBefore = address(relayerSelectedTipRecipient).balance; | ||
| _relayMessage(); | ||
| assertEq(address(relayerSelectedTipRecipient).balance, balanceBefore, "incorrect tip recipient paid"); | ||
| } | ||
| } | ||
|
|
||
| contract UserSetZeroTipRecipient is DepositRecipientIsMessageRelayer { | ||
| function setUp() public override { | ||
| super.setUp(); | ||
| userSelectedTipRecipient = GenericRecipient(payable(0)); | ||
| _encodeReceiveCall(); | ||
| } | ||
|
|
||
| function test_UserSetZeroTipRecipient_relayMessage_shouldTipRelayerSelectedRecipient() public { | ||
| uint256 balanceBefore = address(relayerSelectedTipRecipient).balance; | ||
| _relayMessage(); | ||
| assertEq(address(relayerSelectedTipRecipient).balance, balanceBefore + tip, "tip recipient balance mismatch"); | ||
| } | ||
| } | ||
|
|
||
| // We bypass the `DepositRecipientIsMessageRelayer` because it seems vm.expectCall requires the call to succeed | ||
| contract UserSetInvalidTipRecipient is InitialState { | ||
| function setUp() public override { | ||
| super.setUp(); | ||
| userSelectedTipRecipient.setSuccess(false); | ||
| } | ||
|
|
||
| function test_UserSetInvalidTipRecipient_relayMessage_shouldRevert() public { | ||
| vm.expectRevert(IETHBridge.FailedClaim.selector); | ||
| _relayMessage(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.28; | ||
|
|
||
| import {ISignalService} from "src/protocol/ISignalService.sol"; | ||
|
|
||
| contract MockSignalService is ISignalService { | ||
| error NotImplemented(); | ||
|
|
||
| function sendSignal(bytes32) external pure returns (bytes32) { | ||
| revert NotImplemented(); | ||
| } | ||
|
|
||
| function isSignalStored(bytes32, address) external pure returns (bool) { | ||
| revert NotImplemented(); | ||
| } | ||
|
|
||
| // verification always succeeds | ||
| function verifySignal( | ||
| uint256, /* height */ | ||
| address, /* commitmentPublisher */ | ||
| address, /* sender */ | ||
| bytes32, /* value */ | ||
| bytes memory /* proof */ | ||
| ) external view {} | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix syntax error in require statement.
The
requirestatement with a custom error is using incorrect syntax. Therequirefunction expects a string message, not a custom error.Apply this diff to fix the syntax error:
function _simulateFunctionCall() internal { - require(callWillSucceed, CallFailed()); + if (!callWillSucceed) { + revert CallFailed(); + } emit FunctionCalled(); }📝 Committable suggestion
🤖 Prompt for AI Agents