Pause + final signoff before DOUB claims and CL8Y distribution (design inventory) #55

Closed
opened 2026-04-23 07:36:45 +00:00 by PlasticDigits · 23 comments
PlasticDigits commented 2026-04-23 07:36:45 +00:00 (Migrated from gitlab.com)

Summary

Add an onchain and/or operational pause so that, for CL8Y and DOUB issuance / distribution, the system (or key flows) cannot proceed to user-facing “money movement” until a defined final signoff (e.g. multisig / timelock / explicit contract call) is recorded.

This issue is a scope and inventory checklist — implementation design is TBD. No code in this issue.


1) Clarify what “issuance / distribution / claim” must gate (decision)

Before writing contracts, lock semantics for these distinct surfaces:

DOUB — user “claims” in-repo today

Path Contract What moves Open question
Presale vesting contracts/src/vesting/DoubPresaleVesting.sol — claim() DOUB from vesting contract to beneficiaries Is signoff after startVesting (time starts but no claims) or before startVesting? Or both (fund → startVesting → signoff → claim enabled)?
CHARM → DOUB (sale allocation) contracts/src/TimeCurve.sol — redeemCharms() DOUB from TimeCurve to buyers after endSale Should redemption stay blocked until the same “final signoff” as presale, or a separate governance step?

CL8Y — “distribution” in-repo (several meanings)

Path Where What moves Open question
Per-buy fee routing TimeCurve.buy → FeeRouter → sinks (DoubLPIncentives 30%, burn 40%, PodiumPool 20%, team 0%, RabbitTreasury 10%) CL8Y from buyers into sinks (continuous during sale) Does “no CL8Y distributed until signoff” mean pause all buy (no routing), or only block certain sinks (e.g. LP / podium) while allowing others?
Podium (reserve prizes) TimeCurve.distributePrizes() — pays accepted asset (CL8Y) from PodiumPool to winners CL8Y to podium addresses (after endSale) Is this the primary “CL8Y distribution” to gate, or is it a subset?
CL8Y token / DAO treasury Referenced in docs as external ERC-20; DeployDev uses mock Initial CL8Y supply is out of this repo unless added later If signoff covers “CL8Y genesis airdrop / team unlock”, confirm whether that is in-repo or separate deployment/docs only.

Action: Add an ADR or short docs/operations/… runbook section that names the authoritative onchain “signoff” step(s) and the order of operations (e.g. fund presale contract → D-day multisig #1 → startVesting → D-day multisig #2 → claims open).


2) Smart contracts / interfaces — what likely needs design or change

  • DoubPresaleVesting.sol

    • Today: onlyOwner may call startVesting once; claim() is allowed once vestingStart is set; no “pause for claims” separate from not having started.
    • Candidate patterns: (a) Pausable for claim only; (b) claimsEnabled / signoff flag with role CL8Y governance / timelock; (c) split admin: “schedule start” vs “unpause claims” (two-step).
    • Tests: contracts/test/DoubPresaleVesting.t.sol (new cases for reverts, events, invariants in docs/testing/invariants-and-business-logic.md § DoubPresaleVesting).
  • TimeCurve.sol

    • Gated surfaces: buy (inbound CL8Y and routing), redeemCharms, distributePrizes, and possibly endSale (if you want a single pre-end pause).
    • Candidate patterns: (a) OpenZeppelin Pausable (scope: all externals vs subset); (b) immutable “launch latch” with onlyRole / multisig; (c) separate flags for redemptions vs podiumPayout vs buys to match product.
    • Tests: contracts/test/TimeCurve.t.sol, TimeCurveInvariant.t.sol, TimeCurveReferral.t.sol, any fork smoke.
  • FeeRouter.sol + sinks

    • If “CL8Y cannot flow to sinks” is required without pausing the whole TimeCurve contract, evaluate pausing at router or sink level — document tradeoffs (bypass, ordering, receive from other sources).
  • RabbitTreasury.sol

    • Already has Pausable for deposit/withdraw — unrelated unless the signoff is meant to also gate Burrow; call out explicitly if in or out of scope.
  • tokens/Doubloon.sol

    • Minter / supply bootstrap for genesis — if signoff must precede any further mint, document interaction with PARAMETERS.md and deploy scripts.
  • ABIs / artifacts

    • contracts/script/export_abi_hashes.sh and any package consumers if public interfaces or events change.

3) Documentation to update (when design is fixed)

  • contracts/PARAMETERS.md — new roles, flags, and operator checklist (mainnet TBDs).
  • docs/testing/invariants-and-business-logic.md — new invariants, spec ↔ test map, DoubPresaleVesting and TimeCurve rows.
  • docs/testing/strategy.md / docs/testing/ci.md — if new suites or fork flags.
  • docs/onchain/fee-routing-and-governance.md — if governance actors / authority cross-walk changes (e.g. who can unpause, timelock).
  • docs/product/primitives.md, docs/glossary.md, docs/product/vision.md (only if user-visible rules change).
  • launchplan-timecurve.md — genesis order of operations, signoff checkpoints.
  • contracts/README.md — contract table / behavior.
  • QA — docs/qa/YO-TimeCurve-QA-Checklist.md, docs/qa/QA-onboarding-gitlab-issue-body.md (checklist steps for new gates).
  • Ops — docs/operations/stage2-run-log.md / docs/operations/stage3-mainnet-operator-runbook.md (if present): human steps for “final signoff”.

Agent / Cursor

  • .cursor/skills/yieldomega-guardrails/SKILL.md — if new invariants, testing expectations, or TimeCurve/phase docs are implicated; keep docs/frontend/timecurve-views.md in sync if sale UX gating is affected.
  • Root skills/README.md + skills/play-timecurve-doubloon/SKILL.md — participant-facing: what “not yet live / paused” means for redeemCharms vs presale, and that rules stay onchain.

4) Indexer and frontend

  • indexer/src/decoder.rs, indexer/src/persist.rs, integration tests — if new events, state fields, or Paused / Unpaused patterns are introduced; update REORG notes if reorg tests depend on new tables.
  • frontend/src/pages/timecurve/useTimeCurveSaleSession.ts, frontend/src/lib/abis.ts, and any redeem / prize CTAs — surface “awaiting final signoff” and failed tx copy.
  • Vitest / Playwright — Anvil and UI flows that assume immediate redeemCharms or distributePrizes after endSale may need new branches.

5) Scripts and deploy / CI

  • contracts/script/DeployDev.s.sol and any mainnet/fork deploy scripts — wire roles, initial paused state, multisig.
  • scripts/e2e-anvil.sh, docs/testing/e2e-anvil.md, scripts/start-local-anvil-stack.sh — if stack needs an extra “unpause for E2E” step.
  • contracts/deployments/*.json registries — document any new role holders.

6) Suggested deliverables (for a future implementation MR)

  1. Design doc (short) in-repo: exact pause/signoff order for DOUB presale, TimeCurve redemption, and CL8Y flows.
  2. Foundry tests covering happy path + revert paths + invariants in invariants-and-business-logic.md.
  3. Docs + skills + QA checklist sync.
  4. Indexer/frontend only if onchain state or events are user-visible in product.

7) References (current code)

  • DOUB presale: contracts/src/vesting/DoubPresaleVesting.sol (startVesting, claim)
  • TimeCurve: contracts/src/TimeCurve.sol (redeemCharms, distributePrizes, buy → fee routing)
  • LP sink: contracts/src/sinks/DoubLPIncentives.sol (receives 30% slice per fee doc)
  • Fee policy: docs/onchain/fee-routing-and-governance.md, launchplan-timecurve.md
  • Note: No DoubPresaleVesting UI in frontend/ today — a future “claim” page would also need the same messaging.

Acceptance criteria for this issue

  • Stakeholders agree on the gated operations (table in §1).
  • Implementation issue(s) or MRs can be cut with clear contract + test + doc ownership from §§2–5.
## Summary Add an **onchain and/or operational pause** so that, for **CL8Y and DOUB issuance / distribution**, the system (or key flows) **cannot proceed to user-facing “money movement”** until a **defined final signoff** (e.g. multisig / timelock / explicit contract call) is recorded. **This issue is a scope and inventory checklist** — implementation design is TBD. No code in this issue. --- ## 1) Clarify what “issuance / distribution / claim” must gate (decision) Before writing contracts, lock semantics for these **distinct** surfaces: ### DOUB — user “claims” in-repo today | Path | Contract | What moves | Open question | |------|----------|------------|---------------| | **Presale vesting** | `contracts/src/vesting/DoubPresaleVesting.sol` — `claim()` | DOUB from vesting contract to beneficiaries | Is signoff **after** `startVesting` (time starts but no claims) or **before** `startVesting`? Or both (fund → `startVesting` → signoff → `claim` enabled)? | | **CHARM → DOUB (sale allocation)** | `contracts/src/TimeCurve.sol` — `redeemCharms()` | DOUB from `TimeCurve` to buyers after `endSale` | Should redemption stay blocked until the same “final signoff” as presale, or a **separate** governance step? | ### CL8Y — “distribution” in-repo (several meanings) | Path | Where | What moves | Open question | |------|-------|------------|---------------| | **Per-buy fee routing** | `TimeCurve.buy` → `FeeRouter` → sinks (`DoubLPIncentives` 30%, burn 40%, `PodiumPool` 20%, team 0%, `RabbitTreasury` 10%) | CL8Y from buyers into sinks (continuous during sale) | Does “no CL8Y distributed until signoff” mean **pause all `buy`** (no routing), or only block **certain** sinks (e.g. LP / podium) while allowing others? | | **Podium (reserve prizes)** | `TimeCurve.distributePrizes()` — pays **accepted asset (CL8Y)** from `PodiumPool` to winners | CL8Y to podium addresses (after `endSale`) | Is this the primary “CL8Y distribution” to gate, or is it a subset? | | **CL8Y token / DAO treasury** | Referenced in docs as external ERC-20; `DeployDev` uses mock | Initial CL8Y supply is **out of this repo** unless added later | If signoff covers “CL8Y genesis airdrop / team unlock”, confirm whether that is **in-repo** or **separate** deployment/docs only. | **Action:** Add an ADR or short `docs/operations/…` runbook section that names the **authoritative** onchain “signoff” step(s) and the **order** of operations (e.g. fund presale contract → D-day multisig #1 → `startVesting` → D-day multisig #2 → claims open). --- ## 2) Smart contracts / interfaces — what likely needs design or change - **`DoubPresaleVesting.sol`** - Today: `onlyOwner` may call `startVesting` once; `claim()` is allowed once `vestingStart` is set; no “pause for claims” separate from not having started. - **Candidate patterns:** (a) `Pausable` for `claim` only; (b) `claimsEnabled` / `signoff` flag with role `CL8Y` governance / timelock; (c) split admin: “schedule start” vs “unpause claims” (two-step). - **Tests:** `contracts/test/DoubPresaleVesting.t.sol` (new cases for reverts, events, invariants in `docs/testing/invariants-and-business-logic.md` § DoubPresaleVesting). - **`TimeCurve.sol`** - Gated surfaces: `buy` (inbound CL8Y and routing), `redeemCharms`, `distributePrizes`, and possibly `endSale` (if you want a single pre-end pause). - **Candidate patterns:** (a) OpenZeppelin `Pausable` (scope: all externals vs subset); (b) immutable “launch latch” with `onlyRole` / multisig; (c) separate flags for `redemptions` vs `podiumPayout` vs `buys` to match product. - **Tests:** `contracts/test/TimeCurve.t.sol`, `TimeCurveInvariant.t.sol`, `TimeCurveReferral.t.sol`, any fork smoke. - **`FeeRouter.sol` + sinks** - If “CL8Y cannot flow to sinks” is required **without** pausing the whole `TimeCurve` contract, evaluate pausing at **router** or **sink** level — document tradeoffs (bypass, ordering, `receive` from other sources). - **`RabbitTreasury.sol`** - Already has `Pausable` for deposit/withdraw — **unrelated** unless the signoff is meant to also gate Burrow; call out explicitly if **in** or **out** of scope. - **`tokens/Doubloon.sol`** - Minter / supply bootstrap for genesis — if signoff must precede any further mint, document interaction with `PARAMETERS.md` and deploy scripts. - **ABIs / artifacts** - `contracts/script/export_abi_hashes.sh` and any package consumers if public interfaces or events change. --- ## 3) Documentation to update (when design is fixed) - **`contracts/PARAMETERS.md`** — new roles, flags, and operator checklist (mainnet TBDs). - **`docs/testing/invariants-and-business-logic.md`** — new invariants, spec ↔ test map, DoubPresaleVesting and TimeCurve rows. - **`docs/testing/strategy.md` / `docs/testing/ci.md`** — if new suites or fork flags. - **`docs/onchain/fee-routing-and-governance.md`** — if governance actors / authority cross-walk changes (e.g. who can unpause, timelock). - **`docs/product/primitives.md`**, **`docs/glossary.md`**, **`docs/product/vision.md`** (only if user-visible rules change). - **`launchplan-timecurve.md`** — genesis order of operations, signoff checkpoints. - **`contracts/README.md`** — contract table / behavior. - **QA** — `docs/qa/YO-TimeCurve-QA-Checklist.md`, `docs/qa/QA-onboarding-gitlab-issue-body.md` (checklist steps for new gates). - **Ops** — `docs/operations/stage2-run-log.md` / `docs/operations/stage3-mainnet-operator-runbook.md` (if present): human steps for “final signoff”. **Agent / Cursor** - **`.cursor/skills/yieldomega-guardrails/SKILL.md`** — if new invariants, testing expectations, or TimeCurve/phase docs are implicated; keep `docs/frontend/timecurve-views.md` in sync if sale UX gating is affected. - **Root `skills/README.md` + `skills/play-timecurve-doubloon/SKILL.md`** — participant-facing: what “not yet live / paused” means for `redeemCharms` vs presale, and that rules stay onchain. --- ## 4) Indexer and frontend - **`indexer/src/decoder.rs`**, **`indexer/src/persist.rs`**, **integration tests** — if new events, state fields, or `Paused` / `Unpaused` patterns are introduced; update `REORG` notes if reorg tests depend on new tables. - **`frontend/src/pages/timecurve/useTimeCurveSaleSession.ts`**, **`frontend/src/lib/abis.ts`**, and any redeem / prize CTAs — surface “awaiting final signoff” and failed tx copy. - **Vitest / Playwright** — Anvil and UI flows that assume immediate `redeemCharms` or `distributePrizes` after `endSale` may need new branches. --- ## 5) Scripts and deploy / CI - **`contracts/script/DeployDev.s.sol`** and any mainnet/fork deploy scripts — wire roles, initial paused state, multisig. - **`scripts/e2e-anvil.sh`**, **`docs/testing/e2e-anvil.md`**, **`scripts/start-local-anvil-stack.sh`** — if stack needs an extra “unpause for E2E” step. - **`contracts/deployments/*.json` registries** — document any new role holders. --- ## 6) Suggested deliverables (for a future implementation MR) 1. **Design doc (short)** in-repo: exact pause/signoff order for DOUB presale, TimeCurve redemption, and CL8Y flows. 2. **Foundry** tests covering happy path + revert paths + invariants in `invariants-and-business-logic.md`. 3. **Docs + skills + QA** checklist sync. 4. **Indexer/frontend** only if onchain state or events are user-visible in product. --- ## 7) References (current code) - DOUB presale: `contracts/src/vesting/DoubPresaleVesting.sol` (`startVesting`, `claim`) - TimeCurve: `contracts/src/TimeCurve.sol` (`redeemCharms`, `distributePrizes`, `buy` → fee routing) - LP sink: `contracts/src/sinks/DoubLPIncentives.sol` (receives 30% slice per fee doc) - Fee policy: `docs/onchain/fee-routing-and-governance.md`, `launchplan-timecurve.md` - **Note:** No `DoubPresaleVesting` UI in `frontend/` today — a future “claim” page would also need the same messaging. --- ## Acceptance criteria for *this* issue - [ ] Stakeholders agree on the **gated operations** (table in §1). - [ ] **Implementation issue(s)** or MRs can be cut with clear contract + test + doc ownership from §§2–5.
PlasticDigits commented 2026-04-24 05:05:35 +00:00 (Migrated from gitlab.com)

mentioned in commit 1be556b1c4

mentioned in commit 1be556b1c46b0a150c202175c355ebbe133ffb61
PlasticDigits commented 2026-04-24 05:05:37 +00:00 (Migrated from gitlab.com)

mentioned in commit f35dcbfe3a

mentioned in commit f35dcbfe3af12541c7d6eeb0f41e5998e1060186
PlasticDigits commented 2026-04-24 05:06:13 +00:00 (Migrated from gitlab.com)

Delivered (design + docs, issue scope)

Pushed to main (docs-only): implements the design inventory and acceptance from issue §1–3 by adding an operator-facing runbook and cross-links so stakeholders can sign off on gated surfaces and future implementation work can be cut cleanly.

What was added

Tests

  • FOUNDRY_PROFILE=ci forge test — 178 passed (no Solidity changes; regression check). Primary clone had out/ permission noise; run used a worktree with FOUNDRY_OUT under /tmp.

@brouie Please verify the design matches product/legal intent and that G1–G5 + gated-operation tables are the right set before cutting implementation MRs.

Checklist for verification

  • Gated user-facing paths in the tables match what stakeholders want (presale claim vs startVesting timing, redeemCharms vs presale same switch or not, distributePrizes / buy / fee-sink options).
  • TBD (product) row for per-buy CL8Y routing: confirm whether signoff should block all buy, or subset of sinks / FeeRouter, and document the chosen bypass risks.
  • Rabbit Treasury Pausable called out as separate from TimeCurve/vesting gates unless you want one ceremony — confirm.
  • pause-and-final-signoff.md order-of-ops fits mainnet runbook; update child issue titles when you split implementation.
  • Participant agents: skills + play-timecurve point at the ops doc; chain reads still win for live deployments.

Issue left open per process — close when stakeholders accept gated ops + implementation issues are filed.

## Delivered (design + docs, issue scope) Pushed to `main` (docs-only): implements the **design inventory and acceptance** from issue §1–3 by adding an operator-facing runbook and cross-links so stakeholders can sign off on gated surfaces and future implementation work can be cut cleanly. ### What was added - New **[docs/operations/pause-and-final-signoff.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/operations/pause-and-final-signoff.md)**: tables for **DOUB** (presale `claim`, `redeemCharms`) and **CL8Y** (buy/fee routing, `distributePrizes`), **proposed** defaults, **G1–G5** design invariants, suggested mainnet order of operations, child MR scope. - **Invariants** — new row + section with anchor `#pause-and-final-signoff-design-gitlab-55` in [docs/testing/invariants-and-business-logic.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/testing/invariants-and-business-logic.md). - **Cross-links:** [PARAMETERS.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/contracts/PARAMETERS.md), [fee-routing-and-governance.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/onchain/fee-routing-and-governance.md), [launchplan-timecurve.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/launchplan-timecurve.md) §4.4, [contracts/README.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/contracts/README.md), [stage3-mainnet-operator-runbook.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/operations/stage3-mainnet-operator-runbook.md), [YO-TimeCurve-QA-Checklist.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/qa/YO-TimeCurve-QA-Checklist.md) **B6**, [skills/README.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/skills/README.md) + [play-timecurve-doubloon](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/skills/play-timecurve-doubloon/SKILL.md), [yieldomega-guardrails](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/.cursor/skills/yieldomega-guardrails/SKILL.md) (items 10–11: WarBow #51 + pause #55). - **Onchain implementation** (Pausable, flags, timelock wiring) is explicitly **out of this change**; the doc names follow-up contract/indexer/frontend owners per issue §2–4. ### Tests - `FOUNDRY_PROFILE=ci forge test` — **178 passed** (no Solidity changes; regression check). Primary clone had `out/` permission noise; run used a worktree with `FOUNDRY_OUT` under `/tmp`. @brouie Please verify the **design** matches product/legal intent and that **G1–G5** + gated-operation tables are the right set before cutting implementation MRs. ### Checklist for verification - [ ] Gated **user-facing** paths in the tables match what stakeholders want (presale `claim` vs `startVesting` timing, `redeemCharms` vs presale same switch or not, `distributePrizes` / `buy` / fee-sink options). - [ ] **TBD (product)** row for per-buy CL8Y routing: confirm whether signoff should block **all `buy`**, or **subset of sinks** / `FeeRouter`, and document the chosen bypass risks. - [ ] **Rabbit Treasury** `Pausable` called out as separate from TimeCurve/vesting gates unless you want one ceremony — confirm. - [ ] [pause-and-final-signoff.md](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/operations/pause-and-final-signoff.md) order-of-ops fits mainnet runbook; update **child issue** titles when you split implementation. - [ ] Participant agents: [skills](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/skills/README.md) + play-timecurve point at the ops doc; chain reads still win for live deployments. Issue left **open** per process — close when stakeholders accept gated ops + implementation issues are filed.
PlasticDigits commented 2026-04-24 05:11:07 +00:00 (Migrated from gitlab.com)

mentioned in commit f2500ec53a

mentioned in commit f2500ec53ae0baf5c55f96f6d4ed44167479e4c6
PlasticDigits commented 2026-04-24 05:11:24 +00:00 (Migrated from gitlab.com)

Implementation pushed (issue #55) — @brouie please verify

Merged to main: f2500ec — final signoff / value-movement gates for DOUB presale claims and TimeCurve post-sale + sale-time fee routing.

What changed

  • DoubPresaleVesting: claimsEnabled (default off) and setClaimsEnabled — claim() reverts with DoubVesting__ClaimsNotEnabled after startVesting until the owner enables. Revert order: NotStarted first, then ClaimsNotEnabled.
  • TimeCurve: buyFeeRoutingEnabled (default on in initialize), charmRedemptionEnabled and reservePodiumPayoutsEnabled (default off), each with onlyOwner setters and events. distributePrizes only requires the podium flag when the prize pool is non-zero (empty-pool retry behavior unchanged).
  • Dev / Anvil: DeployDev, DevStackIntegration, SimulateAnvilRichState enable the two post-end flags after startSale for local E2E.
  • Frontend: useTimeCurveSaleSession reads the three flags; TimeCurveSimplePage disables buy / redeem and shows copy when gates are off.
  • Docs: docs/operations/final-signoff-and-value-movement.md, invariants-and-business-logic.md, PARAMETERS.md, skills/, .cursor/skills/yieldomega-guardrails.

Checklist for verification

  • cd contracts && FOUNDRY_PROFILE=ci forge test — all green (182 tests at time of push).
  • cd frontend && npm ci && npx vitest run — all green.
  • On a fresh Anvil DeployDev stack: after sale end, redeemCharms / distributePrizes work (flags enabled in script); toggling charmRedemptionEnabled / reservePodiumPayoutsEnabled off reverts with the new strings.
  • Presale vesting: deploy → fund → startVesting → claim reverts until setClaimsEnabled(true).
  • Upgrade note: new proxy storage defaults — document any post-upgrade set* in your runbook.

Issue left open for stakeholder signoff as in the original inventory. Thanks!

## Implementation pushed (issue #55) — @brouie please verify **Merged to `main`:** `f2500ec` — final signoff / value-movement gates for DOUB presale claims and TimeCurve post-sale + sale-time fee routing. ### What changed - **`DoubPresaleVesting`:** `claimsEnabled` (default off) and `setClaimsEnabled` — `claim()` reverts with `DoubVesting__ClaimsNotEnabled` after `startVesting` until the owner enables. Revert order: `NotStarted` first, then `ClaimsNotEnabled`. - **`TimeCurve`:** `buyFeeRoutingEnabled` (default on in `initialize`), `charmRedemptionEnabled` and `reservePodiumPayoutsEnabled` (default off), each with `onlyOwner` setters and events. `distributePrizes` only requires the podium flag when the prize pool is non-zero (empty-pool retry behavior unchanged). - **Dev / Anvil:** `DeployDev`, `DevStackIntegration`, `SimulateAnvilRichState` enable the two post-end flags after `startSale` for local E2E. - **Frontend:** `useTimeCurveSaleSession` reads the three flags; `TimeCurveSimplePage` disables buy / redeem and shows copy when gates are off. - **Docs:** `docs/operations/final-signoff-and-value-movement.md`, `invariants-and-business-logic.md`, `PARAMETERS.md`, `skills/`, `.cursor/skills/yieldomega-guardrails`. ### Checklist for verification - [ ] `cd contracts && FOUNDRY_PROFILE=ci forge test` — all green (182 tests at time of push). - [ ] `cd frontend && npm ci && npx vitest run` — all green. - [ ] On a fresh Anvil `DeployDev` stack: after sale end, `redeemCharms` / `distributePrizes` work (flags enabled in script); toggling `charmRedemptionEnabled` / `reservePodiumPayoutsEnabled` off reverts with the new strings. - [ ] **Presale vesting:** deploy → fund → `startVesting` → `claim` reverts until `setClaimsEnabled(true)`. - [ ] **Upgrade note:** new proxy storage defaults — document any post-upgrade `set*` in your runbook. Issue left **open** for stakeholder signoff as in the original inventory. Thanks!
PlasticDigits commented 2026-04-24 05:42:58 +00:00 (Migrated from gitlab.com)

Required follow-up (recorded for manual review)

Pause sale interactions (single switch) must include WarBow CL8Y burn paths (warbowSteal, warbowRevenge, warbowActivateGuard) under the same buyFeeRoutingEnabled flag as buy → FeeRouter, so operators can halt all sale-time CL8Y movement from users in one step.

CL8Y allocation (reserve / podium) remains under manual review via reservePodiumPayoutsEnabled before distributePrizes pays winners from PodiumPool (non-zero pool case); charmRedemptionEnabled gates DOUB sale allocation via redeemCharms.

Implementation to be merged with unified revert string TimeCurve: sale interactions disabled for buy + WarBow CL8Y actions.

## Required follow-up (recorded for manual review) **Pause sale interactions (single switch)** must include **WarBow CL8Y burn paths** (`warbowSteal`, `warbowRevenge`, `warbowActivateGuard`) under the same `buyFeeRoutingEnabled` flag as `buy` → `FeeRouter`, so operators can halt **all** sale-time CL8Y movement from users in one step. **CL8Y allocation (reserve / podium)** remains under **manual review** via `reservePodiumPayoutsEnabled` before `distributePrizes` pays winners from `PodiumPool` (non-zero pool case); `charmRedemptionEnabled` gates DOUB sale allocation via `redeemCharms`. Implementation to be merged with unified revert string `TimeCurve: sale interactions disabled` for buy + WarBow CL8Y actions.
PlasticDigits commented 2026-04-24 05:52:09 +00:00 (Migrated from gitlab.com)

mentioned in commit cf6fe19b33

mentioned in commit cf6fe19b335af7aed35b1c1b627fcae7e2d8317c
PlasticDigits commented 2026-04-24 05:52:11 +00:00 (Migrated from gitlab.com)

Update pushed: buyFeeRoutingEnabled now gates WarBow CL8Y paths (warbowSteal, warbowRevenge, warbowActivateGuard) in addition to buy → FeeRouter, with a single revert string TimeCurve: sale interactions disabled. claimWarBowFlag is not gated (no CL8Y). CL8Y reserve allocation to podium winners remains reservePodiumPayoutsEnabled before distributePrizes (non-zero pool). Commit: cf6fe19.

**Update pushed:** `buyFeeRoutingEnabled` now gates **WarBow CL8Y** paths (`warbowSteal`, `warbowRevenge`, `warbowActivateGuard`) in addition to `buy` → `FeeRouter`, with a single revert string `TimeCurve: sale interactions disabled`. `claimWarBowFlag` is **not** gated (no CL8Y). **CL8Y reserve allocation** to podium winners remains **`reservePodiumPayoutsEnabled`** before `distributePrizes` (non-zero pool). Commit: `cf6fe19`.
Brouie commented 2026-04-26 05:40:28 +00:00 (Migrated from gitlab.com)

@PlasticDigits source-level verification of f2500ec + cf6fe19. Issue stays open per your note pending stakeholder signoff and the live-stack item.

Contracts (TimeCurve.sol):

  • Storage L825-829: buyFeeRoutingEnabled / charmRedemptionEnabled / reservePodiumPayoutsEnabled
  • initialize() L258-260: defaults true / false / false (sale runs by default; post-end gates default off)
  • Setters L279/284/289 (onlyOwner)
  • Single helper _requireSaleInteractionsEnabled at L294 with revert string 'TimeCurve: sale interactions disabled'
  • Helper called at: L326 _buy, L478 warbowSteal, L529 warbowRevenge, L554 warbowActivateGuard
  • claimWarBowFlag (L462) intentionally NOT gated, matches your note (no CL8Y burn)
  • L620 charmRedemptionEnabled gate on redeemCharms, revert 'TimeCurve: charm redemptions disabled'
  • L642 reservePodiumPayoutsEnabled gate on distributePrizes, revert 'TimeCurve: reserve podium payouts disabled'

Contracts (DoubPresaleVesting.sol):

  • Storage L57: claimsEnabled
  • Error L76: DoubVesting__ClaimsNotEnabled
  • Setter L125-126 (onlyOwner)
  • claim() L184-186 revert order matches spec: NotStarted -> ClaimsNotEnabled -> NotBeneficiary
  • nonReentrant preserved on claim()

Dev / Anvil scripts:

  • DeployDev.s.sol L141-142: enables both post-end flags after startSale
  • SimulateAnvilRichState.s.sol L15-16 + L142-143: interface + enables
  • DevStackIntegration.t.sol L106-107: enables in test stack

Frontend:

  • useTimeCurveSaleSession.ts L194-196: useReadContracts reads all three flags from chain
  • L550-552 / L822-828: results parsed into session object
  • L561 (buy path) and L739 (redeem path): write-side guards short-circuit with copy when flags off
  • TimeCurveSimplePage.tsx L261: buyFeeRoutingEnabled === false feeds buyDisabled
  • L539: status copy 'Sale interactions are paused onchain (buys + WarBow CL8Y) until operators re-enable'
  • L427/503/696/709: redeem-side gating + status copy when charmRedemptionEnabled off

Tests:

  • TimeCurve.t.sol L416/428/437/447: all three revert strings + buy + WarBow paths covered
  • DoubPresaleVesting.t.sol L389: ClaimsNotEnabled revert covered
  • forge: FOUNDRY_PROFILE=ci forge test -> 183 passed (you cited 182 at push, slight drift from #54 follow-up)
  • frontend vitest: npx vitest run -> 156/156 passing (you cited 135, drift from later test additions in 8951ca7 / 05c7ebd)

Docs:

  • docs/operations/final-signoff-and-value-movement.md present (3153 bytes)
  • docs/operations/pause-and-final-signoff.md present (design inventory, the f2500ec sister doc)
  • invariants-and-business-logic.md / PARAMETERS.md / skills/ updates per your earlier note

Deferred to Monday (blocked by #61 live stack):

  • 'On a fresh Anvil DeployDev stack' E2E checklist row (toggle off -> revert with new strings, toggle on -> redeem/distribute work)

Stakeholder signoff items (not QA-actionable):

  • Per-buy CL8Y routing scope (TBD product row)
  • Rabbit Treasury Pausable as separate ceremony
  • Implementation child issues per your tables in pause-and-final-signoff.md
@PlasticDigits source-level verification of f2500ec + cf6fe19. Issue stays open per your note pending stakeholder signoff and the live-stack item. Contracts (TimeCurve.sol): - Storage L825-829: buyFeeRoutingEnabled / charmRedemptionEnabled / reservePodiumPayoutsEnabled - initialize() L258-260: defaults true / false / false (sale runs by default; post-end gates default off) - Setters L279/284/289 (onlyOwner) - Single helper _requireSaleInteractionsEnabled at L294 with revert string 'TimeCurve: sale interactions disabled' - Helper called at: L326 _buy, L478 warbowSteal, L529 warbowRevenge, L554 warbowActivateGuard - claimWarBowFlag (L462) intentionally NOT gated, matches your note (no CL8Y burn) - L620 charmRedemptionEnabled gate on redeemCharms, revert 'TimeCurve: charm redemptions disabled' - L642 reservePodiumPayoutsEnabled gate on distributePrizes, revert 'TimeCurve: reserve podium payouts disabled' Contracts (DoubPresaleVesting.sol): - Storage L57: claimsEnabled - Error L76: DoubVesting__ClaimsNotEnabled - Setter L125-126 (onlyOwner) - claim() L184-186 revert order matches spec: NotStarted -> ClaimsNotEnabled -> NotBeneficiary - nonReentrant preserved on claim() Dev / Anvil scripts: - DeployDev.s.sol L141-142: enables both post-end flags after startSale - SimulateAnvilRichState.s.sol L15-16 + L142-143: interface + enables - DevStackIntegration.t.sol L106-107: enables in test stack Frontend: - useTimeCurveSaleSession.ts L194-196: useReadContracts reads all three flags from chain - L550-552 / L822-828: results parsed into session object - L561 (buy path) and L739 (redeem path): write-side guards short-circuit with copy when flags off - TimeCurveSimplePage.tsx L261: buyFeeRoutingEnabled === false feeds buyDisabled - L539: status copy 'Sale interactions are paused onchain (buys + WarBow CL8Y) until operators re-enable' - L427/503/696/709: redeem-side gating + status copy when charmRedemptionEnabled off Tests: - TimeCurve.t.sol L416/428/437/447: all three revert strings + buy + WarBow paths covered - DoubPresaleVesting.t.sol L389: ClaimsNotEnabled revert covered - forge: FOUNDRY_PROFILE=ci forge test -> 183 passed (you cited 182 at push, slight drift from #54 follow-up) - frontend vitest: npx vitest run -> 156/156 passing (you cited 135, drift from later test additions in 8951ca7 / 05c7ebd) Docs: - docs/operations/final-signoff-and-value-movement.md present (3153 bytes) - docs/operations/pause-and-final-signoff.md present (design inventory, the f2500ec sister doc) - invariants-and-business-logic.md / PARAMETERS.md / skills/ updates per your earlier note Deferred to Monday (blocked by #61 live stack): - 'On a fresh Anvil DeployDev stack' E2E checklist row (toggle off -> revert with new strings, toggle on -> redeem/distribute work) Stakeholder signoff items (not QA-actionable): - Per-buy CL8Y routing scope (TBD product row) - Rabbit Treasury Pausable as separate ceremony - Implementation child issues per your tables in pause-and-final-signoff.md
PlasticDigits commented 2026-04-26 08:27:07 +00:00 (Migrated from gitlab.com)

mentioned in issue #69

mentioned in issue #69
Brouie commented 2026-04-27 02:46:34 +00:00 (Migrated from gitlab.com)

mentioned in issue #72

mentioned in issue #72
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-04-27 02:48:34 +00:00
Brouie commented 2026-04-27 04:12:19 +00:00 (Migrated from gitlab.com)

mentioned in issue #65

mentioned in issue #65
Brouie commented 2026-04-27 04:23:29 +00:00 (Migrated from gitlab.com)

mentioned in issue #79

mentioned in issue #79
Brouie commented 2026-04-27 04:23:59 +00:00 (Migrated from gitlab.com)

@PlasticDigits per today's process update (file follow-ups, close originals): post-end gate walkthrough items moved to #79.

Today's live verification add (in addition to Sunday's source review note above)

cast against the live local stack (1bdbda8) to exercise the unified _requireSaleInteractionsEnabled helper from cf6fe19:

  • cast send setBuyFeeRoutingEnabled(false) [status=1] -> cast call buy(1e18) reverts with exact: 'TimeCurve: sale interactions disabled'
  • cast send setBuyFeeRoutingEnabled(true) [status=1] -> cast call buy(1e18) reverts past the gate with custom error 0xfb8f41b2 (ERC20InsufficientAllowance) — proves the buy logic is now reachable, gate clears
  • cast send setBuyFeeRoutingEnabled(false) [status=1] -> cast call warbowSteal(addr, false) reverts with same exact: 'TimeCurve: sale interactions disabled' — confirms the unified L295 helper is wired into both buy and WarBow paths
  • restored to true after testing so stack stays usable

That covers the active-sale gate live. Post-end gates (charmRedemption + reservePodiumPayouts) tracked at #79 since they require an ended=true stack from anvil_rich_state.sh.

Stakeholder signoff items (per-buy CL8Y routing TBD, Rabbit Treasury Pausable ceremony, implementation child issues from pause-and-final-signoff.md) noted as not QA-actionable per your framing — should track separately if they become concrete.

Closing #55. Live walkthrough proceeds via #79.

@PlasticDigits per today's process update (file follow-ups, close originals): post-end gate walkthrough items moved to #79. ## Today's live verification add (in addition to Sunday's source review note above) cast against the live local stack (1bdbda8) to exercise the unified _requireSaleInteractionsEnabled helper from cf6fe19: - cast send setBuyFeeRoutingEnabled(false) [status=1] -> cast call buy(1e18) reverts with exact: 'TimeCurve: sale interactions disabled' - cast send setBuyFeeRoutingEnabled(true) [status=1] -> cast call buy(1e18) reverts past the gate with custom error 0xfb8f41b2 (ERC20InsufficientAllowance) — proves the buy logic is now reachable, gate clears - cast send setBuyFeeRoutingEnabled(false) [status=1] -> cast call warbowSteal(addr, false) reverts with same exact: 'TimeCurve: sale interactions disabled' — confirms the unified L295 helper is wired into both buy and WarBow paths - restored to true after testing so stack stays usable That covers the active-sale gate live. Post-end gates (charmRedemption + reservePodiumPayouts) tracked at #79 since they require an ended=true stack from anvil_rich_state.sh. Stakeholder signoff items (per-buy CL8Y routing TBD, Rabbit Treasury Pausable ceremony, implementation child issues from pause-and-final-signoff.md) noted as not QA-actionable per your framing — should track separately if they become concrete. Closing #55. Live walkthrough proceeds via #79.
PlasticDigits commented 2026-04-27 05:07:27 +00:00 (Migrated from gitlab.com)

mentioned in commit 8803428809

mentioned in commit 88034288091d307de99a7afd1c72e87ce30a8c15
PlasticDigits commented 2026-04-30 05:25:10 +00:00 (Migrated from gitlab.com)

mentioned in issue #100

mentioned in issue #100
PlasticDigits commented 2026-05-04 04:14:33 +00:00 (Migrated from gitlab.com)

mentioned in issue #116

mentioned in issue #116
PlasticDigits commented 2026-05-04 08:36:06 +00:00 (Migrated from gitlab.com)

mentioned in issue #133

mentioned in issue #133
PlasticDigits commented 2026-05-04 08:51:59 +00:00 (Migrated from gitlab.com)

mentioned in issue #141

mentioned in issue #141
PlasticDigits commented 2026-05-13 16:07:17 +00:00 (Migrated from gitlab.com)

mentioned in issue #207

mentioned in issue #207
PlasticDigits commented 2026-05-19 07:53:22 +00:00 (Migrated from gitlab.com)

mentioned in issue #217

mentioned in issue #217
PlasticDigits commented 2026-05-21 09:32:21 +00:00 (Migrated from gitlab.com)

mentioned in issue #232

mentioned in issue #232
PlasticDigits commented 2026-05-29 08:06:25 +00:00 (Migrated from gitlab.com)

mentioned in issue #264

mentioned in issue #264
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#55
No description provided.