MorpheusAI

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

No expiration deadline leads to loss of funds while swapping and increase liquidity

Summary

In L2TokenReceiver.sol, swap() and increaseLiquidityCurrentRange() does not set an expiration deadline, resulting in loss of funds when swapping tokens.

Vulnerability Details

Per the contest page, the contracts will also be deployed on Ethereum mainnet along with Arbitrum. Since, Ethereum has mempool and the possibility of this issue is applicable here.

The deadline parameter in the swap() is set to block.timestamp. That means the function will accept a token swap at any block.timestamp which means there is no expiry deadline.

swap() does not allow the function caller to submit a deadline for their actions which execute swaps on Uniswap V3. This missing feature enables pending transactions to be maliciously executed at a later point.

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, @audit // deadline is hardcoded to 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_;
}

Similarly, In increaseLiquidityCurrentRange(), the deadline is hardcoded to block.timestamp and the above issue will also applicable to this function.

function increaseLiquidityCurrentRange(
uint256 tokenId_,
uint256 depositTokenAmountAdd_,
uint256 rewardTokenAmountAdd_,
uint256 depositTokenAmountMin_,
uint256 rewardTokenAmountMin_
) external onlyOwner returns (uint128 liquidity_, uint256 amount0_, uint256 amount1_) {
. . . some code
INonfungiblePositionManager.IncreaseLiquidityParams memory params_ = INonfungiblePositionManager
.IncreaseLiquidityParams({
tokenId: tokenId_,
amount0Desired: amountAdd0_,
amount1Desired: amountAdd1_,
amount0Min: amountMin0_,
amount1Min: amountMin1_,
@> deadline: block.timestamp @audit // deadline is hardcoded to block.timestamp
});
(liquidity_, amount0_, amount1_) = INonfungiblePositionManager(nonfungiblePositionManager).increaseLiquidity(
params_
);
emit LiquidityIncreased(tokenId_, amount0_, amount1_, liquidity_, amountMin0_, amountMin1_);
}

Impact

Without an expiration deadline, a malicious miner/validator can hold a transaction until they favor it or they can make a profit.

Tools Used

Manual review

Recommendations

Set the deadline parameter in swap() and increaseLiquidityCurrentRange(). This user defind timestamp will ensure, once deadline is passed the transaction will expire.

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.