Core Contracts

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

`ReserveLibrary.updateInterestRatesAndLiquidity()` updates rates incorrectly

Summary

The ReserveLibrary.updateInterestRatesAndLiquidity() function retrieves utilizationRate from calculateUtilizationRate() incorrectly, because it passes incorrect params.

Vulnerability Details

The ReserveLibrary.updateInterestRatesAndLiquidity() function passes improper value(reserve.totalUsage) to calculateUtilizationRate() as param.

It should pass computedDebt instead of reserve.totalUsage. The following ReserveLibrary.getBorrowRate(), ReserveLibrary.getLiquidityRate() passes totalDebt as param.

This could result inconsistency in calculation of rateData.currentUsageRate and rateData.currentLiquidityRate.

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);
emit InterestRatesUpdated(rateData.currentLiquidityRate, rateData.currentUsageRate);
}
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);
}
function getLiquidityRate(ReserveData storage reserve,ReserveRateData storage rateData) internal view returns (uint256) {
uint256 totalDebt = getNormalizedDebt(reserve, rateData);
>> uint256 utilizationRate = calculateUtilizationRate(reserve.totalLiquidity, totalDebt);
return calculateLiquidityRate(utilizationRate, rateData.currentUsageRate, rateData.protocolFeeRate, totalDebt);
}

Impact

The rateData.currentUsageRate and rateData.currentLiquidityRate vairable will be updated incorrectly.

Tools Used

Manual Review

Recommendations

Pass computedDebt to calculateUtilizationRate() as second param.

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);
+ uint256 utilizationRate = calculateUtilizationRate(reserve.totalLiquidity, computedDebt);
...
}
Updates

Lead Judging Commences

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

updateInterestRatesAndLiquidity() uses reserve.totalUsage while other functions use getNormalizedDebt(), causing inconsistent utilization rate calculations

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

updateInterestRatesAndLiquidity() uses reserve.totalUsage while other functions use getNormalizedDebt(), causing inconsistent utilization rate calculations

Appeal created

pabloperezacc6 Submitter
3 months ago
inallhonesty Lead Judge
3 months ago
inallhonesty Lead Judge 2 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.