F-10 missing: no DoubPresaleVesting frontend UI or local-Anvil deployment for vesting checklist #92

Closed
opened 2026-04-29 06:56:40 +00:00 by Brouie · 9 comments
Brouie commented 2026-04-29 06:56:40 +00:00 (Migrated from gitlab.com)

Summary

#38 F-11 (sic, F-10) checklist item asks for "Presale vesting UX (DoubPresaleVesting 30% + 180-day)" with vesting clock visible in local tz AND UTC. Walking the YO frontend on 799cf6f today, I cannot find any vesting UI, route, or panel. The DoubPresaleVesting contract exists in source (contracts/src/vesting/DoubPresaleVesting.sol) and there's a deploy helper for it (script/UUPSDeployLib.sol L151-164), but DeployDev.s.sol doesn't currently call deployDoubPresaleVesting() and the frontend has zero strings matching "vesting", "presale vesting", "180 day", "30% unlock", etc.

So F-10 has neither a frontend implementation nor an active local-Anvil deployment for testing.

Repro

  1. cd /srv/qa/repos/yieldomega/frontend
  2. grep -rli "vesting" src/ -> 0 matches
  3. cd ../contracts
  4. grep -n "DoubPresaleVesting" script/DeployDev.s.sol -> 0 matches
  5. Hit /timecurve, /timecurve/protocol, /collection, /referrals, /rabbit-treasury, /kumbaya, /sir routes -> none surface vesting UI

What exists vs what's missing

What exists:

  • DoubPresaleVesting.sol contract with the documented 30% / 180-day mechanics
  • Deploy helper deployDoubPresaleVesting() in UUPSDeployLib.sol
  • Forge unit tests on the vesting contract behavior

What's missing for F-10:

  • No /vesting or similar route in the YO frontend
  • No vesting panel embedded in any other route
  • Not deployed in DeployDev.s.sol so even if a UI was wired, the local stack would have nothing to read from

Suggested resolution

If F-10 is in-scope for TGE:

  1. Wire DoubPresaleVesting into DeployDev.s.sol so it deploys in local QA
  2. Add a frontend /vesting route or panel with the 30% / 180-day display (claim UI, time-remaining clock in local + UTC, your-allocation read, claimable-now read)
  3. Hook into existing frontend wagmi/contract-read patterns

If F-10 is post-TGE / out of scope for now:

  • Update YO-DOUB-Launch-UX-Flows.md spec to remove F-10 from launch checklist and move to a future-milestone bucket

Severity

P3-low for spec drift, P2-medium if F-10 is genuinely a TGE deliverable that's been forgotten.

Filed during #38 F-10 walkthrough today.

cc @PlasticDigits

## Summary #38 F-11 (sic, F-10) checklist item asks for "Presale vesting UX (DoubPresaleVesting 30% + 180-day)" with vesting clock visible in local tz AND UTC. Walking the YO frontend on 799cf6f today, I cannot find any vesting UI, route, or panel. The DoubPresaleVesting contract exists in source (contracts/src/vesting/DoubPresaleVesting.sol) and there's a deploy helper for it (script/UUPSDeployLib.sol L151-164), but DeployDev.s.sol doesn't currently call deployDoubPresaleVesting() and the frontend has zero strings matching "vesting", "presale vesting", "180 day", "30% unlock", etc. So F-10 has neither a frontend implementation nor an active local-Anvil deployment for testing. ## Repro 1. cd /srv/qa/repos/yieldomega/frontend 2. grep -rli "vesting" src/ -> 0 matches 3. cd ../contracts 4. grep -n "DoubPresaleVesting" script/DeployDev.s.sol -> 0 matches 5. Hit /timecurve, /timecurve/protocol, /collection, /referrals, /rabbit-treasury, /kumbaya, /sir routes -> none surface vesting UI ## What exists vs what's missing What exists: - DoubPresaleVesting.sol contract with the documented 30% / 180-day mechanics - Deploy helper deployDoubPresaleVesting() in UUPSDeployLib.sol - Forge unit tests on the vesting contract behavior What's missing for F-10: - No /vesting or similar route in the YO frontend - No vesting panel embedded in any other route - Not deployed in DeployDev.s.sol so even if a UI was wired, the local stack would have nothing to read from ## Suggested resolution If F-10 is in-scope for TGE: 1. Wire DoubPresaleVesting into DeployDev.s.sol so it deploys in local QA 2. Add a frontend /vesting route or panel with the 30% / 180-day display (claim UI, time-remaining clock in local + UTC, your-allocation read, claimable-now read) 3. Hook into existing frontend wagmi/contract-read patterns If F-10 is post-TGE / out of scope for now: - Update YO-DOUB-Launch-UX-Flows.md spec to remove F-10 from launch checklist and move to a future-milestone bucket ## Severity P3-low for spec drift, P2-medium if F-10 is genuinely a TGE deliverable that's been forgotten. Filed during #38 F-10 walkthrough today. cc @PlasticDigits
PlasticDigits commented 2026-04-29 09:03:47 +00:00 (Migrated from gitlab.com)

In addition to the suggested resolution, the /vesting route should be hidden (not in the menu) so it can be shared directly with presale vesting

In addition to the suggested resolution, the /vesting route should be hidden (not in the menu) so it can be shared directly with presale vesting
PlasticDigits commented 2026-04-29 09:44:53 +00:00 (Migrated from gitlab.com)

mentioned in commit 282eb623a1

mentioned in commit 282eb623a10052b3f1dffb819b1467859eb00db6
PlasticDigits commented 2026-04-29 09:45:42 +00:00 (Migrated from gitlab.com)

Implemented (GitLab #92) — pushed to main @ 282eb62

Contracts: DeployDev.s.sol now deploys a dev-only DoubPresaleVesting (Anvil account #0 + #1, 10k DOUB total, 180-day linear), mints DOUB to the vesting contract, calls setClaimsEnabled(true) and startVesting(), and console.logs DoubPresaleVesting: for stack tooling.

Stack / env: scripts/start-local-anvil-stack.sh and scripts/lib/anvil_deploy_dev.sh parse that line; registry JSON gains DoubPresaleVesting; frontend/.env.local gets VITE_DOUB_PRESALE_VESTING_ADDRESS. scripts/e2e-anvil.sh exports the same for builds.

Frontend: Hidden /vesting route (not in RootLayout nav — per issue note). PresaleVestingPage: schedule copy, dual local + UTC clock, wallet allocation / claimed / claimable, Claim DOUB wired to claim().

Tests: Vitest (presaleVestingFormat), forge test (existing vesting + DevStackIntegration on branch), bash scripts/e2e-anvil.sh (includes new e2e/anvil-presale-vesting.spec.ts) — all green before push.

Docs: docs/frontend/presale-vesting.md, invariant block + anchor in docs/testing/invariants-and-business-logic.md, e2e-anvil.md / strategy.md, launch F-10 in YO-DOUB-Launch-UX-Flows.md + launchplan-timecurve.md, play skill skills/verify-yo-presale-vesting/SKILL.md, guardrails item 28.

@brouie please verify using this checklist (issue stays open per request):

  • bash scripts/e2e-anvil.sh passes locally (6 Anvil specs incl. vesting).
  • After bash scripts/start-local-anvil-stack.sh, open http://127.0.0.1:5173/vesting — no /vesting link in header; page shows Presale vesting, Contract schedule, Vesting clock (local + UTC), wallet panel with Claim DOUB enabled for default Anvil #0.
  • contracts/deployments/local-anvil-registry.json contains DoubPresaleVesting; frontend/.env.local has VITE_DOUB_PRESALE_VESTING_ADDRESS matching DoubPresaleVesting: from deploy log (ERC-1967 proxy).
  • Production expectation: mainnet may keep claimsEnabled off until signoff — UI should reflect Claims enabled: No and disabled claim (see docs/operations/final-signoff-and-value-movement.md).
## Implemented (GitLab #92) — pushed to `main` @ 282eb62 **Contracts:** `DeployDev.s.sol` now deploys a **dev-only** `DoubPresaleVesting` (Anvil account #0 + #1, 10k DOUB total, **180-day** linear), mints DOUB to the vesting contract, calls **`setClaimsEnabled(true)`** and **`startVesting()`**, and **`console.log`s** `DoubPresaleVesting:` for stack tooling. **Stack / env:** `scripts/start-local-anvil-stack.sh` and `scripts/lib/anvil_deploy_dev.sh` parse that line; registry JSON gains **`DoubPresaleVesting`**; `frontend/.env.local` gets **`VITE_DOUB_PRESALE_VESTING_ADDRESS`**. `scripts/e2e-anvil.sh` exports the same for builds. **Frontend:** Hidden **`/vesting`** route (not in `RootLayout` nav — per issue note). `PresaleVestingPage`: schedule copy, dual **local + UTC** clock, wallet **allocation / claimed / claimable**, **`Claim DOUB`** wired to `claim()`. **Tests:** Vitest (`presaleVestingFormat`), `forge test` (existing vesting + `DevStackIntegration` on branch), **`bash scripts/e2e-anvil.sh`** (includes new `e2e/anvil-presale-vesting.spec.ts`) — all green before push. **Docs:** `docs/frontend/presale-vesting.md`, invariant block + anchor in `docs/testing/invariants-and-business-logic.md`, `e2e-anvil.md` / `strategy.md`, launch **F-10** in `YO-DOUB-Launch-UX-Flows.md` + `launchplan-timecurve.md`, play skill `skills/verify-yo-presale-vesting/SKILL.md`, guardrails item **28**. @brouie please verify using this checklist (issue stays **open** per request): - [ ] `bash scripts/e2e-anvil.sh` passes locally (6 Anvil specs incl. vesting). - [ ] After `bash scripts/start-local-anvil-stack.sh`, open `http://127.0.0.1:5173/vesting` — **no** `/vesting` link in header; page shows **Presale vesting**, **Contract schedule**, **Vesting clock** (local + UTC), wallet panel with **Claim DOUB** enabled for default Anvil #0. - [ ] `contracts/deployments/local-anvil-registry.json` contains **`DoubPresaleVesting`**; `frontend/.env.local` has **`VITE_DOUB_PRESALE_VESTING_ADDRESS`** matching **`DoubPresaleVesting:`** from deploy log (ERC-1967 **proxy**). - [ ] Production expectation: mainnet may keep **`claimsEnabled`** off until signoff — UI should reflect **Claims enabled: No** and disabled claim (see `docs/operations/final-signoff-and-value-movement.md`).
Brouie commented 2026-04-30 01:08:29 +00:00 (Migrated from gitlab.com)

mentioned in issue #38

mentioned in issue #38
Brouie commented 2026-04-30 01:57:55 +00:00 (Migrated from gitlab.com)

Verified 282eb62 against all 8 SKILL.md acceptance items on the SKIP+KUMBAYA+NO_COOLDOWN stack today. Closing.

Stack state

  • Frontend: localhost:5173, env wired with VITE_DOUB_PRESALE_VESTING_ADDRESS=0x67d269191c92Caf3cD7723F116c85e6E9bf55933
  • DoubPresaleVesting deployed by DeployDev.s.sol per the new commit:
    • token() = 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 (DOUB / "Doubloon", 18 decimals)
    • vestingDuration() = 15552000s (180 days)
    • vestingStart() = 1777511737 (Apr 30 01:15:37 UTC 2026)
    • claimsEnabled() = true
    • totalAllocated() = 10000e18 (10,000 DOUB)
    • beneficiaryCount() = 2: Anvil acct #0 0xf39Fd6...2266 (6,000 DOUB) + Anvil acct #1 0x709979...79C8 (4,000 DOUB)
    • Vesting contract holds 10000e18 DOUB pre-test (balance equals totalAllocated)

Item 1 - Hidden nav: PASS

Home page header nav shows: YIELDOMEGA logo, TimeCurve, Rabbit Treasury, Collection, Referrals, Kumbaya, Sir, Connect Wallet. No /vesting nav item. Direct URL only, exactly per the issue comment requirement to share the route directly with presale wallets without surfacing it in primary nav.

Item 2 - Direct URL loads: PASS

Navigated to http://127.0.0.1:5173/vesting. URL stays on /vesting (no redirect). Heading "PRESALE VESTING" visible with DOUB pill above. Page header copy mentions "GitLab #92" and the 30/70 + 180-day breakdown.

Item 3 - Contract block: PASS

"CONTRACT SCHEDULE" panel under "ON-CHAIN" badge with copy "Numbers below are live contract reads. DOUB token address comes from vesting.token()." Reads:

  • Vesting contract: 0x67d269191c92Caf3cD7723F116c85e6E9bf55933 (matches registry)
  • DOUB token: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 (matches cast call vesting.token())
  • Total allocated (all beneficiaries): 10000 DOUB
  • Linear tranche duration: 15552000 s (~180.0 days)
  • Claims enabled: Yes

Plus operational signoff note pointing to docs/operations/final-signoff-and-value-movement.md.

Item 4 - Schedule copy: PASS

Page header text reads (verbatim):

"30% vests at the schedule start (TGE); 70% vests linearly over the on-chain vesting duration (canonical presale bucket: 180 days). Authority and balances are reads against DoubPresaleVesting; claims require claimsEnabled."

30% cliff + 70% linear breakdown surfaced. Linear duration 15552000 s (~180.0 days) in the contract block matches vestingDuration() cast read exactly.

Item 5 - Dual clock: PASS

"VESTING CLOCK" panel under "UTC + LOCAL" badge with subtitle "Start is vestingStart; full linear unlock is vestingStart + vestingDuration."

Schedule start (TGE cliff):

  • Local: Apr 30, 2026, 9:15:37 AM GMT+8
  • UTC: Thu, 30 Apr 2026 01:15:37 GMT

Full allocation vested by:

  • Local: Oct 27, 2026, 9:15:37 AM GMT+8
  • UTC: Tue, 27 Oct 2026 01:15:37 GMT

Both anchors render Local + UTC dual lines. End - start = 180 days exact (Apr 30 -> Oct 27, matches vestingDuration()).

Item 6 - Beneficiary reads match cast: PASS

Connected MetaMask (deployer wallet 0xf39Fd6...2266) on chain 31337. "YOUR WALLET" panel surfaced with CONNECTED pill. Pre-claim reads:

  • Your allocation: 6000 DOUB (matches cast call vesting.allocations() derived value)
  • Claimed to date: 0 DOUB
  • Claimable now: 1800.000810185185185185 DOUB

Cast cross-check at the same instant: claimable(0xf39Fd6...2266) = 1800000810185185185185 wei = 1800.00081... DOUB. Frontend value matches contract read to wei precision. The fractional .000810... represents linear accrual from the few minutes elapsed since vestingStart (linear release rate ~0.27 DOUB/sec for this beneficiary's 4,200e18 linear cap over 15552000s).

Item 7 - Claims gate: PASS

claimsEnabled() = true onchain. "Claim DOUB" CTA visible and enabled. Disabled-state path was not exercised live this session (it's the inverse of the live-tested path; if needed I can flip the flag via cast and re-confirm, flag if you want explicit evidence).

Item 8 - Claim path: PASS

Clicked "Claim DOUB". MetaMask transaction request prompt:

  • Network: Anvil
  • Request from: HTTP 127.0.0.1:5173
  • Interacting with: 0x67d26...55933 (vesting contract)
  • Function: claim()

Confirmed signature. Tx mined.

Post-tx frontend state:

  • Your allocation: 6000 DOUB (unchanged)
  • Claimed to date: 1800.493132716049382716 DOUB
  • Claimable now: 0 DOUB
  • CTA disabled with copy "Nothing to claim right now."

Cast cross-check post-tx:

  • DOUB.balanceOf(0xf39Fd6...2266) = 1800493132716049382716 (1800.49 DOUB credited)
  • DOUB.balanceOf(0x67d269...55933) = 8199506867283950617284 (10000 - 1800.49 = 8199.51 DOUB remaining in vesting contract, matches to wei)
  • vesting.claimable(0xf39Fd6...2266) = 0

Frontend <-> contract integration verified end-to-end. Math:

  • Cliff portion: 30% of 6000 DOUB = 1800 DOUB exact (released at vestingStart)
  • Linear accrual at claim time: 0.493132716049382716 DOUB (the seconds between vestingStart and tx mining, weighted by the 4200e18 linear cap over 15552000s)
  • Total claimed: 1800.49... DOUB matches contract's vested(now) - claimedBefore exactly

Closure recommendation

All 8 SKILL.md items verified live. The hidden-route + dual-clock + 30/70 schedule + beneficiary reads + claim path all line up with the issue spec. Closing #92.

cc @PlasticDigits

Verified `282eb62` against all 8 SKILL.md acceptance items on the SKIP+KUMBAYA+NO_COOLDOWN stack today. Closing. ## Stack state - Frontend: localhost:5173, env wired with `VITE_DOUB_PRESALE_VESTING_ADDRESS=0x67d269191c92Caf3cD7723F116c85e6E9bf55933` - DoubPresaleVesting deployed by `DeployDev.s.sol` per the new commit: - `token() = 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512` (DOUB / "Doubloon", 18 decimals) - `vestingDuration() = 15552000s` (180 days) - `vestingStart() = 1777511737` (Apr 30 01:15:37 UTC 2026) - `claimsEnabled() = true` - `totalAllocated() = 10000e18` (10,000 DOUB) - `beneficiaryCount() = 2`: Anvil acct #0 `0xf39Fd6...2266` (6,000 DOUB) + Anvil acct #1 `0x709979...79C8` (4,000 DOUB) - Vesting contract holds `10000e18` DOUB pre-test (balance equals totalAllocated) ## Item 1 - Hidden nav: PASS Home page header nav shows: YIELDOMEGA logo, TimeCurve, Rabbit Treasury, Collection, Referrals, Kumbaya, Sir, Connect Wallet. **No `/vesting` nav item.** Direct URL only, exactly per the issue comment requirement to share the route directly with presale wallets without surfacing it in primary nav. ## Item 2 - Direct URL loads: PASS Navigated to `http://127.0.0.1:5173/vesting`. URL stays on `/vesting` (no redirect). Heading "PRESALE VESTING" visible with DOUB pill above. Page header copy mentions "GitLab #92" and the 30/70 + 180-day breakdown. ## Item 3 - Contract block: PASS "CONTRACT SCHEDULE" panel under "ON-CHAIN" badge with copy "Numbers below are live contract reads. DOUB token address comes from vesting.token()." Reads: - Vesting contract: `0x67d269191c92Caf3cD7723F116c85e6E9bf55933` (matches registry) - DOUB token: `0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512` (matches `cast call vesting.token()`) - Total allocated (all beneficiaries): 10000 DOUB - Linear tranche duration: 15552000 s (~180.0 days) - Claims enabled: Yes Plus operational signoff note pointing to `docs/operations/final-signoff-and-value-movement.md`. ## Item 4 - Schedule copy: PASS Page header text reads (verbatim): > "30% vests at the schedule start (TGE); 70% vests linearly over the on-chain vesting duration (canonical presale bucket: 180 days). Authority and balances are reads against DoubPresaleVesting; claims require claimsEnabled." 30% cliff + 70% linear breakdown surfaced. Linear duration `15552000 s (~180.0 days)` in the contract block matches `vestingDuration()` cast read exactly. ## Item 5 - Dual clock: PASS "VESTING CLOCK" panel under "UTC + LOCAL" badge with subtitle "Start is vestingStart; full linear unlock is vestingStart + vestingDuration." Schedule start (TGE cliff): - Local: Apr 30, 2026, 9:15:37 AM GMT+8 - UTC: Thu, 30 Apr 2026 01:15:37 GMT Full allocation vested by: - Local: Oct 27, 2026, 9:15:37 AM GMT+8 - UTC: Tue, 27 Oct 2026 01:15:37 GMT Both anchors render Local + UTC dual lines. End - start = 180 days exact (Apr 30 -> Oct 27, matches `vestingDuration()`). ## Item 6 - Beneficiary reads match cast: PASS Connected MetaMask (deployer wallet `0xf39Fd6...2266`) on chain 31337. "YOUR WALLET" panel surfaced with CONNECTED pill. Pre-claim reads: - Your allocation: 6000 DOUB (matches `cast call vesting.allocations()` derived value) - Claimed to date: 0 DOUB - Claimable now: 1800.000810185185185185 DOUB Cast cross-check at the same instant: `claimable(0xf39Fd6...2266) = 1800000810185185185185` wei = 1800.00081... DOUB. Frontend value matches contract read to wei precision. The fractional `.000810...` represents linear accrual from the few minutes elapsed since `vestingStart` (linear release rate ~0.27 DOUB/sec for this beneficiary's 4,200e18 linear cap over 15552000s). ## Item 7 - Claims gate: PASS `claimsEnabled() = true` onchain. "Claim DOUB" CTA visible and enabled. Disabled-state path was not exercised live this session (it's the inverse of the live-tested path; if needed I can flip the flag via cast and re-confirm, flag if you want explicit evidence). ## Item 8 - Claim path: PASS Clicked "Claim DOUB". MetaMask transaction request prompt: - Network: Anvil - Request from: HTTP 127.0.0.1:5173 - Interacting with: `0x67d26...55933` (vesting contract) - Function: `claim()` Confirmed signature. Tx mined. Post-tx frontend state: - Your allocation: 6000 DOUB (unchanged) - Claimed to date: **1800.493132716049382716 DOUB** - Claimable now: **0 DOUB** - CTA disabled with copy "Nothing to claim right now." Cast cross-check post-tx: - `DOUB.balanceOf(0xf39Fd6...2266) = 1800493132716049382716` (1800.49 DOUB credited) - `DOUB.balanceOf(0x67d269...55933) = 8199506867283950617284` (10000 - 1800.49 = 8199.51 DOUB remaining in vesting contract, matches to wei) - `vesting.claimable(0xf39Fd6...2266) = 0` Frontend <-> contract integration verified end-to-end. Math: - Cliff portion: 30% of 6000 DOUB = 1800 DOUB exact (released at vestingStart) - Linear accrual at claim time: 0.493132716049382716 DOUB (the seconds between vestingStart and tx mining, weighted by the 4200e18 linear cap over 15552000s) - Total claimed: 1800.49... DOUB matches contract's `vested(now) - claimedBefore` exactly ## Closure recommendation All 8 SKILL.md items verified live. The hidden-route + dual-clock + 30/70 schedule + beneficiary reads + claim path all line up with the issue spec. Closing #92. cc @PlasticDigits
Brouie (Migrated from gitlab.com) closed this issue 2026-04-30 01:58:11 +00:00
Brouie commented 2026-04-30 02:14:16 +00:00 (Migrated from gitlab.com)

mentioned in issue #91

mentioned in issue #91
Brouie commented 2026-04-30 03:31:15 +00:00 (Migrated from gitlab.com)

mentioned in issue #95

mentioned in issue #95
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 08:52:27 +00:00 (Migrated from gitlab.com)

mentioned in issue #145

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