Core Contracts

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

Incorrect Liquidity Index calculation, Compound interest applied instead of linear

Summary

The Liquidity Index is supposed to be calculated using linear interest, but the current implementation introduces compounding effects due to the way it updates the index.

Vulnerability Details

The function calculateLiquidityIndex calls calculateLinearInterest, which computes (1 + r * t), but then incorrectly multiplies it with the last index.
Multiplying by lastIndex makes it behave like compound interest over multiple periods:

ReserveLibrary.sol :

function calculateLiquidityIndex(uint256 rate, uint256 timeDelta, uint256 lastIndex) internal pure returns (uint128) {
uint256 cumulatedInterest = calculateLinearInterest(rate, timeDelta, lastIndex);
return cumulatedInterest.rayMul(lastIndex).toUint128();
}
function calculateLinearInterest(uint256 rate, uint256 timeDelta, uint256 lastIndex) internal pure returns (uint256) {
uint256 cumulatedInterest = rate * timeDelta;
cumulatedInterest = cumulatedInterest / SECONDS_PER_YEAR;
return WadRayMath.RAY + cumulatedInterest;
}

Each time calculateLiquidityInterest is called, it applies a new cumulatedInterest factor to lastIndex. Over multiple periods, this results in:

This is the compound interest formula. Linear interest would be like this:

The increase is not depend on last index.

Impact

Liquidity Index will increase with a compounding effect which is more than intended and as a result Liquidity providers will get more funds.

Tools Used

vscode

Recommendations

Modify calculateLiquidityIndex to ensure the new index follows a linear formula:

function calculateLiquidityIndex(uint256 rate, uint256 timeDelta, uint256 lastIndex) internal pure returns (uint128) {
uint256 cumulatedInterest = calculateLinearInterest(rate, timeDelta, lastIndex);
return (lastIndex + cumulatedInterest).toUint128();
}
function calculateLinearInterest(uint256 rate, uint256 timeDelta) internal pure returns (uint256) {
uint256 cumulatedInterest = rate * timeDelta;
cumulatedInterest = cumulatedInterest / SECONDS_PER_YEAR;
return cumulatedInterest; //assuming that initialIndex is always 1 or RAY
}
Updates

Lead Judging Commences

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

ReserveLibrary::calculateLiquidityIndex applies compound interest by multiplying with lastIndex, contradicting documentation that states liquidity rate should be linear

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

ReserveLibrary::calculateLiquidityIndex applies compound interest by multiplying with lastIndex, contradicting documentation that states liquidity rate should be linear

Appeal created

anonymousjoe Auditor
4 months ago
inallhonesty Lead Judge
4 months ago
inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

ReserveLibrary::calculateLiquidityIndex applies compound interest by multiplying with lastIndex, contradicting documentation that states liquidity rate should be linear

Support

FAQs

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