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 }