Core Contracts

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

Invalid Utilization Rate When Reserve is Empty

Summary

The utilization rate measures how much of the reserve's liquidity is being "used" (i.e., borrowed). It is calculated as: [ \text{Utilization Rate} = \frac{\text{Total Debt}}{\text{Total Liquidity} + \text{Total Debt}} ]

Expressed in RAY (27 decimal) precision. A 100% utilization rate (WadRayMath.RAY) means all liquidity is borrowed.

Vulnerability Details

The current implementation of calculateUtilizationRate has a flawed edge-case check

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

When both totalLiquidity and totalDebt are zero (e.g., a newly created reserve with no deposits or borrows), the function incorrectly returns 100% utilization.

The check totalLiquidity < 1 triggers when totalLiquidity == 0, but it doesn't account for totalDebt also being zero.

A 100% utilization rate causes the protocol to calculate excessively high borrow rates (via calculateBorrowRate), even though the reserve is empty.

Example:

A new reserve with 0 liquidity and 0 debt would have maximum borrow rates, deterring users from participating.

Impact

Misleading rates disrupt the protocol's economic incentives, leading to unexpected behavior

Tools Used

Foundry

Recommendations

Update the edge-case logic to handle the scenario where both totalLiquidity and totalDebt are zero.

function calculateUtilizationRate(uint256 totalLiquidity, uint256 totalDebt) internal pure returns (uint256) {
if (totalLiquidity == 0 && totalDebt == 0) {
return 0; // 0% utilization when reserve is empty
}
if (totalLiquidity == 0) {
return WadRayMath.RAY; // 100% utilization if liquidity is 0 but debt exists
}
return totalDebt.rayDiv(totalLiquidity + totalDebt);
}
Updates

Lead Judging Commences

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

ReserveLibrary::calculateUtilizationRate returns 100% when both liquidity and debt are zero, causing artificially high interest rates at pool initialization

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

ReserveLibrary::calculateUtilizationRate returns 100% when both liquidity and debt are zero, causing artificially high interest rates at pool initialization

Support

FAQs

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

Give us feedback!