TimeCurve post-end UI: 'Already redeemed' panel doesn't show DOUB amount received; stake-at-launch numbers can confuse #90
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#90
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
After redeem-charms is executed, the post-end TimeCurve page shows the wallet's historical CHARM holdings + the worth-at-launch projection AS IF those CHARM are still claimable, even though they've already been redeemed for DOUB onchain. This is potentially confusing for users.
Repro
Observed
The "Your stake at launch" panel still shows:
The Settlement panel correctly shows "Already redeemed" (good!), but the stake-at-launch panel above it doesn't reflect that the redemption has occurred. A new user landing on the page in this state may not understand why the redeem path is locked or what they actually received.
Suggested copy / data improvements
Could be solved by either:
A. Add a "Redeemed: 1,000,000 DOUB" line to the Your-stake-at-launch panel when charmsRedeemed=true, derived from totalTokensForSale * charmWeight / totalCharmWeight at the time of redemption (or just from the wallet's DOUB balance at moment of view).
B. Replace the "WORTH AT LAUNCH" line with the actual DOUB amount received post-redeem.
C. Add a dimming / strikethrough effect on the worth-at-launch number when redemption has occurred, with a "(redeemed)" label.
D. Show a green checkmark + "Settled" pill or similar on the panel header when in already-redeemed state.
Severity
P3-low. UX clarity issue, not a functional bug. Already-redeemed protections work correctly at the contract layer (double-spend prevented, button disabled). Just a copy / data display polish.
Filed during #38 F-09 / #39 C6 verification today on the post-end stack pivot.
cc @PlasticDigits
mentioned in issue #39
mentioned in commit
b558ec1d86Implemented #90 on
main(options A, C, D). Option B rejected in-product: replacing “worth at launch” with DOUB-only copy is misleading because participant value is anchored in CL8Y terms while entry used CL8Y / ETH / USDM rails.What shipped
TimeCurveStakeAtLaunchSection: aftercharmsRedeemed, shows Redeemed · X DOUB from the same sale-allocation ratio asredeemCharms(expectedTokenFromCharmsinuseTimeCurveSaleSession).charmWeightstays onchain after redeem).actions.docs/frontend/timecurve-views.md§ stake redeemed, invariants § #90, play checklistskills/verify-yo-timecurve-stake-redeemed-ui/SKILL.md; VitestTimeCurveStakeAtLaunchSection.test.tsx.Verify checklist for @brouie
/timecurve: Your stake at launch shows Settled (check + badge) on the right of the section heading.totalTokensForSale × charmWeight ÷ totalCharmWeight(same as redeem tx / Protocol reads).Leaving issue open for your sign-off.
mentioned in issue #38
Verified
282eb62against all 5 SKILL.md acceptance items on the SKIP+KUMBAYA+NO_COOLDOWN stack today. Closing.Stack state for verification
282eb620xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266(Anvil acct #0)endSale()(status 1, SaleEnded event),charmRedemptionEnabled()=trueredeemCharms()from deployer (status 1, tx0x08babc72...)charmsRedeemed(deployer) = truecharmWeight(deployer) = 5e18(preserved post-redeem per B4 contract semantics)TimeCurve.launchedToken() = 0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1DOUB.balanceOf(deployer) = 1000000000000000000000000(1e24 wei = 1,000,000 DOUB)totalTokensForSale × charmWeight ÷ totalCharmWeight = 1e24 × 5e18 ÷ 5e18 = 1e24(deployer owns 100% of charm weight, redeems 100% of launch supply)Item 1 - Settlement panel "Already redeemed": PASS
Loaded
/timecurve(Simple page) with deployer wallet connected. Settlement section reads:CTA correctly transitions to "Already redeemed" post-redemption (existing behavior preserved).
Item 2 - Settled badge in "Your stake at launch" section header: PASS
Section heading "Your stake at launch" renders a "Settled" badge in the right-side actions area (per the
section-heading__actionsCSS hook noted in the SKILL.md). Settled label visible alongside the section title.Item 3 - Redeemed row shows DOUB amount: PASS
The redeemed row renders:
Abbreviated display of 1,000,000 DOUB. Matches onchain
DOUB.balanceOf(deployer) = 1e24 weiexactly. The integer-division math from the contract (totalTokensForSale × charmWeight ÷ totalCharmWeight) maps cleanly to the rendered value: 1M DOUB credited for 100% of the charm weight in this fresh-stack scenario.Item 4 - Worth at launch struck-through with (redeemed) label: PASS
The historical CL8Y projection renders with strike-through and explicit qualifier:
The CL8Y-at-launch figure (5 CHARM × 1.324 CL8Y/CHARM ≈ 6.62 CL8Y) stays visible as context but is visually marked as historical. The "(redeemed)" qualifier appears immediately before the strike-through value. NOT replaced by DOUB-only copy — exactly the option-B rejection dev called out in the close note.
Plus the section subtitle reinforces the framing:
This addresses the original #90 confusion concern: stake-at-launch numbers no longer mislead the user post-redemption because the CL8Y projection is clearly historical, the actual DOUB received is surfaced explicitly, and the copy explains why both are shown.
Item 5 - data-testid="timecurve-simple-stake-redeemed-doub" (optional): NOT EXERCISED
Marked optional in the SKILL.md, skipping live DevTools inspection. Items 1-4 cleanly verified.
Frontend <-> contract integration check
Sale-side reads all consistent with cast cross-checks:
charmWeight(deployer) = 5e18DOUB.balanceOf(deployer) = 1e245 CHARM × 1.324 CL8Y/CHARM at launchper the linear price helperClosure recommendation
All required SKILL.md items verified live. The post-redeem stake panel correctly preserves historical context (CL8Y projection retained for transparency, struck through to mark settlement) while surfacing the actual DOUB received as the primary settled value. Closing #90.
cc @PlasticDigits
mentioned in issue #100