From 3a24aadefb7114af37441feb4993c04f2e44367a Mon Sep 17 00:00:00 2001 From: baku-ccron Date: Sun, 11 Oct 2026 20:33:06 +0000 Subject: [PATCH 1/2] mutation-test: start IMPL-div-extremes campaign Co-Authored-By: Claude Opus 5.5 From 66fafc98de04b9d182ebf815cf8ffb840496d30e Mon Sep 17 00:00:00 2001 From: baku-ccron Date: Sun, 11 Oct 2026 21:28:14 +0000 Subject: [PATCH 2/2] Mutation coverage: IMPL-div-extremes - testMainEquivalenceDivFloorExamples ran out of memory (MemoryOOG) at 886ca07: the 76 #368 sheds now each run in their own call frame. - testDivNegativePowerOfTenDivisorAtMax pins that only a type(int256).min dividend has the 2^255 quotient at exponent type(int256).max; that conjunct was only killed by fuzz luck before. Co-Authored-By: Claude Opus 5.5 --- .../LibDecimalFloatImplementation.div.t.sol | 11 +++++++++++ ...lFloatImplementation.mainEquivalence.t.sol | 19 +++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol index 261cf569..27d4923f 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol @@ -185,6 +185,17 @@ contract LibDecimalFloatImplementationDivTest is Test { this.divExternal(1e76, 76, 1, type(int256).min + 76); } + /// A positive dividend over a negative power of ten divisor, with the + /// quotient exponent exactly `type(int256).max`: `1e76 10^(max - 76)` over + /// `-1 10^-76` is exactly `-1e76 10^max`, which needs no shed digit, so it + /// returns. Only a `type(int256).min` dividend there has a 2^255 quotient. + function testDivNegativePowerOfTenDivisorAtMax() external pure { + int256 max = type(int256).max; + checkDiv(1e76, max - 76, -1, -76, -1e76, max); + checkDiv(-1e76, max - 76, -1, -76, 1e76, max); + checkDiv(type(int256).max, max - 76, -1, -76, -type(int256).max, max); + } + /// An unfull divisor at the floor overflows the quotient exponent for a /// numerator with a non-negative maximized exponent. function testDivUnfullDivisorExponentOverflow() external { diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.mainEquivalence.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.mainEquivalence.t.sol index b8e72db3..3dd9d316 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.mainEquivalence.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.mainEquivalence.t.sol @@ -538,15 +538,22 @@ contract LibDecimalFloatImplementationMainEquivalenceTest is Test { // #368: a positive 2^255 quotient below the floor, by each scale, // down to the last digit it keeps. for (int256 u = 1; u <= 76; u++) { - assertDiffers( - abi.encodeCall(this.mainDiv, (min, min + 76, -1e76, u)), - abi.encodeCall(this.prDiv, (min, min + 76, -1e76, u)) - ); - checkDiv(min, min + 76, -1e76, u); - checkDiv(min, min + 75, -1e75, u); + this.checkDivMinByMinusScaleBelowFloor(u); } } + /// One shed of the #368 loop, in its own call frame so memory does not + /// accumulate across the 76 sheds. + function checkDivMinByMinusScaleBelowFloor(int256 u) external view { + int256 min = type(int256).min; + assertDiffers( + abi.encodeCall(this.mainDiv, (min, min + 76, -1e76, u)), + abi.encodeCall(this.prDiv, (min, min + 76, -1e76, u)) + ); + checkDiv(min, min + 76, -1e76, u); + checkDiv(min, min + 75, -1e75, u); + } + function testMainEquivalenceAddFloorExamples() external view { int256 min = type(int256).min; assertDiffers(abi.encodeCall(this.mainAdd, (1, min, 1, min)), abi.encodeCall(this.prAdd, (1, min, 1, min)));