Core Contracts

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

Inaccurate Emission Rate Calculation Due to Outdated Utilization Data

Summary

The RAAC emission rate calculation in RAACMinter.sol relies on getUtilizationRate(), which fetches data from lendingPool.getNormalizedDebt() and stabilityPool.getTotalDeposits(). However, the lending pool state is not updated before emissions are recalculated at this stage, leading to outdated values being used. This results in systematically underestimated emissions, reducing the RAAC rewards distributed to users. Given that getNormalizedDebt() grows exponentially while getTotalDeposits() increases linearly, failure to update state suppresses emissions more than expected, discouraging user participation in the protocol.

Vulnerability Details

The core issue lies in the first if logic of tick() function in RAACMinter.sol, which triggers emission rate updates as follows:

RAACMinter.sol#L256-L262

/**
* @dev Triggers the minting process and updates the emission rate if the interval has passed
*/
function tick() external nonReentrant whenNotPaused {
if (emissionUpdateInterval == 0 || block.timestamp >= lastEmissionUpdateTimestamp + emissionUpdateInterval) {
updateEmissionRate();
}

updateEmissionRate() will first trigger calculateNewEmissionRate() which further triggers getUtilizationRate():

RAACMinter.sol#L241-L246

function getUtilizationRate() internal view returns (uint256) {
uint256 totalBorrowed = lendingPool.getNormalizedDebt();
uint256 totalDeposits = stabilityPool.getTotalDeposits();
if (totalDeposits == 0) return 0;
return (totalBorrowed * 100) / totalDeposits;
}

Now, getNormalizedDebt() relates to reserve.usageIndex, which grows exponentially whereas getTotalDeposits(), i.e. the total deposits of rToken is tied to reserve.liquidityIndex, which increases linearly.

Without pre-calling lendingPool.updateState(), both values are stale, leading to returning incorrect utilization rates that results in lower-than-intended emissions, reducing reward distribution. This is because totalBorrowed, the numerator, is exponentially deprived whereas totalDeposits, the denominator, is lineally deprived as far as the scaled up increment is concerned. As such, the fraction of totalBorrowed over totalDeposits will be smaller than expected.

Impact

Underestimated Emissions → Reduced Incentives

  • Since emissions are based on utilization, using outdated values results in suppressed RAAC minting.

  • Users receive fewer rewards than expected, making liquidity provision less attractive.

Incorrect RAAC Reward Distribution

  • The RAAC reward mechanism fails to distribute rewards optimally, leading to inefficient incentives for stability providers.

Long-Term Degradation of Protocol Health

  • If underestimation persists, the RAAC emission schedule is fundamentally flawed, impacting the overall economic model.

Tools Used

Manual

Recommendations

Consider implementing the following refactoring:

RAACMinter.sol#L260-L262

if (emissionUpdateInterval == 0 || block.timestamp >= lastEmissionUpdateTimestamp + emissionUpdateInterval) {
+ lendingPool.updateState();
updateEmissionRate();
}
Updates

Lead Judging Commences

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