Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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
.claude/skills/lifinance-check-rotation-status/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 93% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 52% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 72% | 0% |
| case-21 | ✗→✓ | ▲ Improved | 18% | 0% |
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:
CANCELLER_ROLE — old deployer's role revoked, new deployer'sgranted (deployer rotations).
AccessManagerFacet.addressCanExecuteMethod) — olddeployer's whitelist authority removed; whitelisting moved to the multisig.
owner() — matches the current dev wallet from config.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.
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:
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.
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 toassert 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.
tron, tronshasta are non-EVM → shownas -) 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.
Use when the user says any of:
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.
Required:
0x… rotated-OUT EVM address.0x… rotated-IN EVM address.Optional:
deployer (default; full column set) | dev (staging owner +funding) | pauser (funding + config). Selects applicable checks.
.env PRODUCTION=true double-opt-in rail.
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.
(deployer, dev, pauser). Never run a "rotation complete" assertion against refund / feeCollector / withdraw (CTO-owned) addresses — those are not rotated.
getAddress()-wrap both address flags so a typoaborts at startup instead of reporting a green (a wrong-but-well-formed address would read as "old already removed / not present" and falsely pass).
reported as ❓ with errors, never counted as passing. Prefer premium RPC via ETH_NODE_URI_<NETWORK>.
0 = all applicable checkspass 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.
export PATH="$HOME/.foundry/bin:$HOME/.bun/bin:$PATH".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.
bashexport 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).
for that role (exit 0).
column and hand back to the owning rotation step (do not "fix" it here).
❓ / errors → RPC connectivity, not a rotation failure. Re-run with apremium 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 isverified separately by move-tron-delegation (delegation) and the Tron ownership move — call that out, don't imply Tron is covered here.
State the outcome precisely:
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.
script/tasks/temp/checkOffboardingStatusPerNetwork.ts — referenceimplementation 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 skillexcludes 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.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 14,012 | 6,169 | -56% | 1 | 1 | 0% | 2,814 | 2,616 | -7% | 0 | 0 | — |
case-02 | fail→fail | 13,999 | 5,854 | -58% | 1 | 1 | 0% | 2,958 | 2,753 | -7% | 0 | 0 | — |
case-03 | fail→fail | 15,165 | 5,953 | -61% | 1 | 1 | 0% | 3,043 | 2,629 | -14% | 0 | 0 | — |
case-04 | fail→pass | 11,920 | 9,521 | -20% | 1 | 1 | 0% | 2,435 | 4,093 | +68% | 0 | 0 | — |
case-05 | fail→pass | 7,987 | 4,924 | -38% | 1 | 1 | 0% | 1,609 | 3,102 | +93% | 0 | 0 | — |
case-06 | fail→pass | 12,912 | 5,315 | -59% | 1 | 1 | 0% | 2,058 | 3,123 | +52% | 0 | 0 | — |
case-07 | fail→fail | 9,878 | 6,556 | -34% | 1 | 1 | 0% | 1,820 | 2,657 | +46% | 0 | 0 | — |
case-08 | fail→fail | 6,219 | 5,786 | -7% | 1 | 1 | 0% | 1,240 | 2,590 | +109% | 0 | 0 | — |
case-09 | fail→fail | 3,604 | 6,818 | +89% | 1 | 1 | 0% | 720 | 2,593 | +260% | 0 | 0 | — |
case-10 | fail→pass | 8,916 | 2,721 | -69% | 1 | 1 | 0% | 1,527 | 2,628 | +72% | 0 | 0 | — |
case-21 | fail→pass | 15,246 | 5,206 | -66% | 1 | 1 | 0% | 2,596 | 3,073 | +18% | 0 | 0 | — |
case-11 | pass→pass | 5,998 | 3,908 | -35% | 1 | 1 | 0% | 945 | 2,886 | +205% | 0 | 0 | — |
case-12 | fail→pass | 10,560 | 7,574 | -28% | 1 | 1 | 0% | 1,655 | 3,418 | +107% | 0 | 0 | — |
case-13 | fail→pass | 10,846 | 4,864 | -55% | 1 | 1 | 0% | 1,609 | 2,995 | +86% | 0 | 0 | — |
case-14 | pass→pass | 10,826 | 4,732 | -56% | 1 | 1 | 0% | 1,627 | 2,933 | +80% | 0 | 0 | — |
case-15 | fail→pass | 11,151 | 3,841 | -66% | 1 | 1 | 0% | 1,816 | 2,777 | +53% | 0 | 0 | — |
case-16 | fail→pass | 5,685 | 5,523 | -3% | 1 | 1 | 0% | 833 | 3,228 | +288% | 0 | 0 | — |
case-17 | fail→pass | 11,075 | 5,046 | -54% | 1 | 1 | 0% | 1,672 | 2,957 | +77% | 0 | 0 | — |
case-18 | fail→pass | 6,674 | 2,432 | -64% | 1 | 1 | 0% | 930 | 2,539 | +173% | 0 | 0 | — |
case-19 | fail→pass | 6,515 | 2,735 | -58% | 1 | 1 | 0% | 986 | 2,638 | +168% | 0 | 0 | — |
case-20 | pass→pass | 6,937 | 2,673 | -61% | 1 | 1 | 0% | 1,016 | 2,608 | +157% | 0 | 0 | — |
case-22 | fail→pass | 12,048 | 2,020 | -83% | 1 | 1 | 0% | 1,839 | 2,463 | +34% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 16 counted toward the lift figure. The other 6 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +59 percentage points is the difference between those two pass rates over the 16 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.