Expected Findings
- Balance read and write are not atomic.
- No `SELECT ... FOR UPDATE` or transaction around the operation.
- Idempotency keys are accepted but not actually enforced.
The withdraw flow reads the balance, decides if the request is allowed, then writes — without a transaction or row lock — so two concurrent requests both see funds and both succeed.
CWE-362CWE-367
bal := db.Get(acct); if bal >= amount { db.Set(acct, bal-amount) } // TOCTOU