[#138] Finding 5: Frontend — reduce maxUint256 approvals (H-01 blast radius) #143
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#143
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?
Parent: Split from #138 — Pre-deploy review pass 2 (Finding 5).
Severity: Low–Medium (risk coupling to audit H-01 — compromised upgrade reusing allowances)
Problem
The frontend issues
maxUint256infinite ERC20 approvals in nine places across buy / Kumbaya / referral flows. Combined with audit H-01 (malicious upgraded TimeCurve could drain existing CL8Y allowances), infinite approval amplifies blast radius from “amount in flight” to full wallet balance for repeat visitors. NorevokeApprovalUX, no exact-amount default.References
frontend/src/pages/timeCurveArena/useTimeCurveArenaModel.tsx— WETH/USDM → SwapRouter; CL8Y → TimeCurvefrontend/src/pages/timecurve/useTimeCurveSaleSession.tsfrontend/src/pages/referrals/ReferralRegisterSection.tsxfrontend/src/lib/timeCurveKumbayaSingleTx.tsaudits/— H-01 (proxy upgrade + allowance reuse); cross-link in issuedocs/integrations/kumbaya.mddocs/testing/invariants-and-business-logic.md— buy router / Kumbaya rows.cursor/skills/yieldomega-guardrails/SKILL.md(TimeCurve / Kumbaya)Recommended fix
approve(spender, exactAmount)(may require one approval per buy; wallet UX copy should say so).Acceptance criteria
maxUint256as sole path for first-time users; exact-amount default or explicit opt-in documented in UI.Verification checklist
mentioned in issue #138
mentioned in commit
49c758bc81mentioned in commit
179c621ed6mentioned in commit
e7afcf4d77Status: merged to
main(commit range ending at currentorigin/main)What shipped
approveamounts for Kumbaya router legs (slippage-boundedmaxIn), ReferralRegistry (registrationBurnAmount), and CL8Y → TimeCurve forbuy/ WarBow flows.Cl8yTimeCurveUnlimitedApprovalFieldset+localStoragekeyyieldomega.erc20.cl8yTimeCurveUnlimited.v1, with H-01 disclosure in UI/docs.guardBuySession()still runs;approveAmtcomes fromcl8yTimeCurveApprovalPreference(cl8yTimeCurveApprovalAmountWei+readCl8yTimeCurveUnlimitedApproval).docs/frontend/wallet-connection.md,docs/testing/invariants-and-business-logic.md(INV-ERC20-APPROVAL-143),docs/integrations/kumbaya.md,docs/frontend/timecurve-views.md,.cursor/skills/yieldomega-guardrails/SKILL.md,skills/README.md,skills/play-timecurve-doubloon/SKILL.md.How to verify
cd frontend && npm ci && npm test -- --run— includescl8yTimeCurveApprovalPreference.test.ts.approvetx: spender = TimeCurve proxy, amount = exact gross for that buy (notmaxUint256).approveusestype(uint256).maxfor CL8Y→TimeCurve; disable toggle does not revoke onchain (documented).maxIn-bounded per quote (not silent unlimited on router legs)./referralsregister burn:approvematchesregistrationBurnAmountexactly.cc @brouie for sign-off when convenient.
Issue left open per process — close when you’re satisfied.
mentioned in commit
838a2c1e9b@PlasticDigits — verification PASS on the approval-sizing rework. walked your checklist:
npx vitest run cl8yTimeCurveApprovalPreferencegreen: 3/3 PASS — covers default-needWei branch, opt-in unlimited branch, and storage round-trip.2-6. runtime smoke (live wallet walk + cross-browser + screen reader copy) skipped this round — no localnet stack up. source verified end-to-end:
cl8yTimeCurveApprovalPreference.tsL41-45: returnsneedWeiby default,maxUint256only when localStorage flag (yieldomega.erc20.cl8yTimeCurveUnlimited.v1) is opted in.useTimeCurveSaleSession.tsL1066-1075: CL8Y→TimeCurve approval sized viacl8yTimeCurveApprovalAmountWei(amount, readCl8yTimeCurveUnlimitedApproval()). default flow approves exactly the buy spend.timeCurveKumbayaSingleTx.tsL90, L102-107:maxIn = swapMaxInputFromQuoted(qIn, KUMBAYA_SWAP_SLIPPAGE_BPS), conditional approve only if existing allowance belowmaxIn, approval is exactlymaxIn(slippage-bounded, not unlimited).ReferralRegisterSection.tsxL106: readsregistrationBurnAmountfrom registry, sized exactly per spec.Cl8yTimeCurveUnlimitedApprovalFieldset.tsxexposes the opt-in checkbox with H-01 disclosure copy.maxUint256no longer appears in any of the buy/Kumbaya/referral hot paths outside the explicit opt-in helper. that's the key invariant. H-01 blast radius reduced from 'full balance forever' to 'amount in flight per buy' for default users.INV-ERC20-APPROVAL-143 + cross-links in wallet-connection.md / kumbaya.md / timecurve-views.md / guardrails read cleanly.
ready for close on your side.
mentioned in commit
32cf66eebbmentioned in commit
8731db1f1cmentioned in issue #224
mentioned in issue #262
mentioned in issue #263
mentioned in issue #277
mentioned in issue #325
mentioned in issue #341