mobilegame-qasecurityeconomyqa

How to Test a Mobile Game's Economy and Catch Cheaters

In an F2P game the economy is the business: coins, gems, energy, loot boxes, IAP. Which makes it the prime target. One currency duplication bug or an “infinite coins” cheat and the in-game store your revenue rests on becomes pointless — why pay if you can farm it with a cheat. You don’t test the economy as “does the buy button work”; you test it as abuse resistance. Below are the attacks QA must run itself.

The golden rule: the client lies

Any value coming from the device is potentially forged. Balance, “I bought it,” “I cleared the level,” “grant me the reward” — all of it must be validated and computed on the server, with the client only displaying. The key test: intercept the request (Proxyman/Charles/mitmproxy) and change it — send coins += 1000, level = 99, reward = legendary. The server must reject it (403/validation error), not happily grant it. If it grants it, the economy is leaky, and no client-side checks will save it.

Duplication bugs and idempotency

The classic is doubling a reward/currency at the “action → network → confirmation” seam:

  • Double tap on Buy / Claim reward — two requests. Exactly one operation must go through (idempotency by transaction key), not charge twice or grant the reward twice.
  • Network drop mid-transaction: paid → connection dropped before the response → retry. It must neither duplicate the purchase nor “eat” it without delivery.
  • Rollback/recovery: kill the app during a grant, relaunch — state must reconcile, no duplicates and no losses.

Test: run purchases/rewards with artificial drops and double-clicks (network throttling, killing the app) — the outcome is always “exactly once.”

Device-clock manipulation

Anything tied to time — “wait 8h or pay” timers, daily rewards, energy, cooldowns, time-limited offers — is attacked by changing the system clock. Test: move the device time forward (timer “elapsed,” reward “available”) and back (claim the daily again). Correct: the server tracks time itself; the device is not the source of truth. Check the seam too: change the clock, claim locally, go offline, come back — the server must reject it.

Save-file editing

Local progress in PlayerPrefs, SharedPreferences, a plist, or a save file is editable in a minute (rooted/jailbroken, or just an editor). Test: find where currency/progress is stored, change it to “999999” — what happens? Sensitive values must live on the server or be signed/encrypted so that editing breaks the signature and gets rolled back. If the game honestly trusts a local file, that’s a one-click cheat.

Negative balance, overflow, races

  • Spend more than you have: buy for 100 coins with 50 — must be rejected, not go negative.
  • Overflow: farm/reward currency past 2^31 (or whatever the type is) — must not overflow into negative.
  • Race condition: two parallel debits from one balance (two devices, rapid taps) — the sum must not “split.” The classic: spend the same coins twice simultaneously.

Fake IAP receipts

A real-money purchase is verified by server-side receipt validation via the App Store Server API / Google Play. Without it, a fake or replayed receipt = a free purchase. Test: feed an invalid/someone else’s/replayed receipt — it must not grant the item. (More on IAP in a dedicated purchase breakdown.)

Cheat tools

Players use GameGuardian, memory editors, Lucky Patcher, modified clients. You can’t stop this purely on the client — which is exactly why you need server authority. What to check: critical state (currency, progress, match results) is recomputed/validated by the server; anomalies (impossible gains, impossible scores) are detected; client-side anti-cheat and obfuscation are speed bumps, not protection.

Checklist: attacks on the economy

  • Tampering “+currency / +level / +reward” request → server rejects it.
  • Double tap on buy/reward → exactly one operation.
  • Network drop during a transaction → no duplicates, no losses.
  • Kill the app during a grant → state reconciles.
  • Clock forward/back → timers and dailies computed by the server.
  • Editing the local save (currency/progress) → rolled back / not applied.
  • Purchase above balance → rejected, no going negative.
  • Currency overflow → doesn’t go negative.
  • Parallel debits (2 devices/rapid taps) → no split.
  • Invalid/replayed IAP receipt → item not granted.
  • Critical state validated on the server, not the client.

In short — what to take with you

  • The economy is money, so test it as abuse resistance, not as a “buy button.”
  • Don’t trust the client — compute and validate on the server; the key test is request tampering.
  • Duplication bugs are caught with idempotency: drops, double-taps, kills → “exactly once.”
  • Clock changes and save edits are mandatory attacks; the server owns time and value.
  • Negative balance, overflow, races — check the boundaries.
  • IAP — only with server-side receipt validation.

Further reading: OWASP MASVS — Mobile App Security · Apple — App Store Server API (purchase validation) · Google Play — Billing security