github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 import { Types } from "src/libraries/Types.sol"; 5 import { Hashing } from "src/libraries/Hashing.sol"; 6 import { Encoding } from "src/libraries/Encoding.sol"; 7 import { Burn } from "src/libraries/Burn.sol"; 8 import { ISemver } from "src/universal/ISemver.sol"; 9 10 /// @custom:proxied 11 /// @custom:predeploy 0x4200000000000000000000000000000000000016 12 /// @title L2ToL1MessagePasser 13 /// @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from 14 /// L2 to L1 can be stored. The storage root of this contract is pulled up to the top level 15 /// of the L2 output to reduce the cost of proving the existence of sent messages. 16 contract L2ToL1MessagePasser is ISemver { 17 /// @notice The L1 gas limit set when eth is withdrawn using the receive() function. 18 uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000; 19 20 /// @notice The current message version identifier. 21 uint16 public constant MESSAGE_VERSION = 1; 22 23 /// @notice Includes the message hashes for all withdrawals 24 mapping(bytes32 => bool) public sentMessages; 25 26 /// @notice A unique value hashed with each withdrawal. 27 uint240 internal msgNonce; 28 29 /// @notice Emitted any time a withdrawal is initiated. 30 /// @param nonce Unique value corresponding to each withdrawal. 31 /// @param sender The L2 account address which initiated the withdrawal. 32 /// @param target The L1 account address the call will be send to. 33 /// @param value The ETH value submitted for withdrawal, to be forwarded to the target. 34 /// @param gasLimit The minimum amount of gas that must be provided when withdrawing. 35 /// @param data The data to be forwarded to the target on L1. 36 /// @param withdrawalHash The hash of the withdrawal. 37 event MessagePassed( 38 uint256 indexed nonce, 39 address indexed sender, 40 address indexed target, 41 uint256 value, 42 uint256 gasLimit, 43 bytes data, 44 bytes32 withdrawalHash 45 ); 46 47 /// @notice Emitted when the balance of this contract is burned. 48 /// @param amount Amount of ETh that was burned. 49 event WithdrawerBalanceBurnt(uint256 indexed amount); 50 51 /// @custom:semver 1.1.0 52 string public constant version = "1.1.0"; 53 54 /// @notice Allows users to withdraw ETH by sending directly to this contract. 55 receive() external payable { 56 initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes("")); 57 } 58 59 /// @notice Removes all ETH held by this contract from the state. Used to prevent the amount of 60 /// ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to 61 /// create a contract and self-destruct it to itself. Anyone can call this function. Not 62 /// incentivized since this function is very cheap. 63 function burn() external { 64 uint256 balance = address(this).balance; 65 Burn.eth(balance); 66 emit WithdrawerBalanceBurnt(balance); 67 } 68 69 /// @notice Sends a message from L2 to L1. 70 /// @param _target Address to call on L1 execution. 71 /// @param _gasLimit Minimum gas limit for executing the message on L1. 72 /// @param _data Data to forward to L1 target. 73 function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) public payable { 74 bytes32 withdrawalHash = Hashing.hashWithdrawal( 75 Types.WithdrawalTransaction({ 76 nonce: messageNonce(), 77 sender: msg.sender, 78 target: _target, 79 value: msg.value, 80 gasLimit: _gasLimit, 81 data: _data 82 }) 83 ); 84 85 sentMessages[withdrawalHash] = true; 86 87 emit MessagePassed(messageNonce(), msg.sender, _target, msg.value, _gasLimit, _data, withdrawalHash); 88 89 unchecked { 90 ++msgNonce; 91 } 92 } 93 94 /// @notice Retrieves the next message nonce. Message version will be added to the upper two 95 /// bytes of the message nonce. Message version allows us to treat messages as having 96 /// different structures. 97 /// @return Nonce of the next message to be sent, with added message version. 98 function messageNonce() public view returns (uint256) { 99 return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION); 100 } 101 }