Skip to content
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

feat: add test for the return data #149

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,14 @@ interface IL2ToL2CrossDomainMessenger {
/// already received once and is currently being replayed.
/// @param _id Identifier of the SentMessage event to be relayed
/// @param _sentMessage Message payload of the `SentMessage` event
function relayMessage(Identifier calldata _id, bytes calldata _sentMessage) external payable;
/// @return returnData_ Return data from the target contract call.
function relayMessage(
Identifier calldata _id,
bytes calldata _sentMessage
)
external
payable
returns (bytes memory returnData_);

function messageVersion() external view returns (uint16);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@
}
],
"name": "relayMessage",
"outputs": [],
"outputs": [
{
"internalType": "bytes",
"name": "returnData_",
"type": "bytes"
}
],
"stateMutability": "payable",
"type": "function"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/snapshots/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@
"sourceCodeHash": "0xaef8ea36c5b78cd12e0e62811d51db627ccf0dfd2cc5479fb707a10ef0d42048"
},
"src/L2/L2ToL2CrossDomainMessenger.sol": {
"initCodeHash": "0x45564b97c63419cc12eadc60425c6d001857a3eea688ecaf1439ae7ede6aa9aa",
"sourceCodeHash": "0xed64736338b43a42f6bc6a88cca734403e1bb9ceafa55e4738605dfdedd1a99f"
"initCodeHash": "0xc56db8cb569efa0467fd53ab3fa218af3051e54f5517d7fafb7b5831b4350618",
"sourceCodeHash": "0x72062343a044e9c56f4143dcfc71706286eb205902006c2afcf6a4cd90c3e9f8"
},
"src/L2/OptimismSuperchainERC20.sol": {
"initCodeHash": "0xdac32a1057a6bc8a8d2ffdce1db8f34950cd0ffd1454d2133865736d21869192",
Expand Down
17 changes: 12 additions & 5 deletions packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ pragma solidity 0.8.25;
import { Encoding } from "src/libraries/Encoding.sol";
import { Hashing } from "src/libraries/Hashing.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { SafeCall } from "src/libraries/SafeCall.sol";
import { TransientReentrancyAware } from "src/libraries/TransientContext.sol";

// Interfaces
Expand Down Expand Up @@ -72,8 +71,8 @@ contract L2ToL2CrossDomainMessenger is ISemver, TransientReentrancyAware {
uint16 public constant messageVersion = uint16(0);

/// @notice Semantic version.
/// @custom:semver 1.0.0-beta.13
string public constant version = "1.0.0-beta.13";
/// @custom:semver 1.0.0-beta.14
string public constant version = "1.0.0-beta.14";

/// @notice Mapping of message hashes to boolean receipt values. Note that a message will only be present in this
/// mapping if it has successfully been relayed on this chain, and can therefore not be relayed again.
Expand Down Expand Up @@ -160,7 +159,15 @@ contract L2ToL2CrossDomainMessenger is ISemver, TransientReentrancyAware {
/// @param _id Identifier of the SentMessage event to be relayed
/// @param _sentMessage Message payload of the `SentMessage` event
/// @return returnData_ Return data from the target contract call.
function relayMessage(Identifier calldata _id, bytes calldata _sentMessage) external payable nonReentrant returns (bytes memory returnData_) {
function relayMessage(
Identifier calldata _id,
bytes calldata _sentMessage
)
external
payable
nonReentrant
returns (bytes memory returnData_)
{
// Ensure the log came from the messenger. Since the log origin is the CDM, there isn't a scenario where
// this can be invoked from the CrossL2Inbox as the SentMessage log is not calldata for this function
if (_id.origin != Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER) {
Expand Down Expand Up @@ -196,7 +203,7 @@ contract L2ToL2CrossDomainMessenger is ISemver, TransientReentrancyAware {
_storeMessageMetadata(source, sender);

bool success;
(success, returnData_) = target.call{value: msg.value}(message);
(success, returnData_) = target.call{ value: msg.value }(message);

if (!success) {
revert TargetCallFailed();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,48 @@ contract L2ToL2CrossDomainMessengerTest is Test {
assertEq(l2ToL2CrossDomainMessenger.crossDomainMessageSender(), address(0));
}

/// @dev Tests the `relayMessage` function returns the expected return data of the call to the target contract.
function testFuzz_relayMessage_returnData_succeeds(
uint256 _source,
uint256 _nonce,
address _sender,
uint256 _value,
uint256 _blockNum,
uint256 _logIndex,
uint256 _time,
address _target,
bytes memory _mockedReturnData
)
public
{
// Declare a random call to be made over the target
bytes memory message = abi.encodeWithSignature("randomCall()");

// Construct the message
Identifier memory id =
Identifier(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, _blockNum, _logIndex, _time, _source);
bytes memory sentMessage = abi.encodePacked(
abi.encode(L2ToL2CrossDomainMessenger.SentMessage.selector, block.chainid, _target, _nonce), // topics
abi.encode(_sender, message) // data
);

// Ensure the CrossL2Inbox validates this message
vm.mockCall({
callee: Predeploys.CROSS_L2_INBOX,
data: abi.encodeCall(ICrossL2Inbox.validateMessage, (id, keccak256(message))),
returnData: ""
});

// Mock the random call over the target with the expected return data
vm.mockCall({ callee: _target, data: message, returnData: _mockedReturnData });

hoax(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, _value);
bytes memory returnData = l2ToL2CrossDomainMessenger.relayMessage{ value: _value }(id, sentMessage);

// Check that the return data is the mocked one
assertEq(returnData, _mockedReturnData);
}

/// @dev Mock reentrant function that calls the `relayMessage` function.
/// @param _source Source chain ID of the message.
/// @param _nonce Nonce of the message.
Expand Down