The LendingPool::withdraw(), borrow()
functions are designed to extract liquidity from the Curve-crvUSD vault in case there is no sufficient liquidity in the RToken
, where essentially all the deposits are stored. However calling curve vault's withdraw function will result in DoS because of insufficient balance errors.
When a user decides to withdraw or borrow some crvUSD
tokens, the internal LendingPool::_ensureLiquidity
is invoked to provide the required amount in case of deficit:
The problem here is that in case of withdrawal from the Curve vault, the tokens will be transfered to address(this)
(LendingPool) (here is a link to the Curve vault withdraw(), to verify that receiver is specified as the Lending pool), but upon user deposit the tokens are directly transfered to the RToken
, that's why when determining the current buffer the crvUSD
balances of the RToken
are checked. Hence this will result in DoS.
Consider the following scenario:
Bob deposits 1000 tokens, if the currentBuffer > desiredBuffer (1000 > 200) the excess amount (800) will be deposited into the Curve vault
Now Bob wants to withdraw the full amount, the RToken
will not have enough, so _ensureLiquidity
will be called and try to withdraw the required amount from the Curve vault.
The vault will transfer the needed amount to the LendingPool
instead of the RToken
contract (the root cause of the issue)
And trigger ReserveLibrary::withdraw
, which will try to transfer out the 1000 tokens, but the RToken
will still have insufficient balance.
Results in DoS, same applies for borrows
Medium
, DoS of withdrawals
Manual Review
The receiver should be the RToken
contract
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.