Core Contracts

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

`getUtilizationRate` calculation in RAACMinter is wrong.

Summary

RAACMinter manage RAAC emission based on utilization ratio but in calculation normalizedDebt is used instead of totalUsage

Vulnerability Details

RAACMinter contract manages emission rate based on the utilization ratio. you can see that in calculateNewEmissionRate which is called from updateEmissionRate .

function calculateNewEmissionRate() internal view returns (uint256) {
@-> uint256 utilizationRate = getUtilizationRate();
uint256 adjustment = (emissionRate * adjustmentFactor) / 100;
if (utilizationRate > utilizationTarget) {
uint256 increasedRate = emissionRate + adjustment;
uint256 maxRate = increasedRate > benchmarkRate ? increasedRate : benchmarkRate;
return maxRate < maxEmissionRate ? maxRate : maxEmissionRate;
} else if (utilizationRate < utilizationTarget) {
uint256 decreasedRate = emissionRate > adjustment ? emissionRate - adjustment : 0;
uint256 minRate = decreasedRate < benchmarkRate ? decreasedRate : benchmarkRate;
return minRate > minEmissionRate ? minRate : minEmissionRate;
}
return emissionRate;
}

If we look at the getUtilizationRate function

/**
* @dev Calculates the current system utilization rate
* @return The utilization rate as a percentage (0-100)
*/
function getUtilizationRate() internal view returns (uint256) {
uint256 totalBorrowed = lendingPool.getNormalizedDebt();
uint256 totalDeposits = stabilityPool.getTotalDeposits();
if (totalDeposits == 0) return 0;
return (totalBorrowed * 100) / totalDeposits;
}

Here code is basically trying to get the ratio between totalDeposits and total borrowed funds and convert it to % terms.

totalBorrowed is using getNormalizedDebt which is just a borrow interest and not the whole borrowed amount. because of this, the calculation here is wrong.

/**
* @notice Gets the reserve's normalized debt
* @return The normalized debt (usage index)
*/
function getNormalizedDebt() external view returns (uint256) {
return reserve.usageIndex;
}

The correct calculation for utilization rate can be found in ReserveLibrary:updateInterestRatesAndLiquidity where totalUsage is used instead of normalized debt.

// Calculate utilization rate
uint256 utilizationRate = calculateUtilizationRate(
reserve.totalLiquidity,
reserve.totalUsage
);

Impact

Incorrect utilization will lead to the incorrect reward emission, which will be 0 in most cases or way lower than expected

Recommendations

use totalUsage instead of usageIndex from getNormalizedDebt

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACMinter::getUtilizationRate incorrectly mixes stability pool deposits with lending pool debt index instead of using proper lending pool metrics

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACMinter::getUtilizationRate incorrectly mixes stability pool deposits with lending pool debt index instead of using proper lending pool metrics

Support

FAQs

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

Give us feedback!