@@ -18,13 +18,13 @@ naming is the source of truth for ordering.
1818
1919## Stage & Gate index
2020
21- | Phase | Stages | Gates |
22- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
23- | Entry — Readiness | — | [ G1] ( #gate-g1 ) |
24- | A — Contract deployment | [ S1] ( #stage-s1 ) [ S2] ( #stage-s2 ) [ S3] ( #stage-s3 ) | [ G2] ( #gate-g2 ) [ G3] ( #gate-g3 ) [ G4] ( #gate-g4 ) |
25- | B — Proxy upgrade | [ S4] ( #stage-s4 ) [ S5] ( #stage-s5 ) | [ G5] ( #gate-g5 ) [ G6] ( #gate-g6 ) |
26- | C — Activation | [ S6] ( #stage-s6 ) [ S7] ( #stage-s7 ) [ S8] ( #stage-s8 ) [ S9] ( #stage-s9 ) [ S10] ( #stage-s10 ) [ S11] ( #stage-s11 ) | [ G7] ( #gate-g7 ) [ G8] ( #gate-g8 ) [ G9] ( #gate-g9 ) [ G10] ( #gate-g10 ) [ G11] ( #gate-g11 ) [ G12] ( #gate-g12 ) |
27- | D — Off-chain & close-out (testnet / mainnet only) | [ S12] ( #stage-s12 ) [ S13] ( #stage-s13 ) [ S14] ( #stage-s14 ) [ S15] ( #stage-s15 ) | [ G13] ( #gate-g13 ) [ G14] ( #gate-g14 ) [ G15] ( #gate-g15 ) [ G16] ( #gate-g16 ) |
21+ | Phase | Stages | Gates |
22+ | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------- ----------------------------------------------------------------------------------------------- |
23+ | Entry — Readiness | — | [ G1] ( #gate-g1 ) |
24+ | A — Contract deployment | [ S1] ( #stage-s1 ) [ S2] ( #stage-s2 ) [ S3] ( #stage-s3 ) | [ G2] ( #gate-g2 ) [ G3] ( #gate-g3 ) [ G4] ( #gate-g4 ) |
25+ | B — Proxy upgrade | [ S4] ( #stage-s4 ) [ S5] ( #stage-s5 ) | [ G5] ( #gate-g5 ) [ G6] ( #gate-g6 ) |
26+ | C — Activation | [ S5a ] ( #stage-s5a ) [ S6] ( #stage-s6 ) [ S7] ( #stage-s7 ) [ S8] ( #stage-s8 ) [ S9] ( #stage-s9 ) [ S10] ( #stage-s10 ) [ S11] ( #stage-s11 ) | [ G6a ] ( #gate-g6a ) [ G7] ( #gate-g7 ) [ G8] ( #gate-g8 ) [ G9] ( #gate-g9 ) [ G10] ( #gate-g10 ) [ G11] ( #gate-g11 ) [ G12] ( #gate-g12 ) |
27+ | D — Off-chain & close-out (testnet / mainnet only) | [ S12] ( #stage-s12 ) [ S13] ( #stage-s13 ) [ S14] ( #stage-s14 ) [ S15] ( #stage-s15 ) | [ G13] ( #gate-g13 ) [ G14] ( #gate-g14 ) [ G15] ( #gate-g15 ) [ G16] ( #gate-g16 ) |
2828
2929## Environments
3030
@@ -283,10 +283,10 @@ run record.
283283
284284### Gate G6 — upgrade-complete
285285
286- | Field | Value |
287- | ---------------- | --------------------- |
288- | Postcondition of | [ Stage S5] ( #stage-s5 ) |
289- | Precondition of | [ Stage S6 ] ( #stage-s6 ) |
286+ | Field | Value |
287+ | ---------------- | ----------------------- |
288+ | Postcondition of | [ Stage S5] ( #stage-s5 ) |
289+ | Precondition of | [ Stage S5a ] ( #stage-s5a ) |
290290
291291** Check.**
292292
@@ -316,6 +316,58 @@ Eligibility-integrate ([S6](#stage-s6)/[S7](#stage-s7)) is a no-op only when
316316` RM.providerEligibilityOracle ` already matches the configured oracle; if it
317317differs, the stage re-points it (config is the source of truth).
318318
319+ ** DIPs-dormant rollout.** This environment ships with on-chain indexing
320+ agreements (DIPs) ** off** , via two independent levers — neither turned on by the
321+ activation goals:
322+
323+ - ** Protocol-funded path** — ` IssuanceAllocator.allocations ` in
324+ ` config/<network>.json5 ` omits ` RecurringAgreementManager ` , so RAM receives 0
325+ issuance. ` issuance-connect ` puts RM at 100%, so ` issuance-allocate `
326+ ([ S10] ( #stage-s10 ) /[ S11] ( #stage-s11 ) ) is a no-op — run it only to confirm.
327+ - ** Payer-funded path** — ` RecurringCollector ` is paused ([ S5a] ( #stage-s5a ) ).
328+ This is a ** pause-guardian** action managed out-of-band, not by the deploy
329+ package; ` 09_end ` does ** not** verify it, so [ G6a] ( #gate-g6a ) is the gate that
330+ does.
331+
332+ Turning DIPs on later is the inverse of both levers — see
333+ [ Activating DIPs later] ( #activating-dips-later ) .
334+
335+ <a id =" stage-s5a " ></a >
336+
337+ ### Stage S5a — Pause RecurringCollector (DIPs dormant)
338+
339+ | Field | Value |
340+ | -------------- | ------------------------------------------------ |
341+ | Phase | C — Activation |
342+ | Actor | Pause guardian (out-of-band; see below) |
343+ | Entry gate | [ G6 upgrade-complete] ( #gate-g6 ) |
344+ | Exit gate | [ G6a dips-dormant] ( #gate-g6a ) |
345+ | Parallelizable | No |
346+ | Reference | ` RecurringCollector.pause() ` — onlyPauseGuardian |
347+
348+ ** What this does.** Pauses ` RecurringCollector ` so no indexing agreement can be
349+ accepted, collected, updated, or cancelled (` accept ` /` collect ` /` update ` /` cancel `
350+ are all ` whenNotPaused ` ). This closes the payer-funded DIP path; the
351+ protocol-funded path is already off via config (RAM unallocated).
352+
353+ ** Why out-of-band.** ` RC.pause() ` is ` onlyPauseGuardian ` , and the pause guardian
354+ (` Controller.pauseGuardian() ` ) is a distinct actor from the protocol governor by
355+ design — a separate Safe on mainnet (` 0xB0aD…3aAE ` ), a separate EOA on testnet
356+ (` 0xa044…20D7 ` ). The deploy package only emits governor batches, so it neither
357+ sets nor clears pause state; the guardian performs this directly.
358+
359+ ** When.** As soon as [ G6] ( #gate-g6 ) lands — the guardian role is granted in the
360+ [ S4] ( #stage-s4 ) upgrade batch, so the guardian can act the moment the upgrade
361+ executes. RC is unpaused by default (its initializer leaves it live), so pause
362+ promptly to minimise the window.
363+
364+ ** Steps.**
365+
366+ 1 . Guardian executes ` RecurringCollector.pause() ` :
367+ - Mainnet: propose & execute on the pause-guardian Safe (` 0xB0aD…3aAE ` ).
368+ - Testnet: ` cast send <RC> "pause()" --from <guardian> ` with the guardian EOA
369+ key (` 0xa044…20D7 ` ); the governor key cannot do this.
370+
319371<a id =" stage-s6 " ></a >
320372
321373### Stage S6 — Generate the eligibility-integrate batch
@@ -324,7 +376,7 @@ differs, the stage re-points it (config is the source of truth).
324376| -------------- | ------------------------------------------------------------ |
325377| Phase | C — Activation |
326378| Actor | Deployer (EOA) |
327- | Entry gate | [ G6 upgrade-complete ] ( #gate-g6 ) |
379+ | Entry gate | [ G6a dips-dormant ] ( #gate-g6a ) |
328380| Exit gate | [ G7 eligibility-batch-reviewed] ( #gate-g7 ) |
329381| Parallelizable | No |
330382| Reference | [ Gip0088.md — Activation goals] ( Gip0088.md#activation-goals ) |
@@ -418,6 +470,11 @@ rate (no rebalancing). **Exits** unless the config `issuancePerBlock` equals RM'
418470on-chain rate and the per-target rates sum to it. Skips when no allocations are
419471configured.
420472
473+ In the ** DIPs-dormant** config the only target is RM, already at 100% from
474+ [ S8] ( #stage-s8 ) ` issuance-connect ` , so this stage emits ** no transactions** —
475+ run it to confirm the table matches on-chain. (When DIPs are later activated, the
476+ RAM allocation is added back to config and this stage does the real work.)
477+
421478** Steps.**
422479
4234801 . ` pnpm hardhat deploy --tags GIP-0088:issuance-allocate --network <network> `
@@ -438,7 +495,29 @@ configured.
438495
4394961 . ` pnpm hardhat deploy:execute-governance --network <network> ` (fork/testnet) or
440497 council Safe execution (mainnet).
441- <a id =" gate-g7 " ></a >
498+ <a id =" gate-g6a " ></a >
499+
500+ ### Gate G6a — dips-dormant
501+
502+ | Field | Value |
503+ | ---------------- | ----------------------- |
504+ | Postcondition of | [ Stage S5a] ( #stage-s5a ) |
505+ | Precondition of | [ Stage S6] ( #stage-s6 ) |
506+
507+ ** Check.** ` cast call <RecurringCollector> "paused()(bool)" --rpc-url <rpc> ` (or
508+ the equivalent read). Confirm ` true ` .
509+
510+ ** Pass criterion.** ` RC.paused() == true ` . With RAM unallocated (config) and RC
511+ paused, neither DIP funding path can create or collect an agreement.
512+
513+ ** Note.** ` 09_end ` (the [ G12] ( #gate-g12 ) assertion) does ** not** check pause
514+ state — it would report GIP-0088 "complete" with RC still live. This gate is the
515+ only check that the payer-funded path is closed; do not skip it.
516+
517+ ** If it fails.** RC is still live — re-run [ S5a] ( #stage-s5a ) (have the guardian
518+ execute ` pause() ` ). Until this gate passes the rollout is not dormant.
519+
520+ <a id =" gate-g7 " ></a >
442521
443522### Gate G7 — eligibility-batch-reviewed
444523
@@ -545,7 +624,10 @@ when RM self-minting covers the slack).
545624
546625** Pass criterion.** Exit 0 — upgrade, issuance-connect and eligibility-integrate
547626all verified; the configured REO is the active oracle; and both
548- ` revertOnIneligible ` and the RAM allocation rates match config.
627+ ` revertOnIneligible ` and the allocation rates match config (RAM unallocated in
628+ the dormant config). Note: ` 09_end ` does ** not** check ` RC.paused() ` — dormancy
629+ of the payer-funded path is attested by [ G6a] ( #gate-g6a ) , not here, so both gates
630+ must pass for the rollout to be dormant.
549631
550632** If it fails.** Re-run the stage that owns the unmet goal as named in the
551633output.
@@ -734,6 +816,25 @@ prior stage. Abort is clean before [G4](#gate-g4); after, recovery needs a
734816follow-up governance batch — see
735817[ GovernanceWorkflow.md] ( GovernanceWorkflow.md ) .
736818
819+ ## Activating DIPs later
820+
821+ DIPs ship dormant (see [ Phase C] ( #phase-c--activation ) ). Turning them on is the
822+ inverse of the two dormancy levers, and is a ** separate, later** change — not
823+ part of this rollout:
824+
825+ 1 . ** Restore the issuance split** — in ` config/<network>.json5 ` , add the
826+ ` RecurringAgreementManager ` allocation back to ` IssuanceAllocator.allocations `
827+ (e.g. mainnet ` RewardsManager: 114.73 ` + ` RecurringAgreementManager: 6 ` ), then
828+ run ` GIP-0088:issuance-allocate ` and execute the governor batch. ` ia:status `
829+ should then show RAM funded. The decrease-first ordering means RM drops and RAM
830+ rises within one batch.
831+ 2 . ** Unpause the collector** — the pause guardian executes
832+ ` RecurringCollector.unpause() ` (mainnet: guardian Safe ` 0xB0aD…3aAE ` ; testnet:
833+ guardian EOA ` 0xa044…20D7 ` ). The governor cannot do this.
834+
835+ Each lever is independently reversible: re-apply the RM-only config + re-run
836+ ` issuance-allocate ` to de-fund RAM, and have the guardian ` RC.pause() ` again.
837+
737838## See also
738839
739840- [ Gip0088.md] ( Gip0088.md ) — reference guide: scripts, tags, preconditions, model
0 commit comments