Core Contracts

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

Missing Stale Price Check in Oracle Price House and Prime rate Updates Contracts

Description

The RAACPrimeRateOracle and RAACHousePriceOracle contracts are major components that update key economic parameters such as primeRate and housePrice in the lending protocol. The prime rate determines borrowing costs while house prices determine collateral values and liquidation triggers.
Both contracts lack staleness checks in their _processResponse functions, allowing outdated price data to be used. This creates a significant risk as the protocol continues using potentially stale or incorrect data when oracle updates fail or are delayed.

Vulnerability Details

RAACPrimeRateOracle:

function _processResponse(bytes memory response) internal override {
@> lastPrimeRate = abi.decode(response, (uint256));
@> lastUpdateTimestamp = block.timestamp;
@> lendingPool.setPrimeRate(lastPrimeRate);
emit PrimeRateUpdated(lastPrimeRate);
}

RAACHousePriceORacle:

function _processResponse(bytes memory response) internal override {
@> uint256 price = abi.decode(response, (uint256));
@> housePrices.setHousePrice(lastHouseId, price);
emit HousePriceUpdated(lastHouseId, price);
}

Risk

Likelihood: High

  • Oracle networks experience downtime and delays

  • Network congestion prevents timely updates

  • Oracle nodes can abandon the feed

Impact: Medium

Recommendations

For RAACPrimeRateOracle contract:

function _processResponse(bytes memory response) internal override {
+ uint256 MAX_STALENESS = 1 hour;
+ if (block.timestamp - lastUpdateTimestamp > MAX_STALENESS) {
+ revert StaleOracleData();
+ }
lastPrimeRate = abi.decode(response, (uint256));
lastUpdateTimestamp = block.timestamp;
lendingPool.setPrimeRate(lastPrimeRate);
emit PrimeRateUpdated(lastPrimeRate);
}

For RAACHousePriceOracle contract:

function _processResponse(bytes memory response) internal override {
+ uint256 MAX_STALENESS = 1 hour;
+ if(block.timestamp - lastUpdateTimestamp > MAX_STALENESS){
+ revert StaleOracleData();
+ }
uint256 price = abi.decode(response, (uint256));
housePrices.setHousePrice(lastHouseId, price);
+ lastUpdateTimestamp = block.timestamp;
emit HousePriceUpdated(lastHouseId, price);
}

Documentation: https://blog.openzeppelin.com/secure-smart-contract-guidelines-the-dangers-of-price-oracles

Updates

Lead Judging Commences

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

Give us feedback!