Summary
When healthFactor of position is less than threshold, user can initiates the liquidation of position. and there is grace period under which liquidation finalization should be done. But this also lead to liquidation of healthy position as well.
LendingPool.sol::initiateLiquidation()
->
function initiateLiquidation(address userAddress) external nonReentrant whenNotPaused {
if (isUnderLiquidation[userAddress]) revert UserAlreadyUnderLiquidation();
ReserveLibrary.updateReserveState(reserve, rateData);
UserData storage user = userData[userAddress];
if (healthFactor >= healthFactorLiquidationThreshold) revert HealthFactorTooLow();
isUnderLiquidation[userAddress] = true;
liquidationStartTime[userAddress] = block.timestamp;
emit LiquidationInitiated(msg.sender, userAddress);
}
StabilityPool.sol::liquidateBorrower()
->
function liquidateBorrower(address userAddress) external onlyManagerOrOwner nonReentrant whenNotPaused {
_update();
uint256 userDebt = lendingPool.getUserDebt(userAddress);
uint256 scaledUserDebt = WadRayMath.rayMul(userDebt, lendingPool.getNormalizedDebt());
if (userDebt == 0) revert InvalidAmount();
uint256 crvUSDBalance = crvUSDToken.balanceOf(address(this));
if (crvUSDBalance < scaledUserDebt) revert InsufficientBalance();
bool approveSuccess = crvUSDToken.approve(address(lendingPool), scaledUserDebt);
if (!approveSuccess) revert ApprovalFailed();
lendingPool.updateState();
lendingPool.finalizeLiquidation(userAddress);
emit BorrowerLiquidated(userAddress, scaledUserDebt);
}
Vulnerability Details
A position health factor was bad, so initialization is started.
now suppose before finalization, the health factor restored to healthy value.
but in liquidateBorrower()
it's not re-checked weather position's health is good or bad.
since, checking isn't done, it means heathy position will also be liquidated.
Impact
Loss to user and bad reputation to protocol as a healthy position is liquidated too.
Tools Used
Manual
Recommendations
Inside liquidateBorrower()
recheck the heath factor of position, and perform action accordingly.