diff --git a/Makefile b/Makefile index 24859f815..14edc8786 100644 --- a/Makefile +++ b/Makefile @@ -4,21 +4,33 @@ # `include ../../Makefile`. REPO_ROOT := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) -GAS_INCREASE_DIR = $(network)/$(shell date +'%Y-%m-%d')-increase-gas-limit -GAS_AND_ELASTICITY_INCREASE_DIR = $(network)/$(shell date +'%Y-%m-%d')-increase-gas-and-elasticity-limit -SAFE_MANAGEMENT_DIR = $(network)/$(shell date +'%Y-%m-%d')-safe-management -FUNDING_DIR = $(network)/$(shell date +'%Y-%m-%d')-funding -SET_BASE_BRIDGE_PARTNER_THRESHOLD_DIR = $(network)/$(shell date +'%Y-%m-%d')-pause-bridge-base -PAUSE_BRIDGE_BASE_DIR = $(network)/$(shell date +'%Y-%m-%d')-pause-bridge-base -PAUSE_SUPERCHAIN_CONFIG_DIR = $(network)/$(shell date +'%Y-%m-%d')-pause-superchain-config - -TEMPLATE_GAS_INCREASE = setup-templates/template-gas-increase -TEMPLATE_GAS_AND_ELASTICITY_INCREASE = setup-templates/template-gas-and-elasticity-increase -TEMPLATE_SAFE_MANAGEMENT = setup-templates/template-safe-management -TEMPLATE_FUNDING = setup-templates/template-funding -TEMPLATE_SET_BASE_BRIDGE_PARTNER_THRESHOLD = setup-templates/template-set-bridge-partner-threshold -TEMPLATE_PAUSE_BRIDGE_BASE = setup-templates/template-pause-bridge-base -TEMPLATE_PAUSE_SUPERCHAIN_CONFIG = setup-templates/template-pause-superchain-config +## +# Task lifecycle +## +# Archive a completed EVM task with: +# +# make archive-task +# +.PHONY: archive-task +archive-task: + @set -eu; \ + tasks=$$(find "$(REPO_ROOT)/active/evm/tasks" -mindepth 1 -maxdepth 1 -type d | sort); \ + [ -n "$$tasks" ] || { echo "archive-task: no active tasks"; exit 1; }; \ + echo "Active EVM tasks:"; \ + printf '%s\n' "$$tasks" | awk -F/ '{ printf " %d) %s\n", NR, $$NF }'; \ + printf "Select a task to archive: "; read -r choice; \ + case "$$choice" in ""|*[!0-9]*) echo "archive-task: invalid selection"; exit 1;; esac; \ + source=$$(printf '%s\n' "$$tasks" | sed -n "$${choice}p"); \ + [ -n "$$source" ] || { echo "archive-task: invalid selection"; exit 1; }; \ + task_id=$${source##*/}; \ + case "$$task_id" in ""|.|..|*[!A-Za-z0-9._-]*) echo "archive-task: invalid TASK_ID"; exit 1;; esac; \ + destination="$(REPO_ROOT)/archive/evm/$$task_id"; \ + [ -d "$$source" ] || { echo "archive-task: no such active task: active/evm/tasks/$$task_id"; exit 1; }; \ + [ ! -e "$$destination" ] || { echo "archive-task: destination already exists: archive/evm/$$task_id"; exit 1; }; \ + [ ! -d "$(REPO_ROOT)/active/evm/records" ] || { echo "archive-task: move shared active/evm/records into the task before archiving"; exit 1; }; \ + mkdir -p "$(REPO_ROOT)/archive/evm"; \ + git mv -- "$$source" "$$destination"; \ + echo "Archived active/evm/tasks/$$task_id -> archive/evm/$$task_id" ## # Toolchain bootstrap (mise) @@ -67,51 +79,6 @@ GOPATH = $(shell $(MISE_EXEC) go env GOPATH 2>/dev/null) export GOPATH endif -## -# Project Setup -## -# Run `make setup-gas-increase network=` -setup-gas-increase: - rm -rf $(TEMPLATE_GAS_INCREASE)/cache $(TEMPLATE_GAS_INCREASE)/lib $(TEMPLATE_GAS_INCREASE)/out - cp -r $(TEMPLATE_GAS_INCREASE) $(GAS_INCREASE_DIR) - mkdir -p $(network)/signatures/$(notdir $(GAS_INCREASE_DIR)) - -# Run `make setup-gas-increase network=` -setup-gas-and-elasticity-increase: - rm -rf $(TEMPLATE_GAS_AND_ELASTICITY_INCREASE)/cache $(TEMPLATE_GAS_AND_ELASTICITY_INCREASE)/lib $(TEMPLATE_GAS_AND_ELASTICITY_INCREASE)/out - cp -r $(TEMPLATE_GAS_AND_ELASTICITY_INCREASE) $(GAS_AND_ELASTICITY_INCREASE_DIR) - mkdir -p $(network)/signatures/$(notdir $(GAS_AND_ELASTICITY_INCREASE_DIR)) - -# Run `make setup-safe-management network=` -setup-safe-management: - rm -rf $(TEMPLATE_SAFE_MANAGEMENT)/cache $(TEMPLATE_SAFE_MANAGEMENT)/lib $(TEMPLATE_SAFE_MANAGEMENT)/out - cp -r $(TEMPLATE_SAFE_MANAGEMENT) $(SAFE_MANAGEMENT_DIR) - mkdir -p $(network)/signatures/$(notdir $(SAFE_MANAGEMENT_DIR)) - -# Run `make setup-funding network=` -setup-funding: - rm -rf $(TEMPLATE_FUNDING)/cache $(TEMPLATE_FUNDING)/lib $(TEMPLATE_FUNDING)/out - cp -r $(TEMPLATE_FUNDING) $(FUNDING_DIR) - mkdir -p $(network)/signatures/$(notdir $(FUNDING_DIR)) - -# Run `make setup-bridge-partner-threshold network=` -setup-bridge-partner-threshold: - rm -rf $(TEMPLATE_SET_BASE_BRIDGE_PARTNER_THRESHOLD)/cache $(TEMPLATE_SET_BASE_BRIDGE_PARTNER_THRESHOLD)/lib $(TEMPLATE_SET_BASE_BRIDGE_PARTNER_THRESHOLD)/out - cp -r $(TEMPLATE_SET_BASE_BRIDGE_PARTNER_THRESHOLD) $(SET_BASE_BRIDGE_PARTNER_THRESHOLD_DIR) - mkdir -p $(network)/signatures/$(notdir $(SET_BASE_BRIDGE_PARTNER_THRESHOLD_DIR)) - -# Run `make setup-bridge-pause network=` -setup-bridge-pause: - rm -rf $(TEMPLATE_PAUSE_BRIDGE_BASE)/cache $(TEMPLATE_PAUSE_BRIDGE_BASE)/lib $(TEMPLATE_PAUSE_BRIDGE_BASE)/out - cp -r $(TEMPLATE_PAUSE_BRIDGE_BASE) $(PAUSE_BRIDGE_BASE_DIR) - mkdir -p $(network)/signatures/$(notdir $(PAUSE_BRIDGE_BASE_DIR)) - -# Run `make setup-superchain-config-pause network=` -setup-superchain-config-pause: - rm -rf $(TEMPLATE_PAUSE_SUPERCHAIN_CONFIG)/cache $(TEMPLATE_PAUSE_SUPERCHAIN_CONFIG)/lib $(TEMPLATE_PAUSE_SUPERCHAIN_CONFIG)/out - cp -r $(TEMPLATE_PAUSE_SUPERCHAIN_CONFIG) $(PAUSE_SUPERCHAIN_CONFIG_DIR) - mkdir -p $(network)/signatures/$(notdir $(PAUSE_SUPERCHAIN_CONFIG_DIR)) - ## # Solidity Setup ## diff --git a/setup-templates/template-funding/.env b/setup-templates/template-funding/.env deleted file mode 100644 index 5aa7337f3..000000000 --- a/setup-templates/template-funding/.env +++ /dev/null @@ -1,10 +0,0 @@ -# Required: Git commit hash for https://github.com/base/contracts -BASE_CONTRACTS_COMMIT=be7c7a642e430fa64b04b63203839f8c81f48466 - -# Network-specific addresses are automatically loaded from {network}/.env via include ../.env - -# Required: Address of the Gnosis Safe that will execute the funding transaction -OWNER_SAFE= - -# Required: Address of a signer on OWNER_SAFE (used for simulation) -SENDER= diff --git a/setup-templates/template-funding/FACILITATOR.md b/setup-templates/template-funding/FACILITATOR.md deleted file mode 100644 index f3a0b84b0..000000000 --- a/setup-templates/template-funding/FACILITATOR.md +++ /dev/null @@ -1,22 +0,0 @@ -# Facilitator Guide - -Guide for facilitators managing this task. - -## Task Origin Signing - -After setting up the task, generate cryptographic attestations (sigstore bundles) to prove who created and facilitated the task. These signatures are stored in `/signatures//`. - -### Task creator (run after task setup): -```bash -make sign-as-task-creator -``` - -### Base facilitator: -```bash -make sign-as-base-facilitator -``` - -### Security Council facilitator: -```bash -make sign-as-sc-facilitator -``` diff --git a/setup-templates/template-funding/Makefile b/setup-templates/template-funding/Makefile deleted file mode 100644 index bd95485fa..000000000 --- a/setup-templates/template-funding/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -include ../../Makefile -include ../../Multisig.mk -include ../.env -include .env - -RPC_URL = $(L1_RPC_URL) -SCRIPT_NAME = FundScript - -# Validate required configuration before execution -.PHONY: validate-config -validate-config: - @test -n "$(BASE_CONTRACTS_COMMIT)" || (echo "BASE_CONTRACTS_COMMIT required" && exit 1) - @test -n "$(OWNER_SAFE)" || (echo "OWNER_SAFE required" && exit 1) - @test -n "$(SENDER)" || (echo "SENDER required" && exit 1) - @echo "Configuration validated successfully" - -.PHONY: execute -execute: validate-config - $(call MULTISIG_EXECUTE,$(SIGNATURES)) diff --git a/setup-templates/template-funding/README.md b/setup-templates/template-funding/README.md deleted file mode 100644 index 66ad16dce..000000000 --- a/setup-templates/template-funding/README.md +++ /dev/null @@ -1,148 +0,0 @@ -# Funding - -Status: PENDING - -## Description - -This task contains a single script that can be used to fund addresses from a Gnosis Safe. - -## Procedure - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -cd /-funding -make deps -``` - -### 2. Setup Ledger - -Your Ledger needs to be connected and unlocked. The Ethereum -application needs to be opened on Ledger with the message "Application -is ready". - -### 3. Simulate, Validate, and Sign - -#### 3.1. Simulate and validate the transaction - -Make sure your ledger is still unlocked and run the following. - -```bash -make sign -``` - -You will see a "Simulation link" from the output. - -Paste this URL in your browser. A prompt may ask you to choose a -project, any project will do. You can create one if necessary. - -Click "Simulate Transaction". - -We will be performing 3 validations and extract the domain hash and -message hash to approve on your Ledger: - -1. Validate integrity of the simulation. -2. Validate correctness of the state diff. -3. Validate and extract domain hash and message hash to approve. - -##### 3.1.1. Validate integrity of the simulation. - -Make sure you are on the "Summary" tab of the tenderly simulation, to -validate integrity of the simulation, we need to check the following: - -1. "Network": Check the network is ``. -2. "Timestamp": Check the simulation is performed on a block with a - recent timestamp (i.e. close to when you run the script). -3. "Sender": Check the address shown is your signer account. - -##### 3.1.2. Validate correctness of the state diff. - -Now click on the "State" tab, and refer to the [State Validations](./VALIDATION.md) instructions for the transaction you are signing. -Once complete return to this document to complete the signing. - -### 4. Extract the domain hash and the message hash to approve. - -Now that we have verified the transaction performs the right -operation, we need to extract the domain hash and the message hash to -approve. - -Go back to the "Summary" tab, and find the -`Safe.checkSignatures` call. This call's `data` parameter -contains both the domain hash and the message hash that will show up -in your Ledger. - -It will be a concatenation of `0x1901`, the domain hash, and the -message hash: `0x1901[domain hash][message hash]`. - -Note down this value. You will need to compare it with the ones -displayed on the Ledger screen at signing. - -Once the validations are done, it's time to actually sign the -transaction. - -> [!WARNING] -> This is the most security critical part of the playbook: make sure the -> domain hash and message hash in the following three places match: -> -> 1. On your Ledger screen. -> 2. In the terminal output. -> 3. In the Tenderly simulation. You should use the same Tenderly -> simulation as the one you used to verify the state diffs, instead -> of opening the new one printed in the console. -> - -After verification, sign the transaction. You will see the `Data`, -`Signer` and `Signature` printed in the console. Format should be -something like this: - -```shell -Data: -Signer:
-Signature: -``` - -Double check the signer address is the right one. - -#### 4.1. Send the output to Facilitator(s) - -Nothing has occurred onchain - these are offchain signatures which -will be collected by Facilitators for execution. Execution can occur -by anyone once a threshold of signatures are collected, so a -Facilitator will do the final execution for convenience. - -Share the `Data`, `Signer` and `Signature` with the Facilitator, and -congrats, you are done! - -### [For Facilitator ONLY] How to execute - -#### Execute the transaction - -1. Collect outputs from all participating signers. -1. Concatenate all signatures and export it as the `SIGNATURES` - environment variable, i.e. `export -SIGNATURES="[SIGNATURE1][SIGNATURE2]..."`. -1. Run the `make execute` command as described below to execute the transaction. - -For example, if the quorum is 2 and you get the following outputs: - -```shell -Data: 0xDEADBEEF -Signer: 0xC0FFEE01 -Signature: AAAA -``` - -```shell -Data: 0xDEADBEEF -Signer: 0xC0FFEE02 -Signature: BBBB -``` - -Then you should run: - -Coinbase facilitator: - -```bash -SIGNATURES=AAAABBBB make execute -``` diff --git a/setup-templates/template-funding/foundry.toml b/setup-templates/template-funding/foundry.toml deleted file mode 100644 index 5b8fe4ae7..000000000 --- a/setup-templates/template-funding/foundry.toml +++ /dev/null @@ -1,23 +0,0 @@ -[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -broadcast = 'records' -fs_permissions = [{ access = "read-write", path = "./" }] -optimizer = true -optimizer_runs = 999999 -solc_version = "0.8.15" -via-ir = false -remappings = [ - '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', - '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', - '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', - '@rari-capital/solmate/=lib/solmate/', - '@base-contracts/=lib/contracts', - '@solady/=lib/solady/src/', -] - -[lint] -lint_on_build = false - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/setup-templates/template-funding/funding.json b/setup-templates/template-funding/funding.json deleted file mode 100644 index 3b9dbcefc..000000000 --- a/setup-templates/template-funding/funding.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "recipients": [ - "0x0000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000043" - ], - "funds": [ - 100000000000000000, - 50000000000000000 - ] -} \ No newline at end of file diff --git a/setup-templates/template-funding/script/Fund.s.sol b/setup-templates/template-funding/script/Fund.s.sol deleted file mode 100644 index e6e552893..000000000 --- a/setup-templates/template-funding/script/Fund.s.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {Vm} from "forge-std/Vm.sol"; - -import {MultisigScript} from "@base-contracts/script/universal/MultisigScript.sol"; -import {Simulation} from "@base-contracts/script/universal/Simulation.sol"; -import {Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; - -contract FundScript is MultisigScript { - address internal immutable OWNER_SAFE; - - uint256 internal immutable OWNER_SAFE_BALANCE_BEFORE; - uint256 internal immutable TOTAL_FUNDS; - - address[] internal RECIPIENTS; - uint256[] internal FUNDS; - uint256[] internal RECIPIENT_BALANCES_BEFORE; - - constructor() { - OWNER_SAFE = vm.envAddress("OWNER_SAFE"); - - string memory funding = vm.readFile("./funding.json"); - RECIPIENTS = vm.parseJsonAddressArray(funding, ".recipients"); - FUNDS = vm.parseJsonUintArray(funding, ".funds"); - - uint256 totalFunds = 0; - RECIPIENT_BALANCES_BEFORE = new uint256[](RECIPIENTS.length + 1); - for (uint256 i; i < RECIPIENTS.length; i++) { - RECIPIENT_BALANCES_BEFORE[i] = RECIPIENTS[i].balance; - totalFunds += FUNDS[i]; - } - - OWNER_SAFE_BALANCE_BEFORE = OWNER_SAFE.balance; - TOTAL_FUNDS = totalFunds; - } - - function setUp() public view { - _precheck(); - } - - function _precheck() internal view { - require(RECIPIENTS.length == FUNDS.length, "RECIPIENTS and FUNDS not same length"); - require(RECIPIENTS.length > 0, "RECIPIENTS and FUNDS empty"); - require(OWNER_SAFE.balance >= TOTAL_FUNDS, "OWNER_SAFE not enough balance"); - } - - function _buildCalls() internal view override returns (Call[] memory) { - Call[] memory calls = new Call[](RECIPIENTS.length); - - for (uint256 i; i < RECIPIENTS.length; i++) { - calls[i] = Call({operation: Enum.Operation.Call, target: RECIPIENTS[i], data: "", value: FUNDS[i]}); - } - - return calls; - } - - function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override { - for (uint256 i; i < RECIPIENTS.length; i++) { - vm.assertEq( - RECIPIENTS[i].balance, RECIPIENT_BALANCES_BEFORE[i] + FUNDS[i], "Recipient balance is not correct" - ); - } - - vm.assertEq(OWNER_SAFE.balance, OWNER_SAFE_BALANCE_BEFORE - TOTAL_FUNDS, "Owner safe balance is not correct"); - } - - function _ownerSafe() internal view override returns (address) { - return OWNER_SAFE; - } -} diff --git a/setup-templates/template-gas-and-elasticity-increase/.env b/setup-templates/template-gas-and-elasticity-increase/.env deleted file mode 100644 index 853788356..000000000 --- a/setup-templates/template-gas-and-elasticity-increase/.env +++ /dev/null @@ -1,30 +0,0 @@ -# Required: Git commit hash for https://github.com/base/contracts -BASE_CONTRACTS_COMMIT=be7c7a642e430fa64b04b63203839f8c81f48466 - -# Network-specific addresses are automatically loaded from {network}/.env via include ../.env - -# Required: Current gas limit on chain (for validation) -FROM_GAS_LIMIT=TODO - -# Required: New gas limit to set -TO_GAS_LIMIT=TODO - -# Required: Current EIP-1559 elasticity on chain (for validation) -FROM_ELASTICITY=TODO - -# Required: New EIP-1559 elasticity to set -TO_ELASTICITY=TODO - -# Required: Current DA footprint gas scalar on chain (for validation) -# Use `make da-scalar TARGET_BLOB_COUNT=` to calculate expected value -FROM_DA_FOOTPRINT_GAS_SCALAR=TODO - -# Required: New DA footprint gas scalar to set -# Use `make da-scalar TARGET_BLOB_COUNT=` to calculate expected value -TO_DA_FOOTPRINT_GAS_SCALAR=TODO - -# Required: Address of a signer on OWNER_SAFE (used for simulation) -SENDER= - -# Enable state diff recording for validation -RECORD_STATE_DIFF=true diff --git a/setup-templates/template-gas-and-elasticity-increase/FACILITATOR.md b/setup-templates/template-gas-and-elasticity-increase/FACILITATOR.md deleted file mode 100644 index 5340f05d6..000000000 --- a/setup-templates/template-gas-and-elasticity-increase/FACILITATOR.md +++ /dev/null @@ -1,49 +0,0 @@ -# Facilitator Guide - -Guide for facilitators managing this task. - -## Task Origin Signing - -After setting up the task, generate cryptographic attestations (sigstore bundles) to prove who created and facilitated the task. These signatures are stored in `/signatures//`. - -### Task creator (run after task setup): -```bash -make sign-as-task-creator -``` - -### Base facilitator: -```bash -make sign-as-base-facilitator -``` - -### Security Council facilitator: -```bash -make sign-as-sc-facilitator -``` - -## Execution - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -cd / -make deps -``` - -### 2. Execute upgrade - -```bash -SIGNATURES=AAABBBCCC make execute -``` - -### 3. (**ONLY** if needed) Execute upgrade rollback - -> [!IMPORTANT] -> -> THIS SHOULD ONLY BE PERFORMED IN THE EVENT THAT WE NEED TO ROLLBACK - -```bash -SIGNATURES=AAABBBCCC make execute-rollback -``` diff --git a/setup-templates/template-gas-and-elasticity-increase/Makefile b/setup-templates/template-gas-and-elasticity-increase/Makefile deleted file mode 100644 index 5219cae0c..000000000 --- a/setup-templates/template-gas-and-elasticity-increase/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -include ../../Makefile -include ../../Multisig.mk -include ../.env -include .env - -# Map config variables to script variables -OWNER_SAFE ?= $(INCIDENT_MULTISIG) - -ifndef ROLLBACK_NONCE_OFFSET -override ROLLBACK_NONCE_OFFSET = 1 -endif - -RPC_URL = $(L1_RPC_URL) -SCRIPT_NAME = IncreaseEip1559ElasticityAndIncreaseGasLimitScript -BUILDER_HARD_CAP ?= TODO - -# Validate required configuration before execution -.PHONY: validate-config -validate-config: - @test -n "$(BASE_CONTRACTS_COMMIT)" -a "$(BASE_CONTRACTS_COMMIT)" != "TODO" || (echo "BASE_CONTRACTS_COMMIT required" && exit 1) - @test -n "$(OWNER_SAFE)" || (echo "OWNER_SAFE required" && exit 1) - @test -n "$(SYSTEM_CONFIG)" || (echo "SYSTEM_CONFIG required" && exit 1) - @test -n "$(SENDER)" || (echo "SENDER required" && exit 1) - @test -n "$(FROM_GAS_LIMIT)" -a "$(FROM_GAS_LIMIT)" != "TODO" || (echo "FROM_GAS_LIMIT required" && exit 1) - @test -n "$(TO_GAS_LIMIT)" -a "$(TO_GAS_LIMIT)" != "TODO" || (echo "TO_GAS_LIMIT required" && exit 1) - @test -n "$(FROM_ELASTICITY)" -a "$(FROM_ELASTICITY)" != "TODO" || (echo "FROM_ELASTICITY required" && exit 1) - @test -n "$(TO_ELASTICITY)" -a "$(TO_ELASTICITY)" != "TODO" || (echo "TO_ELASTICITY required" && exit 1) - @test -n "$(FROM_DA_FOOTPRINT_GAS_SCALAR)" -a "$(FROM_DA_FOOTPRINT_GAS_SCALAR)" != "TODO" || (echo "FROM_DA_FOOTPRINT_GAS_SCALAR required" && exit 1) - @test -n "$(TO_DA_FOOTPRINT_GAS_SCALAR)" -a "$(TO_DA_FOOTPRINT_GAS_SCALAR)" != "TODO" || (echo "TO_DA_FOOTPRINT_GAS_SCALAR required" && exit 1) - @echo "Configuration validated successfully" - -# Calculate the DA footprint gas scalar based on the formula: -# da_footprint_gas_scalar = gas_limit / (elasticity * da_soft_cap_blob_count * 32,000) -# Uses TO_GAS_LIMIT and TO_ELASTICITY from .env -.PHONY: da-scalar -da-scalar: -ifndef TARGET_BLOB_COUNT - $(error TARGET_BLOB_COUNT is not set. Usage: make da-scalar TARGET_BLOB_COUNT=) -endif -ifeq ($(TO_GAS_LIMIT),TODO) - $(error TO_GAS_LIMIT is not set. Please set it in .env before running this command.) -endif -ifeq ($(TO_ELASTICITY),TODO) - $(error TO_ELASTICITY is not set. Please set it in .env before running this command.) -endif - @scalar=$$(( $(TO_GAS_LIMIT) / ($(TO_ELASTICITY) * $(TARGET_BLOB_COUNT) * 32000) )); \ - soft_cap=$$(( $(TARGET_BLOB_COUNT) * 32000 )); \ - echo "$(TO_GAS_LIMIT) / ($(TO_ELASTICITY) * $(TARGET_BLOB_COUNT) * 32000) = $$scalar"; \ - echo; \ - echo "Set in .env:"; \ - echo "TO_DA_FOOTPRINT_GAS_SCALAR=$$scalar"; \ - echo; \ - echo "Copy into README.md:"; \ - echo "Set BUILDER_HARD_CAP= from Config Service to fill the builder hard cap row."; \ - echo; \ - echo "| Field | Value |"; \ - echo "|-------|-------|"; \ - echo "| Gas limit | \`$(TO_GAS_LIMIT)\` |"; \ - echo "| Elasticity | \`$(TO_ELASTICITY)\` |"; \ - echo "| DA soft-cap blob count (\`TARGET_BLOB_COUNT\`) | \`$(TARGET_BLOB_COUNT)\` |"; \ - echo "| Calculated scalar | \`$$scalar\` |"; \ - echo "| Implied soft cap | \`$$soft_cap\` estimated DA bytes per L2 block |"; \ - echo "| Builder hard cap | \`$(BUILDER_HARD_CAP)\` estimated DA bytes per L2 block |" - -.PHONY: gen-validation -gen-validation: validate-config deps-signer-tool - $(call GEN_VALIDATION,$(SCRIPT_NAME),,$(SENDER),base-signer.json,NEW_GAS_LIMIT=$(TO_GAS_LIMIT) OLD_GAS_LIMIT=$(FROM_GAS_LIMIT) NEW_ELASTICITY=$(TO_ELASTICITY) OLD_ELASTICITY=$(FROM_ELASTICITY) NEW_DA_FOOTPRINT_GAS_SCALAR=$(TO_DA_FOOTPRINT_GAS_SCALAR) OLD_DA_FOOTPRINT_GAS_SCALAR=$(FROM_DA_FOOTPRINT_GAS_SCALAR)) - -.PHONY: execute -execute: validate-config - NEW_GAS_LIMIT=$(TO_GAS_LIMIT) \ - OLD_GAS_LIMIT=$(FROM_GAS_LIMIT) \ - NEW_ELASTICITY=$(TO_ELASTICITY) \ - OLD_ELASTICITY=$(FROM_ELASTICITY) \ - NEW_DA_FOOTPRINT_GAS_SCALAR=$(TO_DA_FOOTPRINT_GAS_SCALAR) \ - OLD_DA_FOOTPRINT_GAS_SCALAR=$(FROM_DA_FOOTPRINT_GAS_SCALAR) \ - $(call MULTISIG_EXECUTE,$(SIGNATURES)) - -# Generate rollback validation file with swapped old/new values and nonce offset. -# SAFE_NONCE is set to current_nonce + ROLLBACK_NONCE_OFFSET so the rollback -# transaction targets the correct future nonce. -.PHONY: gen-validation-rollback -gen-validation-rollback: validate-config deps-signer-tool - $(call GEN_VALIDATION,$(SCRIPT_NAME),,$(SENDER),base-signer-rollback.json,OLD_GAS_LIMIT=$(TO_GAS_LIMIT) NEW_GAS_LIMIT=$(FROM_GAS_LIMIT) OLD_ELASTICITY=$(TO_ELASTICITY) NEW_ELASTICITY=$(FROM_ELASTICITY) OLD_DA_FOOTPRINT_GAS_SCALAR=$(TO_DA_FOOTPRINT_GAS_SCALAR) NEW_DA_FOOTPRINT_GAS_SCALAR=$(FROM_DA_FOOTPRINT_GAS_SCALAR) SAFE_NONCE=$(shell expr $(call GET_NONCE,$(OWNER_SAFE)) + $(ROLLBACK_NONCE_OFFSET))) - -.PHONY: execute-rollback -execute-rollback: validate-config - OLD_GAS_LIMIT=$(TO_GAS_LIMIT) \ - NEW_GAS_LIMIT=$(FROM_GAS_LIMIT) \ - OLD_ELASTICITY=$(TO_ELASTICITY) \ - NEW_ELASTICITY=$(FROM_ELASTICITY) \ - OLD_DA_FOOTPRINT_GAS_SCALAR=$(TO_DA_FOOTPRINT_GAS_SCALAR) \ - NEW_DA_FOOTPRINT_GAS_SCALAR=$(FROM_DA_FOOTPRINT_GAS_SCALAR) \ - SAFE_NONCE=$(shell expr $(call GET_NONCE,$(OWNER_SAFE)) + $(ROLLBACK_NONCE_OFFSET)) \ - $(call MULTISIG_EXECUTE,$(SIGNATURES)) diff --git a/setup-templates/template-gas-and-elasticity-increase/README.md b/setup-templates/template-gas-and-elasticity-increase/README.md deleted file mode 100644 index 4ccacd0cf..000000000 --- a/setup-templates/template-gas-and-elasticity-increase/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# Update Gas Limit, Elasticity & DA Footprint Gas Scalar in L1 `SystemConfig` - -Status: TODO[READY TO SIGN|DONE] - -## Description - -We are updating the gas limit, elasticity, and DA footprint gas scalar to improve TPS and reduce gas fees. - -This runbook invokes the following script which allows our signers to sign the same call with two different sets of parameters for our Incident Multisig, defined in the [base-org/contracts](https://github.com/base/contracts) repository: - -`IncreaseEip1559ElasticityAndIncreaseGasLimitScript` -- This script will update the gas limit to our new limit of TODO gas, TODO elasticity, and TODO DA footprint gas scalar if invoked as part of the "upgrade" process, or revert to the old limit of TODO gas, TODO elasticity, and TODO DA footprint gas scalar if invoked as part of the "rollback" process. - -### DA Footprint Gas Scalar - -Calculate the DA footprint gas scalar from the DA limits runbook: - -`go/base-da-config` - -`make da-scalar TARGET_BLOB_COUNT=` is the source of truth for the standard soft-cap policy. Since BPO2, Base has used a DA soft-cap blob count of 21, passed as `TARGET_BLOB_COUNT=21`, to allow the chain to use all L1 DA before raising the L2 base fee. Do not read this as Ethereum's target blob count; it is the blob-count input to Base's DA footprint scalar calculation. - -Record the inputs used for this task: - -Use the target network's `op_batcher_throttle_block_size_upper_limit` Config Service value for the builder hard cap row. - -- Mainnet: `https://config.cbhq.net/web3-shared-prod/protocols/base-mainnet-batcherproposer-k8s?q=op_batcher_throttle_block_size_upper_limit` -- Sepolia: `https://config.cbhq.net/web3-shared-prod/protocols/base-sepolia-batcherproposer-k8s?q=op_batcher_throttle_block_size_upper_limit` -- Zeronet: `https://config.cbhq.net/web3-shared-dev/protocols/base-zeronet-batcherproposer-k8s?q=op_batcher_throttle_block_size_upper_limit` - -| Field | Value | -|-------|-------| -| Gas limit | TODO | -| Elasticity | TODO | -| DA soft-cap blob count (`TARGET_BLOB_COUNT`) | TODO | -| Calculated scalar | TODO | -| Implied soft cap | TODO estimated DA bytes per L2 block | -| Builder hard cap | TODO estimated DA bytes per L2 block | - -The values we are sending are statically defined in the `.env` file. - -> [!IMPORTANT] We have two transactions to sign. Please follow -> the flow for both "Approving the Update transaction" and -> "Approving the Rollback transaction". Hopefully we only need -> the former, but will have the latter available if needed. - -## Approving the Update transaction - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -``` - -### 2. Run the signing tool (NOTE: do not enter the task directory. Run this command from the project's root). - -```bash -make sign-task -``` - -### 3. Open the UI at [http://localhost:3000](http://localhost:3000) - -Be sure to select the correct task from the list of available tasks to sign (**not** the "Base Signer Rollback" task). Copy the resulting signature and save it. - -### 4. Rollback signing - -Now, click on the "Base Signer" selection and switch over to the rollback task (called "Base Signer Rollback"). Copy the resulting signature and save it. - -### 5. Send signature to facilitator - -Send the two signatures to the facilitator and make sure to clearly note which one is the primary one and which one is the rollback. - -You may now kill the Signer Tool process in your terminal window by running `Ctrl + C`. diff --git a/setup-templates/template-gas-and-elasticity-increase/foundry.toml b/setup-templates/template-gas-and-elasticity-increase/foundry.toml deleted file mode 100644 index 07f5ee429..000000000 --- a/setup-templates/template-gas-and-elasticity-increase/foundry.toml +++ /dev/null @@ -1,23 +0,0 @@ -[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -broadcast = 'records' -fs_permissions = [ {access = "read-write", path = "./"} ] -optimizer = true -optimizer_runs = 999999 -solc_version = "0.8.15" -via-ir = false -remappings = [ - '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', - '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', - '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', - '@rari-capital/solmate/=lib/solmate/', - '@base-contracts/=lib/contracts', - '@solady/=lib/solady/src/' -] - -[lint] -lint_on_build = false - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/setup-templates/template-gas-and-elasticity-increase/script/IncreaseEip1559ElasticityAndIncreaseGasLimit.s.sol b/setup-templates/template-gas-and-elasticity-increase/script/IncreaseEip1559ElasticityAndIncreaseGasLimit.s.sol deleted file mode 100644 index 3b2e161af..000000000 --- a/setup-templates/template-gas-and-elasticity-increase/script/IncreaseEip1559ElasticityAndIncreaseGasLimit.s.sol +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {Vm} from "forge-std/Vm.sol"; - -import {Simulation} from "@base-contracts/script/universal/Simulation.sol"; -import {MultisigScript} from "@base-contracts/script/universal/MultisigScript.sol"; -import {Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; - -interface ISystemConfig { - function eip1559Elasticity() external view returns (uint32); - function eip1559Denominator() external view returns (uint32); - function setEIP1559Params(uint32 _denominator, uint32 _elasticity) external; - function gasLimit() external view returns (uint64); - function setGasLimit(uint64 _gasLimit) external; - function daFootprintGasScalar() external view returns (uint16); - function setDAFootprintGasScalar(uint16 _daFootprintGasScalar) external; -} - -contract IncreaseEip1559ElasticityAndIncreaseGasLimitScript is MultisigScript { - address internal immutable OWNER_SAFE; - address internal immutable SYSTEM_CONFIG; - - uint32 internal immutable ELASTICITY; - uint32 internal immutable NEW_ELASTICITY; - uint64 internal immutable GAS_LIMIT; - uint64 internal immutable NEW_GAS_LIMIT; - uint32 internal immutable DENOMINATOR; - uint16 internal immutable DA_FOOTPRINT_GAS_SCALAR; - uint16 internal immutable NEW_DA_FOOTPRINT_GAS_SCALAR; - - constructor() { - OWNER_SAFE = vm.envAddress("OWNER_SAFE"); - SYSTEM_CONFIG = vm.envAddress("SYSTEM_CONFIG"); - - GAS_LIMIT = uint64(vm.envUint("OLD_GAS_LIMIT")); - NEW_GAS_LIMIT = uint64(vm.envUint("NEW_GAS_LIMIT")); - - ELASTICITY = uint32(vm.envUint("OLD_ELASTICITY")); - NEW_ELASTICITY = uint32(vm.envUint("NEW_ELASTICITY")); - - DA_FOOTPRINT_GAS_SCALAR = uint16(vm.envUint("OLD_DA_FOOTPRINT_GAS_SCALAR")); - NEW_DA_FOOTPRINT_GAS_SCALAR = uint16(vm.envUint("NEW_DA_FOOTPRINT_GAS_SCALAR")); - - DENOMINATOR = ISystemConfig(SYSTEM_CONFIG).eip1559Denominator(); - } - - function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override { - vm.assertEq(ISystemConfig(SYSTEM_CONFIG).eip1559Denominator(), DENOMINATOR, "Denominator mismatch"); - vm.assertEq(ISystemConfig(SYSTEM_CONFIG).eip1559Elasticity(), NEW_ELASTICITY, "Elasticity mismatch"); - vm.assertEq(ISystemConfig(SYSTEM_CONFIG).gasLimit(), NEW_GAS_LIMIT, "Gas Limit mismatch"); - vm.assertEq( - ISystemConfig(SYSTEM_CONFIG).daFootprintGasScalar(), - NEW_DA_FOOTPRINT_GAS_SCALAR, - "DA Footprint Gas Scalar mismatch" - ); - } - - function _simulationOverrides() internal view override returns (Simulation.StateOverride[] memory _stateOverrides) { - if ( - GAS_LIMIT != ISystemConfig(SYSTEM_CONFIG).gasLimit() - || ELASTICITY != ISystemConfig(SYSTEM_CONFIG).eip1559Elasticity() - || DA_FOOTPRINT_GAS_SCALAR != ISystemConfig(SYSTEM_CONFIG).daFootprintGasScalar() - ) { - // Override SystemConfig state to the expected "from" values so simulations succeeds even - // when the chain already reflects the post-change values (during rollback simulation). - - // Prepare two storage overrides for SystemConfig - Simulation.StateOverride[] memory stateOverrides = new Simulation.StateOverride[](1); - Simulation.StorageOverride[] memory storageOverrides = new Simulation.StorageOverride[](2); - - // Load current packed gas config (slot 0x68) and replace only the lower 64 bits with GAS_LIMIT - bytes32 gasConfigSlotKey = bytes32(uint256(0x68)); - uint256 gasConfigWord = uint256(vm.load(SYSTEM_CONFIG, gasConfigSlotKey)); - uint256 updatedGasConfigWord = (gasConfigWord & ~uint256(0xffffffffffffffff)) | uint256(GAS_LIMIT); - storageOverrides[0] = - Simulation.StorageOverride({key: gasConfigSlotKey, value: bytes32(updatedGasConfigWord)}); - - // Update EIP-1559 params and DA Footprint Gas Scalar (slot 0x6a) - // Storage layout (low to high bits): - // - eip1559Denominator (uint32): bits 0-31 - // - eip1559Elasticity (uint32): bits 32-63 - // - operatorFeeScalar (uint32): bits 64-95 - // - operatorFeeConstant (uint64): bits 96-159 - // - daFootprintGasScalar (uint16): bits 160-175 - // Load existing slot to preserve operatorFeeScalar and operatorFeeConstant, then update - // the fields we care about. - bytes32 eip1559SlotKey = bytes32(uint256(0x6a)); - uint256 existingEip1559Word = uint256(vm.load(SYSTEM_CONFIG, eip1559SlotKey)); - // Mask to preserve bits 64-159 (operatorFeeScalar and operatorFeeConstant) - uint256 operatorFeeMask = uint256(0xFFFFFFFFFFFFFFFFFFFFFFFF) << 64; - uint256 preservedOperatorFees = existingEip1559Word & operatorFeeMask; - uint256 composedEip1559Word = (uint256(DA_FOOTPRINT_GAS_SCALAR) << 160) | preservedOperatorFees - | (uint256(ELASTICITY) << 32) | uint256(DENOMINATOR); - storageOverrides[1] = Simulation.StorageOverride({key: eip1559SlotKey, value: bytes32(composedEip1559Word)}); - - stateOverrides[0] = Simulation.StateOverride({contractAddress: SYSTEM_CONFIG, overrides: storageOverrides}); - return stateOverrides; - } - } - - function _buildCalls() internal view override returns (Call[] memory) { - Call[] memory calls = new Call[](3); - - calls[0] = Call({ - operation: Enum.Operation.Call, - target: SYSTEM_CONFIG, - data: abi.encodeCall(ISystemConfig.setEIP1559Params, (DENOMINATOR, NEW_ELASTICITY)), - value: 0 - }); - - calls[1] = Call({ - operation: Enum.Operation.Call, - target: SYSTEM_CONFIG, - data: abi.encodeCall(ISystemConfig.setGasLimit, (NEW_GAS_LIMIT)), - value: 0 - }); - - calls[2] = Call({ - operation: Enum.Operation.Call, - target: SYSTEM_CONFIG, - data: abi.encodeCall(ISystemConfig.setDAFootprintGasScalar, (NEW_DA_FOOTPRINT_GAS_SCALAR)), - value: 0 - }); - - return calls; - } - - function _ownerSafe() internal view override returns (address) { - return OWNER_SAFE; - } -} diff --git a/setup-templates/template-gas-increase/.env b/setup-templates/template-gas-increase/.env deleted file mode 100644 index 0e54ee1f3..000000000 --- a/setup-templates/template-gas-increase/.env +++ /dev/null @@ -1,10 +0,0 @@ -# Required: Git commit hash for https://github.com/base/contracts -BASE_CONTRACTS_COMMIT=be7c7a642e430fa64b04b63203839f8c81f48466 - -# Network-specific addresses are automatically loaded from {network}/.env via include ../.env - -# Required: Current gas limit on chain (for validation) -OLD_GAS_LIMIT=TODO - -# Required: New gas limit to set -NEW_GAS_LIMIT=TODO diff --git a/setup-templates/template-gas-increase/FACILITATOR.md b/setup-templates/template-gas-increase/FACILITATOR.md deleted file mode 100644 index f3a0b84b0..000000000 --- a/setup-templates/template-gas-increase/FACILITATOR.md +++ /dev/null @@ -1,22 +0,0 @@ -# Facilitator Guide - -Guide for facilitators managing this task. - -## Task Origin Signing - -After setting up the task, generate cryptographic attestations (sigstore bundles) to prove who created and facilitated the task. These signatures are stored in `/signatures//`. - -### Task creator (run after task setup): -```bash -make sign-as-task-creator -``` - -### Base facilitator: -```bash -make sign-as-base-facilitator -``` - -### Security Council facilitator: -```bash -make sign-as-sc-facilitator -``` diff --git a/setup-templates/template-gas-increase/Makefile b/setup-templates/template-gas-increase/Makefile deleted file mode 100644 index c357033dc..000000000 --- a/setup-templates/template-gas-increase/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -include ../../Makefile -include ../../Multisig.mk -include ../.env -include .env - -# Map config variables to script variables -L1_SYSTEM_CONFIG_ADDRESS ?= $(SYSTEM_CONFIG) -SYSTEM_CONFIG_OWNER ?= $(INCIDENT_MULTISIG) - -ifndef ROLLBACK_NONCE_OFFSET -override ROLLBACK_NONCE_OFFSET = 1 -endif - -RPC_URL = $(L1_RPC_URL) -# SCRIPT_NAME can be a Solidity file path (not just a class name); forge accepts both. -SCRIPT_NAME = lib/base-contracts/script/deploy/l1/SetGasLimit.sol - -# Validate required configuration before execution -.PHONY: validate-config -validate-config: - @test -n "$(BASE_CONTRACTS_COMMIT)" -a "$(BASE_CONTRACTS_COMMIT)" != "TODO" || (echo "BASE_CONTRACTS_COMMIT required" && exit 1) - @test -n "$(L1_SYSTEM_CONFIG_ADDRESS)" || (echo "L1_SYSTEM_CONFIG_ADDRESS required" && exit 1) - @test -n "$(SYSTEM_CONFIG_OWNER)" || (echo "SYSTEM_CONFIG_OWNER required" && exit 1) - @test -n "$(OLD_GAS_LIMIT)" -a "$(OLD_GAS_LIMIT)" != "TODO" || (echo "OLD_GAS_LIMIT required" && exit 1) - @test -n "$(NEW_GAS_LIMIT)" -a "$(NEW_GAS_LIMIT)" != "TODO" || (echo "NEW_GAS_LIMIT required" && exit 1) - @echo "Configuration validated successfully" - -.PHONY: sign-upgrade -sign-upgrade: validate-config - FROM_GAS_LIMIT=$(OLD_GAS_LIMIT) \ - TO_GAS_LIMIT=$(NEW_GAS_LIMIT) \ - $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ - $(MISE_EXEC) forge script --rpc-url $(L1_RPC_URL) lib/base-contracts/script/deploy/l1/SetGasLimit.sol \ - --sig "sign()" - -.PHONY: execute-upgrade -execute-upgrade: validate-config - FROM_GAS_LIMIT=$(OLD_GAS_LIMIT) \ - TO_GAS_LIMIT=$(NEW_GAS_LIMIT) \ - $(call MULTISIG_EXECUTE,$(SIGNATURES)) - -.PHONY: sign-rollback -sign-rollback: validate-config - FROM_GAS_LIMIT=$(NEW_GAS_LIMIT) \ - TO_GAS_LIMIT=$(OLD_GAS_LIMIT) \ - SAFE_NONCE=$(shell expr $(call GET_NONCE,$(SYSTEM_CONFIG_OWNER)) + $(ROLLBACK_NONCE_OFFSET)) \ - $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \ - $(MISE_EXEC) forge script --rpc-url $(L1_RPC_URL) lib/base-contracts/script/deploy/l1/SetGasLimit.sol \ - --sig "sign()" - -.PHONY: execute-rollback -execute-rollback: validate-config - FROM_GAS_LIMIT=$(NEW_GAS_LIMIT) \ - TO_GAS_LIMIT=$(OLD_GAS_LIMIT) \ - SAFE_NONCE=$(shell expr $(call GET_NONCE,$(SYSTEM_CONFIG_OWNER)) + $(ROLLBACK_NONCE_OFFSET)) \ - $(call MULTISIG_EXECUTE,$(SIGNATURES)) diff --git a/setup-templates/template-gas-increase/README.md b/setup-templates/template-gas-increase/README.md deleted file mode 100644 index e944c732e..000000000 --- a/setup-templates/template-gas-increase/README.md +++ /dev/null @@ -1,289 +0,0 @@ -# Update Gas Limit in L1 `SystemConfig` - -Status: TODO[READY TO SIGN|DONE] - -## Objective - -We are updating the gas limit to improve TPS and reduce gas fees. - -This runbook invokes the following script which allows our signers to sign the same call with two different sets of parameters for our Incident Multisig, defined in the [base-org/contracts](https://github.com/base-org/contracts) repository: - -`SetGasLimit` -- This script will update the gas limit to our new limit of TODO gas if invoked as part of the "upgrade" process, or revert to the old limit of TODO gas if invoked as part of the "rollback" process. - -The values we are sending are statically defined in the `.env`. - -> [!IMPORTANT] We have two transactions to sign. Please follow -> the flow for both "Approving the Update transaction" and -> "Approving the Rollback transaction". Hopefully we only need -> the former, but will have the latter available if needed. - -## Approving the Upgrade transaction - -### 1. Update repo and move to the appropriate folder: - -``` -cd contract-deployments -git pull -cd mainnet/TODO -make deps -``` - -### 2. Setup Ledger - -Your Ledger needs to be connected and unlocked. The Ethereum -application needs to be opened on Ledger with the message "Application -is ready". - -### 3. Simulate and validate the transaction - -Make sure your ledger is still unlocked and run the following. - -```shell -make sign-upgrade -``` - -Once you run the `make sign...` command successfully, you will see a "Simulation link" from the output. - -Paste this URL in your browser. A prompt may ask you to choose a -project, any project will do. You can create one if necessary. - -Click "Simulate Transaction". - -We will be performing 3 validations and then we'll extract the domain hash and -message hash to approve on your Ledger then verify completion: - -1. Validate integrity of the simulation. -2. Validate correctness of the state diff. -3. Validate and extract domain hash and message hash to approve. - -#### 3.1. Validate integrity of the simulation. - -Make sure you are on the "Summary" tab of the tenderly simulation, to -validate integrity of the simulation, we need to check the following: - -1. "Network": Check the network is Ethereum Mainnet. -2. "Timestamp": Check the simulation is performed on a block with a - recent timestamp (i.e. close to when you run the script). -3. "Sender": Check the address shown is your signer account. If not, - you will need to determine which “number” it is in the list of - addresses on your ledger. -4. "Success" with a green check mark - -#### 3.2. Validate correctness of the state diff. - -Now click on the "State" tab. Verify that: - -1. Verify that the nonce is incremented for the Incident Multisig under the "GnosisSafeProxy" at address `0x14536667Cd30e52C0b458BaACcB9faDA7046E056`. We should see the nonce increment from TODO to TODO: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000005 -Before: TODO -After: TODO -``` - -2. Verify that gas limit value is appropriately updated under "Proxy" at address `0x73a79fab69143498ed3712e519a88a918e1f4072`. We should see that the gas limit has been changed from TODO to TODO: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000068 -Before: TODO -After: TODO -``` - -#### 3.3. Extract the domain hash and the message hash to approve. - -Now that we have verified the transaction performs the right -operation, we need to extract the domain hash and the message hash to -approve. - -Go back to the "Summary" tab, and find the -`Safe.checkSignatures` call. This call's `data` parameter -contains both the domain hash and the message hash that will show up -in your Ledger. - -Here is an example screenshot. Note that the value will be -different for each signer: - -![Screenshot 2024-03-07 at 5 49 02 PM](https://github.com/base-org/contract-deployments/assets/84420280/1b7905f1-1350-4634-a804-7b4458d0ddc9) - -It will be a concatenation of `0x1901`, the domain hash, and the -message hash: `0x1901[domain hash][message hash]`. - -Note down this value. You will need to compare it with the ones -displayed on the Ledger screen at signing. - -### 4. Approve the signature on your ledger - -Once the validations are done, it's time to actually sign the -transaction. Make sure your ledger is still unlocked and run the -following: - -```shell -make sign-upgrade -``` - -> [!IMPORTANT] This is the most security critical part of the -> playbook: make sure the domain hash and message hash in the -> following two places match: - -1. on your Ledger screen. -2. in the Tenderly simulation. You should use the same Tenderly - simulation as the one you used to verify the state diffs, instead - of opening the new one printed in the console. - -There is no need to verify anything printed in the console. There is -no need to open the new Tenderly simulation link either. - -After verification, sign the transaction. You will see the `Data`, -`Signer` and `Signature` printed in the console. Format should be -something like this: - -``` -Data: -Signer:
-Signature: -``` - -Double check the signer address is the right one. - -### 5. Send the output to Facilitator(s) - -Nothing has occurred onchain - these are offchain signatures which -will be collected by Facilitators for execution. Execution can occur -by anyone once a threshold of signatures are collected, so a -Facilitator will do the final execution for convenience. - -Share the `Data`, `Signer` and `Signature` with the Facilitator, and -congrats, you are done! - -## Approving the Rollback transaction - -Complete the above steps for `Approving the Update transaction` before continuing below. - -### 1. Simulate and validate the transaction - -Make sure your ledger is still unlocked and run the following. - -```shell -make sign-rollback -``` - -Once you run the make sign command successfully, you will see a "Simulation link" from the output. Once again paste this URL in your browser and click "Simulate Transaction". - -We will be performing 3 validations and then we'll extract the domain hash and -message hash to approve on your Ledger then verify completion: - -1. Validate integrity of the simulation. -2. Validate correctness of the state diff. -3. Validate and extract domain hash and message hash to approve. -4. Validate that the transaction completed successfully - -#### 3.1. Validate integrity of the simulation. - -Make sure you are on the "Summary" tab of the tenderly simulation, to -validate integrity of the simulation, we need to check the following: - -1. "Network": Check the network is Ethereum Mainnet. -2. "Timestamp": Check the simulation is performed on a block with a - recent timestamp (i.e. close to when you run the script). -3. "Sender": Check the address shown is your signer account. If not, - you will need to determine which “number” it is in the list of - addresses on your ledger. -4. "Success" with a green check mark - -#### 3.2. Validate correctness of the state diff. - -Now click on the "State" tab. Verify that: - -1. Verify that the nonce is incremented for the Incident Multisig under the "GnosisSafeProxy" at address `0x14536667Cd30e52C0b458BaACcB9faDA7046E056`: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000005 -Before: TODO -After: TODO -``` - -2. Verify that gas limit value is appropriately updated under "Proxy" at address `0x73a79fab69143498ed3712e519a88a918e1f4072`: - -``` -Key: 0x0000000000000000000000000000000000000000000000000000000000000068 -Before: TODO -After: TODO -``` - -#### 3.3. Extract the domain hash and the message hash to approve. - -Now that we have verified the transaction performs the right -operation, we need to extract the domain hash and the message hash to -approve. - -Go back to the "Summary" tab, and find the -`Safe.checkSignatures` call. This call's `data` parameter -contains both the domain hash and the message hash that will show up -in your Ledger. - -Here is an example screenshot. Note that the value will be -different for each signer: - -![Screenshot 2024-03-07 at 5 49 32 PM](https://github.com/base-org/contract-deployments/assets/84420280/b6b5817f-0d05-4862-b16a-4f7f5f18f036) - -It will be a concatenation of `0x1901`, the domain hash, and the -message hash: `0x1901[domain hash][message hash]`. - -Note down this value. You will need to compare it with the ones -displayed on the Ledger screen at signing. - -### 4. Approve the signature on your ledger - -Once the validations are done, it's time to actually sign the -transaction. Make sure your ledger is still unlocked and run the -following: - -```shell -make sign-rollback -``` - -> [!IMPORTANT] This is the most security critical part of the -> playbook: make sure the domain hash and message hash in the -> following two places match: - -1. on your Ledger screen. -2. in the Tenderly simulation. You should use the same Tenderly - simulation as the one you used to verify the state diffs, instead - of opening the new one printed in the console. - -There is no need to verify anything printed in the console. There is -no need to open the new Tenderly simulation link either. - -After verification, sign the transaction. You will see the `Data`, -`Signer` and `Signature` printed in the console. Format should be -something like this: - -``` -Data: -Signer:
-Signature: -``` - -Double check the signer address is the right one. - -### 5. Send the output to Facilitator(s) - -Nothing has occurred onchain - these are offchain signatures which -will be collected by Facilitators for execution. Execution can occur -by anyone once a threshold of signatures are collected, so a -Facilitator will do the final execution for convenience. - -Share the `Data`, `Signer` and `Signature` with the Facilitator, and -congrats, you are done! - -## Execute the output - -1. Collect outputs from all participating signers. -2. Concatenate all signatures and export it as the `SIGNATURES` - environment variable, i.e. `export -SIGNATURES="0x[SIGNATURE1][SIGNATURE2]..."`. -3. Run `make execute-upgrade` - -> [!IMPORTANT] IN THE EVENT WE NEED TO PERFORM ROLLBACK -> Repeat the above, but replace the signatures with the signed -> rollback signatures collected, the call `make execute-rollback` diff --git a/setup-templates/template-gas-increase/foundry.toml b/setup-templates/template-gas-increase/foundry.toml deleted file mode 100644 index 07f5ee429..000000000 --- a/setup-templates/template-gas-increase/foundry.toml +++ /dev/null @@ -1,23 +0,0 @@ -[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -broadcast = 'records' -fs_permissions = [ {access = "read-write", path = "./"} ] -optimizer = true -optimizer_runs = 999999 -solc_version = "0.8.15" -via-ir = false -remappings = [ - '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', - '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', - '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', - '@rari-capital/solmate/=lib/solmate/', - '@base-contracts/=lib/contracts', - '@solady/=lib/solady/src/' -] - -[lint] -lint_on_build = false - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/setup-templates/template-pause-bridge-base/.env b/setup-templates/template-pause-bridge-base/.env deleted file mode 100644 index ed32b12bd..000000000 --- a/setup-templates/template-pause-bridge-base/.env +++ /dev/null @@ -1,12 +0,0 @@ -# Required: Git commit hash for https://github.com/base/contracts -BASE_CONTRACTS_COMMIT=be7c7a642e430fa64b04b63203839f8c81f48466 - -# Network-specific addresses are automatically loaded from {network}/.env via include ../.env - -# Required: L2 Bridge contract address to pause/unpause -# Mainnet: 0x3eff766C76a1be2Ce1aCF2B69c78bCae257D5188 -# Sepolia: 0x01824a90d32A69022DdAEcC6C5C14Ed08dB4EB9B -L2_BRIDGE= - -# Enable state diff recording for validation -RECORD_STATE_DIFF=true diff --git a/setup-templates/template-pause-bridge-base/FACILITATOR.md b/setup-templates/template-pause-bridge-base/FACILITATOR.md deleted file mode 100644 index b19abfc13..000000000 --- a/setup-templates/template-pause-bridge-base/FACILITATOR.md +++ /dev/null @@ -1,45 +0,0 @@ -# Facilitator Guide - -Guide for facilitators managing this task. - -## Task Origin Signing - -After setting up the task, generate cryptographic attestations (sigstore bundles) to prove who created and facilitated the task. These signatures are stored in `/signatures//`. - -### Task creator (run after task setup): -```bash -make sign-as-task-creator -``` - -### Base facilitator: -```bash -make sign-as-base-facilitator -``` - -### Security Council facilitator: -```bash -make sign-as-sc-facilitator -``` - -## Execution - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -cd / -make deps -``` - -### 2. Execute pause - -```bash -SIGNATURES=AAABBBCCC make execute-pause -``` - -### 3. (When ready) Execute un-pause - -```bash -SIGNATURES=AAABBBCCC make execute-unpause -``` diff --git a/setup-templates/template-pause-bridge-base/Makefile b/setup-templates/template-pause-bridge-base/Makefile deleted file mode 100644 index dc55923c5..000000000 --- a/setup-templates/template-pause-bridge-base/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -include ../../Makefile -include ../../Multisig.mk -include ../.env -include .env - -# Map config variables to script variables -OWNER_SAFE ?= $(INCIDENT_MULTISIG) -L1_PORTAL ?= $(OPTIMISM_PORTAL) - -# Auto-fetch SAFE_NONCE from chain if not explicitly set (e.g., via .env) -ifndef SAFE_NONCE -SAFE_NONCE := $(call GET_NONCE,$(OWNER_SAFE)) -endif -# TODO: ensure `sender` is a signer for `OWNER_SAFE` -SENDER=0x1841CB3C2ce6870D0417844C817849da64E6e937 - -RPC_URL = $(L1_RPC_URL) -SCRIPT_NAME = PauseBridge - -ZERO_ADDRESS = 0x0000000000000000000000000000000000000000 -SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8 -SAFE_TX_ABI = f(bytes32,address,uint256,bytes32,uint8,uint256,uint256,uint256,address,address,uint256) - -# Validate required configuration before execution -.PHONY: validate-config -validate-config: - @test -n "$(BASE_CONTRACTS_COMMIT)" || (echo "BASE_CONTRACTS_COMMIT required" && exit 1) - @test -n "$(OWNER_SAFE)" || (echo "OWNER_SAFE required" && exit 1) - @test -n "$(L1_PORTAL)" || (echo "L1_PORTAL required" && exit 1) - @test -n "$(L2_BRIDGE)" || (echo "L2_BRIDGE required" && exit 1) - @test -n "$(SENDER)" || (echo "SENDER required" && exit 1) - @test -n "$(SAFE_NONCE)" || (echo "SAFE_NONCE required" && exit 1) - @echo "Configuration validated successfully" - -.PHONY: gen-validation -gen-validation: validate-config deps-signer-tool - $(call GEN_VALIDATION,$(SCRIPT_NAME),,$(SENDER),base-signer.json,IS_PAUSED=true) - -.PHONY: sign-pause -sign-pause: validate-config - @rm -f signatures-pause.txt - @set -e; \ - domain_separator=$$($(MISE_EXEC) cast call $(OWNER_SAFE) "domainSeparator()(bytes32)" --rpc-url $(L1_RPC_URL)); \ - bridge_data=$$($(MISE_EXEC) cast calldata "setPaused(bool)" true); \ - portal_data=$$($(MISE_EXEC) cast calldata "depositTransaction(address,uint256,uint64,bool,bytes)" $(L2_BRIDGE) 0 100000 false $$bridge_data); \ - portal_data_hash=$$($(MISE_EXEC) cast keccak "$$portal_data"); \ - for i in $$(seq 0 19); do \ - nonce=$$(($(SAFE_NONCE) + $$i)); \ - echo "Signing with nonce $$nonce"; \ - safe_tx=$$($(MISE_EXEC) cast abi-encode '$(SAFE_TX_ABI)' $(SAFE_TX_TYPEHASH) $(L1_PORTAL) 0 $$portal_data_hash 0 0 0 0 $(ZERO_ADDRESS) $(ZERO_ADDRESS) $$nonce); \ - message_hash=$$($(MISE_EXEC) cast keccak "$$safe_tx"); \ - signing_data="0x1901$${domain_separator#0x}$${message_hash#0x}"; \ - $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -data "$$signing_data" > sign_output.tmp; \ - cat sign_output.tmp; \ - echo "Nonce: $$nonce" >> signatures-pause.txt; \ - grep -E "^Data:|^Signer:|^Signature:" sign_output.tmp >> signatures-pause.txt || true; \ - echo "" >> signatures-pause.txt; \ - rm -f sign_output.tmp; \ - done - -.PHONY: sign-unpause -sign-unpause: validate-config - @rm -f signatures-unpause.txt - @set -e; \ - domain_separator=$$($(MISE_EXEC) cast call $(OWNER_SAFE) "domainSeparator()(bytes32)" --rpc-url $(L1_RPC_URL)); \ - bridge_data=$$($(MISE_EXEC) cast calldata "setPaused(bool)" false); \ - portal_data=$$($(MISE_EXEC) cast calldata "depositTransaction(address,uint256,uint64,bool,bytes)" $(L2_BRIDGE) 0 100000 false $$bridge_data); \ - portal_data_hash=$$($(MISE_EXEC) cast keccak "$$portal_data"); \ - for i in $$(seq 0 19); do \ - nonce=$$(($(SAFE_NONCE) + $$i)); \ - echo "Signing with nonce $$nonce"; \ - safe_tx=$$($(MISE_EXEC) cast abi-encode '$(SAFE_TX_ABI)' $(SAFE_TX_TYPEHASH) $(L1_PORTAL) 0 $$portal_data_hash 0 0 0 0 $(ZERO_ADDRESS) $(ZERO_ADDRESS) $$nonce); \ - message_hash=$$($(MISE_EXEC) cast keccak "$$safe_tx"); \ - signing_data="0x1901$${domain_separator#0x}$${message_hash#0x}"; \ - $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -data "$$signing_data" > sign_output.tmp; \ - cat sign_output.tmp; \ - echo "Nonce: $$nonce" >> signatures-unpause.txt; \ - grep -E "^Data:|^Signer:|^Signature:" sign_output.tmp >> signatures-unpause.txt || true; \ - echo "" >> signatures-unpause.txt; \ - rm -f sign_output.tmp; \ - done - -# Execute -.PHONY: execute-pause -execute-pause: validate-config - IS_PAUSED=true $(call MULTISIG_EXECUTE,$(SIGNATURES)) - -.PHONY: execute-unpause -execute-unpause: validate-config - IS_PAUSED=false $(call MULTISIG_EXECUTE,$(SIGNATURES)) - -.PHONY: check-status -check-status: - $(MISE_EXEC) cast call $(L2_BRIDGE) "paused()" --rpc-url $(L2_RPC_URL) diff --git a/setup-templates/template-pause-bridge-base/README.md b/setup-templates/template-pause-bridge-base/README.md deleted file mode 100644 index d3aa7e957..000000000 --- a/setup-templates/template-pause-bridge-base/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Pause Base Bridge - -Status: READY TO SIGN - -## Description - -Pauses the Base side of [Base Bridge](https://github.com/base/bridge). - -## Sign Task - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -cd / -make deps -``` - -### 2. Sign pause transactions - -```bash -make sign-pause -``` - -### 3. Sign unpause transactions - -```bash -make sign-unpause -``` - -### 4. Send all signatures to facilitator diff --git a/setup-templates/template-pause-bridge-base/foundry.toml b/setup-templates/template-pause-bridge-base/foundry.toml deleted file mode 100644 index a8a0b9428..000000000 --- a/setup-templates/template-pause-bridge-base/foundry.toml +++ /dev/null @@ -1,24 +0,0 @@ -[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -broadcast = 'records' -fs_permissions = [{ access = "read-write", path = "./" }] -optimizer = true -optimizer_runs = 999999 -solc_version = "0.8.15" -via-ir = false -remappings = [ - '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', - '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', - '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', - '@rari-capital/solmate/=lib/solmate/', - '@base-contracts/=lib/contracts', - '@solady/=lib/solady/src/', - '@lib-keccak=lib/lib-keccak/contracts/lib/' -] - -[lint] -lint_on_build = false - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/setup-templates/template-pause-bridge-base/script/PauseBridge.s.sol b/setup-templates/template-pause-bridge-base/script/PauseBridge.s.sol deleted file mode 100644 index 4a4200307..000000000 --- a/setup-templates/template-pause-bridge-base/script/PauseBridge.s.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {Vm} from "forge-std/Vm.sol"; - -import {Simulation} from "@base-contracts/script/universal/Simulation.sol"; -import {MultisigScript} from "@base-contracts/script/universal/MultisigScript.sol"; -import {Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; - -interface IOptimismPortal2 { - function depositTransaction(address _to, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes memory _data) - external - payable; -} - -interface IBridge { - function setPaused(bool) external; -} - -contract PauseBridge is MultisigScript { - address public immutable OWNER_SAFE = vm.envAddress("OWNER_SAFE"); - address public immutable L1_PORTAL = vm.envAddress("L1_PORTAL"); - address public immutable L2_BRIDGE = vm.envAddress("L2_BRIDGE"); - bool public immutable IS_PAUSED = vm.envBool("IS_PAUSED"); - - function _buildCalls() internal view override returns (Call[] memory) { - Call[] memory calls = new Call[](1); - - address to = L2_BRIDGE; - uint256 value = 0; - uint64 gasLimit = 100_000; - bool isCreation = false; - bytes memory data = abi.encodeCall(IBridge.setPaused, (IS_PAUSED)); - - calls[0] = Call({ - operation: Enum.Operation.Call, - target: L1_PORTAL, - data: abi.encodeCall(IOptimismPortal2.depositTransaction, (to, value, gasLimit, isCreation, data)), - value: value - }); - - return calls; - } - - function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override {} - - function _ownerSafe() internal view override returns (address) { - return OWNER_SAFE; - } -} diff --git a/setup-templates/template-pause-superchain-config/.env b/setup-templates/template-pause-superchain-config/.env deleted file mode 100644 index 892f5b7db..000000000 --- a/setup-templates/template-pause-superchain-config/.env +++ /dev/null @@ -1,7 +0,0 @@ -# Any change to the base contracts commit hash could result in breaking our internal pausing system -# Ensure there are no breaking changes if this must be changed, otherwise an accompanying update to our internal pauser is also required -BASE_CONTRACTS_COMMIT=be7c7a642e430fa64b04b63203839f8c81f48466 - -# Network-specific addresses are automatically loaded from {network}/.env via include ../.env - -RECORD_STATE_DIFF=true diff --git a/setup-templates/template-pause-superchain-config/FACILITATOR.md b/setup-templates/template-pause-superchain-config/FACILITATOR.md deleted file mode 100644 index 3cd0121c0..000000000 --- a/setup-templates/template-pause-superchain-config/FACILITATOR.md +++ /dev/null @@ -1,45 +0,0 @@ -# Facilitator Guide - -Guide for facilitators managing this task. - -## Task Origin Signing - -After setting up the task, generate cryptographic attestations (sigstore bundles) to prove who created and facilitated the task. These signatures are stored in `/signatures//`. - -### Task creator (run after task setup): -```bash -make sign-as-task-creator -``` - -### Base facilitator: -```bash -make sign-as-base-facilitator -``` - -### Security Council facilitator: -```bash -make sign-as-sc-facilitator -``` - -## Execution - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -cd / -make deps -``` - -### 2. Check current pause status - -```bash -make check-status -``` - -### 3. Execute pause - -```bash -SIGNATURES=AAABBBCCC make execute-pause -``` diff --git a/setup-templates/template-pause-superchain-config/Makefile b/setup-templates/template-pause-superchain-config/Makefile deleted file mode 100644 index ac02c11df..000000000 --- a/setup-templates/template-pause-superchain-config/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -include ../../Makefile -include ../../Multisig.mk -include ../.env -include .env - -export INCIDENT_MULTISIG -export SYSTEM_CONFIG - -RPC_URL = $(L1_RPC_URL) -SCRIPT_NAME = PauseSuperchainConfig - -ZERO_ADDRESS = 0x0000000000000000000000000000000000000000 -SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8 -SAFE_TX_ABI = f(bytes32,address,uint256,bytes32,uint8,uint256,uint256,uint256,address,address,uint256) - -.PHONY: sign-pause -sign-pause: - @rm -f signatures-pause.txt - @set -e; \ - start_nonce_hex=$$($(MISE_EXEC) cast call $(INCIDENT_MULTISIG) "nonce()(uint256)" --rpc-url $(L1_RPC_URL)); \ - start_nonce=$$($(MISE_EXEC) cast to-dec "$$start_nonce_hex"); \ - superchain_config=$$($(MISE_EXEC) cast call $(SYSTEM_CONFIG) "superchainConfig()(address)" --rpc-url $(L1_RPC_URL)); \ - domain_separator=$$($(MISE_EXEC) cast call $(INCIDENT_MULTISIG) "domainSeparator()(bytes32)" --rpc-url $(L1_RPC_URL)); \ - call_data=$$($(MISE_EXEC) cast calldata "pause(address)" $(ZERO_ADDRESS)); \ - call_data_hash=$$($(MISE_EXEC) cast keccak "$$call_data"); \ - echo "Starting nonce: $$start_nonce"; \ - for i in $$(seq 0 19); do \ - nonce=$$(($$start_nonce + $$i)); \ - echo "Signing with nonce $$nonce"; \ - safe_tx=$$($(MISE_EXEC) cast abi-encode '$(SAFE_TX_ABI)' $(SAFE_TX_TYPEHASH) $$superchain_config 0 $$call_data_hash 0 0 0 0 $(ZERO_ADDRESS) $(ZERO_ADDRESS) $$nonce); \ - message_hash=$$($(MISE_EXEC) cast keccak "$$safe_tx"); \ - signing_data="0x1901$${domain_separator#0x}$${message_hash#0x}"; \ - $(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -data "$$signing_data" > sign_output.tmp; \ - cat sign_output.tmp; \ - signer=$$(grep "^Signer:" sign_output.tmp | awk '{print $$2}'); \ - sig=$$(grep "^Signature:" sign_output.tmp | awk '{print $$2}'); \ - printf "%s," "$$signer:$$nonce:$$sig" >> signatures-pause.txt; \ - rm -f sign_output.tmp; \ - done; \ - echo "" >> signatures-pause.txt - -# Execute -.PHONY: execute-pause -execute-pause: - $(call MULTISIG_EXECUTE,$(SIGNATURES)) - -.PHONY: check-status -check-status: - @superchain_config=$$($(MISE_EXEC) cast call $(SYSTEM_CONFIG) "superchainConfig()" --rpc-url $(L1_RPC_URL)); \ - superchain_config=$$(echo $$superchain_config | sed 's/0x000000000000000000000000//'); \ - echo "SuperchainConfig address: 0x$$superchain_config"; \ - $(MISE_EXEC) cast call 0x$$superchain_config "paused()" --rpc-url $(L1_RPC_URL) - -.PHONY: check-nonce -check-nonce: - @echo "Incident Safe: $(INCIDENT_MULTISIG)" - @$(MISE_EXEC) cast call $(INCIDENT_MULTISIG) "nonce()" --rpc-url $(L1_RPC_URL) diff --git a/setup-templates/template-pause-superchain-config/README.md b/setup-templates/template-pause-superchain-config/README.md deleted file mode 100644 index b58f58773..000000000 --- a/setup-templates/template-pause-superchain-config/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Pause SuperchainConfig - -Status: READY TO SIGN - -## Description - -Pauses deposits/withdrawals Base. - -## Sign Pause Task - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -cd / -make deps -``` - -### 2. Sign pause transactions - -```bash -make sign-pause -``` - -This will output your signature batch to a `signatures-pause.txt` file. - -### 3. Send the contents of `signatures-pause.txt` to facilitator diff --git a/setup-templates/template-pause-superchain-config/foundry.toml b/setup-templates/template-pause-superchain-config/foundry.toml deleted file mode 100644 index 9b3091091..000000000 --- a/setup-templates/template-pause-superchain-config/foundry.toml +++ /dev/null @@ -1,25 +0,0 @@ -[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -broadcast = 'records' -fs_permissions = [{ access = "read-write", path = "./" }] -optimizer = true -optimizer_runs = 999999 -solc_version = "0.8.15" -via-ir = false -evm_version = "shanghai" -remappings = [ - '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', - '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', - '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', - '@rari-capital/solmate/=lib/solmate/', - '@base-contracts/=lib/contracts', - '@solady/=lib/solady/src/', - '@lib-keccak=lib/lib-keccak/contracts/lib/' -] - -[lint] -lint_on_build = false - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/setup-templates/template-pause-superchain-config/script/PauseSuperchainConfig.s.sol b/setup-templates/template-pause-superchain-config/script/PauseSuperchainConfig.s.sol deleted file mode 100644 index fca752807..000000000 --- a/setup-templates/template-pause-superchain-config/script/PauseSuperchainConfig.s.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {Vm} from "forge-std/Vm.sol"; -import {Simulation} from "@base-contracts/script/universal/Simulation.sol"; -import {MultisigScript} from "@base-contracts/script/universal/MultisigScript.sol"; -import {Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; - -interface ISystemConfig { - function superchainConfig() external view returns (address); -} - -interface ISuperchainConfig { - function pause(address _identifier) external; - function paused(address) external view returns (bool); -} - -contract PauseSuperchainConfig is MultisigScript { - address public immutable INCIDENT_MULTISIG = vm.envAddress("INCIDENT_MULTISIG"); - address public immutable SYSTEM_CONFIG = vm.envAddress("SYSTEM_CONFIG"); - - function _buildCalls() internal view override returns (Call[] memory) { - Call[] memory calls = new Call[](1); - - address superchainConfig = ISystemConfig(SYSTEM_CONFIG).superchainConfig(); - - calls[0] = Call({ - operation: Enum.Operation.Call, - target: superchainConfig, - data: abi.encodeCall(ISuperchainConfig.pause, (address(0))), - value: 0 - }); - - return calls; - } - - function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override { - address superchainConfig = ISystemConfig(SYSTEM_CONFIG).superchainConfig(); - bool paused = ISuperchainConfig(superchainConfig).paused(address(0)); - require(paused == true, "PauseSuperchainConfig: chain is not paused"); - } - - function _ownerSafe() internal view override returns (address) { - return INCIDENT_MULTISIG; - } -} diff --git a/setup-templates/template-safe-management/.env b/setup-templates/template-safe-management/.env deleted file mode 100644 index 096d9a7f8..000000000 --- a/setup-templates/template-safe-management/.env +++ /dev/null @@ -1,14 +0,0 @@ -# Required: Git commit hash for https://github.com/base/contracts -BASE_CONTRACTS_COMMIT=be7c7a642e430fa64b04b63203839f8c81f48466 - -# Network-specific addresses are automatically loaded from {network}/.env via include ../.env - -# Required: Address of the Gnosis Safe whose signers will be updated -OWNER_SAFE=TODO - -# Required: Address of a signer on OWNER_SAFE (used for simulation) -# Must also match the sender defined in validations/base-signer.json -SENDER=TODO - -# Enable state diff recording for validation -RECORD_STATE_DIFF=true diff --git a/setup-templates/template-safe-management/FACILITATOR.md b/setup-templates/template-safe-management/FACILITATOR.md deleted file mode 100644 index f3a0b84b0..000000000 --- a/setup-templates/template-safe-management/FACILITATOR.md +++ /dev/null @@ -1,22 +0,0 @@ -# Facilitator Guide - -Guide for facilitators managing this task. - -## Task Origin Signing - -After setting up the task, generate cryptographic attestations (sigstore bundles) to prove who created and facilitated the task. These signatures are stored in `/signatures//`. - -### Task creator (run after task setup): -```bash -make sign-as-task-creator -``` - -### Base facilitator: -```bash -make sign-as-base-facilitator -``` - -### Security Council facilitator: -```bash -make sign-as-sc-facilitator -``` diff --git a/setup-templates/template-safe-management/Makefile b/setup-templates/template-safe-management/Makefile deleted file mode 100644 index 68c59d3cf..000000000 --- a/setup-templates/template-safe-management/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -include ../../Makefile -include ../../Multisig.mk -include ../.env -include .env - -RPC_URL = $(L1_RPC_URL) -SCRIPT_NAME = UpdateSigners - -# Validate required configuration before execution -.PHONY: validate-config -validate-config: - @test -n "$(BASE_CONTRACTS_COMMIT)" -a "$(BASE_CONTRACTS_COMMIT)" != "TODO" || (echo "BASE_CONTRACTS_COMMIT required" && exit 1) - @test -n "$(OWNER_SAFE)" -a "$(OWNER_SAFE)" != "TODO" || (echo "OWNER_SAFE required" && exit 1) - @test -n "$(SENDER)" -a "$(SENDER)" != "TODO" || (echo "SENDER required" && exit 1) - @echo "Configuration validated successfully" - -.PHONY: deps -deps: new-forge-deps - -.PHONY: new-forge-deps -new-forge-deps: - $(MISE_EXEC) forge install --no-git safe-global/safe-smart-account@186a21a74b327f17fc41217a927dea7064f74604 - -.PHONY: gen-validation -gen-validation: validate-config deps-signer-tool - $(call GEN_VALIDATION,$(SCRIPT_NAME),,$(SENDER),base-signer.json,) - -.PHONY: execute -execute: validate-config - $(call MULTISIG_EXECUTE,$(SIGNATURES)) diff --git a/setup-templates/template-safe-management/OwnerDiff.json b/setup-templates/template-safe-management/OwnerDiff.json deleted file mode 100644 index f2321928d..000000000 --- a/setup-templates/template-safe-management/OwnerDiff.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "OwnersToAdd": [ - "0x0000000000000000000000000000000000000000" - ], - "OwnersToRemove": [ - "0x0000000000000000000000000000000000000001" - ] -} diff --git a/setup-templates/template-safe-management/README.md b/setup-templates/template-safe-management/README.md deleted file mode 100644 index d6ed5a5cb..000000000 --- a/setup-templates/template-safe-management/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Update Sepolia Incident Multisig Signers - -Status: TODO[READY TO SIGN|EXECUTED] - -## Description - -We wish to update the owners of our Incident Multisig to be consistent with the current state of our Base Chain Eng team. This involves removing signers that are no longer closely involved with the team, and adding new team members as signers. The exact signer changes are outlined in the [OwnerDiff.json](./OwnerDiff.json) file. - -## Approving Signers Update - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -``` - -### 2. Run the signing tool (NOTE: do not enter the task directory. Run this command from the project's root). - -```bash -make sign-task -``` - -### 3. Open the UI at [http://localhost:3000](http://localhost:3000) - -Be sure to select the correct task from the list of available tasks to sign. - -### 4. Send signature to facilitator - -You may now kill the Signer Tool process in your terminal window by running `Ctrl + C`. diff --git a/setup-templates/template-safe-management/foundry.toml b/setup-templates/template-safe-management/foundry.toml deleted file mode 100644 index 5b8fe4ae7..000000000 --- a/setup-templates/template-safe-management/foundry.toml +++ /dev/null @@ -1,23 +0,0 @@ -[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -broadcast = 'records' -fs_permissions = [{ access = "read-write", path = "./" }] -optimizer = true -optimizer_runs = 999999 -solc_version = "0.8.15" -via-ir = false -remappings = [ - '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', - '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', - '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', - '@rari-capital/solmate/=lib/solmate/', - '@base-contracts/=lib/contracts', - '@solady/=lib/solady/src/', -] - -[lint] -lint_on_build = false - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/setup-templates/template-safe-management/script/UpdateSigners.s.sol b/setup-templates/template-safe-management/script/UpdateSigners.s.sol deleted file mode 100644 index 958b42a35..000000000 --- a/setup-templates/template-safe-management/script/UpdateSigners.s.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {Vm} from "forge-std/Vm.sol"; -import {stdJson} from "forge-std/StdJson.sol"; -import {Simulation} from "@base-contracts/script/universal/Simulation.sol"; - -import {MultisigScript} from "@base-contracts/script/universal/MultisigScript.sol"; -import {GnosisSafe} from "safe-smart-account/GnosisSafe.sol"; -import {OwnerManager} from "safe-smart-account/base/OwnerManager.sol"; -import {Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; - -contract UpdateSigners is MultisigScript { - using stdJson for string; - - address public constant SENTINEL_OWNERS = address(0x1); - - address public immutable OWNER_SAFE; - uint256 public immutable THRESHOLD; - address[] public EXISTING_OWNERS; - - address[] public OWNERS_TO_ADD; - address[] public OWNERS_TO_REMOVE; - - mapping(address => address) public ownerToPrevOwner; - mapping(address => address) public ownerToNextOwner; - mapping(address => bool) public expectedOwner; - - constructor() { - OWNER_SAFE = vm.envAddress("OWNER_SAFE"); - - GnosisSafe ownerSafe = GnosisSafe(payable(OWNER_SAFE)); - THRESHOLD = ownerSafe.getThreshold(); - EXISTING_OWNERS = ownerSafe.getOwners(); - - string memory rootPath = vm.projectRoot(); - string memory path = string.concat(rootPath, "/OwnerDiff.json"); - string memory jsonData = vm.readFile(path); - - OWNERS_TO_ADD = abi.decode(jsonData.parseRaw(".OwnersToAdd"), (address[])); - OWNERS_TO_REMOVE = abi.decode(jsonData.parseRaw(".OwnersToRemove"), (address[])); - } - - function setUp() external { - require(OWNERS_TO_ADD.length > 0, "Precheck 00"); - require(OWNERS_TO_REMOVE.length > 0, "Precheck 01"); - - GnosisSafe ownerSafe = GnosisSafe(payable(OWNER_SAFE)); - address prevOwner = SENTINEL_OWNERS; - - for (uint256 i = OWNERS_TO_ADD.length; i > 0; i--) { - uint256 index = i - 1; - // Make sure owners to add are not already owners - require(!ownerSafe.isOwner(OWNERS_TO_ADD[index]), "Precheck 03"); - // Prevent duplicates - require(!expectedOwner[OWNERS_TO_ADD[index]], "Precheck 04"); - - ownerToPrevOwner[OWNERS_TO_ADD[index]] = prevOwner; - ownerToNextOwner[prevOwner] = OWNERS_TO_ADD[index]; - prevOwner = OWNERS_TO_ADD[index]; - expectedOwner[OWNERS_TO_ADD[index]] = true; - } - - for (uint256 i; i < EXISTING_OWNERS.length; i++) { - ownerToPrevOwner[EXISTING_OWNERS[i]] = prevOwner; - ownerToNextOwner[prevOwner] = EXISTING_OWNERS[i]; - prevOwner = EXISTING_OWNERS[i]; - expectedOwner[EXISTING_OWNERS[i]] = true; - } - - for (uint256 i; i < OWNERS_TO_REMOVE.length; i++) { - // Make sure owners to remove are owners - require(ownerSafe.isOwner(OWNERS_TO_REMOVE[i]), "Precheck 05"); - // Prevent duplicates - require(expectedOwner[OWNERS_TO_REMOVE[i]], "Precheck 06"); - expectedOwner[OWNERS_TO_REMOVE[i]] = false; - - // Remove from linked list to keep ownerToPrevOwner up to date - // Note: This works as long as the order of OWNERS_TO_REMOVE does not change during `_buildCalls()` - address nextOwner = ownerToNextOwner[OWNERS_TO_REMOVE[i]]; - address prevPtr = ownerToPrevOwner[OWNERS_TO_REMOVE[i]]; - ownerToPrevOwner[nextOwner] = prevPtr; - ownerToNextOwner[prevPtr] = nextOwner; - } - } - - function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override { - GnosisSafe ownerSafe = GnosisSafe(payable(OWNER_SAFE)); - address[] memory postCheckOwners = ownerSafe.getOwners(); - uint256 postCheckThreshold = ownerSafe.getThreshold(); - - uint256 expectedLength = EXISTING_OWNERS.length + OWNERS_TO_ADD.length - OWNERS_TO_REMOVE.length; - - require(postCheckThreshold == THRESHOLD, "Postcheck 00"); - require(postCheckOwners.length == expectedLength, "Postcheck 01"); - - for (uint256 i; i < postCheckOwners.length; i++) { - require(expectedOwner[postCheckOwners[i]], "Postcheck 02"); - } - } - - function _buildCalls() internal view override returns (Call[] memory) { - Call[] memory calls = new Call[](OWNERS_TO_ADD.length + OWNERS_TO_REMOVE.length); - - for (uint256 i; i < OWNERS_TO_ADD.length; i++) { - calls[i] = Call({ - operation: Enum.Operation.Call, - target: OWNER_SAFE, - data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (OWNERS_TO_ADD[i], THRESHOLD)), - value: 0 - }); - } - - for (uint256 i; i < OWNERS_TO_REMOVE.length; i++) { - calls[OWNERS_TO_ADD.length + i] = Call({ - operation: Enum.Operation.Call, - target: OWNER_SAFE, - data: abi.encodeCall( - OwnerManager.removeOwner, (ownerToPrevOwner[OWNERS_TO_REMOVE[i]], OWNERS_TO_REMOVE[i], THRESHOLD) - ), - value: 0 - }); - } - - return calls; - } - - function _ownerSafe() internal view override returns (address) { - return OWNER_SAFE; - } -} diff --git a/setup-templates/template-set-bridge-partner-threshold/.env b/setup-templates/template-set-bridge-partner-threshold/.env deleted file mode 100644 index 6a017f69b..000000000 --- a/setup-templates/template-set-bridge-partner-threshold/.env +++ /dev/null @@ -1,10 +0,0 @@ -# Required: Git commit hash for https://github.com/base/contracts -BASE_CONTRACTS_COMMIT=be7c7a642e430fa64b04b63203839f8c81f48466 - -# Network-specific addresses are automatically loaded from {network}/.env via include ../.env - -# Required: L2 Bridge Validator contract address -L2_BRIDGE_VALIDATOR= - -# Required: New partner threshold value (number of signatures required for message validation) -NEW_THRESHOLD= diff --git a/setup-templates/template-set-bridge-partner-threshold/FACILITATOR.md b/setup-templates/template-set-bridge-partner-threshold/FACILITATOR.md deleted file mode 100644 index c2cfe2d08..000000000 --- a/setup-templates/template-set-bridge-partner-threshold/FACILITATOR.md +++ /dev/null @@ -1,39 +0,0 @@ -# Facilitator Guide - -Guide for facilitators managing this task. - -## Task Origin Signing - -After setting up the task, generate cryptographic attestations (sigstore bundles) to prove who created and facilitated the task. These signatures are stored in `/signatures//`. - -### Task creator (run after task setup): -```bash -make sign-as-task-creator -``` - -### Base facilitator: -```bash -make sign-as-base-facilitator -``` - -### Security Council facilitator: -```bash -make sign-as-sc-facilitator -``` - -## Execution - -### 1. Update repo: - -```bash -cd contract-deployments -git pull -cd / -make deps -``` - -### 2. Execute the transaction - -```bash -SIGNATURES=AAABBBCCC make execute -``` diff --git a/setup-templates/template-set-bridge-partner-threshold/Makefile b/setup-templates/template-set-bridge-partner-threshold/Makefile deleted file mode 100644 index 975793eb0..000000000 --- a/setup-templates/template-set-bridge-partner-threshold/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -include ../../Makefile -include ../../Multisig.mk -include ../.env -include .env - -# Map config variables to script variables -OWNER_SAFE ?= $(INCIDENT_MULTISIG) -L1_PORTAL ?= $(OPTIMISM_PORTAL) - -RPC_URL = $(L1_RPC_URL) -SCRIPT_NAME = SetThreshold - -# Validate required configuration before execution -.PHONY: validate-config -validate-config: - @test -n "$(BASE_CONTRACTS_COMMIT)" || (echo "BASE_CONTRACTS_COMMIT required" && exit 1) - @test -n "$(OWNER_SAFE)" || (echo "OWNER_SAFE required" && exit 1) - @test -n "$(L1_PORTAL)" || (echo "L1_PORTAL required" && exit 1) - @test -n "$(L2_BRIDGE_VALIDATOR)" || (echo "L2_BRIDGE_VALIDATOR required" && exit 1) - @test -n "$(NEW_THRESHOLD)" || (echo "NEW_THRESHOLD required" && exit 1) - @echo "Configuration validated successfully" - -# TODO: ensure `sender` is a signer for `OWNER_SAFE` -# NOTE: Uses bare literal `mise exec --` (not `$(MISE_EXEC)`) so the forge -# command written into validations/signer.json by state-diff stays portable -# across signer machines. See Multisig.mk's GEN_VALIDATION macro for the -# full rationale and the README's "Toolchain (mise)" section for the PATH -# requirement on the signer-tool subprocess. -.PHONY: gen-validation -gen-validation: validate-config - $(GOPATH)/bin/state-diff --rpc $(L1_RPC_URL) -o validations/signer.json \ - -- mise exec -- forge script --rpc-url $(L1_RPC_URL) SetThreshold \ - --sig "sign(address[])" "[$(OWNER_SAFE)]" \ - --sender 0xb2d9a52e76841279EF0372c534C539a4f68f8C0B - -# Execute -.PHONY: execute -execute: validate-config - $(call MULTISIG_EXECUTE,$(SIGNATURES)) diff --git a/setup-templates/template-set-bridge-partner-threshold/README.md b/setup-templates/template-set-bridge-partner-threshold/README.md deleted file mode 100644 index 790672246..000000000 --- a/setup-templates/template-set-bridge-partner-threshold/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Pause Base Bridge - -Status: READY TO SIGN - -## Description - -Updates the partner threshold on Base for [Base Bridge](https://github.com/base/bridge). This updates the required signature count for validating messages. - -## Signing Steps - -### 1. Run the signer tool - -```bash -make sign-task -``` - -### 2. Open the UI at [http://localhost:3000](http://localhost:3000) - -### 3. Send signature to facilitator diff --git a/setup-templates/template-set-bridge-partner-threshold/foundry.toml b/setup-templates/template-set-bridge-partner-threshold/foundry.toml deleted file mode 100644 index e5a15566d..000000000 --- a/setup-templates/template-set-bridge-partner-threshold/foundry.toml +++ /dev/null @@ -1,24 +0,0 @@ -[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -broadcast = 'records' -fs_permissions = [{ access = "read-write", path = "./" }] -optimizer = true -optimizer_runs = 999999 -solc_version = "0.8.28" -via-ir = false -remappings = [ - '@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/', - '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', - '@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts', - '@rari-capital/solmate/=lib/solmate/', - '@base-contracts/=lib/contracts', - '@solady/=lib/solady/src/', - '@lib-keccak=lib/lib-keccak/contracts/lib/' -] - -[lint] -lint_on_build = false - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/setup-templates/template-set-bridge-partner-threshold/script/SetThreshold.s.sol b/setup-templates/template-set-bridge-partner-threshold/script/SetThreshold.s.sol deleted file mode 100644 index f2fc9e525..000000000 --- a/setup-templates/template-set-bridge-partner-threshold/script/SetThreshold.s.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -import {Vm} from "forge-std/Vm.sol"; - -import {Simulation} from "@base-contracts/script/universal/Simulation.sol"; -import {MultisigScript} from "@base-contracts/script/universal/MultisigScript.sol"; -import {Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; - -interface IOptimismPortal2 { - function depositTransaction(address _to, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes memory _data) - external - payable; -} - -interface IBridgeValidator { - function setPartnerThreshold(uint256 newThreshold) external; -} - -contract SetThreshold is MultisigScript { - address public immutable OWNER_SAFE = vm.envAddress("OWNER_SAFE"); - address public immutable L1_PORTAL = vm.envAddress("L1_PORTAL"); - address public immutable L2_BRIDGE_VALIDATOR = vm.envAddress("L2_BRIDGE_VALIDATOR"); - uint256 public immutable NEW_THRESHOLD = vm.envUint("NEW_THRESHOLD"); - - function _buildCalls() internal view override returns (Call[] memory) { - Call[] memory calls = new Call[](1); - - address to = L2_BRIDGE_VALIDATOR; - uint256 value = 0; - uint64 gasLimit = 100_000; - bool isCreation = false; - bytes memory data = abi.encodeCall(IBridgeValidator.setPartnerThreshold, (NEW_THRESHOLD)); - - calls[0] = Call({ - operation: Enum.Operation.Call, - target: L1_PORTAL, - data: abi.encodeCall(IOptimismPortal2.depositTransaction, (to, value, gasLimit, isCreation, data)), - value: value - }); - - return calls; - } - - function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override {} - - function _ownerSafe() internal view override returns (address) { - return OWNER_SAFE; - } -}