From accc291fabfb6560517265a1939cb0bfe13428b0 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Tue, 17 Mar 2026 14:18:59 -0700 Subject: [PATCH] Add zeronet contract deployment config Chain ID: 763360 (0xBA5E0), settling to Sepolia. All L1 contract addresses populated from op-deployer deployment. Co-Authored-By: Claude Opus 4.6 --- zeronet/.env | 50 ++++++++++ zeronet/2026-03-16-deploy/.env | 15 +++ zeronet/2026-03-16-deploy/FACILITATOR.md | 22 +++++ zeronet/2026-03-16-deploy/Makefile | 30 ++++++ zeronet/2026-03-16-deploy/README.md | 98 +++++++++++++++++++ zeronet/2026-03-16-deploy/foundry.toml | 23 +++++ .../script/BasicScript.s.sol | 17 ++++ .../script/CounterMultisigScript.s.sol | 43 ++++++++ 8 files changed, 298 insertions(+) create mode 100644 zeronet/.env create mode 100644 zeronet/2026-03-16-deploy/.env create mode 100644 zeronet/2026-03-16-deploy/FACILITATOR.md create mode 100644 zeronet/2026-03-16-deploy/Makefile create mode 100644 zeronet/2026-03-16-deploy/README.md create mode 100644 zeronet/2026-03-16-deploy/foundry.toml create mode 100644 zeronet/2026-03-16-deploy/script/BasicScript.s.sol create mode 100644 zeronet/2026-03-16-deploy/script/CounterMultisigScript.s.sol diff --git a/zeronet/.env b/zeronet/.env new file mode 100644 index 00000000..2bd3920f --- /dev/null +++ b/zeronet/.env @@ -0,0 +1,50 @@ +NETWORK=zeronet +L1_RPC_URL=https://ethereum-full-sepolia-k8s-dev.cbhq.net +L2_RPC_URL=https://base-zeronet-reth-mempool-k8s-donotuse.cbhq.net:8545 +L1_CHAIN_ID=11155111 +L2_CHAIN_ID=763360 +LEDGER_ACCOUNT=1 + +# Admin Addresses +export BASE_SECURITY_COUNCIL=0xAf6E0E871f38c7B653700F7CbAEDafaa2784D430 +export BATCH_INBOX=0x00975f9c430b216f84ec52374d7f5eb8eec3139a +export BATCH_SENDER=0x30da8353162e03b7056fa49d94608043e76858c0 +export CB_COORDINATOR_MULTISIG=0xAf6E0E871f38c7B653700F7CbAEDafaa2784D430 +export CB_MULTISIG=0xAf6E0E871f38c7B653700F7CbAEDafaa2784D430 +export CHALLENGER=0xf21a70852cc3b1f42603c78aee3f5103c8a46a8a +export INCIDENT_MULTISIG=0xAf6E0E871f38c7B653700F7CbAEDafaa2784D430 +export OP_MULTISIG=0xAf6E0E871f38c7B653700F7CbAEDafaa2784D430 +export PROPOSER=0xe04b123fb943101ba14619c07f6c582b2b230de4 +export PROXY_ADMIN_OWNER=0x90128dbCee6178169BBc3CA90c18a93602A53721 + +# L1 Addresses (populated after L1 contract deployment) +export ANCHOR_STATE_REGISTRY_PROXY=0x63f21f34116daac011972f11eff6ed0f41e21701 +export DISPUTE_GAME_FACTORY_PROXY=0x1ebacdf1f629426e5443764b23051776cdd68c3e +export FAULT_DISPUTE_GAME_IMPL=0xfaede1fa7cb0a650393d5fdca823e83db3c9763e +export FDG_DELAYED_WETH_PROXY=0xf0c90efa51a3d8114d8ac2f2f32a5c19a61cf058 +export L1_CROSS_DOMAIN_MESSENGER=0x4bb6997992d12151ebe84947aa838d2f4acc496e +export L1_ERC721_BRIDGE=0xbf616dad2daef3b6eb62b60d4b03286771f0e45f +export L1_OPTIMISM_MINTABLE_ERC20_FACTORY=0xd1f7d0d4ee2379d806177b320ad28c1bcae7a719 +export L1_PROXY_ADMIN=0x5735d0e40ec265c3f99c274ae1aa0fed2004a17b +export L1_STANDARD_BRIDGE=0x851e0dd0289db181bfc82a3e042a7682564ad5e6 +export MIPS=0x969e7a548b4e1ea6f44b101535318a7d1a469f8a +export OPTIMISM_PORTAL=0xfa009c321190c20039993a20af19ee3f34eba2c5 +export PDG_DELAYED_WETH_PROXY=0xf0c90efa51a3d8114d8ac2f2f32a5c19a61cf058 +export PERMISSIONED_DISPUTE_GAME_IMPL=0xe1dffcbe4e22b813f26d2106d943c102e7cab87e +export PREIMAGE_ORACLE=0x1fb8cdfc6831fc866ed9c51af8817da5c287add3 +export SYSTEM_CONFIG=0xeeabe9da6ddffdbdb666a611699fb67399aa45c2 + +# L2 Addresses (predeploys, same for all OP Stack chains) +export BASE_FEE_VAULT=0x4200000000000000000000000000000000000019 +export GAS_PRICE_ORACLE=0x420000000000000000000000000000000000000F +export L1_BLOCK=0x4200000000000000000000000000000000000015 +export L1_FEE_VAULT=0x420000000000000000000000000000000000001a +export L2_CROSS_DOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 +export L2_ERC721_BRIDGE=0x4200000000000000000000000000000000000014 +export L2_OPTIMISM_MINTABLE_ERC20_FACTORY=0x4200000000000000000000000000000000000012 +export L2_OPTIMISM_MINTABLE_ERC721_FACTORY=0x4200000000000000000000000000000000000017 +export L2_PROXY_ADMIN=0x4200000000000000000000000000000000000018 +export L2_STANDARD_BRIDGE=0x4200000000000000000000000000000000000010 +export L2_TO_L1_MESSAGE_PASSER=0x4200000000000000000000000000000000000016 +export SEQUENCER_FEE_VAULT=0x4200000000000000000000000000000000000011 +export WETH9=0x4200000000000000000000000000000000000006 diff --git a/zeronet/2026-03-16-deploy/.env b/zeronet/2026-03-16-deploy/.env new file mode 100644 index 00000000..5cb9619e --- /dev/null +++ b/zeronet/2026-03-16-deploy/.env @@ -0,0 +1,15 @@ +# 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: Target contract address for the multisig operation +TARGET= + +# Required: Top-level owner safe address +OWNER_SAFE= + +# Optional: Nested safe addresses for nested signing +# L1_0 and L1_1 are child safes under OWNER_SAFE (single-nested hierarchy) +L1_0= +L1_1= diff --git a/zeronet/2026-03-16-deploy/FACILITATOR.md b/zeronet/2026-03-16-deploy/FACILITATOR.md new file mode 100644 index 00000000..f3a0b84b --- /dev/null +++ b/zeronet/2026-03-16-deploy/FACILITATOR.md @@ -0,0 +1,22 @@ +# 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/zeronet/2026-03-16-deploy/Makefile b/zeronet/2026-03-16-deploy/Makefile new file mode 100644 index 00000000..d119337e --- /dev/null +++ b/zeronet/2026-03-16-deploy/Makefile @@ -0,0 +1,30 @@ +include ../../Makefile +include ../../Multisig.mk +include ../.env +include .env + +RPC_URL = $(L1_RPC_URL) +SCRIPT_NAME = ExampleMultisigScript + +# 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)" -a "$(OWNER_SAFE)" != "" || (echo "OWNER_SAFE required" && exit 1) + @test -n "$(TARGET)" -a "$(TARGET)" != "" || (echo "TARGET required" && exit 1) + @echo "Configuration validated successfully" + +# L1_0 +.PHONY: approve-l1-0 +approve-l1-0: + $(call MULTISIG_APPROVE,$(L1_0),$(SIGNATURES)) + +# L1_1 +.PHONY: approve-l1-1 +approve-l1-1: + $(call MULTISIG_APPROVE,$(L1_1),$(SIGNATURES)) + +# Execute +.PHONY: execute +execute: validate-config + $(call MULTISIG_EXECUTE,0x) diff --git a/zeronet/2026-03-16-deploy/README.md b/zeronet/2026-03-16-deploy/README.md new file mode 100644 index 00000000..678154ca --- /dev/null +++ b/zeronet/2026-03-16-deploy/README.md @@ -0,0 +1,98 @@ +# Generic Multisig Script Template + +Status: TEMPLATE + +## Description + +This is the base template for creating new multisig operations. It provides a starting point with the standard file structure and Makefile targets needed for signing and executing transactions via Gnosis Safe multisigs. + +Use this template when you need to create a new task that doesn't fit one of the specialized templates (gas increase, fault proof upgrade, etc.). + +## Setup + +### 1. Create a new task directory + +From the repository root: + +```bash +make setup-task network= task= +``` + +This copies the template to `/-/`. + +### 2. Install dependencies + +```bash +cd /- +make deps +``` + +### 3. Configure environment + +Edit `.env` and set all required variables: + +| Variable | Required | Description | +|----------|----------|-------------| +| `BASE_CONTRACTS_COMMIT` | Yes | Git commit hash for base/contracts | +| `TARGET` | Yes | Target contract address for the operation | +| `OWNER_SAFE` | Yes | Top-level Gnosis Safe address | +| `L1_0`, `L1_1` | Depends | Child safe addresses under OWNER_SAFE (if using nested safes) | + +### 4. Validate configuration + +```bash +make validate-config +``` + +### 5. Implement your script + +Edit `script/BasicScript.s.sol` or `script/CounterMultisigScript.s.sol` to implement your specific operation. The script should: + +1. Read configuration from environment variables in the constructor +2. Implement `_buildCalls()` to return the multicall operations +3. Implement `_postCheck()` to validate the transaction succeeded +4. Implement `_ownerSafe()` to return the safe address + +## Safe Hierarchy + +This template supports a single-nested safe structure for multi-party signing: + +``` +OWNER_SAFE/ +├── L1_0/ +│ └── Signers +└── L1_1/ + └── Signers +``` + +## Signing Flow + +### For signers at L1_0: +```bash +make sign-l1-0 +``` + +### For signers at L1_1: +```bash +make sign-l1-1 +``` + +### For approving nested safes: +```bash +SIGNATURES= make approve-l1-0 +SIGNATURES= make approve-l1-1 +``` + +### Final execution: +```bash +make execute +``` + +## Ledger Setup + +Your Ledger needs to be connected and unlocked. The Ethereum application needs to be opened on Ledger with the message "Application is ready". + +To use a different Ledger account index: +```bash +LEDGER_ACCOUNT=1 make sign-l1-0 +``` diff --git a/zeronet/2026-03-16-deploy/foundry.toml b/zeronet/2026-03-16-deploy/foundry.toml new file mode 100644 index 00000000..5b8fe4ae --- /dev/null +++ b/zeronet/2026-03-16-deploy/foundry.toml @@ -0,0 +1,23 @@ +[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/zeronet/2026-03-16-deploy/script/BasicScript.s.sol b/zeronet/2026-03-16-deploy/script/BasicScript.s.sol new file mode 100644 index 00000000..9a70c98e --- /dev/null +++ b/zeronet/2026-03-16-deploy/script/BasicScript.s.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import "forge-std/Script.sol"; + +contract BasicScript is Script { + function setUp() public {} + + function run() public { + _preCheck(); + // Do something + _postCheck(); + } + + function _preCheck() private {} + function _postCheck() private {} +} diff --git a/zeronet/2026-03-16-deploy/script/CounterMultisigScript.s.sol b/zeronet/2026-03-16-deploy/script/CounterMultisigScript.s.sol new file mode 100644 index 00000000..01afd09f --- /dev/null +++ b/zeronet/2026-03-16-deploy/script/CounterMultisigScript.s.sol @@ -0,0 +1,43 @@ +// 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 ITest { + function counter() external view returns (uint256); + function increment() external; +} + +contract CounterMultisigScript is MultisigScript { + address internal OWNER_SAFE = vm.envAddress("OWNER_SAFE"); + address internal TARGET = vm.envAddress("TARGET"); + + uint256 private COUNT; + + function setUp() external { + // TODO: Add any pre-check assertions here + COUNT = ITest(TARGET).counter(); + } + + function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override { + // TODO: Add any post-check assertions here + require(ITest(TARGET).counter() == COUNT + 1, "Counter did not increment"); + } + + function _buildCalls() internal view override returns (Call[] memory) { + Call[] memory calls = new Call[](1); + + calls[0] = + Call({operation: Enum.Operation.Call, target: TARGET, data: abi.encodeCall(ITest.increment, ()), value: 0}); + + return calls; + } + + function _ownerSafe() internal view override returns (address) { + return OWNER_SAFE; + } +}