security(phase1b): Chain 138 admin transfer-then-revoke Forge scripts + runbook #1
Reference in New Issue
Block a user
Delete Branch "devin/phase1b-chain138-admin-rotation-1776543648"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Part of the sequenced cleanup tracked in https://gitea.d-bis.org/d-bis/proxmox/issues/1. Phase 1b — Chain 138 admin transfer-then-revoke Forge scripts. Scaffolding only; no broadcast, no secret values committed.
The Chain 138 deployer EOA
0x4A666F96fC8764181194447A7dFdb7d471b301C8was committed tod-bis/proxmoxin plaintext and must be rotated off every contract it controls. Because the key is an EOA (not a multisig), rotation is transfer-then-revoke, not revoke-first — perdocs/runbooks/MULTI_CHAIN_EXECUTION_KEY_ROTATION.md.What this PR adds
script/rotation/RotateChain138Admin.s.solRotateStage1(OLD signs, grants NEW),RotateStage2(NEW signs, revokes OLD),VerifyChain138RotationComplete(read-only end-state check). Targets cUSDT, cUSDC, DODOPMMIntegration (plusPOOL_MANAGER_ROLE+SWAP_OPERATOR_ROLEon DODOPMMIntegration).script/rotation/README.mdscripts/rotation/chain138-rotation-runbook.mdforge scriptsequences, Stage-1/Stage-2 verification (cast call), rollback path (only possible between stages), per-chain template for follow-up PRs.Design
forge script ... -vvvsimulates against the RPC and prints calldata; broadcasting requires explicit--broadcast --slow, and the runbook gates that behind per-tx operator approval.vm.addr(PRIVATE_KEY)to match the expected signer (Stage 1: OLD deployer; Stage 2: NEW admin). Prevents signing with the wrong key.docs/11-references/EXPLORER_TOKEN_LIST_CROSSCHECK.md§5; overridable via env for test environments.OLD_DEPLOYER_ADDRESSdefaults to0x4A66…01C8.VerifyChain138RotationCompletereverts with a specific message if any contract still names OLD as owner/admin. Exit code 0 = rotation complete.What this PR does NOT do
forge scriptsimulates by default;--broadcastis a separate operator decision per the runbook.script/rotation/README.md.owner()/_OWNER_()reverted during Phase 1b discovery, suggesting they may be immutable DODO-style pools without a rotatable admin. A follow-up probes their actual role model with the source.MINTER_ROLEon CompliantFiatToken derivatives (cXAUC / cXAUT etc.) — discovery shows the deployer holdsDEFAULT_ADMIN_ROLEon those, andMINTER_ROLEis delegated elsewhere. Follow-up once the actual minter grants are enumerated on-chain.PRIVATE_KEYas an env var the operator supplies locally.Review & Testing Checklist for Human
Risk: yellow — scripts do nothing until
--broadcastis added, but when they do run they change on-chain admin state permanently. Stage 2 is irreversible.scripts/rotation/chain138-rotation-runbook.mdend-to-end; confirm the simulate-before-broadcast + stage-then-revoke flow matches how you actually want this executed.script/rotation/RotateChain138Admin.s.sol:DEFAULT_*constants matchdocs/11-references/EXPLORER_TOKEN_LIST_CROSSCHECK.md§5.requireset covers the failure modes you care about.SWAP_OPERATOR_ROLE/POOL_MANAGER_ROLEgrant in Stage 1 is intentional (deployer holds both today per the Phase 1b discovery).0xff8d…0849,0x6fc6…9D71,0x9f74…0263) need admin rotation — follow-up PR pending.NEW_ADMIN_ADDRESStarget (Gnosis Safe preferred per runbook §0.2) and who holds the signer.Next
Once the
NEW_ADMIN_ADDRESSdecision is made, operator executes §2 and §3 of the runbook with per-tx approval. Follow-up PRs stage the same pattern for the other chains.Tracking: https://gitea.d-bis.org/d-bis/proxmox/issues/1.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.