diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ed062ed..3392586d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,15 @@ Fork → 新建分支 → 写代码 → 提交 PR → 签 CLA → Review → Mer - Commit 规范:[Conventional Commits](https://www.conventionalcommits.org/) - 问题反馈:在本仓库提 Issue +## 版本命名约定 (CC-14 · 全生态) + +对外沟通的版本号**必须带产品名** —— CHANGELOG、PR 标题、release notes、issue 评论、跨仓沟通一律如此,禁止裸报数字。 + +- ✅ `SuperPaymaster v5.4.2`、`@aastar/sdk 0.39.4`、`airaccount-contract v0.27.0`、`YetAnotherAA-Validator (DVT) v1.9.0` +- ❌ `v5.4.2`、`0.39`、`v0.27`(多条独立版本轨道混说会分不清哪个产品) + +版本字符串本身保持**干净 semver**(不要把产品名塞进 `version()` 之外的 npm/tag 字符串——会坏工具链);产品名只出现在**人类可读文本**里。合约 `version()` 沿用 `"ContractName-X.Y.Z"`(如 `"SuperPaymaster-5.4.2"`)。报同步时两边都写全名:「SDK 0.39.4 同步到 SuperPaymaster v5.4.2」。 + ## License Contributions are licensed under [Apache License 2.0](LICENSE). diff --git a/contracts/script/check/CheckVersions.s.sol b/contracts/script/check/CheckVersions.s.sol index 15416cb7..766488e6 100644 --- a/contracts/script/check/CheckVersions.s.sol +++ b/contracts/script/check/CheckVersions.s.sol @@ -27,6 +27,11 @@ contract CheckVersions is Script { network = "op-sepolia"; } else if (block.chainid == 1) { network = "mainnet"; + } else if (block.chainid == 10) { + // OP mainnet → authoritative V5 config (config.op-mainnet.json); NOT the legacy + // V3 config.optimism.json (CC-30 G10). Without this case chainid 10 fell through + // to "10" → config.10.json (missing) → version verification was not executable. + network = "op-mainnet"; } else { network = vm.toString(block.chainid); } diff --git a/deployments/config.op-mainnet.json b/deployments/config.op-mainnet.json index 1f7f6354..f4bae315 100644 --- a/deployments/config.op-mainnet.json +++ b/deployments/config.op-mainnet.json @@ -1 +1 @@ -{"_note":"stub — populated by deploy-core --fresh-deploy op-mainnet"} +{"_note":"AUTHORITATIVE OP mainnet (chain 10) config for the V5.4.2 launch (CC-30 G10). Stub — populated by `./deploy-core op-mainnet --fresh-deploy` (first V5.4.2 full-stack deploy on chain 10 = new UUPS proxies). config.optimism.json is the LEGACY V3 record and must NOT be used for V5 canonical addresses. See docs/deployment/op-mainnet-v5-runbook.md."} diff --git a/deployments/config.optimism.json b/deployments/config.optimism.json index 073095dc..3e55658c 100644 --- a/deployments/config.optimism.json +++ b/deployments/config.optimism.json @@ -1 +1 @@ -{"aPNTs":"0x0B41C78081B5A141eb4C3C7E7FD8E58A7Bde553B","blsAggregator":"0x1C305372ecc5a36CBef1FA371392234bCD55eB19","blsValidator":"0xA88ADec5A8dc422B57488272d5aD5913d728942A","dvtValidator":"0x31Ede6454a56293f7cf2323CA5d5F9a6230558Fb","entryPoint":"0x0000000071727De22E5E9d8BAf0edAc6f37da032","gToken":"0x8d6Fe002dDacCcFBD377F684EC1825f2E1ab7ef6","paymasterFactory":"0x58A7F6E44a57028A255794119F8b37124c9a7eB8","paymasterV4Impl":"0xc4dd13F7825409EEC13FBCBdD9D8f6d618207cca","priceFeed":"0x13e3Ee699D1909E989722E753853AE30b17e08c5","registry":"0x997686219F31405503D32728B1f094F115EF24e7","reputationSystem":"0xA9560898dC0eE4F9Ed3F1db17dbf74dE65e925c2","sbt":"0x28eBFc5fc03B1d7648254AbF1C7B39DbFdef1a94","simpleAccountFactory":"0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985","srcHash":"bf217d53f91e62226b666326f38d4533f57b64b6ebf43728b52c4e636bed1b1a","staking":"0x7A1216C2d814D2389698C64eD23AA1aA9Eb6343E","superPaymaster":"0xA2c9A6e95f19f5D2a364CBCbB5f0b32B1B4d140E","updateTime":"2026-02-11 12:03:21","xPNTsFactory":"0x864971a26384d9DCC7115f0bBC428e2623F28b6e"} \ No newline at end of file +{"_note":"LEGACY V3 (chain 10 / OP mainnet, SuperPaymaster-3.2.2 / Registry-3.0.2). SUPERSEDED for the V5.4.2 launch by config.op-mainnet.json (deploy-core env 'op-mainnet' is authoritative for OP mainnet going forward — CC-30 G10). Kept as the historical on-chain record of the old V3 deployment; do NOT read this for V5 canonical addresses.","aPNTs":"0x0B41C78081B5A141eb4C3C7E7FD8E58A7Bde553B","blsAggregator":"0x1C305372ecc5a36CBef1FA371392234bCD55eB19","blsValidator":"0xA88ADec5A8dc422B57488272d5aD5913d728942A","dvtValidator":"0x31Ede6454a56293f7cf2323CA5d5F9a6230558Fb","entryPoint":"0x0000000071727De22E5E9d8BAf0edAc6f37da032","gToken":"0x8d6Fe002dDacCcFBD377F684EC1825f2E1ab7ef6","paymasterFactory":"0x58A7F6E44a57028A255794119F8b37124c9a7eB8","paymasterV4Impl":"0xc4dd13F7825409EEC13FBCBdD9D8f6d618207cca","priceFeed":"0x13e3Ee699D1909E989722E753853AE30b17e08c5","registry":"0x997686219F31405503D32728B1f094F115EF24e7","reputationSystem":"0xA9560898dC0eE4F9Ed3F1db17dbf74dE65e925c2","sbt":"0x28eBFc5fc03B1d7648254AbF1C7B39DbFdef1a94","simpleAccountFactory":"0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985","srcHash":"bf217d53f91e62226b666326f38d4533f57b64b6ebf43728b52c4e636bed1b1a","staking":"0x7A1216C2d814D2389698C64eD23AA1aA9Eb6343E","superPaymaster":"0xA2c9A6e95f19f5D2a364CBCbB5f0b32B1B4d140E","updateTime":"2026-02-11 12:03:21","xPNTsFactory":"0x864971a26384d9DCC7115f0bBC428e2623F28b6e"} \ No newline at end of file diff --git a/docs/deployment/op-mainnet-v5-runbook.md b/docs/deployment/op-mainnet-v5-runbook.md new file mode 100644 index 00000000..1d7ff152 --- /dev/null +++ b/docs/deployment/op-mainnet-v5-runbook.md @@ -0,0 +1,90 @@ +# OP Mainnet V5.4.2 Deploy Runbook (CC-30 · G1) + +**Goal**: bring OP mainnet (chain 10) from the legacy **V3** stack (`SuperPaymaster-3.2.2 / Registry-3.0.2`) up to the current **V5.4.2** full stack — the headline mainnet blocker (CC-30 G1). SDK/YAAA/airaccount canonical-mainnet all wait on this. + +> **Core principle** (CC-30): testnet vs mainnet = **configuration only**; contract logic is identical to Sepolia V5.4.2 (already live + audited through Codex rounds). This runbook adds **no new deploy code** — the path already exists. + +--- + +## The deploy path already exists + +`./deploy-core op-mainnet` is the canonical V5.4.2 full-stack deploy: +- Reads `.env.op-mainnet` (RPC + signer). +- Runs `DeployLive.s.sol` — **v5.4-aware** (deploys core + `X402Facilitator` + `TimelockController` + `PolicyRegistry` and wires them; shares logic with `DeployV54.s.sol` via `V54Bootstrap` so they cannot drift). +- Writes `deployments/config.op-mainnet.json` (**authoritative** for OP mainnet V5; `config.optimism.json` is the legacy-V3 record — G10). + +So G1 is **not** a code task; it is a **gated ops task**. Do NOT run it until the prerequisites below are green. + +--- + +## Prerequisites (hard gates — all must be green) + +| # | Gate | Owner | State | +|---|---|---|---| +| 1 | External security audit of V5.4.2 full stack passed | jason | 🔴 GA hard gate | +| 2 | OP mainnet deployer keystore funded (cast wallet / Foundry keystore) | jason | 🔴 | +| 3 | `.env.op-mainnet` filled: `OP_MAINNET_RPC_URL` (deploy-core reads `${ENV_UPPER//-/_}_RPC_URL`), signer (`DEPLOYER_ACCOUNT` keystore preferred over `PRIVATE_KEY`) | jason | 🔴 (template exists, secrets pending) | +| 4 | DVT mainnet validators + production nodes ready (BLS quorum is a slash prerequisite) | @repo:dvt | 🔴 | +| 5 | Chainlink ETH/USD price feed address for OP mainnet confirmed in deploy config | SP | 🟡 verify | +| 6 | Mycelium community Safe reachable on OP mainnet (`0x51eDf11fDb0A4F66220eFb8efA54Eca77232E114`, `oeth:`) for post-deploy ownership transfer (CC-31) | jason | ✅ address known | + +--- + +## Deploy sequence + +```bash +# 0. Pre-flight: load env; confirm OP_MAINNET_RPC_URL is set (deploy-core reads it as +# ${ENV_UPPER//-/_}_RPC_URL). config.op-mainnet.json is the target (authoritative); +# config.optimism.json is legacy V3 — do NOT deploy into it. +set -a; . ./.env.op-mainnet; set +a +[ -n "$OP_MAINNET_RPC_URL" ] || { echo "OP_MAINNET_RPC_URL unset"; exit 1; } + +# 1. Full-stack V5.4.2 deploy → writes deployments/config.op-mainnet.json. +# --fresh-deploy: this is the FIRST V5 deploy on chain 10 → new UUPS proxies. V5 is NOT an +# in-place upgrade of the legacy V3 (storage layout differs), so the "--fresh-deploy will +# LOSE all on-chain state" warning is EXPECTED and correct — the V3 stack is superseded, +# not upgraded. (Use plain `./deploy-core op-mainnet` only for later same-stack redeploys; +# `--force` only to override the skip-if-srcHash-unchanged guard.) +./deploy-core op-mainnet --fresh-deploy + +# 2. Verify on-chain versions (fail = stop). Script takes the RPC URL as its arg. +./version-check-onchain.sh "$OP_MAINNET_RPC_URL" # expect SuperPaymaster-5.4.2 / V5 stack + +# 3. Post-deploy ownership → EOA-first, then Safe once stable (mirror CC-29 model). +# Per Ownable contract (SuperPaymaster, Registry, LivenessRegistry, PolicyRegistry guardian, +# factories, …) transfer to the Safe. Exact call is per-contract — Ownable uses +# transferOwnership(address); slashPolicyAdmin / role-admins use their own setter (item 6). +cast send \ + "transferOwnership(address)" 0x51eDf11fDb0A4F66220eFb8efA54Eca77232E114 \ + --rpc-url "$OP_MAINNET_RPC_URL" --account +# Also: slashPolicyAdmin → Safe/Timelock (CC-30 item 6, its own setter, not transferOwnership). + +# 4. aPNTs mainnet address + fund SuperPaymaster deposit (CC-30 item 7). + +# 5. EntryPoint stake / deposit for the paymaster as required. +``` + +> The `` / `` placeholders are the only non-literal +> parts — fill them from the freshly-written `config.op-mainnet.json` and your keystore name. + +--- + +## Post-deploy — record + notify (do not skip) + +1. Commit `deployments/config.op-mainnet.json` (real addresses) via a `deploy(op-mainnet): …` PR — the config-driven single source. +2. Post the mainnet addresses to **CC-30** and `@` the dependents: + - `@repo:sdk` —接入 `CANONICAL_ADDRESSES[10]`(覆盖旧 V3)+ 链上 `version()==5.4.2` 自验 → 发主网 patch(CC-18 两阶段)。 + - `@repo:yaaa` — gasless 主网就绪。 + - `@repo:airaccount-contract` — aPNTs 主网地址交付。 +3. Update memory `cc30-production-readiness`. + +--- + +## Config authority (G10 — resolved) + +| env / file | chain | stack | role | +|---|---|---|---| +| `op-mainnet` / `config.op-mainnet.json` | 10 | V5.4.2 | **authoritative** (this runbook targets it) | +| `optimism` / `config.optimism.json` | 10 | V3 (3.2.2) | **legacy record** — do not read for V5 canonical | + +Downstream (SDK) should read OP-mainnet canonical from the `op-mainnet` config once populated.