[Critical] [Bug] Preparation mana never deducted — free equipment preparation exploit #353

Closed
opened 2026-06-10 19:22:56 +02:00 by Anexim · 2 comments
Owner

Severity: Critical
File: src/lib/game/crafting-actions/preparation-actions.ts (lines 22-41)

Description:
startPreparing() validates that the player has enough raw mana (rawMana < costs.manaTotal → reject), but it never actually deducts the mana from the player's mana store. It only stores the cost in preparationProgress.manaCostPaid for tracking/refund purposes.

Additionally, cancelPreparation() (lines 44-58) reads progress.manaCostPaid and adds it back to rawMana. Since nothing was ever deducted, this creates mana from nothing.

Impact: Infinite mana generation exploit:

  1. Start preparation on any equipment
  2. Cancel preparation
  3. Repeat — each cycle generates mana equal to the preparation cost

This breaks the entire game economy.

Fix needed: startPreparing() must call useManaStore.setState(...) to deduct the mana cost from the player's raw mana pool, similar to how startFabricatorCrafting() in equipment-crafting.ts correctly deducts mana.

**Severity:** Critical **File:** `src/lib/game/crafting-actions/preparation-actions.ts` (lines 22-41) **Description:** `startPreparing()` validates that the player has enough raw mana (`rawMana < costs.manaTotal` → reject), but it **never actually deducts** the mana from the player's mana store. It only stores the cost in `preparationProgress.manaCostPaid` for tracking/refund purposes. Additionally, `cancelPreparation()` (lines 44-58) reads `progress.manaCostPaid` and adds it back to `rawMana`. Since nothing was ever deducted, this **creates mana from nothing**. **Impact:** Infinite mana generation exploit: 1. Start preparation on any equipment 2. Cancel preparation 3. Repeat — each cycle generates mana equal to the preparation cost This breaks the entire game economy. **Fix needed:** `startPreparing()` must call `useManaStore.setState(...)` to deduct the mana cost from the player's raw mana pool, similar to how `startFabricatorCrafting()` in `equipment-crafting.ts` correctly deducts mana.
Anexim added the ai:todo label 2026-06-10 19:22:56 +02:00
n8n-gitea was assigned by Anexim 2026-06-10 19:22:56 +02:00
Anexim added ai:review and removed ai:todo labels 2026-06-10 20:41:38 +02:00
Author
Owner

Fix applied. startPreparing() validated that the player had enough raw mana but never actually deducted it from the mana store. Additionally, cancelPreparation() refunds manaCostPaid — since nothing was ever deducted, this created mana from nothing.

Root cause: Missing useManaStore.setState() call to deduct mana after validation passes.

Fix: Added useManaStore.setState((s) => ({ rawMana: s.rawMana - costs.manaTotal })); after the mana check in startPreparing().

All 1141 tests pass.

**Fix applied.** `startPreparing()` validated that the player had enough raw mana but never actually deducted it from the mana store. Additionally, `cancelPreparation()` refunds `manaCostPaid` — since nothing was ever deducted, this created mana from nothing. **Root cause:** Missing `useManaStore.setState()` call to deduct mana after validation passes. **Fix:** Added `useManaStore.setState((s) => ({ rawMana: s.rawMana - costs.manaTotal }));` after the mana check in `startPreparing()`. All 1141 tests pass.
Anexim added ai:done and removed ai:review labels 2026-06-11 12:37:52 +02:00
Author
Owner

Review complete — fix verified.

startPreparing() now correctly deducts costs.manaTotal from rawMana via useManaStore.setState() after validation passes. The cancel-then-refund path no longer creates mana from nothing — the net effect of prepare→cancel always leaves the player with ≤ their starting mana.

  • Regression test bug-353-preparation-mana.test.ts: 3/3 tests pass
  • Full suite: 68 files, 1158 tests — all green

No remaining issues.

**Review complete — fix verified.** `startPreparing()` now correctly deducts `costs.manaTotal` from `rawMana` via `useManaStore.setState()` after validation passes. The cancel-then-refund path no longer creates mana from nothing — the net effect of prepare→cancel always leaves the player with ≤ their starting mana. - Regression test `bug-353-preparation-mana.test.ts`: 3/3 tests pass - Full suite: 68 files, 1158 tests — all green No remaining issues.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Anexim/Mana-Loop#353