The RToken contract implements an interest-bearing token for the RAAC lending protocol. However, there is a critical issue in the transfer and _update functions where the token amount is scaled twice, leading to incorrect calculations. Specifically, the transfer function scales the amount before calling super.transfer, which internally invokes the _update function, where the amount is scaled again. This duplicate scaling results in users losing tokens during transfers, as the final amount is significantly smaller than intended.
The transfer function scales the amount using ILendingPool(_reservePool).getNormalizedIncome(), which represents the current liquidity index (cumulative interest).
The scaled amount (scaledAmount) is then passed to super.transfer, which internally calls the _update function.
The _update function scales the amount again using the same ILendingPool(_reservePool).getNormalizedIncome().
This results in the amount being scaled twice, leading to an incorrect final value.
The same issue exits in transferFrom , mint and burn .
add the following test case in RToken.test.js
run npx hardhat test --grep "balance is double scaled"
The balance is much bigger than expected.
Incorrect Token Transfers: The duplicate scaling causes the final transferred amount to be much smaller than intended, as the amount is divided by the normalized income twice.
User Losses: Users lose tokens during transfers due to the incorrect scaling logic.
Logical Inconsistency: The contract's behavior deviates from its intended design, where token amounts should be scaled only once to reflect the current interest rates.
The impact is High, the likelihood is High, so the severity is High.
Manual Review
Consider removing the _update function.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.