The LendingPool
contract's integration with Curve's vault fails to handle scenarios where the vault is at a loss, which can lead to a complete denial of service for withdrawals.
The LendingPool::_withdrawFromVault() function attempts to withdraw funds from the Curve vault without considering potential losses in the vault's value. According to Curve's documentation, there can be periods where the vault experiences losses, meaning the actual withdrawn amount would be less than requested.
The current implementation makes an unchecked call to curveVault.withdraw()
which will revert if the vault cannot return the full requested amount:
This withdrawal function is called by _rebalanceLiquidity()
which is triggered on every deposit and withdrawal operation. If the vault is at a loss and the withdrawal reverts, it will cause all deposit and withdrawal operations to fail.
Users deposit funds into the LendingPool which are partially moved to the Curve vault based on the buffer ratio
The Curve vault experiences a loss period where asset value drops
A user attempts to withdraw funds from the LendingPool
_rebalanceLiquidity()
is called which triggers _withdrawFromVault()
The vault withdrawal reverts due to insufficient value
The entire withdrawal transaction reverts, blocking access to user funds
This affects all subsequent withdrawals until the vault recovers its value
Complete denial of service for user withdrawals during vault loss periods
Users cannot access their deposited funds even if the LendingPool has sufficient liquidity in its buffer, because it will still try to rebalance the liquidity in the pool.
Implement a circuit breaker that disables vault integration when losses are detected:
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.