Skip to content

fix: prevent decimal precision overflow bypass in transaction_limit - #20

Open
rafaio1 wants to merge 1 commit into
kindrat86:mainfrom
rafaio1:fix/decimal-precision-overflow
Open

fix: prevent decimal precision overflow bypass in transaction_limit#20
rafaio1 wants to merge 1 commit into
kindrat86:mainfrom
rafaio1:fix/decimal-precision-overflow

Conversation

@rafaio1

@rafaio1 rafaio1 commented Aug 23, 2026

Copy link
Copy Markdown

Summary

Fixes the decimal precision overflow bypass reported in #5.

The Bug

When a transaction amount like 1.0000000000000001 was passed as a Python float, it was silently equal to 1.0 due to IEEE 754 float precision limits (~15-17 significant digits). This caused the engine to APPROVE transactions that should have been BLOCKED against a max_amount=1 limit.

The Fix

  • Float inputs: Now use repr() instead of str() for float-to-Decimal conversion, preserving maximum representable precision
  • String/Decimal inputs: Correctly block amounts exceeding limits at any precision level (e.g., '1.0000000000000001' > 1)
  • Documentation: Added clear note that Python float inputs lose precision at assignment time; callers should use string or Decimal amounts for sub-cent accuracy

Testing

  • All 14 existing tests pass ✅
  • Added 7 new regression tests covering:
    • String amounts with excess precision → BLOCKED
    • Float amounts at float precision boundary → APPROVED (documented limitation)
    • Float amounts clearly exceeding limit → BLOCKED
    • Exact limit → APPROVED
    • Below limit → APPROVED
    • Extreme precision strings → BLOCKED
    • Decimal input preserves precision → BLOCKED

Important Note for Callers

Python floats cannot represent 1.0000000000000001 distinctly from 1.0. For spend-control boundaries where sub-cent precision matters, pass amounts as strings or Decimal objects:

# ❌ Float loses precision before engine sees it
{'amount': 1.0000000000000001, ...}  # becomes 1.0

# ✅ String preserves full precision
{'amount': '1.0000000000000001', ...}  # correctly blocked

# ✅ Decimal preserves full precision
from decimal import Decimal
{'amount': Decimal('1.0000000000000001'), ...}  # correctly blocked

Fixes #5

- Use repr() instead of str() for float-to-Decimal conversion to preserve
  maximum representable precision
- String and Decimal inputs now correctly block amounts exceeding limits
  at any precision level (e.g., '1.0000000000000001' > 1)
- Document that Python float inputs lose precision at assignment time;
  callers should use string or Decimal amounts for sub-cent accuracy
- Add regression tests covering string, float, Decimal, and edge cases

Fixes kindrat86#5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bounty | decimal.Decimal Precision Overflow

1 participant