Core Contracts

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

totalUsage and totalLiquidity values not updated correctly.

Overview

in the updateInterestRatesAndLiquidity the total liquidity and total usage are updated and adjusted accordingly,

*/
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;
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);
emit InterestRatesUpdated(rateData.currentLiquidityRate, rateData.currentUsageRate);
}

Accrued Interest Is Not Accounted for in totalUsage and totalLiquidity
The following functions are called:

uint256 computedDebt = getNormalizedDebt(reserve, rateData);
uint256 computedLiquidity = getNormalizedIncome(reserve, rateData);

These functions compute interest but do not update totalUsage and totalLiquidity accordingly.

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 function computes the additional interest borrowers need to pay.
    However, it does not update reserve.totalUsage to reflect this accrued interest.

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);
}
  • The function above computes additional income for lenders.
    However, it does not update reserve.totalLiquidity to reflect the accrued earnings.

The issue here is both this two functions getNormalizedDebt contribute to the totalUsage and getNormalizedIncome contribute to the totalLiquidity
later we calculate the utilizationRate which uses the totalUsage and totalLiquidity values as shown below

uint256 utilizationRate = calculateUtilizationRate(reserve.totalLiquidity, reserve.totalUsage);

Given that our getNormalizedDebt and getNormalizedIncome are just computing the accrued interests without updating the new values of the new totalUsage and the totalLiquidity our utilizationRate is using wrong values that ought to have been increased after the interests are determined based on the liquidity index and usageIndex.

Impact

inaccurate utilization rate

Recommendation

Update totalUsage and totalLiquidity After Calculating Normalized Debt and normalized income accordingly.

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 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 3 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.