Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- L2CrossDomainMessenger
- Optimization enabled
- true
- Compiler version
- v0.8.9+commit.e5eed63a
- Optimization runs
- 10000
- EVM Version
- default
- Verified at
- 2024-04-02T16:26:22.524028Z
contracts/L2/messaging/L2CrossDomainMessenger.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* Library Imports */ import { AddressAliasHelper } from "../../standards/AddressAliasHelper.sol"; import { Lib_CrossDomainUtils } from "../../libraries/bridge/Lib_CrossDomainUtils.sol"; import { Lib_DefaultValues } from "../../libraries/constants/Lib_DefaultValues.sol"; import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; /* Interface Imports */ import { IL2CrossDomainMessenger } from "./IL2CrossDomainMessenger.sol"; import { iOVM_L2ToL1MessagePasser } from "../predeploys/iOVM_L2ToL1MessagePasser.sol"; /** * @title L2CrossDomainMessenger * @dev The L2 Cross Domain Messenger contract sends messages from L2 to L1, and is the entry point * for L2 messages sent via the L1 Cross Domain Messenger. * */ contract L2CrossDomainMessenger is IL2CrossDomainMessenger { /************* * Variables * *************/ mapping(bytes32 => bool) public relayedMessages; mapping(bytes32 => bool) public successfulMessages; mapping(bytes32 => bool) public sentMessages; uint256 public messageNonce; address internal xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER; address public l1CrossDomainMessenger; /*************** * Constructor * ***************/ constructor(address _l1CrossDomainMessenger) { l1CrossDomainMessenger = _l1CrossDomainMessenger; } /******************** * Public Functions * ********************/ // slither-disable-next-line external-function function xDomainMessageSender() public view returns (address) { require( xDomainMsgSender != Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER, "xDomainMessageSender is not set" ); return xDomainMsgSender; } /** * Sends a cross domain message to the target messenger. * @param _target Target contract address. * @param _message Message to send to the target. * @param _gasLimit Gas limit for the provided message. */ // slither-disable-next-line external-function function sendMessage( address _target, bytes memory _message, uint32 _gasLimit ) public { bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( _target, msg.sender, _message, messageNonce ); sentMessages[keccak256(xDomainCalldata)] = true; // Actually send the message. // slither-disable-next-line reentrancy-no-eth, reentrancy-events iOVM_L2ToL1MessagePasser(Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER).passMessageToL1( xDomainCalldata ); // Emit an event before we bump the nonce or the nonce will be off by one. // slither-disable-next-line reentrancy-events emit SentMessage(_target, msg.sender, _message, messageNonce, _gasLimit); // slither-disable-next-line reentrancy-no-eth messageNonce += 1; } /** * Relays a cross domain message to a contract. * @inheritdoc IL2CrossDomainMessenger */ // slither-disable-next-line external-function function relayMessage( address _target, address _sender, bytes memory _message, uint256 _messageNonce ) public { // Since it is impossible to deploy a contract to an address on L2 which matches // the alias of the L1CrossDomainMessenger, this check can only pass when it is called in // the first call from of a deposit transaction. Thus reentrancy is prevented here. require( AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1CrossDomainMessenger, "Provided message could not be verified." ); bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( _target, _sender, _message, _messageNonce ); bytes32 xDomainCalldataHash = keccak256(xDomainCalldata); require( successfulMessages[xDomainCalldataHash] == false, "Provided message has already been received." ); // Prevent calls to OVM_L2ToL1MessagePasser, which would enable // an attacker to maliciously craft the _message to spoof // a call from any L2 account. if (_target == Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER) { // Write to the successfulMessages mapping and return immediately. successfulMessages[xDomainCalldataHash] = true; return; } xDomainMsgSender = _sender; // slither-disable-next-line reentrancy-no-eth, reentrancy-events, reentrancy-benign (bool success, ) = _target.call(_message); // slither-disable-next-line reentrancy-benign xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER; // Mark the message as received if the call was successful. Ensures that a message can be // relayed multiple times in the case that the call reverted. if (success == true) { // slither-disable-next-line reentrancy-no-eth successfulMessages[xDomainCalldataHash] = true; // slither-disable-next-line reentrancy-events emit RelayedMessage(xDomainCalldataHash); } else { // slither-disable-next-line reentrancy-events emit FailedRelayedMessage(xDomainCalldataHash); } // Store an identifier that can be used to prove that the given message was relayed by some // user. Gives us an easy way to pay relayers for their work. bytes32 relayId = keccak256(abi.encodePacked(xDomainCalldata, msg.sender, block.number)); // slither-disable-next-line reentrancy-benign relayedMessages[relayId] = true; } }
contracts/L2/messaging/IL2CrossDomainMessenger.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /* Interface Imports */ import { ICrossDomainMessenger } from "../../libraries/bridge/ICrossDomainMessenger.sol"; /** * @title IL2CrossDomainMessenger */ interface IL2CrossDomainMessenger is ICrossDomainMessenger { /******************** * Public Functions * ********************/ /** * Relays a cross domain message to a contract. * @param _target Target contract address. * @param _sender Message sender address. * @param _message Message to send to the target. * @param _messageNonce Nonce for the provided message. */ function relayMessage( address _target, address _sender, bytes memory _message, uint256 _messageNonce ) external; }
contracts/L2/predeploys/iOVM_L2ToL1MessagePasser.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title iOVM_L2ToL1MessagePasser */ interface iOVM_L2ToL1MessagePasser { /********** * Events * **********/ event L2ToL1Message(uint256 _nonce, address _sender, bytes _data); /******************** * Public Functions * ********************/ function passMessageToL1(bytes calldata _message) external; }
contracts/libraries/bridge/ICrossDomainMessenger.sol
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; /** * @title ICrossDomainMessenger */ interface ICrossDomainMessenger { /********** * Events * **********/ event SentMessage( address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit ); event RelayedMessage(bytes32 indexed msgHash); event FailedRelayedMessage(bytes32 indexed msgHash); event RelayedFastMessage( address indexed target, address sender, bytes message, uint256 messageNonce ); event FailedRelayedFastMessage( address indexed target, address sender, bytes message, uint256 messageNonce ); /************* * Variables * *************/ function xDomainMessageSender() external view returns (address); /******************** * Public Functions * ********************/ /** * Sends a cross domain message to the target messenger. * @param _target Target contract address. * @param _message Message to send to the target. * @param _gasLimit Gas limit for the provided message. */ function sendMessage( address _target, bytes calldata _message, uint32 _gasLimit ) external; }
contracts/libraries/bridge/Lib_CrossDomainUtils.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_CrossDomainUtils */ library Lib_CrossDomainUtils { /** * Generates the correct cross domain calldata for a message. * @param _target Target contract address. * @param _sender Message sender address. * @param _message Message to send to the target. * @param _messageNonce Nonce for the provided message. * @return ABI encoded cross domain calldata. */ function encodeXDomainCalldata( address _target, address _sender, bytes memory _message, uint256 _messageNonce ) internal pure returns (bytes memory) { return abi.encodeWithSignature( "relayMessage(address,address,bytes,uint256)", _target, _sender, _message, _messageNonce ); } }
contracts/libraries/constants/Lib_DefaultValues.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_DefaultValues */ library Lib_DefaultValues { // The default x-domain message sender being set to a non-zero value makes // deployment a bit more expensive, but in exchange the refund on every call to // `relayMessage` by the L1 and L2 messengers will be higher. address internal constant DEFAULT_XDOMAIN_SENDER = 0x000000000000000000000000000000000000dEaD; }
contracts/libraries/constants/Lib_PredeployAddresses.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; /** * @title Lib_PredeployAddresses */ library Lib_PredeployAddresses { address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000; address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001; address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002; address payable internal constant OVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000); address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007; address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008; address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009; address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; address internal constant L2_STANDARD_TOKEN_FACTORY = 0x4200000000000000000000000000000000000012; address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013; }
contracts/standards/AddressAliasHelper.sol
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2019-2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ pragma solidity ^0.8.7; library AddressAliasHelper { uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); /// @notice Utility function that converts the address in the L1 that submitted a tx to /// the inbox to the msg.sender viewed in the L2 /// @param l1Address the address in the L1 that triggered the tx to L2 /// @return l2Address L2 address as viewed in msg.sender function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) { unchecked { l2Address = address(uint160(l1Address) + offset); } } /// @notice Utility function that converts the msg.sender viewed in the L2 to the /// address in the L1 that submitted a tx to the inbox /// @param l2Address L2 address as viewed in msg.sender /// @return l1Address the address in the L1 that triggered the tx to L2 function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) { unchecked { l1Address = address(uint160(l2Address) - offset); } } }
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":10000,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_l1CrossDomainMessenger","internalType":"address"}]},{"type":"event","name":"FailedRelayedFastMessage","inputs":[{"type":"address","name":"target","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":false},{"type":"bytes","name":"message","internalType":"bytes","indexed":false},{"type":"uint256","name":"messageNonce","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"FailedRelayedMessage","inputs":[{"type":"bytes32","name":"msgHash","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"RelayedFastMessage","inputs":[{"type":"address","name":"target","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":false},{"type":"bytes","name":"message","internalType":"bytes","indexed":false},{"type":"uint256","name":"messageNonce","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RelayedMessage","inputs":[{"type":"bytes32","name":"msgHash","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"SentMessage","inputs":[{"type":"address","name":"target","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":false},{"type":"bytes","name":"message","internalType":"bytes","indexed":false},{"type":"uint256","name":"messageNonce","internalType":"uint256","indexed":false},{"type":"uint256","name":"gasLimit","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"l1CrossDomainMessenger","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"messageNonce","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"relayMessage","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_sender","internalType":"address"},{"type":"bytes","name":"_message","internalType":"bytes"},{"type":"uint256","name":"_messageNonce","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"relayedMessages","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"sendMessage","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"bytes","name":"_message","internalType":"bytes"},{"type":"uint32","name":"_gasLimit","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"sentMessages","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"successfulMessages","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"xDomainMessageSender","inputs":[]}]
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a71198691161005b578063a71198691461012a578063b1b1b2091461014a578063cbd4ece91461016d578063ecc704281461018057600080fd5b806321d800ec1461008d5780633dbb202b146100c55780636e296e45146100da57806382e3702d14610107575b600080fd5b6100b061009b366004610826565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100d86100d3366004610942565b610197565b005b6100e26102e2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100bc565b6100b0610115366004610826565b60026020526000908152604090205460ff1681565b6005546100e29073ffffffffffffffffffffffffffffffffffffffff1681565b6100b0610158366004610826565b60016020526000908152604090205460ff1681565b6100d861017b3660046109ad565b61038b565b61018960035481565b6040519081526020016100bc565b60006101a784338560035461078d565b80516020808301919091206000908152600290915260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fcafa81dc0000000000000000000000000000000000000000000000000000000081529091507342000000000000000000000000000000000000009063cafa81dc9061023c908490600401610a89565b600060405180830381600087803b15801561025657600080fd5b505af115801561026a573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385600354866040516102bc9493929190610aa3565b60405180910390a26001600360008282546102d79190610aef565b909155505050505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1661dead141561036e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f78446f6d61696e4d65737361676553656e646572206973206e6f74207365740060448201526064015b60405180910390fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330173ffffffffffffffffffffffffffffffffffffffff161461046a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f50726f7669646564206d65737361676520636f756c64206e6f7420626520766560448201527f7269666965642e000000000000000000000000000000000000000000000000006064820152608401610365565b60006104788585858561078d565b8051602080830191909120600081815260019092526040909120549192509060ff1615610527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f50726f7669646564206d6573736167652068617320616c72656164792062656560448201527f6e2072656365697665642e0000000000000000000000000000000000000000006064820152608401610365565b73ffffffffffffffffffffffffffffffffffffffff8616734200000000000000000000000000000000000000141561059957600090815260016020819052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905550610787565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff878116919091179091556040516000918816906105f2908790610b2e565b6000604051808303816000865af19150503d806000811461062f576040519150601f19603f3d011682016040523d82523d6000602084013e610634565b606091505b5050600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801515600114156106d557600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2610701565b60405182907f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f90600090a25b600083334360405160200161071893929190610b4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815291829052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505b50505050565b6060848484846040516024016107a69493929190610b9c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60006020828403121561083857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126108a857600080fd5b813567ffffffffffffffff808211156108c3576108c3610868565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561090957610909610868565b8160405283815286602085880101111561092257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561095757600080fd5b6109608461083f565b9250602084013567ffffffffffffffff81111561097c57600080fd5b61098886828701610897565b925050604084013563ffffffff811681146109a257600080fd5b809150509250925092565b600080600080608085870312156109c357600080fd5b6109cc8561083f565b93506109da6020860161083f565b9250604085013567ffffffffffffffff8111156109f657600080fd5b610a0287828801610897565b949793965093946060013593505050565b60005b83811015610a2e578181015183820152602001610a16565b838111156107875750506000910152565b60008151808452610a57816020860160208601610a13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a9c6020830184610a3f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff85168152608060208201526000610ad26080830186610a3f565b905083604083015263ffffffff8316606083015295945050505050565b60008219821115610b29577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b60008251610b40818460208701610a13565b9190910192915050565b60008451610b5c818460208901610a13565b60609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001691909301908152601481019190915260340192915050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610bd56080830185610a3f565b90508260608301529594505050505056fea26469706673582212209e26e0d082da53f3f8c17c71ac9ad2222b021c1b86f578d12cd4fa29c86eea7964736f6c63430008090033