Core Contracts

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

`RToken.updateLiquidityIndex()` function is Ineffective Due to Missing Implementation in `Reserve Pool`

Summary

In RToken contract, the updateLiquidityIndex() functions cannot be executed as intended because the Reserve Pool contract lacks the necessary implementation to call it. Additionally, _liquidityIndex remains unchanged, always defaulting to WadRayMath.RAY in every transferFrom() function.

Vulnerability Detail

The function updateLiquidityIndex() is intended to update _liquidityIndex, but it is never called from the Reserve Pool contract.As a result, _liquidityIndex always retains its default value of WadRayMath.RAY.

function updateLiquidityIndex(uint256 newLiquidityIndex) external override onlyReservePool {
if (newLiquidityIndex < _liquidityIndex) revert InvalidAmount();
_liquidityIndex = newLiquidityIndex;
emit LiquidityIndexUpdated(newLiquidityIndex);
}

This directly affects every transferFrom() function where _liquidityIndex is used, causing incorrect scaling of values.

function transferFrom(address sender, address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
uint256 scaledAmount = amount.rayDiv(_liquidityIndex);
return super.transferFrom(sender, recipient, scaledAmount);
}

Impact

Due to the absence of implementation in the Reserve Pool contract, the _liquidityIndex remains unchanged, leading to incorrect scaling in transferFrom(), potentially affecting token transfers and balances.

The protocol inconsistently uses different indexes in transfer() and transferFrom(), leading to potential discrepancies in token transfers.

Tool used

Manual Review

Recommendation

  • Remove the updateLiquidityIndex() function since it is never used.

  • Replace _liquidityIndex with ILendingPool(_reservePool).getNormalizedIncome() in transferFrom() to ensure accurate scaling.

function transferFrom(address sender, address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
- uint256 scaledAmount = amount.rayDiv(_liquidityIndex);
+ uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
return super.transferFrom(sender, recipient, scaledAmount);
}
Updates

Lead Judging Commences

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

RToken::updateLiquidityIndex() has onlyReservePool modifier but LendingPool never calls it, causing transferFrom() to use stale liquidity index values

Support

FAQs

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