Lingering permissions from uncleaned DEX swap token approvals
In PositionInteractionFacet._swapAssetToAsset(), the function approves amountInMaximum for swapping but the required amountIn could be less than or equal to amountInMaximum.
In PositionInteractionFacet._swapAssetToAsset(), the function approves amountInMaximum for swapping but the required amountIn could be less than or equal to amountInMaximum. This will leave the lingered approval to external Dex router.
function _swapAssetToAsset(...) internal returns (uint256 amountIn) {--- SNIPPED ---@> (uint256 amountInMaximum,,,) = IQuoterV2(dex.dexQuoter).quoteExactOutputSingle(quoteParams);@> amountInMaximum = _applySlippage(amountInMaximum);@> IERC20Metadata(assetIn).safeIncreaseAllowance(dex.dexRouter, amountInMaximum);IV3SwapRouter.ExactOutputSingleParams memory params = IV3SwapRouter.ExactOutputSingleParams({tokenIn: assetIn,tokenOut: assetOut,fee: dex.dexFee,recipient: address(this),deadline: block.timestamp + 30 minutes,amountOut: amountOut,amountInMaximum: amountInMaximum,sqrtPriceLimitX96: sqrtPriceLimitX96});@> amountIn = IV3SwapRouter(dex.dexRouter).exactOutputSingle(params);--- SNIPPED ---}
While this does not pose a significant security risk since:
- Only the trusted router contract has the approval.
- Future operations will reset approvals via
safeIncreaseAllowance.
It is still best practice to clean up unused approvals to minimize the attack surface.
Consider clearing the approval after the swap.
Report provenance
Published by Pashov Audit Group, with Carlos (Bloqarl) participating as a contractor. The source report states that its fixes review was not fully completed; no final remediation disposition is recorded for this finding. Read the full report.