LendingPool::_withdrawFromVault
is used when the function _rebalanceLiquidity
is called. If the currentBuffer
is lower than the desiredBuffer
then the contract would withdraw some asset token to satisfy the buffer.
But the receiver of the withdraw function from curve vault is LendingPool token and not the RToken address, this would lead the currentBuffer < desiredBuffer
to always resulting in true statement. making the subsequent _rebalanceLiquidity
always calling _withdrawFromVault
to satisfy the missing buffer.
if we check how currentBuffer
and desiredBuffer
are calculated inside _rebalanceLiquidity
, then this issue would be easy to understand:
desiredBuffer
is the total liquidty in the system multiplied with the desired buffer ratio, where the currentBuffer
is the asset token balance of reserve.reserveRTokenAddress
and this value is the RToken
address.
if the desired buffer is not satisfied, then the shortage would be withdrawn from curve vault:
but the address used to receive the token is address(this)
which is the LendingPool itself.
this is problematic because the currentBuffer
is calculated from the asset token balance of RToken address, not lending pool address.
so even after the withdraw, later when the liquidity is rebalanced again, the currentBuffer > desiredBuffer
would always return to false.
with the currentBuffer > desiredBuffer
is always false then making the else if block executed, the contract would always try to withdraw from vault until the shortage
amount is bigger than what the contract current deposit balance, this would lead to DoS because the maxLoss
params is set to 0.
the said DoS function would be LendingPool deposit, withdraw and _repay function.
manual review
the receiver of curve vault withdraw should be RToken
address instead address(this)
to make the buffer check logic consistent.
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.