This problem arises from the LendingPool::_withdrawFromVault() function. The 2nd argument is wrong and will make the tx always revert.
As per the interface provided ICurveCrvUSDVault, see here:
But when withdrawing lending pool passes address(this) as the owner argument instead of the RToken.address. This will make the tx revert as when RToken tries to transfer the funds to the user it won't have enough because the funds have been withdrawn to the LendingPool and not to the RToken where actually all funds deposited are stored.
Let's showcase a detailed flow of a withdrawal that requires to withdraw from the CRV vault.
_ensureLiquidity() detects that a _withdrawFromVault() is needed and transfers the funds to the LendingPool.
Call flow: LendingPool::withdraw() -> _ensureLiquidity() -> _withdrawFromVault()
As you can see after this the next step is withdraw from reserve library here. That calls burn from RToken here.
Burn transfers amount from RToken to the receiver here.
As we could see in the _ensureLiquidity() function, the withdrawal only triggers if amount was too big and required for funds to be transferred.
So the transfer from the RToken will revert because the balance of the RToken contract is smaller than the amount, because if _ensureLiquidity() is triggered, that means there were not enough available liquidity deposited.
But as said, then the receiver of the withdrawn from CRV tokens is the LendingPool and not the RToken contract. Yet the eventual transfer happens on the RToken as we saw here. Note that there is no transfer from LendingPool to RToken contract before the burn function call in this flow either, see again here.
_withdrawFromVault() is incorrectly implemented due to the receiver argument. Temporarely DOSing vital funcitons if they require withdrawing from CRV vaults, functions like LendingPool::withdraw() or LendingPool::borrow(). They both call _withdrawFromVault() form _ensureLiquidity().
At _withdrawFromVault() the receiver arg should be RToken.address.
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.