msc-smart-contract-auditing/vulnerable-functions-base huggingface dataset:
Vulnerability: Unsafe arithmetic casts
Severity: medium

Description:
The reason for using signed integers in some situations appears to be to use negative values as an indicator to withdraw everything. Using a whole bit of uint256 for this is quite a lot when using `type(uint256).max` would equal or better serve as a flag to withdraw everything.\\nFurthermore, even though the code uses `solidity 0.8.x`, which safeguards arithmetic operations against under/overflows, arithmetic typecast is not protected.\\nAlso, see issue 4.9 for a related issue.\\n```\\n⇒ solidity-shell\\n\\n🚀 Entering interactive Solidity ^0.8.11 shell. '.help' and '.exit' are your friends.\\n » ℹ️ ganache-mgr: starting temp. ganache instance // rest of code\\n » uint(int(-100))\\n115792089237316195423570985008687907853269984665640564039457584007913129639836\\n » int256(uint(2\\*\\*256-100))\\n-100\\n```\\n\\n```\\n// Compute how much collateral needs to be swapt\\nuint256 collateralInPlay = \\_getCollateralInPlay(\\n vAssets.collateralAsset,\\n vAssets.borrowAsset,\\n debtTotal + bonus\\n);\\n\\n// Burn f1155\\n\\_burnMulti(addrs, borrowBals, vAssets, \\_vault, f1155);\\n\\n// Withdraw collateral\\nIVault(\\_vault).withdrawLiq(int256(collateralInPlay));\\n```\\n\\n```\\n// Compute how much collateral needs to be swapt for all liquidated users\\nuint256 collateralInPlay = \\_getCollateralInPlay(\\n vAssets.collateralAsset,\\n vAssets.borrowAsset,\\n \\_amount + \\_flashloanFee + bonus\\n);\\n\\n// Burn f1155\\n\\_burnMulti(\\_addrs, \\_borrowBals, vAssets, \\_vault, f1155);\\n\\n// Withdraw collateral\\nIVault(\\_vault).withdrawLiq(int256(collateralInPlay));\\n```\\n\\n```\\nuint256 amount = \\_amount < 0 ? debtTotal : uint256(\\_amount);\\n```\\n\\n```\\nfunction withdrawLiq(int256 \\_withdrawAmount) external override nonReentrant onlyFliquidator {\\n // Logic used when called by Fliquidator\\n \\_withdraw(uint256(\\_withdrawAmount), address(activeProvider));\\n IERC20Upgradeable(vAssets.collateralAsset).univTransfer(\\n payable(msg.sender),\\n uint256(\\_withdrawAmount)\\n );\\n}\\n```\\n\\npot. unsafe truncation (unlikely)\\n```\\nfunction updateState(uint256 \\_assetID, uint256 newBalance) external override onlyPermit {\\n uint256 total = totalSupply(\\_assetID);\\n if (newBalance > 0 && total > 0 && newBalance > total) {\\n uint256 newIndex = (indexes[\\_assetID] \\* newBalance) / total;\\n indexes[\\_assetID] = uint128(newIndex);\\n }\\n}\\n```\\n

Impact:

Recommended mitigation:
If negative values are only used as a flag to indicate that all funds should be used for an operation, use `type(uint256).max` instead. It is wasting less value-space for a simple flag than using the uint256 high-bit range. Avoid typecast where possible. Use `SafeCast` instead or verify that the casts are safe because the values they operate on cannot under- or overflow. Add inline code comments if that's the case.
Vulnerability: Missing input validation on flash close fee factors
Severity: medium

Description:
The `FliquidatorFTM` contract allows authorized parties to set the flash close fee factor. The factor is provided as two integers denoting numerator and denominator. Due to a lack of boundary checks, it is possible to set unrealistically high factors, which go well above 1. This can have unexpected effects on internal accounting and the impact of flashloan balances.\\n```\\nfunction setFlashCloseFee(uint64 \\_newFactorA, uint64 \\_newFactorB) external isAuthorized {\\n flashCloseF.a = \\_newFactorA;\\n flashCloseF.b = \\_newFactorB;\\n```\\n

Impact:

Recommended mitigation:
Add a requirement making sure that `flashCloseF.a <= flashCloseF.b`.
Vulnerability: Separation of concerns and consistency in vaults
Severity: medium

Description:
The `FujiVaultFTM` contract contains multiple balance-changing functions. Most notably, `withdraw` is passed an `int256` denoted amount parameter. Negative values of this parameter are given to the `_internalWithdraw` function, where they trigger the withdrawal of all collateral. This approach can result in accounting mistakes in the future as beyond a certain point in the vault's accounting; amounts are expected to be only positive. Furthermore, the concerns of withdrawing and entirely withdrawing are not separated.\\nThe above issue applies analogously to the `payback` function and its dependency on `_internalPayback`.\\nFor consistency, `withdrawLiq` also takes an `int256` amount parameter. This function is only accessible to the `Fliquidator` contract and withdraws collateral from the active provider. However, all occurrences of the `_withdrawAmount` parameter are cast to `uint256`.\\nThe `withdraw` entry point:\\n```\\nfunction withdraw(int256 \\_withdrawAmount) public override nonReentrant {\\n updateF1155Balances();\\n \\_internalWithdraw(\\_withdrawAmount);\\n}\\n```\\n\\n_internalWithdraw's negative amount check:\\n```\\nuint256 amountToWithdraw = \\_withdrawAmount < 0\\n ? providedCollateral - neededCollateral\\n : uint256(\\_withdrawAmount);\\n```\\n\\nThe `withdrawLiq` entry point for the Fliquidator:\\n```\\nfunction withdrawLiq(int256 \\_withdrawAmount) external override nonReentrant onlyFliquidator {\\n // Logic used when called by Fliquidator\\n \\_withdraw(uint256(\\_withdrawAmount), address(activeProvider));\\n IERC20Upgradeable(vAssets.collateralAsset).univTransfer(\\n payable(msg.sender),\\n uint256(\\_withdrawAmount)\\n );\\n}\\n```\\n

Impact:

Recommended mitigation:
We recommend splitting the `withdraw(int256)` function into two: `withdraw(uint256)` and `withdrawAll()`. These will provide the same functionality while rendering the updated code of `_internalWithdraw` easier to read, maintain, and harder to manipulate. The recommendation applies to `payback` and `_internalPayback`.\\nSimilarly, withdrawLiq's parameter should be a `uint256` to prevent unnecessary casts.
Vulnerability: Missing slippage protection for rewards swap
Severity: medium

Description:
In `FujiVaultFTM.harvestRewards` a swap transaction is generated using a call to `SwapperFTM.getSwapTransaction`. In all relevant scenarios, this call uses a minimum output amount of zero, which de-facto deactivates slippage checks. Most values from harvesting rewards can thus be siphoned off by sandwiching such calls.\\n`amountOutMin` is `0`, effectively disabling slippage control in the swap method.\\n```\\ntransaction.data = abi.encodeWithSelector(\\n IUniswapV2Router01.swapExactETHForTokens.selector,\\n 0,\\n path,\\n msg.sender,\\n type(uint256).max\\n);\\n```\\n\\nOnly success required\\n```\\n// Swap rewards -> collateralAsset\\n(success, ) = swapTransaction.to.call{ value: swapTransaction.value }(swapTransaction.data);\\nrequire(success, "failed to swap rewards");\\n```\\n

Impact:

Recommended mitigation:
Use a slippage check such as for liquidator swaps:\\n```\\nrequire(\\n (priceDelta \\* SLIPPAGE\\_LIMIT\\_DENOMINATOR) / priceFromOracle < SLIPPAGE\\_LIMIT\\_NUMERATOR,\\n Errors.VL\\_SWAP\\_SLIPPAGE\\_LIMIT\\_EXCEED\\n);\\n```\\n\\nOr specify a non-zero `amountOutMin` argument in calls to `IUniswapV2Router01.swapExactETHForTokens`.
Vulnerability: Unclaimed or front-runnable proxy implementations
Severity: medium

Description:
Various smart contracts in the system require initialization functions to be called. The point when these calls happen is up to the deploying address. Deployment and initialization in one transaction are typically safe, but it can potentially be front-run if the initialization is done in a separate transaction.\\nA frontrunner can call these functions to silently take over the contracts and provide malicious parameters or plant a backdoor during the deployment.\\nLeaving proxy implementations uninitialized further aides potential phishing attacks where users might claim that - just because a contract address is listed in the official documentation/code-repo - a contract is a legitimate component of the system. At the same time, it is ‘only' a proxy implementation that an attacker claimed. For the end-user, it might be hard to distinguish whether this contract is part of the system or was a maliciously appropriated implementation.\\n```\\nfunction initialize(\\n address \\_fujiadmin,\\n address \\_oracle,\\n address \\_collateralAsset,\\n address \\_borrowAsset\\n) external initializer {\\n```\\n\\n`FujiVault` was initialized many days after deployment, and `FujiVault` inherits `VaultBaseUpgradeable`, which exposes a `delegatecall` that can be used to `selfdestruct` the contract's implementation.\\nAnother `FujiVault` was deployed by `deployer` initialized in a 2-step approach that can theoretically silently be front-run.\\ncode/artifacts/250-core.deploy:L2079-L2079\\n```\\n"deployer": "0xb98d4D4e205afF4d4755E9Df19BD0B8BD4e0f148",\\n```\\n\\nTransactions of deployer:\\nhttps://ftmscan.com/txs?a=0xb98d4D4e205afF4d4755E9Df19BD0B8BD4e0f148&p=2\\nThe specific contract was initialized 19 blocks after deployment.\\nhttps://ftmscan.com/address/0x8513c2db99df213887f63300b23c6dd31f1d14b0\\n\\n`FujiAdminFTM` (and others) don't seem to be initialized. (low prior; no risk other than pot. reputational damage)\\ncode/artifacts/250-core.deploy:L1-L7\\n```\\n{\\n "FujiAdmin": {\\n "address": "0xaAb2AAfBFf7419Ff85181d3A846bA9045803dd67",\\n "deployer": "0xb98d4D4e205afF4d4755E9Df19BD0B8BD4e0f148",\\n "abi": [\\n {\\n "anonymous": false,\\n```\\n

Impact:

Recommended mitigation:
It is recommended to use constructors wherever possible to immediately initialize proxy implementations during deploy-time. The code is only run when the implementation is deployed and affects the proxy initializations. If other initialization functions are used, we recommend enforcing deployer access restrictions or a standardized, top-level `initialized` boolean, set to `true` on the first deployment and used to prevent future initialization.\\nUsing constructors and locked-down initialization functions will significantly reduce potential developer errors and the possibility of attackers re-initializing vital system components.
Vulnerability: WFTM - Use of incorrect interface declarations
Severity: low

Description:
The `WFTMUnwrapper` and various providers utilize the `IWETH` interface declaration for handling funds denoted in `WFTM`. However, the `WETH` and `WFTM` implementations are different. `WFTM` returns `uint256` values to indicate error conditions while the `WETH` contract does not.\\n```\\ncontract WFTMUnwrapper {\\n address constant wftm = 0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83;\\n\\n receive() external payable {}\\n\\n /\\*\\*\\n \\* @notice Convert WFTM to FTM and transfer to msg.sender\\n \\* @dev msg.sender needs to send WFTM before calling this withdraw\\n \\* @param \\_amount amount to withdraw.\\n \\*/\\n function withdraw(uint256 \\_amount) external {\\n IWETH(wftm).withdraw(\\_amount);\\n (bool sent, ) = msg.sender.call{ value: \\_amount }("");\\n require(sent, "Failed to send FTM");\\n }\\n}\\n```\\n\\nThe `WFTM` contract on Fantom returns an error return value. The error return value cannot be checked when utilizing the `IWETH` interface for `WFTM`. The error return values are never checked throughout the system for `WFTM` operations. This might be intentional to allow `amount=0` on `WETH` to act as a NOOP similar to `WETH`.\\n```\\n// convert FTM to WFTM\\nif (isFtm) IWETH(\\_tokenAddr).deposit{ value: \\_amount }();\\n```\\n\\nAlso see issues: issue 4.4, issue 4.5, issue 4.10

Impact:

Recommended mitigation:
We recommend using the correct interfaces for all contracts instead of partial stubs. Do not modify the original function declarations, e.g., by omitting return value declarations. The codebase should also check return values where possible or explicitly state why values can safely be ignored in inline comments or the function's natspec documentation block.
Vulnerability: Inconsistent isFTM, isETH checks
Severity: low

Description:
`LibUniversalERC20FTM.isFTM()` and `LibUniversalERC20.isETH()` identifies native assets by matching against two distinct addresses while some components only check for one.\\nThe same is true for `FTM`.\\n`Flasher` only identifies a native `asset` transfer by matching `asset` against `_ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` while `univTransfer()` identifies it using `0x0 || 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`\\n```\\nfunction callFunction(\\n address sender,\\n Account.Info calldata account,\\n bytes calldata data\\n) external override {\\n require(msg.sender == \\_dydxSoloMargin && sender == address(this), Errors.VL\\_NOT\\_AUTHORIZED);\\n account;\\n\\n FlashLoan.Info memory info = abi.decode(data, (FlashLoan.Info));\\n\\n uint256 \\_value;\\n if (info.asset == \\_ETH) {\\n // Convert WETH to ETH and assign amount to be set as msg.value\\n \\_convertWethToEth(info.amount);\\n \\_value = info.amount;\\n } else {\\n // Transfer to Vault the flashloan Amount\\n // \\_value is 0\\n IERC20(info.asset).univTransfer(payable(info.vault), info.amount);\\n }\\n```\\n\\n`LibUniversalERC20`\\n```\\nlibrary LibUniversalERC20 {\\n using SafeERC20 for IERC20;\\n\\n IERC20 private constant \\_ETH\\_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);\\n IERC20 private constant \\_ZERO\\_ADDRESS = IERC20(0x0000000000000000000000000000000000000000);\\n\\n function isETH(IERC20 token) internal pure returns (bool) {\\n return (token == \\_ZERO\\_ADDRESS || token == \\_ETH\\_ADDRESS);\\n }\\n```\\n\\n```\\nfunction univTransfer(\\n IERC20 token,\\n address payable to,\\n uint256 amount\\n) internal {\\n if (amount > 0) {\\n if (isETH(token)) {\\n (bool sent, ) = to.call{ value: amount }("");\\n require(sent, "Failed to send Ether");\\n } else {\\n token.safeTransfer(to, amount);\\n }\\n }\\n}\\n```\\n\\nThere are multiple other instances of this\\n```\\nuint256 \\_value = vAssets.borrowAsset == ETH ? debtTotal : 0;\\n```\\n

Impact:

Recommended mitigation:
Consider using a consistent way to identify native asset transfers (i.e. `ETH`, FTM) by using `LibUniversalERC20.isETH()`. Alternatively, the system can be greatly simplified by expecting WFTM and only working with it. This simplification will remove all special cases where the library must handle non-ERC20 interfaces.
Vulnerability: FujiOracle - setPriceFeed should check asset and priceFeed decimals
Severity: low

Description:
`getPriceOf()` assumes that all price feeds return prices with identical decimals, but `setPriceFeed` does not enforce this. Potential misconfigurations can have severe effects on the system's internal accounting.\\n```\\n/\\*\\*\\n \\* @dev Sets '\\_priceFeed' address for a '\\_asset'.\\n \\* Can only be called by the contract owner.\\n \\* Emits a {AssetPriceFeedChanged} event.\\n \\*/\\nfunction setPriceFeed(address \\_asset, address \\_priceFeed) public onlyOwner {\\n require(\\_priceFeed != address(0), Errors.VL\\_ZERO\\_ADDR);\\n usdPriceFeeds[\\_asset] = \\_priceFeed;\\n emit AssetPriceFeedChanged(\\_asset, \\_priceFeed);\\n}\\n```\\n

Impact:

Recommended mitigation:
We recommend adding additional checks to detect unexpected changes in assets' properties. Safeguard price feeds by enforcing `priceFeed` == address(0) || priceFeed.decimals() == `8`. This allows the owner to disable a `priceFeed` (setting it to zero) and otherwise ensure that the feed is compatible and indeed returns `8` decimals.
Vulnerability: UniProxy.depositSwap - Tokens are not approved before calling Router.exactInput
Severity: high

Description:
the call to Router.exactInputrequires the sender to pre-approve the tokens. We could not find any reference for that, thus we assume that a call to `UniProxy.depositSwap` will always revert.\\n```\\nrouter = ISwapRouter(\\_router);\\nuint256 amountOut;\\nuint256 swap;\\nif(swapAmount < 0) {\\n    //swap token1 for token0\\n\\n    swap = uint256(swapAmount \\* -1);\\n    IHypervisor(pos).token1().transferFrom(msg.sender, address(this), deposit1+swap);\\n    amountOut = router.exactInput(\\n        ISwapRouter.ExactInputParams(\\n            path,\\n            address(this),\\n            block.timestamp + swapLife,\\n            swap,\\n            deposit0\\n        )\\n    );\\n}\\nelse{\\n    //swap token1 for token0\\n    swap = uint256(swapAmount);\\n    IHypervisor(pos).token0().transferFrom(msg.sender, address(this), deposit0+swap);\\n\\n    amountOut = router.exactInput(\\n        ISwapRouter.ExactInputParams(\\n            path,\\n            address(this),\\n            block.timestamp + swapLife,\\n            swap,\\n            deposit1\\n        )\\n    );     \\n}\\n```\\n

Impact:

Recommended mitigation:
Resolution\\nFixed in GammaStrategies/[email protected]9a7a3dd by deleting the `depositSwap` function.\\nConsider approving the exact amount of input tokens before the swap.
Vulnerability: Uniproxy.depositSwap - _router should not be determined by the caller
Severity: high

Description:
`Uniproxy.depositSwap` uses `_router` that is determined by the caller, which in turn might inject a “fake” contract, and thus may steal funds stuck in the `UniProxy` contract.\\nThe `UniProxy` contract has certain trust assumptions regarding the router. The router is supposed to return not less than deposit1(or deposit0) amount of tokens but that fact is never checked.\\n```\\nfunction depositSwap(\\n  int256 swapAmount, // (-) token1, (+) token0 for token1; amount to swap\\n  uint256 deposit0,\\n  uint256 deposit1,\\n  address to,\\n  address from,\\n  bytes memory path,\\n  address pos,\\n  address \\_router\\n) external returns (uint256 shares) {\\n```\\n

Impact:

Recommended mitigation:
Consider removing the `_router` parameter from the function, and instead, use a storage variable that will be initialized in the constructor.
Vulnerability: Re-entrancy + flash loan attack can invalidate price check
Severity: high

Description:
The `UniProxy` contract has a price manipulation protection:\\n```\\nif (twapCheck || positions[pos].twapOverride) {\\n  // check twap\\n  checkPriceChange(\\n    pos,\\n    (positions[pos].twapOverride ? positions[pos].twapInterval : twapInterval),\\n    (positions[pos].twapOverride ? positions[pos].priceThreshold : priceThreshold)\\n  );\\n}\\n```\\n\\nBut after that, the tokens are transferred from the user, if the token transfer allows an attacker to hijack the call-flow of the transaction inside, the attacker can manipulate the Uniswap price there, after the check happened. The Hypervisor's `deposit` function itself is vulnerable to the flash-loan attack.

Impact:

Recommended mitigation:
Make sure the price does not change before the `Hypervisor.deposit` call. For example, the token transfers can be made at the beginning of the `UniProxy.deposit` function.
Vulnerability: UniProxy.properDepositRatio - Proper ratio will not prevent liquidity imbalance for all possible scenarios
Severity: high

Description:
`UniProxy.properDepositRatio` purpose is to be used as a mechanism to prevent liquidity imbalance. The idea is to compare the deposit ratio with the `hypeRatio`, which is the ratio between the tokens held by the `Hypervisor` contract. In practice, however, this function will not prevent a skewed deposit ratio in many cases. `deposit1 / deposit0` might be a huge number, while `10^16 <= depositRatio <= 10^18`, and 10^16 <= `hypeRatio` <= 10^18. Let us consider the case where `hype1 / hype0 >= 10`, that means `hypeRatio = 10^18`, and now if `deposit1 / deposit0` = 10^200 for example, `depositRatio = 10^18`, and the transaction will pass, which is clearly not intended.\\n```\\nfunction properDepositRatio(\\n  address pos,\\n  uint256 deposit0,\\n  uint256 deposit1\\n) public view returns (bool) {\\n  (uint256 hype0, uint256 hype1) = IHypervisor(pos).getTotalAmounts();\\n  if (IHypervisor(pos).totalSupply() != 0) {\\n    uint256 depositRatio = deposit0 == 0 ? 10e18 : deposit1.mul(1e18).div(deposit0);\\n    depositRatio = depositRatio > 10e18 ? 10e18 : depositRatio;\\n    depositRatio = depositRatio < 10e16 ? 10e16 : depositRatio;\\n    uint256 hypeRatio = hype0 == 0 ? 10e18 : hype1.mul(1e18).div(hype0);\\n    hypeRatio = hypeRatio > 10e18 ? 10e18 : hypeRatio;\\n    hypeRatio = hypeRatio < 10e16 ? 10e16 : hypeRatio;\\n    return (FullMath.mulDiv(depositRatio, deltaScale, hypeRatio) < depositDelta &&\\n            FullMath.mulDiv(hypeRatio, deltaScale, depositRatio) < depositDelta);\\n  }\\n  return true;\\n}\\n```\\n

Impact:

Recommended mitigation:
Resolution\\nFixed in GammaStrategies/[email protected]9a7a3dd by deleting the `properDepositRatio` function.\\nConsider removing the cap of [0.1,10] both for `depositRatio` and for `hypeRatio`.
Vulnerability: UniProxy.depositSwap doesn't deposit all the users' funds
Severity: medium

Description:
When executing the swap, the minimal amount out is passed to the router (deposit1 in this example), but the actual swap amount will be `amountOut`. But after the trade, instead of depositing `amountOut`, the contract tries to deposit `deposit1`, which is lower. This may result in some users' funds staying in the `UniProxy` contract.\\n```\\nelse{\\n    //swap token1 for token0\\n    swap = uint256(swapAmount);\\n    IHypervisor(pos).token0().transferFrom(msg.sender, address(this), deposit0+swap);\\n\\n    amountOut = router.exactInput(\\n        ISwapRouter.ExactInputParams(\\n            path,\\n            address(this),\\n            block.timestamp + swapLife,\\n            swap,\\n            deposit1\\n        )\\n    );     \\n}\\n\\nrequire(amountOut > 0, "Swap failed");\\n\\nif (positions[pos].version < 2) {\\n  // requires lp token transfer from proxy to msg.sender\\n  shares = IHypervisor(pos).deposit(deposit0, deposit1, address(this));\\n  IHypervisor(pos).transfer(to, shares);\\n}\\n```\\n

Impact:

Recommended mitigation:
Resolution\\nFixed in GammaStrategies/[email protected]9a7a3dd by deleting the `depositSwap` function.\\nDeposit all the user's funds to the Hypervisor.
Vulnerability: Hypervisor - Multiple “sandwiching” front running vectors
Severity: medium

Description:
The amount of tokens received from `UniswapV3Pool` functions might be manipulated by front-runners due to the decentralized nature of AMMs, where the order of transactions can not be pre-determined. A potential “sandwicher” may insert a buying order before the user's call to `Hypervisor.rebalance` for instance, and a sell order after.\\nMore specifically, calls to `pool.swap`, `pool.mint`, `pool.burn` are susceptible to “sandwiching” vectors.\\n`Hypervisor.rebalance`\\n```\\nif (swapQuantity != 0) {\\n    pool.swap(\\n        address(this),\\n        swapQuantity > 0,\\n        swapQuantity > 0 ? swapQuantity : -swapQuantity,\\n        swapQuantity > 0 ? TickMath.MIN\\_SQRT\\_RATIO + 1 : TickMath.MAX\\_SQRT\\_RATIO - 1,\\n        abi.encode(address(this))\\n    );\\n}\\n```\\n\\n```\\nfunction \\_mintLiquidity(\\n    int24 tickLower,\\n    int24 tickUpper,\\n    uint128 liquidity,\\n    address payer\\n) internal returns (uint256 amount0, uint256 amount1) {\\n    if (liquidity > 0) {\\n        (amount0, amount1) = pool.mint(\\n            address(this),\\n            tickLower,\\n            tickUpper,\\n            liquidity,\\n            abi.encode(payer)\\n        );\\n    }\\n}\\n```\\n\\n```\\nfunction \\_burnLiquidity(\\n    int24 tickLower,\\n    int24 tickUpper,\\n    uint128 liquidity,\\n    address to,\\n    bool collectAll\\n) internal returns (uint256 amount0, uint256 amount1) {\\n    if (liquidity > 0) {\\n        // Burn liquidity\\n        (uint256 owed0, uint256 owed1) = pool.burn(tickLower, tickUpper, liquidity);\\n\\n        // Collect amount owed\\n        uint128 collect0 = collectAll ? type(uint128).max : \\_uint128Safe(owed0);\\n        uint128 collect1 = collectAll ? type(uint128).max : \\_uint128Safe(owed1);\\n        if (collect0 > 0 || collect1 > 0) {\\n            (amount0, amount1) = pool.collect(to, tickLower, tickUpper, collect0, collect1);\\n        }\\n    }\\n}\\n```\\n

Impact:

Recommended mitigation:
Consider adding an `amountMin` parameter(s) to ensure that at least the `amountMin` of tokens was received.