Core Contracts

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

Missing implementation of time-based update intervals in RAACHousePrices.sol to prevent frequent price manipulations

Summary

The contract lacks implementation of time-based update intervals to prevent frequent price manipulations, which could be exploited to manipulate liquidations in the LendingPool.

Vulnerability Details

The contract documentation states it "Implements a time-based update interval to prevent too frequent price updates" but no such protection exists. The setHousePrice() function updates prices without any cooldown period:

function setHousePrice(
uint256 _tokenId,
uint256 _amount
) external onlyOracle {
tokenToHousePrice[_tokenId] = _amount;
lastUpdateTimestamp = block.timestamp;
emit PriceUpdated(_tokenId, _amount);
}

This is particularly concerning because the LendingPool relies on these prices using RAACHousePrices::getLatestPrice() function to determine the current NFT Price https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/LendingPool/LendingPool.sol#L591-L592 for critical operations like:

  • Calculating collateral values

  • Determining borrowing capacity

  • Initiating liquidations

Impact

Without update interval protection, the owner of the RAACHousePriceOracle contract could:

  • Rapidly update prices to trigger unfair liquidations

  • Manipulate collateral values to allow excessive borrowing

  • Front-run transactions by updating prices right before user actions

Tools Used

  • Manual Review

Recommendations

Add a minimum update interval to the RAACHousePrices contract to prevent overly frequent updates:

contract RAACHousePrices is Ownable {
+ uint256 public constant MIN_UPDATE_INTERVAL = 14 days; // <== should be an adequate value
+ mapping(uint256 => uint256) public lastTokenUpdateTime;
function setHousePrice(uint256 _tokenId, uint256 _amount) external onlyOracle {
+ require(block.timestamp >= lastTokenUpdateTime[_tokenId] + MIN_UPDATE_INTERVAL, "Price update too frequent");
+ lastTokenUpdateTime[_tokenId] = block.timestamp;
tokenToHousePrice[_tokenId] = _amount;
lastUpdateTimestamp = block.timestamp;
emit PriceUpdated(_tokenId, _amount);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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