Pause blocks roll, claim, and topUp — contract guards, tests, ops doc #349

Closed
opened 2026-06-25 20:07:23 +00:00 by PlasticDigits · 5 comments
PlasticDigits commented 2026-06-25 20:07:23 +00:00 (Migrated from gitlab.com)

Parent

Transition Gap Analysis (#342) — P1 #9, P3 #17. Bundles M-C1.

Product decision (approved on #342): Pause should block roll (and claim / top-up).

Current codebase

  • rollPodiumEpoch is external with no _requireLive() — only checks category, armed, deadline (#312 autoroll on buy uses _requireLiveAndAutoroll internally).
  • claimCred and topUpPodiumPools check arenaStart but not paused.
  • Pause matrix tests (INV-TIME-ARENA-PAUSE-MUTATING) cover buy/WarBow/flag only (TimeArena.t.sol ~L2100).
  • docs/operations/pause-and-final-signoff.md lists podium roll as “permissionless liveness” — contradicts approved direction.

Why needed

During incident pause, settlement and claims should not move value or advance epochs. Ops runbook and tests must match contract behavior.

Constraints / guardrails

  • Add _requireLive() (or require(!paused)) to rollPodiumEpoch, claimCred, topUpPodiumPools.
  • Autoroll inside _requireLiveAndAutoroll on buy/WarBow: decide whether autoroll runs while paused — likely blocked because _requireLive() fails first on buy; document explicitly.
  • Update pause-and-final-signoff.md gated surfaces table.
  • Add invariant row in invariants-and-business-logic.md.

Relevant files

  • contracts/src/arena/TimeArena.sol
  • contracts/test/TimeArena.t.sol
  • docs/operations/pause-and-final-signoff.md
  • docs/testing/invariants-and-business-logic.md
  1. Gate rollPodiumEpoch, claimCred, topUpPodiumPools with _requireLive().
  2. Add test_pause_blocks_rollPodiumEpoch, test_pause_blocks_claimCred, test_pause_blocks_topUpPodiumPools.
  3. Update ops doc: roll/claim/top-up blocked when paused.
  4. Frontend: existing write gates should surface pause reverts (no new RPC reads).

Acceptance criteria

  • All three functions revert when paused == true.
  • Forge pause matrix extended; forge test PASS.
  • Ops doc and invariants updated.
  • No change to ReferralRegistry.registerCode (always live per doc).

Test plan

Path Command
Contracts cd contracts && forge test --match-test pause
Full cd contracts && forge test

Attack / abuse test plan

  • Permissionless roll cannot be used to bypass pause.
  • Owner setPaused(true) immediately blocks new rolls without upgrade.

Verification criteria

  • test_pause_blocks_rollPodiumEpoch PASS.
  • pause-and-final-signoff.md table matches on-chain gates.
## Parent [Transition Gap Analysis (#342)](https://gitlab.com/PlasticDigits/yieldomega/-/issues/342) — P1 #9, P3 #17. Bundles **M-C1**. **Product decision (approved on #342):** **Pause should block roll** (and claim / top-up). ## Current codebase - `rollPodiumEpoch` is `external` with no `_requireLive()` — only checks category, armed, deadline ([#312](https://gitlab.com/PlasticDigits/yieldomega/-/issues/312) autoroll on buy uses `_requireLiveAndAutoroll` internally). - `claimCred` and `topUpPodiumPools` check `arenaStart` but not `paused`. - Pause matrix tests (`INV-TIME-ARENA-PAUSE-MUTATING`) cover buy/WarBow/flag only (`TimeArena.t.sol` ~L2100). - `docs/operations/pause-and-final-signoff.md` lists podium roll as “permissionless liveness” — **contradicts approved direction**. ## Why needed During incident pause, settlement and claims should not move value or advance epochs. Ops runbook and tests must match contract behavior. ## Constraints / guardrails - Add `_requireLive()` (or `require(!paused)`) to `rollPodiumEpoch`, `claimCred`, `topUpPodiumPools`. - **Autoroll inside `_requireLiveAndAutoroll`** on buy/WarBow: decide whether autoroll runs while paused — likely blocked because `_requireLive()` fails first on buy; document explicitly. - Update `pause-and-final-signoff.md` gated surfaces table. - Add invariant row in `invariants-and-business-logic.md`. ## Relevant files - `contracts/src/arena/TimeArena.sol` - `contracts/test/TimeArena.t.sol` - `docs/operations/pause-and-final-signoff.md` - `docs/testing/invariants-and-business-logic.md` ## Recommended direction 1. Gate `rollPodiumEpoch`, `claimCred`, `topUpPodiumPools` with `_requireLive()`. 2. Add `test_pause_blocks_rollPodiumEpoch`, `test_pause_blocks_claimCred`, `test_pause_blocks_topUpPodiumPools`. 3. Update ops doc: roll/claim/top-up blocked when `paused`. 4. Frontend: existing write gates should surface pause reverts (no new RPC reads). ## Acceptance criteria - [ ] All three functions revert when `paused == true`. - [ ] Forge pause matrix extended; `forge test` PASS. - [ ] Ops doc and invariants updated. - [ ] No change to `ReferralRegistry.registerCode` (always live per doc). ## Test plan | Path | Command | |------|---------| | Contracts | `cd contracts && forge test --match-test pause` | | Full | `cd contracts && forge test` | ## Attack / abuse test plan - Permissionless roll cannot be used to bypass pause. - Owner `setPaused(true)` immediately blocks new rolls without upgrade. ## Verification criteria - `test_pause_blocks_rollPodiumEpoch` PASS. - `pause-and-final-signoff.md` table matches on-chain gates.
PlasticDigits commented 2026-06-25 20:07:50 +00:00 (Migrated from gitlab.com)

mentioned in issue #342

mentioned in issue #342
PlasticDigits commented 2026-06-25 22:05:36 +00:00 (Migrated from gitlab.com)

mentioned in commit 81fdb595c8

mentioned in commit 81fdb595c8dac9a76e620343064d2252a06f05db
PlasticDigits commented 2026-06-25 22:05:46 +00:00 (Migrated from gitlab.com)

mentioned in merge request !520

mentioned in merge request !520
PlasticDigits commented 2026-06-25 22:23:32 +00:00 (Migrated from gitlab.com)

mentioned in commit df186aa483

mentioned in commit df186aa483bddb7944e32c150a2d586d07e1696a
PlasticDigits commented 2026-06-26 06:57:36 +00:00 (Migrated from gitlab.com)

Verification complete — PASS

Verified Pause blocks roll, claim, and topUp on main (no repo changes; no MR).

Acceptance criteria

Criterion Result How verified
rollPodiumEpoch, claimCred, topUpPodiumPools revert when paused == true PASS TimeArena.sol gates all three with _requireLive(); tests expect "TimeArena: paused"
Forge pause matrix extended; forge test PASS PASS cd contracts && forge test --match-test pause → 9/9 PASS (includes test_pause_blocks_rollPodiumEpoch, test_pause_blocks_claimCred, test_pause_blocks_topUpPodiumPools)
Ops doc and invariants updated PASS docs/operations/pause-and-final-signoff.md gated-surfaces table lists roll/claim/top-up as paused via _requireLive() ([#349]); docs/operations/final-signoff-and-value-movement.md aligned; INV-TIME-ARENA-PAUSE-MUTATING and INV-DOCS-320-PAUSE-OPS in invariants-and-business-logic.md
No change to ReferralRegistry.registerCode (always live) PASS registerCode has no pause gate; ops doc row "Referral registration … Always live"

Verification criteria (issue body)

Item Result Command / evidence
test_pause_blocks_rollPodiumEpoch PASS forge test --match-test test_pause_blocks_rollPodiumEpoch
pause-and-final-signoff.md table matches on-chain gates PASS Manual cross-check vs TimeArena.sol _requireLive() on roll/claim/top-up/WarBow/buy paths

Attack / abuse plan

Scenario Result Evidence
Permissionless roll cannot bypass pause PASS test_pause_blocks_rollPodiumEpoch arms timer, warps past deadline, sets paused, expects revert
setPaused(true) immediately blocks rolls PASS Same test; no upgrade required

Additional checks

Path Result Notes
Full contract suite PASS (issue scope) cd contracts && forge test → 227 passed; 4 SKIP — DoubAirdropMegaethFork requires gitignored airdrop/doub.csv (documented AGENTS.md exception; unrelated to #349)
Autoroll while paused PASS (documented) _requireLiveAndAutoroll calls _requireLive() first; ops doc §2 step 5 documents blocked autoroll
Play skills cross-link PASS skills/play-active-time-arena/SKILL.md blocks roll/claim/top-up when paused ([#349])

Summary

Implementation, tests, ops runbook, and invariants for #349 are complete on main. Closing as verified.

## Verification complete — PASS Verified **Pause blocks roll, claim, and topUp** on `main` (no repo changes; no MR). ### Acceptance criteria | Criterion | Result | How verified | |-----------|--------|--------------| | `rollPodiumEpoch`, `claimCred`, `topUpPodiumPools` revert when `paused == true` | **PASS** | `TimeArena.sol` gates all three with `_requireLive()`; tests expect `"TimeArena: paused"` | | Forge pause matrix extended; `forge test` PASS | **PASS** | `cd contracts && forge test --match-test pause` → **9/9 PASS** (includes `test_pause_blocks_rollPodiumEpoch`, `test_pause_blocks_claimCred`, `test_pause_blocks_topUpPodiumPools`) | | Ops doc and invariants updated | **PASS** | `docs/operations/pause-and-final-signoff.md` gated-surfaces table lists roll/claim/top-up as **`paused`** via `_requireLive()` ([#349]); `docs/operations/final-signoff-and-value-movement.md` aligned; **`INV-TIME-ARENA-PAUSE-MUTATING`** and **`INV-DOCS-320-PAUSE-OPS`** in `invariants-and-business-logic.md` | | No change to `ReferralRegistry.registerCode` (always live) | **PASS** | `registerCode` has no pause gate; ops doc row "Referral registration … Always live" | ### Verification criteria (issue body) | Item | Result | Command / evidence | |------|--------|-------------------| | `test_pause_blocks_rollPodiumEpoch` | **PASS** | `forge test --match-test test_pause_blocks_rollPodiumEpoch` | | `pause-and-final-signoff.md` table matches on-chain gates | **PASS** | Manual cross-check vs `TimeArena.sol` `_requireLive()` on roll/claim/top-up/WarBow/buy paths | ### Attack / abuse plan | Scenario | Result | Evidence | |----------|--------|----------| | Permissionless roll cannot bypass pause | **PASS** | `test_pause_blocks_rollPodiumEpoch` arms timer, warps past deadline, sets `paused`, expects revert | | `setPaused(true)` immediately blocks rolls | **PASS** | Same test; no upgrade required | ### Additional checks | Path | Result | Notes | |------|--------|-------| | Full contract suite | **PASS** (issue scope) | `cd contracts && forge test` → **227 passed**; **4 SKIP** — `DoubAirdropMegaethFork` requires gitignored `airdrop/doub.csv` (documented AGENTS.md exception; unrelated to #349) | | Autoroll while paused | **PASS** (documented) | `_requireLiveAndAutoroll` calls `_requireLive()` first; ops doc §2 step 5 documents blocked autoroll | | Play skills cross-link | **PASS** | `skills/play-active-time-arena/SKILL.md` blocks roll/claim/top-up when paused ([#349]) | ### Summary Implementation, tests, ops runbook, and invariants for #349 are complete on `main`. Closing as verified.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-26 06:57:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#349
No description provided.