20,000 USDC
View results
Submission Details
Severity: medium
Valid

Loss of profits for many ERC20s

Summary

Limited liquidity of certain ERC20 tokens will lead to loss of profits

Vulnerability Details

The sellProfits function requires tokens to be liquidated to WETH via a single Uniswap v3 pool with 0.3% fee. This will, for many ERC20 tokens, cause profits to be stuck in the contract, siphoned by attackers, or significantly diminished from slippage.
This breaks from Beedle's target to be compatible with any ERC20 (https://twitter.com/beedlefi/status/1682072339612155907).

  • A token without a direct pool to WETH at 0.03% fee will not be able to be swapped and the token will be stuck in the contract.

  • An attacker could create a uniswap pool with the token against WETH and initialize it with a token balance in a way that creates an artificially low price for the profit asset and then execute the trade. This would give the attacker the profit assets in exchange for a very small amount of WETH.

  • Additionally, a token that is compatible may experience extreme slippage if the fee level is uncommon, as the pool will have relatively low liquidity and therefore higher slippage. For example, the rETH:ETH pool on mainnet at a 0.05% fee currently has 108x the liquidity that the 0.3% pool has. This will cause excessive slippage and a loss of profit for the protocol.

Impact

Any profits from a loan using an ERC20 token that has no pool or a low-liquidity pool against WETH at 0.3% fee on Uniswap v3. This is a large portion of the total ERC20s available currently, including LUSD, rETH, etc.

Recommendations

On chain swapping when the calldata cannot be trusted is an extremely difficult problem. In order to prevent loss due to liquidity fragmentation different routes and DEXes could be set per token, however this would compromise Beedle's asset agnostic approach.

I believe the best solution is not a simple code update, because I do not think there is a safe way to accomplish the swap without compromising the vision. Instead I would suggest a design change - replace the DEX swap with a dutch auction mechanism. Once enough profits accrue an external user can kick off an auction for X amount of Y token (make sure to consider griefing attack of kicking against extremely small quantities of profit). The price will decrease with time and users (arbitrage bots most likely) can trigger a purchase when the price gets to a level low enough for them to profit.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.