Review a pull request: coupons and withdrawals
Not solvedMoney-moving code that is correct one request at a time. Find what breaks when requests arrive together.
- Level
- Advanced
- Estimated time
- ~25 min
- Points
- 0/75 pts
- Questions
- 0/0 answered
- OWASP
- A06:2025
- CWE
- CWE-362
- CWE
- CWE-367
src/services/wallet.ts0/2 found
| import { db } from '../db' | ||
| + | export async function redeemCoupon(userId: string, code: string) { | |
| + | const coupon = await db.one('SELECT * FROM coupons WHERE code = $1', [code]) | |
| + | if (!coupon) throw new HttpError(404, 'Unknown coupon') | |
| + | if (coupon.redeemed_at) throw new HttpError(409, 'Coupon already used') | |
| + | await credit(userId, coupon.amount) | |
| + | await db.query('UPDATE coupons SET redeemed_at = now(), redeemed_by = $2 WHERE id = $1', [coupon.id, userId]) | |
| + | } | |
| + | ||
| + | export async function withdraw(userId: string, amount: number) { | |
| + | if (!Number.isInteger(amount) || amount <= 0) throw new HttpError(400, 'Invalid amount') | |
| + | const wallet = await db.one('SELECT balance FROM wallets WHERE user_id = $1', [userId]) | |
| + | if (wallet.balance < amount) throw new HttpError(402, 'Insufficient funds') | |
| + | await db.query('UPDATE wallets SET balance = $2 WHERE user_id = $1', [userId, wallet.balance - amount]) | |
| + | await payouts.send(userId, amount) | |
| + | } | |
| async function credit(userId: string, amount: number) { | ||
| await db.query('UPDATE wallets SET balance = balance + $2 WHERE user_id = $1', [userId, amount]) | ||
| } |
Click a line number to flag a defect. The review code appears when every defect is flagged with no false positives.