caliperforge/cf-invariants-anchor

GitHub: caliperforge/cf-invariants-anchor

cf-invariants-anchor:基于AI的Solana智能合约属性生成与验证工具

Stars: 1 | Forks: 0

# cf-invariants-anchor [![ci](https://static.pigsec.cn/wp-content/uploads/repos/cas/99/993938d8ce5e902ccfb9d6747725c320d855dea3235ed9a304cedf0d94c9321f.svg)](https://github.com/caliperforge/cf-invariants-anchor/actions/workflows/ci.yml) **Solana / Anchor 上 [Crucible](https://github.com/asymmetric-research/crucible) 和 [Trident](https://github.com/Ackee-Blockchain/trident) 的 AI 不变量编写工具。** cf-invariants-anchor 是两个用于 Solana 程序的开源不变量模糊测试 harness 的*附属工具*: - **Crucible** (Asymmetric Research, MIT, LibAFL + LiteSVM, v0.2.0) — 主要的生成目标。 - **Trident** (Ackee Blockchain, MIT) — 次要的生成目标(在 Phase 1 阶段推出)。 我们**不会重构 harness**。Crucible 和 Trident 已经拥有了 LiteSVM 执行轨道以及基于 IDL 驱动的程序模糊测试 底层架构。尚未被覆盖的领域——也是本 crate 唯一 提供的功能——是位于它们之上的 **AI 建议不变量编写工具**: 接收一个 Anchor IDL,从类库中提出排序后的候选不变量(Phase 0 包含余额守恒;路线图中包含单调性、 访问控制、预言机时效性),并生成一个 可直接运行的包含 `#[fuzz_fixture]` + `#[invariant_test]` 的 源代码文件,供 Crucible 使用。 本包是针对 Cairo 的 [cf-invariants](../cf-invariants/) (Starknet / snforge) 的 Anchor 配套版本,由 同一运营商发布。 ## 状态 **Phase 0 — 可用工件,1.0 之前版本。** 本构建中已上线的功能: - `cf-invariants-anchor ingest ` — 将 Anchor 0.30 / Codama 风格的 IDL JSON 解析为类型化的合约接口(程序 id、指令、 每个存储账户的标量余额字段)。 - `cf-invariants-anchor suggest ` — 通过启发式建议器生成排序后的 候选不变量列表。**目前已提供三个类别**:`balance_conservation`、`monotonic_accounting`、 `access_control`。`InvariantClass` trait + `ClassRegistry` 使得 添加第四个(预言机/时效性)只需修改一个文件即可。 - `cf-invariants-anchor suggest --ai` — 通过 `cf-invariants-anchor-ai` 路由以获取 AI 建议的候选项。每个返回的 候选项都带有 `InvariantSource::AiSuggested { model, prompt_version, timestamp_utc }`;一条 JSON 审计日志条目会被写入 `.cf-invariants-anchor/ai-log/.json`(包含 token 计数、 美元成本、响应的 SHA-256)。默认传输方式为 `MockTransport` (确定性、无需 API key、CI 安全);当 CLI 使用 `--features live-ai` 构建且设置了 `CF_INVARIANTS_ANCHOR_AI_LIVE=1` 和 `ANTHROPIC_API_KEY` 时,将激活 `LiveAnthropicTransport`。 - `cf-invariants-anchor emit --target crucible` — 为选定的候选项渲染 兼容 Crucible 的模糊测试 fixture。每个 类别都有其自己的生成形态:余额使用 fixture 端账本 + `fuzz_assert_eq!`;单调性使用 `last_seen_*` 快照 + `fuzz_assert_le!`; 访问控制使用攻击者密钥对探测 + 粘滞标志断言。 - `--target trident` — Phase-1 存根。生成操作会返回一个解释性的 占位符,以便在尚未接入 Trident 渲染的情况下仍能访问 CLI 接口。 - **三对参考合约**,每个发布的类别一对: - `references/vault_ref{,_planted}` — `balance_conservation`。植入漏洞的提款操作转移了 `amount` lamports,但将 `vault.amount` 减去了 `amount-1`;守恒不变量能在 1 次提款中捕捉到 这种偏差。 - `references/counter_ref{,_planted}` — `monotonic_accounting`。添加了一个 `lifetime_deposited: u64` 棘轮字段;植入漏洞的提款操作在每次调用时都会递减它,导致终身计数器倒退。 - `references/admin_ref{,_planted}` — `access_control`。无漏洞的 提款操作强制要求 `seeds = [b"vault", depositor.key().as_ref()]` 且 `has_one = depositor`;植入漏洞的变体删除了这两个限制,因此任何 签名者都可以抽干任何 vault PDA。生成的攻击者探测 fixture 会在第一次成功的未授权提款时触发异常。 - **记分卡渲染器**,每当 `ai_suggestions_included > 0` 时,就会输出 AI 披露横幅。默认的参考运行 使用启发式来源,因此这些 记分卡上的横幅处于休眠状态(渲染器路径已通过测试覆盖); `--ai` 标志会触发该横幅。 - 工作区测试套件(36 个测试,`cargo test --workspace`)。 ## 它不包含什么 - **不是 Crucible 或 Trident 的分支。**两者均作为上游 依赖项提供;cf-invariants-anchor 仅负责编写不变量。 - **不是形式化验证工具。**属于随机化不变量搜索, 而非数学证明。 - **不能替代手动编写的不变量。**AI / 启发式 候选项始终被标记为 `UNVERIFIED`,直到合约 作者接受它们。 ## 架构 `cf-invariants-anchor` 是一个包含五个 Rust crate 的 Cargo 工作区: ``` crates/ cf-invariants-anchor-cli/ # binary cf-invariants-anchor-core/ # shared types: ContractSurface, InvariantCandidate, Scorecard cf-invariants-anchor-idl/ # Anchor IDL parser → ContractSurface cf-invariants-anchor-suggest/ # ClassRegistry + balance_conservation suggester cf-invariants-anchor-emit/ # Render to Crucible / Trident-stub source cf-invariants-anchor-report/ # Scorecard markdown + JSON renderer references/ vault_ref{,_planted}/ # balance_conservation pair counter_ref{,_planted}/ # monotonic_accounting pair admin_ref{,_planted}/ # access_control pair findings/ vault_ref_{clean,planted}/ # scorecard.expected.md + CI capture counter_ref_{clean,planted}/ # scorecard.expected.md + CI capture admin_ref_{clean,planted}/ # scorecard.expected.md + CI capture docs/ architecture.md # design, emit-target abstraction, Crucible API record ai-disclosure.md # AI involvement, disclosure path, audit log scripts/ run_phase0_harness.sh # reproduce-from-clone driver prompts/ invariant_suggestion_v1.txt # versioned prompt (Phase 1 AI path) ``` ## 固定工具链 这些是 CI 在每次推送时构建所依据的版本(参见 [`.github/workflows/ci.yml`](./.github/workflows/ci.yml))。所有版本 锁定均已根据上游 tag 的 `Cargo.toml` 进行了经验性验证, 而非仅从代码结构粗略估计: - Rust **stable** (工作区 MSRV: `1.79`)。 - `anchor-lang` **1.0.1** — 与 Crucible v0.2.0 的工作区匹配 (`asymmetric-research/crucible @ v0.2.0` 锁定了 `anchor-lang = "1.0.1"`)。 - Anza / Solana CLI **v2.1.21**,用于 `cargo-build-sbf`。 - Solana platform-tools **v1.52**(Crucible v0.2.0 的依赖项需要 edition2024 支持;早期的 platform-tools 附带 rustc 1.84,无法 构建它们 — 通过 `--tools-version v1.52` 传递)。 - 上游 Crucible **v0.2.0** 在 CI 中通过源码构建 (`cargo install --path crates/crucible-fuzz-cli`)。 模糊测试的 `Cargo.toml` 通过路径依赖引用 Crucible,位于 `../../../../../crucible/crates/crucible-fuzzer` — CI 将 Crucible 克隆到 `/../crucible`,因此该路径能够正确解析。如需在本地 重现,要么将 Crucible 克隆到该路径,要么本地化引入这两个 crate 并编辑 模糊测试的 Cargo.tomls。 参见 [`.tool-versions`](./.tool-versions)(仅供参考;以 CI 为准)。 ## 安装 ``` cargo install --path crates/cf-invariants-anchor-cli ``` ## 快速开始 ``` # Ingest 一个 Anchor IDL。 cf-invariants-anchor ingest references/vault_ref/idls/vault_ref.json # 向 suggester 请求排序后的候选 invariant。 cf-invariants-anchor suggest references/vault_ref/idls/vault_ref.json # 生成一个 Crucible #[fuzz_fixture] + #[invariant_test] 文件。 cf-invariants-anchor emit references/vault_ref/idls/vault_ref.json \ --target crucible \ --out references/vault_ref/fuzz/vault_ref/src/main.rs ``` ## 端到端 Phase 0 演示 CI 每次推送时都会准确运行此流程;本地重现是可选的。参见 [`scripts/run_phase0_harness.sh`](./scripts/run_phase0_harness.sh) 获取 规范的驱动程序。 ``` # 1. 构建干净的参考程序及其植入 twin (SBPF)。 cargo build-sbf --tools-version v1.52 \ --manifest-path references/vault_ref/programs/vault_ref/Cargo.toml cargo build-sbf --tools-version v1.52 \ --manifest-path references/vault_ref_planted/programs/vault_ref/Cargo.toml # 2. 生成 conservation invariant(已在此 repo 中预先生成)。 cf-invariants-anchor emit references/vault_ref/idls/vault_ref.json \ --target crucible \ --out references/vault_ref/fuzz/vault_ref/src/main.rs cp references/vault_ref/fuzz/vault_ref/src/main.rs \ references/vault_ref_planted/fuzz/vault_ref/src/main.rs # 3. 针对两个 variants 运行 Crucible(timeout 足够小以适用于 CI; # 植入 bug 的最小 counterexample 为 2 个 action 并且会快速触发)。 (cd references/vault_ref/fuzz/vault_ref && \ crucible run vault_ref invariant_amount_conservation --release --timeout 30) (cd references/vault_ref_planted/fuzz/vault_ref && \ crucible run vault_ref invariant_amount_conservation --release --timeout 30) ``` CI 工作流将这些运行的真实输出捕获到 `findings/vault_ref_{clean,planted}/scorecard.md` 中,并将其作为 `crucible-scorecards` 构建产物上传。同级的 `scorecard.expected.{json,md}` 文件作为编写的参考保留,以便进行差异对比。 ## 路线图 | 阶段 | 范围 | |-------|---------| | **0** | IDL 接收 → 排序后的余额守恒候选 → Crucible 生成 → 记分卡渲染器。仅包含启发式建议器。✅ 已发布。 | | **1** | AI 建议的不变量上线(Anthropic Claude Sonnet 路径:默认为 MockTransport,在 `--features live-ai` + 环境变量后启用 LiveAnthropicTransport)。单调性 + 访问控制类别已添加到建议器 + 生成器中。✅ 已发布。 | | **2 (当前构建)** | `counter_ref`(单调性)+ `admin_ref`(访问控制)参考对,包含 CI Crucible 证明 — 每个新类别都能在 `clean=0 / planted≥1` 下捕获其植入的漏洞。✅ 已入库;下次推送时基于 CI 绿色状态进行门控。 | | 3 | Trident 生成目标。预言机时效性类别。CI 记分卡偏差预警。缩减。多账户状态范围(使用完整的账户可变性集合分析代替名称启发式)。 | ## 报告问题与安全联系 在 GitHub 仓库中提交 issue,或联系 [team@caliperforge.com](mailto:team@caliperforge.com)。 对于涉及 cf-invariants-anchor 本身的敏感安全披露, 请直接联系 [michael@caliperforge.com](mailto:michael@caliperforge.com)。 ## 许可证 Apache-2.0。参见 `LICENSE`。 cf-invariants-anchor 由 Michael Moffett 以 CaliperForge 的名义运营。CaliperForge 是一家个人运营的工程工作室。 在 AI 辅助下构建。由 CaliperForge 的运营者 Michael Moffett 编写和审查。完整政策请访问 [caliperforge.com/ai-disclosure](https://caliperforge.com/ai-disclosure)。关于 AI 模块的功能、审计日志路径以及如何禁用它的仓库内详细信息,请参见 [`docs/ai-disclosure.md`](./docs/ai-disclosure.md)。 [caliperforge.com](https://caliperforge.com)
标签:通知系统