MorpheusAI

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

Using `block.timestamp` for deadline does not protect against MEV attacks

Summary

The L2TokenReceiver contract uses block.timestamp as the deadline for token swapping and liquidity management within the swap and increaseLiquidityCurrentRange functions. However, setting the deadline as block.timestamp essentially makes the deadline parameter useless and gives malicious miners the ability to hold the transaction for as long as they like and execute it at a more favourable block number.

Vulnerability Details

Both the swap and increaseLiquidityCurrentRange functions utilize block.timestamp to set the deadlines. This method does not effectively safeguard against the manipulation of transaction timing by miners or through MEV strategies. The point of the deadline parameter is that it will check against block.timestamp when the transaction is mined. If block.timestamp <= deadline, then the transaction is successful. However, if you set the deadline as block.timestamp, it is just comparing against the same value and defeats the purpose of the deadline protection. Visit here for more details.

swap function:

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_;
}

increaseLiquidityCurrentRange function:

function increaseLiquidityCurrentRange(
uint256 tokenId_,
uint256 depositTokenAmountAdd_,
uint256 rewardTokenAmountAdd_,
uint256 depositTokenAmountMin_,
uint256 rewardTokenAmountMin_
) external onlyOwner returns (uint128 liquidity_, uint256 amount0_, uint256 amount1_) {
uint256 amountAdd0_;
uint256 amountAdd1_;
uint256 amountMin0_;
uint256 amountMin1_;
(, , address token0_, , , , , , , , , ) = INonfungiblePositionManager(nonfungiblePositionManager).positions(
tokenId_
);
if (token0_ == params.tokenIn) {
amountAdd0_ = depositTokenAmountAdd_;
amountAdd1_ = rewardTokenAmountAdd_;
amountMin0_ = depositTokenAmountMin_;
amountMin1_ = rewardTokenAmountMin_;
} else {
amountAdd0_ = rewardTokenAmountAdd_;
amountAdd1_ = depositTokenAmountAdd_;
amountMin0_ = rewardTokenAmountMin_;
amountMin1_ = depositTokenAmountMin_;
}
INonfungiblePositionManager.IncreaseLiquidityParams memory params_ = INonfungiblePositionManager
.IncreaseLiquidityParams({
tokenId: tokenId_,
amount0Desired: amountAdd0_,
amount1Desired: amountAdd1_,
amount0Min: amountMin0_,
amount1Min: amountMin1_,
@> deadline: block.timestamp
});
(liquidity_, amount0_, amount1_) = INonfungiblePositionManager(nonfungiblePositionManager).increaseLiquidity(
params_
);
emit LiquidityIncreased(tokenId_, amount0_, amount1_, liquidity_, amountMin0_, amountMin1_);
}

Impact

Despite being restricted to onlyOwner, these operations influence the protocol's liquidity and market positions, impacting user assets. It can also lead to suboptimal swap rates or liquidity positions, potentially diminishing the protocol's assets or affecting its ability to provide user services effectively, and loss of user trust.

Tools Used

Manual review.

Recommendations

Consider modifying the swap and increaseLiquidityCurrentRange to allow the owner of the contract to use a specific deadline input parameter, rather than using block.timestamp.

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.