MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: low
Invalid

The `deadline` parameter in `L2TokenReceiver::swap` function is set to `block.timestamp`

Summary

In the L2TokenReceiver::swap function the deadline parameter is set to block.timestamp.

Vulnerability Details

The L2TokenReceiver::swap function has parameter deadline set to block.timestamp:

function swap(uint256 amountIn_, uint256 amountOutMinimum_) external onlyOwner returns (uint256) {
SwapParams memory params_ = params;
ISwapRouter.ExactInputSingleParams memory swapParams_ = ISwapRouter.ExactInputSingleParams({
tokenIn: params_.tokenIn,
tokenOut: params_.tokenOut,
fee: params_.fee,
recipient: address(this),
@> deadline: block.timestamp,
amountIn: amountIn_,
amountOutMinimum: amountOutMinimum_,
sqrtPriceLimitX96: params_.sqrtPriceLimitX96
});
uint256 amountOut_ = ISwapRouter(router).exactInputSingle(swapParams_);
emit TokensSwapped(params_.tokenIn, params_.tokenOut, amountIn_, amountOut_, amountOutMinimum_);
return amountOut_;
}

Since block.timestamp is always relative, using it in any way is equivalent to using no deadline at all. Needs to use a user defined input to effectively enforce any deadline. If there is no deadline, the transaction will be left hanging in the mempool and be executed later than the user wanted. This leads to user getting a worse price, because a validator can just hold onto the transaction. And when it does get around to putting the transaction in a block, it'll be block.timestamp, so there is no protection.
Here is a link to an article that describes briefly the impact of use block.timestamp as deadline is swap function and how Uniswap deals with it:
https://web.archive.org/web/20230525014603/https://blog.bytes032.xyz/p/why-you-should-stop-using-block-timestamp-as-deadline-in-swaps

Impact

The impact of the setting deadline parameter to block.timestamp is that in some cases, transactions might be delayed due to network congestion, causing them to miss their deadline. This could lead to the transaction failing unnecessarily.
Also, this results in the user getting a worse price because the validator can hold the transaction. And when it comes to putting the transaction into a block, it will be block.timestamp, so there is no protection.

Tools Used

Manual Review

Recommendations

It is recommended to set the deadline parameter to be uint256 value. You can define deadline value or add an additional input parameter deadline:

+ function swap(uint256 amountIn_, uint256 amountOutMinimum_, uint256 deadline) external onlyOwner returns (uint256) {
- function swap(uint256 amountIn_, uint256 amountOutMinimum_) external onlyOwner returns (uint256) {
SwapParams memory params_ = params;
ISwapRouter.ExactInputSingleParams memory swapParams_ = ISwapRouter.ExactInputSingleParams({
tokenIn: params_.tokenIn,
tokenOut: params_.tokenOut,
fee: params_.fee,
recipient: address(this),
+ deadline: deadline,
- deadline: block.timestamp,
amountIn: amountIn_,
amountOutMinimum: amountOutMinimum_,
sqrtPriceLimitX96: params_.sqrtPriceLimitX96
});
uint256 amountOut_ = ISwapRouter(router).exactInputSingle(swapParams_);
emit TokensSwapped(params_.tokenIn, params_.tokenOut, amountIn_, amountOut_, amountOutMinimum_);
return amountOut_;
}
Updates

Lead Judging Commences

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

Protocol should not use block.timestamp as deadline in Uniswap interactions because it renders the protection mechanism useless

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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