Core Contracts

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

Incorrect Utilization Rate Calculation Leading to Underestimated Interest

Summary

The calculateUtilizationRate function incorrectly computes the utilization rate by using totalDebt / (totalLiquidity + totalDebt), rather than the correct formula totalDebt / totalLiquidity. This results in underestimating the available liquidity and miscalculating utilization-based interest rate adjustments, potentially leading to Underestimated Interest

Vulnerability Details

function calculateUtilizationRate(uint256 totalLiquidity, uint256 totalDebt) internal pure returns (uint256) {
if (totalLiquidity < 1) {
return WadRayMath.RAY; // 100% utilization if no liquidity
}
// Incorrect calculation
uint256 utilizationRate = totalDebt.rayDiv(totalLiquidity + totalDebt).toUint128();
return utilizationRate;
}

The function mistakenly divides totalDebt by (totalLiquidity + totalDebt), which skews the utilization rate lower than it should be. The correct calculation should be:

uint256 utilizationRate = totalDebt.rayDiv(totalLiquidity).toUint128();

This incorrect formula distorts the protocol's interest rate model, affecting borrower incentives and liquidity provider returns.

For example:

  • If totalDebt = 80 and totalLiquidity = 100

  • Current calculation: 80 / (100 + 80) = 44.4% utilization

  • Correct calculation: 80 / 100 = 80% utilization

Which means there is no possible way this function would have been trigger:

function calculateBorrowRate(
uint256 primeRate,
uint256 baseRate,
uint256 optimalRate,
uint256 maxRate,
uint256 optimalUtilizationRate,
uint256 utilizationRate
) internal pure returns (uint256) {
// ... some codes
uint256 rate;
if (utilizationRate <= optimalUtilizationRate) {
uint256 rateSlope = primeRate - baseRate;
uint256 rateIncrease = utilizationRate.rayMul(rateSlope).rayDiv(optimalUtilizationRate);
rate = baseRate + rateIncrease;
} else {
uint256 excessUtilization = utilizationRate - optimalUtilizationRate;
uint256 maxExcessUtilization = WadRayMath.RAY - optimalUtilizationRate;
uint256 rateSlope = maxRate - primeRate;
uint256 rateIncrease = excessUtilization.rayMul(rateSlope).rayDiv(maxExcessUtilization);
rate = primeRate + rateIncrease;
}
return rate;
}

The utilizationRate will always be less than optimalUtilizationRatein this case until probably the optimalUtilizationRateis drastically reduced which doesnt remove the impact.

Impact

  • Lower utilization rates lead to lower interest rates

  • Protocol earns less fees than it should

  • Borrowers pay less interest than they should

  • Lenders receive lower returns than intended

Tools Used

Manual

Recommendations

function calculateUtilizationRate(uint256 totalLiquidity, uint256 totalDebt) internal pure returns (uint256) {
if (totalLiquidity < 1) {
return WadRayMath.RAY; // 100% utilization if no liquidity
}
// Correct calculation
uint256 utilizationRate = totalDebt.rayDiv(totalLiquidity).toUint128();
return utilizationRate;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!