Core Contracts

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

Missing oracle staleness check in `LendingPool::getNFTPrice` can lead to usage of outdated NFT prices in LendingPool

Summary

The getNFTPrice function in the LendingPool contract fails to implement oracle price staleness validation, allowing outdated NFT prices to be used in critical financial calculations. This could lead to incorrect collateralization ratios and potentially unfair liquidations.

Vulnerability Details

The following function retrieves NFT prices but fails to validate the lastUpdateTimestamp against a maximum acceptable age. This means that prices that could be hours, days, or even weeks old would be considered valid.

This function is used in several critical contexts:

  1. getUserCollateralValue() - For calculating total collateral value

  2. calculateHealthFactor() - For determining liquidation eligibility

  3. withdrawNFT() - For validating collateralization after NFT withdrawal

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

Impact

The vulnerability could lead to:

  1. Incorrect Collateralization:

    • Users could borrow against overvalued collateral if prices have decreased

    • System could prevent legitimate withdrawals if prices have increased

  2. Unfair Liquidations:

    • Users could be liquidated based on outdated low prices

    • Users could avoid liquidation despite being undercollateralized

Tools Used

Manual code review

Recommendations

Add a staleness check with a configurable maximum age for prices:

+ uint256 public constant MAX_PRICE_AGE = 1 hours; // Or other appropriate duration
function getNFTPrice(uint256 tokenId) public view returns (uint256) {
(uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
if (price == 0) revert InvalidNFTPrice();
+ if (block.timestamp - lastUpdateTimestamp > MAX_PRICE_AGE) {
+ revert StalePriceError(tokenId, lastUpdateTimestamp);
+ }
return price;
}
+ error StalePriceError(uint256 tokenId, uint256 lastUpdate);
Updates

Lead Judging Commences

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

LendingPool::getNFTPrice or getPrimeRate doesn't validate timestamp staleness despite claiming to, allowing users to exploit outdated collateral values during price drops

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

LendingPool::getNFTPrice or getPrimeRate doesn't validate timestamp staleness despite claiming to, allowing users to exploit outdated collateral values during price drops

Support

FAQs

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

Give us feedback!