The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: medium
Valid

Deadline check is not effective

Summary

The deadline parameter passed to ISwapRouter.ExactInputSingleParams is not effective and the transaction might be left hanging in the mempool and be executed way later than the user wanted at a possibly worse price.

Vulnerability Details

The SmartVaultV3 contract allows users to swap their collateral for a different token through the UniswapV3 SwapRouter. For example, this means that if a user deposited ETH as collateral it can swap it to wBTC or any other supported token directly within the vault.

function swap(bytes32 _inToken, bytes32 _outToken, uint256 _amount) external onlyOwner {
uint256 swapFee = _amount * ISmartVaultManagerV3(manager).swapFeeRate() / ISmartVaultManagerV3(manager).HUNDRED_PC();
address inToken = getSwapAddressFor(_inToken);
uint256 minimumAmountOut = calculateMinimumAmountOut(_inToken, _outToken, _amount);
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: inToken,
tokenOut: getSwapAddressFor(_outToken),
fee: 3000,
recipient: address(this),
deadline: block.timestamp //@audit not sufficient
amountIn: _amount - swapFee,
amountOutMinimum: minimumAmountOut,
sqrtPriceLimitX96: 0
});
inToken == ISmartVaultManagerV3(manager).weth()
executeNativeSwapAndFee(params, swapFee) :
executeERC20SwapAndFee(params, swapFee);
}

However, the deadline is hardcoded to block.timestamp. The deadline parameter enforces a time limit by which the transaction must be executed otherwise it will revert.

Let's take a look at the checkDeadline modifier that is present in the function which is called in the SwapRouter contract:

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

Now when the deadline is hardcoded as block.timestamp, the transaction will not revert because the require statement will always be fulfilled by block.timestamp == block.timestamp.

If a user chooses a transaction fee that is too low for miners to be interested in including the transaction in a block, the transaction stays pending in the mempool for extended periods, which could be hours, days, weeks, or even longer.

This could lead to users getting a worse price because a validator can just hold onto the transaction.

Impact

If the transaction stays for too long in the mempool before the swap is executed, the price for the swap could be much worse leading to a loss for the user.

Tools Used

Manual Review

Recommendations

Use a user-supplied deadline instead of block.timestamp.

Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

deadline-check-low

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

deadline-check

Support

FAQs

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