Block timestamps order events across blocks, but they do not order transactions inside one block.

Use the timestamp for coarse order

A block timestamp is good for saying that one block was included before another. On Ethereum today, the post-Merge slot schedule determines the timestamp carried in the execution payload, so a validator does not get a free-form wall-clock field. Missed slots can make time jump, and a transaction's timestamp is the block's value at execution—not when it was signed or entered the mempool.

That is enough for expiry, cooldowns, and “which batch came later?” It cannot distinguish two events in one block: both inherit the block's timestamp. Timestamps from different chains are not a shared clock either, because their schedules and genesis times differ.

Use position for exact order

Exact order comes from canonical position: block number, transaction index, and log index. An ERC-20 Standard transfer emitted by Frax Share, for example, can be compared with another log in the same block by these fields. If you need state changes that emit no logs, follow the transaction's internal call trace instead.

A Frax Swap and a Curve Finance pool action can therefore share one timestamp while having a definite execution order. Use the timestamp for the block-level question; use position for the event-level question.

In a swap, the deadline check against block.timestamp is evaluated when execution happens.

If the transaction waits in the mempool past its deadline, it can revert even though the signature was created earlier. That is the boundary: timestamps decide whether time-sensitive logic passes; indexes decide what happened first.