MorpheusAI

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

`L2TokenReceiver` contract: using `block.timestamp` when interacting with Uniswap doesn't protect against execution of pending transactions

Summary

L2TokenReceiver contract: using block.timestamp when interacting with Uniswap NonfungiblePositionManager & SwapRouter doesn't protect against execution of pending transactions, since using block.timestamp as a deadline for the transaction indicates that the transaction can be executed at any time as long as exection time (block.timestamp) is <= deadline (which is block.timestamp).

Vulnerability Details

  • L2TokenReceiver contract is meant to receive the bridged overPlus staked stETH on L1, and utilizing them to farm yield by providing them to a Uniswap wstETH pool.

  • This contract interacts with Uniswap nonfungiblePositionManager contract to increase the liquidity of the created positions:

    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_
    );
  • As can be noticed; the IncreaseLiquidityParams.deadline, which represents when the pending transaction shouldn't be executed after, is set to block.timestamp, and this doesn't provide any protection against execution of staled/pending transactions, as it indicates that the transaction can be executed at any time (block.timestamp).

  • The same issue in L2TokenReceiver.swap function.

Impact

  • Not providing a valid deadline will introduce risks to the created position/contract swapped tokens, since setting the execution deadline to the block.timestamp will enable pending transactions to be executed at any time in the future regardless being staled for a while, while the requested minimum parameters were suitable for the time transaction created, for example:

    • a increaseLiquidityCurrentRange transaction is initiated with specific rewardTokenAmountMin_ & depositTokenAmountMin_ values that are supposed to protect against slippage.

    • The transaction isn't executed in the same block (not included by the validators in the same block due to low gas provided for execution), but executed at some time later where the required values of rewardTokenAmountMin_ & depositTokenAmountMin_ become low where they don't protect against slippage.

Proof of Concept

L2TokenReceiver.increaseLiquidityCurrentRange function/L105-L117

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

L2TokenReceiver.swap function/L60-L69

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

Tools Used

Manual Review.

Recommendations

Update increaseLiquidityCurrentRang & swap functions to have a deadline parameter that's determined by the caller (contract owner) instead of 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.