Core Contracts

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

Stale Oracle Data Allows Undercollateralized Loans and Protocol Insolvency

Summary

A critical vulnerability exists in the getNFTPrice function (Lines 484-489) of the LendingPool contract. The function fails to validate the freshness of price data from the IRAACHousePrices oracle, enabling attackers to exploit stale NFT valuations. This allows overborrowing against inflated collateral and delays liquidations until price updates, directly threatening protocol solvency.


Vulnerability Details

Risk Type: High

Technical Analysis

The getNFTPrice function retrieves NFT prices from an external oracle but does not verify if the returned lastUpdateTimestamp is recent:

function getNFTPrice(uint256 tokenId) public view returns (uint256) {
(uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
if (price == 0) revert InvalidNFTPrice();
return price; // No timestamp validation
}

This creates two attack vectors:

  1. Overborrowing During Oracle Downtime
    If the oracle stops updating (e.g., due to technical failure), users can borrow against stale high prices, creating undercollateralized positions.

  2. Liquidation Avoidance
    Borrowers can maintain unhealthy positions indefinitely if the oracle halts updates, preventing liquidators from triggering repayments.


Impact

  1. Protocol Insolvency
    Stale prices enable users to borrow more than their collateral’s real value. When prices correct, the protocol is left with unrecoverable debt.

  2. Delayed Liquidations
    Undercollateralized positions avoid liquidation until the oracle resumes updates, increasing systemic risk.

  3. Oracle Manipulation
    Attackers could intentionally freeze oracle updates during market volatility to exploit price discrepancies.


Tools Used

  1. Hardhat: Simulated oracle downtime and validated borrowing/liquidation logic.

  2. Manual Code Review: Identified missing timestamp checks in getNFTPrice.

  3. Slither: Detected unvalidated external calls to IRAACHousePrices.


Proof of Concept (PoC)

Test Setup

  1. Malicious Oracle Contract
    Deploys an oracle that reports stale NFT prices:

    contract MaliciousOracle {
    uint256 public constant STALE_PRICE = 100 ether;
    uint256 public lastUpdateTimestamp;
    function getLatestPrice(uint256) external view returns (uint256, uint256) {
    return (STALE_PRICE, lastUpdateTimestamp); // Always returns 100 ETH
    }
    function setTimestamp(uint256 _time) external {
    lastUpdateTimestamp = _time; // Allows timestamp manipulation
    }
    }
  2. Exploit Test
    Demonstrates borrowing against stale data and subsequent insolvency:

    it("Exploit: Borrow using stale NFT price to create bad debt", async () => {
    // 1. Deposit NFT with stale price (100 ETH)
    await pool.connect(user).depositNFT(1);
    // 2. Borrow 80 ETH (80% of 100 ETH collateral)
    await pool.connect(user).borrow(ethers.utils.parseEther("80"));
    // 3. Update oracle to real price (50 ETH)
    await oracle.setTimestamp(Math.floor(Date.now() / 1000));
    // 4. Verify bad debt (50 ETH collateral < 80 ETH debt)
    const userDebt = await pool.getUserDebt(user.address);
    const collateralValue = await pool.getUserCollateralValue(user.address);
    expect(collateralValue.lt(userDebt)).to.be.true; // Passes
    });

Recommendations

Immediate Fix

Add time-based validation to reject stale prices in getNFTPrice:

function getNFTPrice(uint256 tokenId) public view returns (uint256) {
(uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
if (price == 0) revert InvalidNFTPrice();
if (block.timestamp - lastUpdateTimestamp > 24 hours) revert StalePriceData(); // Reject old data
return price;
}

Long-Term Mitigation

  1. Decentralized Oracle Fallback:
    Integrate a secondary oracle (e.g., Chainlink) to cross-validate prices.

  2. Circuit Breakers:
    Pause borrowing if oracle data is stale beyond a threshold.


Conclusion

This vulnerability allows attackers to manipulate collateral valuations by exploiting stale oracle data, directly jeopardizing protocol solvency. Implementing timestamp validation and decentralized price feeds is critical to prevent systemic collapse.

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!