diff --git a/onchain/src/Optimizer.sol b/onchain/src/Optimizer.sol index 08b8769..1fd2e82 100644 --- a/onchain/src/Optimizer.sol +++ b/onchain/src/Optimizer.sol @@ -361,11 +361,13 @@ contract Optimizer is Initializable, UUPSUpgradeable, IOptimizer { virtual returns (uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth) { - // Guard against non-zero shift and negative mantissa. + // Guard against non-zero shift, negative mantissa, and overflow. + // All 8 slots must be in [0, 1e18] — the uniform dyadic range. // shift is reserved for future use; uint256() cast silently wraps negatives. for (uint256 k; k < 8; k++) { require(inputs[k].shift == 0, "shift not yet supported"); require(inputs[k].mantissa >= 0, "negative mantissa"); + require(inputs[k].mantissa <= 1e18, "mantissa overflow"); } // Extract slots 0 and 1 (shift=0 enforced above — mantissa IS the value) uint256 percentageStaked = uint256(inputs[0].mantissa); diff --git a/onchain/src/OptimizerV3Push3Lib.sol b/onchain/src/OptimizerV3Push3Lib.sol index da3774b..0a7f870 100644 --- a/onchain/src/OptimizerV3Push3Lib.sol +++ b/onchain/src/OptimizerV3Push3Lib.sol @@ -17,14 +17,13 @@ library OptimizerV3Push3Lib { pure returns (uint256 ci, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth) { - // Validate mantissa for percentageStaked - 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). + // Validate that shift is 0 (future-only field, not yet supported), + // that no mantissa is negative (uint256 cast silently wraps negatives), + // and that all slots are within the [0, 1e18] dyadic range. for (uint256 k = 0; k < 8; k++) { require(inputs[k].shift == 0, "shift not yet supported"); require(inputs[k].mantissa >= 0, "negative mantissa"); + require(inputs[k].mantissa <= 1e18, "mantissa overflow"); } uint256 percentagestaked = uint256(uint256(inputs[0].mantissa));