From d061bec8492272f8a8c1a7174851eed8c55edba4 Mon Sep 17 00:00:00 2001 From: BhariGowda Date: Sat, 22 Aug 2026 16:56:20 +0530 Subject: [PATCH] Fix float_to_wire returning "-0" The guard that was meant to turn negative zero into "0" compares the pre-normalization string, which is always fixed to 8 decimal places ("-0.00000000"), so it never matched and was dead code. The "-0" only appears after Decimal.normalize(), so the check has to run on the normalized output. Reproduces on master: >>> float_to_wire(-0.0) '-0' >>> float_to_wire(-1e-13) '-0' Both are reachable from ordinary caller arithmetic, for example round(-1e-9, 2) evaluates to -0.0, which then goes out on the wire as an order size or price of "-0". Moved the check after normalize() and added a test covering negative zero, plain zero and a couple of ordinary values so the sign handling does not regress. --- hyperliquid/utils/signing.py | 7 ++++--- tests/signing_test.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hyperliquid/utils/signing.py b/hyperliquid/utils/signing.py index 56041471..0a74a43a 100644 --- a/hyperliquid/utils/signing.py +++ b/hyperliquid/utils/signing.py @@ -476,10 +476,11 @@ def float_to_wire(x: float) -> str: rounded = f"{x:.8f}" if abs(float(rounded) - x) >= 1e-12: raise ValueError("float_to_wire causes rounding", x) - if rounded == "-0": - rounded = "0" normalized = Decimal(rounded).normalize() - return f"{normalized:f}" + wire = f"{normalized:f}" + if wire == "-0": + wire = "0" + return wire def float_to_int_for_hashing(x: float) -> int: diff --git a/tests/signing_test.py b/tests/signing_test.py index b6e89d9f..50daba61 100644 --- a/tests/signing_test.py +++ b/tests/signing_test.py @@ -9,6 +9,7 @@ action_hash, construct_phantom_agent, float_to_int_for_hashing, + float_to_wire, order_request_to_order_wire, order_wires_to_order_action, sign_l1_action, @@ -186,6 +187,15 @@ def test_float_to_int_for_hashing(): float_to_int_for_hashing(0.000012312312) +def test_float_to_wire_normalizes_negative_zero(): + assert float_to_wire(-0.0) == "0" + assert float_to_wire(0.0) == "0" + assert float_to_wire(-1e-13) == "0" + assert float_to_wire(-1.5) == "-1.5" + assert float_to_wire(1.5) == "1.5" + assert float_to_wire(0.00001231) == "0.00001231" + + def test_sign_usd_transfer_action(): wallet = eth_account.Account.from_key("0x0123456789012345678901234567890123456789012345678901234567890123") message = {