From d0012dd4f14cc17bc590a9feaff752e4f2754ecb Mon Sep 17 00:00:00 2001 From: Javier Donoso Date: Fri, 10 Apr 2026 17:16:55 +0200 Subject: [PATCH 1/4] feat: add SetBatcherAndSigner template Adds a reusable L2TaskBase template for atomically updating batcherHash and unsafeBlockSigner on SystemConfig in a single batched Multicall3 tx from FoundationUpgradeSafe. Mirrors the SystemConfigGasParams pattern. Includes an OP Sepolia example task and a pinned-calldata regression test. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/template/SetBatcherAndSigner.sol | 104 ++++++++++++++++++ test/tasks/Regression.t.sol | 28 +++++ .../sep/035-set-batcher-and-signer/.env | 1 + .../035-set-batcher-and-signer/config.toml | 13 +++ 4 files changed, 146 insertions(+) create mode 100644 src/template/SetBatcherAndSigner.sol create mode 100644 test/tasks/example/sep/035-set-batcher-and-signer/.env create mode 100644 test/tasks/example/sep/035-set-batcher-and-signer/config.toml diff --git a/src/template/SetBatcherAndSigner.sol b/src/template/SetBatcherAndSigner.sol new file mode 100644 index 000000000..ab919573a --- /dev/null +++ b/src/template/SetBatcherAndSigner.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {VmSafe} from "forge-std/Vm.sol"; +import {stdToml} from "lib/forge-std/src/StdToml.sol"; + +import {L2TaskBase} from "src/tasks/types/L2TaskBase.sol"; +import {SuperchainAddressRegistry} from "src/SuperchainAddressRegistry.sol"; +import {Action} from "src/libraries/MultisigTypes.sol"; + +interface ISystemConfig { + function setBatcherHash(bytes32 _batcherHash) external; + function setUnsafeBlockSigner(address _unsafeBlockSigner) external; + function batcherHash() external view returns (bytes32); + function unsafeBlockSigner() external view returns (address); +} + +/// @notice Template for updating the batcher hash and unsafe block signer on SystemConfig. +/// Both calls are batched into a single Multicall3 transaction from the SystemConfig owner. +contract SetBatcherAndSigner is L2TaskBase { + using stdToml for string; + + /// @notice Configuration for each chain's batcher and signer update. + struct TaskInputs { + bytes32 batcherHash; + address unsafeBlockSigner; + } + + /// @notice Mapping of chain ID to configuration for the task. + mapping(uint256 => TaskInputs) public cfg; + + /// @notice Returns the safe address string identifier. + function safeAddressString() public pure override returns (string memory) { + return "FoundationUpgradeSafe"; + } + + /// @notice Returns the storage write permissions required for this task. + function _taskStorageWrites() internal pure virtual override returns (string[] memory) { + string[] memory storageWrites = new string[](2); + storageWrites[0] = "SystemConfigProxy"; + storageWrites[1] = "FoundationUpgradeSafe"; + return storageWrites; + } + + /// @notice Sets up the template with configuration from a TOML file. + function _templateSetup(string memory _taskConfigFilePath, address _rootSafe) internal override { + super._templateSetup(_taskConfigFilePath, _rootSafe); + + string memory tomlContent = vm.readFile(_taskConfigFilePath); + SuperchainAddressRegistry.ChainInfo[] memory _chains = superchainAddrRegistry.getChains(); + + address batcherAddress = tomlContent.readAddress(".sequencerConfig.batcherAddress"); + address unsafeBlockSigner = tomlContent.readAddress(".sequencerConfig.unsafeBlockSigner"); + bytes32 batcherHash = bytes32(uint256(uint160(batcherAddress))); + + for (uint256 i = 0; i < _chains.length; i++) { + uint256 chainId = _chains[i].chainId; + cfg[chainId] = TaskInputs({batcherHash: batcherHash, unsafeBlockSigner: unsafeBlockSigner}); + } + } + + /// @notice Builds the batched transaction calling setBatcherHash and setUnsafeBlockSigner. + function _build(address) internal override { + SuperchainAddressRegistry.ChainInfo[] memory chains = superchainAddrRegistry.getChains(); + for (uint256 i = 0; i < chains.length; i++) { + uint256 chainId = chains[i].chainId; + TaskInputs memory taskInput = cfg[chainId]; + address systemConfigProxy = superchainAddrRegistry.getAddress("SystemConfigProxy", chainId); + ISystemConfig(systemConfigProxy).setBatcherHash(taskInput.batcherHash); + ISystemConfig(systemConfigProxy).setUnsafeBlockSigner(taskInput.unsafeBlockSigner); + } + } + + /// @notice Validates that the batcher hash and unsafe block signer were updated correctly. + function _validate(VmSafe.AccountAccess[] memory, Action[] memory, address) internal view override { + SuperchainAddressRegistry.ChainInfo[] memory chains = superchainAddrRegistry.getChains(); + for (uint256 i = 0; i < chains.length; i++) { + uint256 chainId = chains[i].chainId; + address systemConfigProxy = superchainAddrRegistry.getAddress("SystemConfigProxy", chainId); + TaskInputs memory taskInput = cfg[chainId]; + require( + ISystemConfig(systemConfigProxy).batcherHash() == taskInput.batcherHash, + "SetBatcherAndSigner: batcher hash mismatch" + ); + require( + ISystemConfig(systemConfigProxy).unsafeBlockSigner() == taskInput.unsafeBlockSigner, + "SetBatcherAndSigner: unsafe block signer mismatch" + ); + } + } + + /// @notice The batcher and signer addresses are typically EOAs, so they won't have code. + function _getCodeExceptions() internal view virtual override returns (address[] memory) { + SuperchainAddressRegistry.ChainInfo[] memory chains = superchainAddrRegistry.getChains(); + address[] memory exceptions = new address[](chains.length * 2); + for (uint256 i = 0; i < chains.length; i++) { + uint256 chainId = chains[i].chainId; + TaskInputs memory taskInput = cfg[chainId]; + exceptions[i * 2] = address(uint160(uint256(taskInput.batcherHash))); + exceptions[i * 2 + 1] = taskInput.unsafeBlockSigner; + } + return exceptions; + } +} diff --git a/test/tasks/Regression.t.sol b/test/tasks/Regression.t.sol index bb33d71a5..39af54058 100644 --- a/test/tasks/Regression.t.sol +++ b/test/tasks/Regression.t.sol @@ -46,6 +46,7 @@ import {AddGameTypeTemplate} from "src/template/AddGameTypeTemplate.sol"; import {MigrateToLiveness2} from "src/template/MigrateToLiveness2.sol"; import {RevShareUpgradeAndSetup} from "src/template/RevShareUpgradeAndSetup.sol"; import {RevShareSetup} from "src/template/RevShareSetup.sol"; +import {SetBatcherAndSigner} from "src/template/SetBatcherAndSigner.sol"; /// @notice Ensures that simulating the task consistently produces the same call data and data to sign. /// This guarantees determinism if a bug is introduced in the task logic, the call data or data to sign @@ -1273,4 +1274,31 @@ contract RegressionTest is Test { rootSafe, rootSafeCalldata, expectedDataToSign, rootSafeNonce, MULTICALL3_ADDRESS ); } + + /// @notice Expected call data and data to sign generated by manually running the SetBatcherAndSigner template at block 10624099 on sepolia. + /// Simulate from task directory (test/tasks/example/sep/035-set-batcher-and-signer) with: + /// SIMULATE_WITHOUT_LEDGER=1 just --dotenv-path $(pwd)/.env --justfile ../../../../../src/justfile simulate + function testRegressionCallDataMatches_SetBatcherAndSigner() public { + string memory taskConfigFilePath = "test/tasks/example/sep/035-set-batcher-and-signer/config.toml"; + // Call data generated by manually running the SetBatcherAndSigner template at block 10624099 on sepolia. + string memory expectedCallData = + "0x174dea710000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000034edd2a225f7f429a63e0f1d2084b9e0a93b5380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000024c9b26f610000000000000000000000001234567890abcdef1234567890abcdef1234567800000000000000000000000000000000000000000000000000000000000000000000000000000000034edd2a225f7f429a63e0f1d2084b9e0a93b538000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000002418d13918000000000000000000000000abcdef0123456789abcdef0123456789abcdef0100000000000000000000000000000000000000000000000000000000"; + MultisigTask multisigTask = new SetBatcherAndSigner(); + address rootSafe = address(0xDEe57160aAfCF04c34C887B5962D0a69676d3C8B); // FoundationUpgradeSafe on Sepolia + address[] memory allSafes = MultisigTaskTestHelper.getAllSafes(rootSafe); + + (Action[] memory actions, uint256[] memory allOriginalNonces) = + _setupAndSimulate(taskConfigFilePath, 10624099, "sepolia", multisigTask, allSafes); + + bytes memory rootSafeCalldata = + _assertCallDataMatches(multisigTask, actions, allSafes, allOriginalNonces, expectedCallData); + uint256 rootSafeNonce = allOriginalNonces[allOriginalNonces.length - 1]; + + string memory expectedDataToSign = + "0x190137e1f5dd3b92a004a23589b741196c8a214629d4ea3a690ec8e41ae45c689cbb801a8413c3c6a66df018408ea42aaf3d6763dae1dddaec68bd31b3833b716ab8"; + + _assertDataToSignSingleMultisig( + rootSafe, rootSafeCalldata, expectedDataToSign, rootSafeNonce, MULTICALL3_ADDRESS + ); + } } diff --git a/test/tasks/example/sep/035-set-batcher-and-signer/.env b/test/tasks/example/sep/035-set-batcher-and-signer/.env new file mode 100644 index 000000000..a6f83d864 --- /dev/null +++ b/test/tasks/example/sep/035-set-batcher-and-signer/.env @@ -0,0 +1 @@ +FORK_BLOCK_NUMBER=10624099 diff --git a/test/tasks/example/sep/035-set-batcher-and-signer/config.toml b/test/tasks/example/sep/035-set-batcher-and-signer/config.toml new file mode 100644 index 000000000..6db3a7f2e --- /dev/null +++ b/test/tasks/example/sep/035-set-batcher-and-signer/config.toml @@ -0,0 +1,13 @@ +templateName = "SetBatcherAndSigner" + +l2chains = [{name = "OP Sepolia Testnet", chainId = 11155420}] + +[sequencerConfig] +batcherAddress = "0x1234567890AbcdEF1234567890aBcdef12345678" +unsafeBlockSigner = "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01" + +[stateOverrides] +# Override SystemConfig owner (slot 0x33) to FoundationUpgradeSafe on Sepolia +0x034edD2A225f7f429A63E0f1D2084B9E0A93b538 = [ + { key = "0x0000000000000000000000000000000000000000000000000000000000000033", value = "0x000000000000000000000000DEe57160aAfCF04c34C887B5962D0a69676d3C8B" } +] From 17ad2e34341581b6836b1b3606964b4442fa1539 Mon Sep 17 00:00:00 2001 From: Javier Donoso Date: Mon, 13 Apr 2026 16:09:11 +0200 Subject: [PATCH 2/4] feat(SetBatcherAndSigner): guard against misconfig and redundant writes Adds two defensive checks in _templateSetup and makes _build skip setters whose target value already matches the current on-chain state: - Reject zero batcherAddress or unsafeBlockSigner in TOML parsing. - Reject a task where both fields already match the on-chain values (OR-semantics, so partial rotations remain valid). - Precompute per-chain updateBatcher/updateSigner flags in setup and call only the setters for fields that actually change, avoiding redundant ConfigUpdate events and SSTOREs on partial rotations. Calldata for the existing example task is unchanged (both fields differ at the pinned block), so the regression test still passes byte-identical. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/template/SetBatcherAndSigner.sol | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/template/SetBatcherAndSigner.sol b/src/template/SetBatcherAndSigner.sol index ab919573a..443421fb2 100644 --- a/src/template/SetBatcherAndSigner.sol +++ b/src/template/SetBatcherAndSigner.sol @@ -24,6 +24,8 @@ contract SetBatcherAndSigner is L2TaskBase { struct TaskInputs { bytes32 batcherHash; address unsafeBlockSigner; + bool updateBatcher; + bool updateSigner; } /// @notice Mapping of chain ID to configuration for the task. @@ -51,23 +53,38 @@ contract SetBatcherAndSigner is L2TaskBase { address batcherAddress = tomlContent.readAddress(".sequencerConfig.batcherAddress"); address unsafeBlockSigner = tomlContent.readAddress(".sequencerConfig.unsafeBlockSigner"); + require(batcherAddress != address(0), "SetBatcherAndSigner: batcherAddress is zero address"); + require(unsafeBlockSigner != address(0), "SetBatcherAndSigner: unsafeBlockSigner is zero address"); bytes32 batcherHash = bytes32(uint256(uint160(batcherAddress))); for (uint256 i = 0; i < _chains.length; i++) { uint256 chainId = _chains[i].chainId; - cfg[chainId] = TaskInputs({batcherHash: batcherHash, unsafeBlockSigner: unsafeBlockSigner}); + ISystemConfig systemConfig = ISystemConfig(superchainAddrRegistry.getAddress("SystemConfigProxy", chainId)); + bool updateBatcher = batcherHash != systemConfig.batcherHash(); + bool updateSigner = unsafeBlockSigner != systemConfig.unsafeBlockSigner(); + require(updateBatcher || updateSigner, "SetBatcherAndSigner: no-op (both fields already match current values)"); + cfg[chainId] = TaskInputs({ + batcherHash: batcherHash, + unsafeBlockSigner: unsafeBlockSigner, + updateBatcher: updateBatcher, + updateSigner: updateSigner + }); } } - /// @notice Builds the batched transaction calling setBatcherHash and setUnsafeBlockSigner. + /// @notice Builds the batched transaction, calling only the setters for fields that actually change. function _build(address) internal override { SuperchainAddressRegistry.ChainInfo[] memory chains = superchainAddrRegistry.getChains(); for (uint256 i = 0; i < chains.length; i++) { uint256 chainId = chains[i].chainId; TaskInputs memory taskInput = cfg[chainId]; address systemConfigProxy = superchainAddrRegistry.getAddress("SystemConfigProxy", chainId); - ISystemConfig(systemConfigProxy).setBatcherHash(taskInput.batcherHash); - ISystemConfig(systemConfigProxy).setUnsafeBlockSigner(taskInput.unsafeBlockSigner); + if (taskInput.updateBatcher) { + ISystemConfig(systemConfigProxy).setBatcherHash(taskInput.batcherHash); + } + if (taskInput.updateSigner) { + ISystemConfig(systemConfigProxy).setUnsafeBlockSigner(taskInput.unsafeBlockSigner); + } } } From b0533d6db1dfa50a1b3518b3fd6e34e4b863766a Mon Sep 17 00:00:00 2001 From: Javier Donoso Date: Mon, 13 Apr 2026 16:12:40 +0200 Subject: [PATCH 3/4] style: apply forge fmt to SetBatcherAndSigner Co-Authored-By: Claude Opus 4.6 (1M context) --- src/template/SetBatcherAndSigner.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/template/SetBatcherAndSigner.sol b/src/template/SetBatcherAndSigner.sol index 443421fb2..c0715917e 100644 --- a/src/template/SetBatcherAndSigner.sol +++ b/src/template/SetBatcherAndSigner.sol @@ -62,7 +62,9 @@ contract SetBatcherAndSigner is L2TaskBase { ISystemConfig systemConfig = ISystemConfig(superchainAddrRegistry.getAddress("SystemConfigProxy", chainId)); bool updateBatcher = batcherHash != systemConfig.batcherHash(); bool updateSigner = unsafeBlockSigner != systemConfig.unsafeBlockSigner(); - require(updateBatcher || updateSigner, "SetBatcherAndSigner: no-op (both fields already match current values)"); + require( + updateBatcher || updateSigner, "SetBatcherAndSigner: no-op (both fields already match current values)" + ); cfg[chainId] = TaskInputs({ batcherHash: batcherHash, unsafeBlockSigner: unsafeBlockSigner, From 655b652a92399f2f9c70680f40bc8bc9ebc4fe3e Mon Sep 17 00:00:00 2001 From: Javier Donoso Date: Tue, 21 Apr 2026 07:03:55 +0200 Subject: [PATCH 4/4] refactor(SetBatcherAndOrSigner): rename and apply review nits - Rename contract/file SetBatcherAndSigner -> SetBatcherAndOrSigner to reflect that either or both fields can be rotated (partial rotations are valid). - Replace hardcoded "FoundationUpgradeSafe" in _taskStorageWrites with safeAddressString() to remove duplication and make the template friendlier to a future configurable-owner refactor. - Tighten _getCodeExceptions NatSpec per review. Calldata and EIP-712 data-to-sign are unaffected by the rename; the existing pinned regression test passes byte-identical. Co-Authored-By: Claude Opus 4.6 (1M context) --- ...erAndSigner.sol => SetBatcherAndOrSigner.sol} | 16 ++++++++-------- test/tasks/Regression.t.sol | 10 +++++----- .../sep/035-set-batcher-and-signer/config.toml | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) rename src/template/{SetBatcherAndSigner.sol => SetBatcherAndOrSigner.sol} (88%) diff --git a/src/template/SetBatcherAndSigner.sol b/src/template/SetBatcherAndOrSigner.sol similarity index 88% rename from src/template/SetBatcherAndSigner.sol rename to src/template/SetBatcherAndOrSigner.sol index c0715917e..55f0617e2 100644 --- a/src/template/SetBatcherAndSigner.sol +++ b/src/template/SetBatcherAndOrSigner.sol @@ -17,7 +17,7 @@ interface ISystemConfig { /// @notice Template for updating the batcher hash and unsafe block signer on SystemConfig. /// Both calls are batched into a single Multicall3 transaction from the SystemConfig owner. -contract SetBatcherAndSigner is L2TaskBase { +contract SetBatcherAndOrSigner is L2TaskBase { using stdToml for string; /// @notice Configuration for each chain's batcher and signer update. @@ -40,7 +40,7 @@ contract SetBatcherAndSigner is L2TaskBase { function _taskStorageWrites() internal pure virtual override returns (string[] memory) { string[] memory storageWrites = new string[](2); storageWrites[0] = "SystemConfigProxy"; - storageWrites[1] = "FoundationUpgradeSafe"; + storageWrites[1] = safeAddressString(); return storageWrites; } @@ -53,8 +53,8 @@ contract SetBatcherAndSigner is L2TaskBase { address batcherAddress = tomlContent.readAddress(".sequencerConfig.batcherAddress"); address unsafeBlockSigner = tomlContent.readAddress(".sequencerConfig.unsafeBlockSigner"); - require(batcherAddress != address(0), "SetBatcherAndSigner: batcherAddress is zero address"); - require(unsafeBlockSigner != address(0), "SetBatcherAndSigner: unsafeBlockSigner is zero address"); + require(batcherAddress != address(0), "SetBatcherAndOrSigner: batcherAddress is zero address"); + require(unsafeBlockSigner != address(0), "SetBatcherAndOrSigner: unsafeBlockSigner is zero address"); bytes32 batcherHash = bytes32(uint256(uint160(batcherAddress))); for (uint256 i = 0; i < _chains.length; i++) { @@ -63,7 +63,7 @@ contract SetBatcherAndSigner is L2TaskBase { bool updateBatcher = batcherHash != systemConfig.batcherHash(); bool updateSigner = unsafeBlockSigner != systemConfig.unsafeBlockSigner(); require( - updateBatcher || updateSigner, "SetBatcherAndSigner: no-op (both fields already match current values)" + updateBatcher || updateSigner, "SetBatcherAndOrSigner: no-op (both fields already match current values)" ); cfg[chainId] = TaskInputs({ batcherHash: batcherHash, @@ -99,16 +99,16 @@ contract SetBatcherAndSigner is L2TaskBase { TaskInputs memory taskInput = cfg[chainId]; require( ISystemConfig(systemConfigProxy).batcherHash() == taskInput.batcherHash, - "SetBatcherAndSigner: batcher hash mismatch" + "SetBatcherAndOrSigner: batcher hash mismatch" ); require( ISystemConfig(systemConfigProxy).unsafeBlockSigner() == taskInput.unsafeBlockSigner, - "SetBatcherAndSigner: unsafe block signer mismatch" + "SetBatcherAndOrSigner: unsafe block signer mismatch" ); } } - /// @notice The batcher and signer addresses are typically EOAs, so they won't have code. + /// @notice Whitelists for each chain's Batcher and UnsafeBlockSigner since batcher and signer addresses are EOAs. function _getCodeExceptions() internal view virtual override returns (address[] memory) { SuperchainAddressRegistry.ChainInfo[] memory chains = superchainAddrRegistry.getChains(); address[] memory exceptions = new address[](chains.length * 2); diff --git a/test/tasks/Regression.t.sol b/test/tasks/Regression.t.sol index 39af54058..8bd6c9c7a 100644 --- a/test/tasks/Regression.t.sol +++ b/test/tasks/Regression.t.sol @@ -46,7 +46,7 @@ import {AddGameTypeTemplate} from "src/template/AddGameTypeTemplate.sol"; import {MigrateToLiveness2} from "src/template/MigrateToLiveness2.sol"; import {RevShareUpgradeAndSetup} from "src/template/RevShareUpgradeAndSetup.sol"; import {RevShareSetup} from "src/template/RevShareSetup.sol"; -import {SetBatcherAndSigner} from "src/template/SetBatcherAndSigner.sol"; +import {SetBatcherAndOrSigner} from "src/template/SetBatcherAndOrSigner.sol"; /// @notice Ensures that simulating the task consistently produces the same call data and data to sign. /// This guarantees determinism if a bug is introduced in the task logic, the call data or data to sign @@ -1275,15 +1275,15 @@ contract RegressionTest is Test { ); } - /// @notice Expected call data and data to sign generated by manually running the SetBatcherAndSigner template at block 10624099 on sepolia. + /// @notice Expected call data and data to sign generated by manually running the SetBatcherAndOrSigner template at block 10624099 on sepolia. /// Simulate from task directory (test/tasks/example/sep/035-set-batcher-and-signer) with: /// SIMULATE_WITHOUT_LEDGER=1 just --dotenv-path $(pwd)/.env --justfile ../../../../../src/justfile simulate - function testRegressionCallDataMatches_SetBatcherAndSigner() public { + function testRegressionCallDataMatches_SetBatcherAndOrSigner() public { string memory taskConfigFilePath = "test/tasks/example/sep/035-set-batcher-and-signer/config.toml"; - // Call data generated by manually running the SetBatcherAndSigner template at block 10624099 on sepolia. + // Call data generated by manually running the SetBatcherAndOrSigner template at block 10624099 on sepolia. string memory expectedCallData = "0x174dea710000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000034edd2a225f7f429a63e0f1d2084b9e0a93b5380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000024c9b26f610000000000000000000000001234567890abcdef1234567890abcdef1234567800000000000000000000000000000000000000000000000000000000000000000000000000000000034edd2a225f7f429a63e0f1d2084b9e0a93b538000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000002418d13918000000000000000000000000abcdef0123456789abcdef0123456789abcdef0100000000000000000000000000000000000000000000000000000000"; - MultisigTask multisigTask = new SetBatcherAndSigner(); + MultisigTask multisigTask = new SetBatcherAndOrSigner(); address rootSafe = address(0xDEe57160aAfCF04c34C887B5962D0a69676d3C8B); // FoundationUpgradeSafe on Sepolia address[] memory allSafes = MultisigTaskTestHelper.getAllSafes(rootSafe); diff --git a/test/tasks/example/sep/035-set-batcher-and-signer/config.toml b/test/tasks/example/sep/035-set-batcher-and-signer/config.toml index 6db3a7f2e..4d5c11583 100644 --- a/test/tasks/example/sep/035-set-batcher-and-signer/config.toml +++ b/test/tasks/example/sep/035-set-batcher-and-signer/config.toml @@ -1,4 +1,4 @@ -templateName = "SetBatcherAndSigner" +templateName = "SetBatcherAndOrSigner" l2chains = [{name = "OP Sepolia Testnet", chainId = 11155420}]