The L2TokenReceiver contract uses block.timestamp as the deadline for transactions in the swap and increaseLiquidityCurrentRange functions. This practice does not provide the intended protection against the execution of stale transactions and may lead to unintended consequences if transactions are mined with a delay.
When a miner chooses to include the transaction into a block, its validity is established at that moment, as the block.timestamp reflects the current timestamp as the deadline.
The contract sets the deadline for certain operations to block.timestamp, which is the timestamp of the current block. Since the deadline is checked against the timestamp of the block in which the transaction is included, using block.timestamp as the deadline means the check will always pass as long as the transaction is included in any block, rendering the deadline check ineffective.
Please see the execution flows of swap() and increaseLiquidityCurrentRange().
In the code snippet of the swap function below, you can see that on line 65, block.timestamp is utilized as the deadline.
https://github.com/Cyfrin/2024-01-Morpheus/blob/07c900d22073911afa23b7fa69a4249ab5b713c8/contracts/L2TokenReceiver.sol#L57C1-L71C80
And observe what happens if line 71 calls the exactInputSingle() function from the SwapRouter contract in Uniswap V3.
https://github.com/Uniswap/v3-periphery/blob/697c2474757ea89fec12a4e6db16a574fe259610/contracts/SwapRouter.sol#L115C5-L121C6
The exactInputSingle() function employs the checkDeadline() modifier at line 119, which effectively compares the same current timestamps at line 8 in the code below.
https://github.com/Uniswap/v3-periphery/blob/697c2474757ea89fec12a4e6db16a574fe259610/contracts/base/PeripheryValidation.sol#L7C1-L10C6
In the provided code snippet for the increaseLiquidityCurrentRange function, you can see that block.timestamp is used as the deadline on line 112.
https://github.com/Cyfrin/2024-01-Morpheus/blob/07c900d22073911afa23b7fa69a4249ab5b713c8/contracts/L2TokenReceiver.sol#L78C1-L117C11
See the line 115 invokes the increaseLiquidity() function from the NonfungiblePositionManager contract in Uniswap V3.
https://github.com/Uniswap/v3-periphery/blob/697c2474757ea89fec12a4e6db16a574fe259610/contracts/NonfungiblePositionManager.sol#L198C1-L208C6
The increaseLiquidity() function utilizes the checkDeadline() modifier at line 202, effectively comparing the current timestamps as seen on line 8 in the provided code.
https://github.com/Uniswap/v3-periphery/blob/697c2474757ea89fec12a4e6db16a574fe259610/contracts/base/PeripheryValidation.sol#L7C1-L10C6
The ineffective use of deadlines in transaction execution can expose protocol to significant risks, particularly in volatile market conditions.
Transactions intended to manage swaps, liquidity or preempt liquidation events may be delayed by miners, who could prioritize more profitable operations with their subsequent transactions.
This delay could result in the original transaction being executed at a time when market conditions have shifted unfavorably, leading to substantial slippage or making the protocol vulnerable to front-running.
Additionally, miners may intentionally withhold transactions until the point of maximum slippage, exacerbating the protocol's potential losses and undermining the transaction's original intent.
Manual Review
Modify the contract functions to accept a deadline parameter from the caller instead of using block.timestamp directly within the functions.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.