At RToken::burn()
, the token amount passed to _burn()
is a normal token amount, this is not correct. It must be the scaled amount to properly account for interests.
For example when user does LendinPool::withdraw()
we see that the burn amount parameters is in token decimals, see withdraw logic here, which calls reserve library here without altering the amount
arg. Which will be just burned on RToken
here.
Notice that this is always in token amounts, never scaled. Even when amount > userBalance
the amount will be in token amounts as userBalance
is read with balanceOf()
which multiplies by the liquidity index, see here the assignment and here the read.
Why should it be the scaled amount? The AAVE book explains it pretty well, as RToken is a very similar re-creation to AAVE's aToken you can read here.
Summed up, when depositing we must write in storage the scaled amount that comes from dividing by the current index, this is to discount new deposits from historical interets. For example if you deposit 100 USDC at an index of 1.1 you must be minted 90.9 aUSDC.
Then later at withdrawal, let's say now index has increased to 1.3, then your 100 USDC are worth 118.17 USDC due to accrued interests (90.9 * 1.3 = 118.17). This properly reflects the accrued interests over time according to when you deposit or withdraw. But as you might have noticed, the minted amount of aToken in storage is 90.9 yet you should be able to withdraw(118)
.
If we pass _burn(118)
to a proper aToken implementation, like RToken is meant to be, it will revert as it will try to substract 118 to 90.9. So to keep things and math in order we must burn the scaled amount of the desired withdrawal. This is simply done by dividing by the index.
You can also check AAVE aToken code to see it should be the scaled amount, here. The contract just linked is inherited by aToken, see here.
Burning normal amounts makes the user lose too much RTokens as the correct amount to burn should be divided by the index. This leads to reverts if a user tries to withdraw higher amounts than the RToken scaled balance in storage. Interests are not being accrued correctly and people are not able to withdraw what they should.
Note that the mint implementaiton is also faulty as it incorrectly mints token amounts instead of scaled amounts. I've reported this in another report as it is different source of errors.
You have to burn the scaledAmount
by dividing the amount by the corresponding index.
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.