Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions zeronet/2026-07-15-fix-nitro-verifier-id/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
BASE_CONTRACTS_COMMIT=1baa168c9db6a946ae47863ea07295bedb3599a6

# Owner and live verifier used by the Zeronet TEEProverRegistry.
TEE_PROVER_REGISTRY_OWNER=0x856611ed7e07d83243b15e93f6321f2df6865852
NITRO_ENCLAVE_VERIFIER=0xDC06089B0224e59bAAa9B59c3C5aAF9Ff105997C

# Align NitroEnclaveVerifier with the Boundless Nitro attestation guest.
CURRENT_NITRO_ZK_VERIFIER_ID=0x15051db631d6ed382d957c795a558a0abdd00d0d22a1670455721bc2712d3d6e
NITRO_ZK_VERIFIER_ID=0x20141665fe40bce01fbcfa0a95c8a1bd750eadbe3f24e06a75571e6fd7a9dc11

RECORD_STATE_DIFF=true
21 changes: 21 additions & 0 deletions zeronet/2026-07-15-fix-nitro-verifier-id/FACILITATOR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Facilitator Guide

## Generate the validation file

```bash
cd zeronet/2026-07-15-fix-nitro-verifier-id
make deps
make gen-validation
```

This creates `validations/base-signer.json`.

The script requires the live RISC Zero verifier ID to equal `CURRENT_NITRO_ZK_VERIFIER_ID` before it creates the approval payload.

## Execute

Collect the required signatures, then run:

```bash
SIGNATURES="[SIGNATURE1][SIGNATURE2]..." make execute
```
41 changes: 41 additions & 0 deletions zeronet/2026-07-15-fix-nitro-verifier-id/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
include ../../Makefile
include ../../Multisig.mk
include ../.env
include .env

RPC_URL = $(L1_RPC_URL)
SCRIPT_NAME = script/FixNitroVerifierId.s.sol:FixNitroVerifierId
VALIDATION_FILE = base-signer.json
SENDER ?= $(shell cast call $(TEE_PROVER_REGISTRY_OWNER) "getOwners()(address[])" --rpc-url $(L1_RPC_URL) | tr -d '[]' | cut -d',' -f1)

.PHONY: deps
deps: task-extra-deps

.PHONY: task-extra-deps
task-extra-deps:
forge install --no-git github.com/base/op-enclave@a2d5398f04c3a8e4df929d58ee638ba4a037bfec
forge install --no-git github.com/risc0/risc0-ethereum@a78ac4a52fe9cfa14120c3b496430f0d42e1d8d3
forge install --no-git github.com/succinctlabs/sp1-contracts@22c4a47cd0a388cb4e25b4f2513954e4275c74ca
git clone --no-checkout https://github.com/OpenZeppelin/openzeppelin-contracts.git lib/openzeppelin-contracts-v5 && \
cd lib/openzeppelin-contracts-v5 && git checkout dbb6104ce834628e473d2173bbc9d47f81a9eec3
git clone --no-checkout https://github.com/Vectorized/solady.git lib/solady-v0.0.245 && \
cd lib/solady-v0.0.245 && git checkout e0ef35adb0ccd1032794731a995cb599bba7b537

.PHONY: validate-config
validate-config:
@test -n "$(BASE_CONTRACTS_COMMIT)" || (echo "BASE_CONTRACTS_COMMIT required" && exit 1)
@test -n "$(TEE_PROVER_REGISTRY_OWNER)" || (echo "TEE_PROVER_REGISTRY_OWNER required" && exit 1)
@test -n "$(NITRO_ENCLAVE_VERIFIER)" || (echo "NITRO_ENCLAVE_VERIFIER required" && exit 1)
@test -n "$(CURRENT_NITRO_ZK_VERIFIER_ID)" || (echo "CURRENT_NITRO_ZK_VERIFIER_ID required" && exit 1)
@test -n "$(NITRO_ZK_VERIFIER_ID)" || (echo "NITRO_ZK_VERIFIER_ID required" && exit 1)
@test -n "$(SENDER)" || (echo "SENDER required" && exit 1)
@echo "Configuration validated successfully"

.PHONY: gen-validation
gen-validation: validate-config deps-signer-tool
mkdir -p validations; \
$(call GEN_VALIDATION,$(SCRIPT_NAME),,$(SENDER),$(VALIDATION_FILE),)

.PHONY: execute
execute: validate-config
$(call MULTISIG_EXECUTE,$(SIGNATURES))
17 changes: 17 additions & 0 deletions zeronet/2026-07-15-fix-nitro-verifier-id/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Fix Nitro Verifier ID

Status: READY TO SIGN

## Description

This task updates Zeronet `NitroEnclaveVerifier` to use the RISC Zero guest image that the registrar sends to Boundless.

It changes the RISC Zero verifier ID from `0x15051db631d6ed382d957c795a558a0abdd00d0d22a1670455721bc2712d3d6e` to `0x20141665fe40bce01fbcfa0a95c8a1bd750eadbe3f24e06a75571e6fd7a9dc11`.

No verifier route, proof submitter, certificate configuration, or ownership changes.

## Sign

Run the signing tool from the repository root, then sign `base-signer.json`.

For execution steps, see `FACILITATOR.md`.
36 changes: 36 additions & 0 deletions zeronet/2026-07-15-fix-nitro-verifier-id/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
broadcast = 'records'
fs_permissions = [{ access = "read-write", path = "./" }]
optimizer = true
optimizer_runs = 200
auto_detect_solc = true
evm_version = "prague"
via-ir = false
remappings = [
'@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts',
'@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts',
'@base-contracts/=lib/contracts/',
'@solady/=lib/solady/src/',
'@solady-v0.0.245/=lib/solady-v0.0.245/src/',
'forge-std/=lib/forge-std/src/',
'interfaces/dispute/=lib/contracts/interfaces/dispute/',
'interfaces/L1/=lib/contracts/interfaces/L1/',
'interfaces/legacy/=lib/contracts/interfaces/legacy/',
'interfaces/multiproof/=lib/contracts/interfaces/multiproof/',
'interfaces/universal/=lib/contracts/interfaces/universal/',
'src/L1/=lib/contracts/src/L1/',
'src/libraries/=lib/contracts/src/libraries/',
'src/dispute/=lib/contracts/src/dispute/',
'src/universal/=lib/contracts/src/universal/',
'lib/op-enclave/=lib/op-enclave/',
'openzeppelin/=lib/risc0-ethereum/lib/openzeppelin-contracts/',
'@lib-keccak/=lib/lib-keccak/contracts/lib/',
'interfaces/cannon/=lib/contracts/interfaces/cannon/',
'src/cannon/=lib/contracts/src/cannon/',
]

[lint]
lint_on_build = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

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";
import {ZkCoProcessorConfig, ZkCoProcessorType} from "interfaces/multiproof/tee/INitroEnclaveVerifier.sol";
import {NitroEnclaveVerifier} from "@base-contracts/src/multiproof/tee/NitroEnclaveVerifier.sol";

contract FixNitroVerifierId is MultisigScript {
address internal immutable nitroOwnerEnv;
address internal immutable nitroEnclaveVerifierEnv;
bytes32 internal immutable currentNitroZkVerifierIdEnv;
bytes32 internal immutable newNitroZkVerifierIdEnv;

address internal immutable currentProofSubmitter;
address internal immutable currentRevoker;
uint64 internal immutable currentMaxTimeDiff;
bytes32 internal immutable currentRootCert;
bytes32 internal immutable currentAggregatorId;
address internal immutable currentRouter;
bytes32 internal immutable currentVerifierProofId;

constructor() {
nitroOwnerEnv = vm.envAddress("TEE_PROVER_REGISTRY_OWNER");
nitroEnclaveVerifierEnv = vm.envAddress("NITRO_ENCLAVE_VERIFIER");
currentNitroZkVerifierIdEnv = vm.envBytes32("CURRENT_NITRO_ZK_VERIFIER_ID");
newNitroZkVerifierIdEnv = vm.envBytes32("NITRO_ZK_VERIFIER_ID");

NitroEnclaveVerifier nev = NitroEnclaveVerifier(nitroEnclaveVerifierEnv);

currentProofSubmitter = nev.proofSubmitter();
currentRevoker = nev.revoker();
currentMaxTimeDiff = nev.maxTimeDiff();
currentRootCert = nev.rootCert();
currentVerifierProofId = nev.getVerifierProofId(ZkCoProcessorType.RiscZero);

ZkCoProcessorConfig memory cfg = nev.getZkConfig(ZkCoProcessorType.RiscZero);
currentAggregatorId = cfg.aggregatorId;
currentRouter = cfg.zkVerifier;
}

function setUp() public {
require(currentNitroZkVerifierIdEnv != newNitroZkVerifierIdEnv, "verifier id already target");

NitroEnclaveVerifier nev = NitroEnclaveVerifier(nitroEnclaveVerifierEnv);
require(nev.owner() == nitroOwnerEnv, "nitro owner mismatch");

ZkCoProcessorConfig memory cfg = nev.getZkConfig(ZkCoProcessorType.RiscZero);
require(cfg.verifierId == currentNitroZkVerifierIdEnv, "unexpected current verifier id");
}

function _buildCalls() internal view override returns (Call[] memory calls) {
calls = new Call[](1);

calls[0] = Call({
operation: Enum.Operation.Call,
target: nitroEnclaveVerifierEnv,
data: abi.encodeCall(
NitroEnclaveVerifier.updateVerifierId,
(ZkCoProcessorType.RiscZero, newNitroZkVerifierIdEnv, currentVerifierProofId)
),
value: 0
});
}

function _postCheck(Vm.AccountAccess[] memory, Simulation.Payload memory) internal view override {
NitroEnclaveVerifier nev = NitroEnclaveVerifier(nitroEnclaveVerifierEnv);
ZkCoProcessorConfig memory cfg = nev.getZkConfig(ZkCoProcessorType.RiscZero);

require(nev.owner() == nitroOwnerEnv, "nitro owner changed");
require(nev.proofSubmitter() == currentProofSubmitter, "nitro proof submitter changed");
require(nev.revoker() == currentRevoker, "nitro revoker changed");
require(nev.maxTimeDiff() == currentMaxTimeDiff, "nitro max time diff changed");
require(nev.rootCert() == currentRootCert, "nitro root cert changed");
require(cfg.verifierId == newNitroZkVerifierIdEnv, "nitro verifier id mismatch");
require(cfg.aggregatorId == currentAggregatorId, "nitro aggregator id changed");
require(cfg.zkVerifier == currentRouter, "nitro router changed");
require(
nev.getVerifierProofId(ZkCoProcessorType.RiscZero) == currentVerifierProofId,
"nitro verifier proof id changed"
);
}

function _ownerSafe() internal view override returns (address) {
return nitroOwnerEnv;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"cmd": "mise exec -- forge script --rpc-url https://c3-chainproxy-eth-hoodi-full-dev.cbhq.net script/FixNitroVerifierId.s.sol:FixNitroVerifierId --sig sign(address[]) [] --sender 0x821Ff2A3fB66B008fA668B40Eca9d3535B246575",
"ledgerId": 1,
"rpcUrl": "https://c3-chainproxy-eth-hoodi-full-dev.cbhq.net",
"skipTaskOriginValidation": true,
"expectedDomainAndMessageHashes": {
"address": "0x856611eD7E07D83243b15E93f6321f2df6865852",
"domainHash": "0xc88eae2baaa4c8513a3d87913666de9463f106158aaf8be5cd31588215ccd5c4",
"messageHash": "0x7c820b997b00ef28657e75e91ef15c4bcd8f3aaa23e5fd86792574231ad992ac"
},
"stateOverrides": [
{
"name": "CB Signer Safe - Zeronet",
"address": "0x856611eD7E07D83243b15E93f6321f2df6865852",
"overrides": [
{
"key": "0x0000000000000000000000000000000000000000000000000000000000000004",
"value": "0x0000000000000000000000000000000000000000000000000000000000000001",
"description": "Override the threshold to 1 so the transaction simulation can occur.",
"allowDifference": false
},
{
"key": "0x3555b9fe675f9c37d47cdf5d509afa835b3a15227e5296f281542e1a3c8712db",
"value": "0x0000000000000000000000000000000000000000000000000000000000000001",
"description": "Simulates an approval from msg.sender in order for the task simulation to succeed.",
"allowDifference": false
}
]
}
],
"stateChanges": [
{
"name": "CB Signer Safe - Zeronet",
"address": "0x856611eD7E07D83243b15E93f6321f2df6865852",
"changes": [
{
"key": "0x0000000000000000000000000000000000000000000000000000000000000005",
"before": "0x0000000000000000000000000000000000000000000000000000000000000015",
"after": "0x0000000000000000000000000000000000000000000000000000000000000016",
"description": "Increments the nonce",
"allowDifference": false
}
]
},
{
"name": "NitroEnclaveVerifier - Zeronet",
"address": "0xDC06089B0224e59bAAa9B59c3C5aAF9Ff105997C",
"changes": [
{
"key": "0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0",
"before": "0x15051db631d6ed382d957c795a558a0abdd00d0d22a1670455721bc2712d3d6e",
"after": "0x20141665fe40bce01fbcfa0a95c8a1bd750eadbe3f24e06a75571e6fd7a9dc11",
"description": "Updates the RISC Zero verifier ID used by NitroEnclaveVerifier.",
"allowDifference": false
}
]
}
],
"balanceChanges": [],
"taskOriginConfig": {
"taskCreator": {
"commonName": "jack.chuma@coinbase.com"
}
}
}
Loading