Skip to content

Instantly share code, notes, and snippets.

@GalloDaSballo
Last active November 4, 2023 21:28
Show Gist options
  • Save GalloDaSballo/0a33a8b07e681d49c8228b6f8e9c9bd2 to your computer and use it in GitHub Desktop.
Save GalloDaSballo/0a33a8b07e681d49c8228b6f8e9c9bd2 to your computer and use it in GitHub Desktop.

Cost of DOS for 10 minutes

Note: this may be wrong, but hopefully it's a start

Output

blocks_dossed 51
fee 406236221416.0 ## 406 GWEI
total_paid 1.0941377978739001e+20 ## 100 ETH

Script

"""

		# check if the base fee is correct
		if INITIAL_FORK_BLOCK_NUMBER == block.number:
			expected_base_fee_per_gas = INITIAL_BASE_FEE
		elif parent_gas_used == parent_gas_target:
			expected_base_fee_per_gas = parent_base_fee_per_gas
		elif parent_gas_used > parent_gas_target:
			gas_used_delta = parent_gas_used - parent_gas_target
			base_fee_per_gas_delta = max(parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1)
			expected_base_fee_per_gas = parent_base_fee_per_gas + base_fee_per_gas_delta
		else:
"""


INITIAL_BASE_FEE = 1000000000 ## 1 gwei
ELASTICITY_MULTIPLIER = 2
BASE_FEE_MAX_CHANGE_DENOMINATOR = 8

GAS_TARGET  = 15e6
GAS_USED = 30e6
GAS_LIMIT = 30e6

MINUTES_TO_DOS = 10
SECONDS_PER_BLOCK = 12
BLOCKS_TO_DOS = MINUTES_TO_DOS  * 60 / SECONDS_PER_BLOCK

def main():
    blocks_dossed = 0
    fee = INITIAL_BASE_FEE
    total_paid = 0
    while (blocks_dossed <= BLOCKS_TO_DOS):
      gas_used_delta = GAS_USED - GAS_TARGET
      base_fee_per_gas_delta = max(fee * gas_used_delta // GAS_TARGET // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1)
      expected_base_fee_per_gas = fee + base_fee_per_gas_delta
      fee = expected_base_fee_per_gas
      total_paid += fee * GAS_USED
      blocks_dossed += 1
    
    print("blocks_dossed", blocks_dossed)
    print("fee", fee)
    print("total_paid", total_paid)



main()
@0xmonrel
Copy link

0xmonrel commented Nov 4, 2023

Okay, I see where my confusion comes from. Your script was linked in the context of a DOS of a transaction from a specific account and not a network wide DOS. As in we can include all other transactions other than a specific transaction from a certain address.

A censorship attack can work exactly because it can include all but one transaction and as a result not drive up the gas fees tremendously. I should have paid more attention to the differences between a network DOS and censorship/single tx DOS before commenting here, sorry about that!

Here is a script calculating the cost of a censorship attack when MEV-boosted blocks have 55% gas utilization:

Output

Minutes: 15
blocks_dossed: 76
fee: 182.0 GWEI
total_boost_payment: 64.0
total_paid: 197.0
Total in dollar at 1800 $/ETH: 354803.0

Script

import random

INITIAL_BASE_FEE = 18000000000 ## 18 gwei
ELASTICITY_MULTIPLIER = 2
BASE_FEE_MAX_CHANGE_DENOMINATOR = 8

GAS_TARGET  = 15e6
GAS_LIMIT = 30e6

PRIORTY_FEE = 2 # 2 - Sets priority fee at 100% of base fee 
MEV_BOOST_PAYMENT = 1e18 # 1 ETH in MEV-boost payment for each block (this is ~20x the 6month average) 

MINUTES_TO_DOS = 15
SECONDS_PER_BLOCK = 12
BLOCKS_TO_DOS = MINUTES_TO_DOS  * 60 / SECONDS_PER_BLOCK

def main():
    blocks_dossed = 0
    fee = INITIAL_BASE_FEE
    total_paid = 0
    total_boost_payment = 0
    parent_gas_used = 30e6
    while (blocks_dossed <= BLOCKS_TO_DOS):
      mevBoost = True if random.randint(1,10) <9 else False  # ~93% of validators use MEV-boost

      if not mevBoost:
         gas_used_delta = parent_gas_used - GAS_TARGET
         base_fee_per_gas_delta = max(fee * gas_used_delta // GAS_TARGET // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1)
         expected_base_fee_per_gas = fee + base_fee_per_gas_delta
         fee = expected_base_fee_per_gas
         total_paid += fee*PRIORTY_FEE*30e6 
         blocks_dossed += 1
         parent_gas_used = 30e6
         
      else: #If it is a MEV-boosted block, we buy the block and consume only 10e6

         gas_used_delta = parent_gas_used - GAS_TARGET
         base_fee_per_gas_delta = max(fee * gas_used_delta // GAS_TARGET // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1)
         expected_base_fee_per_gas = fee + base_fee_per_gas_delta
         fee = expected_base_fee_per_gas
         total_paid += fee * 15e6  + MEV_BOOST_PAYMENT
         total_boost_payment += MEV_BOOST_PAYMENT 
         blocks_dossed += 1
         parent_gas_used = 15e6

   
    print("Minutes:", MINUTES_TO_DOS)
    
    print("blocks_dossed:", blocks_dossed)
    print("fee:", str(fee//1e9) + " GWEI")

    print("total_boost_payment:", total_boost_payment//1e18)
    print("total_paid:", total_paid//1e18)
    print("Total in dollar at 1800 $/ETH:", 1800 * total_paid//1e18)


main()



Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment