fix: No negative-mantissa guard in OptimizerV3Push3 (#650) (#966)

Fixes #650

## Changes
Add require(inputs[k].mantissa >= 0, 'negative mantissa') for all 8 input slots inside the existing validation loop in OptimizerV3Push3.sol, matching the guard pattern in Optimizer.sol lines 372-374. Added 3 tests covering slots 0, 1, and 5 to confirm revert on negative mantissa.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/966
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
This commit is contained in:
johba 2026-03-19 11:30:18 +01:00
parent bab3a6751d
commit 5c4ceaf78d
2 changed files with 26 additions and 0 deletions

View file

@ -56,8 +56,10 @@ contract OptimizerV3Push3 is IOptimizer {
require(inputs[0].mantissa <= 1e18, "mantissa overflow");
// Validate that shift is 0 (future-only field, not yet supported)
// and that no mantissa is negative (uint256 cast silently wraps negatives).
for (uint256 k = 0; k < 8; k++) {
require(inputs[k].shift == 0, "shift not yet supported");
require(inputs[k].mantissa >= 0, "negative mantissa");
}
uint256 percentagestaked = uint256(uint256(inputs[0].mantissa));

View file

@ -200,6 +200,30 @@ contract OptimizerV3Push3Test is Test {
_assertBull(ci, as_, aw, dd);
}
// ---- Negative mantissa guards ----
function testNegativeMantissaSlot0Reverts() public {
OptimizerInput[8] memory inp;
inp[0] = OptimizerInput({mantissa: -1, shift: 0});
vm.expectRevert("negative mantissa");
push3.calculateParams(inp);
}
function testNegativeMantissaSlot1Reverts() public {
OptimizerInput[8] memory inp;
inp[0] = OptimizerInput({mantissa: int256(_pct(95)), shift: 0});
inp[1] = OptimizerInput({mantissa: -1, shift: 0});
vm.expectRevert("negative mantissa");
push3.calculateParams(inp);
}
function testNegativeMantissaSlot5Reverts() public {
OptimizerInput[8] memory inp;
inp[5] = OptimizerInput({mantissa: -1, shift: 0});
vm.expectRevert("negative mantissa");
push3.calculateParams(inp);
}
// ---- Fuzz ----
function testFuzzNeverReverts(uint256 percentageStaked, uint256 averageTaxRate) public view {