Skip to main content
Sigvex

Outdated Compiler

Detects contracts compiled with Solidity versions affected by published compiler advisories, using bytecode metadata for version evidence.

Outdated Compiler

Overview

Remediation Guide: Outdated Compiler Remediation

The outdated compiler detector checks the Solidity version a contract was built with against a registry of published compiler advisories — miscompilation bugs and missing safety features tied to specific version ranges. It reads the version from the CBOR-encoded metadata that solc appends to deployed bytecode, then emits one finding per advisory whose version range matches.

Advisories fall into two classes, and the detector treats them differently:

  • Trigger-gated advisories depend on build settings (optimizer enabled, viaIR, specific Yul passes). When the trigger can be proven from the contract, the finding fires at the advisory’s full severity and confidence. When compiler settings are unknown — typical for unverified on-chain contracts — the finding still fires, at reduced confidence.
  • Version-only advisories have no per-contract structural evidence, so they are capped at low severity and reduced confidence: an upgrade signal, not a proven bug.

If no advisory matches but the compiler is simply old (for example, pre-0.8.0 without default overflow checks), a single informational stale-version finding is emitted instead.

Why This Is an Issue

Compiler bugs produce wrong bytecode from correct source. Notable examples covered by the advisory registry include the 0.8.13–0.8.16 Yul unused-store eliminator dropping storage writes, the pre-0.8.3 keccak256 optimizer caching bug, and the 2023-07 selector-side-effects advisory. Separately, anything below 0.8.0 lacks default overflow/underflow checks, so unguarded arithmetic wraps silently.

How to Resolve

Recompile with a current, unaffected compiler release and pin it exactly.

// Before: old version with known miscompilation windows
pragma solidity 0.8.13;

// After: pinned, current release outside all advisory ranges
pragma solidity 0.8.30;

If an upgrade is not immediately possible, check whether your build settings hit an advisory’s trigger (optimizer, viaIR) and disable the triggering configuration until you can move.

Examples

Sample Sigvex Output

{
  "detector_id": "outdated-compiler",
  "severity": "high",
  "confidence": 0.9,
  "description": "Contract compiled with Solidity 0.8.14, inside the 0.8.13-0.8.16 range affected by the Yul unused-store eliminator advisory. Storage writes before conditional terminators may have been removed.",
  "location": { "function": "contract-level", "offset": 0 }
}

Detection Methodology

  1. Version extraction: Decodes the CBOR metadata section at the end of the runtime bytecode to recover the exact solc version. Reliable metadata yields a high confidence base; heuristic recovery yields a lower one. Bytecode with no recoverable version produces a single unknown-version finding.
  2. Advisory matching: Walks the advisory registry and selects every advisory whose affected version range contains the extracted version.
  3. Trigger evaluation: For trigger-gated advisories, checks available build evidence (for example, whether the bytecode uses transient storage opcodes for the 2026-02 transient-helper advisory). Proven triggers keep full confidence; unknown settings scale confidence down.
  4. Severity assignment: Per-finding severity comes from the matched advisory, not from the detector default — so a single scan can produce findings from low to high.

Limitations

  • Contracts deployed without metadata (stripped or nonstandard toolchains) cannot be version-matched and receive only the unknown-version finding.
  • Version-only advisories cannot confirm the bug is actually present in this contract; treat them as an upgrade prompt, not a confirmed vulnerability.
  • Vyper and other non-solc toolchains are out of scope.

References