diff --git a/src/fps/example/task-00/testnetConfig.toml b/src/fps/example/task-00/testnetConfig.toml deleted file mode 100644 index 138490772..000000000 --- a/src/fps/example/task-00/testnetConfig.toml +++ /dev/null @@ -1,5 +0,0 @@ -# this is the file used to determine the network configuration for the testnet task -l2chains = [{"name": "Mode Testnet", "chainId": 919}, {"name": "Metal L2 Testnet", "chainId": 1740}, {"name": "Zora Sepolia Testnet", "chainId": 999999999}] - -[gasConfigs] -gasLimits = [{chainId = 919, gasLimit = 100000000}, {chainId = 1740, gasLimit = 100000000}, {chainId = 999999999, gasLimit = 100000000}] \ No newline at end of file diff --git a/src/fps/example/template/GasConfigTemplate.sol b/src/fps/example/template/GasConfigTemplate.sol index d67c1a9ba..72d17854f 100644 --- a/src/fps/example/template/GasConfigTemplate.sol +++ b/src/fps/example/template/GasConfigTemplate.sol @@ -28,7 +28,7 @@ contract GasConfigTemplate is MultisigTask { /// @notice Returns the storage write permissions required for this task /// @return Array of storage write permissions - function _taskStorageWrites() internal pure override returns (string[] memory) { + function _taskStorageWrites() internal pure virtual override returns (string[] memory) { string[] memory storageWrites = new string[](1); storageWrites[0] = "SystemConfigProxy"; return storageWrites; diff --git a/src/fps/task/MultisigTask.sol b/src/fps/task/MultisigTask.sol index bdcf2a9dd..caf3af08d 100644 --- a/src/fps/task/MultisigTask.sol +++ b/src/fps/task/MultisigTask.sol @@ -194,9 +194,9 @@ abstract contract MultisigTask is Test, Script, ITask { multisig == addresses.getAddress(config.safeAddressString, chains[i].chainId), string.concat( "MultisigTask: safe address mismatch. Caller: ", - vm.getLabel(multisig), + getAddressLabel(multisig), ". Actual address: ", - vm.getLabel(addresses.getAddress(config.safeAddressString, chains[i].chainId)) + getAddressLabel(addresses.getAddress(config.safeAddressString, chains[i].chainId)) ) ); } @@ -250,7 +250,7 @@ abstract contract MultisigTask is Test, Script, ITask { /// @notice print the data to sig by EOA for single multisig function printDataToSign() public view { - console.logBytes(_getDataToSign(multisig, getCalldata())); + console.logBytes(getDataToSign(multisig, getCalldata())); } /// @notice print the hash to approve by EOA for single multisig @@ -261,7 +261,7 @@ abstract contract MultisigTask is Test, Script, ITask { /// @notice get the data to sign by EOA for single multisig /// @param data The calldata to be executed /// @return The data to sign - function _getDataToSign(address safe, bytes memory data) internal view returns (bytes memory) { + function getDataToSign(address safe, bytes memory data) public view returns (bytes memory) { uint256 useNonce; if (safe == multisig) { @@ -339,7 +339,7 @@ abstract contract MultisigTask is Test, Script, ITask { _allowedStorageAccesses.contains(addr), string( abi.encodePacked( - "MultisigTask: address ", _getAddressLabel(addr), " not in allowed storage accesses" + "MultisigTask: address ", getAddressLabel(addr), " not in allowed storage accesses" ) ) ); @@ -352,7 +352,7 @@ abstract contract MultisigTask is Test, Script, ITask { _taskStateChangeAddresses.contains(addr), string( abi.encodePacked( - "MultisigTask: address ", _getAddressLabel(addr), " not in task state change addresses" + "MultisigTask: address ", getAddressLabel(addr), " not in task state change addresses" ) ) ); @@ -429,7 +429,7 @@ abstract contract MultisigTask is Test, Script, ITask { console.log("\n------------------ Task Actions ------------------"); for (uint256 i; i < actions.length; i++) { console.log("%d). %s", i + 1, actions[i].description); - console.log("target: %s\npayload", _getAddressLabel(actions[i].target)); + console.log("target: %s\npayload", getAddressLabel(actions[i].target)); console.logBytes(actions[i].arguments); console.log("\n"); } @@ -441,7 +441,7 @@ abstract contract MultisigTask is Test, Script, ITask { for (uint256 i; i < _taskTransferFromAddresses.length(); i++) { address account = _taskTransferFromAddresses.at(i); - console.log("\n\n", string(abi.encodePacked(_getAddressLabel(account), ":"))); + console.log("\n\n", string.concat(getAddressLabel(account), ":")); // print token transfers TransferInfo[] memory transfers = _taskTransfers[account]; @@ -453,7 +453,7 @@ abstract contract MultisigTask is Test, Script, ITask { console.log( string( abi.encodePacked( - "Sent ", vm.toString(transfers[j].value), " ETH to ", _getAddressLabel(transfers[j].to) + "Sent ", vm.toString(transfers[j].value), " ETH to ", getAddressLabel(transfers[j].to) ) ) ); @@ -464,9 +464,9 @@ abstract contract MultisigTask is Test, Script, ITask { "Sent ", vm.toString(transfers[j].value), " ", - _getAddressLabel(transfers[j].tokenAddress), + getAddressLabel(transfers[j].tokenAddress), " to ", - _getAddressLabel(transfers[j].to) + getAddressLabel(transfers[j].to) ) ) ); @@ -480,7 +480,7 @@ abstract contract MultisigTask is Test, Script, ITask { address account = _taskStateChangeAddresses.at(k); StateInfo[] memory stateChanges = _stateInfos[account]; if (stateChanges.length > 0) { - console.log("\n State Changes for account:", _getAddressLabel(account)); + console.log("\n State Changes for account:", getAddressLabel(account)); } for (uint256 j; j < stateChanges.length; j++) { console.log("Slot:", vm.toString(stateChanges[j].slot)); @@ -508,21 +508,21 @@ abstract contract MultisigTask is Test, Script, ITask { /// @notice print the data to sign by EOA for nested multisig function printNestedDataToSign() public view { - bytes memory callData = _generateApproveMulticallData(); + bytes memory callData = generateApproveMulticallData(); for (uint256 i; i < startingOwners.length; i++) { - bytes memory dataToSign = _getDataToSign(startingOwners[i], callData); - console.log("Nested multisig: %s", _getAddressLabel(startingOwners[i])); + bytes memory dataToSign = getDataToSign(startingOwners[i], callData); + console.log("Nested multisig: %s", getAddressLabel(startingOwners[i])); console.logBytes(dataToSign); } } /// @notice print the hash to approve by EOA for nested multisig function printNestedHashToApprove() public view { - bytes memory callData = _generateApproveMulticallData(); + bytes memory callData = generateApproveMulticallData(); for (uint256 i; i < startingOwners.length; i++) { - bytes32 hash = keccak256(_getDataToSign(startingOwners[i], callData)); - console.log("Nested multisig: %s", _getAddressLabel(startingOwners[i])); + bytes32 hash = keccak256(getDataToSign(startingOwners[i], callData)); + console.log("Nested multisig: %s", getAddressLabel(startingOwners[i])); console.logBytes32(hash); } } @@ -535,9 +535,9 @@ abstract contract MultisigTask is Test, Script, ITask { /// @notice get the hash for this safe transaction /// can only be called after the build function, otherwise it reverts - function getHash() internal view returns (bytes32) { + function getHash() public view returns (bytes32) { bytes memory data = getCalldata(); - return keccak256(_getDataToSign(multisig, data)); + return keccak256(getDataToSign(multisig, data)); } /// @notice validate actions inclusion @@ -555,7 +555,7 @@ abstract contract MultisigTask is Test, Script, ITask { } /// @notice helper function to generate the approveHash calldata to be executed by child multisig owner on parent multisig - function _generateApproveMulticallData() internal view returns (bytes memory) { + function generateApproveMulticallData() public view returns (bytes memory) { bytes32 hash = getHash(); Call3Value memory call = Call3Value({ target: multisig, @@ -641,7 +641,7 @@ abstract contract MultisigTask is Test, Script, ITask { description: string( abi.encodePacked( "calling ", - _getAddressLabel(accountAccesses[i].account), + getAddressLabel(accountAccesses[i].account), " with ", vm.toString(accountAccesses[i].value), " eth and ", @@ -747,7 +747,7 @@ abstract contract MultisigTask is Test, Script, ITask { } /// @notice helper method to get labels for addresses - function _getAddressLabel(address contractAddress) internal view returns (string memory) { + function getAddressLabel(address contractAddress) public view returns (string memory) { string memory label = vm.getLabel(contractAddress); bytes memory prefix = bytes("unlabeled:"); diff --git a/test/.gitkeep b/test/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/AddressRegistry.t.sol b/test/registry/AddressRegistry.t.sol similarity index 98% rename from test/AddressRegistry.t.sol rename to test/registry/AddressRegistry.t.sol index 9629700b7..20bef24a0 100644 --- a/test/AddressRegistry.t.sol +++ b/test/registry/AddressRegistry.t.sol @@ -126,7 +126,7 @@ contract MainnetAddressRegistryTest is Test { /// Construction failure tests function testInvalidChainIdInSuperchainsFails() public { - string memory networkConfigFilePath = "test/mock/invalidChainIdNetworkConfig.toml"; + string memory networkConfigFilePath = "test/registry/mock/invalidChainIdNetworkConfig.toml"; vm.expectRevert("Invalid chain ID in config"); new AddressRegistry(networkConfigFilePath); diff --git a/test/mock/invalidChainIdNetworkConfig.toml b/test/registry/mock/invalidChainIdNetworkConfig.toml similarity index 100% rename from test/mock/invalidChainIdNetworkConfig.toml rename to test/registry/mock/invalidChainIdNetworkConfig.toml diff --git a/test/task/NestedMultisigTask.t.sol b/test/task/NestedMultisigTask.t.sol new file mode 100644 index 000000000..7d60a4663 --- /dev/null +++ b/test/task/NestedMultisigTask.t.sol @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {IGnosisSafe, Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; +import {IMulticall3} from "forge-std/interfaces/IMulticall3.sol"; +import {Test} from "forge-std/Test.sol"; + +import {MultisigTask} from "src/fps/task/MultisigTask.sol"; +import {MULTICALL3_ADDRESS} from "src/fps/utils/Constants.sol"; +import {DisputeGameUpgradeTemplate} from "src/fps/example/template/DisputeGameUpgradeTemplate.sol"; +import {AddressRegistry as Addresses} from "src/fps/AddressRegistry.sol"; + +/// @notice This test is used to test the nested multisig task. +contract NestedMultisigTaskTest is Test { + MultisigTask private multisigTask; + Addresses private addresses; + /// ProxyAdminOwner safe for task-01 is a nested multisig for Op mainnet L2 chain. + string taskConfigFilePath = "src/fps/example/task-01/mainnetConfig.toml"; + + function setUp() public { + vm.createSelectFork("mainnet"); + multisigTask = new DisputeGameUpgradeTemplate(); + multisigTask.run(taskConfigFilePath); + addresses = multisigTask.addresses(); + } + + function testSafeNested() public view { + assertEq(multisigTask.isNestedSafe(), true, "Expected isNestedSafe to be false"); + } + + function testNestedDataToSignAndHashToApprove() public view { + IGnosisSafe parentMultisig = IGnosisSafe(multisigTask.multisig()); + address[] memory childOwnerMultisigs = parentMultisig.getOwners(); + + /// child multisigs have to approve the transaction that the parent multisig is going to execute. + /// hashToApproveByChildMultisig is the hash of the transaction that the parent multisig is going + /// to execute which the child multisigs have to approve. + /// nonce is decremented by 1 because when we ran the task, in simulation, execTransaction is called + /// which increments the nonce by 1 and we want to generate the hash by using the nonce before it was incremented. + bytes32 hashToApproveByChildMultisig = parentMultisig.getTransactionHash( + MULTICALL3_ADDRESS, + 0, + multisigTask.getCalldata(), + Enum.Operation.DelegateCall, + 0, + 0, + 0, + address(0), + address(0), + parentMultisig.nonce() - 1 + ); + + IMulticall3.Call3Value memory call = IMulticall3.Call3Value({ + target: address(parentMultisig), + allowFailure: false, + value: 0, + callData: abi.encodeCall(parentMultisig.approveHash, (hashToApproveByChildMultisig)) + }); + + IMulticall3.Call3Value[] memory calls = new IMulticall3.Call3Value[](1); + calls[0] = call; + + /// callDataToApprove is the data that the child multisig has to execute to + /// approve the transaction that the parent multisig is going to execute. + bytes memory callDataToApprove = + abi.encodeWithSignature("aggregate3Value((address,bool,uint256,bytes)[])", calls); + assertEq(callDataToApprove, multisigTask.generateApproveMulticallData(), "Wrong callDataToApprove"); + for (uint256 i; i < childOwnerMultisigs.length; i++) { + /// dataToSign is the data that the EOA owners of the child multisig has to sign to help + /// execute the child multisig approval of hashToApproveByChildMultisig + bytes memory dataToSign = getNestedDataToSign(childOwnerMultisigs[i]); + /// nonce is not decremented by 1 because in task simulation approveHash is called by + /// the child multisig which does not increment the nonce + bytes memory expectedDataToSign = IGnosisSafe(childOwnerMultisigs[i]).encodeTransactionData({ + to: MULTICALL3_ADDRESS, + value: 0, + data: callDataToApprove, + operation: Enum.Operation.DelegateCall, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: address(0), + _nonce: IGnosisSafe(childOwnerMultisigs[i]).nonce() + }); + assertEq(dataToSign, expectedDataToSign, "Wrong data to sign"); + + /// nestedHashToApprove is the hash that the EOA owners of the child multisig has to approve to help + /// execute the child multisig approval of hashToApproveByChildMultisig + bytes32 nestedHashToApprove = keccak256(dataToSign); + bytes32 expectedNestedHashToApprove = IGnosisSafe(childOwnerMultisigs[i]).getTransactionHash( + MULTICALL3_ADDRESS, + 0, + callDataToApprove, + Enum.Operation.DelegateCall, + 0, + 0, + 0, + address(0), + address(0), + IGnosisSafe(childOwnerMultisigs[i]).nonce() + ); + assertEq(nestedHashToApprove, expectedNestedHashToApprove, "Wrong nested hash to approve"); + } + } + + function getNestedDataToSign(address owner) public view returns (bytes memory) { + bytes memory callData = multisigTask.generateApproveMulticallData(); + return multisigTask.getDataToSign(owner, callData); + } +} diff --git a/test/task/SingleMultisigTask.t.sol b/test/task/SingleMultisigTask.t.sol new file mode 100644 index 000000000..981475d3e --- /dev/null +++ b/test/task/SingleMultisigTask.t.sol @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {Test} from "forge-std/Test.sol"; + +import {AddressRegistry as Addresses} from "src/fps/AddressRegistry.sol"; +import {MultisigTask} from "src/fps/task/MultisigTask.sol"; +import {GasConfigTemplate} from "src/fps/example/template/GasConfigTemplate.sol"; +import {IncorrectGasConfigTemplate1} from "test/task/mock/IncorrectGasConfigTemplate1.sol"; +import {IncorrectGasConfigTemplate2} from "test/task/mock/IncorrectGasConfigTemplate2.sol"; +import {IMulticall3} from "forge-std/interfaces/IMulticall3.sol"; +import {IGnosisSafe, Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; +import {MULTICALL3_ADDRESS} from "src/fps/utils/Constants.sol"; + +contract SingleMultisigTaskTest is Test { + MultisigTask private multisigTask; + Addresses private addresses; + + /// @notice ProxyAdminOwner safe for task-00 is a single multisig. + string taskConfigFilePath = "src/fps/example/task-00/mainnetConfig.toml"; + + function setUp() public { + vm.createSelectFork("mainnet"); + } + + function runTask() public { + multisigTask = new GasConfigTemplate(); + multisigTask.run(taskConfigFilePath); + } + + function testTemplateSetup() public { + runTask(); + assertEq(GasConfigTemplate(address(multisigTask)).gasLimits(291), 100000000, "Expected gas limit for 291"); + assertEq(GasConfigTemplate(address(multisigTask)).gasLimits(1750), 100000000, "Expected gas limit for 1750"); + } + + function testSafeSetup() public { + runTask(); + addresses = multisigTask.addresses(); + assertEq(multisigTask.multisig(), addresses.getAddress("SystemConfigOwner", 291), "Wrong safe address string"); + assertEq(multisigTask.multisig(), addresses.getAddress("SystemConfigOwner", 1750), "Wrong safe address string"); + assertEq(multisigTask.isNestedSafe(), false, "Expected isNestedSafe to be false"); + } + + function testAllowedStorageWrites() public { + runTask(); + addresses = multisigTask.addresses(); + address[] memory allowedStorageAccesses = multisigTask.getAllowedStorageAccess(); + assertEq( + allowedStorageAccesses[0], + addresses.getAddress("SystemConfigProxy", 291), + "Wrong storage write access address" + ); + assertEq( + allowedStorageAccesses[1], + addresses.getAddress("SystemConfigProxy", 1750), + "Wrong storage write access address" + ); + } + + function testBuild() public { + MultisigTask localMultisigTask = new GasConfigTemplate(); + + vm.expectRevert("No actions found"); + localMultisigTask.getTaskActions(); + + localMultisigTask.run(taskConfigFilePath); + + addresses = localMultisigTask.addresses(); + + (address[] memory targets, uint256[] memory values, bytes[] memory arguments) = + localMultisigTask.getTaskActions(); + + assertEq(targets.length, 2, "Expected 2 targets"); + assertEq(targets[0], addresses.getAddress("SystemConfigProxy", 291), "Expected SystemConfigProxy target"); + assertEq(targets[1], addresses.getAddress("SystemConfigProxy", 1750), "Expected SystemConfigProxy target"); + assertEq(values.length, 2, "Expected 2 values"); + assertEq(values[0], 0, "Expected 0 value"); + assertEq(values[1], 0, "Expected 0 value"); + assertEq(arguments.length, 2, "Expected 2 arguments"); + assertEq(arguments[0], abi.encodeWithSignature("setGasLimit(uint64)", uint64(100000000)), "Wrong calldata"); + assertEq(arguments[1], abi.encodeWithSignature("setGasLimit(uint64)", uint64(100000000)), "Wrong calldata"); + } + + function testGetCallData() public { + runTask(); + + (address[] memory targets, uint256[] memory values, bytes[] memory arguments) = multisigTask.getTaskActions(); + + IMulticall3.Call3Value[] memory calls = new IMulticall3.Call3Value[](targets.length); + + for (uint256 i = 0; i < targets.length; i++) { + calls[i] = IMulticall3.Call3Value({ + target: targets[i], + allowFailure: false, + value: values[i], + callData: arguments[i] + }); + } + + bytes memory expectedCallData = + abi.encodeWithSignature("aggregate3Value((address,bool,uint256,bytes)[])", calls); + + bytes memory callData = multisigTask.getCalldata(); + assertEq(callData, expectedCallData, "Wrong calldata"); + } + + function testGetDataToSign() public { + runTask(); + addresses = multisigTask.addresses(); + bytes memory callData = multisigTask.getCalldata(); + bytes memory dataToSign = multisigTask.getDataToSign(multisigTask.multisig(), callData); + + /// The nonce is decremented by 1 because we want to recreate the data to sign with the same nonce + /// that was used in the simulation. The nonce was incremented as part of running the simulation. + bytes memory expectedDataToSign = IGnosisSafe(multisigTask.multisig()).encodeTransactionData({ + to: MULTICALL3_ADDRESS, + value: 0, + data: callData, + operation: Enum.Operation.DelegateCall, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: address(0), + _nonce: IGnosisSafe(multisigTask.multisig()).nonce() - 1 + }); + assertEq(dataToSign, expectedDataToSign, "Wrong data to sign"); + } + + function testHashToApprove() public { + runTask(); + bytes memory callData = multisigTask.getCalldata(); + bytes32 hash = multisigTask.getHash(); + bytes32 expectedHash = IGnosisSafe(multisigTask.multisig()).getTransactionHash( + MULTICALL3_ADDRESS, + 0, + callData, + Enum.Operation.DelegateCall, + 0, + 0, + 0, + address(0), + address(0), + IGnosisSafe(multisigTask.multisig()).nonce() - 1 + ); + assertEq(hash, expectedHash, "Wrong hash to approve"); + } + + function testRevertIfReInitialised() public { + runTask(); + vm.expectRevert("MultisigTask: already initialized"); + multisigTask.run(taskConfigFilePath); + } + + function testRevertIfUnsupportedChain() public { + vm.chainId(10); + MultisigTask localMultisigTask = new GasConfigTemplate(); + vm.expectRevert("Unsupported network"); + localMultisigTask.run(taskConfigFilePath); + } + + function testRevertIfDifferentL2SafeAddresses() public { + string memory incorrectTaskConfigFilePath = "test/task/mock/IncorrectMainnetConfig.toml"; + MultisigTask localMultisigTask = new GasConfigTemplate(); + Addresses addressRegistry = new Addresses(incorrectTaskConfigFilePath); + bytes memory expectedRevertMessage = bytes( + string.concat( + "MultisigTask: safe address mismatch. Caller: ", + localMultisigTask.getAddressLabel(addressRegistry.getAddress("SystemConfigOwner", 291)), + ". Actual address: ", + localMultisigTask.getAddressLabel(addressRegistry.getAddress("SystemConfigOwner", 10)) + ) + ); + vm.expectRevert(expectedRevertMessage); + localMultisigTask.run(incorrectTaskConfigFilePath); + } + + function testRevertIfIncorrectAllowedStorageWrite() public { + MultisigTask localMultisigTask = new IncorrectGasConfigTemplate1(); + Addresses addressRegistry = new Addresses(taskConfigFilePath); + bytes memory expectedRevertMessage = bytes( + string.concat( + "MultisigTask: address ", + localMultisigTask.getAddressLabel(addressRegistry.getAddress("SystemConfigProxy", 291)), + " not in allowed storage accesses" + ) + ); + vm.expectRevert(expectedRevertMessage); + localMultisigTask.run(taskConfigFilePath); + } + + function testRevertIfAllowedStorageNotWritten() public { + MultisigTask localMultisigTask = new IncorrectGasConfigTemplate2(); + Addresses addressRegistry = new Addresses(taskConfigFilePath); + bytes memory expectedRevertMessage = bytes( + string.concat( + "MultisigTask: address ", + localMultisigTask.getAddressLabel(addressRegistry.getAddress("SystemConfigOwner", 291)), + " not in task state change addresses" + ) + ); + vm.expectRevert(expectedRevertMessage); + localMultisigTask.run(taskConfigFilePath); + } +} diff --git a/test/task/mock/IncorrectGasConfigTemplate1.sol b/test/task/mock/IncorrectGasConfigTemplate1.sol new file mode 100644 index 000000000..e752051e4 --- /dev/null +++ b/test/task/mock/IncorrectGasConfigTemplate1.sol @@ -0,0 +1,17 @@ +pragma solidity 0.8.15; + +import {SystemConfig} from "@eth-optimism-bedrock/src/L1/SystemConfig.sol"; + +import {GasConfigTemplate} from "src/fps/example/template/GasConfigTemplate.sol"; +import {AddressRegistry as Addresses} from "src/fps/AddressRegistry.sol"; + +/// @title IncorrectGasConfigTemplate1 +/// @notice allowed storage write to incorrect address +contract IncorrectGasConfigTemplate1 is GasConfigTemplate { + function _taskStorageWrites() internal pure override returns (string[] memory) { + string[] memory storageWrites = new string[](1); + /// wrong address + storageWrites[0] = "SystemConfigOwner"; + return storageWrites; + } +} diff --git a/test/task/mock/IncorrectGasConfigTemplate2.sol b/test/task/mock/IncorrectGasConfigTemplate2.sol new file mode 100644 index 000000000..5bd012124 --- /dev/null +++ b/test/task/mock/IncorrectGasConfigTemplate2.sol @@ -0,0 +1,18 @@ +pragma solidity 0.8.15; + +import {SystemConfig} from "@eth-optimism-bedrock/src/L1/SystemConfig.sol"; + +import {GasConfigTemplate} from "src/fps/example/template/GasConfigTemplate.sol"; +import {AddressRegistry as Addresses} from "src/fps/AddressRegistry.sol"; + +/// @title IncorrectGasConfigTemplate2 +/// @notice not all allowed storages writes are written to +contract IncorrectGasConfigTemplate2 is GasConfigTemplate { + function _taskStorageWrites() internal pure override returns (string[] memory) { + string[] memory storageWrites = new string[](2); + /// expected to be written to + storageWrites[0] = "SystemConfigOwner"; + storageWrites[1] = "SystemConfigProxy"; + return storageWrites; + } +} diff --git a/test/task/mock/IncorrectMainnetConfig.toml b/test/task/mock/IncorrectMainnetConfig.toml new file mode 100644 index 000000000..dedc7db85 --- /dev/null +++ b/test/task/mock/IncorrectMainnetConfig.toml @@ -0,0 +1,6 @@ +# this is the file used to determine the network configuration + +l2chains = [{name = "Orderly", chainId = 291}, {name = "Metal", chainId = 1750}, {name = "Optimism Mainnet", chainId = 10}] + +[gasConfigs] +gasLimits = [{chainId = 291, gasLimit = 100000000}, {chainId = 1750, gasLimit = 100000000}, {chainId = 10, gasLimit = 100000000}] \ No newline at end of file