The bug lies in the way collateral is verified during NFT withdrawals . Instead of properly adjusting the collateral value after removing an NFT, the contract compares either the total collateral or the raw difference (collateralValue - nftValue) against the user's debt scaled by the liquidation threshold. This calculation fails to ensure that, after an NFT is withdrawn, the remaining collateral still meets the required safety margin.
->
The root cause is an incorrect formula used in the collateral checks. In the withdrawNFT function, for example, the check is performed as:
if (collateralValue - nftValue < userDebt.percentMul(liquidationThreshold))
This comparison does not properly apply the liquidation threshold to the adjusted collateral value. Similarly, the borrow function uses the total collateral value without accounting for individual NFT withdrawals. The intended behavior is to ensure that after subtracting the NFT’s value, the remaining collateral (when scaled by the liquidation threshold) is still enough to cover the debt.
Consider the following scenario:
A user has total collateral valued at $1,000,000.
The user’s outstanding debt is $800,000.
The liquidation threshold is set at 80%, meaning that the remaining collateral must be at least 125% of the debt (or the debt should not exceed 80% of the collateral’s value).
The user wants to withdraw an NFT worth $300,000.
After the NFT is withdrawn, the remaining collateral would be $700,000. The correct safety check requires that 80% of $700,000 (which is $560,000) is greater than or equal to the debt. However, since $560,000 is less than the $800,000 debt, the withdrawal should be disallowed. If the contract instead compares the wrong values (for example, using the raw collateral value or misapplying the threshold), it might erroneously permit the withdrawal. This would leave the user undercollateralized, exposing the protocol to significant financial risk if the collateral value later declines further.
Because of this miscalculation, users can withdraw NFTs or borrow funds even when their remaining collateral is insufficient. This can lead to undercollateralized positions where the collateral backing the debt is lower than required, increasing the risk of defaults and potential protocol insolvency.
To fix the issue, the collateral check must be adjusted so that it applies the liquidation threshold to the remaining collateral value after subtracting the NFT being withdrawn. For example, in the withdrawNFT function, the condition should be modified as follows:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.