Skip to content

feat(zeronet): add Cobalt upgrade task - #790

Merged
jackchuma merged 14 commits into
mainfrom
jackchuma/zeronet-cobalt-upgrade
Sep 15, 2026
Merged

jackchuma merged 14 commits into
mainfrom
jackchuma/zeronet-cobalt-upgrade

Conversation

@jackchuma

@jackchuma jackchuma commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

What changed? Why?

Adds the Zeronet configuration for the Cobalt upgrade task, scheduled for September 16, 2026 at 16:00 UTC. It deploys the required implementations and prepares one ProxyAdmin-owner Safe transaction that:

  1. deploys and initializes ProtocolVersions for dynamic upgrades;
  2. upgrades OptimismPortal2 and SystemConfig for EthLockbox removal;
  3. upgrades DisputeGameFactory to deploy new dispute games with CREATE2; and
  4. registers a redeployed AggregateVerifier for game type 621, bound to the new registry.

The task includes deployment artifacts, Base and Security Council signer validation files, source-verification targets, and explicit TASK_NETWORK=zeronet Make targets. It pins the required base/contracts revision and compiler profiles so the deployed bytecode matches the contract compilation restrictions.

Notes to reviewers

  • The Zeronet-specific SystemConfig patch preserves its 2,000,000,000 gas limit through the upgrade.
  • The execution script verifies the current implementation addresses, confirms no EthLockbox is configured, and checks that portal ETH, dispute-game count, gas limit, and pause state are unchanged after execution.
  • ProtocolVersions.initialize requires at least one hour of notice before the configured activation, so execute before September 16, 2026 at 15:00 UTC, or reschedule Cobalt.

How has it been tested?

  • Ran the core and proofs deployment scripts against an Anvil fork of Zeronet L1 (chain ID 560048); their postcondition checks passed and the resulting broadcasts are committed.
  • Ran the upgrade script’s signing path on the same fork, exercising its pre- and post-upgrade checks, including the AggregateVerifier registry binding.

Bundles the three Cobalt L1 changes into a single ProxyAdmin-owner
transaction for Zeronet:

- Dynamic upgrades: deploys a ProtocolVersions registry (proxy plus
  implementation) and redeploys AggregateVerifier, which binds the
  registry as a constructor immutable and so cannot be upgraded in place.
- EthLockbox removal: upgrades OptimismPortal2 and SystemConfig.
- CREATE2 for dispute games: upgrades DisputeGameFactory and registers
  the new AggregateVerifier for game type 621.

Deployment is split across two Foundry profiles because base/contracts
pins per-contract optimizer runs (5000 for the portal, system config,
factory and proxy; 999999 for the registry and verifier). Zeronet's
SystemConfig carries a local MAX_GAS_LIMIT raise, so the task re-applies
it as a patch and asserts the resulting build suffix rather than letting
a stock build silently revert the limit.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cb-heimdall

cb-heimdall commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Heimdall Review Status

Requirement Status More Info
Reviews ✅ 2/2
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 2
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 2
2
1 if commit is unverified 0
Sum 2

jackchuma and others added 2 commits September 14, 2026 14:06
Co-authored-by: Cursor <cursoragent@cursor.com>
Moves BASE_CONTRACTS_COMMIT from 30e4390 to 0ae2de1, which reverts the
AggregateVerifier cadence split (#436) and removes the BaseTime predeploy
(#437). ProtocolVersions, OptimismPortal2, SystemConfig and
DisputeGameFactory are untouched between the two pins.

The revert collapses the slow/fast interval pairs back to a single
blockInterval/intermediateBlockInterval pair, so the constructor takes two
plain arguments instead of an IntervalConfig struct and the previously
assumed fast-cadence values are gone -- both intervals now come straight
from the live implementation.

The revert also rolls AggregateVerifier back to 0.1.0, the same version
the live implementation reports, so version no longer distinguishes them.
The upgrade script now asserts the redeploy produced a different address
and relies on the PROTOCOL_VERSIONS binding, which the predecessor does
not have, as the real discriminator.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/FACILITATOR.md Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/Makefile Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/Makefile Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/Makefile Outdated
Comment thread active/evm/foundry.toml Outdated
- Point the pin comment at the v8.3.0 release branch.
- Drop RECORD_STATE_DIFF; the pinned signer tool injects it when it spawns
  forge (src/lib/state-diff.ts).
- Schedule Cobalt for 2026-09-16 18:00:00 UTC instead of leaving it
  unscheduled.
- Set the minimum protocol version to v1.4.0, documenting the packing and
  the cast command to re-derive it.
- Blank the TEE and ZK program hashes with a TODO pointing at
  base/base releases/v1.4.0; the deploy script refuses to run until they
  are set. Every other AggregateVerifier constructor argument, including
  the config hash and block intervals, is now read back from the live
  implementation, and the portal's proof maturity delay is read from the
  live portal.
- Record the ABI-encoded constructor args in addresses.json so the verify
  targets no longer rebuild them from config.
- Remove the DEPLOYER variable and both Makefile validation targets; the
  scripts already assert these conditions.
- Fold the shared remappings into profile.default so the Cobalt profiles
  only carry the optimizer settings that actually differ.
- Trim the facilitator risk list to the items that apply to us.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/foundry.toml Outdated
… profiles

Move the Cobalt activation to 2026-09-16 16:00:00 UTC and lower the minimum
protocol version to v1.3.2.

Replace the two Cobalt foundry profiles with FOUNDRY_* overrides on the deploy
targets, matching what the verify targets already do. Verified the overrides
reproduce the profile builds byte for byte for OptimismPortal2 at 5000 runs and
for ProtocolVersions and AggregateVerifier at 999999.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
Set the three AggregateVerifier proof hashes and move to the semver bump
commit on releases/v8.3.0.

The repin changes OptimismPortal2 5.2.0 -> 6.0.0, DisputeGameFactory
1.4.0 -> 1.5.0 and AggregateVerifier 0.1.0 -> 0.2.0, so update the version
assertions in all three scripts. Because version() now distinguishes old from
new, add postchecks that read it back through the portal and factory proxies
and off the registered verifier, and drop the FACILITATOR note that said
version strings were useless here.

Co-authored-by: Cursor <cursoragent@cursor.com>
@jackchuma

Copy link
Copy Markdown
Contributor Author

Heads up on a gap this task surfaced, raised upstream:

#439, the commit this task now pins to, bumped OptimismPortal2, DisputeGameFactory and AggregateVerifier because each had source changes relative to what is deployed onchain while still declaring the same semver. SystemConfig qualifies on the same grounds and was missed: #378 changed paused() to stop selecting the pause identifier from the lockbox address, and dropped the ETH_LOCKBOX guard in _setFeature, with no version change. semver-lock.json already recorded a different sourceCodeHash and initCodeHash across that change while @custom:semver stayed at 3.13.2.

Minor rather than major since no function, error or event declarations moved, matching the DisputeGameFactory 1.4.0 -> 1.5.0 precedent. Both PRs are green (just test 1231 passed on main, 1214 on the release branch; just snapshots produces no changes beyond the one lock entry).

This PR is unaffected as it stands — it stays pinned to 33cad5ec and _postCheck compares the SystemConfig implementation address, so a missed upgrade is still caught. If #441 merges before this task executes, the repin is mechanical but touches four places: patch/max-gas-limit.patch rewrites the semver line, and the 3.13.2+max-gas-limit-2000M assertions in DeployCobaltCoreImpls, ExecuteCobaltUpgrade (pre- and postcheck) and the FACILITATOR caveat would all become 3.14.0+max-gas-limit-2000M. Happy to do that once it lands, or leave this on the current pin — your call.

Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env Outdated
base/contracts#441 landed the SystemConfig bump on releases/v8.3.0, so
SystemConfig now goes 3.13.2 -> 3.14.0 and the patched build is
3.14.0+max-gas-limit-2000M.

Regenerate max-gas-limit.patch against the new baseline rather than editing the
hunks by hand, and update the patched-version assertions in
DeployCobaltCoreImpls and in the ExecuteCobaltUpgrade pre- and postchecks.

SystemConfig is no longer the contract where only the implementation address
distinguishes old from new, so drop that caveat from FACILITATOR.md; all four
upgraded contracts now bump their version.

Co-authored-by: Cursor <cursoragent@cursor.com>
@jackchuma

Copy link
Copy Markdown
Contributor Author

Repinned to 385f21a4 now that base/contracts#441 has merged, so SystemConfig is 3.13.2 -> 3.14.0 and the patched build is 3.14.0+max-gas-limit-2000M.

  • Regenerated patch/max-gas-limit.patch against the new baseline rather than hand-editing the hunks; it applies with no fuzz.
  • Updated the patched-version assertions in DeployCobaltCoreImpls and in both the pre- and postcheck of ExecuteCobaltUpgrade.
  • Dropped the FACILITATOR caveat that singled out SystemConfig — all four upgraded contracts now bump, so version() read through each proxy is a sound check that the upgrade landed.

Re-validated on a hoodi fork at the new pin. Both deploys produce OptimismPortal2 6.0.0, SystemConfig 3.14.0+max-gas-limit-2000M, DisputeGameFactory 1.5.0, ProtocolVersions 1.0.0 and AggregateVerifier 0.2.0; _preCheck passes; and after the five calls every proxy serves the expected version with portal balance, slot 63, gas limit, game count and pause state unchanged. Also confirmed setGasLimit(1_999_999_999) still succeeds post-upgrade, which would revert against the stock 500M cap — so the patch survived the repin.

Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env
jackchuma and others added 5 commits September 15, 2026 07:46
forge verify-contract runs with lib/contracts as the project root, which is the
only root the target paths resolve from. base/contracts imports its own
dependencies through literal lib/<dep>/... paths that resolve against that root
as well, but the build keeps them a level up in active/evm/lib, so the submitted
standard JSON omitted them and Etherscan failed to compile.

Link the four dependencies in for the duration of each verify target and remove
them afterwards. Leaving them in place is not an option: the build then matches
those imports in two locations and fails as ambiguous.
The schedule assumed a re-genesised Zeronet had every fork through Beryl active
at the genesis timestamp. Azul and Beryl actually activated after it, at genesis
+300s and +600s, per the ZERONET chain config in base/base, which is what the
nodes fork on. Ids 10 and 11 were therefore importing activations five and ten
minutes earlier than they happened.

Every other id matches the node config. The schedule is an initialize argument
passed in the upgrade transaction, and neither the deployed AggregateVerifier
nor the registry bakes it in, so nothing needs redeploying.
@jackchuma
jackchuma marked this pull request as ready for review September 15, 2026 13:58
Comment thread active/evm/tasks/2026-09-14-cobalt-upgrade/config/zeronet/.env
The three hashes were listed with no provenance, so a reviewer had no way to
check them short of asking. Record the node release they are built from,
base/base releases/v1.4.0, and how each is produced: the TEE value is PCR0 of the
reproducible Nitro enclave image from crates/proof/tee, and the two ZK values are
the SP1 range and aggregation verification keys from just succinct vkeys --build.

All three match the AggregateVerifier already deployed at 0x2504B1c3.
@cb-heimdall
cb-heimdall dismissed roger-bai-coinbase’s stale review September 15, 2026 18:00

Approved review 5213222189 from roger-bai-coinbase is now dismissed due to new commit. Re-request for approval.

@jackchuma
jackchuma merged commit a670931 into main Sep 15, 2026
5 checks passed
@jackchuma
jackchuma deleted the jackchuma/zeronet-cobalt-upgrade branch September 15, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants