The StabilityPool.sol code assumes the current implementation of the transfer() function in RToken.sol behaves like a regular ERC20 transfer function which is not the case. This assumption leads to permanently locking funds from lenders who have deposited in the StabilityPool.
The function withdraw() converts a user's DETokens 1:1 with RTokens and then sends the RTokens to the user via rToken.safeTransfer(msg.sender, rcrvUSDAmount);
There is an issue with how the transfer() function in RToken.sol is defined.
The function first descales the amount by ILendingPool(_reservePool).getNormalizedIncome() which returns reserve.liquidityIndex.
Example:
reserve.liquidityIndex = 4
A user has deposited 100 RTokensand has received 100 DETokens.
The user wishes to withdraw all of his tokens and calls withdraw(100)
rToken.safeTransfer(user, 100); is called => the transfer function divides the amount (100) by the index (4): 100 / 4 = 25 RTokens, 25 tokens are send back to the user.
It is impossible for users to withdraw all of their deposits in the StabilityPool leading to a loss of funds for the users.
manual review
Remove the logic for descaling the provided amount from the overridden transfer() function. Make it behave like a regular ERC20 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.