feat(lib): chain-aware token-owner Safe assertion - #267
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Add `LibSafeInvariants.assertActiveChainTokenOwnerSafe(chainId)` — the single entry point that resolves the active chain's token-owner Safe and asserts it chain-appropriately: Base (the reference chain) order-sensitively via `assertAll` against the canonical pinned roster; every other chain order- insensitively via `assertPolicyMatchesBase` (a per-chain Safe shares the owner SET + threshold + v1.4.1 identity, but its getOwners() order is an incidental deploy artifact). Fork-tested against the LIVE Base and Ethereum Safes, so any consumer (e.g. a broadcast script's pre-flight) is proven against every pinned chain's Safe on every CI run — a dispatch can never revert on a Safe check CI hasn't already exercised on that chain. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VPs1hCTxusmaSeFKvoc4Kr
Rename `assertPolicyMatchesBase` -> `assertTokenOwnerSafePolicy` and reframe: the pinned owner SET + threshold + v1.4.1 identity are properties of the ORGANISATION, not of Base — every chain's token-owner Safe (Base included) is asserted against the same pins. `assertActiveChainTokenOwnerSafe` drops its Base special-case: resolve the chain's Safe address (the only per-chain artifact), assert the shared policy, identically everywhere. `LibInvariants.assertProductionState` now composes the resolve+assert entry point instead of hand-pairing `safeForChainId` with the policy check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VPs1hCTxusmaSeFKvoc4Kr
18acfcf to
4d875cc
Compare
|
Reviewed 4d875cc: approved Human approval given interactively. Merging over two reds — both inherited
Caveat recorded: the CI is staleThose results are from 2026-07-21T22:5x — before #268 merged (07-22) and before I retargeted this PR from Why the change is soundAdds I probed the obvious fail-open in that weakening — can an unordered set check miss an extra owner? It cannot. An unpinned chain reverts This is also the prerequisite for #266, which fixes Landing with |

Add
LibSafeInvariants.assertActiveChainTokenOwnerSafe(chainId)— the singleentry point that resolves the active chain's token-owner Safe and asserts it
chain-appropriately: Base (the reference chain) order-sensitively via
assertAllagainst the canonical pinned roster; every other chain order-insensitively via
assertPolicyMatchesBase(a per-chain Safe shares the ownerSET + threshold + v1.4.1 identity, but its getOwners() order is an incidental
deploy artifact).
Fork-tested against the LIVE Base and Ethereum Safes, so any consumer (e.g. a
broadcast script's pre-flight) is proven against every pinned chain's Safe on
every CI run — a dispatch can never revert on a Safe check CI hasn't already
exercised on that chain.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01VPs1hCTxusmaSeFKvoc4Kr