What changed, and why it matters
This commit fixes a display bug in how Krux formats negative Bitcoin amounts. Previously, a value like -1000 satoshis was shown incorrectly as roughly -1.99 bitcoins instead of -0.00001 bitcoins, because the code split the number before handling the minus sign. The fix simply removes the sign, formats the absolute value, then reattaches the minus sign. It is a user-interface bug, not a wallet-security vulnerability.
No security action required beyond normal review and merge. Users relying on displayed balances should verify negative amounts render correctly after updating.
Security signals we found
UI/display bug in financial amount rendering
No cryptographic, authorization, or memory-safety changes
No input validation, parsing, or serialization of untrusted data changed
Evidence from the diff
format_btc() in src/krux/format.py previously applied floor division and modulo directly to a possibly negative integer. Python’s // and % round toward negative infinity, so for amount=-1000 and SATS_PER_BTC=100000000, btc_without_decimal became -1 and btc_decimal_only became 99999000, producing ‘-1.99 999 000’. The patch captures the sign, takes abs(amount), splits the magnitude, then prepends the sign. A new test verifies symmetry for several values and the specific -1000 case.
Changed components
src/krux/format.pytests/test_format.pyInspect captured patch +22 / −1
diff --git a/src/krux/format.py b/src/krux/format.py
index 557a2ea..e2d7059 100644
--- a/src/krux/format.py
+++ b/src/krux/format.py
@@ -33,12 +33,18 @@ def format_btc(amount):
while still using the idea behind the Satcomma standard
"""
+ # Floor division and modulo round towards minus infinity, so the sign has
+ # to be taken out before splitting the amount
+ sign = "-" if amount < 0 else ""
+ amount = abs(amount)
+
btc_without_decimal = amount // SATS_PER_BTC
btc_decimal_only = amount % SATS_PER_BTC
btc_decimal_8char = ("{:0>" + BTC_SATS_LEN + "}").format(btc_decimal_only)
return (
- generate_thousands_separator(btc_without_decimal)
+ sign
+ + generate_thousands_separator(btc_without_decimal)
+ render_decimal_separator()
+ btc_decimal_8char[:2]
+ THOUSANDS_SEPARATOR
diff --git a/tests/test_format.py b/tests/test_format.py
index 4432b6b..3fde27a 100644
--- a/tests/test_format.py
+++ b/tests/test_format.py
@@ -22,3 +22,18 @@ def test_format_btc(m5stickv):
]
for case in cases:
assert format_btc(case[0]) == case[1]
+
+
+def test_format_btc_negative(m5stickv):
+ """A negative amount is the positive one with a minus sign.
+
+ Floor division and modulo round towards minus infinity, so splitting the
+ amount before taking the sign out used to render -1000 as -1.99 999 000.
+ """
+ from krux.format import format_btc, THOUSANDS_SEPARATOR
+
+ for amount in (1, 999, 1000, 100000000, 199999000, 2098989898989898):
+ assert format_btc(-amount) == "-" + format_btc(amount)
+
+ separator = THOUSANDS_SEPARATOR
+ assert format_btc(-1000) == "-0.00" + separator + "001" + separator + "000"
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.