Core Contracts

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

Oracle configuration lacks staleness checks which could delay real estate liquidations

Relevant GitHub Links

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/primitives/RAACHousePrices.sol#L13

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/LendingPool/LendingPool.sol#L591

Summary

The LendingPool does not validate the staleness of house prices when calculating health factors, which could delay liquidations in illiquid real estate market conditions.

Vulnerability Details

The RAACHousePrices oracle and LendingPool interaction lacks staleness validation:

// RAACHousePrices.sol
contract RAACHousePrices is Ownable {
mapping(uint256 => uint256) public tokenToHousePrice;
uint256 public lastUpdateTimestamp; // tracks last update
}
// LendingPool.sol
function getNFTPrice(uint256 tokenId) public view returns (uint256) {
(uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
// @audit never checks staleness
if (price == 0) revert InvalidNFTPrice();
return price;
}

While price staleness could affect health factor calculations:

function calculateHealthFactor(address userAddress) public view returns (uint256) {
uint256 collateralValue = getUserCollateralValue(userAddress);
uint256 userDebt = getUserDebt(userAddress);
if (userDebt < 1) return type(uint256).max;
uint256 collateralThreshold = collateralValue.percentMul(liquidationThreshold);
return (collateralThreshold * 1e18) / userDebt;
}

Impact

  • Potential delay in liquidations during market downturns

  • Increased bad debt possible

  • StabilityPool protected by manager intervention ability

Tools Used

Manual Review

Recommendations

Add configurable staleness threshold with governance control:

contract LendingPool {
uint256 public maxPriceStaleness = 7 days; // Governable
function getNFTPrice(uint256 tokenId) public view returns (uint256) {
(uint256 price, uint256 lastUpdateTimestamp) = priceOracle.getLatestPrice(tokenId);
if (price == 0) revert InvalidNFTPrice();
if (block.timestamp - lastUpdateTimestamp > maxPriceStaleness) {
revert StalePriceNotAllowed();
}
return price;
}
}
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!