Description
In contracts/libraries/math/InterestRates.sol, the function _toQuadruplePrecisionInt (line 86-95) has a rounding bug for negative inputs.
Code
function _toQuadruplePrecisionInt(int256 number, int256 decimals) private pure returns (bytes16) {
if (number % decimals > 0) { // <-- never true for negative numbers
number += 1;
}
bytes16 nominator = ABDKMathQuad.fromInt(number);
bytes16 denominator = ABDKMathQuad.fromInt(decimals);
bytes16 fraction = ABDKMathQuad.div(nominator, denominator);
return fraction;
}
Problem
In Solidity, the modulo operator preserves the sign of the dividend. For negative number:
(-7) % 3 == -1 (not 2)
- Since
-1 > 0 is false, the number += 1 rounding is skipped
The unsigned version _toQuadruplePrecision (line 73-83) works correctly because uint256 % uint256 is always non-negative.
Impact
When negative values pass through _toQuadruplePrecisionInt, they miss the rounding adjustment that the unsigned version applies. The difference is approximately 1/decimals per call (dust-level), but it creates an asymmetry between positive and negative interest calculations.
Suggested Fix
function _toQuadruplePrecisionInt(int256 number, int256 decimals) private pure returns (bytes16) {
if (number % decimals != 0) {
number += 1;
}
// ...
}
Or for direction-aware rounding:
int256 remainder = number % decimals;
if (remainder > 0) {
number += 1;
} else if (remainder < 0) {
number -= 1;
}
Description
In
contracts/libraries/math/InterestRates.sol, the function_toQuadruplePrecisionInt(line 86-95) has a rounding bug for negative inputs.Code
Problem
In Solidity, the modulo operator preserves the sign of the dividend. For negative
number:(-7) % 3 == -1(not2)-1 > 0isfalse, thenumber += 1rounding is skippedThe unsigned version
_toQuadruplePrecision(line 73-83) works correctly becauseuint256 % uint256is always non-negative.Impact
When negative values pass through
_toQuadruplePrecisionInt, they miss the rounding adjustment that the unsigned version applies. The difference is approximately 1/decimals per call (dust-level), but it creates an asymmetry between positive and negative interest calculations.Suggested Fix
Or for direction-aware rounding: