LendingPool::getNormalizedIncome doesn't return the latest normalized income. Users can transfer more rTokens
RToken is a rebasing token, meaning it increases in balance not in value. rToken balance is derived from the scaledBalance, which remains constant for a user unless they deposit, withdraw or transfer.
The key relationship is rToken balance = scaledBalance * liquidityIndex.
liquidityIndex is updated before any interaction with the rToken to get the correct ratio between balance and scaledBalance.
In RToken::_update, LendingPool::getNormalizedIncome is used to get the scaledAmount, the actual amount transferred.
getNormalizedIncome returns the latest stored value for liquidityIndex:
The problem is the returned liquidityIndex can have an obsolete value. It's not the latest calculated value.
Consider the following example.
Let's consider 1 rToken = 1 asset (crvUsd) = 1 USD
alice deposits 1100 assets and get back 1100 rToken; liquidityIndex is 1.1
no more interactions with LendingPool take places for some time; liquidityIndex from storage is still 1.1
alice transfer 110 rTokens to Bob. RToken::_update gets called. scaledAmount is caluclated as: scaledAmount = amount / liquidityIndex <=> scaledAmount = 110 / 1.1 = 100;
100 of scaledAmount is transferred to Bob;
bob observes that pool's data wasn't updated for a long time and calls LendignPool::updateState. liquidityIndex is updated to 1.11.
bob check his rToken balance and calls balanceOf(bob) which returns scaledBalance * liquidityIndex = 100 *1.11 = 111.
Alice wanted to transfer 110 USD value but she actually transferred 110.
In interactions with the LendingPool, liquidityIndex is updated before it's used, but, since getNormalizedIncome doesn't return an updated value, users can give away tokens.
Same issue is present for getNormalizeDebt.
Users may loose tokens by transferring more than they wanted.
Use ReserveLibrary::getNormalizedIncome to return latest value for liquidityIndex:
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.