Core Contracts

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

**Risk of Using Stale NFT Prices in** **`getNFTPrice`** **Function**

Summary

The getNFTPrice function in the LendingPool contract fetches the latest NFT price from the priceOracle, but it does not check if the retrieved price is up to date. If the oracle fails to refresh the price for an extended period, the contract might rely on outdated data, leading to inaccurate valuations and financial discrepancies. To address this, the contract should implement a heartbeat mechanism to reject stale prices based on a defined expiration time, ensuring only fresh prices are used.


Vulnerability Details

Issue:

  • The function retrieves the most recent NFT price and its corresponding last update timestamp from the price oracle:

    (uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
  • However, there is no check to confirm if the lastUpdateTimestamp is recent.

  • If the price has not been updated for a long period, the contract may return a stale price, leading to incorrect loan valuations, miscalculations in liquidations, or poor lending decisions.

Root Cause:

  • The contract assumes that the price oracle always provides fresh, up-to-date prices, but in reality, oracles may experience delays, failures, or be vulnerable to attacks.

  • Without a heartbeat check, the contract cannot differentiate between fresh and outdated prices, leading to potential issues in operations.

Expected Behavior:

  • The contract should compare the last update timestamp to the current block timestamp, ensuring the price is recent.

  • If the price is outdated beyond a predefined threshold (e.g., HEARTBEAT_INTERVAL), the contract should reject the price and prevent its use.


Impact

  1. Inaccurate Loan Valuations:

    • Using stale prices may allow borrowers to take loans based on overinflated NFT prices, exposing the protocol to bad debt.

    • Conversely, outdated prices lower than the actual value could result in under-collateralized loans, harming borrowers and lenders alike.

  2. Improper Liquidations:

    • Liquidators may act on incorrect prices, leading to unfair liquidations or missed opportunities if the NFT value is not accurately reflected.


Tools Used

  • Manual Code Review


Recommendations

1. Implement a Heartbeat Check

Before returning the NFT price, compare the last update timestamp with the current block timestamp. If the price is outdated, reject it.

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 compares the time difference between the last price update and the current block timestamp.

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

2. Make HEARTBEAT_INTERVAL Configurable

Allow governance or an admin to modify the HEARTBEAT_INTERVAL to accommodate changing network conditions and oracle reliability.

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

Benefit:

  • This flexibility allows the protocol to adjust the heartbeat interval according to network performance and oracle reliability.

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!