In RToken.sol-> the liquidityIndexis used throughout the contract for the purpose of scaling the amount of RTokensthat either the protocol or user has in their balance.
The correct and most accurate and up-to-date liquidityIndexis used everywhere accept for in the function transferFrom.
For all functions and actions that use the liquidityIndexfor scaling purposes, the most up-to-date and accurate value is used as the scaling factor, accept for transferFrom.
It is important to note that liquidityIndexis a value that is updated and stored within LendingPool(which is represented as _reservePoolin the RTokencontract.
The contract uses the most up-to-date index by these 2 methods:
Accepts the most up-to-date and accurate liquidityIndexvalue as an argument within a function. The argument is populated from the LendingPool, when calling these functions in RToken: as such:
Calls the LendingPooldirectly and gets the return value of getNormalizedIncome-> which returns the accurate liquidityIndex
BUT the transferFromfunction uses _liquidityIndexfor the scaling factor. This variable is defined and stored within the RTokencontract itself.
It is originally set during the constructorof RToken:
There is a function, updateLiquidityIndex-> that is supposed to update the local liquidityIndex-> and is only callable by the LendingPool/reservePool. The reservePool is the LendingPool contract.
The problem is that this function is never called within the LendingPool. There is no point in the LendingPoolor the contracts inherited by the LendingPoolthat call this function. Therefore, the local _liquidityIndexis never updated and is continuously the value it was set as in the cosntructor.
When transferFromis called, it will use a different liquidityIndexthan the rest of the contract uses.
To compare the discrepancy lets look at the difference between transferand transferFrom-> which both attempt to scale the value by the liquidityIndex:
The wrong amount will be transferred when transferFromis called.
I have this as a LOW becasue the protocol does not lose any funds, but the discrepency in the value can cause a user to lose funds and have the wrong amount transferred out. Also, it can have the reverse effect.
Manual Review
Follow the methods of using the liquidityIndexas the rest of the contract does. In this scenario, since it is a public variable and not accepting input paramater of liquidityIndex-> Use the logic in transfer
get the liquidityIndexby calling the lending pool directly - amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
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.