The user uses the deposit function to deposit crvUsd and in exchange rTokens are minted to the depositor. The amount of rTokens that the user is supposed to get minted varies accordingly depending on the index.
The user uses the deposit function to deposit crvUsd and in exchange rTokens are minted to the depositor. The amount of rTokens that the user is supposed to get minted varies accordingly depending on the index of the user i.e UserState.index and the global liquidity index. This liquidityIndex variiable is updated everytime a function is called in the LendingPool contract whether that function be deposit , withdraw , borrow , repay or any other function that user interacts with in the LendingPool and same goes for the UserState.index is also updated in almost very transaction and it is updated along with the global liquidity index via ReserveLibrary.updateReserveState function and the mint function in the RToken contract. Now when the user deposits reserveAssets i.e crvUsd using the deposit function, he is supposed get minted rtokens and the amount of RTokens that the user should get minted will initially be 1:1 but as the liquidityIndex accrues the rTokens that are to be minted to the user must change. Now these RTokens that should be minted along with the interest accrued are computed here in the mint function of the RToken.sol. However, the issue that arises here is that even though these accrued tokens are computed, they are not minted to the user. instead the RTokens which get minted to the user are minted 1:1 with the deposited amount which is not the intended behaviour because- The deposit-to-rToken ratio is not always 1:1 and can change over time. This ratio is influenced by the liquidity index, which represents the cumulative interest accrued over time. When users deposit assets, they receive rTokens based on the current liquidity index. As interest accrues, the value of each rToken increases, . And as can be seen in the mint function, the balanceIncrease is being calculated depending on the liquidityIndex but when the tokens are minted in the end of the function this balanceIncrease is not being included there and this will lead to the user getting less amount tokens than he is supposed to get.
Also Note that this same vulnerability will also cause problems in the withdraw function too as the user deposits and when they withdraw they are supposed to get back the deposited amount along with the interest accrued on that amount, the user will not get the accrued part because of the reasons given above i.e the balanceIncrease is computed but that amount of rTokens is never minted to the user
Even though the user is depositing their funds n the protocol to provide with liquidity, in return they are not fully getting the amount of tokens that they are supposed to get. For example- lets assume the user deposits - 100e18 for the first time and his index is updated to 1e27 which is the initial index, then some time passes maybe a few weeks after the same user comes again and deposits 200e18 tokens, this time the liquidityIndex = 1.1e27 and userIndex=1e27 from before, the balance increase is computed as- balanceIncrease =scaledBalance.rayMul(index) -scaledBalance.rayMul(_userState[onBehalfOf].index); scaledBal here will be 100e18 which the user deposited for the first time so- balIncrease = 100e18.ray*(1.1e27) - 100e18.rayMul(1e27) = 10e18 Now 200e18 + balance increase = 210e18 but the user only gets minted amountToMint i.e 200e18
Manual Review
when minting the rTokens instead of only passing amountToMint in the ERC20 _mint function add the balanceIncrease var along with it too like this:-
_mint(onBehalfOf, balanceIncrease + amountToMint.toUint128());
The balanceIncrease is the interest that has already accrued on the user's existing scaledBalance since their last interaction. It's not something you mint as new tokens in the _mint function.
The balanceIncrease is the interest that has already accrued on the user's existing scaledBalance since their last interaction. It's not something you mint as new tokens in the _mint 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.