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.