Core Contracts

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

Wrong calculation of getBorrowRate

Summary

The getBorrowRate function incorrectly calculates the value of total Debt. The normalized debt index is used directly instead of the actual total debt amount, leading to severely underestimated utilization rates and incorrect interest rate calculations.

Vulnerability Details

In the ReserveLibrary, getBorrowRate function incorrectly use the normalized debt index as the total debt amount:

function getBorrowRate(ReserveData storage reserve,ReserveRateData storage rateData) internal view returns (uint256) {
uint256 totalDebt = getNormalizedDebt(reserve, rateData);
uint256 utilizationRate = calculateUtilizationRate(reserve.totalLiquidity, totalDebt);
return calculateBorrowRate(rateData.primeRate, rateData.baseRate, rateData.optimalRate, rateData.maxRate, rateData.optimalUtilizationRate, utilizationRate);
}

However, the getNormalizedDebt() function returns an index in RAY units (1e27) that tracks interest accrual.

function getNormalizedDebt(ReserveData storage reserve, ReserveRateData storage rateData) internal view returns (uint256) {
uint256 timeDelta = block.timestamp - uint256(reserve.lastUpdateTimestamp);
if (timeDelta < 1) {
return reserve.totalUsage;
}
return calculateCompoundedInterest(rateData.currentUsageRate, timeDelta).rayMul(reserve.usageIndex);
}

This index should be multiplied with the total usage to get the actual total debt.

Impact

The incorrect calculation of totalDebt causes borrowing rates to be significantly underpriced, with rates remaining near the base rate even when utilization is high. When actual utilization could be 50%, the protocol calculates it at 0.1%, leading borrowers to pay much lower interest than they should. This creates an unsustainable lending environment where borrowing is too cheap relative to risk, potentially depleting protocol liquidity and destabilizing the system's economic model.

Tools Used

Manual Review

Recommendations:

function getBorrowRate(ReserveData storage reserve,ReserveRateData storage rateData) internal view returns (uint256) {
- uint256 totalDebt = getNormalizedDebt(reserve, rateData);
+ uint256 totalDebt = (reserve.totalUsage).rayMul(getNormalizedDebt(reserve, rateData));
uint256 utilizationRate = calculateUtilizationRate(reserve.totalLiquidity, totalDebt);
return calculateBorrowRate(rateData.primeRate, rateData.baseRate, rateData.optimalRate, rateData.maxRate, rateData.optimalUtilizationRate, 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!