Skip to content

Packed sub reverts ExponentUnderflow near EXPONENT_MIN where the unpacked reference path succeeds #271

Description

@thedavidmeister

Found by the testSubPacked fuzz on PR #270's CI run (seed-dependent; the PR's diff is dep pins only and does not touch this code path).

Counterexample

testSubPacked(
    Float.wrap(0x8000000000000000000000000000000000000000000000000000000000000003),
    Float.wrap(0x800000000000000000000000000000000000000000000000000000000000000a)
)

i.e. a = 3e-2147483648, b = 10e-2147483648 (both at the packed exponent minimum).

  • Reference path: LibDecimalFloatImplementation.sub(3, -2147483648, 10, -2147483648) succeeds, and packLossy of its result succeeds.
  • Packed path: LibDecimalFloat.sub(a, b) reverts ExponentUnderflow(-7e75, -2147483723) — the -7 difference gets normalised up to full precision (-7e75), pushing the exponent 75 below int32 min.

The test's contract is that the two paths agree (same result or same revert), so this is a genuine inconsistency at the exponent floor, not a test artefact.

Pre-existing

Replayed bit-for-bit on unbumped main (bcd9ed9, solmem 0.1.3 / datacontract 0.1.0) and on the #270 branch: identical revert, identical gas (9566) on both. Latent on main; CI's random fuzz seed on #270 happened to find it.

Repro harness used

A concrete test mirroring testSubPacked's body with the counterexample inputs wrapped via Float.wrap, run in the flake shell on both refs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions