Core Contracts

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

Non-Token-Specific Price Update Timestamp in RAACHousePrices

Summary

The RAACHousePrices contract uses a single global lastUpdateTimestamp for all token price updates, rather than tracking timestamps individually per token. This prevents accurate staleness checks for individual token prices.

Vulnerability Details

In RAACHousePrices, the lastUpdateTimestamp is stored as a single state variable:

uint256 public lastUpdateTimestamp;

When prices are updated via setHousePrice(), it updates this global timestamp:

function setHousePrice(uint256 _tokenId, uint256 _amount) external onlyOracle {
tokenToHousePrice[_tokenId] = _amount;
lastUpdateTimestamp = block.timestamp;
emit PriceUpdated(_tokenId, _amount);
}
/**
* @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) {
// @audit the timestamp is not token-specific but just a global one
return (tokenToHousePrice[_tokenId], lastUpdateTimestamp);
}

This is problematic because:

  1. If house A's price is updated at t=100 and house B's price at t=200, house A will show lastUpdateTimestamp=200

  2. This makes it impossible to determine when a specific token's price was last updated

  3. Price staleness checks become unreliable as newer updates to any token mask the age of other token prices

  4. The contract comment in setHousePrice explicitly states "Updates timestamp for each token individually" which is violated

Impact

  • Inability to properly implement price staleness checks per token

  • Misleading timestamp information for token price updates

  • Potential acceptance of stale prices in the protocol and other dependent protocols.

Tools Used

Manual Review

Recommendations

Modify the contract to track timestamps per token:

contract RAACHousePrices is Ownable {
mapping(uint256 => uint256) public tokenToHousePrice;
mapping(uint256 => uint256) public tokenToTimestamp;
address public oracle;
function setHousePrice(uint256 _tokenId, uint256 _amount) external onlyOracle {
tokenToHousePrice[_tokenId] = _amount;
tokenToTimestamp[_tokenId] = block.timestamp;
emit PriceUpdated(_tokenId, _amount);
}
function getLatestPrice(uint256 _tokenId) external view returns (uint256, uint256) {
return (tokenToHousePrice[_tokenId], tokenToTimestamp[_tokenId]);
}
}
Updates

Lead Judging Commences

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

Give us feedback!