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

ERC20 `approval` missed for `swapRouter` in `Fees` contract

Summary

The code omits a crucial step of ensuring that the swapRouter contract has enough allowance to spend the _profits tokens before calling swapRouter.exactInputSingle(params).

Vulnerability Details

The function sellProfits is designed to swap _profits tokens for WETH using the Uniswap v3 router.

function sellProfits(address _profits) public {
require(_profits != WETH, "not allowed");
uint256 amount = IERC20(_profits).balanceOf(address(this));
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter
.ExactInputSingleParams({
tokenIn: _profits,
tokenOut: WETH,
fee: 3000,
recipient: address(this),
deadline: block.timestamp,
amountIn: amount,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
amount = swapRouter.exactInputSingle(params);
IERC20(WETH).transfer(staking, IERC20(WETH).balanceOf(address(this)));
}

Lacks a necessary approval step to grant the swapRouter enough allowance to spend the _profits tokens. Without this approval, the exactInputSingle call will fail.

Impact

The absence of the ERC20 approval step can result in transaction failures. If the contract does not have a sufficient allowance, the exactInputSingle call will fail, leading to a failed transaction.

Tools Used

Manual review

Recommendations

Set unlimited allowance in the constructor. Consider granting unlimited allowance for the swap router in the constructor itself. This can be done once and avoids the need to approve the allowance repeatedly. Example:

constructor(address _weth, address _staking) {
WETH = _weth;
staking = _staking;
IERC20(_weth).approve(address(swapRouter), type(uint256).max);
}

Support

FAQs

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