Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

Swapping on uniswap always revert due to deadline input is always equal to 0

Vulnerability Details

In UniswapV3Adapter contract, it call to uniswap router to swap token:
function executeSwapExactInputSingle(SwapExactInputSinglePayload calldata swapPayload)
external
returns (uint256 amountOut)
{
// transfer the tokenIn from the send to this contract
IERC20(swapPayload.tokenIn).transferFrom(msg.sender, address(this), swapPayload.amountIn);

// cache uniswap v3 swap strategy router
IUniswapV3RouterInterface swapRouter = IUniswapV3RouterInterface(uniswapV3SwapStrategyRouter);
// approve the tokenIn to the swap router
IERC20(swapPayload.tokenIn).approve(address(swapRouter), swapPayload.amountIn);
// get the expected output amount
uint256 expectedAmountOut = getExpectedOutput(swapPayload.tokenIn, swapPayload.tokenOut, swapPayload.amountIn);
// Calculate the minimum acceptable output based on the slippage tolerance
uint256 amountOutMin = calculateAmountOutMin(expectedAmountOut);
return swapRouter.exactInputSingle( // <--
IUniswapV3RouterInterface.ExactInputSingleParams({
tokenIn: swapPayload.tokenIn,
tokenOut: swapPayload.tokenOut,
fee: feeBps,
recipient: swapPayload.recipient,
deadline: deadline, // <--
amountIn: swapPayload.amountIn,
amountOutMinimum: amountOutMin,
sqrtPriceLimitX96: 0
})
);
}
/// inheritdoc IDexAdapter
function executeSwapExactInput(SwapExactInputPayload calldata swapPayload) external returns (uint256 amountOut) {
// transfer the tokenIn from the send to this contract
IERC20(swapPayload.tokenIn).transferFrom(msg.sender, address(this), swapPayload.amountIn);
// cache uniswap v3 swap strategy router
IUniswapV3RouterInterface swapRouter = IUniswapV3RouterInterface(uniswapV3SwapStrategyRouter);
// approve the tokenIn to the swap router
IERC20(swapPayload.tokenIn).approve(address(swapRouter), swapPayload.amountIn);
// get the expected output amount
uint256 expectedAmountOut = getExpectedOutput(swapPayload.tokenIn, swapPayload.tokenOut, swapPayload.amountIn);
// Calculate the minimum acceptable output based on the slippage tolerance
uint256 amountOutMinimum =
(expectedAmountOut * (Constants.BPS_DENOMINATOR - slippageToleranceBps)) / Constants.BPS_DENOMINATOR;
return swapRouter.exactInput( // <--
IUniswapV3RouterInterface.ExactInputParams({
path: swapPayload.path,
recipient: swapPayload.recipient,
deadline: deadline, // <--
amountIn: swapPayload.amountIn,
amountOutMinimum: amountOutMinimum
})
);
}

In both functions above, deadlinevariable is not defined. In solidity, it will become zero due to default value.

In uniswap v3, it have checkDeadline‎modifier in both functions:

modifier checkDeadline(uint256 deadline) {
require(_blockTimestamp() <= deadline, 'Transaction too old');
_;
}

from checkDeadline modifier, it can be seen that transaction always revert because deadline always equal to 0, which do not meet require condition

Impact

Swapping on uniswap always revert

Recommendations

Make deadline equal to block.timestamp.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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