Skip to content
Merged
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
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
5 changes: 5 additions & 0 deletions contracts/script/check/CheckVersions.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion deployments/config.op-mainnet.json
Original file line number Diff line number Diff line change
@@ -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."}
2 changes: 1 addition & 1 deletion deployments/config.optimism.json
Original file line number Diff line number Diff line change
@@ -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"}
{"_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"}
90 changes: 90 additions & 0 deletions docs/deployment/op-mainnet-v5-runbook.md
Original file line number Diff line number Diff line change
@@ -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 <each-Ownable-contract> \
"transferOwnership(address)" 0x51eDf11fDb0A4F66220eFb8efA54Eca77232E114 \
--rpc-url "$OP_MAINNET_RPC_URL" --account <deployer-keystore>
# 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 `<each-Ownable-contract>` / `<deployer-keystore>` 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.
Loading