Core Contracts

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

Lack of stale price verification in `RAACNFT::mint`

Summary

The RAACNFT::mint function retrieves prices using RAACHousePrices::tokenToHousePrice, which only returns the price without a timestamp. This prevents the contract from verifying whether the retrieved price is stale, potentially allowing users to mint NFTs using outdated price data.

Vulnerability Details

Problem Description

The RAACHousePrices contract provides two functions for retrieving house prices:

  1. tokenToHousePrice(address token) → uint256

    • Returns the price of the token but does not include the timestamp.

  2. getLatestPrice(address token) → (uint256 price, uint256 timestamp)

    • Returns both the latest price and the corresponding timestamp, allowing verification of price freshness.

However, RAACNFT::mint currently uses tokenToHousePrice instead of getLatestPrice, meaning it does not check whether the price is stale. If an outdated price remains unchanged in RAACHousePrices, users could potentially mint NFTs based on an invalid price, leading to economic discrepancies.

the price staleness is possible if the RAACHousePriceOracle::fulfillRequest function receives an error response, which indicates an issue with the Chainlink function. Since the contract does not properly handle such errors, the outdated price could persist, leading to inaccurate NFT minting prices.

Proof of Concept (PoC)

Consider the following scenario:

  1. The price is updated using RAACHousePrices::setHousePrice.

  2. Due to a delay or malfunction in chainlink function, the price is not updated for an extended period.

  3. A user calls RAACNFT::mint, which retrieves the price using tokenToHousePrice.

  4. The minting process succeeds without verifying whether the price is up-to-date.

  5. An attacker could exploit this by minting NFTs at a price that no longer reflects real conditions.

Impact

  • Minting NFTs at Incorrect Prices: Without a timestamp verification, NFTs can be minted based on outdated or manipulated price data.

  • Potential Economic Loss: If house prices change significantly, users might exploit stale prices to gain unfair advantages.

Tools Used

Manual Review

Recommendations

Modify RAACNFT::mint to use getLatestPrice instead of tokenToHousePrice and introduce a time threshold to verify price freshness before minting.

function mint(uint256 _tokenId, uint256 _amount) public override {
// @audit-issue not verifying the price updated time
+ (uint256 price, uint256 timestamp) = housePrices.getLatestPrice(token);
+ require(block.timestamp - timestamp < MAX_PRICE_AGE, "Stale price detected");
- uint256 price = raac_hp.tokenToHousePrice(_tokenId);
if(price == 0) { revert RAACNFT__HousePrice(); }
if(price > _amount) { revert RAACNFT__InsufficientFundsMint(); }
// transfer erc20 from user to contract - requires pre-approval from user
token.safeTransferFrom(msg.sender, address(this), _amount);
// mint tokenId to user
_safeMint(msg.sender, _tokenId);
// If user approved more than necessary, refund the difference
if (_amount > price) {
uint256 refundAmount = _amount - price;
token.safeTransfer(msg.sender, refundAmount);
}
emit NFTMinted(msg.sender, _tokenId, price);
}

This ensures that only recent price data is used for minting NFTs, preventing stale price exploits and maintaining economic fairness in the contract.

Updates

Lead Judging Commences

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