---
name: generate-contract-docs
description: Use when generating documentation for Solidity contracts, when user says /generate-contract-docs, or when updating contract docs after deployment changes. Supports full sweep or single contract.
---

# Generate Contract Docs

Generate structured markdown documentation for Solidity contracts by analyzing source code, git history, and deployment addresses in `config/prod.toml`.

## Invocation

- `/generate-contract-docs` — all contracts
- `/generate-contract-docs <filename>.sol` — single contract

## Process

### 1. Gather Context (parallel)

Run all of these in parallel:

- `find contracts/ -name "*.sol" -not -path "*/interfaces/*"` — list all documentable contracts
- Read `config/prod.toml` — extract all `deployed_*` keys and their addresses per chain section
- For single-contract mode: only process the specified file

### 2. Parse prod.toml Addresses

For each chain section (e.g. `[sepolia.address]`, `[mainnet.address]`):

1. Extract every key starting with `deployed_`
2. Strip the `deployed_` prefix
3. Convert snake_case to PascalCase to match contract names
4. Handle `_impl` and `_proxy` suffixes: map both to the same contract, noting which is proxy vs implementation
5. Keys that don't match any contract file (e.g. `deployed_timelock_*` for OpenZeppelin imports) go in the "unmatched" list for the summary report

Example: `deployed_cork_pool_manager_proxy` -> contract `CorkPoolManager`, type `proxy`

Build a lookup: `{ ContractName: { chain: { address, type } } }`

### 3. Analyze Each Contract

For each `.sol` file, read the source and extract:

**Category inference (apply in order, first strong match wins):**

| Signal | Category |
|--------|----------|
| In `contracts/libraries/` | `library` |
| In `contracts/core/` + name contains `Controller` | `controller` |
| In `contracts/core/` + name contains `Manager` | `core` |
| In `contracts/core/` + name contains `Storage` | `core` |
| In `contracts/core/` | `core` |
| Name ends with `Factory` | `factory` |
| Name ends with `Escrow` | `escrow` |
| Name ends with `Proxy` and in periphery | `proxy` |
| Name contains `Adapter` | `entrypoint` |
| Name contains `Settler` or `Settlement` | `settlement` |
| Name contains `Wrapper` | `wrapper` |
| Name contains `Hook` | `hook` |
| Name contains `Account` | `account` |
| Name contains `Vending` | `vending-machine` |
| Inherits `ERC4626` or similar vault pattern | `vault` |
| Inherits `TimelockController` | `timelock` |
| Fallback: directory name (`core` or `periphery`) | directory name |

**From NatSpec:**
- `@title` -> use as description basis
- `@notice` on contract -> supplement description
- `@author` -> include if present

**From code structure:**
- `is X, Y, Z` inheritance list -> `inherits` frontmatter field
- `import` statements -> build call graph (what this contract references)
- External/public function names -> "Key Functions" section

**From git:**
- Run `git log --oneline -10 -- <file_path>`
- Include in "Recent Changes" section

### 4. Generate Markdown Files

Create `docs/contracts/` directory if it doesn't exist.

For each contract, write `docs/contracts/<ContractName>.md` using this **exact** format:

```yaml
---
title: ContractName
category: inferred-category
description: "One-line description from NatSpec @title or @notice"
networks:
  sepolia:
    proxy: "0x..."
    implementation: "0x..."
  mainnet:
    proxy: "0x..."
    implementation: "0x..."
inherits:
  - ParentContract1
  - ParentContract2
---
```

**Frontmatter rules:**
- `networks` field: use nested object with chain names as keys. Each chain has `proxy`, `implementation`, or `address` (for non-upgradeable contracts)
- If a contract has NO deployed address in prod.toml, **omit the `networks` field entirely** — do NOT include `networks: []` or `networks: {}`
- `description`: always a single quoted string in the frontmatter
- `inherits`: list contract names only (not interfaces prefixed with `I`)

**Body format:**

```markdown
# ContractName

[Description paragraph derived from NatSpec + code analysis.
What this contract does, why it exists in the protocol.]

## Role

- **Called by:** [contracts/externals that call this]
- **Calls:** [contracts this depends on]

## Key Functions

- `functionName(args)` — brief description from NatSpec or inferred
- `anotherFunction(args)` — description

## Recent Changes

- `abcd1234` commit message 1
- `efgh5678` commit message 2
```

**Do NOT include:**
- A separate "Description" heading — the paragraph after the `# Title` IS the description
- Empty sections — if no git history, omit "Recent Changes" entirely

### 5. Generate Index

Write `docs/contracts/index.md`:

```markdown
---
title: Contract Reference
---

# Cork Protocol — Contract Reference

## Core

| Contract | Category | Sepolia | Mainnet |
|----------|----------|---------|---------|
| [Name](Name.md) | `core` | `0x...` | `0x...` |

## Periphery

| Contract | Category | Sepolia | Mainnet |
|----------|----------|---------|---------|
| [Name](Name.md) | `entrypoint` | `0x...` | `0x...` |

## Libraries

| Contract | Category |
|----------|----------|
| [Name](Name.md) | `library` |
```

**Index rules:**
- Group into: Core, Periphery (all non-core non-library contracts), Libraries
- Within each group, sort alphabetically
- Libraries table has no address columns
- For proxy contracts, show the proxy address (not implementation)
- Contracts with no deployed address: show `—` in address columns

### 6. Summary Report

After generation, **always** output a summary to the user (not to a file):

```
Generated X contract docs in docs/contracts/

Categories: N core, N periphery, N library
Deployed: N contracts with addresses, N without

Unmatched prod.toml keys (no contract file):
  - deployed_timelock_upgrade
  - deployed_timelock_controller_admin
  - ...

Uncertain categories (conflicting signals):
  - WrapperRateConsumer: in periphery/ but acts as core adapter
  - ...
```

**Do NOT skip the summary report.** It is the primary safety mechanism for catching mismatches between prod.toml and the codebase.

## Rules

- Full overwrite every run — never preserve prior content
- Skip `contracts/interfaces/` — reference interfaces in their implementor's docs
- If a contract has no NatSpec, derive description from contract name, inheritance, and function signatures
- Always run git log even for single-contract mode
- Create `docs/contracts/` directory if missing
- When running single-contract mode, regenerate that one file AND update `index.md`
