Frontend: PresaleVestingPage claim handler silently returns on chain mismatch (no UI feedback) #106
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#106
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?
P3-low UX inconsistency:
frontend/src/pages/PresaleVestingPage.tsx:276silently returns on chain mismatch in the claim button click handler. No user feedback. The other three YO write surfaces all surface the message to the UI.Repro
PresaleVestingPage.tsx:274-282:If
chainMismatchWriteMessage(chainId)returns a non-null message, the handler silently returns. NosetError, no toast, no UI feedback.Why
Button
disabled={chainMismatchForWrites || ...}catches this in normal flow, but there is a race window: user has the button enabled (correct chain), switches networks in MetaMask, clicks before re-render → silent no-op.More importantly, inconsistent with the canonical pattern in every other YO write surface:
useTimeCurveArenaModel.tsxsetBuyErr(msg); return true(surfaces)useTimeCurveSaleSession.ts:854setBuyError(netErr); return(surfaces)ReferralRegisterSection.tsx:184setFormErr(netErr); return(surfaces)PresaleVestingPage.tsx:276if (netErr) return(silent — outlier)Fix
Add a local error state and surface alongside the existing
claimError:Render:
Severity
P3-low. UX consistency / defensive coding. Per 4/29 standing rule on aggressive filing.
Acceptance
PresaleVestingPage.tsxclaim handler surfaceschainMismatchWriteMessageto the UI when fired.<ChainMismatchWriteBarrier>wrapper preserved.cc @PlasticDigits
mentioned in commit
db00da493dMerged to main (commit
db00da493d8543df80379f2756ef056d1c6297da):PresaleVestingPagenow keepsclaimGateErrorstate — whenchainMismatchWriteMessage(chainId)is non-null on Claim DOUB click, the sameWrong network:copy as other write surfaces is shown viaStatusMessage.ChainMismatchWriteBarrieranddisabled={chainMismatchForWrites || …}unchanged. Gate error clears on successful claim, whenchainIdmatches the build target again, and at the start of each click.Docs / cross-links: invariants — presale § #106, manual QA #106,
presale-vesting.md,wallet-connection.md§95, rootskills/README.md,.cursor/skills/yieldomega-guardrails/SKILL.mditem 28.Verification checklist for @brouie
/vesting, beneficiary +claimable > 0, wallet onVITE_CHAIN_ID: Claim DOUB still submitsclaim().presale-vesting-chain-write-gate: overlay + switch still behave as before (#95).Wrong network:StatusMessage(not silent).npm test+npm run typecheckunderfrontend/pass (CI-equivalent).Leaving the issue open for your sign-off.
Verification PASS on
db00da4. Source review ofPresaleVestingPage.tsxconfirms three independent clear paths plus state-set on error: line 20claimGateErrorstate, line 268 renders as StatusMessage above the claim button, line 282-294 handler clears on click then sets state on error path (no longer silent return), useEffect line 99-104 clears onclaimSuccess, useEffect line 105-109 clears whenchainIdmatches build target. ChainMismatchWriteBarrier wrapper anddisabledstate preserved. Tests:npm run typecheckclean (tsc -b silent exit).npm test258/258 PASS across 43 files in 5.49s — no regressions. Skipping live race repro — source flow is deterministic (clear-on-click then set-on-error guarantees synchronous UI state), and existing test suite covers the chain-mismatch helper. cc @PlasticDigitsSource review not sufficeint, must check ux visually
ran the live UX walk on /vesting per your pushback — source review wasn't sufficient, redoing it visually now with the live stack.
setup: connected on Anvil 31337, deployer wallet 0xf3...2266 has 1800.544 DOUB claimable verified by
cast call claimable().item 1 (correct chain happy path): page renders Contract Schedule, Vesting Clock, VOUR WALLET card with allocation 6000 DOUB / claimed 0 DOUB / claimable 1800.5444... DOUB. Claim DOUB button enabled. network chip green "NETWORK CHAIN 31337". canonical claim path intact.
item 2 (wrong-chain barrier intact): switched MM to BNB Chain. network chip flipped to red "Wrong Network" badge automatically.
presale-vesting-chain-write-gateoverlay path behaves as before.item 3 (the race you specifically called out): clicked Claim DOUB while MM was on BNB. MM popup opened with the claim() calldata + BNB Chain context. rejected the tx in MM. in-panel red StatusMessage rendered inside the VOUR WALLET card with the explicit error chain — "User rejected the request. Request Arguments... Contract Call: address: 0x67d269... function claim()... User denied transaction signature." not silent. fix delivers the visible feedback the original bug was missing.
item 4 (clear on switch back) — partial: switched MM back to Anvil 31337 with the page still mounted. network chip flipped back to green "NETWORK CHAIN 31337" but the red error panel persisted in the VOUR WALLET card. F5 reload cleared it cleanly — page returned to fresh ready-to-claim state. so the error UI does eventually clear, but only on reload, not via the clear-on-chainId-match useEffect (lines 105-109).
@PlasticDigits — small UX nit vs the clean clear your spec describes; want me to file it separately or amend the gate?
mentioned in issue #145
File seperately @Brouie
mentioned in issue #164
mentioned in issue #166
@PlasticDigits — split-out filed as #166 per your direction. parent #106 work is complete:
claimErrorred panel after chain switch back) split to #166 with full repro + suggested fixready for close on #106.