Verify a wallet rotation / SC-dev offboarding is complete across all active networks — Safe-owner membership (old removed / new added), Timelock CANCELLER_ROLE (old removed / new granted), whitelist permission, staging-diamond `owner()`, and wallet funding (the CI funding check). Generalizes the hardcoded `script/tasks/temp/checkOffboardingStatusPerNetwork.ts` (whose addresses are baked-in module constants) into a reusable, flag-driven check that takes old/new addresses as citty flags — writi...
Scanned 9/1/2026
Install to Claude Code
npx -y skills add lifinance/contracts --skill check-rotation-status --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Check Rotation Status?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lifinance-check-rotation-status)More formats (shields.io, HTML) on the badges page.
---
name: check-rotation-status
description: Verify a wallet rotation / SC-dev offboarding is complete across all active networks — Safe-owner membership (old removed / new added), Timelock CANCELLER_ROLE (old removed / new granted), whitelist permission, staging-diamond `owner()`, and wallet funding (the CI funding check). Generalizes the hardcoded `script/tasks/temp/checkOffboardingStatusPerNetwork.ts` (whose addresses are baked-in module constants) into a reusable, flag-driven check that takes old/new addresses as citty flags — writing that generalized checker is this skill's real work. Read-only, so it is the natural final gate for every rotate-* skill and the `offboard-sc-dev` orchestrator. Use when the user says "check the offboarding status", "verify the rotation is complete", "is the deployer/dev rotation done across all chains", "run the rotation status check", or similar. NOT for performing any rotation step — those are `rotate-dev-wallet` / `rotate-deployer-wallet` / `rotate-pauser-wallet`. Requires `bun` and RPC access (premium RPC via `ETH_NODE_URI_<NETWORK>` env vars recommended).
usage: /check-rotation-status --old-address 0xOLD --new-address 0xNEW [--role deployer|dev|pauser] [--removed-signer 0x] [--network <csv>] [--production]
---
# Check Rotation Status
## Purpose
Confirm, across every active network, that a wallet rotation actually landed
on-chain — not just that the PRs merged. It reads the same set of facts a
completed rotation must satisfy and prints a per-network pass/fail matrix:
- **Safe multisig membership** — old signer removed, new signer added.
- **Timelock `CANCELLER_ROLE`** — old deployer's role revoked, new deployer's
granted (deployer rotations).
- **Whitelist permission** (`AccessManagerFacet.addressCanExecuteMethod`) — old
deployer's whitelist authority removed; whitelisting moved to the multisig.
- **Staging diamond `owner()`** — matches the current dev wallet from config.
- **Wallet funding** — the rotated-in wallet has gas on each chain (the CI
funding check), so it can actually operate.
Because it changes nothing, it is the completeness gate at the end of every
`rotate-*` flow and of `offboard-sc-dev`.
## The real work: generalize the hardcoded temp checker
`script/tasks/temp/checkOffboardingStatusPerNetwork.ts` already implements the
per-network read logic (Safe owners via `getOwners`, Timelock `CANCELLER_ROLE`
via `hasRole`, whitelist via `addressCanExecuteMethod`, staging `owner()`), the
parallel fan-out over active networks, the `tron`/`tronshasta` exclusion, and
the colored pass/fail table. **But its addresses are hardcoded module
constants** (`OLD_DEPLOYER`, `NEW_DEPLOYER`, `MICHAL_SAFE_SIGNER`,
`OLD_SC_DEV_WALLET`, `NEW_SC_DEV_WALLET`) tied to one offboarding cycle — so it
cannot be reused for the next rotation without editing source.
This skill owns turning that one-off into a **flag-driven, reusable** check.
Concretely:
1. Copy the read logic out of `temp/` into a permanent home
(e.g. `script/tasks/checkRotationStatusPerNetwork.ts`) — keep the `temp/`
file as the reference implementation; do not delete it as part of this skill.
2. Replace the hardcoded constants with **citty flags** (camelCase, matching
the repo's other citty scripts):
- `--oldAddress` (required) — the rotated-OUT EVM address.
- `--newAddress` (required) — the rotated-IN EVM address.
- `--role` — `deployer` | `dev` | `pauser`, selects which checks apply
(a dev rotation has no CANCELLER/whitelist columns; a pauser rotation is
the funding + config check).
- `--removedSigner` (optional) — an additional departing Safe signer to
assert removed (the `MICHAL_SAFE_SIGNER` case, for offboarding).
- `--network` (optional) — restrict to one network; default all active.
- `--json` (optional) — machine-readable output for the orchestrator.
Wrap each address flag in viem's `getAddress()` at parse time (as the temp
script does with its constants) so a mistyped literal fails fast at startup
rather than silently flipping a check to a false pass.
3. Preserve the existing exclusions (`tron`, `tronshasta` are non-EVM → shown
as `-`) and the premium-RPC-first resolution (`getRPCEnvVarName` →
`ETH_NODE_URI_<NETWORK>` fallback to `networks.json`).
Until that generalized script exists in the branch, this skill's first action
is to create it; do not shell out to the `temp/` file with edited constants.
## When to use / when NOT
Use when the user says any of:
- "check the offboarding / rotation status"
- "verify the rotation is complete" / "is the deployer rotation done everywhere"
- "run the rotation status check across all chains"
Called as the final gate by `rotate-dev-wallet`, `rotate-deployer-wallet`,
`rotate-pauser-wallet`, and `offboard-sc-dev`.
Do NOT use to *perform* any rotation step (Safe owner swap, role move, funding).
Those belong to the `rotate-*` skills and `multisig-rollout`. This skill only
reads and reports.
## Inputs
Required:
- **--old-address** — `0x…` rotated-OUT EVM address.
- **--new-address** — `0x…` rotated-IN EVM address.
Optional:
- **--role** — `deployer` (default; full column set) | `dev` (staging owner +
funding) | `pauser` (funding + config). Selects applicable checks.
- **--removed-signer** — extra departing Safe signer to assert removed.
- **--network** — restrict to the given network(s) (csv); default all active.
- **--production** — target production (default staging), mirroring the
`.env PRODUCTION=true` double-opt-in rail.
## Guardrails
- **Read-only.** This skill and its script make only `view`/`call` RPC reads.
It never signs, broadcasts, or writes config. It is safe to run any number of
times and is the intended dry-run gate for the rotations.
- **Custody guard.** The addresses under test must be SC-owned roles
(**deployer, dev, pauser**). Never run a "rotation complete" assertion against
refund / feeCollector / withdraw (CTO-owned) addresses — those are not rotated.
- **Fail fast on bad input.** `getAddress()`-wrap both address flags so a typo
aborts at startup instead of reporting a green (a wrong-but-well-formed
address would read as "old already removed / not present" and falsely pass).
- **No silent RPC downgrade.** Networks that error (RPC auth/403/deprecated) are
reported as `❓ with errors`, never counted as passing. Prefer premium RPC via
`ETH_NODE_URI_<NETWORK>`.
- **Exit codes** (so an orchestrator can branch): `0` = all applicable checks
pass on all reachable networks; `1` = at least one check failed on a reachable
network (rotation incomplete — report which); `2` = recoverable misconfig
(e.g. required RPC env missing for networks that erred — name the var). Tron
exclusions and genuinely-absent staging diamonds are not failures.
- Foundry/bun may need `export PATH="$HOME/.foundry/bin:$HOME/.bun/bin:$PATH"`.
## Workflow
### 1. Ensure the generalized checker exists (this skill's build step)
If `script/tasks/checkRotationStatusPerNetwork.ts` does not yet exist on the
branch, create it per "The real work" above — lift the read logic from
`script/tasks/temp/checkOffboardingStatusPerNetwork.ts`, swap the hardcoded
constants for citty flags, keep the exclusions and premium-RPC resolution.
Leave the `temp/` script in place as the reference.
### 2. Run the check
```bash
export PATH="$HOME/.foundry/bin:$HOME/.bun/bin:$PATH"
bunx tsx script/tasks/checkRotationStatusPerNetwork.ts \
--oldAddress 0xOLD --newAddress 0xNEW --role deployer
```
Add `--removedSigner 0x…` for an offboarding that also drops a departing Safe
signer, `--network <name>` to scope to one chain, or `--json` for the
orchestrator. The script fans out over active networks in parallel and prints
the per-network matrix plus a summary (`✅ completed / ❌ incomplete / ❓ errors`).
### 3. Interpret the matrix
- **All applicable columns ✅ on every reachable network** → rotation complete
for that role (exit `0`).
- **Any ❌** → that check has not landed on that network; name the network +
column and hand back to the owning rotation step (do not "fix" it here).
- **`❓` / errors** → RPC connectivity, not a rotation failure. Re-run with a
premium `ETH_NODE_URI_<NETWORK>` set; if still unreachable, report the network
as unverified rather than pass or fail.
- **`-` (tron/tronshasta)** → excluded EVM-check-wise; Tron completeness is
verified separately by `move-tron-delegation` (delegation) and the Tron
ownership move — call that out, don't imply Tron is covered here.
## Verification
State the outcome precisely:
- Per-network pass/fail for each applicable column, and the summary counts.
- Networks that errored (and the env var to set to re-verify them).
- An explicit "rotation complete" claim ONLY when every applicable check is ✅
on every reachable network AND the Tron side has been confirmed by its own
skill. Otherwise list exactly what remains and which skill owns it.
## Reuse map
- `script/tasks/temp/checkOffboardingStatusPerNetwork.ts` — reference
implementation this skill generalizes (hardcoded → flag-driven).
- `config/networks.json` + `getRPCEnvVarName` / `getViemChainForNetworkName` /
`getDeployments` — network list, RPC resolution, chain + deployment lookups
reused by the generalized script.
- `move-tron-delegation` — verifies the Tron delegation half (this skill
excludes Tron from EVM checks).
- `rotate-dev-wallet` / `rotate-deployer-wallet` / `rotate-pauser-wallet` /
`offboard-sc-dev` — callers that use this skill as their completeness gate.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!