Core Contracts

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

RAACNFT Oracle Price Validation

Summary

RAACNFT's mint function relies solely on price > 0 validation from the oracle, without checking for data staleness or manipulation, enabling potential minting of NFTs at incorrect valuations.

Vulnerability Details

If raac_hp.tokenToHousePrice(_tokenId) returns 0, minting reverts, but there’s no check for stale data.

function mint(uint256 _tokenId, uint256 _amount) public override {
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);

Initial State:

  • Oracle (raac_hp) is operational

  • Price data exists for valid tokenIds

  • Attacker identifies oracle manipulation vector

Exploitation Steps

The RAACNFT contract blindly accepts any non-zero price from the oracle, creating a fundamental security gap. The code assumes price validity based solely on the non-zero check, ignoring critical validation of data freshness and authenticity.

function mint(uint256 _tokenId, uint256 _amount) public override {
uint256 price = raac_hp.tokenToHousePrice(_tokenId);
if(price == 0) { revert RAACNFT__HousePrice(); }
// Missing checks for:
// - Price timestamp
// - Price deviation
// - Oracle health
}
function mint(uint256 _tokenId, uint256 _amount) public override {
uint256 price = raac_hp.tokenToHousePrice(_tokenId);
if(price == 0) { revert RAACNFT__HousePrice(); }
if(price > _amount) { revert RAACNFT__InsufficientFundsMint(); }
token.safeTransferFrom(msg.sender, address(this), _amount);
_safeMint(msg.sender, _tokenId);
}

Resulting State:

  • NFTs minted at manipulated prices

  • Protocol accepts incorrect valuations

  • Asset-backing becomes misaligned

Similar to the Cream Finance oracle manipulation attack where stale prices led to $130M loss. Both cases demonstrate how implicit trust in oracle data without freshness/validity checks can lead to catastrophic asset mispricing.

Also Mango Markets oracle manipulation attack ($114M loss) demonstrates how insufficient oracle validation leads to catastrophic asset mispricing. Both cases show how DeFi protocols requiring precise asset valuation can be exploited through oracle trust assumptions.

Impact

NFTs for invalid tokenId could be minted if the oracle is compromised.

Tools Used

vs

Recommendations

Add a whitelist for valid tokenId ranges or implement oracle staleness checks.

function mint(uint256 _tokenId, uint256 _amount) public override {
// Validate tokenId range
if (_tokenId < MIN_TOKEN_ID || _tokenId > MAX_TOKEN_ID) {
revert RAACNFT__InvalidTokenId();
}
// Get price with staleness check
(uint256 price, uint256 timestamp) = raac_hp.getTokenPriceWithTimestamp(_tokenId);
// Validate price data
if (price == 0) { revert RAACNFT__HousePrice(); }
if (block.timestamp - timestamp > PRICE_STALENESS_THRESHOLD) {
revert RAACNFT__StalePrice();
}
if (price > _amount) { revert RAACNFT__InsufficientFundsMint(); }
// Execute mint
token.safeTransferFrom(msg.sender, address(this), _amount);
_safeMint(msg.sender, _tokenId);
}
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.