Core Contracts

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

Misuse of Raw vs. Normalized Values in Utilization Rate Calculation

Summary

The calculateUtilizationRate function is designed to calculate the utilization rate of a reserve based on its liquidity and debt values. However, it currently uses the raw values (reserve.totalLiquidity and reserve.totalUsage) instead of the normalized values (computedLiquidity and computedDebt). This discrepancy may lead to inaccurate calculations of the utilization rate, potentially undermining the integrity of the reserve’s financial metrics and calculations.

Vulnerability Details

The calculateUtilizationRate function takes two parameters, totalLiquidity and totalDebt, which represent the total liquidity and total debt in the reserve. However, these parameters should reflect the normalized or compounded values (computedLiquidity and computedDebt) to account for changes over time, such as interest accumulation and liquidity adjustments. By using the raw values, the function does not properly consider the current state of the reserve, potentially leading to incorrect utilization rate calculations.

Key Issues:

  • Incorrect Parameters: The function uses raw values (reserve.totalLiquidity and reserve.totalUsage) rather than normalized values.

  • Mismatch with Normalized Metrics: The function’s comment suggests that it should use normalized values, but the actual implementation does not align with this intent.

Code

updateInterestRatesAndLiquidity

function updateInterestRatesAndLiquidity(ReserveData storage reserve,ReserveRateData storage rateData,uint256 liquidityAdded,uint256 liquidityTaken) internal {
......
uint256 totalLiquidity = reserve.totalLiquidity;
uint256 totalDebt = reserve.totalUsage;
uint256 computedDebt = getNormalizedDebt(reserve, rateData);
uint256 computedLiquidity = getNormalizedIncome(reserve, rateData);
// Calculate utilization rate
uint256 utilizationRate = calculateUtilizationRate(reserve.totalLiquidity, reserve.totalUsage);
// Update current usage rate (borrow rate)
rateData.currentUsageRate = calculateBorrowRate(
rateData.primeRate,
rateData.baseRate,
rateData.optimalRate,
rateData.maxRate,
rateData.optimalUtilizationRate,
utilizationRate
);
// Update current liquidity rate
rateData.currentLiquidityRate = calculateLiquidityRate(
utilizationRate,
rateData.currentUsageRate,
rateData.protocolFeeRate,
totalDebt
);
// Update the reserve interests
updateReserveInterests(reserve, rateData);
......
}

getNormalizedDebt

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);
}

getNormalizedIncome

function getNormalizedIncome(ReserveData storage reserve, ReserveRateData storage rateData) internal view returns (uint256) {
uint256 timeDelta = block.timestamp - uint256(reserve.lastUpdateTimestamp);
if (timeDelta < 1) {
return reserve.liquidityIndex;
}
return calculateLinearInterest(rateData.currentLiquidityRate, timeDelta, reserve.liquidityIndex).rayMul(reserve.liquidityIndex);
}

calculateUtilizationRate

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;
}

Impact

Using raw values instead of normalized values can result in inaccurate calculations of the utilization rate, which may affect:

  • Reserve Health: The reserve’s financial health may be miscalculated, potentially leading to suboptimal decisions related to liquidity and debt management.

  • Interest Rate Calculations: The incorrect utilization rate could impact the correct calculation of usage and liquidity rates, leading to suboptimal rates being applied to borrowers and liquidity providers.

Tools Used

Manual

Recommendations

  • Refactor the Function: Modify the calculateUtilizationRate function to take normalized liquidity and debt values (computedLiquidity and computedDebt) as parameters, rather than the raw reserve.totalLiquidity and reserve.totalUsage values.

Updates

Lead Judging Commences

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

calculateUtilizationRate mixes unscaled totalLiquidity with scaled totalUsage values, causing incorrect utilization rates and interest calculations across the protocol

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

calculateUtilizationRate mixes unscaled totalLiquidity with scaled totalUsage values, causing incorrect utilization rates and interest calculations across the protocol

Support

FAQs

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

Give us feedback!