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

`Fees::sellProfits` does not allow for slippage protection; protocol funds will be lost to sandwich attacks

Summary

By using Fees::sellProfits, any amount of fees that are accumulated up to that point in it will be swapped for WETH and sent to the staking contract.
Since swapping is done without slippage protection, any swap can be easily sandwiched leading to protocol losses.

Also, because anyone can call sellProfits it is even easier for it to be included in an attack as a malicious caller can simply chain the executions one after another and himself trigger the attack.

Vulnerability Details

Swapping is done using Uniswap V3 router (ISwapRouter) with the following swap arguments:

ISwapRouter.ExactInputSingleParams memory params = ISwapRouter
.ExactInputSingleParams({
tokenIn: _profits,
tokenOut: WETH,
fee: 3000,
recipient: address(this),
deadline: block.timestamp,
amountIn: amount,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});

Leaving amountOutMinimum as 0 is a significant issue and will surely result protocol funds lost due to it.

Theoretical POC:

  • alice wants to move what profits exist from the Fees contract to the staking contract and calls sellProfits

  • bob's MEV bot sees that alice's transaction does not have slippage so it initiates a sandwich attack on the transactions

    • the bot buys the token before alice's execution (also using a flashloan), front-running-it and making the price grow by 20%.

    • alice's execution is done, buying less tokens then first speculated

    • bob's bot also fired a back-run execution, within the same transaction, that sells all tokens bought, basically gaining a profit due to alices buy

Since a malicious party can initiate this attack whenever he pleases since sellProfits is callable by anyone this issue is especially severe.

Impact

Protocol fee rewards will be lost due to sandwich attacks.

Tools Used

Manual review

Recommend Mitigation

  • Add amountOutMinimum as an extra parameter to sellProfits function and set in the ExactInputSingleParams. This way, calling 3rd party can protect protocol funds from being stolen.

  • Also, either add a minimum percentage to amountOutMinimum or add access control to sellProfits. If this is not done, a malicious party may still call the function but using no slippage to achieve the same damage.

Support

FAQs

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