Tightening the round-trip pow fuzz catch in #232 (commit af358b1) surfaced a latent bug that the old catch-all was swallowing.
Repro (deterministic, pristine main): pow(1e1700000000, -8e69) reverts with a raw Panic(0x11) (arithmetic overflow) instead of a clean custom error.
Root cause: for a negative exponent, pow recurses to pow(a.inv(), -b); the exponentiation-by-squaring loop (LibDecimalFloat.sol:795-805) repeatedly doubles the base exponent until the CHECKED add exponent = exponentA + exponentB in LibDecimalFloatImplementation.mul (impl:177) overflows int256 and panics — instead of the clean ExponentOverflow that testPowIntegerExponentSquaringOverflow documents as the intended behaviour.
Impact: reachable across the fuzz space (seeds 0x0, 0x7666..., others). The now-correctly-tightened testRoundTripFuzzPow (PR #232) fails on triggering seeds; it is no longer masked by the old catch (bytes memory) catch-all.
Fix direction: bound the exponent against EXPONENT_MAX before/within the squaring mul so the overflow surfaces as ExponentOverflow rather than the checked-add panic. This is a core-arithmetic change that moves DecimalFloat deploy constants (redeploy required).
Blocks #232 — its tightened test cannot be green until pow reverts cleanly here.
Tightening the round-trip pow fuzz catch in #232 (commit af358b1) surfaced a latent bug that the old catch-all was swallowing.
Repro (deterministic, pristine main): pow(1e1700000000, -8e69) reverts with a raw Panic(0x11) (arithmetic overflow) instead of a clean custom error.
Root cause: for a negative exponent, pow recurses to pow(a.inv(), -b); the exponentiation-by-squaring loop (LibDecimalFloat.sol:795-805) repeatedly doubles the base exponent until the CHECKED add exponent = exponentA + exponentB in LibDecimalFloatImplementation.mul (impl:177) overflows int256 and panics — instead of the clean ExponentOverflow that testPowIntegerExponentSquaringOverflow documents as the intended behaviour.
Impact: reachable across the fuzz space (seeds 0x0, 0x7666..., others). The now-correctly-tightened testRoundTripFuzzPow (PR #232) fails on triggering seeds; it is no longer masked by the old catch (bytes memory) catch-all.
Fix direction: bound the exponent against EXPONENT_MAX before/within the squaring mul so the overflow surfaces as ExponentOverflow rather than the checked-add panic. This is a core-arithmetic change that moves DecimalFloat deploy constants (redeploy required).
Blocks #232 — its tightened test cannot be green until pow reverts cleanly here.