Goal (explicit, ruled 2026-08-04)
We hate the placeholder→backfill dance. Killing it is an explicit goal: every authoriser clone is deployed deterministically (cloneDeterministic + salt, rain-factory 0.1.5), at the same chain-invariant address on every chain, pinned up-front in generated pointers — no address(0) placeholders, no post-deploy hydration PRs.
Why the address is chain-invariant
clone = f(impl, keccak(deployer, salt), factory) — verified from 0.1.5 source: init data is NOT in the derivation (atomic initialize after CREATE2), and the salt is deployer-namespaced (unsquattable). Factory and impl are Zoltu-deployed (same address everywhere), so same deployer key + same salt ⇒ same clone address on every chain, even though per-chain init config (paymentToken, owner Safe) differs.
Two steps (the user's shape — artifacts map 1:1)
Step 1 — deploy deterministic authorisers: PR #250, complete in one PR. rain-factory 0.1.5 (+ forced rain-vats 0.1.7) bump, clone()→cloneDeterministic fixture migration, nonce-factory pin (bytecode-complete per #293), AND the dated cloneDeterministic deploy script for every chain with prod config (Base + Ethereum; the HyperEVM wave — #274/#276/#278 — rescopes to deploy deterministically from the start and never needs migration), with the predicted address pinned as a migration-target constant per the #293 shape (address + EIP-1167 runtime bytecode + codehash + offline predicted==pinned and keccak asserts). Live pins (STOX_PROD_AUTHORISER_V4_CLONE, the Ethereum clone pin) stay untouched. Post-merge: broadcast via the manual dispatch with the deployer key; the deployed clones are inert (initialized, grantless, unreferenced) until step 2.
Step 2 — upgrade to them (the only follow-up):
History
Goal (explicit, ruled 2026-08-04)
We hate the placeholder→backfill dance. Killing it is an explicit goal: every authoriser clone is deployed deterministically (
cloneDeterministic+ salt, rain-factory 0.1.5), at the same chain-invariant address on every chain, pinned up-front in generated pointers — noaddress(0)placeholders, no post-deploy hydration PRs.Why the address is chain-invariant
clone = f(impl, keccak(deployer, salt), factory)— verified from 0.1.5 source: init data is NOT in the derivation (atomic initialize after CREATE2), and the salt is deployer-namespaced (unsquattable). Factory and impl are Zoltu-deployed (same address everywhere), so same deployer key + same salt ⇒ same clone address on every chain, even though per-chain init config (paymentToken, owner Safe) differs.Two steps (the user's shape — artifacts map 1:1)
Step 1 — deploy deterministic authorisers: PR #250, complete in one PR. rain-factory 0.1.5 (+ forced rain-vats 0.1.7) bump,
clone()→cloneDeterministicfixture migration, nonce-factory pin (bytecode-complete per #293), AND the datedcloneDeterministicdeploy script for every chain with prod config (Base + Ethereum; the HyperEVM wave — #274/#276/#278 — rescopes to deploy deterministically from the start and never needs migration), with the predicted address pinned as a migration-target constant per the #293 shape (address + EIP-1167 runtime bytecode + codehash + offline predicted==pinned and keccak asserts). Live pins (STOX_PROD_AUTHORISER_V4_CLONE, the Ethereum clone pin) stay untouched. Post-merge: broadcast via the manual dispatch with the deployer key; the deployed clones are inert (initialized, grantless, unreferenced) until step 2.Step 2 — upgrade to them (the only follow-up):
RoleGranted/RoleRevokedlogs on the nonce clones — never repo greps (issuer DEPOSIT+WITHDRAW per feat(script): grant new issuer DEPOSIT+WITHDRAW on shared authoriser #221, service signer per feat(authoriser): additional service signer — canonical pin + provisioning #280, admin-holders per feat(lib): LibTimelockInvariants + authoriser grant-map admin-holder parameterisation #284).setAuthorizerSafe bundles (owner-gated, pairing guard) — timelocked choreography after feat(script): 20260729-migrate-governance-to-timelock Safe bundle #286–feat(timelock): migrate the upgrade beacons under the timelock too #290 settles.History