The LendingPool's liquidity rebalancing mechanism incorrectly assumes the excess crvUSD buffer is held in the LendingPool contract when it's actually held in the RToken contract. This mismatch causes the _depositIntoVault
function to fail due to insufficient balance, resulting in a DoS of core protocol functions that depend on liquidity rebalancing.
The issue stems from a fundamental misunderstanding in how asset custody works in the protocol. Let's break down the flow:
When users deposit crvUSD into the protocol, the assets are transferred to the RToken contract, not the LendingPool:
When deposit() is called on the LendingPool the ReserveLibrary's deposit() function is used internally,
The _rebalanceLiquidity function checks balances and attempts to rebalance:
When attempting to deposit to the vault:
The failure in _depositIntoVault
causes _rebalanceLiquidity
to revert, which is called in critical functions:
Alice deposits 1000 crvUSD into the protocol
The crvUSD tokens are transferred to the RToken contract
The protocol calculates desiredBuffer as 200 crvUSD (20% of 1000)
Since currentBuffer (1000 in RToken) > desiredBuffer (200)
LendingPool tries to deposit 800 crvUSD to Curve vault
Transaction reverts as LendingPool has 0 crvUSD
Complete DoS of core protocol functions (deposit, withdraw, borrow) due to failed liquidity rebalancing.
The excess crvUSD is never deposited in to the curve vault
Manual review
Modify _depositIntoVault
to first transfer the assets from RToken to LendingPool:
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.