AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
审查代码和制品,以用于 Base 合约部署、升级和调用
AI 翻译
Review code and artifacts for Base contract deployments, upgrades, and calls
AI 摘要 · README
开发工具Solidity · MakefileGitHub @base自行安装运营者未确认
试用过了吗? 点一下就好,无需登录。
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
安装型项目无需部署域名也可验证。个人仓库可通过 GitHub 登录验证,组织仓库可使用上方的仓库验证文件。
base/contract-deployments
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
This repo contains execution code and artifacts related to Base contract deployments, upgrades, and calls. For actual contract implementations, see base/contracts.
This repo is structured with each network having a high-level directory which contains subdirectories of any "tasks" (contract deployments/calls) that have happened for that network.查看完整 README ↗This repo contains execution code and artifacts related to Base contract deployments, upgrades, and calls. For actual contract implementations, see base/contracts.
EVM operations have three lifecycles: pending one-off tasks in active/evm/tasks/, pre-reviewed dateless operations in standby/evm/tasks/, and historical dated tasks in archive/evm/.
Foundry, Node.js, Bun, and Go are pinned in mise.toml so contributors and signers run identical versions. This prevents mismatches in domain separators, build artifacts, and generated signatures. Standby lifecycle commands also require Python 3.9 or newer on PATH and use only its standard library. On Linux, building eip712sign (installed by make deps) also needs the libudev headers: libudev-dev on Debian/Ubuntu, systemd-devel on Fedora/RHEL. macOS needs nothing extra.
make sign-task, make deps, and execution targets bootstrap the mise-managed toolchain automatically:
mise to ~/.local/bin/mise if it's not already present, using the vendored installer at scripts/install-mise.sh.mise.toml and runs mise install to fetch the pinned foundry, node, bun, and go versions.mise exec --, so the pinned versions are used without modifying your shell environment or PATH. This deliberately avoids conflicts with any existing foundryup or system-level installs.Important —
misemust be on your PATH for the signer-tool. The generated validation files contain acmdfield withmise exec --(deliberately, so the JSON is portable across machines), and the signer-tool re-executes that command in a fresh shell. Ifmiseis not on your PATH, that subprocess will fail with "command not found".make bootstrap-misewill warn you if this is the case. To fix it, add this to your shell config (e.g.~/.zshrcor~/.bashrc) and restart your shell:export PATH="$HOME/.local/bin:$PATH"Alternatively, install
misesystem-wide so it lands on your default PATH.
$ mise exec -- forge --version
forge Version: 1.5.1-...
Commit SHA: b0a9dd9ceda36f63e2326ce530c10e6916f4b8a2
The Commit SHA is the source of truth — it must match the commit pinned in mise.toml.
If you want bare forge/cast/bun/go invocations in your interactive shell to resolve to the pinned versions while you're working inside this repo, add mise's shell hook to your shell config:
# zsh
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
# bash
echo 'eval "$(mise activate bash)"' >> ~/.bashrc
This is purely a convenience for task authors — make targets work correctly without it.
To execute a new task, run one of the following commands (depending on the type of change you're making):
make setup-gas-increase network=<network>make setup-gas-and-elasticity-increase network=<network>make setup-safe-management network=<network>make setup-funding network=<network>make setup-bridge-partner-threshold network=<network>make setup-bridge-pause network=<network>make setup-superchain-config-pause network=<network>Each setup-* command also creates a matching <network>/signatures/<task-dir-basename>/ directory for task origin signing. The parent signatures/ directory is created automatically via mkdir -p for networks that do not yet have one.
Next, cd into the directory that was created for you and follow the steps listed below for the relevant template.
Please note, for some older tasks (that have not yet been adapted to use the signer tool) you will need to manually create validation file(s) for your task as they are bespoke to each task and therefore not created automatically as a part of the templates. We use one validation Markdown file per multisig involved in the task, so if there's only one multisig involved in your task, then you can simply create a VALIDATION.md file at the root of your task containing the validation instructions, while if there are multiple multisigs involved in the task, then create a validations/ sub-directory at the root of your task containing the corresponding validation Markdown files. If you need examples to work from, you can browse through similar past tasks in this repo and adapt them to your specific task. Also, please note that we have tooling to generate these files (like the task-signer-tool) which removes the manual aspect of creating these validation files, we will soon update these instructions to reflect how this process can be automated.
Global config/<network>.env files define stable addresses and network metadata. EVM tasks include the selected global file and their own config/<network>/.env. Stable PROTOCOL_VERSIONS_PROXY values belong in global config; incident-specific inputs belong in the invocation.
The network .env files contain:
NETWORK, L1_RPC_URL, L2_RPC_URL, L1_CHAIN_ID, L2_CHAIN_ID, LEDGER_ACCOUNTAll address variables are prefixed with export so they are available to child shell processes (Forge scripts, shell commands, etc.). Foundry scripts can access them via vm.envAddress("VARIABLE_NAME").
Update stable addresses in
config/<network>.env. Override an address in an invocation only when that operation targets a different deployment.
Active EVM tasks share the Foundry project under active/evm/, while each task owns its Makefile, facilitator guide, network configurations, signatures, and execution records. Reusable operation scripts live under script/common/<category>/; one-off scripts stay with their task.
active/evm/
├── foundry.toml # shared Foundry configuration
├── script/
│ └── common/ # reusable scripts, shared across tasks
│ └── <category>/ # bridge, funding, gas, ownership, safe, superchain
└── tasks/
└── <YYYY-MM-DD-task-name>/
├── Makefile # task dependencies, validation, approvals, and execution
├── FACILITATOR.md # network-agnostic facilitator procedure
├── status.json # task progress across network invocations
├── script/ # optional one-off task scripts
├── config/
│ └── <network>/
│ ├── .env # network-specific task inputs + BASE_CONTRACTS_COMMIT
│ ├── addresses.json # generated network-specific deployment addresses
│ ├── README.md # status + description parsed by the signer tool
│ └── validations/ # generated per-signer validation JSON
├── signatures/
│ └── <network>/ # task-origin signatures when required
└── records/
└── <script>/<chain-id>/ # Forge broadcast records
README.md files are for signers and should contain only the concise information needed to sign. For active EVM tasks, they live in config/<network>/README.md.FACILITATOR.md files are for facilitators and cover generating validation files, executing approvals, and executing the task. Some legacy tasks use the name FACILITATORS.md for this guide.Run task commands from active/evm/tasks/<task-id>/. A task with multiple network configurations must require TASK_NETWORK on each Make command line, for example make TASK_NETWORK=sepolia gen-validation-cb; it must not rely on a mutable default or exported environment value. Keep the root FACILITATOR.md authoritative and network-agnostic, and make the need to replace TASK_NETWORK=<network> explicit. Per-network facilitator files are discouraged; if one is unavoidable for a materially different procedure, put only that procedural delta in config/<network>/FACILITATOR.md and link to it from the root guide.
One task directory represents one logical operation across its intended network rollouts. Add sibling config/<network>/ directories and keep the task active until all intended networks are executed or canceled and their final artifacts are committed. Do not run make archive-task between network rollouts.
Reusable scripts are documented in active/evm/script/common/README.md. To install dependencies for the shared project without selecting a task, invoke the root Makefile with a project directory and explicit contracts commit:
make deps PROJECT_DIR="$PWD/active/evm" BASE_CONTRACTS_COMMIT=<commit>
Canonical standby tasks are dateless, pre-reviewed operations with no real network configuration or artifacts. Invoke directly from standby/evm/tasks/<operation>/ by adding config/<network>/.env, a concise signer README with Status: READY TO SIGN, and a task-root status.json. Do not copy the task into active or edit its canonical Makefile, Solidity, or root FACILITATOR.md for an incident. Every Make command requires explicit command-line TASK_NETWORK=<network>, not an exported value or default.
Use the upgrade-delay guide or verifier hash rotation guide for exact commands. The verifier operation supports AggregateVerifier 0.3.0 at its reviewed contracts pin and replaces the former common verifier scripts. Standby tasks use the shared active/evm Foundry project, but each operation's dependency pin and build settings must be respected. Signer discovery includes an invocation only after JSON validations exist under config/<network>/validations/. The pinned signer checkout receives the deterministic repo-owned patch in scripts/patches/signer-standby.patch; changing its upstream pin or content without reviewing the patch fails closed.
Pre-review does not replace incident-specific simulation. Re-review the canonical operation if the target ABI, ownership or responder role, base/contracts pin, or signing workflow changes. Keep addresses and other network-specific artifacts under config/<network>/; Forge records stay at task scope under records/<script>/<chain-id>/.
After execution or cancellation, finalize every present network's README and commit all final artifacts. Fetch main, then run make TASK_NETWORK=<network> archive-task TASK_DATE=<YYYY-MM-DD>. Pending sibling invocations block archival because task-scoped records cannot safely be split by network. The command refuses invalid identifiers, overwrites, and canonical differences from origin/main. It preserves all finalized networks and artifacts in archive/evm/<YYYY-MM-DD>-<operation>/, including the canonical task source, Foundry configuration, and global network snapshots. Only invocation directories are removed; canonical standby files remain byte-for-byte identical.
Keep the operational PR unmerged until all intended invocations are executed or canceled and the dated archive, final artifacts, and standby invocation removals are committed. On main, canonical standby must remain unchanged and contain no invocation-specific data before and after merge.
standby/evm/tasks/<operation>/
├── Makefile
├── FACILITATOR.md
├── README.md
└── script/
└── <operation>.s.sol
Invocation-only config/, signatures/, and records/ directories and the task-root status.json are added during an incident and removed by archival. Later incidents reuse the canonical standby directory. Historical archives must not be edited or executed.
Each legacy task (under a network directory, or archive/legacy/) has a directory structure similar to the following:
.env)Every active task and every standby operation with a network invocation has one task-root status.json. Humans and the automation bot read and update the same file. Never put it under config/<network>/, because task-origin signing covers that directory and later status updates must not change the signed payload. A canonical standby operation without invocations must not have a status file; archival carries invocation status into the dated archive and removes it from standby.
scripts/task-status.schema.json defines version 1. All fields are required and unknown fields are rejected. schema_version is 1, task matches the task directory name, kind is active or standby, and last_updated is a UTC timestamp in YYYY-MM-DDTHH:MM:SSZ form. networks contains exactly the directories under the task's config/ and must not be empty. Each network has:
step, one of the lifecycle steps below.pr, the task's pull request URL in this repository, or null before one exists.blocksec_ticket, an HTTPS ticket URL, or null if none applies.signatures, an object keyed by validation file stem, such as base-signer, with nonnegative integer collected and positive integer required counts. Use {} until the required signer roles are known.executed_tx, a 32-byte hex transaction hash only when the step is executed; otherwise null.| Step | Meaning |
|---|---|
authoring | The facilitator is writing scripts and configuration. |
validation | The facilitator is generating and checking simulation artifacts. |
review | Reviewers are checking the task and validation files. |
ready_to_sign | Reviewed validation files are ready for signers. |
collecting | Signers are submitting signatures. |
ready_to_execute | Required signatures and approvals are ready for execution. |
executed | Execution succeeded and its transaction hash is recorded. |
canceled | The invocation will not execute. |
The facilitator or bot updates the network step, links, signature counts, and last_updated when progress changes. The initial machine step is authoring even though the signer README starts with Status: READY TO SIGN; do not ask signers to sign until validations are reviewed. Finalize the signer README as EXECUTED or CANCELED and update status.json in the same change. The checker requires both final states to match and accepts only uppercase EXECUTED or CANCELED, optionally followed by an HTTP(S) URL, or [EXECUTED](<url>) or [CANCELED](<url>) with an HTTP(S) URL. Other final-looking formats are rejected.
Run these commands from the repository root. Provide exactly one selector and a command-line TASK_NETWORK with a matching global config/<network>.env. The date defaults to today; identifiers use lowercase letters, digits, and single hyphens, with slugs, operations, and networks starting with a letter.
make new-task TASK_SLUG=<slug> TASK_NETWORK=<network> TASK_DATE=YYYY-MM-DD
make new-task TASK_ID=<existing-active-task-id> TASK_NETWORK=<network>
make new-task STANDBY_OP=<operation> TASK_NETWORK=<network>
make check-task-status
The first mode creates active/evm/tasks/<date>-<slug>/ with a shared Makefile skeleton, facilitator guide, tracked script/ directory, network .env, signer README, and initial status.json. Implement the operation and fill in the empty contracts pin before using it. The second mode adds only a network config and status entry to an existing active task. The third adds a standby invocation without changing canonical files; follow the operation's facilitator guide to fill in its reviewed pin and required inputs. All modes refuse overwrites and leave generated validations, addresses, signatures, and records to the facilitator.
To adopt an existing task, run python3 -B scripts/task-status.py add-network <task-dir> <network> once for each existing network, then update its progress and final artifacts. The CLI refuses duplicate entries. make check-task-status validates all active tasks and invoked standby operations, including network directories, execution hashes, and finalized README consistency. The task status workflow runs the checker and scaffolder tests on pull requests and pushes to main.
The GitHub Actions workflow validates shared active scripts and canonical standby Solidity on every pull request and push to main.
What CI checks:
forge fmt --check script/ and forge build check the shared active project.forge fmt --root . --check standby/evm/tasks/ scripts/tests/*.sol checks standby formatting. The delay script compiles against the shared active project's dependencies; verifier rotation builds and tests in an isolated fixture against its supported v8.4.0.rc2 pin.sh scripts/tests/run-standby-solidity.sh tests delay invariants against local ProtocolVersions proxies. STANDBY_OPERATION=update-verifier-hashes sh scripts/tests/run-standby-solidity.sh installs the supported pin, format-checks and builds canonical scripts, and tests verifier deployment, prechecks, factory write scope, and postchecks without RPC or credentials.python3 -B -m unittest scripts.tests.test_standby_lifecycle -v checks lossless archival and Make guards in temporary Git repositories without RPC or credentials.sh scripts/tests/run-signer-standby.sh runs the pinned signer's TypeScript checks, discovery/API tests, and local validation-generator tests for the direct delay and nested verifier approval paths.How it works:
jdx/mise-action GitHub Action using the versions pinned in mise.toml, so CI matches local signer environments.make deps PROJECT_DIR="$PWD/active/evm" installs dependencies into the shared active/evm Foundry project. BASE_CONTRACTS_COMMIT is supplied via the workflow's env block, since the shared project has no task .env of its own.What CI does NOT do:
forge script (requires RPC URLs, env vars, and hardware wallets).See
.github/workflows/validate-common-scripts.ymlfor the full workflow definition.
All task templates use global macros defined in Multisig.mk for multisig operations:
| Macro | Purpose | Key arguments |
|---|---|---|
MULTISIG_APPROVE | Approve a transaction (nested safe hierarchy) | (address_list, signatures) |
MULTISIG_EXECUTE | Execute an approved transaction on-chain | (signatures) |
GEN_VALIDATION | Generate a validation JSON file for signers via the signer-tool | (script_name, safe_addr, sender, output_file, env_vars) |
Two helper macros are also available for tasks that need nonce offset calculations or address manipulation:
| Macro | Purpose | Key arguments |
|---|---|---|
GET_NONCE | Fetch the current nonce of a Safe contract on-chain | (safe_address) |
ADDR_UPPER | Convert an address to uppercase (for env var construction) | (address) |
Signing is handled externally by the task-signing-tool.
Every template Makefile should include Multisig.mk and define at least two variables for the macros to work:
include ../../Makefile
include ../../Multisig.mk
include ../.env
include .env
RPC_URL = $(L1_RPC_URL) # or $(L2_RPC_URL)
SCRIPT_NAME = MyScript # class name or .sol file path
Templates that generate validation files should use GEN_VALIDATION with the deps-signer-tool prerequisite (which checks out and installs the signer-tool):
gen-validation: validate-config deps-signer-tool
$(call GEN_VALIDATION,$(SCRIPT_NAME),,$(SENDER),base-signer.json,)
Templates should use these macros rather than inline forge script / eip712sign / bun run invocations. The known exceptions are the incident-response pause templates, which pre-sign 20 future nonces in a loop using inline eip712sign; only their execute-* targets use MULTISIG_EXECUTE.
The root Makefile provides three targets for generating cryptographic attestations (sigstore bundles) that prove who created and facilitated a task. These are inherited by all task Makefiles via include ../../Makefile.
| Target | Purpose |
|---|---|
make sign-as-task-creator | Attest authorship of the task (run after setup) |
make sign-as-base-facilitator | Attest Base team facilitation |
make sign-as-sc-facilitator | Attest Security Council facilitation |
Signatures are stored in <network>/signatures/<task-name>/, where <task-name> is auto-derived from the task directory name. This directory is created automatically when you run any setup-* target (in both the root and Solana Makefiles), so it is ready for the signing tool when you invoke one of the targets below. Two variables control this behavior and can be overridden in a task's Makefile if the defaults are not appropriate:
| Variable | Default | Description |
|---|---|---|
TASK_NAME | $(notdir $(CURDIR)) (directory basename) | Name used to locate signature dir |
SIGNATURE_DIR | $(CURDIR)/../signatures/$(TASK_NAME) | Directory where signatures are stored |
All three targets depend on deps-signer-tool, which checks out and installs the task-signing-tool automatically.
For active/evm tasks, the shared Makefile overrides TASK_ORIGIN_DIR and SIGNATURE_DIR: the signer tool signs over the active/evm/tasks/<task-id>/config/<network> directory (TASK_ORIGIN_DIR), while the signatures themselves are written to active/evm/tasks/<task-id>/signatures/<network>/ (SIGNATURE_DIR) — outside the signed directory, so generating signatures does not change the signed payload. A task may opt out of task-origin validation entirely by setting skipTaskOriginValidation: true at the root of each validation file (e.g. non-production networks such as zeronet).
This template is increasing the throughput on Base Chain.
setupmake setup-gas-increase network=<network> step.env and README files. Tip: you can run make deps followed by make sign-upgrade to produce a Tenderly simulation which will help fill in several of the TODOs in the README (and also make sign-rollback).EXECUTED in the README.This template is used to update the gas limit, elasticity, and DA footprint gas scalar, or roll back the changes (if needed).
setup, including running make setup-gas-and-elasticity-increase network=<network> and then go to the folder that was created by this command..env file.make deps..env file that have per-network comments (e.g., OWNER_SAFE, SENDER), using the value for your target network.SENDER variable in the .env file is set to a signer of OWNER_SAFE.FROM_* and TO_* values for gas limit and elasticity in the .env file.go/base-da-config. make da-scalar TARGET_BLOB_COUNT=<value> is the source of truth for the standard soft-cap policy and calculates gas_limit / (elasticity * da_soft_cap_blob_count * 32,000). 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. The command prints the .env value and the DA table to copy into the task README. Pass BUILDER_HARD_CAP=<value> after checking the target network's op_batcher_throttle_block_size_upper_limit Config Service value. The task README includes links for the standard network scopes. Set the FROM_DA_FOOTPRINT_GAS_SCALAR and TO_DA_FOOTPRINT_GAS_SCALAR values in the .env file.forge build.make gen-validation.make gen-validation-rollback.cmd field at the top of both of the generated validation files and ensure that the value passed to the --sender flag matches the SENDER env var already defined in the .env file.TODO in the tasks's README.md have been properly filled out.This template is used to perform ownership management on a Gnosis Safe, like the incident multisig, specifically it can be used to change the owners of the multisig.
setup, including running make setup-safe-management network=<network> and go to the folder that was created by this command..env file.make deps.OWNER_SAFE, which is the safe multisig where an owner will be replaced and the SENDER which should be the address of a current signer of the multisig.OwnerDiff.json inside the task's directory with the addresses to add to, and remove from, the multisig in their respective fields.EXISTING_OWNERS_LENGTH constant value inside the script/UpdateSigners.s.sol script is set appropriately, in particular that it equals the exact number of current members of the Incident Multisig Safe (prior to running the task).forge build.make gen-validation.cmd field at the top of the generated validation file at validations/base-signer.json and ensure that the value passed to the --sender flag matches the SENDER env var already defined in the .env file.EXECUTED in the README.This template is used to fund addresses from a Gnosis Safe.
setup.make setup-funding network=<network> and go to the folder that was created by this command..env file.make deps.SAFE, which is the safe that will fund the addresses in the .env file.recipients and funds arrays (in 1e18 units) in the funding.json file.forge build.make sign and update the generic validations in VALIDATION.md with the real values.EXECUTED in the README.This template is used to update the partner threshold in Base Bridge, affecting the amount of required partner signatures to approve bridge messages.
setup.make setup-bridge-partner-threshold network=<network> and go to the folder that was created by this command..env file.make deps..env file that have per-network comments, using the value for your target network.NEW_THRESHOLD variable in the .env file.--sender flag in the make gen-validation command in the Makefile file is set to a signer for OWNER_SAFE in .env.forge build.make gen-validation.EXECUTED in the README.This template is used to pause or un-pause Base Bridge.
setup.make setup-bridge-pause network=<network> and go to the folder that was created by this command..env file.make deps..env file that have per-network comments (e.g., L2_BRIDGE), using the value for your target network.IS_PAUSED variable to true or false in the .env file depending on if you intend to pause or unpause the bridge.SENDER variable in the Makefile is set to a signer for OWNER_SAFE.forge build.make gen-validation.EXECUTED in the README.This template is used to pause or un-pause the L1 SuperchainConfig contract.
setup.make setup-superchain-config-pause network=<network> and go to the folder that was created by this command..env file.make deps..env file that have per-network comments, using the value for your target network.forge build.make sign-pause or generate the validation file for un-pausing with make gen-validation-unpause.EXECUTED in the README.EXECUTED