github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  // Testing utilities
     5  import { CommonTest } from "test/setup/CommonTest.sol";
     6  
     7  // Libraries
     8  import { Types } from "src/libraries/Types.sol";
     9  import { Hashing } from "src/libraries/Hashing.sol";
    10  
    11  contract L2ToL1MessagePasserTest is CommonTest {
    12      /// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state
    13      ///      of the message passer for the withdrawal hash.
    14      function testFuzz_initiateWithdrawal_succeeds(
    15          address _sender,
    16          address _target,
    17          uint256 _value,
    18          uint256 _gasLimit,
    19          bytes memory _data
    20      )
    21          external
    22      {
    23          uint256 nonce = l2ToL1MessagePasser.messageNonce();
    24  
    25          bytes32 withdrawalHash = Hashing.hashWithdrawal(
    26              Types.WithdrawalTransaction({
    27                  nonce: nonce,
    28                  sender: _sender,
    29                  target: _target,
    30                  value: _value,
    31                  gasLimit: _gasLimit,
    32                  data: _data
    33              })
    34          );
    35  
    36          vm.expectEmit(address(l2ToL1MessagePasser));
    37          emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);
    38  
    39          vm.deal(_sender, _value);
    40          vm.prank(_sender);
    41          l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);
    42  
    43          assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true);
    44  
    45          bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));
    46  
    47          assertEq(vm.load(address(l2ToL1MessagePasser), slot), bytes32(uint256(1)));
    48      }
    49  
    50      /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed
    51      ///      log when called by a contract.
    52      function testFuzz_initiateWithdrawal_fromContract_succeeds(
    53          address _target,
    54          uint256 _gasLimit,
    55          uint256 _value,
    56          bytes memory _data
    57      )
    58          external
    59      {
    60          bytes32 withdrawalHash = Hashing.hashWithdrawal(
    61              Types.WithdrawalTransaction({
    62                  nonce: l2ToL1MessagePasser.messageNonce(),
    63                  sender: address(this),
    64                  target: _target,
    65                  value: _value,
    66                  gasLimit: _gasLimit,
    67                  data: _data
    68              })
    69          );
    70  
    71          vm.expectEmit(address(l2ToL1MessagePasser));
    72          emit MessagePassed(
    73              l2ToL1MessagePasser.messageNonce(), address(this), _target, _value, _gasLimit, _data, withdrawalHash
    74          );
    75  
    76          vm.deal(address(this), _value);
    77          l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);
    78      }
    79  
    80      /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed
    81      ///      log when called by an EOA.
    82      function testFuzz_initiateWithdrawal_fromEOA_succeeds(
    83          uint256 _gasLimit,
    84          address _target,
    85          uint256 _value,
    86          bytes memory _data
    87      )
    88          external
    89      {
    90          uint256 nonce = l2ToL1MessagePasser.messageNonce();
    91  
    92          // EOA emulation
    93          vm.prank(alice, alice);
    94          vm.deal(alice, _value);
    95          bytes32 withdrawalHash =
    96              Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, _target, _value, _gasLimit, _data));
    97  
    98          vm.expectEmit(address(l2ToL1MessagePasser));
    99          emit MessagePassed(nonce, alice, _target, _value, _gasLimit, _data, withdrawalHash);
   100  
   101          l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data });
   102  
   103          // the sent messages mapping is filled
   104          assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true);
   105          // the nonce increments
   106          assertEq(nonce + 1, l2ToL1MessagePasser.messageNonce());
   107      }
   108  
   109      /// @dev Tests that `burn` succeeds and destroys the ETH held in the contract.
   110      function testFuzz_burn_succeeds(uint256 _value, address _target, uint256 _gasLimit, bytes memory _data) external {
   111          vm.deal(address(this), _value);
   112  
   113          l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data });
   114  
   115          assertEq(address(l2ToL1MessagePasser).balance, _value);
   116          emit WithdrawerBalanceBurnt(_value);
   117          l2ToL1MessagePasser.burn();
   118  
   119          // The Withdrawer should have no balance
   120          assertEq(address(l2ToL1MessagePasser).balance, 0);
   121      }
   122  }