Blog

Understanding the Redundancy of block.timestamp + 10 minutes in Smart Contracts

The Redundant Use of Timestamps in Smart Contracts

When conducting smart contract audits, we frequently encounter code patterns that, while not functionally harmful, are nevertheless unnecessary. One such pattern that regularly appears is the use of timestamp deadlines for atomic transactions. This article explains why this practice is redundant and how you can optimize your code.

Identifying the Redundant Pattern

During smart contract audits, code like this often appears:
solidity

(, , uint256 liquidityAmount) = uniswapV2Router.addLiquidityETH{value: msg.value}(
token, // The address of the token contract
_tokenAmount, // The amount of token to add as liquidity
minToken, // Minimum amount of token to add (for slippage protection)
minEth, // Minimum amount of ETH to add (for slippage protection)
address(this), // Address that will receive the liquidity tokens
block.timestamp + 10 minutes // Deadline for transaction completion
);
The last line is particularly interesting: block.timestamp + 10 minutes. This parameter is supposed to set a deadline for the transaction, but as we'll see, this practice is completely superfluous in most cases.

Why Is This Practice Redundant?

The redundancy of this practice lies in how the Ethereum Virtual Machine (EVM) operates:
  1. Atomic Execution: Transactions in the EVM are executed atomically. This means either the entire transaction is executed in one block, or it fails completely.
  2. Execution Timing: When a transaction is confirmed for a block, block.timestamp is already set - it's the timestamp of that exact block.
  3. No "Partial" Execution: A transaction is not executed across multiple blocks. It's either fully executed in the current block or not at all.
Therefore, specifying a deadline like block.timestamp + 10 minutes is effectively meaningless for the actual transaction. If the transaction is included in the block, the deadline hasn't been reached anyway. If the transaction is delayed for any reason, the issue lies outside the smart contract's control.

Legitimate Use Cases for Deadlines

There are, however, legitimate use cases for deadlines in smart contracts:
  1. User-Initiated Processes: When a user initiates an action (e.g., a token swap on a DEX) that might be executed later, a deadline makes sense to prevent the transaction from being executed at later times with potentially unfavorable market conditions.
  2. Multi-Step Processes: For processes requiring multiple separate transactions (like some bridge operations or Layer-2 interactions), deadlines can be important.
  3. Front-Running Protection: In some cases, deadlines can serve as part of a broader strategy to protect against front-running attacks.

Optimizing Your Code

For atomic transactions like adding liquidity in a single function call, you can optimize your code as follows:
solidity

// Optimized version without redundant deadline
(, , uint256 liquidityAmount) = uniswapV2Router.addLiquidityETH{value: msg.value}(
token,
_tokenAmount,
minToken,
minEth,
address(this),
block.timestamp // Simply use the current block timestamp
);
Or even simpler, if the Uniswap router implementation allows it:
solidity

// Alternative with current timestamp
(, , uint256 liquidityAmount) = uniswapV2Router.addLiquidityETH{value: msg.value}(
token,
_tokenAmount,
minToken,
minEth,
address(this),
block.timestamp
);

Benefits of Optimization

Removing redundant code elements offers several advantages:
  1. Gas Efficiency: Every calculation in Solidity costs gas. Calculating block.timestamp + 10 minutes requires additional gas consumption, even if it's a small amount.
  2. Code Clarity: Code that's free of redundant elements is easier to understand and maintain.
  3. Reduced Complexity: Every unnecessary element increases the complexity of your smart contract and can lead to confusion for future developers.

Examples from Real Projects

During our smart contract audits, we've found numerous examples of this type of redundant code. This is particularly common in DeFi protocols that interact with Uniswap or similar DEXes.
A recurring pattern looks like this:
solidity

function swap() external {
// ... Code for preparing the swap ...

router.swapExactTokensForTokens(
amountIn,
minAmountOut,
path,
address(this),
block.timestamp + 15 minutes // <-- Redundant!
);

// ... Further processing ...
}
In our proven audit workflow, we identify such patterns and recommend optimizations that improve gas efficiency without compromising functionality.

When Should You Keep a Deadline?

Although we've highlighted the redundancy of deadlines in atomic transactions, there are scenarios where they might make sense:
  1. Queue-based Systems: If your transaction might be queued before execution.
  2. Interactions with External Protocols: Some protocols explicitly require deadline parameters, even if they aren't necessarily used meaningfully internally.
  3. Compatibility with Existing Systems: Sometimes it's more important to remain compatible with existing systems than to make small gas optimizations.

Conclusion: Efficiency Through Understanding the EVM

Understanding the fundamental operation of the EVM can help you write more efficient and clearer code. Detecting and eliminating redundant practices like unnecessary deadlines for atomic transactions is a small but important step toward improving the quality of your smart contracts.
For more insights into best practices for smart contract development and security, visit our blog or learn about our comprehensive security services.