flashbots / mev-geth

Go implementation of MEV-Auction for Ethereum
GNU Lesser General Public License v3.0
784 stars 197 forks source link

Feature to manipulate BLOCKHASH #117

Open fulldecent opened 2 years ago

fulldecent commented 2 years ago

Rationale

MEV exists for manipulating BLOCKHASH.

Why should this feature exist?

Because it is MEV.

What are the use-cases?

Gaming. Random drops.

Discussion

I do understand that controlling the BLOCKHASH for just one bit equals the electricity cost of mining one block.

So the fee offered for this control must exceed that. Also, these fees can be combined—if multiple people want a BLOCKHASH that is an even number, they can both pay the fee.

Going forward with proof of stake, the cost of mining goes to zero. So I think this pricing will become a lot more accessible.

The most important thing at this time is to discuss now if this might be implemented.

Implementation

Do you have ideas regarding the implementation of this feature?

Here are reusable components used in discussions below

The BlockhashDesirability smart contract interface is defined as follows:

interface BlockhashDesirability {
    function isDesirable(bytes32 txHash, bytes32 blockhash) pure returns (bool);
}

Then we publish a singleton public utility contract, FLASHBOTS_BLOCKHASH_BOUNTY implementing:

interface FlashbatsBlockhashBounty {
    function fundBounty(bytes32 txHash, uint256 expirationTime, BlockhashDesirability checker) payable; // emits event Bounty(uint256 id);
    function bountyDetails(uint256 bountyID) returns (...);
    function takeBountyForNotPublishingUndesiribleBlock(uint256 bountyID, bytes32 blockhash, address coinbase, bytes inclusionProof) payable;
    function takeBountyForPublishingDesiribleBlock(uint256 bountyID, uint256 blockNumber, address coinbase, bytes inclusionProof);
    ...
}

Flashbots under proof of work

A searcher wants to influence the BLOCKHASH. In this example they are sending Ether to a commit-reveal coin flip that has a desirable result If the BLOCKHASH that tx is included in has zero in the last bit:

  1. The searcher prepares a transaction TX_HEADS which starts the commit-reveal.
  2. The searcher deploys a smart contract implementing a function that returns true if the blockhash has a zero in the last bit.
  3. The searcher funds a bounty with FlashbatsBlockhashBounty and gets the bounty ID.
  4. The searcher sends the TX_HEADS transaction and the bounty ID to the miner.
  5. The miner is lucky and finds a good nonce. This is the "candidate block".
  6. The miner checks (by evaluating a transaction AFTER the candidate block) if this is desirable:
    1. If desirable, the miner mines the block and then later (using normal public mempool) claims their inclusion bounty with takeBountyForPublishingDesiribleBlock.
    2. If undesirable, the miner does NOT mine the block. Afterwards it proves that it had and burned a valid block and claims the bounty with takeBountyForPublishingDesiribleBlock. This bounty is very large.

Under proof of stake

  1. The searcher prepares a transaction TX_HEADS which starts the commit-reveal.
  2. The searcher deploys a smart contract implementing a function that returns true if the blockhash has a zero in the last bit.
  3. The searcher funds a bounty with FlashbatsBlockhashBounty and gets the bounty ID.
  4. The searcher sends the TX_HEADS transaction and the bounty ID to the miner.
  5. The miner is lucky and finds a good nonce. This is the "candidate block".
  6. The miner checks (by evaluating a transaction AFTER the candidate block) if this is desirable:
    1. If desirable, the miner mines the block and then later (using normal public mempool) claims their inclusion bounty with takeBountyForPublishingDesiribleBlock. This bounty is large.
    2. If undesirable, the miner just tries again, there is no cost here and the miner could probably try a bunch of times without much effort.
    3. If undesirable AND the miner is bored of trying it does NOT mine the block. Afterwards it proves that it had and burned a valid block and claims the bounty with takeBountyForPublishingDesiribleBlock. This bounty is small.

Are you willing to implement this feature?

Maybe

ytrezq commented 7 months ago

I propose an other alternative. How about conditionally include a transaction based on a programmable condition about blockhash? This would allow to use the existing sandwich infrastructure.

Or maybe it already exists.