Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ValidatorWalletTest.t.sol #511

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions contracts/test/RollupMock.sol
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have this in
./contracts/src/test-helpers/RollupMock.sol

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.4;

contract RollupMock {
event WithdrawTriggered();
event ZombieTriggered();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused event

Suggested change
event ZombieTriggered();


function withdrawStakerFunds() external returns (uint256) {
emit WithdrawTriggered();
return 0;
}
}
164 changes: 164 additions & 0 deletions contracts/test/ValidatorWalletTest.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright 2021-2022, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.17;

import "forge-std/Test.sol";
import "../src/rollup/ValidatorWallet.sol";
import "../src/rollup/ValidatorWalletCreator.sol";
import "./RollupMock.sol";

contract ValidatorWalletTest is Test {
// Contract instances
ValidatorWalletCreator creator;
ValidatorWallet wallet;
RollupMock rollupMock1;
RollupMock rollupMock2;
Comment on lines +16 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need 2 rollup, if you want to test batching you can simply call the same rollup twice.


// Set initial executor and owner
address public executor = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
address public owner = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
Comment on lines +20 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are some very specific addresses lol usually we can just use sth like addr(1337); no big deal tho


function setUp() public {
// Create instances
creator = new ValidatorWalletCreator();
rollupMock1 = new RollupMock();
rollupMock2 = new RollupMock();

// Set up executor and owner
address[] memory initialExecutors = new address[](1);
initialExecutors[0] = executor;

// Create wallet and explicitly initialize with executor and owner
vm.prank(owner);
address walletAddress = creator.createWallet(initialExecutors);
wallet = ValidatorWallet(payable(walletAddress));
}

// Test wallet creation and executor setup
function testWalletCreation() public {
address[] memory newExecutors = new address[](1);
newExecutors[0] = executor;
bool[] memory isExecutor = new bool[](1);
isExecutor[0] = true;

// Set executor and check if it is marked as executor
vm.expectEmit(true, false, false, false);
emit ExecutorUpdated(executor, true);
vm.prank(owner);
wallet.setExecutor(newExecutors, isExecutor);
require(wallet.executors(executor), "Executor should be marked as executor");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of require(cond, reason), use assertEq(a,b,reason)

require(wallet.allowedExecutorDestinations(executor), "Executor should be allowed");
}

// Test setting allowed executor destinations
function testSetAllowedExecutorDestinations() public {
address[] memory allowedAddrs = new address[](3);
allowedAddrs[0] = address(0x1234567812345678123456781234567812345678);
allowedAddrs[1] = address(0x0000000000000000000000000000000000000000);
allowedAddrs[2] = address(0x0123000000000000000000000000000000000000);
bool[] memory isSet = new bool[](3);
isSet[0] = true;
isSet[1] = true;
isSet[2] = true;

// Set allowed executor destinations
vm.prank(owner);
wallet.setAllowedExecutorDestinations(allowedAddrs, isSet);
// Check if the set destinations are allowed
require(wallet.allowedExecutorDestinations(allowedAddrs[0]), "Address 0 should be allowed");
require(wallet.allowedExecutorDestinations(allowedAddrs[1]), "Address 1 should be allowed");
require(wallet.allowedExecutorDestinations(allowedAddrs[2]), "Address 2 should be allowed");

// Check if a non-set destination is not allowed
require(
!wallet.allowedExecutorDestinations(address(0x1114567812345678123456781234567812341111)),
"Address 0x1114567812345678123456781234567812341111 should not be allowed"
);
}

function testAllowExecutorToExecuteTxs() public {
address[] memory newExecutors = new address[](1);
newExecutors[0] = executor;
bool[] memory isExecutor = new bool[](1);
isExecutor[0] = true;
address[] memory destinationAddrs = new address[](1);
destinationAddrs[0] = address(rollupMock1);
bool[] memory isSet = new bool[](1);
isSet[0] = true;
bytes memory data = abi.encodeWithSignature("withdrawStakerFunds()");

// Set executor
vm.prank(owner);
wallet.setExecutor(newExecutors, isExecutor);
// Expect the transaction to revert with a specific error message when called by the executor
vm.expectRevert(abi.encodeWithSelector(OnlyOwnerDestination.selector, owner, executor, address(rollupMock1)));
vm.prank(executor);
wallet.executeTransaction(data, address(rollupMock1), 0);

vm.expectEmit(false, false, false, false);
// Expecet the transaction to go through when called by owenr
emit WithdrawTriggered();
vm.prank(owner);
wallet.executeTransaction(data, address(rollupMock1), 0);

vm.prank(owner);
// Set allowed executor destinations using the provided arrays
wallet.setAllowedExecutorDestinations(destinationAddrs, isSet);

// Expect the transaction to go through when called by the executor
emit WithdrawTriggered();
vm.prank(executor);
wallet.executeTransaction(data, address(rollupMock1), 0);
}

function testRejectBatchIfSingleTxNotAllowed() external {
address[] memory addrs = new address[](1);
addrs[0] = executor;
bool[] memory isExecutor = new bool[](1);
isExecutor[0] = true;

// Encode function data for 'withdrawStakerFunds' in RollupMock
bytes memory data1 = abi.encodeWithSignature("withdrawStakerFunds()");
bytes memory data2 = abi.encodeWithSignature("withdrawStakerFunds()");

bytes[] memory data = new bytes[](2);
data[0] = data1;
data[1] = data2;

uint256[] memory amount = new uint256[](2);
amount[0] = 0;
amount[1] = 0;

// Set allowed executor destinations in wallet
address[] memory destination_addrs = new address[](2);
destination_addrs[0] = address(rollupMock1);
destination_addrs[1] = address(rollupMock2);
bool[] memory isSet = new bool[](2);
isSet[0] = true;
isSet[1] = false;

// Set executor
vm.prank(owner);
wallet.setExecutor(addrs, isExecutor);

// Set allowed executor destinations using the provided arrays
vm.prank(owner);
wallet.setAllowedExecutorDestinations(destination_addrs, isSet);

// Expect the transaction to revert with a specific error message when called by the executor
vm.expectRevert(abi.encodeWithSelector(OnlyOwnerDestination.selector, owner, executor, address(rollupMock2)));
vm.prank(executor);
wallet.executeTransactions(data, destination_addrs, amount);
}

/**
*
* Event declarations
*
*/

event WithdrawTriggered();
event ExecutorUpdated(address indexed executor, bool isExecutor);
}
Loading