# Precision loss in toPackedFloat function when mantissa is in range (MAX_M_DIGIT_NUMBER, MIN_L_DIGIT_NUMBER)

Float128.toPackedFloat picks M vs L format by exponent only, silently truncating mantissas in the (MAX_M_DIGIT_NUMBER, MIN_L_DIGIT_NUMBER) range and corrupting downstream arithmetic.

- Payout: Contest reward
- Severity: high
- Program: Forte
- Credited: v2110
- Disclosed: 2025-04-29
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-04-forte-float128-solidity-library#h-05
- Library page: https://bugbountylibrary.com/r/c4%3A2025-04-forte-float128-solidity-library%3AH-05
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:high tech:solidity technique:fuzzing technique:source-review vuln:precision-loss

**Target:** Float128 fixed-point math library (Solidity)
**Root cause:** Result mantissa size (M vs L) is chosen solely from the exponent, ignoring digitsMantissa; when mantissa digits fall between MAX_M_DIGIT_NUMBER and MIN_L_DIGIT_NUMBER and exponent <= 20 - digitsMantissa, the mantissa is downcast via division by BASE^(digitsMantissa - MAX_DIGITS_M), losing digitsMantissa - MAX_DIGITS_M digits.
**Steps:**
1. Call `man.toPackedFloat(expo)` with `man = 2^235`, `expo = -51` (near MIN_L_DIGIT_NUMBER lower boundary).
2. Decode the packed float and re-normalize; observe decoded mantissa is strictly less than original man.
3. Repeat with `man = 2^127`, `expo = -19` (near MAX_M_DIGIT_NUMBER upper boundary); same truncation.
4. Compare `Float128.mul(float,float)` against a Python reference via FFI: mantissas differ by ~35 digits at exponent -32.
**How found:** Code reading of toPackedFloat: noticed format selection keyed only on exponent, then reasoned about mantissas whose digit count sits between the M and L thresholds, and confirmed with boundary-value tests plus FFI differential against Python.
**Escalation:** Precision loss propagates through all arithmetic built on toPackedFloat (e.g. mul, sqrt), compounding errors in downstream calculations.
**Insight:** In fixed-point libraries with multiple mantissa widths, format selection must consider mantissa digit count, not just exponent; fuzz boundary values where digitsMantissa straddles the M/L threshold and diff against a reference implementation.
