Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Valid

`LendingPool` allows users to borrow while being undercollateralized, allowing for bad debt

Summary

The LendingPool allows users to borrow funds if they have a healthy collateral factor. However, there seems to be an issue whenever the user's collateral is checked during borrowing, as it checks that the collateral is not lower than the current debt, multiplied by the liquidation threshold, which is initially set to be 8000 or 80% (basically allowing for under-collateralization). What is more, the functions that allow admins to set new liquidation threshold do not allow the value to be set to over 10000.


Vulnerability Details

Let's take a look at how the borrow() function in the LendingPool, checks the collateral:

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/LendingPool/LendingPool.sol#L341-L346

uint256 userTotalDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex) + amount;
// Ensure the user has enough collateral to cover the new debt
if (collateralValue < userTotalDebt.percentMul(liquidationThreshold)) {
revert NotEnoughCollateralToBorrow();
}

From the above, we can see that when borrowing, the current collateral of the user should only be bigger than liquidationThreshold % of the total debt, which includes the newly borrowed amount. Users can borrow while being under-collateralized, leading to accrual of bad debt.

The same issue is observed when users want to withdraw their NFTs:

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/LendingPool/LendingPool.sol#L298-L304

uint256 userDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex);
uint256 collateralValue = getUserCollateralValue(msg.sender);
uint256 nftValue = getNFTPrice(tokenId);
if (collateralValue - nftValue < userDebt.percentMul(liquidationThreshold)) {
revert WithdrawalWouldLeaveUserUnderCollateralized();
}

Users can withdraw while being under-collateralized.

Schematic Proof of Concept (PoC):

  1. Bob deposits NFTs worth $100,000.(one for 50k, one for 20k and one for 30k)

  2. Bob borrows $100,000, which passes, as he only has to have 80k worth of collateral.

  3. Bob withdraws his NFT that costs $20,000, as the check incorrectly passes.

  4. Bob does not repay his debt, effectively profiting $20,000 at the protocol’s expense.


Impact

  • Loss of protocol funds due to improper collateral checks.

  • Potential insolvency if exploited at scale.


Tools Used

  • Manual review


Recommendations

  • **Initialize the liquidation threshold to be more than 100% and allow for the setters to set it to more than 100%.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

LendingPool::borrow as well as withdrawNFT() reverses collateralization check, comparing collateral < debt*0.8 instead of collateral*0.8 > debt, allowing 125% borrowing vs intended 80%

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!