The convert function allows users to convert between different types of deposits, such as converting LP tokens into Beans or vice versa, depending on whether Beanstalk is above or below peg.
This function calls the removeLiquidityOneToken
method to execute the conversion. However, this implementation does not include a pre-execution check to ensure that sufficient liquidity is available in the pool to support the requested conversion. This omission can lead to failed transactions if there isn't enough liquidity to fulfill the request, wasting gas and potentially leading to DOS for the user.
The lack of a liquidity check before attempting to remove liquidity from a pool introduces a vulnerability where users can unknowingly initiate conversions that are doomed to fail due to insufficient liquidity.
POC:
Denial Of Service
Lets just say for argument sake Bob has 1,000 LP tokens in a Beanstalk with limited liquidity in the pool.
Its determined that Bob should receive 10,000 Beans in exchange for his LP tokens.
The actual liquidity in the pool can only provide 5,000 Beans.
Bob initiates a conversion of his 1,000 LP tokens into Beans, expecting around 10,000 Beans based on current rates.
The conversion process includes a call to _wellRemoveLiquidityTowardsPeg
, which aims to remove liquidity as Beans, given Bob's LP tokens.
Before executing the liquidity removal, the process calculates lpConverted = lp > maxLp ? maxLp : lp;.
This line determines the amount of LP to convert based on the maximum LP that can be converted to Beans at current rates (maxLp)
and the amount Bob wants to convert (lp).
If maxLp
(the maximum convertible LP based on liquidity) is less than Bob's LP (lp), lpConverted is set to maxLp
, capping the conversion at the pool's liquidity limit. Otherwise, Bob's full amount (lp) is used.
The calculation lpConverted = lp > maxLp ? maxLp : lp;
effectively limits Bob's conversion to the pool's
available liquidity. However, it does not pre-emptively inform Bob of the liquidity shortage or adjust his
expectations accordingly.
Bob's transaction proceeds, and due to the liquidity cap (maxLp)
, he receives only 2,000 Beans instead of the
expected 10,000, along with transaction costs.
Griefing
Bob has 1,000 LP tokens in a Beanstalk Farms pool with limited liquidity.
Its determined that Bob should receive 10,000 Beans for his LP tokens.
Actual liquidity in the pool can only provide 5,000 Beans.
Alice is monitoring pending transactions and the pool's liquidity status.
Bob initiates a conversion of his 1,000 LP tokens into Beans, expecting around 10,000 Beans.
The conversion process, through _wellRemoveLiquidityTowardsPeg
, calculates lpConverted = lp > maxLp ? maxLp : lp;
,
effectively capping Bob's conversion at 5,000 Beans due to liquidity limitations. Bob's transaction, due to a low gas fee provided, remains pending, exposing the transaction details to potential front-running.
Alice observes Bob's pending transaction and the liquidity limitation. She decides to exploit the situation by injecting her transaction with a higher gas fee, ensuring her transaction is processed before Bob's.
Alice's transaction further depletes the pool's liquidity, leaving even less for Bob's conversion.
Alice successfully front-runs Bob's transaction, exploiting the liquidity limitation and the lack of a
preemptive liquidity check or transaction deadline enforcement. When Bob's transaction finally processes, the liquidity in the pool is insufficient to meet even the reduced expectations set by lpConverted
, leading to his transaction failing or resulting in significantly less Beans than initially calculated.
This scenario highlights a compounded vulnerability where liquidity limitations not only lead to reduced
conversion outcomes but also expose users to potential DoS attacks or front-running by malicious actors.
As mentioned above, exposure to DOS and Griefing.
Manual Review
Implementing a mechanism to check for sufficient liquidity before attempting conversions could mitigate these risks. This could involve querying the pool's state to ascertain the available liquidity and comparing it with the requested amount for conversion, thereby ensuring that the operation is viable before it is executed
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.