Summary
The withdrawNFT functions have incorrect calculation in the if condition for collateral .
Vulnerability Details
In withdrawNFT Function , userDebt.percentMul(liquidationThreshold) is compared to collateralValue - nftValue , which is incorrect .
If we withdraw NFT , the collateral value decreses , then the debt should also be decreased by liquidationThreshold % of the new collateral value .
if (collateralValue - nftValue < userDebt.percentMul(liquidationThreshold)) {
revert WithdrawalWouldLeaveUserUnderCollateralized();
}
function withdrawNFT(uint256 tokenId) external nonReentrant whenNotPaused {
if (isUnderLiquidation[msg.sender]) revert CannotWithdrawUnderLiquidation();
UserData storage user = userData[msg.sender];
if (!user.depositedNFTs[tokenId]) revert NFTNotDeposited();
ReserveLibrary.updateReserveState(reserve, rateData);
uint256 userDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex);
uint256 collateralValue = getUserCollateralValue(msg.sender);
uint256 nftValue = getNFTPrice(tokenId);
if (collateralValue - nftValue < userDebt.percentMul(liquidationThreshold)) {
revert WithdrawalWouldLeaveUserUnderCollateralized();
}
for (uint256 i = 0; i < user.nftTokenIds.length; i++) {
if (user.nftTokenIds[i] == tokenId) {
user.nftTokenIds[i] = user.nftTokenIds[user.nftTokenIds.length - 1];
user.nftTokenIds.pop();
break;
}
}
user.depositedNFTs[tokenId] = false;
raacNFT.safeTransferFrom(address(this), msg.sender, tokenId);
emit NFTWithdrawn(msg.sender, tokenId);
}
Impact
The collateral value will be much lower then the actual liquidationThreshold of the collateral value .
Debt value will be greater then the liquidationThreshold , which is incorrect .
Tools Used
Manual Review
Recommendations
-if (collateral-nftValue< userDebt.percentMul(liquidationThreshold)){ }
+if ((collateralVaule - nftValue).percentMul(liquidationThreshold) < userDebt){
revert WithdrawalWouldLeaveUserUnderCollateralized()
;}