133 Languages

Documentation

Whitepaper

Abstract

Awesome ETH Linter is an LLM-powered security tool that automatically detects specification drift between Ethereum protocol specifications and client implementations. By leveraging large language models to perform semantic comparison of spec definitions against production code, it identifies logic divergences, missing validations, and constant mismatches that could lead to consensus failures or security vulnerabilities.

Problem Statement

Ethereum clients must faithfully implement the consensus and execution specifications. Manual code review is time-consuming and error-prone, especially as specs evolve across hard forks (Phase0 → Altair → Bellatrix → Capella → Deneb → Electra). A single implementation bug can cause chain splits, fund losses, or network instability.

Solution Architecture

The linter operates in three phases: (1) Parse spec files using Python AST to extract function signatures, constants, and container definitions across fork versions; (2) Analyze client code using Tree-sitter to identify corresponding implementations; (3) Use LLM comparison to semantically verify that client logic matches spec intent, detecting subtle divergences that pattern-matching tools would miss.

Key Capabilities

  • Fork-aware spec parsing with inheritance resolution
  • Automatic spec↔client function mapping with manual overrides
  • LLM-powered semantic comparison (Anthropic Claude / OpenAI)
  • PR-scoped scanning for CI integration
  • SARIF output for GitHub Security tab integration

Installation

# Clone the repository
git clone https://github.com/nichechristie/Awesome-ETH-Linter.git
cd Awesome-ETH-Linter

# Install the package
pip install -e .

# Or with development dependencies
pip install -e ".[dev]"

Configuration

Copy config.example.yml to eth-spec-lint.yml and customize:

spec:
  # Path to ethereum/consensus-specs checkout
  repo_path: ./consensus-specs
  # Forks to analyze (in order)
  forks:
    - phase0
    - altair
    - bellatrix
    - capella
    - deneb
    - electra

client:
  name: lodestar
  repo_path: ./lodestar
  source_globs:
    - "packages/beacon-node/src/**/*.ts"
    - "packages/state-transition/src/**/*.ts"

llm:
  provider: anthropic  # or "openai"
  model: claude-sonnet-4-20250514
  concurrency: 4
  temperature: 0.0

report:
  formats:
    - json
    - markdown
    - sarif
  output_dir: ./reports

Set your API key in the environment:

export ANTHROPIC_API_KEY="your-key-here"
# or
export OPENAI_API_KEY="your-key-here"

CLI Commands

# Full spec-vs-client comparison scan
eth-spec-lint scan

# With custom config file
eth-spec-lint -c my-config.yml scan

# PR-scoped scan (only files changed since base)
eth-spec-lint check-pr --base origin/main

# List matched spec<->client function pairs
eth-spec-lint list-mappings

# Enable verbose logging
eth-spec-lint -v scan

GitHub Action

Add to your workflow at .github/workflows/spec-lint.yml:

name: Spec Lint
on: [pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: nichechristie/Awesome-ETH-Linter@main
        with:
          config: eth-spec-lint.yml
          mode: pr
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

Finding Categories

  • LOGIC_DIVERGENCE (error) — Implementation doesn't match spec logic.
  • MISSING_CHECK (error) — Validation present in spec but absent in client.
  • CONSTANT_MISMATCH (error) — Constant value differs between spec and implementation.
  • TYPE_MISMATCH (warning) — Type or structure differs meaningfully.
  • OFF_BY_ONE (error) — Off-by-one error in bounds or indexing.
  • OPTIMIZATION_SAFE (note) — Different implementation but provably equivalent behavior.

Development

# Clone and install dev dependencies
git clone https://github.com/nichechristie/Awesome-ETH-Linter.git
cd Awesome-ETH-Linter
pip install -e ".[dev]"

# Run tests
pytest

# Run a scan with example config
cp config.example.yml eth-spec-lint.yml
eth-spec-lint scan