EVM Gas Oracle

Overview

The **EVM Gas Oracle** is a specialized component designed to estimate gas fees for Ethereum and EVM-compatible blockchains (e.g., Avalanche, Polygon, Optimism). Gas fees are critical for users and applications to understand the transaction costs on these networks and to set appropriate fees for timely inclusion in blocks.

This module exists to solve the problem of accurately estimating dynamic gas fees by continuously tracking recent block and transaction gas prices on the blockchain. It provides fee recommendations at different percentiles (e.g., slow, average, fast) by analyzing historical data, enabling client applications and APIs to suggest reasonable gas prices to end users.


Core Concept and Purpose

The oracle aggregates transaction gas prices and priority fees from recent blocks, cleans the data, and computes percentile-based fee estimates. This approach balances responsiveness with historical data smoothing.


How the Gas Oracle Works

Initialization

Data Collection

Continuous Update

Fee Estimation


Interaction with Other System Components


Important Concepts and Design Patterns

Chain-Specific Behavior Encapsulation

This approach isolates chain peculiarities in one place, making the oracle adaptable to multiple EVM chains.

Data Structures and Algorithms

Resilience and Retry Logic

Event-Driven Updates


Code References and Examples

Oracle Initialization and Chain Configuration

constructor(args: GasOracleArgs) {
  // ...
  switch (args.coinstack) {
    case 'avalanche':
      this.baseFeeBuffer = false
      this.latestBlockTag = 'latest'
      this.canQueryPendingBlockByHeight = true
      break
    case 'optimism':
      this.baseFeeBuffer = true
      this.latestBlockTag = 'latest'
      this.canQueryPendingBlockByHeight = true
      break
    // ... other chains
    default:
      throw new Error(`no coinstack support for: ${args.coinstack}`)
  }
}

Fee Estimation Method

The `estimateFees` method calculates fee estimates at requested percentiles:

async estimateFees(percentiles: Array<number>, blockCount = 20): Promise<EstimatedFees> {
  await this.sync()

  const blockFees = Array.from(this.feesByBlock.entries())
    .sort(([blockA], [blockB]) => Number(blockB) - Number(blockA))
    .slice(0, blockCount)
    .map(([, fees]) => fees)

  const estimatedFees = percentiles.reduce<EstimatedFees>((estimatedFees, percentile) => {
    const { gasPrice, maxPriorityFee } = this.averageAtPercentile(blockFees, percentile)
    estimatedFees[percentile.toString()] = {
      gasPrice: gasPrice.toFixed(0),
      ...(this.baseFeePerGas && {
        maxFeePerGas: (maxPriorityFee + Number(this.baseFeePerGas) * (this.baseFeeBuffer ? 2 : 1)).toFixed(0),
        maxPriorityFeePerGas: maxPriorityFee.toFixed(0),
      }),
    }
    return estimatedFees
  }, {})

  return estimatedFees
}

Integration in EVM Service

The service class uses the gas oracle to provide fee info:

async getGasFees(): Promise<GasFees> {
  const baseFeePerGas = this.gasOracle.getBaseFeePerGas()
  const estimatedFees = await this.gasOracle.estimateFees([1, 60, 90])

  return {
    baseFeePerGas,
    slow: estimatedFees['1'],
    average: estimatedFees['60'],
    fast: estimatedFees['90'],
  }
}

Visual Diagram: Flow of Gas Fee Estimation

sequenceDiagram
  participant Client
  participant APIService
  participant GasOracle
  participant BlockchainRPC

  Note over GasOracle: Initialization (fetch recent blocks)

  Client->>APIService: Request gas fee estimates
  APIService->>GasOracle: estimateFees([1,60,90])
  GasOracle->>GasOracle: sync internal state (fetch missing blocks)
  GasOracle->>BlockchainRPC: getBlock(blockNumber or tag)
  BlockchainRPC-->>GasOracle: Block data with tx fees
  GasOracle->>GasOracle: update internal fee data
  GasOracle-->>APIService: Estimated fees at requested percentiles
  APIService-->>Client: Return gas fee estimates

Summary

The **EVM Gas Oracle** is a vital module that continuously monitors recent blocks on Ethereum and compatible chains to generate accurate gas fee estimates. It addresses the challenges of dynamic gas pricing by applying statistical analysis to recent transaction fees, supporting multiple chains with chain-specific configurations. The oracle integrates tightly with the API service, enabling responsive and reliable fee estimation for transaction submission workflows.