Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
reviews:
path_filters:
- "!audit/**"
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
result
.env
.env
.fixes
71 changes: 71 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What is Rainix

Rainix is a Nix flake that provides development environments and build tasks for the Rain Protocol ecosystem. It's a shared infrastructure flake consumed by other Rain repos — the actual project code lives in downstream consumers. The `test/fixture/` directory contains example contracts/crates used for CI validation of the flake itself.

## Development Environment

Requires Nix with flakes enabled. Enter the dev shell before working:

```
nix develop # default shell (Solidity + Rust + Node + subgraph tools)
nix develop .#tauri-shell # Tauri desktop app development (macOS-specific quirks)
```

The shell auto-sources `.env` if present and runs `npm ci --ignore-scripts` if `package.json` exists.

## Build Tasks

All tasks are Nix packages run via `nix run`. From a consuming repo (or `test/fixture/`):

### Solidity
- `nix run ..#rainix-sol-prelude` — `forge install && forge build`
- `nix run ..#rainix-sol-test` — `forge test -vvv`
- `nix run ..#rainix-sol-static` — `slither . && forge fmt --check`
- `nix run ..#rainix-sol-legal` — `reuse lint` (REUSE/DCL-1.0 license compliance)
- `nix run ..#rainix-sol-artifacts` — deploy to testnet via `script/Deploy.sol`

### Rust
- `nix run ..#rainix-rs-prelude` — (currently no-op, placeholder for env prep)
- `nix run ..#rainix-rs-test` — `cargo test`
- `nix run ..#rainix-rs-static` — `cargo fmt --all -- --check && cargo clippy --all-targets --all-features -- -D clippy::all`
- `nix run ..#rainix-rs-artifacts` — `cargo build --release`
Comment on lines +22 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The nix run ..#... examples do not match the documented test/fixture/ location.

From test/fixture/, ..# points at test/, not this repo’s flake. These examples are likely broken if copied verbatim from the location named in the intro.

Proposed doc fix
-All tasks are Nix packages run via `nix run`. From a consuming repo (or `test/fixture/`):
+All tasks are Nix packages run via `nix run`.
+
+From `test/fixture/` in this repository:
- `nix run ..#rainix-sol-prelude` — `forge install && forge build`
- `nix run ..#rainix-sol-test` — `forge test -vvv`
- `nix run ..#rainix-sol-static` — `slither . && forge fmt --check`
- `nix run ..#rainix-sol-legal` — `reuse lint` (REUSE/DCL-1.0 license compliance)
- `nix run ..#rainix-sol-artifacts` — deploy to testnet via `script/Deploy.sol`
+- `nix run ../..#rainix-sol-prelude` — `forge install && forge build`
+- `nix run ../..#rainix-sol-test` — `forge test -vvv`
+- `nix run ../..#rainix-sol-static` — `slither . && forge fmt --check`
+- `nix run ../..#rainix-sol-legal` — `reuse lint` (REUSE/DCL-1.0 license compliance)
+- `nix run ../..#rainix-sol-artifacts` — deploy to testnet via `script/Deploy.sol`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` around lines 22 - 35, The nix invocation examples in CLAUDE.md are
incorrect for the stated working directory; when run from test/fixture/ the
prefix "..#..." resolves to test/, not the repository flake. Update the examples
so they point to the correct flake from test/fixture/ (e.g., change the prefix
to "../..#..." for all occurrences like `nix run ..#rainix-sol-prelude`, `nix
run ..#rainix-rs-test`, etc.), or alternatively update the intro to state that
the examples must be run from the repository root and leave the commands as-is;
apply the chosen fix consistently for every `nix run ..#...` example in the
file.


### Subgraph
- `subgraph-build` — forge build + npm ci + graph codegen/build
- `subgraph-test` — `docker compose up` in `./subgraph`
- `subgraph-deploy` — requires `GOLDSKY_TOKEN` and `GOLDSKY_NAME_AND_VERSION`

## Pinned Versions

- Rust: 1.94.0 (with `wasm32-unknown-unknown` target)
- Solidity: solc 0.8.19
- Foundry: via foundry.nix
- Graph CLI: 0.69.2
- Goldsky CLI: 8.6.6
- wasm-bindgen-cli: 0.2.100

## Architecture

The flake exports:
- **`packages`**: All `rainix-*` task derivations plus `tauri-release-env`
- **`devShells`**: `default` (full toolchain) and `tauri-shell` (Tauri + macOS workarounds)
- **Reusable outputs**: `pkgs`, `rust-toolchain`, `rust-build-inputs`, `sol-build-inputs`, `node-build-inputs`, `mkTask`, `network-list` — consumed by downstream Rain flakes to compose their own tasks/shells

`mkTask` is the core abstraction: it creates self-contained Nix derivations wrapping shell scripts with their dependencies on `PATH`.

## CI

Defined in `.github/workflows/`:
- **test.yml** — runs sol and rs tasks against `test/fixture/` on Ubuntu + macOS (ARM only; sol tasks Ubuntu-only)
- **check-shell.yml** — verifies dev shell tools are available
- **pr-assessment.yaml** — PR size assessment

## Code Style

- Rust: `cargo fmt` and `cargo clippy` with all warnings denied (`-D clippy::all`)
- Solidity: `forge fmt` and `slither` static analysis
- License: DecentraLicense 1.0, enforced via `reuse lint`
5 changes: 4 additions & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ path = [
".gitignore",
".gitmodules",
"REUSE.toml",
"CLAUDE.md",
".coderabbit.yaml",
".github/**/",
".vscode/**/",
"test/**/"
"test/**/",
"audit/**/"
]
SPDX-FileCopyrightText = "Copyright (c) 2020 thedavidmeister"
SPDX-License-Identifier = "LicenseRef-DCL-1.0"
42 changes: 42 additions & 0 deletions audit/2026-03-12-01/pass0/process.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Pass 0: Process Review

## Evidence of thorough reading

### CLAUDE.md
Comment on lines +4 to +5
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add blank line before heading for markdown compliance.

Markdown best practices require blank lines around headings for better readability and parser compatibility.

📝 Proposed formatting fix
 ## Evidence of thorough reading
 
 ### CLAUDE.md
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 5-5: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass0/process.md` around lines 4 - 5, Add a blank line
immediately before the "### CLAUDE.md" heading in process.md so the heading is
separated from the preceding content; locate the "### CLAUDE.md" heading and
insert a single empty line above it to comply with Markdown heading spacing
rules.

- Sections: What is Rainix, Development Environment, Build Tasks (Solidity, Rust, Subgraph), Pinned Versions, Architecture, CI, Code Style
- Line 7: project description
- Lines 14-15: dev shell commands
- Lines 18: shell auto-source behavior
- Lines 25-29: Solidity tasks
- Lines 32-35: Rust tasks
- Lines 38-40: Subgraph tasks
- Lines 44-49: Pinned versions
- Lines 53-58: Architecture description
- Lines 62-65: CI workflows
- Lines 69-71: Code style

## Findings

### A01-1 [LOW] Inaccurate CI platform description

**File:** CLAUDE.md:63

The CLAUDE.md states test.yml runs on "Ubuntu + macOS (Intel & ARM)". However, test.yml only uses `ubuntu-latest` and `macos-latest` — it does not include `macos-13` (Intel). The Intel + Apple Silicon matrix is only in `check-shell.yml`. A future session relying on this could incorrectly assume Rust tests run on Intel macOS.

### A01-2 [LOW] Task path prefix varies by working directory but documentation uses single prefix

**File:** CLAUDE.md:22-29

Tasks are documented as `nix run ..#rainix-sol-test` (single `..`), which is correct from a direct consumer repo. But from `test/fixture/` (the only runnable location in this repo), the actual invocation is `nix run ../..#rainix-sol-test` (double `../..`), as confirmed in `.github/workflows/test.yml:50`. The note "From a consuming repo (or `test/fixture/`)" doesn't clarify that the path prefix differs.

### A01-3 [LOW] Subgraph tasks not runnable via `nix run`

**File:** CLAUDE.md:38-40

Subgraph tasks (`subgraph-build`, `subgraph-test`, `subgraph-deploy`) are listed under the "Build Tasks" section that opens with "All tasks are Nix packages run via `nix run`." However, these tasks are not exported in `packages` — they're only available on `PATH` inside the dev shell. A future session could attempt `nix run ..#subgraph-build` and fail.

### A01-4 [INFO] Required environment variables for artifact deployment not documented

**File:** CLAUDE.md:29

`rainix-sol-artifacts` requires `DEPLOYMENT_KEY`, `ETH_RPC_URL`, and optionally `ETHERSCAN_API_KEY`, `DEPLOY_BROADCAST`, `DEPLOY_VERIFY`, `DEPLOY_VERIFIER`, `DEPLOY_VERIFIER_URL`, `DEPLOY_LEGACY`. None are mentioned. Similarly, subgraph-deploy requires `GOLDSKY_TOKEN` and `GOLDSKY_NAME_AND_VERSION` (this one is documented). A future session attempting deployment would need to discover these from the flake source.
17 changes: 17 additions & 0 deletions audit/2026-03-12-01/pass1/Counter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Pass 1: Security — Counter.sol

## Evidence of thorough reading

**File:** test/fixture/src/Counter.sol (15 lines)

### Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
Comment on lines +3 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Evidence section omits pragma version.

The "Evidence of thorough reading" section does not mention the pragma version (pragma solidity ^0.8.25; at line 3 of Counter.sol), despite it being the first substantive code line. This is particularly notable given that Pass 4 documents pragma version consistency issues across the fixture files. Including the pragma version in the evidence section would demonstrate more thorough documentation.

📝 Suggested enhancement
 ## Evidence of thorough reading
 
 **File:** test/fixture/src/Counter.sol (15 lines)
+
+- Pragma: solidity ^0.8.25 (line 3)
 
 ### Contract: Counter (line 5)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Evidence of thorough reading
**File:** test/fixture/src/Counter.sol (15 lines)
### Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
## Evidence of thorough reading
**File:** test/fixture/src/Counter.sol (15 lines)
- Pragma: solidity ^0.8.25 (line 3)
### Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass1/Counter.md` around lines 3 - 10, The Evidence
section for the Counter contract omits the Solidity pragma; update the "Evidence
of thorough reading" entry in Counter.md to include the pragma declaration found
in test/fixture/src/Counter.sol (the line containing "pragma solidity ^0.8.25;")
so the evidence lists the pragma version alongside the state variable `number`
and functions `setNumber` and `increment`, e.g. add a bullet or sentence noting
the pragma version string to ensure pragma presence is documented.


### Types/errors/constants
- None

## Findings

No security findings. This is a test fixture contract. `setNumber` has no access control, which is intentional for a CI validation fixture. Arithmetic overflow in `increment()` is handled by Solidity 0.8+ built-in checks.
18 changes: 18 additions & 0 deletions audit/2026-03-12-01/pass1/Counter.t.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Pass 1: Security — Counter.t.sol

## Evidence of thorough reading

**File:** test/fixture/test/Counter.t.sol (25 lines)

### Contract: CounterTest is Test (line 8)
- State variable: `counter` (Counter, public) — line 9
- Function: `setUp()` — line 11
- Function: `test_Increment()` — line 16
- Function: `testFuzz_SetNumber(uint256 x)` — line 21

### Types/errors/constants
- None

## Findings

No security findings. Standard Foundry test contract.
16 changes: 16 additions & 0 deletions audit/2026-03-12-01/pass1/Deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Pass 1: Security — Deploy.sol

## Evidence of thorough reading

**File:** test/fixture/script/Deploy.sol (13 lines)

### Contract: Deploy is Script (line 7)
- Function: `setUp()` — line 8 (empty)
- Function: `run()` — line 10 (calls vm.broadcast() with no deployment actions)

### Types/errors/constants
- None

## Findings

No security findings. Empty deployment script fixture — `vm.broadcast()` with no subsequent calls is a no-op.
54 changes: 54 additions & 0 deletions audit/2026-03-12-01/pass1/flake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Pass 1: Security — flake.nix

## Evidence of thorough reading

**File:** flake.nix (414 lines)

### Inputs (lines 4-12)
- nixpkgs, flake-utils, rust-overlay, foundry, solc, nixpkgs-old

### Let bindings (lines 17-163)
- `wasm-bindgen-overlay` (line 17): overlay pinning wasm-bindgen-cli to 0.2.100
- `overlays` (line 20): combined overlay list
- `pkgs` (line 21): nixpkgs with overlays
- `old-pkgs` (line 22): pinned old nixpkgs
- `rust-version` (line 24): "1.94.0"
- `rust-toolchain` (line 25): stable rust with wasm32 target and extensions
- `rust-build-inputs` (line 31): list of rust build dependencies
- `sol-build-inputs` (line 48): list of solidity build dependencies
- `node-build-inputs` (line 56): nodejs_22
- `network-list` (line 57): ["base" "flare"]
- `the-graph` (line 58): mkDerivation for graph CLI 0.69.2, fetched by URL+SHA per system
- `goldsky` (line 90): mkDerivation for goldsky CLI 8.6.6, fetched by URL+SHA per system
- `tauri-build-inputs` (line 123): tauri dependencies including old-pkgs
- `tauri-release-env` (line 141): buildEnv for tauri releases
- `mkTask` (line 151): helper to create wrapped script derivations
- `rainix-sol-prelude` (line 165): forge install + build
- `rainix-sol-static` (line 180): slither + forge fmt --check
- `rainix-sol-legal` (line 190): reuse lint
- `rainix-sol-test` (line 199): forge test -vvv
- `rainix-sol-artifacts` (line 208): deploy with retry loop (up to 10 attempts)
- `rainix-rs-prelude` (line 253): no-op
- `rainix-rs-static` (line 261): cargo fmt + clippy
- `rainix-rs-test` (line 271): cargo test
- `rainix-rs-artifacts` (line 280): cargo build --release
- `rainix-tasks` (line 289): aggregated task list
- `subgraph-build` (line 302): forge build + npm ci + graph codegen/build
- `subgraph-test` (line 315): docker compose up
- `subgraph-deploy` (line 323): subgraph-build + goldsky deploy
- `subgraph-tasks` (line 333): aggregated subgraph task list
- `source-dotenv` (line 335): sources .env if present
- `tauri-shellhook-test` (line 343): BATS test runner (Darwin-only)

### Outputs (lines 354-413)
- `packages` (line 364): all rainix-* tasks + tauri-release-env
- `devShells.default` (line 371): full dev shell
- `devShells.tauri-shell` (line 385): tauri-specific dev shell with macOS workarounds

### Types/constants
- `network-list`: ["base" "flare"]
- `rust-version`: "1.94.0"

## Findings

No security findings. External binaries (graph CLI, goldsky) are fetched with SHA256 pins preventing MITM. Shell scripts use `set -euxo pipefail`. Environment variable interpolation uses Nix `''${}` escaping. `.env` sourcing is guarded by file existence check and `.env` is gitignored.
15 changes: 15 additions & 0 deletions audit/2026-03-12-01/pass1/main.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Pass 1: Security — main.rs

## Evidence of thorough reading

**File:** test/fixture/crates/test-rs/src/main.rs (3 lines)

### Module: (crate root)
- Function: `main()` — line 1

### Types/errors/constants
- None

## Findings

No security findings. Hello world program.
20 changes: 20 additions & 0 deletions audit/2026-03-12-01/pass1/shellhook.test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Pass 1: Security — shellhook.test.bats

## Evidence of thorough reading

**File:** test/bats/devshell/tauri/shellhook.test.bats (32 lines)

### Tests
- `/usr/bin should be in PATH` — line 1
- `nixpkgs apple_sdk xcrun should NOT be in PATH` — line 5
- `should have access to native macos xcrun` — line 9
- `should have access to native macos SetFile bin through native macos xcrun` — line 18
- `should have access to native macos SetFile bin through /usr/bin in PATH` — line 24
- `DEVELOPER_DIR should be unset` — line 30

### Types/errors/constants
- None

## Findings

No security findings. Shell environment validation tests for macOS Tauri dev shell.
29 changes: 29 additions & 0 deletions audit/2026-03-12-01/pass2/Counter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Pass 2: Test Coverage — Counter.sol

## Evidence of thorough reading

### Source: test/fixture/src/Counter.sol (15 lines)
- Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12

### Test: test/fixture/test/Counter.t.sol (25 lines)
- Contract: CounterTest is Test (line 8)
- Function: `setUp()` — line 11: creates Counter, sets number to 0
- Function: `test_Increment()` — line 16: increments once, asserts == 1
- Function: `testFuzz_SetNumber(uint256 x)` — line 21: fuzz sets number, asserts
Comment on lines +5 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Separate both ### headings from their lists.

This report currently triggers MD022 on the Source and Test sections because both lists start immediately under their headings.

📝 Proposed doc fix
 ### Source: test/fixture/src/Counter.sol (15 lines)
+
 - Contract: Counter (line 5)
 - State variable: `number` (uint256, public) — line 6
 - Function: `setNumber(uint256 newNumber)` — line 8
 - Function: `increment()` — line 12
 
 ### Test: test/fixture/test/Counter.t.sol (25 lines)
+
 - Contract: CounterTest is Test (line 8)
 - Function: `setUp()` — line 11: creates Counter, sets number to 0
 - Function: `test_Increment()` — line 16: increments once, asserts == 1
 - Function: `testFuzz_SetNumber(uint256 x)` — line 21: fuzz sets number, asserts
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Source: test/fixture/src/Counter.sol (15 lines)
- Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
### Test: test/fixture/test/Counter.t.sol (25 lines)
- Contract: CounterTest is Test (line 8)
- Function: `setUp()` — line 11: creates Counter, sets number to 0
- Function: `test_Increment()` — line 16: increments once, asserts == 1
- Function: `testFuzz_SetNumber(uint256 x)` — line 21: fuzz sets number, asserts
### Source: test/fixture/src/Counter.sol (15 lines)
- Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
### Test: test/fixture/test/Counter.t.sol (25 lines)
- Contract: CounterTest is Test (line 8)
- Function: `setUp()` — line 11: creates Counter, sets number to 0
- Function: `test_Increment()` — line 16: increments once, asserts == 1
- Function: `testFuzz_SetNumber(uint256 x)` — line 21: fuzz sets number, asserts
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 7-7: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass2/Counter.md` around lines 5 - 15, Add a blank line
between each "###" heading and its following list to satisfy MD022: insert an
empty line after the headings "### Source: test/fixture/src/Counter.sol (15
lines)" and "### Test: test/fixture/test/Counter.t.sol (25 lines)" so the bullet
lists under those headings do not start immediately on the next line.


## Findings

### A01-1 [LOW] No test for increment overflow behavior

**File:** test/fixture/test/Counter.t.sol

`test_Increment` only tests incrementing from 0 to 1. There is no test verifying that `increment()` reverts when `number` is `type(uint256).max`. While Solidity 0.8+ guarantees overflow reverts, an explicit test documents this expected behavior and would catch regressions if the contract were modified to use `unchecked`.

### A01-2 [LOW] No test for consecutive increments

**File:** test/fixture/test/Counter.t.sol

`test_Increment` calls `increment()` once from 0. There is no test verifying multiple consecutive increments (e.g., increment from 0 to N) to exercise accumulation behavior.
15 changes: 15 additions & 0 deletions audit/2026-03-12-01/pass2/Deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Pass 2: Test Coverage — Deploy.sol

## Evidence of thorough reading

### Source: test/fixture/script/Deploy.sol (13 lines)
- Contract: Deploy is Script (line 7)
- Function: `setUp()` — line 8 (empty)
- Function: `run()` — line 10 (calls vm.broadcast() only)

### Test files: None found
- Grepped for "Deploy" across test/ directory — only referenced in CI workflow, not tested directly
Comment on lines +10 to +11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inaccurate claim about Deploy.sol reference location.

Line 11 states that Deploy is "only referenced in CI workflow, not tested directly." However, the relevant code snippet shows that Deploy.sol is actually invoked in flake.nix (lines 210-245) within the rainix-sol-artifacts task via forge script script/Deploy.sol:Deploy. The CI workflow references the flake task, not Deploy.sol directly.

📝 Suggested correction
 ### Test files: None found
-- Grepped for "Deploy" across test/ directory — only referenced in CI workflow, not tested directly
+- Grepped for "Deploy" across test/ directory — invoked via flake.nix rainix-sol-artifacts task, not tested directly
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass2/Deploy.md` around lines 10 - 11, Update the
inaccurate statement that "Deploy is only referenced in CI workflow, not tested
directly" to reflect that Deploy.sol is invoked via flake.nix: the
`rainix-sol-artifacts` task in flake.nix calls `forge script
script/Deploy.sol:Deploy`, and the CI workflow triggers that flake task rather
than calling Deploy.sol directly; reference the symbols Deploy.sol, flake.nix,
rainix-sol-artifacts, and the `forge script script/Deploy.sol:Deploy` invocation
in the corrected text.


## Findings

No findings. This is an intentionally empty deployment script fixture used only to validate the CI deploy pipeline. Testing an empty `vm.broadcast()` call adds no value.
25 changes: 25 additions & 0 deletions audit/2026-03-12-01/pass2/flake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Pass 2: Test Coverage — flake.nix

## Evidence of thorough reading

### Source: flake.nix (414 lines)
- See Pass 1 flake.md for complete function/binding inventory

### Test files:
- `.github/workflows/test.yml` — runs rainix-sol-*, rainix-rs-* tasks against test/fixture/
- `.github/workflows/check-shell.yml` — verifies dev shell tool availability
- `test/bats/devshell/tauri/shellhook.test.bats` — validates tauri shell environment
Comment on lines +5 to +11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Refresh the flake metadata and heading spacing.

flake.nix in this PR is 416 lines, not 414, and both ### headings need a blank line below them to clear MD022. If these reports are generated, this looks worth fixing at the template level too.

📝 Proposed doc fix
-### Source: flake.nix (414 lines)
+### Source: flake.nix (416 lines)
+
 - See Pass 1 flake.md for complete function/binding inventory
 
 ### Test files:
+
 - `.github/workflows/test.yml` — runs rainix-sol-*, rainix-rs-* tasks against test/fixture/
 - `.github/workflows/check-shell.yml` — verifies dev shell tool availability
 - `test/bats/devshell/tauri/shellhook.test.bats` — validates tauri shell environment
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Source: flake.nix (414 lines)
- See Pass 1 flake.md for complete function/binding inventory
### Test files:
- `.github/workflows/test.yml` — runs rainix-sol-*, rainix-rs-* tasks against test/fixture/
- `.github/workflows/check-shell.yml` — verifies dev shell tool availability
- `test/bats/devshell/tauri/shellhook.test.bats` — validates tauri shell environment
### Source: flake.nix (416 lines)
- See Pass 1 flake.md for complete function/binding inventory
### Test files:
- `.github/workflows/test.yml` — runs rainix-sol-*, rainix-rs-* tasks against test/fixture/
- `.github/workflows/check-shell.yml` — verifies dev shell tool availability
- `test/bats/devshell/tauri/shellhook.test.bats` — validates tauri shell environment
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 5-5: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 8-8: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass2/flake.md` around lines 5 - 11, Update the flake
report headings: correct "### Source: flake.nix (414 lines)" to reflect the
actual 416 lines, and ensure there is a blank line after both "### Source:
flake.nix (416 lines)" and "### Test files:" headings to satisfy MD022; modify
the template or generator that produces those headings (the strings "### Source:
flake.nix (… lines)" and "### Test files:") so it inserts a newline after each
heading and computes the file length from the current flake.nix when rendering.


## Findings

### A02-1 [LOW] No CI coverage for subgraph tasks

**File:** .github/workflows/

`subgraph-build`, `subgraph-test`, and `subgraph-deploy` are defined in the flake but have no CI workflow exercising them. While subgraph-test requires Docker and subgraph-deploy requires tokens, subgraph-build could be validated in CI (it just runs forge build + npm ci + graph codegen/build).

### A02-2 [LOW] Default dev shell not tested in check-shell.yml

**File:** .github/workflows/check-shell.yml

`check-shell.yml` tests specific tool availability (`cargo release`, `flamegraph`, `graph`, `goldsky`) and the tauri shell hook, but does not test basic dev shell entry (`nix develop --command true`) or verify that the default shell's `shellHook` (which runs `npm ci`) succeeds. If a nixpkgs update breaks the shell derivation, there's no direct CI signal.
13 changes: 13 additions & 0 deletions audit/2026-03-12-01/pass2/main.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Pass 2: Test Coverage — main.rs

## Evidence of thorough reading

### Source: test/fixture/crates/test-rs/src/main.rs (3 lines)
- Function: `main()` — line 1 (prints "Hello, world!")

### Test files: None found
- No `tests/` directory, no `#[cfg(test)]` module, no `*_test.rs` files in the crate

## Findings

No findings. This is a hello-world fixture crate used only to validate that `cargo test` and `cargo build --release` work in CI. The crate has no logic to test.
13 changes: 13 additions & 0 deletions audit/2026-03-12-01/pass3/Counter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Pass 3: Documentation — Counter.sol

## Evidence of thorough reading

### Source: test/fixture/src/Counter.sol (15 lines)
- Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
Comment on lines +5 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a blank line below the ### Source heading.

This file currently triggers MD022 because the list starts immediately under the heading.

📝 Proposed doc fix
 ### Source: test/fixture/src/Counter.sol (15 lines)
+
 - Contract: Counter (line 5)
 - State variable: `number` (uint256, public) — line 6
 - Function: `setNumber(uint256 newNumber)` — line 8
 - Function: `increment()` — line 12
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Source: test/fixture/src/Counter.sol (15 lines)
- Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
### Source: test/fixture/src/Counter.sol (15 lines)
- Contract: Counter (line 5)
- State variable: `number` (uint256, public) — line 6
- Function: `setNumber(uint256 newNumber)` — line 8
- Function: `increment()` — line 12
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 5-5: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass3/Counter.md` around lines 5 - 9, The file's "###
Source: test/fixture/src/Counter.sol (15 lines)" heading is immediately followed
by a list, triggering MD022; open Counter.md and insert a single blank line
directly below the "### Source: test/fixture/src/Counter.sol (15 lines)" heading
so the subsequent list items (e.g., "Contract: Counter", "State variable:
`number`", "Function: `setNumber(uint256 newNumber)`", "Function:
`increment()`") are separated from the heading.


## Findings

No findings. This is a minimal test fixture. NatSpec documentation on a CI validation fixture would add no value.
13 changes: 13 additions & 0 deletions audit/2026-03-12-01/pass3/Counter.t.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Pass 3: Documentation — Counter.t.sol

## Evidence of thorough reading

### Source: test/fixture/test/Counter.t.sol (25 lines)
- Contract: CounterTest is Test (line 8)
Comment on lines +5 to +6
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a blank line after the Source heading.

This page also violates markdownlint MD022.

Proposed fix
 ### Source: test/fixture/test/Counter.t.sol (25 lines)
+
 - Contract: CounterTest is Test (line 8)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Source: test/fixture/test/Counter.t.sol (25 lines)
- Contract: CounterTest is Test (line 8)
### Source: test/fixture/test/Counter.t.sol (25 lines)
- Contract: CounterTest is Test (line 8)
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 5-5: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass3/Counter.t.md` around lines 5 - 6, Add a single
blank line after the "Source:" heading in the Counter.t.md file so the heading
block is separated from the following content (e.g., between "### Source:
test/fixture/test/Counter.t.sol" and the "Contract: CounterTest is Test" line)
to satisfy markdownlint MD022.

- Function: `setUp()` — line 11
- Function: `test_Increment()` — line 16
- Function: `testFuzz_SetNumber(uint256 x)` — line 21

## Findings

No findings. Test names are self-documenting.
Comment on lines +11 to +13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Scope this to documentation findings.

No findings reads as a blanket conclusion, but the same source file has a recorded Pass 4 code-quality finding for the unused console2 import. Clarify this as No documentation findings or explicitly defer non-documentation issues to later passes to avoid cross-pass contradiction.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit/2026-03-12-01/pass3/Counter.t.md` around lines 11 - 13, Update the
summary line in Counter.t.md so it only asserts documentation-related results:
replace the blanket "No findings" with "No documentation findings" or add a
short qualifier like "No documentation findings; code-quality issues (e.g.,
unused symbol console2) are deferred to Pass 4" so the statement no longer
contradicts the recorded Pass 4 code-quality finding for console2.

Loading
Loading