SIP-2020: Dynamic Gas Fee Module - Bedrock


Simple Summary

The sip proposes to update the dynamic gas fee module, in order to cater for the post bedrock paradigm in gas price computation. The module is able to adjust the minKeeperFee, within bounds set by governance. Note that the updateMinKeeperFee function is a publicly callable function that doesn't require any endorsed address for execution.

The updated calculation is similar to what is used currently, except that the L2 gas price is a function of l2BaseFee and an l2PriorityFee.


The dynamic gas fee module is a standard Gnosis Safe Module that is able to alter the minKeeperFee in our PerpsV2MarketSettings within bounds specified in the contract and configurable via governance:

  • The calculation steps of the minKeeperFee is as follows:
  1. costOfExecutionGross := (L2BaseFee + L2PriorityFee) * l2GasUnits + L1BaseFee * (l1GasUnits+l1FeeOverhead) * l1FeeScalar * ETH/USD
  2. profitMargin := max(profitMarginUSD; costOfExecution * profitMarginPercent )
  3. costOfExecutionNet := costOfExecutionGross + profitMargin
  4. minKeeperFee := min( max(costOfExecutionNet, minKeeperFeeLowerBound) ; minKeeperFeeUpperBound)
  • The ETH/USD price is obtained with the on-chain chainlink ETH oracle
  • The profit margin is incorporated in order to absorb shocks to gas prices on the one hand and to incentivize a decentralised keeper network
  • The lower and upper bounds on the minKeeperFee are incoporated for safety purposes
  • The number of gas units required on L1 and L2, as well as the L2 priority fee, are all configurableble via SCCP
  • l1FeeOverhead, l1BaseFee, and l1FeeScalar can be all queried on-chain with the help of the L1Block contract under 0x4200000000000000000000000000000000000015
  • l2BaseFee can be queried on chain with block.basefee


The main motivation is to continue to support the network of decentralized keepers that have contributed to minimizing the number of cancellations since SIP-2013 was implemented.

It is worth nothing that although the L2 priority fee could vary depending on network congestion, if the fee follows the pre-bedrock gas paradigm, the L1 security fee would still constitute the vast majority of the overall gas fee. In addition, the profitMarginUSD parameter (currently set to 2 sUSD), can be calibrated as to absorb shocks into priority fee and allow for executions to continue to take place on chain.

The post-bedrock gas price paradigm would be monitored and in case situation is seen where staleness is caused by l2PriorityFee being too low, then a new SIP would be proposed where the l2PriorityFee could be queried on-chain with the help of a chainlink oracle.



This is a getter public function that returns computed gas price given on-chain variables


This is a publically callable function that updates the minKeeperFee in PerpsV2MarketSettings


This is a getter public function that returns the current configurations specified under the Configurable Values section.


This can only be called by the owner, whereby the variables specified under the Configurable Values section, can be updated.


This is a getter public function that returns the state of the module.


This can only be called by the owner, allowing to pause the module and disabling it's ability to update the minKeeperFee.

Rejected by the author.

Test Cases

Gas Price Module Configurations:

  • profitMarginPercent: 20%
  • profitmarginUSD: 2 sUSD
  • minKeeperFeeUpperBound: 15 sUSD
  • minKeeperFeeLowerBound: 2 sUSD
  • l1GasUnits : 20,000 GAS
  • l2GasUnits : 1 million GAS
  • l2PriorityFee: 0.001 GWEI/GAS (note that this value would be updated by the owner post bedrock to reflect the state of the network as it very early to tell to what level it would converge to)

On-chain Gas Price Values:

  • l1BaseFee : 100 GWEI/GAS (found as basefee under L1Block, in wei)
  • l2BaseFee : 0.00000005 GWEI/GAS (found on chain by calling block.basefee as shown under this contract in wei )
  • l1FeeScalar: 1 (found as l1FeeScalar under L1Block, after incorporating 1e6 decimal adjustment)
  • l1FeeOverhead: 2,100 GAS, (found as l1FeeOverhead under L1Block )
  • ETH/USD: 1,869$, obtained from the chainlink oracle

minKeeperFee Computations:

  • costOfExecutionGrossGwei = (0.001 + 0.00000005) * 1e6 + (20,000 + 2,100) * 100 * 1 = 2,211,000 GWEI
  • costOfExecutionGrossETH = 2,211,200 / 1e9 = 0.002211 ETH
  • costOfExecutionGrossUSD = 0.0026692 ETH * 1,869 USD / ETH = 4.132359 sUSD
  • profitMargin = max(2 ; 20% * 4.132359) = 2 sUSD
  • costOfExecutionNet = 2+4.132359 = 6.132359 sUSD
  • minKeeperFee = max(min(6.132359;15) ; 2) = 6.132359 sUSD

Configurable Values (Via SCCP)

  • minKeeperFeeLowerBound being the lower bound on the minKeeperFee that can be updated
  • minKeeperFeeUpperBound being the upper bound on the minKeeperFee that can be updated
  • l1GasUnits and l2GasUnits being the number of gas units required to execute a pending offchain delayed order
  • l2PriorityFee being the priority fee paid on L2
  • profitMarginUSD being a profit margin in sUSD, applied on the cost of execution
  • profitMarginPercent being a keeper profit margin in percentage, applied on the cost of execution


Copyright and related rights waived via CC0.