Core Contracts

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

Inconsistent Scaling in transfer::RToken and transferFrom::RToken Leading to Incorrect Token Transfers

Finding Description and Impact

The transfer and transferFrom functions in the RToken contract are used to transfer tokens between users. However, these functions scale the amount parameter differently:

  • transfer uses ILendingPool(_reservePool).getNormalizedIncome() for scaling.

  • transferFrom uses _liquidityIndex for scaling.

This inconsistency can lead to incorrect token transfers, especially if _liquidityIndex is not updated correctly or diverges from the normalized income.

Impact:

  • Users may receive incorrect amounts of tokens during transfers.

  • The protocol's accounting could become inconsistent, leading to potential loss of funds or unfair advantages for certain users.

  • Off-chain systems relying on accurate token balances may malfunction.


Proof of Concept

  1. Code References:

    function transfer(address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
    uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
    return super.transfer(recipient, scaledAmount);
    }
    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);
    }
  2. Steps to Reproduce:

    • Deploy the RToken contract.

    • Mint tokens to two users, Alice and Bob.

    • Perform a transfer from Alice to Bob using transfer.

    • Perform a transferFrom from Alice to Bob using transferFrom.

    • Observe that the amounts transferred are inconsistent due to different scaling mechanisms.


Recommended Mitigation Steps

To ensure consistent scaling across both functions, update transferFrom to use ILendingPool(_reservePool).getNormalizedIncome() for scaling, similar to transfer:

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

This change ensures that both functions use the same scaling mechanism, preventing inconsistencies in token transfers.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 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 about 2 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.