Core Contracts

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

Potential Use of Stale NFT Prices in `getNFTPrice` Function

Summary

The getNFTPrice function in the LendingPool contract retrieves the latest NFT price from the priceOracle. However, it does not check whether the returned price is stale. If the oracle fails to update the price for a prolonged period, the contract may rely on outdated data, leading to incorrect valuations and financial discrepancies. To ensure price freshness, the contract should implement a heartbeat mechanism, rejecting stale prices based on a predefined expiration time.

Vulnerability Details

Issue:

  • The function retrieves the latest NFT price along with the last update timestamp:

    (uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
  • However, it does not verify whether the lastUpdateTimestamp is recent.

  • If the oracle has not updated the price for an extended period, the function may return an outdated price, which could lead to incorrect loan valuations, liquidations, or lending decisions.

Root Cause:

  • The contract assumes that the oracle always provides fresh prices, but in reality, an oracle may experience delays, failures, or attacks that prevent timely updates.

  • Without a heartbeat check, the contract has no way of distinguishing between fresh and stale prices.

Expected Behavior:

  • The contract should check the last update timestamp against the current block timestamp and ensure that the price is recent.

  • If the price is outdated beyond a predefined threshold (e.g., HEARTBEAT_INTERVAL), the function should reject the price to prevent reliance on stale data.

Impact

  1. Incorrect Loan Valuations:

    • If the contract relies on an outdated price, it may allow borrowers to take loans based on an inflated NFT price, exposing the protocol to bad debt.

    • Conversely, if the price is stale and lower than the actual value, borrowers may receive less loan value than they should, leading to inefficiencies.

  2. Faulty Liquidations:

    • Liquidators may execute liquidations based on outdated prices, causing unfair liquidations or missed liquidation opportunities when the price is not accurately reflected.

Tools Used

  • Manual Code Review

Recommendations

1. Implement a Heartbeat Check

Before returning the NFT price, check if the last update timestamp is within a predefined HEARTBEAT_INTERVAL (e.g., 1 hour). If the price is outdated, revert the transaction.

Fixed Code:

uint256 constant HEARTBEAT_INTERVAL = 3600; // 1 hour in seconds
function getNFTPrice(uint256 tokenId) public view returns (uint256) {
(uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
if (price == 0) revert InvalidNFTPrice();
if (block.timestamp - lastUpdateTimestamp > HEARTBEAT_INTERVAL) revert StalePriceError();
return price;
}

Explanation:

  • The function now checks the time difference between the last price update and the current block timestamp.

  • If the difference exceeds HEARTBEAT_INTERVAL, it reverts, ensuring that only fresh prices are used.

2. Make HEARTBEAT_INTERVAL Configurable

Instead of hardcoding the HEARTBEAT_INTERVAL, allow governance or the admin to update it dynamically.

uint256 public heartbeatInterval = 3600; // Default to 1 hour
function setHeartbeatInterval(uint256 interval) external onlyAdmin {
heartbeatInterval = interval;
}

Benefit:

  • Allows flexibility to adjust the interval based on network conditions, oracle reliability, and security concerns.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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 4 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.