In LendingPool::depositIntoVaultThe LendingPool send crvUSDto the curve vault and receives shares in return.
However, the LendingPool does not have the crvUSD tokens within its contract, it has no balance to deposit into the vault. The crvUSD tokens are held in a different contract, RToken.
The LendingPoolcannot deposit into the curveVault becasue it does not have any or receive any crvUSD (reserveAsset) - All of the crvUSD/ reserveAsset is held within RToken.
The intended functionality is to deposit some crvUSD / reserveAsset into the curveVaultand receive and store the shares in the LendingPool. The protocol then has 2 places where their reserves lie: RTokenand curveVault.
This is impossible with the current logic becasue the deposit to curveVault will never happen, because LendingPooldoes not have the crvUSD to deposit.
When a user deposits crvUSD to get minted RTokens in return, the crvUSD deposit is sent to RTokencontract, not the LendingPool.
The crvUSD amount is then KEPT within the RToken contract. The crvUSD never gets sent to LendingPool. But it is intentionally that crvUSD is kept in RToken, that is intended.
But becasue of that, LendingPoolnever receives crvUSD and thus never has crvUSD to deposit into curveVault when attempting to do so :
** The use of RTokencontract as the holder of all reserveAsset/crvUSD is prevelant throughout the codebase, where every transaction that involves the transfer of reserveAssetis facilitated by the LendingPoolbut never receives the reserve crvUSD, they are always transferred to RTokencontract. The LendingPooldoes not have crvUSD within its contract to deposit.
Another example of this, is in the finializeLiquidationfunction, crvUSD is not sent to the LendingPoolit is sent to RTokencontract. The LendingPoolonly facilitates the transfers of crvUSD but never holds any, they are always sent to and held in RToken.
This is severe becasue crvUSD can never be deposited to curveVault by the LendingPool. The protocol intends to have their total amount of reserveAsset/crvUSD distributed amongst 2 different contracts : RTokenand curveVault.
When a user withdraws, The protocol ensures there is enough liquid reserveAsset to send to the user to complete the withdraw by :
Checking the total amount of reserveAssetheld within RToken
If that amount is not enough to fulfill the withdraw, the protocol redeems the remaining needed amount from the curveVault.
This process shows the intended distribution of the reserveAssetbeing held in RTokenand curveVault. And when it is necessary to retrieve more reserveAssetto the system for withdraws, the protocol can do this by redeeming crvUSDfrom the curveVaultby burning their shares (THAT THEY ONLY GET WHEN THE VAULT DEPOSIT SUCCEEDS).
This distribution is INTEGRAL to the protocol - BUT it can never be acheived because the LEndingPoolcan never make the deposit to the curveVault becasue all of the reserveTokensare held in RTokencontract.
The functionality of the protocol is broken by the inability of the LendingPoolto deposit crvUSD to the curveVault.
manual review
Becasue crvUSD. / reserveAssetis held only in the RTokencontract -> extend the functionality in _depositIntoVaultby adding that function and logic within the RTokencontract.
Place the modifier (already used within RToken) onlyReservePoolon the function, which ensures only the pool can call that function.
When depositing to curveVaultensure the receiver of the shares is LendingPool.
Update the totalVaultDepositswithin the LendingPool contract by adding the returned amount.
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.