Core Contracts

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

Invalid Variable Usage in `RToken::_liquidityIndex`

Summary

Invalid Variable Usage in RToken::_liquidityIndex

Vulnerability Details

The _liquidityIndex variable is designed to track cumulative interest and is expected to be updated by the LendingPool contract. However, in the current implementation, the new contract no longer maintains this functionality. Instead, the interest tracking mechanism has been replaced with ILendingPool(_reservePool).getNormalizedIncome().

As a result, _liquidityIndex no longer holds valid data but is still referenced in multiple functions, leading to potential inconsistencies.

// Liquidity index, represents cumulative interest
uint256 private _liquidityIndex;
@> function updateLiquidityIndex(uint256 newLiquidityIndex) external override onlyReservePool {
if (newLiquidityIndex < _liquidityIndex) revert InvalidAmount();
_liquidityIndex = newLiquidityIndex;
emit LiquidityIndexUpdated(newLiquidityIndex);
}

Despite being obsolete, _liquidityIndex is still utilized in the following functions:

// RToken::transferFrom()
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);
}
// RToken::transferFrom()
function getLiquidityIndex() external view override returns (uint256) {
return _liquidityIndex;
}

Impact

Since _liquidityIndex no longer holds valid data, any function that relies on it will return incorrect values, potentially affecting interest calculations and token transfers.

Tools Used

Manual Review

Recommendations

Replace _liquidityIndex with ILendingPool(_reservePool).getNormalizedIncome() when retrieving the liquidity index.

// RToken::transferFrom()
function getLiquidityIndex() external view override returns (uint256) {
- return _liquidityIndex;
+ return ILendingPool(_reservePool).getNormalizedIncome();
}

The transferFrom() function is not modified here because _liquidityIndex is initialized to 1e27, and scaling within transferFrom() is unnecessary.

// RToken::constructor(
constructor(
string memory name,
string memory symbol,
address initialOwner,
address assetAddress
) ERC20(name, symbol) ERC20Permit(name) Ownable(initialOwner) {
// SNIP...
_liquidityIndex = WadRayMath.RAY; // 1e27
// SNIP...
}
Updates

Lead Judging Commences

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

RToken::transfer uses getNormalizedIncome() while transferFrom uses _liquidityIndex, creating inconsistent transfer amounts depending on function used

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

RToken::transfer uses getNormalizedIncome() while transferFrom uses _liquidityIndex, creating inconsistent transfer amounts depending on function used

Support

FAQs

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

Give us feedback!