Submitted by anon
The timestamp constraints and batch creation limitations in zkSync have several significant impacts on the platforms functionality and operations:
Upon initiating transaction processing in the bootloader, the first step involves creating a new batch using the setNewBatch function in the SystemContext contract.
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/bootloader/bootloader.yul#L3675
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/contracts/SystemContext.sol#L416
This operation enforces that the timestamp of the new batch must be greater than the timestamp of the previous batch and the timestamp of the last block in the previous batch.
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/contracts/SystemContext.sol#L423
https://github.com/code-423n4/2023-10-zksync/blob/1fb4649b612fac7b4ee613df6f6b7d921ddd6b0d/code/system-contracts/contracts/SystemContext.sol#L402
Subsequently, when processing a specific transaction, an L2 block is designated by invoking the setL2Block function within the SystemContext contract. This action ensures that the timestamp of the block is not lower than the timestamp of the current batch.
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/bootloader/bootloader.yul#L559
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/contracts/SystemContext.sol#L323
Once the processing of all transactions is completed, an additional fictive block is generated, serving as the final block within the batch. 
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/bootloader/bootloader.yul#L3812
Finally, the timestamp data is disclosed to L1 for verification.
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/bootloader/bootloader.yul#L3816
On the L1 side, during batch commitment, the _verifyBatchTimestamp function is called to confirm the accuracy of the timestamps. It enforces that the batchs timestamp is later than the previous batch and not less than block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER. Additionally, it ensures that the timestamp of the last block in this batch is not greater than block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA.
https://github.com/code-423n4/2023-10-zksync/blob/main/code/contracts/ethereum/contracts/zksync/facets/Executor.sol#L85
https://github.com/code-423n4/2023-10-zksync/blob/main/code/contracts/ethereum/contracts/zksync/facets/Executor.sol#L93
https://github.com/code-423n4/2023-10-zksync/blob/main/code/contracts/ethereum/contracts/zksync/facets/Executor.sol#L94
A critical concern arises when the operator, during the creation of a new batch on L2, sets its timestamp in close proximity to the value block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA. To illustrate this point, consider the following example:
Imagine a new batch, numbered 1000, is created with a timestamp of X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA - 1. This batch includes a block with a timestamp of X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA - 1 and a fictive block with a timestamp of X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA. Importantly, these values adhere to all the timestamp requirements outlined in the SystemContext contract, as explained earlier.
When this batch 1000, is committed on L1 at a specific time blockTimestamp1000 (meaning the time at which the batch 1000 is committed on L1), during timestamp verification, the following requirement is met (assuming X <= blockTimestamp1000):
https://github.com/code-423n4/2023-10-zksync/blob/main/code/contracts/ethereum/contracts/zksync/facets/Executor.sol#L94
Because:
This results in a successful proof and execution of the batch 1000. Now, when a new batch, 1001, is to be created on L2, its timestamp must be higher than X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA because a batchs timestamp should surpass the timestamp of the last block in the previous batch.
Suppose the timestamp of batch 1001 is X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA + Y, and the last block within this batch carries a timestamp of X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA + Y + K.
To summarize:
During the timestamp verification of batch 1001 on L1, to meet the requirement:
We must have:
Simplifying the condition yields:
Here, X represents the time set by the operator, where X <= blockTimestamp1000 as explained earlier. In the worst case scenario, if X = blockTimestamp1000, the condition becomes:
The variable Y signifies the amount of time required for the timestamp of batch 1001 to be higher than the timestamp of the last block in batch 1000. The minimum value of Y is 1 second. Assuming it is equal to 1 second (please note that if Y is higher than 1, the situation becomes even worse), the condition simplifies to:
This condition imposes a critical limitation on the number of blocks that can be included in a batch. As a reminder, the timestamp of the first block in batch 1001 is X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA + Y, while the timestamp of the last block in this batch is X + COMMIT_TIMESTAMP_APPROXIMATION_DELTA + Y + K (the fictive block). The difference between these two timestamps equals K, and since each blocks timestamp must be greater than the previous block, K defines the maximum number of blocks allowed in a batch.
This condition has several implications:
https://etherscan.io/tx/0xbfec43599bb73af95eaf4ac9ff83a62cdbe084382dd6f5d12bc8e817ce3574e5
https://etherscan.io/tx/0x1826d459ce7f2ab233374595569a13c4098e8e1eeb26517a98e42d9b5aab7374
https://github.com/code-423n4/2023-10-zksync/blob/main/docs/Smart%20contract%20Section/Batches%20%26%20L2%20blocks%20on%20zkSync.md#motivation
One potential solution is to commit batches on L1 with a longer delay to allow for more blocks to be included in batches. However, this approach may lead to other issues, such as an increased number of pending transactions and significantly extended finality.
Addressing this issue is not straightforward, and it would necessitate an upgrade of the Executor facet and a redesign of the timestamp verification process.
In summary, if the operator sets the timestamp of a batch too far into the future while still complying with L1 requirements, it can restrict the number of blocks that can be included in batches, resulting in a variety of challenges.
It is recommended that a more stricter timestamp constraint currently enforced in the _verifyBatchTimestamp function on L1 to also apply on L2. This will help prevent the creation and submission of batches with timestamps set in the distant future to L1. 
https://github.com/code-423n4/2023-10-zksync/blob/main/code/contracts/ethereum/contracts/zksync/facets/Executor.sol#L94
Context
Alex the Entreprenerd (judge) decreased severity to Medium
anon (warden) commented:
unforgiven (warden) commented:
miladpiri (zkSync) commented:
Alex the Entreprenerd (judge) commented:
vladbochok (zkSync) disputed, disagreed with severity and commented:
