Core Contracts

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

`RAACMinter` can use outdated data to compute utilization rate, leading to incorrect RAAC minting pace

Vulnerability Details

When calculating the utilization rate at RAACMinter::getUtilizationRate(), the LendingPool is called, specifically LendingPool::getNormalizedDebt(). This function return value depends on the debt interest index which always increases and changes. Thus, every time its value is needed the lending pool should update the indexes.

And the problem is precisely that, RAACMinter wil use an outdated debt index because the getNormalizedDebt() does not update LendingPool
indexes.

Proof Of Concept

You can see that there is no call to update indexes on the lending pool in any of the execution paths that use the getUtilizationRate():

  • RAACMinter::updateEmissionRate() public -> RAACMinter::calculateNewEmissionRate() internal -> RAACMinter::getUtilizationRate() internal

See no third party calls in updateEmissionRate() here. Neither in calculateEmissionRate() here.

  • RAACMinter::tick() external callable by anyone -> RAACMinter::updateEmissionRate() public

No third party calls in tick() either, see here. And it can only be updated once every X seconds interval due to the emissionUpdateInterval check. So once a faulty calculation is done it remains like that for the whole interval.

  • StabilityPool::_mintRAACRewards() -> RAACMinter::tick()

  • StabilityPool::deposit() || withdraw() -> StabilityPool::_update() -> StabilityPool::_mintRAACRewards()

Deposit and withdraw call _update() right at the beginning of their execution, so it doesn't matter if they later update the lending pool, they will use an outdated value for the calculation of utilization rate. See deposit here, see withdraw here.

Impact

There can be wrong utilization rate calculations if no other actions is taken on the LendingPool previously in the same block. Likely underestimating how much debt there is actually in the system. Utilization rate is used to determine how much RAAC to mint. Wrongly calculating it will slower down or accelerate the minting process.

If a user calls an action that updates interest and this actions is executed previous to the RAACMinting, then the utilization rate will be correct. As the indexes will be updated. But notice that not always this will be the case. Maybe in 1 block no-one interacts with the LendingPool yet someone deposits in the StabilityPool, triggering a RAACMinter call.

Recommendations

Call LendingPool::updateState() to update the lending pool indexes before calling LendingPool::getNormalizedDebt() when calculatin the utilization rate on RAACMinter contract:

function getUtilizationRate() internal view returns (uint256) {
+ lendingPool.updateState();
uint256 totalBorrowed = lendingPool.getNormalizedDebt();
// more code...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

LendingPool::getNormalizedIncome() and getNormalizedDebt() returns stale data without updating state first, causing RToken calculations to use outdated values

Support

FAQs

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