The LendingPool contract's implementation of Curve vault withdrawals assumes incorrect ownership parameters, causing withdrawals to revert and leading to a Denial of Service in critical lending functions including borrowing, depositing, and withdrawing.
Let's break down the flow:
When users deposit crvUSD into the protocol, they interact with the deposit()
function in LendingPool
The crvUSD tokens are transferred to the RToken contract address (reserve.reserveRTokenAddress
)
The excess liquidity above the buffer ratio is deposited into the Curve vault by the LendingPool contract which is the one which receives the curve vault shares.
Looking at _depositIntoVault, it is the LendinPool contract (address(this)) that received the curve vault shares.
Withdrawal Implementation Issue in _withdrawFromVault:
The critical error is in the withdraw()
call to the Curve vault. Looking at ICurveCrvUSDVault interface:
The implementation passes msg.sender
as the owner parameter, but the actual owner of the vault shares is the LendingPool contract (address(this)
), since it was the one that deposited and received the shares.
The incorrect withdrawal implementation affects functions such as _ensureLiquidity()
:
This function is indirectly / directly called in:
withdraw()
- Lenders can't withdraw their deposits
borrow()
- Borrowers can't borrow against their collateral
deposit()
- Lenders can't deposit assets.
_rebalanceLiquidity()
- Protocol can't stake crvUSD into curve vault.
Alice deposits 1000 crvUSD into the LendingPool
The LendingPool deposits 800 crvUSD (80%) into Curve vault, keeping 200 as buffer
Bob tries to borrow 300 crvUSD
borrow()
calls _ensureLiquidity(300)
Function attempts to withdraw 100 from vault but reverts because msg.sender
(Bob) is not the owner of vault shares
Bob's borrow transaction fails
Complete DoS of core LendingPool functions including borrowing, withdrawing, and depositing
User funds become locked
Manual review
Correct the withdrawal function to use the LendingPool contract as owner:
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.