Core Contracts

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

Shared variable overwrite for last update timestamp in RAACHousePrices

Summary

The RAACHousePrices contract uses an update timestamp variable that is shared for all NFTs, leading to a condition where each call to setHousePrices(..) overwrites this variable.

Vulnerability Details

The contract RAACHousePrices.sol:L17 has a variable called lastUpdateTimestamp. It can hold a single uint256 value. The function setHousePrice(..)in L49 and getLatestPrice(..)in L34 both utilize this variable. As a result, whenever the price is set for a single NFT, the variable is overwritten and the last update timestamp is reported for all NFTs, even though only a single token ID had its price updated.

/// @notice Timestamp of the last price update
uint256 public lastUpdateTimestamp;
...
/**
* @notice Retrieves the latest price and update timestamp for a given token
* @param _tokenId The ID of the RAAC token
* @return The latest price and the timestamp of the last update
*
* Returns token-specific update timestamp
*/
function getLatestPrice(
uint256 _tokenId
) external view returns (uint256, uint256) {
return (tokenToHousePrice[_tokenId], lastUpdateTimestamp);
}
...
/**
* @notice Allows the owner to set the house price for a token
* @param _tokenId The ID of the RAAC token
* @param _amount The price to set for the house in USD
*
* Updates timestamp for each token individually
*/
function setHousePrice(
uint256 _tokenId,
uint256 _amount
) external onlyOracle {
tokenToHousePrice[_tokenId] = _amount;
lastUpdateTimestamp = block.timestamp;
emit PriceUpdated(_tokenId, _amount);
}

Impact

Incorrect update timestamps will cause NFT related transactions to execute at an incorrect price, leading to financial loss for the protocol or the users (depending on the direction of the price error).

Tools Used

  • Manual review

Recommendations

The lastUpdateTimestamp should be a mapping and the relevant functions (setHousePrice, getLatestPrice) should set/get the last update timestamp that corresponds to a specific token id.

mapping(uint256 => uint256) public lastUpdateTimestamp;
function getLatestPrice(uint256 _tokenId) external view returns (uint256, uint256) {
return (tokenToHousePrice[_tokenId], lastUpdateTimestamp[_tokenId]);
}
function setHousePrice(uint256 _tokenId, uint256 _amount) external onlyOracle {
tokenToHousePrice[_tokenId] = _amount;
lastUpdateTimestamp[_tokenId] = block.timestamp;
emit PriceUpdated(_tokenId, _amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACHousePrices uses a single global lastUpdateTimestamp for all NFTs instead of per-token tracking, causing misleading price freshness data

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACHousePrices uses a single global lastUpdateTimestamp for all NFTs instead of per-token tracking, causing misleading price freshness data

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.