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  }