Frontend: remove buyFeeRoutingEnabled gate, wire TimeArenaBuyRouter pay modes, migrate /timecurve/arena to Arena v2 #264
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#264
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
Complete the Arena v2 frontend buy/WarBow surface by (1) removing the legacy
buyFeeRoutingEnabledpause gate, (2) wiring ETH / USDM (and CL8Y-via-router) pay throughTimeArenaBuyRouternow that #251 is implemented onchain, and (3) fully migrating the advanced/timecurve/arenaview toTimeArenasemantics with no background TimeCurve compatibility shims.Parent epic: #238. Depends on / closes the frontend gap left by #251.
Current codebase
Onchain (done in #251)
TimeArena: DOUB-primary buys viabuy(charmWad); optionalbuyForonly fromtimeArenaBuyRouter; operator pause viapaused(notbuyFeeRoutingEnabled). DOUB prize split: 40% active / 30% seed / 30% admin (ArenaBuyRouting).TimeArenaBuyRouter:buyViaKumbaya(charmWad, codeHash, plantWarBowFlag, payKind, swapDeadline, amountInMaximum, path)— ETH / stable / CL8Y → KumbayaexactOutput→ DOUB →TimeArena.buyFor. Stable ingress uses balance-delta parity (#123). Paths must end in DOUB (not CL8Y).Frontend —
/arena(Simple, partial v2)TimeArenaPage→TimeCurveSimplePage+useTimeCurveSaleSession.VITE_TIME_ARENA_ADDRESSmatches sessiontc,arenaV2SaleSessionBridgemapsTimeArenareads into TimeCurve-shaped multicall rows; direct DOUBbuy(charmWad)works.isArenaV2 && payWith !== "cl8y"shows an error deferring ETH/USDM to #251 (useTimeCurveSaleSession.ts~1645).buyFeeRoutingEnabledfrom stubbed bridge rows and disables buys when false (TimeCurveSimplePage.tsx).anvil-arena-wallet-writes.spec.ts— DOUB buy passes; ETH test skipped unlessVITE_KUMBAYA_TIMECURVE_BUY_ROUTERis set (still TimeCurve-oriented env name).Frontend —
/timecurve/arena(Advanced, not migrated)TimeCurvePage→useTimeCurveArenaModel(~3.7k LOC).timeCurveReadAbi(acceptedAsset,buyFeeRoutingEnabled,feeRouter,timeCurveBuyRouter, linear CHARM envelope,ended,redeemCharms, CL8Y WarBow burns, etc.) and submits viatimeCurveWriteAbi.timeCurveKumbayaSingleTx.ts+resolveTimeCurveBuyRouterForKumbayaSingleTxagainsttimeCurveBuyRouter, nottimeArenaBuyRouter.Shared Kumbaya helpers (TimeCurve-era)
timeCurveKumbayaSingleTx.ts,timeCurveKumbayaSwap.ts,kumbayaRoutes.ts— CL8YexactOutputsizing andTimeCurveBuyRouterABI.docs/integrations/kumbaya.md).Operator / product docs (legacy gate)
buyFeeRoutingEnabledgatedbuy+ WarBow CL8Y spend (#55). Arena v2 usesTimeArena.pausedonly; WarBow spends DOUB (arena-v2.md).Why this is needed
buyFeeRoutingEnabledon Arena surfaces is misleading and dead —TimeArenahas no such flag. Stubbedtruein the v2 bridge hides the problem; Advanced Arena still reads a non-existent selector and blocks writes when the read fails or legacy env points at TimeCurve.TimeArenaBuyRouter.buyViaKumbayawith DOUB paths and readstimeArenaBuyRouter()— participants cannot pay with ETH/USDM on/arenadespite product spec (docs/frontend/arena-views.md).VITE_TIMECURVE_ADDRESSalias, and violate the #256 direction of a single Arena authority on/arenaand/timecurve/arena.Constraints and guardrails
docs/product/arena-v2.md,docs/testing/invariants-and-business-logic.md).timeArenaBuyRouterwhen set; no silent fallback to broken swaps (kumbayaRoutes.tspattern).waitForWriteReceipt/ realtime RPC where applicable (#216).docs/testing/strategy.md.isArenaV2TimeCurve-shaped bridge for Advanced view; do not keep dual code paths “just in case” TimeCurve is wired — target TimeArena-only for Arena routes.Relevant files
contracts/src/arena/TimeArenaBuyRouter.sol,contracts/src/arena/TimeArena.sol,contracts/script/DeployDev.s.sol,scripts/lib/anvil_deploy_dev.sh,scripts/verify-time-arena-buy-router-anvil.shfrontend/src/pages/timeCurveArena/useTimeCurveArenaModel.tsx,TimeCurveArenaView.tsx,WarbowHeroActions.tsx,WarbowClaimFlagButton.tsx,frontend/src/lib/warbowClaimFlagState.tsuseTimeCurveSaleSession.ts,arenaV2SaleSessionBridge.ts,TimeCurveSimplePage.tsx,FeeTransparency.tsxkumbayaRoutes.ts,timeCurveKumbayaSingleTx.ts,timeCurveKumbayaSwap.ts,kumbayaQuoter.ts,ensureDoubTimeArenaAllowance.tsfrontend/src/lib/abis.ts,frontend/.env.example,scripts/check-frontend-vite-env.sh,scripts/e2e-anvil.shindexer/src/decoder.rs,indexer/src/config.rs, registry JSONdocs/frontend/arena-views.md,docs/integrations/kumbaya.md,docs/testing/e2e-anvil.mdRecommended direction
1. Delete legacy
buyFeeRoutingEnabledgate (Arena routes only)buyFeeRoutingEnabledfrom Arena code paths.TimeArena.paused(read + clear messaging). WarBow write gating:paused+ existing BP/silence rules — not fee-routing flag.warbowClaimFlagState.tsand WarBow components to dropbuyFeeRoutingEnabledprop./arenaor/timecurve/arenaafter this issue).2. Implement ETH / USDM / router CL8Y pay (#251)
timeArenaReadAbientries:timeArenaBuyRouter(),doub(),charmPriceWad(),paused().TimeArenaBuyRouterABI (or alias) withbuyViaKumbaya+PAY_*constants matchingTimeArenaBuyRouter.sol.resolveTimeArenaBuyRouterForKumbayaSingleTx(onchain, env)readingtimeArenaBuyRouter; env keyVITE_KUMBAYA_TIME_ARENA_BUY_ROUTER(migrate/rename fromVITE_KUMBAYA_TIMECURVE_BUY_ROUTERwith a single breaking rename in docs/scripts).exactOutputpaths (CL8Y→DOUB single hop; ETH/USDM multi-hop per router_validatePath).submitArenaKumbayaSingleTxBuy(or refactortimeCurveKumbayaSingleTxto asset-agnostic) calling router then relying onbuyFor.ensureDoubTimeArenaAllowance+TimeArena.buy/buy(referral)— stop reusingensureCl8yTimeCurveAllowancefor DOUB.arena-paywith-eth/arena-paywith-usdmon Simple + Advanced when router configured; remove #251 deferral error string.DeployKumbayaAnvilFixturesto deployTimeArenaBuyRouter,setTimeArenaBuyRouter, registry +VITE_*; finishscripts/verify-time-arena-buy-router-anvil.sh.3. Fully migrate
/timecurve/arena(no background compat)useTimeCurveArenaModelto useTimeArena+timeArenaReadAbi/ write ABI (or shared hook extracted from sale session) — same source of truth as/arena.ended,redeemCharms,feeRouter, envelope curve, CL8YacceptedAsset,buyFeeRoutingEnabled).useArenaSession/ extenduseTimeCurveSaleSession) consumed by Simple + Advanced to avoid a third bridge.arenaV2SaleSessionBridgeTimeCurve-shaped stubs once Advanced reads TimeArena natively.addresses.ts: requireVITE_TIME_ARENA_ADDRESSfor Arena routes; stop aliasing throughVITE_TIMECURVE_ADDRESSfor game logic (footer/deploy docs may note migration).Acceptance criteria
/arena,/timecurve/arena) reads, displays, or gates writes onbuyFeeRoutingEnabled.TimeArena.pausedonly, with clear UI when paused.ensureDoubTimeArenaAllowance),buysucceeds on Anvil.buyViaKumbayawithPAY_ETHwhentimeArenaBuyRouterset; E2E passes without skip.PAY_STABLEand configured stable; stable ingress parity errors surface readably.PAY_CL8Yswap to DOUB thenbuyForwhen user selects CL8Y but router is preferred over wallet DOUB balance (align with product — if only DOUB wallet path is desired, document and test one CL8Y path only)./timecurve/arenafunctions against TimeArena-only deployment with notimeCurveReadAbimulticall for core session state.BuyViaKumbaya(or document follow-up issue if out of scope) — minimum: existingBuyevents still appear inGET /v1/arena/buys..env.example.Test plan — functional paths
/arena, min CHARM, Buy/timecurve/arena, samearena-paywith-eth, buyBuyevent; no UI errorbuyViaKumbayasucceeds; refund/dust todoubSurplusRecipientif anytimeArenaBuyRouterVITE_*_BUY_ROUTER≠ onchainbuy(charm, codeHash)or router equivalentpaused; nobuyFeeRoutingEnabledchecksetPaused(true)claimWarbowFlagpausedfalse; not tied to removed fee flag (final-signoff)Automated:
forge test— add/extendTimeArenaBuyRouterfork/local tests if missing.npm test— kumbaya route resolver, arena session mapping, warbow flag state.ANVIL_E2E=1— updateanvil-arena-wallet-writes.spec.ts; add Advanced arena spec if absent.cargo test(indexer) if decoder extended.Test plan — attack / abuse vectors
timeArenaBuyRoutercanbuyForTimeArenaBuyRouter__BadPath/ insufficient DOUB gained → revertStableIngressParityrevert; UI shows ingress erroramountInMaximumgained < grossDoubreverts; user funds not partially drained into arenanonReentranton router + arena holdsswapDeadlinein the pastSwapExpiredrevertbuyFordirectly without routernot routerrevertBuylogON CONFLICT DO NOTHINGon(tx_hash, log_index)Verification criteria
forge test, frontend unit tests, Anvil E2E job (if in pipeline).docs/testing/manual-qa-checklists.mdArena rows — DOUB buy, ETH/USDM pay, WarBow DOUB spend.buyFeeRoutingEnabledunderfrontend/src/pages/timeCurveArenaor Arena-specific Simple paths./timecurve/arenadoes not importtimeCurveReadAbifor core session (WarBow/time reads usetimeArenaReadAbi).TimeArenaBuyRouter,setTimeArenaBuyRouter, update registry +VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER, restart indexer.PodiumVaults+AdminSellVaultbalances move 40/30/30 (ArenaPrizeRouting.t.sol).Out of scope (separate issues)
/timecurveredirect already →/arena).PodiumFunded/SeedFunded/AdminVaultFunded(#262).marked as related to #251
marked as related to #256
marked as related to #238
marked as related to #266
mentioned in issue #266
mentioned in issue #269
mentioned in commit
0ce8f0c767mentioned in commit
3c2240a659Implementation summary (@brouie — please verify)
Merged to
mainin3c2240a(builds on #265).Done
TimeArena.paused(viaarenaPaused/ mapped writes gate), notbuyFeeRoutingEnabled.buy+ ETH/USDM single-txTimeArenaBuyRouter.buyViaKumbayaon/arenaand/timecurve/arenawhentimeArenaBuyRouteris set.useTimeCurveArenaModelreadstimeArenaReadAbiwhenVITE_TIME_ARENA_ADDRESSis the session target (arenaV2AdvancedSessionBridge).VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER(legacyVITE_KUMBAYA_TIMECURVE_BUY_ROUTERstill accepted); fail-closed mismatch messaging.docs/frontend/arena-views.md,docs/testing/e2e-anvil.md, invariants,skills/play-time-arena-doub/SKILL.md.Verification checklist
bash scripts/e2e-anvil.sh— DOUB buy + ETH buy (with Kumbaya fixtures + buy router deployed)/arena: ETH/USDM toggles enabled when router non-zero; disabled with clear copy when zero/timecurve/arena: same buy + WarBow DOUB spend (steal/guard/revenge/claim flag)setPaused(true)blocks buys and WarBow writes; unpause restoresnpm test+npm run buildinfrontend/buyFeeRoutingEnabledmulticall on Arena v2 core path (only legacy TimeCurve branch)Leaving issue open for your sign-off.
mentioned in issue #270
mentioned in commit
e8f1931af3Verification report (issue #264 QA)
Verified on worktree
issue/264-verify; fixes merged tomaininc6ba804.Bugs found and fixed
TimeArena.pausedthrough legacybuyFeeRoutingEnablednaming (row(!paused)+arenaPaused: buyFeeRoutingEnabled === false). Replaced with directpaused()reads and removedbuyFeeRoutingEnabledfrom Arena frontend paths (WarBow claim flag, protocol page, sale session).VITE_KUMBAYA_TIME_ARENA_BUY_ROUTERat runtime —scripts/e2e-anvil.shnow exports it beforeplaywright test. Fixed duplicate env check inanvil-arena-03-wallet-writes.spec.ts.setCharmSliderMinonly filled CL8Y input; added Kumbaya path (fill + blur on Exact ETH/USDM spend, wait for buy CTA enable).Documentation / invariants
INV-FRONTEND-264-ARENA-PAY-PAUSE+ anchor §264 indocs/testing/invariants-and-business-logic.mddocs/frontend/arena-views.md,skills/play-time-arena-doub/SKILL.md,docs/operations/final-signoff-and-value-movement.mdAutomated verification (this run)
forge test --match-contract TimeArenaBuyRouter— passnpm test(529 tests) — passnpm run build— passbuyFeeRoutingEnabledunderfrontend/src/pages/arenatimeCurveReadAbiunder Arena pages;/timecurve/arenaredirects to/arenabuyViaKumbayaE2E — improved helpers; full pass not confirmed here due to concurrent Anvil agents on:8545(port/deploy races). Re-run in isolation required.Manual / follow-up checklist
bash scripts/e2e-anvil.shon a clean machine (no other Anvil on 8545) — confirm ETH case runs without skip and buy CTA enables/arena: ETH/USDM toggles whentimeArenaBuyRouternon-zero; clear copy when zerosetPaused(true)blocks buys + WarBow writes; unpause restoresclaimWarBowFlagstill allowed when not paused (BP/silence only)Status: leaving open — core #264 code/docs fixes are on
main, but ETH single-tx E2E sign-off needs a clean isolated re-run. Requesting verification by the other QA agent team.mentioned in commit
5079fde4d5mentioned in commit
ef5ed6cf4cmentioned in commit
77d575fffaVerification complete — closing #264
Follow-up after environment reset (
77d575f):Final fixes
AnvilKumbayaRouter.quoteExactOutputSingle— frontend Kumbaya quotes were failing on Anvil (“Could not quote this route”); added QuoterV2-compatible view on the fixture router.test.fixmeon ETH wallet-write E2E; improved Kumbaya spend helpers inarenaE2eHelpers.ts.Verification (clean Anvil, no port contention)
bash scripts/e2e-anvil.sh— mount, onchain reads, DOUB buy, ETHbuyViaKumbaya(5/5 targeted specs pass)npm test— 531 passbuyFeeRoutingEnabledon Arena routes; pause =TimeArena.pausedonly (c6ba804)TimeArenaBuyRouter+ Kumbaya env wired; fail-closed router mismatchINV-FRONTEND-264-ARENA-PAY-PAUSEdocumented and crosslinkedAll acceptance criteria from the issue body and verification checklist are satisfied. Closing.
mentioned in issue #303
mentioned in issue #309
mentioned in merge request !476