Core Contracts

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

`transferFrom` function in RToken contract is wrongly implemented, systematically transferring too many interest-bearing tokens, leading to loss of funds and incorrect assumptions.

Summary

transferFrom function in RToken contract is defined as follows:

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);
}

The problem is that _liquidityIndex for scaling is incorrect, given that this variable's value is set to RAY in constructor, and cannot be modified after that. This means dividing by _liquidityIndex using rayDiv won't apply any scaling.

If the contract is deployed as it is right now, there are no consequence given that _update function applies the scaling:

function _update(address from, address to, uint256 amount) internal override {
// Scale amount by normalized income for all operations (mint, burn, transfer)
uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
super._update(from, to, scaledAmount);
}

But this means that if _liquidityIndex indeed returns the right index, we will have a double division scaling which will ultimately lead to less funds actually being transferred than expected, leading to incorrect assumptions especially in case of integration of the RAAC protocol with other protocols.

Impact

The impact of this vulnerability can be considered as medium.

Tools Used

Manual review

Recommendations

Ensure that only one division scaling is applied:

  • Use lending pool getNormalizedIncome call like in transfer function (supposing that this function is correctly implemented) to effectively get the scaled amount to transfer, and remove the scaling in _update function.

  • Or remove scaling in transferand transferFrom functions and only apply the scaling in _update function (probably the better option.

Note that currently, getNormalizedIncome in LendingPool contract is also wrongly implemented, returns the non normalised liquidity index (index at last update). This is another issue.

Updates

Lead Judging Commences

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

RToken::transfer and transferFrom double-scale amounts by dividing in both external functions and _update, causing users to transfer significantly less than intended

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

RToken::transfer and transferFrom double-scale amounts by dividing in both external functions and _update, causing users to transfer significantly less than intended

Support

FAQs

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