In LendingPool::depositIntoVault
The LendingPool send crvUSD
to 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 LendingPool
cannot 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 curveVault
and receive and store the shares in the LendingPool
. The protocol then has 2 places where their reserves lie: RToken
and curveVault
.
This is impossible with the current logic becasue the deposit to curveVault will never happen, because LendingPool
does not have the crvUSD to deposit.
When a user deposits crvUSD to get minted RTokens in return, the crvUSD deposit is sent to RToken
contract, 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, LendingPool
never receives crvUSD and thus never has crvUSD to deposit into curveVault when attempting to do so :
** The use of RToken
contract as the holder of all reserveAsset
/crvUSD is prevelant throughout the codebase, where every transaction that involves the transfer of reserveAsset
is facilitated by the LendingPool
but never receives the reserve crvUSD, they are always transferred to RToken
contract. The LendingPool
does not have crvUSD within its contract to deposit.
Another example of this, is in the finializeLiquidation
function, crvUSD is not sent to the LendingPool
it is sent to RToken
contract. The LendingPool
only 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 : RToken
and 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 reserveAsset
held 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 reserveAsset
being held in RToken
and curveVault
. And when it is necessary to retrieve more reserveAsset
to the system for withdraws, the protocol can do this by redeeming crvUSD
from the curveVault
by 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 LEndingPool
can never make the deposit to the curveVault becasue all of the reserveTokens
are held in RToken
contract.
The functionality of the protocol is broken by the inability of the LendingPool
to deposit crvUSD to the curveVault.
manual review
Becasue crvUSD.
/ reserveAsset
is held only in the RToken
contract -> extend the functionality in _depositIntoVault
by adding that function and logic within the RToken
contract.
Place the modifier (already used within RToken) onlyReservePool
on the function, which ensures only the pool can call that function.
When depositing to curveVault
ensure the receiver of the shares is LendingPool
.
Update the totalVaultDeposits
within 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.