Fix race conditions and negative balance vulnerabilities#5
Fix race conditions and negative balance vulnerabilities#5
Conversation
- Use atomic find_one_and_update with $gte guards for tips, withdrawals, and red envelope creation to prevent spending more than available balance - Use $inc instead of $set for all balance mutations to prevent race conditions between concurrent operations - Use Decimal arithmetic for all FIRO calculations to prevent floating point precision errors (stored as float in MongoDB for backward compatibility with existing database) - Fix withdrawal fee logic: atomic deduct full amount, rollback exact amount on RPC failure - Fix catch_envelope to atomically deduct from envelope remains with $gte guard, preventing over-distribution - Fix update_balance withdrawal handler to properly handle locked amount reduction without leaving stale locked values - Store MongoClient as self.client for transaction session access - Replace print() with structured logging throughout - Replace deprecated insert() calls with insert_one() https://claude.ai/code/session_01K7FrkbpYpqJAoJfcx67osm
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| except Exception as exc: | ||
| print(exc) | ||
| traceback.print_exc() | ||
| logger.error(exc, exc_info=True) |
There was a problem hiding this comment.
Missing rollback when wallet API throws exception
High Severity
In withdraw_coins, the atomic find_one_and_update deducts the user's Balance and increments Locked before calling spendspark. If spendspark raises an exception (network timeout, connection error, JSON decode failure) rather than returning an error response, execution jumps to the outer except block, which only logs the error — no rollback is performed. The user's funds are permanently deducted from Balance and stuck in Locked with no corresponding on-chain transaction. The old code was safe here because the database update happened after the successful API call.
|
This should fix this PR: |


Summary
Test plan
Note
High Risk
Modifies core balance accounting for tips, withdrawals, deposits, and envelopes using new atomic MongoDB update patterns; mistakes here could incorrectly credit/debit funds or lock balances.
Overview
Prevents double-spend/negative balances by replacing read-then-write balance updates with atomic MongoDB operations (primarily
find_one_and_updatewith$gteguards and$inc) across tips, withdrawals, deposit processing, and red envelope creation/claims.Improves value precision and safety by introducing
Decimalhelpers (to_decimal,decimal_to_store) for 8-decimal FIRO amounts, tightening amount validation (non-negative/minimums/fee checks), and adjusting withdrawal flow to move funds toLockedatomically with rollback on wallet send failure.Operational changes include deduping already-processed transactions in
update_balanceviatxIdchecks and replacingprint/tracebackusage with structuredlogging(includingexc_info).Written by Cursor Bugbot for commit 3c24ddd. This will update automatically on new commits. Configure here.