The Fees::sellProfits()
lacks slippage protection, resulting in being attacked by a sandwich attack to drain all locked ERC-20 tokens.
The sellProfits()
is a permissionless function that can be called by anyone. The function lacks slippage protection (the parameters amountOutMinimum
and sqrtPriceLimitX96
are set to 0) when swapping tokens through Uniswap's pools.
In this way, an attacker can launch a sandwich attack with a flash loan to drain all ERC-20 tokens (e.g., USDC, DAI, CRV, etc.) locked in the Fees
contract.
For instance, to drain all USDC, consider the following proof-of-concept.
Attacker borrows a flash loan for USDC and buys WETH from Uniswap's WETH/USDC pool.
Attacker executes the sellProfits(USDC)
.
The sellProfits()
will spend all locked USDC for buying WETH at a very high price.
Attacker sells the previously obtained WETH for USDC at the same pool and repays the flash loan.
Attacker takes all locked USDC as profit.
Moreover, an attacker can perform steps 1-5 above to steal other ERC-20 tokens locked in the Fees
contract.
https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Fees.sol#L38-L39
An attacker can drain all ERC-20 tokens (e.g., USDC, DAI, CRV, etc.) locked in the Fees
contract. Therefore, I consider this vulnerability a high-risk issue.
Manual Review
I recommend adding the onlyOwner
modifier and setting the amountOutMinimum
parameter to protect price slippage from MEV bots. If necessary, specify the sqrtPriceLimitX96
parameter to set a stop price.
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.