Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
Try it Live
Run FeeMarket examples in the interactive playground
EIP-1559 Base Fee Calculations
Dynamic base fee mechanism adjusting based on block gas utilization.
Overview
EIP-1559 introduced a dynamic base fee that:
- Targets 50% full blocks (gasLimit / 2)
- Increases up to 12.5% per block when above target
- Decreases up to 12.5% per block when below target
- Enforces minimum of 7 wei
BaseFee
BaseFee(
parentGasUsed: bigint,
parentGasLimit: bigint,
parentBaseFee: bigint
): BaseFee
Construct next block’s base fee using EIP-1559 formula.
Parameters:
parentGasUsed - Gas used in parent block
parentGasLimit - Gas limit of parent block
parentBaseFee - Base fee of parent block (wei)
Returns: Next block’s base fee (wei)
Formula:
gasTarget = gasLimit / ELASTICITY_MULTIPLIER (= gasLimit / 2)
if gasUsed > gasTarget:
increase = (baseFee * (gasUsed - gasTarget)) / gasTarget / 8
newBaseFee = baseFee + max(increase, 1)
if gasUsed < gasTarget:
decrease = (baseFee * (gasTarget - gasUsed)) / gasTarget / 8
newBaseFee = max(baseFee - max(decrease, 1), MIN_BASE_FEE)
if gasUsed == gasTarget:
newBaseFee = baseFee
Always: newBaseFee >= MIN_BASE_FEE (7 wei)
Examples:
import * as FeeMarket from './FeeMarket.js';
// At target (50% full): unchanged
const baseFee1 = FeeMarket.BaseFee(
15_000_000n, // 50% of 30M
30_000_000n,
1_000_000_000n // 1 gwei
);
// baseFee1 === 1_000_000_000n
// Full block: maximum increase (12.5%)
const baseFee2 = FeeMarket.BaseFee(
30_000_000n, // 100% full
30_000_000n,
1_000_000_000n
);
// baseFee2 === 1_125_000_000n (12.5% increase)
// Empty block: decrease
const baseFee3 = FeeMarket.BaseFee(
0n, // Empty
30_000_000n,
1_000_000_000n
);
// baseFee3 === 1_000_000_000n (stays same for empty blocks)
// Below target: decrease
const baseFee4 = FeeMarket.BaseFee(
7_500_000n, // 25% full (half of target)
30_000_000n,
1_000_000_000n
);
// baseFee4 < 1_000_000_000n (decreased)
Edge Cases:
// Minimum base fee enforced
const minFee = FeeMarket.BaseFee(0n, 30_000_000n, 10n);
// minFee >= 7n (MIN_BASE_FEE)
// Very high base fee
const highFee = FeeMarket.BaseFee(
30_000_000n,
30_000_000n,
100_000_000_000n // 100 gwei
);
// highFee === 112_500_000_000n (still 12.5% increase)
getGasTarget
getGasTarget(state: State): bigint
Get target gas usage for a block (50% of gas limit).
Parameters:
state - Block state with gasLimit
Returns: Target gas (gasLimit / 2)
Example:
const state: FeeMarket.State = {
gasUsed: 20_000_000n,
gasLimit: 30_000_000n,
baseFee: 1_000_000_000n,
excessBlobGas: 0n,
blobGasUsed: 0n
};
const target = FeeMarket.getGasTarget(state);
// target === 15_000_000n (30M / 2)
State method:
const target = FeeMarket.State.getGasTarget.call(state);
// Same result
isAboveGasTarget
isAboveGasTarget(state: State): boolean
Check if block gas usage is above target (will increase base fee).
Parameters:
Returns: true if gasUsed > gasTarget
Example:
const state: FeeMarket.State = {
gasUsed: 20_000_000n, // Above target
gasLimit: 30_000_000n, // Target is 15M
baseFee: 1_000_000_000n,
excessBlobGas: 0n,
blobGasUsed: 0n
};
const isAbove = FeeMarket.isAboveGasTarget(state);
// isAbove === true (20M > 15M target)
// Base fee will increase in next block
const nextState = FeeMarket.nextState(state);
// nextState.baseFee > state.baseFee
State method:
const isAbove = FeeMarket.State.isAboveGasTarget.call(state);
// Same result
Constants
See constants.mdx#eip1559:
FeeMarket.Eip1559.MIN_BASE_FEE // 7n wei
FeeMarket.Eip1559.BASE_FEE_CHANGE_DENOMINATOR // 8n (12.5% = 1/8)
FeeMarket.Eip1559.ELASTICITY_MULTIPLIER // 2n (target = limit/2)
Base Fee Dynamics
Increase Rate
Block above target by X% → base fee increases by up to X/2 * 12.5%
// 100% full (100% above target = 50% above target of 50%)
const fee100 = FeeMarket.BaseFee(30_000_000n, 30_000_000n, 1_000_000_000n);
// Increases by 12.5% (maximum)
// 75% full (50% above target)
const fee75 = FeeMarket.BaseFee(22_500_000n, 30_000_000n, 1_000_000_000n);
// Increases by ~6.25%
// 62.5% full (25% above target)
const fee625 = FeeMarket.BaseFee(18_750_000n, 30_000_000n, 1_000_000_000n);
// Increases by ~3.125%
Decrease Rate
Block below target by X% → base fee decreases by up to X/2 * 12.5%
// 0% full (maximum below target)
const fee0 = FeeMarket.BaseFee(0n, 30_000_000n, 1_000_000_000n);
// Stays same for empty blocks
// 25% full (50% below target)
const fee25 = FeeMarket.BaseFee(7_500_000n, 30_000_000n, 1_000_000_000n);
// Decreases by ~6.25%
// 37.5% full (25% below target)
const fee375 = FeeMarket.BaseFee(11_250_000n, 30_000_000n, 1_000_000_000n);
// Decreases by ~3.125%
Equilibrium
Constant 50% utilization maintains stable base fee:
let baseFee = 1_000_000_000n;
const gasLimit = 30_000_000n;
const gasUsed = 15_000_000n; // Exactly at target
for (let i = 0; i < 100; i++) {
baseFee = FeeMarket.BaseFee(gasUsed, gasLimit, baseFee);
}
// baseFee === 1_000_000_000n (unchanged)
Projecting Base Fees
See BaseFee projections:
// Project 10 blocks with high utilization
const state: FeeMarket.State = {
gasUsed: 0n,
gasLimit: 30_000_000n,
baseFee: 1_000_000_000n, // 1 gwei
excessBlobGas: 0n,
blobGasUsed: 0n
};
const fees = FeeMarket.projectBaseFees(
state,
10, // blocks
25_000_000n, // 83% full (above target)
0n // no blobs
);
// fees[0] > 1 gwei (increasing)
// fees[9] >> 1 gwei (compounded increase)
Usage Patterns
Fee Estimation
// Get current state
const state = getCurrentBlockState();
// Calculate next block's base fee
const nextState = FeeMarket.nextState(state);
console.log(`Next base fee: ${FeeMarket.weiToGwei(nextState.baseFee)} gwei`);
// Check if fees are rising
if (FeeMarket.State.isAboveGasTarget.call(state)) {
console.log('⬆ Fees rising - blocks above target');
} else {
console.log('⬇ Fees falling - blocks below target');
}
Gas Target Monitoring
const state: FeeMarket.State = { /* ... */ };
const target = FeeMarket.getGasTarget(state);
const utilization = Number(state.gasUsed * 100n / state.gasLimit);
const targetPct = Number(state.gasUsed * 100n / target);
console.log(`Gas: ${utilization.toFixed(1)}% of limit`);
console.log(`Target: ${targetPct.toFixed(1)}% of target (50%)`);
if (state.gasUsed > target) {
const abovePct = Number((state.gasUsed - target) * 100n / target);
console.log(`${abovePct.toFixed(1)}% above target → base fee rising`);
}
Implementation
Location: /src/primitives/FeeMarket/BrandedFeeMarket/BaseFee.js
See branded-feemarket.mdx for implementation details.
References