Flashbots Cheatsheet

Notes on the current state of flashbots docs with relevance to assumptions of bundle process.

const blockNumber = await provider.getBlockNumber()
const minTimestamp = (await provider.getBlock(blockNumber)).timestamp
const maxTimestamp = minTimestamp + 120
const signedBundle = flashbotsProvider.signBundle(
signedTransaction: SIGNED_ORACLE_UPDATE_FROM_PENDING_POOL // serialized signed transaction hex
signer: wallet, // ethers signer
transaction: transaction // ethers populated transaction object
const bundleReceipt = await flashbotsProvider.sendRawBundle(
signedBundle, // bundle we signed above
targetBlockNumber, // block number at which this bundle is valid
minTimestamp, // optional minimum timestamp at which this bundle is valid (inclusive)
maxTimestamp, // optional maximum timestamp at which this bundle is valid (inclusive)
revertingTxHashes: [tx1, tx2] // optional list of transaction hashes allowed to revert. Without specifying here, any revert invalidates the entire bundle.


To include as last action of smart contract


Edge case to deal with sending to a miner contract

block.coinbase.call{value: _ethAmountToCoinbase}(new bytes(0));

subject to reentrancy attacks


Conflicting bundles received by flashbots are ordered by the following formula:

\bg_white \Large score=\fracminerBribe + totalGasUsed * priorityFeePerGas - mempoolGasUsed * priorityFeePerGastotalGasUsed


Bundles must have a target blockNumber and a priorityFeePerGas >= 1 Gwei.


"When constructing a block the node should reject any bundle or megabundle that has a reverting transaction unless its hash is included in the RevertingTxHashes list of the bundle"


  1. Transaction failure (ANY within the bundle)

  2. Incentives (gas price/coinbase transfers) not high enough to offset value of block space

Simulate bundle:

const signedTransactions = await flashbotsProvider.signBundle(transactionBundle);
const simulation = await flashbotsProvider.simulate(signedTransactions, targetBlockNumber, targetBlockNumber + 1);
console.log(JSON.stringify(simulation, null, 2));
  1. Competitors paying more

Get conflicting bundles for a prior block:

const signedTransactions = await flashbotsProvider.signBundle(transactionBundle);
await flashbotsProvider.getConflictingBundle(
13140328, // blockNumber
  1. Bundle received too late to appear in target block

Get submission time data and compare to block time:

await flashbotsProvider.getBundleStats(
  1. A miner for target block not running Flashbots