Summary
The checkUpkeep function in LiquidationKeeper has insufficient bounds validation that could lead to inefficient or failed liquidation operations.
Vulnerability Details
In the checkUpkeep function:
function checkUpkeep(bytes calldata checkData)
external
view
returns (bool upkeepNeeded, bytes memory performData)
{
(uint256 checkLowerBound, uint256 checkUpperBound, uint256 performLowerBound, uint256 performUpperBound) =
abi.decode(checkData, (uint256, uint256, uint256, uint256));
if (checkLowerBound >= checkUpperBound || performLowerBound >= performUpperBound) {
revert Errors.InvalidBounds();
}
}
The current validation only checks if lower bounds are less than upper bounds, but misses several important validations:
No check for non-zero values
No maximum range limitation
No validation of the relationship between check and perform bounds
No protection against extremely large ranges that could cause out-of-gas issues
Impact
Potential DOS through excessive gas consumption
Inefficient liquidation operations
Possible missed liquidations due to improper bound settings
System performance degradation with extremely large ranges
Tools Used
Manual code review
Slither
Gas analyzer
Recommendations
1/ Implement comprehensive bounds validation:
/Users/jojo/Library/Mobile Documents/com~apple~CloudDocs/AUDIT/2025-01-zaros-part-2/src/external/chainlink/keepers/liquidation/LiquidationKeeper.sol
function checkUpkeep(bytes calldata checkData)
external
view
returns (bool upkeepNeeded, bytes memory performData)
{
(uint256 checkLowerBound, uint256 checkUpperBound, uint256 performLowerBound, uint256 performUpperBound) =
abi.decode(checkData, (uint256, uint256, uint256, uint256));
if (checkLowerBound == 0 || checkUpperBound == 0 || performLowerBound == 0 || performUpperBound == 0) {
revert Errors.ZeroBounds();
}
if (checkLowerBound >= checkUpperBound || performLowerBound >= performUpperBound) {
revert Errors.InvalidBounds();
}
if (checkUpperBound - checkLowerBound > MAX_CHECK_RANGE) {
revert Errors.RangeTooLarge();
}
if (performUpperBound - performLowerBound > MAX_PERFORM_RANGE) {
revert Errors.RangeTooLarge();
}
if (performUpperBound > checkUpperBound) {
revert Errors.InvalidBoundRelation();
}
}
uint256 private constant MAX_CHECK_RANGE = 1000;
uint256 private constant MAX_PERFORM_RANGE = 100;
2/Add events for monitoring:
event BoundsValidated(
uint256 checkLowerBound,
uint256 checkUpperBound,
uint256 performLowerBound,
uint256 performUpperBound
);
3/ Consider implementing adaptive bounds based on gas costs and network conditions.
These changes will improve the robustness and efficiency of the liquidation process while preventing potential DOS attacks or system inefficiencies.