Core Contracts

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

totalUsage stale value in LendingPool

Summary

In the LendingPool contract, the totalUsage variable tracks the total debt in the system, scaled by the debt index. However, if there are no new borrows or repayments, the totalUsage value becomes stale because it is not updated to reflect the growing debt index over time. This leads to incorrect calculations of the utilization rate, which in turn affects the computation of interest rates and indices.

Vulnerability Details

The totalUsage variable represents the total debt in the system, scaled by the debt index (debtIndex). It is updated during borrow and repayment operations. However, the debt index grows over time due to accrued interest, and if no borrows or repayments occur, the totalUsage value becomes outdated. This results in incorrect calculations of the utilization rate, which is used to determine borrowing and liquidity rates.

Code Analysis

The updateInterestRatesAndLiquidity function in the ReserveLibrary is responsible for updating interest rates and liquidity. It calculates the utilization rate based on totalLiquidity and totalUsage. However, totalUsage is not updated to reflect the latest debt index unless a borrow or repayment occurs. This leads to stale values being used in the utilization rate calculation.

function updateInterestRatesAndLiquidity(
ReserveData storage reserve,
ReserveRateData storage rateData,
uint256 liquidityAdded,
uint256 liquidityTaken
) internal {
// Update total liquidity
if (liquidityAdded > 0) {
reserve.totalLiquidity = reserve.totalLiquidity + liquidityAdded.toUint128();
}
if (liquidityTaken > 0) {
if (reserve.totalLiquidity < liquidityTaken) revert InsufficientLiquidity();
reserve.totalLiquidity = reserve.totalLiquidity - liquidityTaken.toUint128();
}
uint256 totalLiquidity = reserve.totalLiquidity;
uint256 totalDebt = reserve.totalUsage; // totalSupply of debtTokens
uint256 computedDebt = getNormalizedDebt(reserve, rateData);
uint256 computedLiquidity = getNormalizedIncome(reserve, rateData);
// Calculate utilization rate
uint256 utilizationRate = calculateUtilizationRate(reserve.totalLiquidity, reserve.totalUsage); // ok
// 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);
emit InterestRatesUpdated(rateData.currentLiquidityRate, rateData.currentUsageRate);
}

Impact

  1. Incorrect Utilization Rate: The utilization rate is calculated based on stale totalUsage values, leading to inaccurate borrowing and liquidity rates.

  2. Wrong Index Computation: The debt index (debtIndex) and liquidity index (liquidityIndex) are computed incorrectly, affecting the overall system's state.

Tools Used

Manual Review

Recommendations

To address this issue, update the totalUsage value every time a new rate or index is computed, ensuring it reflects the latest debt index.

Updates

Lead Judging Commences

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

ReserveLibrary calculates computedDebt and computedLiquidity but never uses them, leading to stale totalUsage and totalLiquidity values in utilization rate calculations

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

ReserveLibrary calculates computedDebt and computedLiquidity but never uses them, leading to stale totalUsage and totalLiquidity values in utilization rate calculations

Support

FAQs

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