Losing time

There might be a new kind of MEV emerging that will incentivize Ethereum miners and validators to mess with the block timestamp. As far as I can tell, this could cause the on-chain recorded time to fall further and further behind real time.

Background

Timekeeping is a tough problem in distributed systems, one that's deeply related to the problem of achieving consensus. One way of looking at blockchains is that they are simply sophisticated timekeepers. Satoshi's big invention was a fully decentralized way to agree, for any two transactions, which one comes first. Every other ingredient for Bitcoin--public key signatures, Merkle trees, gossip protocols, proof-of-work--had already existed for over a decade beforehand.

Bitcoin and Ethereum don't rely on wall clock time for the core problem of transaction ordering. They do, however, include a timestamp in each block. Both share a simple timestamp validity rule. For each new block:

  • The timestamp must be greater than the timestamp of the previous block
  • The timestamp can't be in the future.

That second condition is subjective. You could create a block which one node accepts and another rejects, because its clock is a little behind. So far this has not been a problem: a block proposer cannot put the timestamp far in the future, or the rest of the network won't accept it and it'll be as if they'd proposed a block at all. If they put a timestamp, say, one second in the future, then the rest of the network accepts it in waves over the coming second or two --just a slightly delayed version of normal block gossip. They can't set the timestamp far in the past, due to the greater-than-previous-block rule. Historically, there's been no reason for them deviate from the default client behavior of just using the system time. This results in chains with mostly accurate block timestamps.



Ethereum contracts reading the wall time

Historically, nothing important on chain depends on the block timestamp. Scheduled events, like hard forks, soft forks or NFT drops, lockup periods for exiting a rollup, etc etc are all done in terms of block height. Block height is the total number of blocks since genesis, and can be used to time future events approximately. For example, the next Eth fork is scheduled for block #13773000, expected on Dec 9 around 12pm Pacific. Block height is impossible to game, short of directly attacking the chain via a fork. A block proposer (= a miner today, validator soon, maybe a specialized proposer role after PBS) has no control over block height. Any valid block is simply #(previous block height + 1).

An ethereum contract can read the block height. Ethereum also allows a contract transaction to read the timestamp of the current block. (It's impossible to allow a transaction to read the hash of the current block. The reason why is left as an exercise. 😇)


What's new

Some contracts are using the current block timestamp as a randomness mechanism. That's because it's the only piece information that a transaction can read that's typically unknown to the sender of the transaction. Check out this very interesting Snake game implemented entirely on chain.


ArcadeGlyphs NFT contract

Underlying snake game contract

Specifically, check out the insertCoin function in the Snake contract. It records the previous block hash, the current block timestamp, and current block height. These serve as the random seed for each game.

Only 2000 Snake NFTs can be minted. The top-three scoring games get special additional 1-of-1 prize NFTs. If I'm a block proposer, I can bend the rules in my favor by picking just the right block timestamp.

You can see where I'm going with this...


Flashbots for timestamps

The Ethereum ecosystem has developed out-of-band block space auctions. The most important one is the Flashbots protocol. There are others, and the details are fascinating, but that's for another post. The bottom line: it's already standard practice for some people to pay block proposers to do things their way. Today, they mostly say "here's are some private transactions--don't let anyone see them, but include them at the very front of the next block you mine". 

If any application using block timestamps for randomness gains enough value, the same mechanism will be extended to bid for a particular block time. What would this mean for the network?

Timestamps are Unix time in seconds, so initially bidders would have just a few possible values to choose from--anything between previous block time and current UTC time, which on Ethereum is usually anywhere from 0 to 30 seconds later.

MEV searchers would bid for times as part of a flashbots bundle that includes a transaction taking advantage of that particular, favorable timestamp. Their bots would iterate over the range of allowable timestamps, simulating the contract "randomness" at each to find the one most favorable to them.

Since this is being used as a random seed, the "best" timestamp will be uniformly distributed in the range of allowed times. On average, the auction-winning timestamp will be halfway between the previous block time and the current time.

How much will blocks end up delayed? I ran a simulation to find out.


Looks like with every block proposer auctioning off the block timestamp, we end up on average 14 seconds = exactly one block interval delayed. On closer thought, this makes sense! We can see that this is a stable arrangement:

Call the mean time between blocks t = 14 seconds. The last block was t seconds ago, so its timestamp is 2t seconds ago. A new block arrives. The auction-winning time is randomly distributed in the range [now - 2t, now], which is on average again t seconds ago.

Tldr; once we have timestamp auction, newly found block timestamps go from (present time) to (roughly the time of the previous block). Specifically, they become: present time minus a randomly distributed 0 to ~2x the block time, with outliers. This is assuming contracts are using the current timestamp as a random seed, like that Snake game. If an app ever manages to expose significant value for earlier timestamps, then the block times could fall arbitrarily far behind real time. 


What can we do about it?

One way of nipping this in the bud would be to redefine the EVM TIMESTAMP opcode (and by extension block.timestamp in Solidity) to refer to the previous block timestamp. This would have to be done in a future hard fork.

This would restore the original economics, where there was no reason for a proposer to pick a fake timestamp.

The Snake game would still be gameable. Eventually, a lucky block comes around where the next call to mint() will return a winning snake game. But it will be deterministic. Players simply bid for who gets to be the next one to call mint() first. That's regular old MEV, the kind we already have lots of.


Update

It looks like there's already a Github issue in Flashbots for adding timestamp auctions: https://github.com/flashbots/mev-geth/issues/4

Light on details, so I'm not sure if we're talking about the same thing. I'm also not sure if anything came of it, or if any miner is already using timestamps to capture MEV today. If anyone knows more I'd love to hear it.