github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/L2/CrossDomainOwnable2.t.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 // Testing utilities 5 import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; 6 7 // Libraries 8 import { Hashing } from "src/libraries/Hashing.sol"; 9 import { Encoding } from "src/libraries/Encoding.sol"; 10 import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; 11 12 // Target contract dependencies 13 import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; 14 15 // Target contract 16 import { CrossDomainOwnable2 } from "src/L2/CrossDomainOwnable2.sol"; 17 18 contract XDomainSetter2 is CrossDomainOwnable2 { 19 uint256 public value; 20 21 function set(uint256 _value) external onlyOwner { 22 value = _value; 23 } 24 } 25 26 contract CrossDomainOwnable2_Test is Bridge_Initializer { 27 XDomainSetter2 setter; 28 29 /// @dev Sets up the test suite. 30 function setUp() public override { 31 super.setUp(); 32 vm.prank(alice); 33 setter = new XDomainSetter2(); 34 } 35 36 /// @dev Tests that the `onlyOwner` modifier reverts when the caller is not the messenger. 37 function test_onlyOwner_notMessenger_reverts() external { 38 vm.expectRevert("CrossDomainOwnable2: caller is not the messenger"); 39 setter.set(1); 40 } 41 42 /// @dev Tests that the `onlyOwner` modifier reverts when not called by the owner. 43 function test_onlyOwner_notOwner_reverts() external { 44 // set the xDomainMsgSender storage slot 45 bytes32 key = bytes32(uint256(204)); 46 bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice)); 47 vm.store(address(l2CrossDomainMessenger), key, value); 48 49 vm.prank(address(l2CrossDomainMessenger)); 50 vm.expectRevert("CrossDomainOwnable2: caller is not the owner"); 51 setter.set(1); 52 } 53 54 /// @dev Tests that the `onlyOwner` modifier causes the relayed message to fail. 55 function test_onlyOwner_notOwner2_reverts() external { 56 uint240 nonce = 0; 57 address sender = bob; 58 address target = address(setter); 59 uint256 value = 0; 60 uint256 minGasLimit = 0; 61 bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1); 62 63 bytes32 hash = Hashing.hashCrossDomainMessage( 64 Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message 65 ); 66 67 // It should be a failed message. The revert is caught, 68 // so we cannot expectRevert here. 69 vm.expectEmit(true, true, true, true); 70 emit FailedRelayedMessage(hash); 71 72 vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); 73 l2CrossDomainMessenger.relayMessage( 74 Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message 75 ); 76 77 assertEq(setter.value(), 0); 78 } 79 80 /// @dev Tests that the `onlyOwner` modifier succeeds when called by the messenger. 81 function test_onlyOwner_succeeds() external { 82 address owner = setter.owner(); 83 84 // Simulate the L2 execution where the call is coming from 85 // the L1CrossDomainMessenger 86 vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); 87 l2CrossDomainMessenger.relayMessage( 88 Encoding.encodeVersionedNonce(1, 1), 89 owner, 90 address(setter), 91 0, 92 0, 93 abi.encodeWithSelector(XDomainSetter2.set.selector, 2) 94 ); 95 96 assertEq(setter.value(), 2); 97 } 98 }