soroban-fixed-point-math has Incorrect Rounding and Overflow Handling in Signed Fixed-Point Math with Negatives

Description

Impact

Incorrect rounding direction for signed mul and div operations

The mulDiv(x, y, z) function incorrectly handled cases where both the intermediate product $x * y$ and the divisor $z$ were negative. The logic assumed that if the intermediate product was negative, the final result must also be negative, neglecting the sign of $z$.

This resulted in rounding being applied in the wrong direction for cases where both $x * y$ and $z$ were negative. The functions most at risk are fixed_div_floor and fixed_div_ceil, as they often use non-constant numbers as the divisor $z$ in mulDiv.

This error is present in all signed FixedPoint and SorobanFixedPoint implementations, including i64, i128, and I256.

Negative Overflow in i64

The mulDiv(x, y, z) function for i64 used the i128 type to handle "phantom overflows". These are overflows that occur intermediately during a calculation, like when computing the intermediate product $x * y$. When the final result of mulDiv was computed in i128, it was scaled back down to i64 before returning. While the code verified that the result did not exceed i64::MAX, it did not check against i64::MIN.

This caused negative results smaller than i64:MIN to wrap around to a large positive number instead of being caught as an overflow.

This error only exists for the FixedPoint implementation of i64.

Patches

  • v1.3.0 users should upgrade to patch v1.3.1
  • v1.4.0 users should upgrade to patch v1.4.1

All versions >=v1.4.1 contain the patch.

Workarounds

There are no known workarounds. Upgrade to the patched version.

Credits

soroban-fixed-point-math would like to thank the team at Certora for discovering and reporting the issue.

Basic information

Type
reviewed
Severity
high
Advisory on GitHub
Open advisory ↗
Repository advisory
Open repository advisory ↗
Source code
Browse source ↗
Published (advisory)
2026-01-28 16:18:54 UTC
Updated
2026-01-28 16:18:55 UTC
GitHub reviewed
2026-01-28 16:18:54 UTC
NVD published
2026-01-27

EPSS Score

Score Percentile
0.01% 2.73%

CVSS Scores

Base score Version Severity Vector
7.5 3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N Click to expand
Attack vector (AV:N)
Could be attacked over the internet or any normal routed network—not just someone sitting at the machine.
Attack complexity (AC:L)
Once they can reach the bug, pulling it off is straightforward—no weird race conditions or rare setup.
Privileges required (PR:N)
No account or special rights needed—anonymous or random user is enough.
User interaction (UI:N)
Nobody has to click “OK” or open a trap file; it can work without a victim helping.
Scope (S:U)
Damage stays in the same “trust bubble” as the broken component—no big spill into unrelated systems.
Confidentiality (C:N)
Doesn’t really leak secrets in a meaningful way.
Integrity (I:H)
They could widely tamper with or forge data—trust in the data is badly hurt.
Availability (A:N)
Service keeps running; no real outage angle.

Identifiers

CWEs

CWE id Name
CWE-682 Incorrect Calculation

Affected packages (2)

Vulnerable version ranges and first patched releases as published by GitHub.

Ecosystem Package Vulnerable range First patched Vulnerable functions
rust soroban-fixed-point-math = 1.4.0 1.4.1
rust soroban-fixed-point-math = 1.3.0 1.3.1

References

cvelogic Threat Intelligence