-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adds ArbitrumCrossDomainForwarder foundry tests
- Loading branch information
1 parent
e9b0e56
commit edd4bfc
Showing
1 changed file
with
197 additions
and
0 deletions.
There are no files selected for viewing
197 changes: 197 additions & 0 deletions
197
contracts/src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainForwarder.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import {ArbitrumCrossDomainForwarder} from "../../../dev/arbitrum/ArbitrumCrossDomainForwarder.sol"; | ||
import {Greeter} from "../../../../../v0.8/tests/Greeter.sol"; | ||
import {L2EPTest} from "../L2EPTest.t.sol"; | ||
|
||
// Use this command from the /contracts directory to run this test file: | ||
// | ||
// FOUNDRY_PROFILE=l2ep forge test -vvv --match-path ./src/v0.8/l2ep/test/v1_0_0/arbitrum/ArbitrumCrossDomainForwarder.t.sol | ||
// | ||
contract ArbitrumCrossDomainForwarderTest is L2EPTest { | ||
/// Helper variables | ||
address internal s_strangerAddr = vm.addr(0x1); | ||
address internal s_l1OwnerAddr = vm.addr(0x2); | ||
address internal s_crossDomainMessengerAddr = toArbitrumL2AliasAddress(s_l1OwnerAddr); | ||
address internal s_newOwnerCrossDomainMessengerAddr = toArbitrumL2AliasAddress(s_strangerAddr); | ||
|
||
/// Contracts | ||
ArbitrumCrossDomainForwarder internal s_arbitrumCrossDomainForwarder; | ||
Greeter internal s_greeter; | ||
|
||
/// Events | ||
event L1OwnershipTransferRequested(address indexed from, address indexed to); | ||
event L1OwnershipTransferred(address indexed from, address indexed to); | ||
|
||
/// Setup | ||
function setUp() public { | ||
// Deploys contracts | ||
vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); | ||
s_arbitrumCrossDomainForwarder = new ArbitrumCrossDomainForwarder(s_l1OwnerAddr); | ||
s_greeter = new Greeter(address(s_arbitrumCrossDomainForwarder)); | ||
vm.stopPrank(); | ||
} | ||
|
||
/// @param l1Address - Address on L1 | ||
/// @return an Arbitrum L2 address | ||
function toArbitrumL2AliasAddress(address l1Address) public pure returns (address) { | ||
return address(uint160(l1Address) + uint160(0x1111000000000000000000000000000000001111)); | ||
} | ||
} | ||
|
||
contract Constructor is ArbitrumCrossDomainForwarderTest { | ||
/// @notice it should set the owner correctly | ||
function test_Owner() public { | ||
assertEq(s_arbitrumCrossDomainForwarder.owner(), s_l1OwnerAddr); | ||
} | ||
|
||
/// @notice it should set the l1Owner correctly | ||
function test_L1Owner() public { | ||
assertEq(s_arbitrumCrossDomainForwarder.l1Owner(), s_l1OwnerAddr); | ||
} | ||
|
||
/// @notice it should set the crossdomain messenger correctly | ||
function test_CrossDomainMessenger() public { | ||
assertEq(s_arbitrumCrossDomainForwarder.crossDomainMessenger(), s_crossDomainMessengerAddr); | ||
} | ||
|
||
/// @notice it should set the typeAndVersion correctly | ||
function test_TypeAndVersion() public { | ||
assertEq(s_arbitrumCrossDomainForwarder.typeAndVersion(), "ArbitrumCrossDomainForwarder 1.0.0"); | ||
} | ||
} | ||
|
||
contract Forward is ArbitrumCrossDomainForwarderTest { | ||
/// @notice it should not be callable by unknown address | ||
function test_NotCallableByUnknownAddress() public { | ||
vm.startPrank(s_strangerAddr, s_strangerAddr); | ||
vm.expectRevert("Sender is not the L2 messenger"); | ||
s_arbitrumCrossDomainForwarder.forward(address(s_greeter), abi.encode("")); | ||
vm.stopPrank(); | ||
} | ||
|
||
/// @notice it should be callable by crossdomain messenger address / L1 owner | ||
function test_Forward() public { | ||
// Sets msg.sender and tx.origin | ||
vm.startPrank(s_crossDomainMessengerAddr, s_crossDomainMessengerAddr); | ||
|
||
// Defines the cross domain message to send | ||
string memory greeting = "hello"; | ||
|
||
// Sends the message | ||
s_arbitrumCrossDomainForwarder.forward( | ||
address(s_greeter), | ||
abi.encodeWithSelector(s_greeter.setGreeting.selector, greeting) | ||
); | ||
|
||
// Checks that the greeter got the message | ||
assertEq(s_greeter.greeting(), greeting); | ||
|
||
// Resets msg.sender and tx.origin | ||
vm.stopPrank(); | ||
} | ||
|
||
/// @notice it should revert when contract call reverts | ||
function test_ForwardRevert() public { | ||
// Sets msg.sender and tx.origin | ||
vm.startPrank(s_crossDomainMessengerAddr, s_crossDomainMessengerAddr); | ||
|
||
// Sends an invalid message | ||
vm.expectRevert("Invalid greeting length"); | ||
s_arbitrumCrossDomainForwarder.forward( | ||
address(s_greeter), | ||
abi.encodeWithSelector(s_greeter.setGreeting.selector, "") | ||
); | ||
|
||
// Resets msg.sender and tx.origin | ||
vm.stopPrank(); | ||
} | ||
} | ||
|
||
contract TransferL1Ownership is ArbitrumCrossDomainForwarderTest { | ||
/// @notice it should not be callable by non-owners | ||
function test_NotCallableByNonOwners() public { | ||
vm.startPrank(s_strangerAddr, s_strangerAddr); | ||
vm.expectRevert("Sender is not the L2 messenger"); | ||
s_arbitrumCrossDomainForwarder.transferL1Ownership(s_strangerAddr); | ||
vm.stopPrank(); | ||
} | ||
|
||
/// @notice it should not be callable by L2 owner | ||
function test_NotCallableByL2Owner() public { | ||
vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); | ||
assertEq(s_arbitrumCrossDomainForwarder.owner(), s_l1OwnerAddr); | ||
vm.expectRevert("Sender is not the L2 messenger"); | ||
s_arbitrumCrossDomainForwarder.transferL1Ownership(s_strangerAddr); | ||
vm.stopPrank(); | ||
} | ||
|
||
/// @notice it should be callable by current L1 owner | ||
function test_CallableByL1Owner() public { | ||
// Sets msg.sender and tx.origin | ||
vm.startPrank(s_crossDomainMessengerAddr, s_crossDomainMessengerAddr); | ||
|
||
// Defines the cross domain message to send | ||
vm.expectEmit(false, false, false, true); | ||
emit L1OwnershipTransferRequested(s_arbitrumCrossDomainForwarder.l1Owner(), s_strangerAddr); | ||
|
||
// Sends the message | ||
s_arbitrumCrossDomainForwarder.transferL1Ownership(s_strangerAddr); | ||
|
||
// Resets msg.sender and tx.origin | ||
vm.stopPrank(); | ||
} | ||
|
||
/// @notice it should be callable by current L1 owner to zero address | ||
function test_CallableByL1OwnerOrZeroAddress() public { | ||
// Sets msg.sender and tx.origin | ||
vm.startPrank(s_crossDomainMessengerAddr, s_crossDomainMessengerAddr); | ||
|
||
// Defines the cross domain message to send | ||
vm.expectEmit(false, false, false, true); | ||
emit L1OwnershipTransferRequested(s_arbitrumCrossDomainForwarder.l1Owner(), address(0)); | ||
|
||
// Sends the message | ||
s_arbitrumCrossDomainForwarder.transferL1Ownership(address(0)); | ||
|
||
// Resets msg.sender and tx.origin | ||
vm.stopPrank(); | ||
} | ||
} | ||
|
||
contract AcceptL1Ownership is ArbitrumCrossDomainForwarderTest { | ||
/// @notice it should not be callable by non pending-owners | ||
function test_NotCallableByNonPendingOwners() public { | ||
// Sets msg.sender and tx.origin | ||
vm.startPrank(s_crossDomainMessengerAddr, s_crossDomainMessengerAddr); | ||
|
||
// Sends the message | ||
vm.expectRevert("Must be proposed L1 owner"); | ||
s_arbitrumCrossDomainForwarder.acceptL1Ownership(); | ||
|
||
// Resets msg.sender and tx.origin | ||
vm.stopPrank(); | ||
} | ||
|
||
/// @notice it should be callable by pending L1 owner | ||
function test_CallableByPendingL1Owner() public { | ||
// Request ownership transfer | ||
vm.startPrank(s_crossDomainMessengerAddr, s_crossDomainMessengerAddr); | ||
s_arbitrumCrossDomainForwarder.transferL1Ownership(s_strangerAddr); | ||
|
||
// Prepares expected event payload | ||
vm.expectEmit(false, false, false, true); | ||
emit L1OwnershipTransferred(s_l1OwnerAddr, s_strangerAddr); | ||
|
||
// Accepts ownership transfer request | ||
vm.startPrank(s_newOwnerCrossDomainMessengerAddr, s_newOwnerCrossDomainMessengerAddr); | ||
s_arbitrumCrossDomainForwarder.acceptL1Ownership(); | ||
|
||
// Asserts that the ownership was actually transferred | ||
assertEq(s_arbitrumCrossDomainForwarder.l1Owner(), s_strangerAddr); | ||
|
||
// Resets msg.sender and tx.origin | ||
vm.stopPrank(); | ||
} | ||
} |