Core Contracts

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

Stale house prices when minting RAACNFT

Summary

The mint() function in RAACNFT contract uses price data from the oracle without validating whether the price is stale, allowing potential price manipulation attacks through outdated price data.

Vulnerability Details

In the RAACNFT contract, the mint() function retrieves the house price from the RAACHousePrices oracle contract using raac_hp.tokenToHousePrice(_tokenId). However, it only checks if the price is non-zero but fails to verify whether this price is recent/fresh enough to be used.

Looking at the RAACHousePrices contract, we can see that it maintains a lastUpdateTimestamp which gets updated whenever a price is set. This timestamp is accessible via the getLatestPrice() function, but RAACNFT doesn't utilize this information.

// In RAACNFT.sol
function mint(uint256 _tokenId, uint256 _amount) public override {
// @audit No staleness check here
uint256 price = raac_hp.tokenToHousePrice(_tokenId);
if (price == 0) revert RAACNFT__HousePrice();
if (price > _amount) revert RAACNFT__InsufficientFundsMint();
...
}

The RAACHousePrices contract provides a way to get both price and timestamp:

function getLatestPrice(uint256 _tokenId) external view returns (uint256, uint256) {
return (tokenToHousePrice[_tokenId], lastUpdateTimestamp);
}

This vulnerability becomes particularly dangerous in scenarios where;

  • The oracle becomes unavailable or fails to update prices in a timely manner

  • house price changes rapidly (just imagine what if a house catches fire or is destroyed suddenly)

In such cases, users might end up minting NFTs at outdated prices that don't reflect the current market value, leading to potential financial losses.

PoC

  1. Oracle sets house price for TokenID #1 at 100,000 usd

  2. Market conditions change, house value increases to 150,000 usd

  3. Oracle fails to update the price due to technical issues

  4. Attacker monitors the situation and mints TokenID #1 at the stale price of 100,000 usd

  5. Attacker profits from the difference between actual market value and stale price

Impact

  • Users might mint NFTs at incorrect prices

  • Protocol could suffer financial losses due to mispriced assets

  • Potential for price manipulation attacks

  • Loss of trust in the protocol's pricing mechanism

Tools Used

Manual Review

Recommendations

Implement a staleness check in the mint function:

function mint(uint256 _tokenId, uint256 _amount) public {
(uint256 price, uint256 lastUpdate) = raac_hp.getLatestPrice(_tokenId);
if (block.timestamp - lastUpdate > MAXIMUM_PRICE_AGE)
revert RAACNFT__StalePrice();
...
}
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.