Orchestrator instance deploy script + pinned invariants - #316
Merged
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 Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
Contributor
Author
This was referenced Aug 18, 2026
hardyjosh
force-pushed
the
2026-08-17-orchestrator-manual-sol-artifacts
branch
from
August 18, 2026 11:07
76e72a1 to
1c7e986
Compare
hardyjosh
force-pushed
the
2026-08-18-deploy-orchestrator-instance
branch
from
August 18, 2026 11:07
d9c6bea to
4271d04
Compare
hardyjosh
force-pushed
the
2026-08-17-orchestrator-manual-sol-artifacts
branch
from
August 25, 2026 08:09
1c7e986 to
511811c
Compare
hardyjosh
force-pushed
the
2026-08-18-deploy-orchestrator-instance
branch
from
August 25, 2026 08:09
4271d04 to
e7eb280
Compare
hardyjosh
added a commit
that referenced
this pull request
Aug 25, 2026
## Why Main's test CI (and cron) has been red since **2026-08-22**, and #314's inherits it: the `20260810-revoke-fireblocks-service-signer` Safe bundles **executed on all three chains** (verified live — the retired signer `0x1C66…D1A9` holds no `DEPOSIT`/`WITHDRAW`/`CERTIFY` on Base, Ethereum, or HyperEVM), which flipped its forcing-function tests red by design: they demand this pin PR. ## What (per the script's own retire instructions) - **Canonical grant map**: the retired signer's three rows leave `expectedGrants` (16 → 13 entries). The `GRANTEE_SERVICE_1C66` constant stays as the audit-trail record. - **The revocation is pinned as an absence**: `assertExpectedGrants` gains `assertRetiredSignerAbsent` — any action role landing back on the retired signer red-lines cron with the new `UnexpectedRetiredSignerGrant`. Strictly stronger than the old presence rows. - **Spent fixtures retire**: the script, its `run-script.yaml` registry entry, the `.prod.t.sol` forcing tests, the unit tests, and both harnesses are deleted — the standing absence assertion supersedes their pre-flight per the registry's deletion rule. ## Consumers of the retired rows (second round — surfaced by CI, masked locally by RPC rate limits) - `20260619-deploy-v4-authoriser-clone`: `MIRROR_COUNT` 9 → 6 (the operational slice is now Safe + service signer) plus its replica test. - `20260729-migrate-governance-to-timelock`: the governance-loop proof's sample no-op op re-granted `DEPOSIT` to the retired signer — post-revocation that's a real grant and trips the absence check. Now re-grants to the live signer (`GRANTEE_SERVICE_3D0C`, a genuine no-op again). - `20260723-provision-additional-service-signer` drift test: drift is now created by revoking the Safe's `DEPOSIT` row instead of the departed retired-signer row. ## Verification Against live forks on all three chains: the full previously-red set passes — provisioning prod tests (`AlreadyProvisioned` refusals restored), timelock-migration surface, cross-chain parity, Base prod-state, Ethereum clone pin. `slither .` 0, fmt/reuse clean. ## Merge order This merges **first**; the orchestrator stack (#314 → #316 → #317) restacks on it and its inherited test failures disappear. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01KbsbYN4C4YDa8pu9DdudoX <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Updates** * Retired service signer access has been removed from the expected authorization configuration. * Authorization grants now reflect six operational grants, with Safe grants listed before service grants. * Governance validation now uses the active service signer for `DEPOSIT`. * Added checks to prevent accidental regranting of roles to the retired signer. * **Maintenance** * Removed the retired signer revocation workflow and its associated validation tests. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
20260818-deploy-orchestrator (manual-broadcast, per network): one deploy-key broadcast that calls the 0.1.8 beacon-set deployer's deploy(owner) with the chain's token-owner Safe, so the Safe holds DEFAULT_ADMIN_ROLE from initialisation and the deploy key never holds anything (asserted). Unlike the token deploys there is no owner-gated wiring step, so no transient deploy-key ownership window exists. The whole surface is deterministic and pinned UP FRONT in the new LibOrchestratorInvariants: the beacon is the set deployer's CREATE at nonce 1 (0xbA0d89f6, matches live Base) and the first deploy()'s BeaconProxy is its CREATE at nonce 2 (0x21372a9D), identical on every chain. Pre-flight enforces the audited 0.1.8 closure by codehash, refuses a live pinned instance, and refuses a set-deployer nonce that shows an unpinned earlier deploy(). Prod fork test walks the rollout's three states per chain with a 2026-10-01 deadline: closure pending (Ethereum/HyperEVM — pins the ClosureNotDeployed refusal), instance pending (Base — drives run() end to end on the fork and asserts the pinned end state incl. the ERC-1967 beacon slot), executed (steady-state instance asserts, the orchestrator analogue of the token-instance prod asserts, plus the re-dispatch refusal). Guard coverage without a fork in the unit test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KbsbYN4C4YDa8pu9DdudoX
hardyjosh
force-pushed
the
2026-08-17-orchestrator-manual-sol-artifacts
branch
from
August 25, 2026 11:13
511811c to
985cfa0
Compare
hardyjosh
force-pushed
the
2026-08-18-deploy-orchestrator-instance
branch
from
August 25, 2026 11:13
e7eb280 to
76a8311
Compare
This was referenced Aug 25, 2026
This was referenced Aug 27, 2026
thedavidmeister
changed the base branch from
2026-08-17-orchestrator-manual-sol-artifacts
to
main
August 27, 2026 17:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #314 (the audited 0.1.30 orchestrator-set workflow) — merge that first.
Why
#314 makes the orchestrator singletons deployable, but creating the production orchestrator instance (
ST0xOrchestratorBeaconSetDeployer.deploy(owner)) had no sanctioned path. This adds it in the token-deploy pattern: a datedmanual-broadcastscript that broadcasts as the CI deploy key and landsDEFAULT_ADMIN_ROLEon the chain's token-owner Safe, with the result pinned and asserted the way the token beacons and token instances are.What
script/20260818-deploy-orchestrator.s.sol(PENDING, registered inmanual-broadcast.yaml, one dispatch per network): pre-flights the audited 0.1.30 closure by codehash, validates the chain's token-owner Safe policy, then callsdeploy(safe)and asserts the end state. One divergence from20260807-deploy-missing-tokens, documented in the NatSpec: there is no owner-gated wiring step (nosetAuthorizeranalogue), so the Safe is passed straight todeploy(owner)and the deploy key never holdsDEFAULT_ADMIN_ROLEat all (asserted). OperationalMINT_ROLE/BURN_ROLEgrants for the issuance bot's signer stay Safe transactions per the issuance-side onboarding runbook.LibProdDeployV4(emitted byBuildPointersbeside the authoriser-clone pin) and are aliased by the newLibOrchestratorInvariants;testOrchestratorBeaconPin/testOrchestratorInstancePinre-derive both from the beacon-set deployer pin via the CREATE/RLP derivation, so a drifted literal fails a test. The whole surface is deterministic, so it is pinned up front rather than hydrated from the broadcast:0xb9DCd744…4613= the set deployer'sCREATEat nonce 1 (CREATE nonce-1 of the 0.1.30 set-deployer);0x3A7387a4…03E2= the firstdeploy()'sBeaconProxy, the set deployer'sCREATEat nonce 2 — identical on every chain.Asserts: beacon reported by the set deployer, beacon impl = the audited 0.1.30 orchestrator, beacon owner =
BEACON_INITIAL_OWNER, instance admin = chain Safe,vaultLogicIsExpected()true.OrchestratorAlreadyDeployed(re-dispatch refusal, likeNoMissingTokens); set-deployer nonce ≠ 2 without code at the pin ⇒UnexpectedSetDeployerNonce(an unpinned earlierdeploy()— resolve manually, never deploy a second instance). The pin, notDeployment-event discovery, is the source of truth —deployis permissionless and the event is front-runnable (see the interface NatSpec).test/script/20260818-deploy-orchestrator.prod.t.sol— live-fork rollout walk per chain (no mocks), with a 2026-10-01 deadline after which a still-pending chain red-lines cron:ClosureNotDeployedrefusal + logs the outstanding dispatch;run()end to end on the fork: instance lands at the pin, Safe0xe70d…d611holds admin, deploy key holds nothing, vault-logic lock passes, ERC-1967 beacon slot = pinned beacon;test/script/20260818-deploy-orchestrator.t.sol— every guard andassertDeployLandedfailure mode shown to fire without a fork (11 tests).Verification
slither .0 results;forge fmt --check,reuse lintclean.Rollout order per chain
manual-sol-artifacts-0-1-8suites in listed order (no-ops on Base) — Deploy workflow for the audited 0.1.30 orchestrator set #314manual-broadcast→20260818-deploy-orchestrator(this PR)MINT_ROLE/BURN_ROLEto the issuance bot's signer; then the issuance-side preflight/cutover runbookFlag (not in scope)
The orchestrator beacon's owner is still
BEACON_INITIAL_OWNER(0x8E4b…f5b) on Base — it never joined the beacon-owner migration that moved the token beacons to the per-chain Safes. The invariant pins that as current truth; if the beacon should follow the token beacons (or the timelock), that's a separate Safe op + pin flip.🤖 Generated with Claude Code
https://claude.ai/code/session_01KbsbYN4C4YDa8pu9DdudoX