Timestamp Dependence
Detects reliance on block.timestamp for time-sensitive logic where validator manipulation of the timestamp by up to ~15 seconds can influence outcomes.
Timestamp Dependence
Overview
Remediation Guide: How to Fix Timestamp Dependence
The timestamp dependence detector identifies smart contract logic that relies on block.timestamp (EVM opcode TIMESTAMP) for outcomes where a validator’s ability to adjust the timestamp by approximately 15 seconds creates an exploitable window. Validators can include a block with a timestamp anywhere in the range [parent_timestamp + 1, now + 15s], giving them slight but potentially profitable control over time-sensitive contract logic.
Sigvex scans for TIMESTAMP opcode usage and traces the value through data-flow to determine whether it influences: random seed generation (covered by weak-randomness), deadline comparisons, time-lock releases, interest accrual cutoffs, or auction end conditions. The detector is specifically concerned with applications where a 15-second manipulation window has financial impact.
Why This Is an Issue
While block.timestamp is generally reliable for long-duration timekeeping (days, weeks), it is unsuitable for sub-minute precision. The 15-second manipulation window is enough to:
- Prevent an auction from ending at the stated time
- Cause a staking reward to accrue slightly more or less than intended
- Allow a validator who controls a time-locked function to unlock it one block early
- Bias a random outcome that depends on precise timing
Pre-Merge, miners had more flexibility. Post-Merge (Ethereum PoS), validators have a smaller manipulation window but it is not zero.
How to Resolve
// Before: Vulnerable — vulnerable to 15-second validator manipulation
function endAuction() external {
require(block.timestamp >= auctionEnd, "Auction still running");
// Finalize auction...
}
// For many use cases, block.timestamp is acceptable — use block.number for precision
// After: Use block number for time-critical logic with fine granularity
uint256 public endBlock;
function endAuction() external {
require(block.number >= endBlock, "Auction still running");
// block.number cannot be manipulated by validators in PoS
}
For applications that genuinely need wall-clock time with higher precision:
// Use a Chainlink oracle for off-chain time when precision matters
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
// For most deadline/cooldown cases, block.timestamp is fine if the window is > 30s
// Document the acceptable tolerance explicitly
uint256 public constant TIMESTAMP_TOLERANCE = 15 seconds;
uint256 public deadline;
function isExpired() public view returns (bool) {
// Allow 15s tolerance — make this explicit in documentation
return block.timestamp > deadline + TIMESTAMP_TOLERANCE;
}
Examples
Vulnerable Code
// Seed generation using timestamp — covered also by weak-randomness
contract VulnerableAuction {
uint256 public endTime;
address public highestBidder;
// Validator can manipulate to prevent end at exactly the right moment
function finalizeAuction() external {
require(block.timestamp >= endTime, "Not ended");
// Validator with 15-second window can decide whether to include this
// — beneficial if they want to extend bidding
_transferToBidder(highestBidder);
}
}
Fixed Code
contract SecureAuction {
uint256 public endBlock; // Use block number instead
constructor(uint256 durationBlocks) {
endBlock = block.number + durationBlocks;
}
function finalizeAuction() external {
require(block.number >= endBlock, "Not ended");
_transferToBidder(highestBidder);
}
}
Sample Sigvex Output
{
"detector_id": "timestamp",
"severity": "medium",
"confidence": 0.72,
"description": "Function finalizeAuction() uses block.timestamp as the sole condition for a financial operation. Validators can manipulate this by up to 15 seconds.",
"location": { "function": "finalizeAuction()", "offset": 44 }
}
Detection Methodology
- TIMESTAMP opcode detection: Identifies all uses of the
TIMESTAMPopcode. - Financial impact assessment: Traces the timestamp value to determine whether it influences: financial transfers, token minting, interest calculations, or access control with time-dependent logic.
- Window size estimation: Attempts to determine the sensitivity of the comparison (e.g.,
>= deadlinewith a deadline in the past by only seconds is more critical than a comparison with a 7-day window). - Non-critical usage recognition: Timestamp used for event emission, logging, or informational display is not flagged.
Limitations
False positives:
block.timestampis perfectly acceptable for cooldown periods longer than 30 seconds, staking reward periods, and protocol-level timeouts. These may still be flagged at lower confidence.- Timestamps used only for event parameters or off-chain indexing are sometimes caught.
False negatives:
- Indirect timestamp usage (stored in storage, then read later in a different function) may be missed without cross-function analysis.
Related Detectors
- Weak Randomness — detects timestamp used as a randomness source
- Front-Running — timing-dependent ordering sensitivity