Core Contracts

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

Incorrect utilization rate calculation in `RAACMinter::getUtilizationRate` leads to excessive RAACToken emissions

Summary

The RAACMinter::calculateNewEmissionRate calculates the new emission rate based on the system utilization and benchmark rate to determine RAACToken emission rates. However, the current implementation in the RAACMinter::getUtilizationRate function incorrectly uses the normalized debt index (usageIndex) instead of actual borrowed amounts for calculating the total borrowed in the LendingPool, leading to severely inflated utilization calculations.

Vulnerability Details

RAACMinter.sol:

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

LendingPool.sol:

function getNormalizedDebt() external view returns (uint256) {
@> return reserve.usageIndex;
}

Impact

The LendingPool::getNormalizedDebt returns reserve.usageIndex which is a cumulative interest rate index that starts at 1.0 (RAY = 1e27) and grows over time instead of using the reserve.totalUsage, which represents the actual total borrowed amount. This leads the system to always think utilization is above target and consistently increase emission rate (emissionRate + adjustment) reaching the maxEmissionRate quickly and stay there. Resulting in maximum RAACToken emissions regardless of actual utilization. The system fails to properly incentivize borrowing/lending based on actual usage.

Considering this scenario:

  • usageIndex = 1.0 RAY (1e27)

  • totalDeposits = 1000e18

  • utilizationTarget = 80%

Current calculation:

  • utilizationRate = 1e27 * 100 / 1000e18
    = 1e11% (astronomical number)

The utilizationRate is always greater then utilizationTarget (80%). This always triggers maximum emissions ignoring actual borrowed amounts.

Tools Used

Manual review

Recommendations

Implement a function in the LendingPool.sol that calculates the total borrowed.

+ function getTotalBorrowed() public view returns (uint256) {
+ return reserve.totalUsage;
+ }
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!