Arena player progression: XP/level cap (5), feature unwrapping, onboarding UX #299

Closed
opened 2026-06-07 07:50:08 +00:00 by PlasticDigits · 14 comments
PlasticDigits commented 2026-06-07 07:50:08 +00:00 (Migrated from gitlab.com)

Summary

Introduce player progression as a primary Arena pillar: cap levels at 5, gate podium mechanics behind level unlocks (“unwrapping”), surface XP/level prominently in the UX, and tune first-buy onboarding so two starter buys teach the loop and reach level 2.

Parent epic: #238. Related: #250 (XP math), #265 (buy-path XP), #268 (first-buy CRED), #256 (unified /arena).


Current codebase

Onchain (TimeArena)

  • XP / level — ArenaXp.sol: charm maps to 1–10 XP per buy; level thresholds min(20 + (L-1)*5, 100); uncapped level via _cachedLevel + xpTowardNext (#265).
  • Every qualifying buy in _finishBuy extends all four podium deadlines (_extendOtherPodiumTimers), updates Time Booster totals, Defended Streak, WarBow BP, and may plant/cancel flags — no per-player gating today.
  • WarBow flags — any buyer can pass plantWarBowFlag; buys from a new leader cancel pending flags immediately (_maybePlantWarBowFlag).
  • First buy — FIRST_BUY_CRED_BONUS = 150e18 scheduled in epochFixedCredBonus[lastBuyEpoch+1] (#268); not tuned for “second buy free + level 2” onboarding.
  • Level views — level(user), xp(user), xpToNextLevel(user).

Frontend

  • XP appears in wallet profile modal only (WalletProfileXpSection); not a primary /arena hero element.
  • Buy preview (arenaBuyProjectedEffects.ts) assumes full mechanics (timer, streak, WarBow BP, flags) for every connected wallet.
  • No “Locked until Level X” affordances or first-unlock mechanic popovers.

Indexer

  • Wallet stats API exposes level / xp (#255); no unlocked_features or feature_tutorial_seen persistence yet.

Product spec


Why this is needed

New players currently land in a fully unlocked arena: one buy moves four independent timers, WarBow scoring, streak logic, and flag PvP simultaneously. XP/level is a secondary stat buried in the wallet modal.

Progressive unwrapping teaches mechanics one podium at a time, reduces early cognitive load, and makes leveling a core retention loop. Capping at level 5 gives a clear mastery arc. First-buy CRED tuning ensures the onboarding path is self-funding through level 2 without whale assumptions.

Note: Prize DOUB routing to all podiums regardless of unlock state is specified in the companion issue (100% epoch-weighted podium funding). This issue covers player-scoped buy effects and UX only.


Constraints & guardrails

  1. Onchain authority — level gates for timer extension, scoring hooks, WarBow actions, and flag cancel/plant must be enforced in TimeArena (not UI-only). Indexer/frontend are derived.
  2. AGPL-3.0 — all new Solidity/TS/Rust under repo license.
  3. UUPS append-only — new per-wallet mappings (featureTutorialSeen, etc.) must be append-only for upgrade safety.
  4. XP independence — timer hard-reset / lastBuyEpoch roll must not reset level, xpTowardNext, or lifetime xp (#250).
  5. Buy-path gas — retain O(1) applyXpGain; max 5 level-ups per buy (#265).
  6. Level cap — MAX_PLAYER_LEVEL = 5; XP may still accrue but level stops at 5 (define overflow behavior: bank XP vs discard — recommend bank for future cap raises).
  7. Global vs player scope — other players’ buys always run full mechanics; only the buyer’s level gates their buy side effects.
  8. Prize funding — buys still fund all podium vaults (companion routing issue); locked UI must not imply “your buy doesn’t fund the arena.”
  9. CRED buy path — buyWithCred participates in XP/level and first-buy bonus per #268; level gates apply equally.
  10. Do not reintroduce retired v1 surfaces (#241–#244).

Level unlock matrix

Level Unlocks Player buy effects
1 (start) Last Buy podium only Extends Last Buy timer only; Last Buy scoring only; no Time Booster / Streak / WarBow / flags
2 Time Booster + extends Time Booster deadline; Time Booster leaderboard scoring
3 Defended Streak + streak processing
4 WarBow + WarBow BP; steal/guard/revenge (existing costs)
5 Flag plant & disruption + plantWarBowFlag; buys can cancel/replace pending flags

Until level 5: player buys must not cancel or replace warbowPendingFlagOwner (other players still can).

Locked UI copy: Locked until Level {N} + lock icon on gated controls/sections.

Mechanic popover: On first unlock (or help ? button), show a modal/popover explaining that feature’s rules (reuse play-skill copy where possible: skills/play-active-time-arena, skills/play-time-arena-warbow).


First-buy onboarding (tune constants)

Goal: First buy ever (per wallet, buyCount == 0 before increment) grants enough bonus CRED to afford a second buy at the same CHARM, plus ~10% headroom, and two buys at the recommended starter CHARM yield ≥ 20 XP (level 2 threshold).

Current: fixed 150 CRED (#268).

Recommended direction:

  • Define a documented starter CHARM (e.g. min band 0.99e18 or product-chosen default on /arena).
  • Set FIRST_BUY_CRED_BONUS (or formula: credBurn(firstBuyCharm) * 1.10) so claimable CRED covers second buyWithCred at same charm + 10%.
  • Verify xpForCharm(starter) * 2 >= xpToAdvance(1) (20 XP); adjust starter charm hint or bonus XP event if needed (prefer charm/CRED tuning over special-case XP grants).
  • Update verify-cred-buy-anvil.sh and invariants §268.

Relevant files

Layer Files
Contracts TimeArena.sol, ArenaXp.sol, ArenaPodiumTimerConfig.sol
Tests TimeArena.t.sol, ArenaXp.t.sol
Frontend ArenaSimplePage.tsx, ArenaSections.tsx, ArenaTimerChips.tsx, ArenaWarbowHeroPanel.tsx, arenaBuyProjectedEffects.ts, arenaXpMath.ts, WalletProfileModalSections.tsx
Indexer arena_wallet_stats.rs, api_arena.rs
Docs arena-v2.md, arena-views.md, invariants-and-business-logic.md
Verify verify-cred-buy-anvil.sh, verify-wallet-profile-anvil.sh, e2e-anvil.sh

Contracts

  1. Add MAX_PLAYER_LEVEL = 5 in ArenaXp; clamp in applyXpGain / level view.
  2. Add function _playerLevel(address) internal view and branch _finishBuy:
    • Level ≥ 1: Last Buy timer + _trackLastBuyer (always).
    • Level ≥ 2: _extendOtherPodiumTimers for cat 1 only (not all secondary podiums at once).
    • Level ≥ 3: extend cat 2 + _processDefendedStreak.
    • Level ≥ 4: extend cat 3 + _applyBuyWarBowBp.
    • Level ≥ 5: flag plant/cancel path in _maybePlantWarBowFlag.
  3. Gate warbowSteal / warbowActivateGuard / warbowRevenge at level ≥ 4.
  4. Emit LevelUp / FeatureUnlocked events for indexer + UX (optional XpGained enrichment).
  5. Retune FIRST_BUY_CRED_BONUS per onboarding math.

Frontend

  1. XP hero on /arena (level badge, progress bar to next level, XP gained on buy toast).
  2. Per-section lock overlays on Time Booster, Streak, WarBow, flag UI.
  3. FeatureMechanicModal — localStorage or indexer-backed “seen” + first-unlock trigger.
  4. Buy preview filters projected effect lines by effective player level (read chain level).

Indexer

  1. Decode new events; expose level, xp_toward_next, optional unlocked_level on wallet stats.
  2. Optional: POST not needed — persist tutorial seen client-side unless cross-device required.

Acceptance criteria

  • level capped at 5 onchain and mirrored in frontend/indexer.
  • Level-1 wallet buy extends only Last Buy timer; no secondary podium deadline changes from that wallet’s buy.
  • Level-2+ unlocks match matrix above; verified per level in Forge.
  • Level < 5 wallet cannot cancel/replace pending WarBow flag via buy; level ≥ 5 can.
  • Level < 4 wallet cannot call WarBow steal/guard/revenge.
  • Locked controls show lock icon + Locked until Level N.
  • First unlock (and help button) opens mechanic explainer popover/modal.
  • XP/level is visible on main /arena view without opening wallet profile.
  • First-buy CRED bonus + recommended starter path: two buys → level ≥ 2 and second buy affordable via CRED (incl. ~10% headroom).
  • buyWithCred respects same gates and XP cap.
  • Docs + invariants updated with INV-ARENA-PROGRESSION-* rows.
  • Existing whales / high buyCount wallets: define migration (grandfather full unlock at level 5 if buyCount > 0 or recompute level from XP — product decision, document in issue/MR).

Test plan (functional paths)

Path Layer Command / evidence
XP cap + level-up clamp Contracts forge test --match-contract ArenaXp + new TimeArena level-cap tests
Per-level timer gating Contracts forge test --match-test test_level_*_gates_timers in TimeArena.t.sol
Per-level WarBow/flag gating Contracts forge test --match-test test_level_*_warbow
First-buy CRED onboarding Contracts + script bash scripts/verify-cred-buy-anvil.sh (extend assertions)
Frontend XP hero + locks Frontend npm run typecheck && npm run lint && npm test
Lock copy + popover Frontend component tests + arena.spec.ts / anvil-arena-*.spec.ts
Buy preview by level Frontend arenaBuyProjectedEffects.test.ts cases per level
Indexer level field Indexer cargo test + verify-wallet-profile-anvil.sh
E2E buy at level 1 vs 5 Playwright bash scripts/e2e-anvil.sh (mock wallet; level state via Anvil impersonation / pre-seeded buys)
Manual QA Rabby Level 1 connect → buy → only Last Buy timer moves; level-up → new section unlocks

Test plan (attack / abuse / edge vectors)

Vector Expected behavior Test
UI bypass — call buy(plantWarBowFlag=true) at level < 5 Tx reverts or flag ignored onchain Forge test_level4_buy_plant_flag_reverts
UI bypass — WarBow steal at level < 4 Revert TimeArena: level (or equivalent) Forge
Level-up mid-block / same tx Gates use post-XP level from same _finishBuy Forge multi-level-up in one buy
Whale sybil — fresh wallet to avoid gates Expected; gates are per-wallet progression Document as accepted
First-buy bonus farming — transfer wallet buyCount / first-buy keyed to address; no reset on hard-reset Forge + existing §268 tests
CRED burn without DOUB — skip prize but gain XP buyWithCred still levels; no double-dip on DOUB routing Forge
Reentrancy on level-gated external calls nonReentrant preserved Forge
Indexer lies about level Frontend write paths use onchain level for tx building Integration test
Popover spam / localStorage clear Re-show on help only after seen flag Frontend test
Grandfathering exploit — reset level via upgrade bug UUPS storage layout review + _disableInitializers Manual + storage gap
Griefing — max-level player cancels flags Allowed by design at level 5 Play skill regression

Verification criteria (merge gate)

Check Command PASS when
Contracts cd contracts && forge test All new + existing tests green
Indexer cd indexer && cargo clippy --all-targets -- -D warnings && cargo test Green
Frontend cd frontend && npm run typecheck && npm run lint && npm test Green
CRED onboarding bash scripts/verify-cred-buy-anvil.sh Extended script PASS
Wallet profile bash scripts/verify-wallet-profile-anvil.sh Level cap reflected
Doc gates bash scripts/check-doc-anchors.sh PASS
E2E (if UI touched) bash scripts/e2e-anvil.sh PASS or documented scope skip
## Summary Introduce **player progression** as a primary Arena pillar: cap levels at **5**, gate podium mechanics behind level unlocks (“unwrapping”), surface XP/level prominently in the UX, and tune **first-buy onboarding** so two starter buys teach the loop and reach **level 2**. Parent epic: [#238](https://gitlab.com/PlasticDigits/yieldomega/-/issues/238). Related: [#250](https://gitlab.com/PlasticDigits/yieldomega/-/issues/250) (XP math), [#265](https://gitlab.com/PlasticDigits/yieldomega/-/issues/265) (buy-path XP), [#268](https://gitlab.com/PlasticDigits/yieldomega/-/issues/268) (first-buy CRED), [#256](https://gitlab.com/PlasticDigits/yieldomega/-/issues/256) (unified `/arena`). --- ## Current codebase ### Onchain (`TimeArena`) - **XP / level** — [`ArenaXp.sol`](contracts/src/arena/libraries/ArenaXp.sol): charm maps to **1–10 XP** per buy; level thresholds `min(20 + (L-1)*5, 100)`; **uncapped** level via `_cachedLevel` + `xpTowardNext` ([#265](https://gitlab.com/PlasticDigits/yieldomega/-/issues/265)). - **Every qualifying buy** in `_finishBuy` extends **all four** podium deadlines (`_extendOtherPodiumTimers`), updates Time Booster totals, Defended Streak, WarBow BP, and may plant/cancel flags — **no per-player gating** today. - **WarBow flags** — any buyer can pass `plantWarBowFlag`; buys from a new leader cancel pending flags immediately (`_maybePlantWarBowFlag`). - **First buy** — `FIRST_BUY_CRED_BONUS = 150e18` scheduled in `epochFixedCredBonus[lastBuyEpoch+1]` ([#268](https://gitlab.com/PlasticDigits/yieldomega/-/issues/268)); not tuned for “second buy free + level 2” onboarding. - **Level views** — `level(user)`, `xp(user)`, `xpToNextLevel(user)`. ### Frontend - XP appears in **wallet profile modal** only ([`WalletProfileXpSection`](frontend/src/components/WalletProfileModalSections.tsx)); not a primary `/arena` hero element. - Buy preview ([`arenaBuyProjectedEffects.ts`](frontend/src/pages/arena/arenaBuyProjectedEffects.ts)) assumes full mechanics (timer, streak, WarBow BP, flags) for every connected wallet. - No “Locked until Level X” affordances or first-unlock mechanic popovers. ### Indexer - Wallet stats API exposes `level` / `xp` ([#255](https://gitlab.com/PlasticDigits/yieldomega/-/issues/255)); no `unlocked_features` or `feature_tutorial_seen` persistence yet. ### Product spec - [`docs/product/arena-v2.md`](docs/product/arena-v2.md) documents uncapped XP and all-four-podium buy side effects. --- ## Why this is needed New players currently land in a **fully unlocked** arena: one buy moves four independent timers, WarBow scoring, streak logic, and flag PvP simultaneously. XP/level is a secondary stat buried in the wallet modal. Progressive **unwrapping** teaches mechanics one podium at a time, reduces early cognitive load, and makes leveling a **core retention loop**. Capping at **level 5** gives a clear mastery arc. First-buy CRED tuning ensures the onboarding path is **self-funding** through level 2 without whale assumptions. **Note:** Prize DOUB routing to all podiums regardless of unlock state is specified in the companion issue (100% epoch-weighted podium funding). This issue covers **player-scoped buy effects** and **UX** only. --- ## Constraints & guardrails 1. **Onchain authority** — level gates for timer extension, scoring hooks, WarBow actions, and flag cancel/plant must be enforced in `TimeArena` (not UI-only). Indexer/frontend are derived. 2. **AGPL-3.0** — all new Solidity/TS/Rust under repo license. 3. **UUPS append-only** — new per-wallet mappings (`featureTutorialSeen`, etc.) must be append-only for upgrade safety. 4. **XP independence** — timer hard-reset / `lastBuyEpoch` roll must **not** reset level, `xpTowardNext`, or lifetime `xp` ([#250](https://gitlab.com/PlasticDigits/yieldomega/-/issues/250)). 5. **Buy-path gas** — retain O(1) `applyXpGain`; max **5 level-ups per buy** ([#265](https://gitlab.com/PlasticDigits/yieldomega/-/issues/265)). 6. **Level cap** — `MAX_PLAYER_LEVEL = 5`; XP may still accrue but level stops at 5 (define overflow behavior: bank XP vs discard — recommend bank for future cap raises). 7. **Global vs player scope** — other players’ buys always run full mechanics; only the **buyer’s level** gates **their** buy side effects. 8. **Prize funding** — buys still fund all podium vaults (companion routing issue); locked UI must not imply “your buy doesn’t fund the arena.” 9. **CRED buy path** — `buyWithCred` participates in XP/level and first-buy bonus per [#268](https://gitlab.com/PlasticDigits/yieldomega/-/issues/268); level gates apply equally. 10. **Do not reintroduce** retired v1 surfaces ([#241](https://gitlab.com/PlasticDigits/yieldomega/-/issues/241)–[#244](https://gitlab.com/PlasticDigits/yieldomega/-/issues/244)). --- ## Level unlock matrix | Level | Unlocks | Player buy effects | |-------|---------|-------------------| | **1** (start) | Last Buy podium only | Extends **Last Buy** timer only; Last Buy scoring only; no Time Booster / Streak / WarBow / flags | | **2** | Time Booster | + extends Time Booster deadline; Time Booster leaderboard scoring | | **3** | Defended Streak | + streak processing | | **4** | WarBow | + WarBow BP; steal/guard/revenge (existing costs) | | **5** | Flag plant & disruption | + `plantWarBowFlag`; buys can cancel/replace pending flags | **Until level 5:** player buys **must not** cancel or replace `warbowPendingFlagOwner` (other players still can). **Locked UI copy:** `Locked until Level {N}` + lock icon on gated controls/sections. **Mechanic popover:** On first unlock (or help `?` button), show a modal/popover explaining that feature’s rules (reuse play-skill copy where possible: [`skills/play-active-time-arena`](skills/play-active-time-arena/SKILL.md), [`skills/play-time-arena-warbow`](skills/play-time-arena-warbow/SKILL.md)). --- ## First-buy onboarding (tune constants) **Goal:** First buy ever (per wallet, `buyCount == 0` before increment) grants enough **bonus CRED** to afford a **second buy** at the same CHARM, **plus ~10% headroom**, and **two buys at the recommended starter CHARM** yield **≥ 20 XP** (level 2 threshold). **Current:** fixed `150 CRED` ([#268](https://gitlab.com/PlasticDigits/yieldomega/-/issues/268)). **Recommended direction:** - Define a documented **starter CHARM** (e.g. min band `0.99e18` or product-chosen default on `/arena`). - Set `FIRST_BUY_CRED_BONUS` (or formula: `credBurn(firstBuyCharm) * 1.10`) so claimable CRED covers second `buyWithCred` at same charm + 10%. - Verify `xpForCharm(starter) * 2 >= xpToAdvance(1)` (20 XP); adjust starter charm hint or bonus XP event if needed (prefer charm/CRED tuning over special-case XP grants). - Update [`verify-cred-buy-anvil.sh`](scripts/verify-cred-buy-anvil.sh) and invariants §268. --- ## Relevant files | Layer | Files | |-------|-------| | Contracts | [`TimeArena.sol`](contracts/src/arena/TimeArena.sol), [`ArenaXp.sol`](contracts/src/arena/libraries/ArenaXp.sol), [`ArenaPodiumTimerConfig.sol`](contracts/src/arena/libraries/ArenaPodiumTimerConfig.sol) | | Tests | [`TimeArena.t.sol`](contracts/test/TimeArena.t.sol), [`ArenaXp.t.sol`](contracts/test/ArenaXp.t.sol) | | Frontend | [`ArenaSimplePage.tsx`](frontend/src/pages/arena/ArenaSimplePage.tsx), [`ArenaSections.tsx`](frontend/src/pages/arena/ArenaSections.tsx), [`ArenaTimerChips.tsx`](frontend/src/pages/arena/ArenaTimerChips.tsx), [`ArenaWarbowHeroPanel.tsx`](frontend/src/pages/arena/ArenaWarbowHeroPanel.tsx), [`arenaBuyProjectedEffects.ts`](frontend/src/pages/arena/arenaBuyProjectedEffects.ts), [`arenaXpMath.ts`](frontend/src/lib/arenaXpMath.ts), [`WalletProfileModalSections.tsx`](frontend/src/components/WalletProfileModalSections.tsx) | | Indexer | [`arena_wallet_stats.rs`](indexer/src/arena_wallet_stats.rs), [`api_arena.rs`](indexer/src/api_arena.rs) | | Docs | [`arena-v2.md`](docs/product/arena-v2.md), [`arena-views.md`](docs/frontend/arena-views.md), [`invariants-and-business-logic.md`](docs/testing/invariants-and-business-logic.md) | | Verify | [`verify-cred-buy-anvil.sh`](scripts/verify-cred-buy-anvil.sh), [`verify-wallet-profile-anvil.sh`](scripts/verify-wallet-profile-anvil.sh), [`e2e-anvil.sh`](scripts/e2e-anvil.sh) | --- ## Recommended solution direction ### Contracts 1. Add `MAX_PLAYER_LEVEL = 5` in `ArenaXp`; clamp in `applyXpGain` / `level` view. 2. Add `function _playerLevel(address) internal view` and branch `_finishBuy`: - Level ≥ 1: Last Buy timer + `_trackLastBuyer` (always). - Level ≥ 2: `_extendOtherPodiumTimers` for **cat 1 only** (not all secondary podiums at once). - Level ≥ 3: extend cat 2 + `_processDefendedStreak`. - Level ≥ 4: extend cat 3 + `_applyBuyWarBowBp`. - Level ≥ 5: flag plant/cancel path in `_maybePlantWarBowFlag`. 3. Gate `warbowSteal` / `warbowActivateGuard` / `warbowRevenge` at level ≥ 4. 4. Emit `LevelUp` / `FeatureUnlocked` events for indexer + UX (optional `XpGained` enrichment). 5. Retune `FIRST_BUY_CRED_BONUS` per onboarding math. ### Frontend 1. **XP hero** on `/arena` (level badge, progress bar to next level, XP gained on buy toast). 2. Per-section lock overlays on Time Booster, Streak, WarBow, flag UI. 3. `FeatureMechanicModal` — localStorage or indexer-backed “seen” + first-unlock trigger. 4. Buy preview filters projected effect lines by effective player level (read chain `level`). ### Indexer 1. Decode new events; expose `level`, `xp_toward_next`, optional `unlocked_level` on wallet stats. 2. Optional: `POST` not needed — persist tutorial seen client-side unless cross-device required. --- ## Acceptance criteria - [ ] `level` capped at **5** onchain and mirrored in frontend/indexer. - [ ] Level-1 wallet buy extends **only** Last Buy timer; no secondary podium deadline changes from that wallet’s buy. - [ ] Level-2+ unlocks match matrix above; verified per level in Forge. - [ ] Level &lt; 5 wallet cannot cancel/replace pending WarBow flag via buy; level ≥ 5 can. - [ ] Level &lt; 4 wallet cannot call WarBow steal/guard/revenge. - [ ] Locked controls show **lock icon** + `Locked until Level N`. - [ ] First unlock (and help button) opens mechanic explainer popover/modal. - [ ] XP/level is **visible on main `/arena` view** without opening wallet profile. - [ ] First-buy CRED bonus + recommended starter path: **two buys → level ≥ 2** and second buy affordable via CRED (incl. ~10% headroom). - [ ] `buyWithCred` respects same gates and XP cap. - [ ] Docs + invariants updated with `INV-ARENA-PROGRESSION-*` rows. - [ ] Existing whales / high `buyCount` wallets: define migration (grandfather full unlock at level 5 if `buyCount > 0` **or** recompute level from XP — **product decision**, document in issue/MR). --- ## Test plan (functional paths) | Path | Layer | Command / evidence | |------|-------|-------------------| | XP cap + level-up clamp | Contracts | `forge test --match-contract ArenaXp` + new `TimeArena` level-cap tests | | Per-level timer gating | Contracts | `forge test --match-test test_level_*_gates_timers` in `TimeArena.t.sol` | | Per-level WarBow/flag gating | Contracts | `forge test --match-test test_level_*_warbow` | | First-buy CRED onboarding | Contracts + script | `bash scripts/verify-cred-buy-anvil.sh` (extend assertions) | | Frontend XP hero + locks | Frontend | `npm run typecheck && npm run lint && npm test` | | Lock copy + popover | Frontend | component tests + `arena.spec.ts` / `anvil-arena-*.spec.ts` | | Buy preview by level | Frontend | `arenaBuyProjectedEffects.test.ts` cases per level | | Indexer level field | Indexer | `cargo test` + `verify-wallet-profile-anvil.sh` | | E2E buy at level 1 vs 5 | Playwright | `bash scripts/e2e-anvil.sh` (mock wallet; level state via Anvil impersonation / pre-seeded buys) | | Manual QA | Rabby | Level 1 connect → buy → only Last Buy timer moves; level-up → new section unlocks | --- ## Test plan (attack / abuse / edge vectors) | Vector | Expected behavior | Test | |--------|-------------------|------| | UI bypass — call `buy(plantWarBowFlag=true)` at level &lt; 5 | Tx reverts or flag ignored onchain | Forge `test_level4_buy_plant_flag_reverts` | | UI bypass — WarBow steal at level &lt; 4 | Revert `TimeArena: level` (or equivalent) | Forge | | Level-up mid-block / same tx | Gates use post-XP level from same `_finishBuy` | Forge multi-level-up in one buy | | Whale sybil — fresh wallet to avoid gates | Expected; gates are per-wallet progression | Document as accepted | | First-buy bonus farming — transfer wallet | `buyCount` / first-buy keyed to address; no reset on hard-reset | Forge + existing §268 tests | | CRED burn without DOUB — skip prize but gain XP | `buyWithCred` still levels; no double-dip on DOUB routing | Forge | | Reentrancy on level-gated external calls | `nonReentrant` preserved | Forge | | Indexer lies about level | Frontend write paths use onchain `level` for tx building | Integration test | | Popover spam / localStorage clear | Re-show on help only after seen flag | Frontend test | | Grandfathering exploit — reset level via upgrade bug | UUPS storage layout review + `_disableInitializers` | Manual + storage gap | | Griefing — max-level player cancels flags | Allowed by design at level 5 | Play skill regression | --- ## Verification criteria (merge gate) | Check | Command | PASS when | |-------|---------|-----------| | Contracts | `cd contracts && forge test` | All new + existing tests green | | Indexer | `cd indexer && cargo clippy --all-targets -- -D warnings && cargo test` | Green | | Frontend | `cd frontend && npm run typecheck && npm run lint && npm test` | Green | | CRED onboarding | `bash scripts/verify-cred-buy-anvil.sh` | Extended script PASS | | Wallet profile | `bash scripts/verify-wallet-profile-anvil.sh` | Level cap reflected | | Doc gates | `bash scripts/check-doc-anchors.sh` | PASS | | E2E (if UI touched) | `bash scripts/e2e-anvil.sh` | PASS or documented scope skip |
PlasticDigits commented 2026-06-07 07:50:09 +00:00 (Migrated from gitlab.com)

marked as related to #238

marked as related to #238
PlasticDigits commented 2026-06-07 07:50:17 +00:00 (Migrated from gitlab.com)

marked as related to #300

marked as related to #300
ghost1 commented 2026-06-07 09:56:01 +00:00 (Migrated from gitlab.com)

mentioned in commit 71dc5a157b

mentioned in commit 71dc5a157b84a2fd7042a6f4cbb97d48e969495c
PlasticDigits commented 2026-06-07 09:56:30 +00:00 (Migrated from gitlab.com)

mentioned in merge request !441

mentioned in merge request !441
PlasticDigits commented 2026-06-07 10:03:52 +00:00 (Migrated from gitlab.com)

mentioned in commit a49b3dfb21

mentioned in commit a49b3dfb216aa74a5151fcb5eb6cab50e508ebaf
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-07 10:03:54 +00:00
PlasticDigits commented 2026-06-08 08:45:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 377e3a881f

mentioned in commit 377e3a881f491fb1f9f160d82d3d5d57005446ee
PlasticDigits commented 2026-06-10 03:30:12 +00:00 (Migrated from gitlab.com)

mentioned in issue #304

mentioned in issue #304
PlasticDigits commented 2026-06-13 08:05:15 +00:00 (Migrated from gitlab.com)

mentioned in merge request !460

mentioned in merge request !460
PlasticDigits commented 2026-06-14 02:41:04 +00:00 (Migrated from gitlab.com)

mentioned in commit 9d384bf7f1

mentioned in commit 9d384bf7f1cfdf16a14b695e65f36fa6d1115a6f
PlasticDigits commented 2026-06-14 02:41:07 +00:00 (Migrated from gitlab.com)

mentioned in merge request !475

mentioned in merge request !475
PlasticDigits commented 2026-06-14 03:00:42 +00:00 (Migrated from gitlab.com)

mentioned in commit 6dda90975b

mentioned in commit 6dda90975b2407b117817eb5deb65a49ddb378c2
PlasticDigits commented 2026-06-14 03:00:46 +00:00 (Migrated from gitlab.com)

mentioned in merge request !479

mentioned in merge request !479
PlasticDigits commented 2026-06-19 03:09:45 +00:00 (Migrated from gitlab.com)

mentioned in issue #331

mentioned in issue #331
PlasticDigits commented 2026-06-19 03:44:17 +00:00 (Migrated from gitlab.com)

mentioned in merge request !504

mentioned in merge request !504
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#299
No description provided.