# solidity-audit

Use when performing a formal Solidity security review across mixed-protocol codebases, especially when contracts may belong to multiple protocol types and the review must produce a consolidated findings list and module-level audit conclusions.

- **Kind:** skill
- **Source:** https://github.com/zpano/solidity-audit
- **Page:** https://forefy.com/skills/e647a240-ae30-4e1f-afae-36f4d83116f4
- **API (JSON + files):** https://forefy.com/api/skills/e647a240-ae30-4e1f-afae-36f4d83116f4

---

## .gitignore

```

```

## README.md

# Solidity Audit Skill

A Codex skill for formal Solidity security reviews across mixed-protocol
codebases.

This repo is not a standalone scanner. It is a reusable skill package that
orchestrates contract discovery, protocol classification, module
clustering, specialized child-agent audits, and final finding synthesis.

It is built for audits that are too broad, too compositional, or too
cross-domain for a single generic review pass.

## Quick Start

### Install via AI CLI

If your agent supports skill installation from GitHub, use the shortest
path:

```text
Install skill https://github.com/zpano/solidity-audit/
```

To update later:

```text
update the solidity-audit skill to latest version from https://github.com/zpano/solidity-audit/
```

### Manual Install

Clone and symlink into your local skills directory:

```bash
git clone git@github.com:zpano/solidity-audit.git
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$CODEX_HOME/skills"
ln -s /absolute/path/to/solidity-audit \
  "$CODEX_HOME/skills/solidity-audit"
```

Or clone and copy:

```bash
git clone git@github.com:zpano/solidity-audit.git
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$CODEX_HOME/skills"
cp -R /absolute/path/to/solidity-audit \
  "$CODEX_HOME/skills/solidity-audit"
```

Restart Codex after installation so the skill registry reloads.

## How To Use

Use this skill when the target is a non-trivial Solidity codebase and you
want a formal or near-formal security review rather than a quick bug
triage.

Example prompt:

```text
Use the solidity-audit skill to review ./contracts and ./src.
Discover in-scope contracts, classify them by protocol, cluster modules,
audit high-risk paths, and write the final report under assets/findings/.
```

If you name specific files or folders, the skill treats those as the
primary review scope.

## When To Use It

Good fit:

- multi-contract Solidity systems
- codebases mixing DEX, Lending, Staking, Bridge, Governance, Oracle, and
  Vault behavior
- audits that need both a global findings list and per-module conclusions
- reviews where cross-module interactions matter as much as single-contract
  logic

Bad fit:

- single-function bug triage
- linting or style review
- gas-only review
- simple one-contract questions

## What It Does

The orchestrator in [SKILL.md](./SKILL.md)
drives a staged audit flow:

1. Discover in-scope Solidity contracts.
2. Build a conservative contract dependency and interaction graph.
3. Classify each contract into one or more protocol labels.
4. Identify complexity-heavy and liveness-critical paths.
5. Check active-lifecycle mutability and live dependency reads.
6. Cluster the system into coherent modules.
7. Build per-contract audit bundles.
8. Dispatch specialized child agents.
9. Merge results by `root_cause_key`.
10. Render final findings and module conclusions.

The core design choice is narrow, specialized child agents plus a strict
orchestrator, instead of a single broad prompt trying to do everything at
once.

## Supported Labels

The classifier currently routes contracts into:

- `DEX`
- `Lending`
- `Staking`
- `Bridge`
- `Governance`
- `Oracle`
- `Vault`
- `Generic`

Multi-label classification is allowed and expected.

## Architecture

The repository is split into layers so the audit process stays modular,
reusable, and explainable.

### 1. Orchestrator

[SKILL.md](./SKILL.md) defines:

- scope rules
- the staged audit workflow
- bundle composition
- agent routing
- the final output contract

### 2. Workflow Layer

`references/workflow/` contains process rules:

- `classification-rubric.md`
- `module-clustering.md`
- `complexity-feasibility.md`
- `active-draw-mutability.md`
- `judging.md`
- `report-format.md`
- `research-triangulation.md`

This is the layer that tells the skill how to reason consistently, not
just what to read.

### 3. Common Security Layer

`references/common/` contains reusable cross-protocol review lenses:

- access control
- custody and callbacks
- external integrations
- math and accounting
- upgradeability
- generic Solidity checks
- vulnerability taxonomy

### 4. Protocol Layer

`references/protocols/` contains protocol-specific review guides for:

- DEX
- Lending
- Staking
- Bridge
- Governance
- Oracle
- Vault
- Generic

These references also include high-frequency category cross-checks derived
from protocol-specific audit findings.

### 5. Agent Layer

`references/agents/` defines narrow child-agent contracts:

- `classifier-agent`
- `protocol-auditor-agent`
- `generic-auditor-agent`
- `cross-module-agent`
- `complexity-auditor-agent`
- `mutable-dependency-agent`
- `module-summarizer-agent`
- `aggregator-agent`

Each one has a small, specific responsibility. That is deliberate. It
keeps classification, finding generation, summarization, and aggregation
from bleeding into each other.

### 6. Script Layer

`scripts/` contains helper utilities used by the orchestrator:

- `discover-contracts.sh`
- `build-contract-graph.py`
- `build-audit-bundles.py`
- `merge-findings.py`

## Repository Layout

```text
solidity-audit/
|-- SKILL.md
|-- README.md
|-- references/
|   |-- agents/
|   |-- common/
|   |-- protocols/
|   `-- workflow/
|-- scripts/
|   |-- discover-contracts.sh
|   |-- build-contract-graph.py
|   |-- build-audit-bundles.py
|   `-- merge-findings.py
`-- assets/
    `-- findings/
```

## External Knowledge Sources

This skill now absorbs four external sources into local documents instead
of relying on those sources at runtime.

### `pashov/skills`

Source:
[github.com/pashov/skills](https://github.com/pashov/skills)

Absorbed as:

- cleaner public-skill install and update ergonomics in this README
- a more direct “install -> run -> update” user path for public skill repos

### `smart-contract-vulnerabilities`

Source:
[github.com/kadenzipfel/smart-contract-vulnerabilities](https://github.com/kadenzipfel/smart-contract-vulnerabilities)

Absorbed as:

- generic vulnerability classes in
  [vulnerability-taxonomy.md](./references/common/vulnerability-taxonomy.md)
- stronger cross-protocol grounding for access control, reentrancy,
  accounting, DoS, data handling, and unsafe logic classes

### `protocol-vulnerabilities-index`

Source:
[github.com/kadenzipfel/protocol-vulnerabilities-index](https://github.com/kadenzipfel/protocol-vulnerabilities-index)

Absorbed as:

- protocol-specific “high-frequency category cross-check” sections inside
  the local protocol guides
- stronger priority ordering for what must get an explicit pass in Bridge,
  DEX, Lending, Oracle, Staking, Vault, Governance, and Generic reviews

### `evmresearch`

Source:
[evmresearch.io/index](https://evmresearch.io/index)

Absorbed as:

- exploit-mechanic and edge-case routing in
  [research-triangulation.md](./references/workflow/research-triangulation.md)
- more explicit handling for hidden callbacks, stale approvals, router
  calldata abuse, proxy initialization races, compiler footguns, and
  process-layer failures

## Why The Source Absorption Matters

The audit loop now triangulates three knowledge layers:

- protocol identity and high-risk entry points
- generic vulnerability taxonomy
- exploit-mechanic and edge-case research

That matters because protocol-specific heuristics alone miss generic bug
classes, while generic taxonomies alone miss which classes are most common
for a given protocol type.

## Helper Script Usage

These scripts are optional building blocks. The main audit logic still
lives in `SKILL.md`.

### Discover Contracts

```bash
./scripts/discover-contracts.sh contracts src
```

By default this excludes common noise paths such as `lib/`, `test/`,
`tests/`, `mocks/`, `interfaces/`, `script/`, and `broadcast/`.

### Build A Contract Graph

```bash
./scripts/discover-contracts.sh contracts src | \
  python3 scripts/build-contract-graph.py
```

This produces JSON with declared contracts, imports, inheritance, and
basic neighbor relationships.

### Build Audit Bundles

```bash
python3 scripts/build-audit-bundles.py \
  --tasks-json tasks.json \
  --references-root references \
  --output-dir bundles
```

This renders downstream review bundles for child agents.

### Merge Findings

```bash
python3 scripts/merge-findings.py findings/*.json > merged.json
```

This keeps the highest-confidence version of each root cause and collects
module conclusions.

## Output Model

Intermediate child agents return JSON only.

The final merged output contains:

- `final_findings`
- `module_conclusions`

Each finding is expected to include:

- `title`
- `root_cause_key`
- `module_id`
- `labels`
- `location`
- `confidence`
- `severity`
- `broken_invariant`
- `description`
- `fix`
- `evidence`

If file output is requested, the final rendered report can be written under
`assets/findings/`.

## Scope Defaults

By default, the skill includes `.sol` source files and excludes common
noise such as:

- `lib/`
- `test/`
- `tests/`
- `mocks/`
- `interfaces/`
- `script/`
- `broadcast/`
- `*.t.sol`
- `*Test*.sol`
- `*Mock*.sol`

External dependencies are treated as context by default, not as findings
scope, unless the user explicitly includes them.

## Requirements

- Codex with local skill loading enabled
- `bash`, `find`, and standard Unix shell tools
- `python3` for the helper scripts
- a runtime that supports multi-agent orchestration for full use

## Limitations

- This repo is an orchestration skill, not a standalone security product.
- It is not designed for linting, style review, or gas-only review.
- It works best when child-agent execution and report synthesis are both
  available in the runtime.
- Final audit quality still depends on model quality, scope definition, and
  evidence discipline.

## SKILL.md

---
name: solidity-audit
description: Use when performing a formal Solidity security review across mixed-protocol codebases, especially when contracts may belong to multiple protocol types and the review must produce a consolidated findings list and module-level audit conclusions.
---

# Solidity Formal Audit

## Overview

You are the orchestrator of a formal Solidity security audit. Your job is to:

1. discover in-scope contracts
2. classify each contract with one or more protocol labels
3. identify complexity, callback, and liveness-critical paths
4. identify mutable active-draw dependencies and unsnapshotted configuration
5. cluster contracts into modules using the contract dependency subgraph
6. spawn specialized audit agents per `contract x label`
7. merge results into a single findings list plus module-level conclusions

Do not try to perform the full audit alone if the codebase is non-trivial. This skill is built around specialized agents with narrow responsibilities.

## When To Use

Use this skill when:

- the target is a Solidity codebase with multiple contracts
- the review is intended to be a formal or near-formal security assessment
- the protocol may mix multiple domains such as DEX, Lending, Staking, Bridge, Governance, Oracle, or Vault
- the output must include both a global findings list and per-module conclusions

Do not use this skill for:

- a quick single-function bug triage
- linting, style review, or gas-only review
- small one-off code questions answerable from one contract

## Scope Rules

- Include Solidity source files with `.sol` suffix.
- Exclude common noise by default: `lib/`, `test/`, `tests/`, `mocks/`, `interfaces/`, `script/`, `broadcast/`.
- Also exclude files matching `*.t.sol`, `*Test*.sol`, `*Mock*.sol`, unless the user explicitly asks to include them.
- If the user names specific files or folders, treat those as the primary scope.
- Treat external dependencies as context, not findings scope, unless the user explicitly includes them.

## References

Read only what is needed at each stage:

- research routing stage:
  `references/workflow/research-triangulation.md`
- generic class mapping stage:
  `references/common/vulnerability-taxonomy.md`
- classification stage:
  `references/workflow/classification-rubric.md`
- module clustering stage:
  `references/workflow/module-clustering.md`
- feasibility stage:
  `references/workflow/complexity-feasibility.md`
- active lifecycle mutability stage:
  `references/workflow/active-draw-mutability.md`
- finding validation stage:
  `references/workflow/judging.md`
- final rendering stage:
  `references/workflow/report-format.md`
- protocol-specific analysis stage:
  `references/protocols/<label>.md`
- generic baseline analysis stage:
  `references/common/*.md`
- agent contracts:
  `references/agents/*.md`

## Workflow

### Stage 1: Discover

- Find in-scope Solidity contracts.
- Prefer `scripts/discover-contracts.sh` if present.
- Build a contract list with file path, declared contract names, and basic role hints from names.

### Stage 2: Graph Build

- Build a contract dependency and interaction graph.
- Prefer `scripts/build-contract-graph.py` if present.
- Capture direct imports, inheritance, constructor wiring, external contract fields, library usage, and obvious call edges.
- Keep the graph conservative: direct relationships first, not speculative long chains.

### Stage 3: Classification

- For each contract, run `classifier-agent`.
- Allowed labels:
  `DEX`, `Lending`, `Staking`, `Bridge`, `Governance`, `Oracle`, `Vault`
- Multi-label is allowed and expected.
- If no label is strong enough, route the contract to `Generic`.
- Classification must be evidence-based, not name-based alone.

### Stage 4: Feasibility And Complexity

- Identify settlement, callback, matching, liquidation, or queue-processing paths that may fail to execute at realistic chain gas limits.
- Treat keeper, oracle, bridge, and randomness callbacks as liveness-critical paths.
- Prefer `references/workflow/complexity-feasibility.md`.
- A gas finding is reportable only when it can break settlement, callback completion, withdrawals, governance actions, or another critical invariant.

### Stage 5: Active-Draw Mutability

- Identify global variables and external dependencies whose values can change during an active lifecycle window.
- For jackpot-like systems this includes draw-time, settlement-time, callback-time, claim-time, and emergency-time dependencies.
- Prefer `references/workflow/active-draw-mutability.md`.
- Explicitly check whether ticket pricing, fee parameters, payout calculators, entropy providers, bridge routes, and callback targets are snapshotted or read live.

### Stage 6: Module Clustering

- Group contracts into modules using the contract dependency subgraph.
- A module is a contract-centered cluster with core contracts plus direct dependencies and direct interaction partners.
- Prefer fewer, coherent modules over many tiny fragments.
- Keep cross-module edges so a later cross-module review can analyze them.

### Stage 7: Bundle Preparation

- For each `contract x label`, prepare a bundle containing:
  - the target contract
  - its direct dependency/interaction subgraph
  - `research-triangulation.md`
  - `vulnerability-taxonomy.md`
  - relevant common references
  - one protocol reference
  - feasibility and mutability workflow references when relevant
  - `judging.md`
- For unlabelled contracts, prepare a Generic bundle.
- For high-risk module edges, prepare a cross-module bundle.

### Stage 8: Audit Dispatch

- Spawn one `protocol-auditor-agent` per `contract x label`.
- Spawn one `generic-auditor-agent` for Generic contracts.
- Spawn `cross-module-agent` for risky module boundaries.
- Spawn `complexity-auditor-agent` for settlement, callback, matching, or queue-heavy paths.
- Spawn `mutable-dependency-agent` for active lifecycle systems where admin or provider changes can affect current state.
- Spawn `module-summarizer-agent` after findings exist for each module.
- Spawn `aggregator-agent` only after all prior results are available.

### Stage 9: Merge

- Merge by `root_cause_key`.
- Keep the highest-confidence version of duplicate findings.
- If two findings share a root cause but differ in scope, preserve the broader, better-evidenced version.
- Keep `confidence` separate from `severity`.
- Do not invent new findings during aggregation.

### Stage 10: Render

- Produce a final findings list.
- Produce module-level audit conclusions.
- Use `references/workflow/report-format.md`.
- If the user asks for file output, write the report under `assets/findings/`.

## Agent Routing Rules

- `classifier-agent` only classifies.
- `protocol-auditor-agent` only audits one `contract x label`.
- `generic-auditor-agent` audits Generic infrastructure contracts.
- `cross-module-agent` audits risky interactions between modules or labels.
- `complexity-auditor-agent` audits gas, callback, and liveness feasibility of critical paths.
- `mutable-dependency-agent` audits unsnapshotted globals and replaceable dependencies during active protocol lifecycles.
- `module-summarizer-agent` summarizes one module and adds no new findings.
- `aggregator-agent` only deduplicates, sorts, groups, and prepares report-ready output.

## Output Contract

All intermediate agents should return JSON only.

Every finding object must include:

- `title`
- `root_cause_key`
- `module_id`
- `labels`
- `location`
- `confidence`
- `severity`
- `broken_invariant`
- `description`
- `fix`
- `evidence`

## Hard Rules

- Do not skip Generic coverage for unclassified contracts.
- Do not collapse multiple labels into one if evidence supports multiple labels.
- Do not treat user-controlled external call targets as benign if the contract also custodies tokens, NFTs, approvals, or execution authority.
- Do not dismiss gas findings if they can block settlement, callback execution, claims, governance, or liveness.
- Do not assume admin changes are future-only; verify whether the active lifecycle reads snapshotted or live values.
- Do not report style issues, gas-only notes, or generic centralization observations without an exploit path.
- Do not ignore compiler, proxy-deployment, or hidden-callback classes when the bundle contains proxies, routers, token hooks, or version-sensitive code.
- Do not rewrite child-agent findings during merge unless normalization is strictly required for formatting.
- Do not treat confidence as severity.

## assets

```

```

## assets/findings

```

```

## assets/findings/.gitkeep

```

```

## references

```

```

## references/agents

```

```

## references/agents/aggregator-agent.md

# Aggregator Agent

You merge audit results into report-ready data.

## Read First

- `references/workflow/judging.md`
- `references/workflow/report-format.md`

## Goal

Produce final findings and module conclusions by deduplicating child-agent output.

## Rules

- Do not invent new findings.
- Deduplicate by `root_cause_key`.
- Keep the highest-confidence version of duplicates.
- Preserve broader scope when evidence strength is equal.
- Keep confidence and severity separate.
- Return sorted findings, highest confidence first.

## Output

Return JSON only:

```json
{
  "final_findings": [],
  "module_conclusions": []
}
```

## references/agents/classifier-agent.md

# Classifier Agent

You classify one Solidity contract into one or more protocol labels.

## Allowed Labels

- `DEX`
- `Lending`
- `Staking`
- `Bridge`
- `Governance`
- `Oracle`
- `Vault`

Fallback:

- `Generic`

## Read First

- `references/workflow/classification-rubric.md`

## Rules

- Only classify. Do not report vulnerabilities.
- Use evidence from behavior, state, and direct interactions.
- Contract names are weak evidence by themselves.
- Multi-label is allowed.
- If evidence is weak, lower confidence instead of forcing certainty.

## Output

Return JSON only:

```json
{
  "contract_name": "",
  "labels": [
    {
      "label": "",
      "confidence": 0,
      "evidence": []
    }
  ],
  "fallback_label": "Generic"
}
```

## references/agents/complexity-auditor-agent.md

# Complexity Auditor Agent

You audit execution feasibility of critical Solidity paths.

## Read First

- `references/workflow/complexity-feasibility.md`
- `references/workflow/judging.md`

## Goal

Find liveness and denial-of-service issues caused by realistic gas, callback, or execution-budget limits.

## Rules

- Focus on settlement, callback, queue, matching, liquidation, and batch-processing paths.
- Identify the scaling variable and the critical path it breaks.
- Compare algorithmic growth against realistic chain or provider limits.
- Do not report micro-optimizations.
- Report only when execution failure breaks a protocol invariant or leaves a lifecycle stuck.

## Output

Return JSON only with the standard finding schema.

## references/agents/cross-module-agent.md

# Cross-Module Agent

You audit risky interactions across module boundaries.

## Read First

- `references/workflow/research-triangulation.md`
- `references/common/vulnerability-taxonomy.md`
- `references/workflow/judging.md`
- `references/workflow/complexity-feasibility.md`
- `references/workflow/active-draw-mutability.md`
- relevant protocol references for the interacting modules
- `references/common/external-integrations.md`

## Goal

Find vulnerabilities that only emerge from module interaction, for example:

- Lending <-> Oracle
- Governance <-> Upgrade
- Bridge <-> Vault
- DEX <-> Oracle

## Rules

- Do not duplicate single-module findings unless the real root cause is the boundary itself.
- Focus on replay, trust boundary mismatch, stale state, ordering gaps, cross-domain accounting drift, and permission handoff failures.
- Focus on mutable dependency replacement across active lifecycle windows, such as provider swaps, calculator swaps, or live global fee reads crossing a snapshot boundary.
- Focus on arbitrary external call capability where one module custodies assets and another module exposes user-controlled execution.
- Focus on liveness breaks where one module's scaling variable makes another module's callback or settlement infeasible.
- Use `affected_modules` in evidence or description when relevant.

## Output

Return JSON only:

```json
{
  "agent_type": "cross-module-auditor",
  "findings": []
}
```

## references/agents/generic-auditor-agent.md

# Generic Auditor Agent

You audit infrastructure or uncategorized Solidity contracts using the Generic lens.

## Read First

- `references/workflow/research-triangulation.md`
- `references/common/vulnerability-taxonomy.md`
- `references/workflow/judging.md`
- `references/workflow/complexity-feasibility.md`
- `references/workflow/active-draw-mutability.md`
- `references/protocols/generic.md`
- relevant common references

## Suitable Targets

- access managers
- registries
- proxy admins
- treasuries
- fee collectors
- config holders
- helpers that still affect trust, accounting, or funds

## Rules

- Do not invent a protocol label if the bundle is Generic.
- Focus on access control, initialization, external integration, accounting, and upgrade safety.
- If the contract custodies assets, approvals, tickets, or receipts for others, read `references/common/custody-and-callbacks.md`.
- Treat managers, helpers, routers, and bridge adapters as potential custody surfaces, not harmless glue.
- Explicitly check user-controlled call targets, callback targets, approval targets, and live global reads during active lifecycle windows.
- Explicitly check for deployment-phase, proxy-initialization, selector
  mismatch, stale approval, and hidden callback classes when the contract
  functions as glue between systems.
- Use the same finding schema as `protocol-auditor-agent`.

## Output

Return JSON only with `agent_type` set to `generic-auditor`.

## references/agents/module-summarizer-agent.md

# Module Summarizer Agent

You summarize one module after findings already exist.

## Goal

Produce a concise module-level audit conclusion without inventing new vulnerabilities.

## Rules

- Do not add findings.
- Do not change finding confidence or severity.
- Summarize primary risks, reviewed surfaces, and important caveats.

## Output

Return JSON only:

```json
{
  "module_id": "",
  "summary": {
    "primary_risk": "",
    "coverage_note": "",
    "conclusion": ""
  }
}
```

## references/agents/mutable-dependency-agent.md

# Mutable Dependency Agent

You audit active lifecycle drift caused by mutable globals and replaceable dependencies.

## Read First

- `references/workflow/active-draw-mutability.md`
- `references/workflow/judging.md`

## Goal

Find cases where an active round, callback window, claim path, or emergency path reads live values that should have been snapshotted or frozen.

## Rules

- Enumerate mutable globals that affect pricing, fees, payouts, refunds, timing, and settlement.
- Enumerate replaceable dependencies such as entropy providers, payout calculators, bridge verifiers, and executors.
- Verify whether current lifecycle logic reads round-local snapshots or live state.
- Prefer concrete examples over broad centralization observations.

## Output

Return JSON only with the standard finding schema.

## references/agents/protocol-auditor-agent.md

# Protocol Auditor Agent

You audit exactly one `contract x label` bundle.

## Read First

- `references/workflow/research-triangulation.md`
- `references/common/vulnerability-taxonomy.md`
- `references/workflow/judging.md`
- `references/workflow/complexity-feasibility.md`
- `references/workflow/active-draw-mutability.md`
- the relevant protocol reference
- relevant common references

## Scope

Your scope is:

- the target contract
- its direct dependency and interaction subgraph
- one protocol label only

Do not broaden scope beyond the provided bundle unless explicitly instructed.

## Audit Goal

Find concrete vulnerabilities that break protocol or accounting invariants under the given label lens.

## Rules

- Focus on one protocol label only.
- Use the FP gate before reporting.
- State the broken invariant explicitly.
- Keep `confidence` separate from `severity`.
- Produce `root_cause_key` values stable enough for later deduplication.
- Translate each concrete issue into both a protocol-specific failure mode and
  a generic vulnerability class before reporting it.
- Explicitly audit user-controlled external call sinks, especially if the contract custodies assets, approvals, or execution authority for multiple users.
- Explicitly audit settlement, callback, and counting paths for realistic gas and liveness feasibility.
- Explicitly audit active lifecycle reads for mutable globals and replaceable dependencies.
- Explicitly consider hidden ERC callback surfaces, stale approvals, router
  calldata abuse, and version-sensitive proxy or compiler assumptions when the
  bundle suggests them.
- If docs or comments claim a parameter only affects future rounds, verify that claim against live read paths.
- If the target or its neighbors custody third-party assets, also read `references/common/custody-and-callbacks.md`.

## Output

Return JSON only:

```json
{
  "agent_type": "protocol-auditor",
  "contract_name": "",
  "label": "",
  "module_id": "",
  "findings": [
    {
      "title": "",
      "root_cause_key": "",
      "module_id": "",
      "labels": [],
      "location": [],
      "confidence": 0,
      "severity": "",
      "broken_invariant": "",
      "description": "",
      "fix": "",
      "evidence": []
    }
  ]
}
```

## references/common

```

```

## references/common/access-control.md

# Access Control Reference

## Focus Areas

- owner, admin, operator, guardian, governor, signer roles
- initialization and one-time setup
- timelock and executor separation
- delegated privilege paths
- signature authority and replay boundaries

## Common Failure Modes

- missing or partial role checks
- role checks on one function but not the helper it calls
- privileged upgrade path bypass
- initialization takeover
- authority inferred from unsafe assumptions such as `tx.origin`

## Audit Questions

- who can call this today
- who can grant or revoke that ability
- can a temporary privilege become permanent
- can governance or upgrade flows bypass ordinary checks

## references/common/custody-and-callbacks.md

# Custody And Callbacks Reference

## Use Case

Apply this reference whenever a contract:

- custodies ERC20, ERC721, ERC1155, bridge receipts, tickets, or claim balances for multiple users
- grants approvals before external execution
- executes user-controlled call targets or calldata
- dispatches callbacks while privileged state or custodied assets remain live

## Core Invariants

- one user's external execution must not affect another user's custodied assets
- approvals must stay scoped to the intended asset and amount
- callback execution must not bypass custody or authorization boundaries
- local ownership bookkeeping must stay aligned with actual asset custody

## High-Risk Patterns

- `approve -> arbitrary call`
- `custody -> callback -> transferFrom`
- arbitrary external call while the contract still holds unrelated user assets
- local `ticketOwner` or receipt bookkeeping that is weaker than actual asset ownership
- receiver hooks or callback hooks that run before state fully settles

## Audit Questions

- what third-party assets are currently custodied by this contract
- can a user-controlled target consume approvals or move assets outside the intended scope
- can a callback chain reach transfer or approval state for assets belonging to another user
- does the contract behave like a hidden custodian even if named manager, helper, or bridge

## references/common/external-integrations.md

# External Integrations Reference

## Focus Areas

- ERC20 and ERC4626 assumptions
- callbacks and reentrancy surfaces, including ERC721, ERC777, and ERC1155
  hooks
- oracle reads
- bridge or cross-domain messaging
- external strategy or router interactions
- custodied tokens, NFTs, allowances, and execution authority
- user-controlled external call targets or calldata
- interface signature mismatches and unsafe type casts
- spender migrations that leave stale approvals alive

## Common Failure Modes

- assuming standard ERC20 behavior
- stale external state read before settlement
- reentrancy through callbacks or token hooks
- trusting external return data without validation
- broken assumptions about chain IDs, message uniqueness, or freshness
- arbitrary external calls while the contract custodies third-party assets
- granting approvals before calling untrusted targets
- capability leakage where a payload can move unrelated custodied assets
- interface mismatches that silently dispatch to fallback or attacker code
- stale approvals surviving cancellation, migration, or spender replacement

## Audit Questions

- what external system is trusted here
- what happens if that system is stale, malicious, paused, or non-standard
- are external effects observed before local accounting settles
- can a user-controlled call target reach token, NFT, or approval state the caller should not control
- does this contract hold assets for multiple users while also executing arbitrary external calls
- does the interface used for an external dependency actually match the
  deployed selector surface

## references/common/generic-solidity.md

# Generic Solidity Audit Reference

## Core Invariants

- privileged actions are constrained to the intended trust boundary
- accounting state remains internally consistent across all state transitions
- external calls cannot invalidate local assumptions
- initialization and upgrade state cannot be hijacked

## Primary Checks

- unsafe ownership or role transitions
- missing initialization guards
- storage layout or upgrade assumptions
- unsafe external calls and unchecked return values
- state update ordering around asset movement
- hidden trust assumptions in helper or registry contracts

## Cross-Check

Before declaring a generic surface safe, map it against
`references/common/vulnerability-taxonomy.md`, especially for:

- stale approvals and router calldata abuse
- hidden callbacks and reentrancy entry points
- selector mismatch and unsafe interface assumptions
- deployment-sequencing and proxy-initialization risk

## Review Order

1. external entry points
2. privileged state transitions
3. asset movement and accounting updates
4. initialization and upgrade paths

## references/common/math-and-accounting.md

# Math And Accounting Reference

## Focus Areas

- rounding direction
- decimal normalization
- share and debt accounting
- reward distribution
- fee accrual
- first-user edge cases

## Common Failure Modes

- stale snapshots used for later checks
- asymmetric mint and burn math
- share inflation from empty-vault or first-depositor edge cases
- incorrect accrual ordering
- precision loss that benefits the attacker repeatedly
- accounting updates split across partially trusted calls

## Audit Questions

- what quantity is the true source of record
- which states must always remain in sync
- who benefits from rounding in each direction
- can a user profit by round-tripping a state transition

## references/common/upgradeability.md

# Upgradeability Reference

## Focus Areas

- proxy patterns
- initializer safety
- implementation takeover risk
- upgrade authorization
- storage layout compatibility
- deployment sequencing and atomic initialization
- re-initialization risk after upgrades

## Common Failure Modes

- unprotected initializer
- upgrade path bypassing governance or timelock
- storage collision or layout drift
- implementation contract left claimable
- emergency upgrade powers inconsistent with trust assumptions
- non-atomic proxy deployment that leaves a mempool-visible initialization
  window
- re-initialization after upgrade resets critical trust assumptions
- missing authorization on UUPS `_authorizeUpgrade`

## Audit Questions

- who can upgrade
- can implementation or admin addresses be changed unexpectedly
- can initialization be replayed or front-run
- does proxy deployment pass initialization data atomically
- are post-upgrade storage and initialization assumptions re-verified

## references/common/vulnerability-taxonomy.md

# Vulnerability Taxonomy Reference

Distilled cross-protocol vulnerability classes based on public smart
contract vulnerability catalogs and exploit research.

Use this reference to translate a concrete candidate issue into a known
class before deciding whether it clears the FP gate.

## Access Control And Authority

- missing or partial role checks
- `tx.origin` or code-size based trust assumptions
- privileged helper paths that bypass the main guard
- unvalidated router calldata combined with existing approvals
- stale approvals that survive migration, cancellation, or spender changes
- signature replay, signature malleability, or `ecrecover` zero-address
  authorization
- ownership transfer flows where the confirmation step can be hijacked,
  skipped, or permanently bricked

## Reentrancy And State Ordering

- external call before critical state update
- hidden callbacks via ERC-721 safe transfers, ERC-777 hooks, or ERC-1155
  receiver hooks
- read-only reentrancy where a dependent protocol reads inconsistent state
- approval granted before untrusted execution
- state update ordering errors that make CEI appear present but ineffective

## Math, Accounting, And Share Systems

- precision loss or decimal mismatch
- asymmetric mint, burn, deposit, withdraw, borrow, or redeem math
- first-depositor or empty-vault inflation
- stale cached totals or stale share price reads
- balance-of based accounting that can be distorted by direct donation
- debt, collateral, fee, or reward accounting that drifts after external
  calls or partial updates

## Control Flow And Liveness

- unbounded loops or queue processing that can exceed realistic gas limits
- unexpected revert paths that brick settlement or withdrawal
- insufficient gas griefing in relayer, callback, or forwarder flows
- unbounded return data or attacker-controlled memory expansion
- array underflow, out-of-bounds, or empty-pop panics that permanently block
  critical paths

## Oracle, Pricing, Slippage, And MEV

- spot-price oracle manipulation
- stale oracle values, wrong heartbeat assumptions, or incomplete round
  validation
- LP or vault price manipulation through reserve distortion or direct
  donation
- on-chain quote based slippage checks that reuse manipulable state
- missing deadline or `minOut == 0` style protection
- thin-liquidity, sandwich, or front-running assumptions hidden inside
  economic logic

## Upgradeability, Deployment, And Process Layer

- uninitialized proxies or re-initialization after upgrade
- missing authorization on upgrade entry points such as UUPS
  `_authorizeUpgrade`
- storage layout drift or unsafe storage gaps
- non-atomic proxy deployment windows where initialization can be raced
- deployment or upgrade procedures that are safe in code review but unsafe in
  transaction sequencing

## Data Handling, Language, And Compiler Footguns

- unchecked low-level call return values
- arbitrary storage writes or dangling storage references
- `msg.value` reuse across loops or multiple payment paths
- interface signature mismatch that dispatches to fallback silently
- inheritance linearization surprises
- compiler-version-specific behavior that invalidates source-level
  assumptions
- transient storage or proxy mechanics that break ordinary composability
  expectations

## Reporting Rule

- map the candidate issue to at least one class above
- explain the broken invariant in protocol terms, not category terms alone
- do not report a category label without a reachable exploit path

## references/protocols

```

```

## references/protocols/bridge.md

# Bridge Audit Reference

## Protocol Identity

Bridge contracts move value or messages across domains using proof verification, message uniqueness, and controlled settlement.

## Core Invariants

- a valid message is processed once
- source and destination domain assumptions are explicit
- mint, burn, lock, and release operations stay consistent across domains
- rate limits and emergency controls bound damage
- assets custodied for one user cannot be moved by another user's bridge payload
- bridge execution cannot use arbitrary call data to exercise unrelated contract authority

## High-Risk Entry Points

- receive message
- verify proof
- process deposit or withdrawal
- mint or release funds
- configure remote peers or verifiers
- claim paths that both release funds and execute arbitrary bridge payloads
- ticket or NFT custody managers that hold assets on behalf of multiple users

## Common Failure Modes

- cross-chain replay
- chain ID confusion
- nonce or message uniqueness gaps
- verifier trust boundary mismatch
- funds locked due to settlement inconsistency
- unsafe token handling on remote settlement
- arbitrary call target or calldata controlling custodied assets
- approval-plus-call patterns that let the bridge payload escape its intended asset scope
- live price or fee reads in bridge helpers when the core protocol uses round snapshots

## High-Frequency Category Cross-Check

- access control misconfiguration around peers, verifiers, executors, or
  rate-limit roles
- external call injection in receive, claim, or settlement payloads
- funds locked by partial settlement or inconsistent mint, burn, lock, and
  release bookkeeping
- gas-limit or execution-budget failure on delivery, proving, or callback
  completion
- initialization and upgrade flaws around verifier or peer configuration
- non-standard token and native ETH handling on both sides of settlement
- state update inconsistency between message consumption and value movement

## Cross-Tag Interactions

- `Bridge + Vault`: share accounting may not survive asynchronous settlement
- `Bridge + Governance`: remote control paths can bypass local trust assumptions
- `Bridge + Generic`: helper managers may custody unrelated user assets while executing bridge payloads

## references/protocols/dex.md

# DEX Audit Reference

## Protocol Identity

DEX contracts route swaps, manage pools, compute quotes, or maintain reserve-based pricing.

## Core Invariants

- reserve and balance accounting stay aligned
- swap execution respects slippage and deadline expectations
- liquidity shares are minted and burned fairly
- oracle or reserve-derived pricing cannot be abused through ordering gaps

## High-Risk Entry Points

- swap, route, quote-to-execute paths
- add/remove liquidity
- fee collection and reserve sync
- callback settlement and flash interactions

## Common Failure Modes

- missing slippage protection
- stale reserves or stale pool state
- price manipulation via flash liquidity or oracle coupling
- unsafe callbacks
- token decimal mismatch
- incorrect fee accounting

## High-Frequency Category Cross-Check

- flash-loan or single-block reserve manipulation
- front-running and MEV around quote-to-execute flows
- fee-on-transfer or non-standard token handling
- first-depositor or share inflation when pools or vault-like wrappers start
  near empty
- token approval issues and unsafe external calls in routers or aggregators
- stale state after swaps, syncs, or liquidity actions
- signature and replay vulnerabilities in permit or off-chain order paths

## Cross-Tag Interactions

- `DEX + Oracle`: manipulated spot inputs leak into protected decisions
- `DEX + Vault`: share pricing can inherit stale pool assumptions

## references/protocols/generic.md

# Generic Protocol Reference

## Use Case

Use this label for important contracts that do not fit a specialized protocol type but still affect trust, funds, permissions, or critical state.

## Core Invariants

- trust boundaries are explicit
- privileged changes are bounded
- configuration cannot silently invalidate safety assumptions
- helpers and registries cannot corrupt downstream protocol logic
- active lifecycle logic must not read live mutable values when a round-local snapshot is expected
- callback or helper contracts must remain safe even when they custody third-party assets

## Priority Checks

- access control
- initialization and upgrade paths
- registry integrity
- unsafe external call assumptions
- critical config mutation
- mutable dependency replacement during active lifecycle windows
- callback feasibility and liveness on realistic gas budgets

## High-Frequency Category Cross-Check

- router-style arbitrary calldata execution against existing approvals
- selector mismatch or unsafe interface casts on external dependencies
- hidden custody surfaces in helpers, managers, and adapters
- proxy initialization or deployment sequencing gaps
- stale approvals that survive migration or cancellation
- compiler or version-sensitive assumptions that make the source-level guard
  misleading

## references/protocols/governance.md

# Governance Audit Reference

## Protocol Identity

Governance contracts manage proposals, voting, timelocks, execution, and role transitions driven by voting power.

## Core Invariants

- proposal execution matches approved intent
- voting power is measured at the intended snapshot
- quorum and threshold rules cannot be bypassed
- privileged execution paths remain time-delayed when promised

## High-Risk Entry Points

- propose, queue, execute
- set governance parameters
- grant executor powers
- emergency or guardian override paths

## Common Failure Modes

- current-balance voting instead of snapshot-based voting
- flash-loan governance manipulation
- timelock bypass
- proposal hash ambiguity
- executor privilege escalation

## Research-Derived Cross-Check

- voting and execution allowed in the same transaction
- snapshot source tied to manipulable live balances or wrappers
- off-chain vote or permit style signatures missing nonce, expiry, or domain
  separation
- governance executor that can silently control upgrades, proxy admins, or
  bridge peers
- queue, cancel, or execute paths with stale proposal state or incorrect
  state transitions
- emergency or guardian powers that bypass promised delay or quorum rules

## Cross-Tag Interactions

- `Governance + Upgrade`: proposal execution may silently control upgrades
- `Governance + Oracle`: voting power or execution conditions may depend on manipulable prices

## references/protocols/lending.md

# Lending Audit Reference

## Protocol Identity

Lending contracts manage collateral, debt, utilization, interest accrual, and liquidation.

## Core Invariants

- solvency and health checks reflect current economic state
- debt and collateral accounting remain synchronized
- liquidation rules preserve protocol safety margins
- interest accrual updates happen before dependent checks

## High-Risk Entry Points

- deposit collateral
- borrow, repay
- liquidate
- accrue interest
- set oracle or risk parameters

## Common Failure Modes

- stale health factor checks
- liquidation ordering bugs
- interest accrual mismatch
- bad debt creation or hidden insolvency
- precision loss in borrow or repay share math
- unsafe oracle assumptions

## High-Frequency Category Cross-Check

- accounting share mismatch between debt shares, asset balances, and treasury
  fees
- bad debt or hidden insolvency after partial liquidation or stale accrual
- interest rate or interest accrual update ordering bugs
- external protocol integration assumptions in adapters, wrappers, or
  collateral managers
- position health checks using stale prices, stale totals, or post-action
  state
- locked funds from withdrawal, liquidation, or rescue edge cases
- vault share inflation when vault-like collateral is accepted directly

## Cross-Tag Interactions

- `Lending + Oracle`: stale or manipulated prices break solvency checks
- `Lending + Vault`: share pricing and collateral value assumptions interact

## references/protocols/oracle.md

# Oracle Audit Reference

## Protocol Identity

Oracle contracts publish, aggregate, normalize, or validate external data used by economic or governance logic.

## Core Invariants

- data freshness assumptions are enforced
- units and decimals are normalized correctly
- fallback logic is safe and bounded
- price consumers cannot mistake stale or invalid data for current truth

## High-Risk Entry Points

- publish or update price
- read normalized price
- configure source or heartbeat
- choose fallback or aggregation strategy

## Common Failure Modes

- stale price acceptance
- unit normalization errors
- unsafe fallback choice
- price manipulation through narrow observation windows
- inconsistent price use across dependent modules

## High-Frequency Category Cross-Check

- incorrect decimal normalization between feeds and consumers
- invalid round, version, or completeness handling
- reserve-derived or AMM-derived prices used without manipulation resistance
- TWAP miscalculation or asymmetric TWAP enforcement
- unchecked external call return values from oracle adapters
- stale oracle price data accepted because heartbeat assumptions are wrong
- missing access control on source, heartbeat, or fallback configuration

## Cross-Tag Interactions

- `Oracle + Lending`: stale or manipulated prices break liquidation safety
- `Oracle + DEX`: spot-derived values can be attacker-controlled

## references/protocols/staking.md

# Staking Audit Reference

## Protocol Identity

Staking contracts lock assets or voting power and distribute rewards over time or across epochs.

## Core Invariants

- stake shares and underlying balances remain aligned
- reward emission and claim accounting are monotonic and fair
- unlock or cooldown logic cannot be bypassed
- penalties and slashing affect the intended balances only

## High-Risk Entry Points

- stake and unstake
- claim rewards
- queue unlock or withdraw
- slash or emergency actions

## Common Failure Modes

- reward accounting drift
- queue or epoch boundary bugs
- rounding-based dust extraction
- cooldown bypass
- state inconsistency after slash events

## High-Frequency Category Cross-Check

- balance accounting drift between stake shares and underlying assets
- reward distribution flaws across epochs, slash events, or rebases
- withdrawal and unstaking issues that trap assets or bypass cooldown
- share price manipulation or first-depositor inflation in wrapper-style
  staking tokens
- approval or allowance vulnerabilities around reward or unstake helpers
- stale state after claim, slash, or checkpoint updates
- pause, blacklist, or emergency controls that unexpectedly block exits

## Cross-Tag Interactions

- `Staking + Governance`: voting weight may diverge from economic lock state
- `Staking + Vault`: share conversion can amplify reward or exit bugs

## references/protocols/vault.md

# Vault Audit Reference

## Protocol Identity

Vault contracts accept assets, mint shares, manage withdrawals, and may allocate funds to strategies.

## Core Invariants

- asset/share conversion is economically consistent
- deposits and withdrawals preserve total accounting integrity
- strategy gains and losses are reflected correctly
- withdrawal queues and fee paths cannot strand value

## High-Risk Entry Points

- deposit, mint, withdraw, redeem
- harvest, report, rebalance
- set fee or strategy
- process queued withdrawals

## Common Failure Modes

- first-depositor or empty-vault inflation
- asymmetric rounding on deposit and redeem
- stale total assets or strategy value
- withdrawal queue denial of service
- fee accounting leakage

## High-Frequency Category Cross-Check

- stale cached state or state update ordering errors between strategy reports
  and user actions
- oracle or price manipulation through vault donation, LP pricing, or stale
  strategy valuations
- unsafe token approvals and unsafe ERC20 handling in strategy interactions
- reward or fee accounting manipulation across harvest and rebalance flows
- locked or irretrievable funds in queues, rescue paths, or emergency exits
- upgradeability or storage-gap flaws in upgradeable vault deployments
- callback-token reentrancy during deposit, withdraw, or strategy execution

## Cross-Tag Interactions

- `Vault + Lending`: collateral valuation may depend on stale share pricing
- `Vault + Bridge`: delayed settlement can desynchronize share accounting

## references/workflow

```

```

## references/workflow/active-draw-mutability.md

# Active Lifecycle Mutability Rules

## Goal

Detect when a protocol promises that current state is fixed, but implementation still reads mutable globals or replaceable dependencies during an active lifecycle.

## Active Lifecycle Windows

Treat these as sensitive windows:

- active draw
- active epoch
- active auction
- post-lock pre-settlement
- pending callback
- unclaimed winnings period
- emergency refund period

## Mandatory Checks

### 1. Mutable Global Variables

List every global variable that can affect:

- pricing
- payout
- fee extraction
- refund amount
- collateral checks
- reward distribution
- timing or scheduling

Then verify whether current lifecycle logic reads:

- a snapshotted per-round value
- or the live mutable global

### 2. Replaceable Dependencies

List every external dependency that can be swapped:

- entropy provider
- payout calculator
- oracle source
- bridge verifier
- executor
- strategy

Then verify whether active lifecycle logic assumes the dependency is immutable.

### 3. Claim-Time Drift

Check whether claim, refund, or settlement logic uses:

- purchase-time values
- round-time values
- or current live values

### 4. Future-Only Promise Validation

If docs, comments, or product assumptions say a change applies only to future rounds, verify that claim in code.

## High-Risk Patterns

- bridge manager charges using a live global while core logic uses a round snapshot
- callback after lock reads a freshly replaceable dependency
- claim or refund reads a global fee that was not snapshotted at purchase time
- settlement reads a live calculator or provider that can be replaced mid-lifecycle

## Output Expectations

A valid finding should name:

- the mutable variable or dependency
- the active lifecycle window
- the expected snapshot boundary
- the actual live read path
- the user or protocol impact

## references/workflow/classification-rubric.md

# Contract Classification Rubric

## Goal

Assign one or more protocol labels to each contract based on behavior, state, and interactions.

Allowed labels:

- `DEX`
- `Lending`
- `Staking`
- `Bridge`
- `Governance`
- `Oracle`
- `Vault`

If none is sufficiently supported, use `Generic`.

## Evidence Rules

- Base labels on functions, state variables, accounting flows, and direct dependencies.
- Contract name is supporting evidence only, never enough by itself.
- A contract may receive multiple labels.
- Prefer precision over recall; weak hints should lower confidence, not force a label.

## Label Signals

### DEX

Strong signals:

- swap, route, quote, pool, reserve, pair, liquidity management
- price path computation
- slippage or deadline handling
- reserve accounting or pool share logic

### Lending

Strong signals:

- collateral, debt, borrow, repay, liquidation, health factor
- utilization or interest rate model
- debt shares, borrow shares, insolvency logic

### Staking

Strong signals:

- stake, unstake, queue, cooldown, reward accrual
- share minting tied to deposited assets or voting power
- reward distribution over time

### Bridge

Strong signals:

- message verification, remote chain IDs, bridge proof handling
- mint/burn or lock/release across chains
- nonce, replay protection, rate limiting

### Governance

Strong signals:

- propose, vote, queue, execute, quorum, timelock
- delegated voting or checkpoint snapshots
- privileged execution via proposal flow

### Oracle

Strong signals:

- price feed reads or price aggregation
- freshness checks, heartbeat, decimals normalization
- price publication or external data ingestion

### Vault

Strong signals:

- asset/share conversion
- deposit, mint, withdraw, redeem semantics
- strategy accounting or ERC4626-like behavior

## Multi-Label Rules

- Keep all labels with meaningful evidence.
- If one label is primary and another is supporting, keep both.
- Use confidence to indicate strength, not to suppress valid multi-label cases.

Examples:

- `LendingPool` reading liquidation prices from a feed can be `Lending + Oracle`.
- `StakingVault` with deposit/redeem shares can be `Staking + Vault`.
- `BridgeGovernor` can be `Bridge + Governance`.

## Generic Fallback

Use `Generic` when the contract is core infrastructure but does not cleanly fit a protocol label, for example:

- access managers
- registries
- configuration holders
- helper routers
- treasury and fee collectors
- upgrade admins or proxy tooling

## Output Schema

Return JSON with:

- `contract_name`
- `labels`: array of `{label, confidence, evidence}`
- `fallback_label`

## references/workflow/complexity-feasibility.md

# Complexity And Feasibility Rules

## Goal

Identify paths that are logically correct in isolation but fail in practice because they cannot be executed within realistic chain, keeper, or callback limits.

## Reportable Cases

Report complexity or gas findings when they can break:

- settlement
- callback completion
- liquidation
- withdrawals
- governance execution
- message delivery
- queue processing
- other liveness-critical invariants

Do not report micro-optimizations.

## Mandatory Checks

### 1. Critical Path Enumeration

Always inspect:

- settlement callbacks
- draw finalization
- winner counting
- liquidation loops
- queue processing
- batched claims
- proof verification and bridge execution

### 2. Growth Driver Analysis

For each critical path, identify which variables scale work:

- user count
- ticket count
- subset count
- bonusball range
- array length
- module size
- strategy count
- validator count

### 3. Budget Comparison

Compare estimated work against:

- target chain block gas limits
- per-transaction gas limits
- keeper or provider callback constraints
- hardcoded protocol gas caps

### 4. Asynchronous Callback Feasibility

For oracle, entropy, bridge, and keeper callbacks:

- check whether the callback gas is bounded
- check whether user or admin actions can push the callback above feasible limits
- check whether a failed callback leaves the protocol permanently locked or partially progressed

## Heuristics

- Nested loops over dynamic domains are high risk.
- Combinatorics and subset enumeration are high risk even when inputs are bounded.
- Any formula that converts pool size into callback gas or iteration count must be treated as adversarially steerable.
- A liveness break can be medium or high severity even without direct theft.

## Output Expectations

A valid finding should name:

- the critical path
- the scaling variable
- the realistic execution ceiling
- the resulting broken invariant or locked lifecycle

## references/workflow/judging.md

# Finding Validation

## FP Gate

A finding must pass all three checks before it can be reported.

### 1. Concrete Exploit Path

You must be able to explain:

- who triggers the path
- which entry point is used
- which state changes matter
- what invariant breaks
- what user or protocol impact follows

### 2. Reachable Entry

The attack path must be reachable in the actual trust model.

Check:

- modifiers
- role checks
- caller restrictions
- governance or timelock constraints
- initialization state

### 3. No Existing Guard

Drop the finding if an existing control already blocks it:

- validation checks
- replay protection
- accounting bounds
- reentrancy guards
- pause checks
- sequencing guarantees

### 4. Operational Feasibility

For liveness or complexity findings, you must also explain:

- which execution path fails in practice
- why the required gas, callback budget, or operational assumption is unrealistic
- why failure leaves funds, state, or control flow stuck or unsafe

## Confidence

Confidence measures how certain the finding is real and exploitable.

Start at `100` and deduct as needed:

- privileged caller required: `-25`
- attack path partially inferred: `-20`
- impact is narrow or self-contained: `-15`
- dependency behavior assumption is material but unverified: `-10`
- chain or provider feasibility assumption is material but unverified: `-10`

## Severity

Severity measures impact, not certainty.

Suggested buckets:

- `CRITICAL`
- `HIGH`
- `MEDIUM`
- `LOW`

## Do Not Report

Do not report:

- style or readability issues
- gas-only notes
- missing comments or events
- centralization observations without a concrete exploit path
- broad worries without a broken invariant
- self-harm only flows with no protocol spillover

Do not drop a finding only because it is gas-related if the gas issue breaks liveness of a critical path.

## Merge Rule

If two findings share the same root cause:

- keep the higher-confidence version
- preserve wider scope if the evidence is equally strong
- note composability only when the interaction is concrete

## references/workflow/module-clustering.md

# Module Clustering Rules

## Goal

Cluster contracts into review modules using direct dependency and direct interaction edges.

## Core Idea

A module is a coherent contract-centered subgraph, not just a folder or naming convention.

Each module should contain:

- one or more core contracts
- direct dependencies required to reason about them
- direct interaction partners required to assess safety of state transitions

## Edge Types

Treat the following as module edges:

- import and inheritance edges
- constructor or initializer wiring of contract addresses
- persistent external contract references stored in state
- direct external calls to named contracts or interfaces
- mint/burn/transfer authority relationships

Do not expand indefinitely beyond direct edges unless the user explicitly requests deep graph expansion.

## Core Contract Heuristics

A contract is more likely to be a module core if it:

- exposes important external state-changing entry points
- owns or moves funds
- orchestrates multiple collaborators
- maintains key accounting state
- contains upgrade, governance, liquidation, or settlement logic

## Clustering Rules

- Start from candidate core contracts.
- Pull in direct dependencies and direct interaction partners.
- Merge clusters when two candidate modules share the same dominant accounting or control surface.
- Keep modules separate when the shared edge is narrow and auditable as a boundary.

## Cross-Module Boundaries

Preserve edges between modules for later review by `cross-module-agent`.

High-priority boundaries include:

- Lending <-> Oracle
- Vault <-> Strategy
- Bridge <-> Message Verifier
- Governance <-> Upgrade or Executor
- DEX <-> Oracle

## Output Schema

Return JSON with:

- `modules`: array of
  - `module_id`
  - `core_contracts`
  - `contracts`
  - `labels_present`
  - `boundary_edges`

## references/workflow/report-format.md

# Report Format

## Final Report Sections

The final report should contain these sections in order:

1. `Security Review — <Project>`
2. `Scope`
3. `Module Map`
4. `Findings`
5. `Findings List`
6. `Module Conclusions`
7. `Residual Risks`
8. `Disclaimer`

## Scope

Include:

- mode
- reviewed files
- reviewed contracts
- discovered modules
- labels used

## Module Map

For each module include:

- `module_id`
- core contracts
- all included contracts
- labels present

## Finding Fields

Every finding should render:

- confidence marker
- numbered title
- module id
- labels
- location
- confidence
- severity
- broken invariant
- description
- fix, if confidence is above threshold

## Confidence Threshold

Default threshold: `75`

Below threshold:

- keep the finding in the report
- omit the fix section

## Module Conclusions

For each module include:

- labels present
- core contracts
- primary risks
- coverage note
- conclusion

## Residual Risks

Call out:

- important assumptions
- incomplete protocol documentation
- external dependencies not fully reviewed
- cross-module edges with limited visibility

## references/workflow/research-triangulation.md

# Research Triangulation

Use this workflow when you want to turn broad security intuition into a
defensible finding or a focused non-finding.

## Source Roles

- generic vulnerability catalogs provide the baseline class taxonomy
- protocol-specific frequency indexes provide a priority order for explicit
  protocol checks
- exploit research and mechanic notes provide edge cases, hidden callback
  surfaces, compiler behavior, and deployment-process failure modes
- skill packaging examples provide user-facing install and update ergonomics

## Audit Loop

1. Start with the local protocol reference and enumerate the entry points
   that can break the protocol's core invariants.
2. Map each candidate issue to one or more generic classes from
   `references/common/vulnerability-taxonomy.md`.
3. Cross-check the protocol's high-frequency categories before declaring an
   area low risk.
4. If the mechanic is unusual, explicitly test whether it is really one of
   these research-heavy classes:
   - hidden token callback reentrancy
   - read-only reentrancy
   - router approval drain or arbitrary calldata execution
   - vault donation or LP pricing oracle manipulation
   - same-transaction governance vote and execution
   - compiler-version or deployment-sequencing bugs
   - proxy initialization race or proxy hijack patterns
5. Return to `references/workflow/judging.md` and keep only findings with a
   reachable exploit path and a broken invariant.

## How To Use Frequency Priors

- use frequency to decide what must get an explicit pass
- do not use frequency as a substitute for evidence
- do not use frequency as a severity score
- rare classes still matter when the code contains the enabling mechanic

## Upstream Knowledge Sources

- `pashov/skills`: concise install and update ergonomics for public skill
  repos
- `kadenzipfel/smart-contract-vulnerabilities`: generic cross-protocol
  vulnerability classes
- `kadenzipfel/protocol-vulnerabilities-index`: high-frequency categories per
  protocol type from audit findings
- `evmresearch`: exploit mechanics, language and compiler footguns, and
  process-layer failure modes

## scripts

```

```

## scripts/build-audit-bundles.py

```python
#!/usr/bin/env python3

import argparse
import json
from pathlib import Path


def read_text(path: Path) -> str:
    return path.read_text(encoding="utf-8", errors="ignore")


def render_source_section(path: Path) -> str:
    return f"## Source: {path}\n\n```solidity\n{read_text(path).rstrip()}\n```\n"


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--tasks-json", required=True)
    parser.add_argument("--references-root", required=True)
    parser.add_argument("--output-dir", required=True)
    args = parser.parse_args()

    tasks = json.loads(Path(args.tasks_json).read_text(encoding="utf-8"))
    references_root = Path(args.references_root)
    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    for task in tasks:
        parts = [
            f"# Audit Bundle: {task['target_contract']} x {task['label']}",
            f"- module_id: {task['module_id']}",
        ]
        for source in task["contracts"]:
            parts.append(render_source_section(Path(source)))
        for common_ref in task.get("common_references", []):
            ref_path = references_root / "common" / common_ref
            parts.append(f"## Reference: {common_ref}\n\n{read_text(ref_path)}")
        protocol_ref = task.get("protocol_reference")
        if protocol_ref:
            ref_path = references_root / "protocols" / protocol_ref
            parts.append(f"## Protocol Reference: {protocol_ref}\n\n{read_text(ref_path)}")
        judging = references_root / "workflow" / "judging.md"
        parts.append(f"## Validation Reference\n\n{read_text(judging)}")
        out_path = output_dir / f"{task['module_id']}--{task['target_contract']}--{task['label']}.md"
        out_path.write_text("\n\n".join(parts) + "\n", encoding="utf-8")


if __name__ == "__main__":
    main()
```

## scripts/build-contract-graph.py

```python
#!/usr/bin/env python3

import json
import re
import sys
from pathlib import Path


CONTRACT_RE = re.compile(r"\b(?:abstract\s+)?contract\s+([A-Za-z_][A-Za-z0-9_]*)")
INTERFACE_RE = re.compile(r"\binterface\s+([A-Za-z_][A-Za-z0-9_]*)")
LIBRARY_RE = re.compile(r"\blibrary\s+([A-Za-z_][A-Za-z0-9_]*)")
IMPORT_RE = re.compile(r'import\s+(?:[^;]*?\s+from\s+)?["\']([^"\']+\.sol)["\']\s*;')
INHERIT_RE = re.compile(
    r"\b(?:abstract\s+)?contract\s+[A-Za-z_][A-Za-z0-9_]*\s+is\s+([^{]+)\{",
    re.MULTILINE,
)


def read_paths(argv):
    if argv:
        return [Path(p) for p in argv]
    return [Path(line.strip()) for line in sys.stdin if line.strip()]


def parse_file(path: Path):
    text = path.read_text(encoding="utf-8", errors="ignore")
    declared = CONTRACT_RE.findall(text)
    interfaces = INTERFACE_RE.findall(text)
    libraries = LIBRARY_RE.findall(text)
    imports = IMPORT_RE.findall(text)
    inherits = []
    for group in INHERIT_RE.findall(text):
        inherits.extend(
            item.strip().split(" ")[0]
            for item in group.split(",")
            if item.strip()
        )
    return {
        "path": str(path),
        "declared_contracts": declared,
        "declared_interfaces": interfaces,
        "declared_libraries": libraries,
        "imports": imports,
        "inherits": inherits,
        "text": text,
    }


def main():
    paths = [p for p in read_paths(sys.argv[1:]) if p.exists() and p.suffix == ".sol"]
    parsed = [parse_file(path) for path in paths]

    known_names = set()
    for item in parsed:
        known_names.update(item["declared_contracts"])
        known_names.update(item["declared_interfaces"])
        known_names.update(item["declared_libraries"])

    output_contracts = []
    for item in parsed:
        text = item.pop("text")
        referenced = []
        for name in sorted(known_names):
            if name in item["declared_contracts"]:
                continue
            if re.search(rf"\b{name}\b", text):
                referenced.append(name)
        neighbors = sorted(set(item["inherits"] + referenced))
        output_contracts.append(
            {
                **item,
                "references": referenced,
                "neighbors": neighbors,
            }
        )

    json.dump({"contracts": output_contracts}, sys.stdout, indent=2)
    sys.stdout.write("\n")


if __name__ == "__main__":
    main()
```

## scripts/discover-contracts.sh

```bash

```

## scripts/merge-findings.py

```python
#!/usr/bin/env python3

import argparse
import json
import sys
from pathlib import Path


def load_json(path: Path):
    return json.loads(path.read_text(encoding="utf-8"))


def score(finding):
    return int(finding.get("confidence", 0))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("inputs", nargs="+")
    args = parser.parse_args()

    findings_by_key = {}
    module_conclusions = []

    for raw in args.inputs:
        path = Path(raw)
        if not path.exists():
            continue
        payload = load_json(path)
        for finding in payload.get("findings", []) + payload.get("final_findings", []):
            key = finding.get("root_cause_key") or finding.get("title")
            current = findings_by_key.get(key)
            if current is None or score(finding) > score(current):
                findings_by_key[key] = finding
        if "summary" in payload:
            module_conclusions.append(payload)
        module_conclusions.extend(payload.get("module_conclusions", []))

    final_findings = sorted(findings_by_key.values(), key=score, reverse=True)
    json.dump(
        {
            "final_findings": final_findings,
            "module_conclusions": module_conclusions,
        },
        sys.stdout,
        indent=2,
    )
    sys.stdout.write("\n")


if __name__ == "__main__":
    main()
```

