{"owner":"foundry-rs","repo":"foundry","hasSkills":true,"totalSkillsCount":2,"totalTokensCount":5095,"categories":["root-instruction","cursor-rule"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md",".cursorrules (solidity-foundry-cursorrules-prompt-file.mdc)"],"skills":{"AGENTS.md":"# AGENTS.md\n\nGuidance for AI coding agents working in this repository.\n\n## Project Overview\n\nFoundry is a fast, portable, modular toolkit for Ethereum application development,\nwritten in Rust.\n\n- `forge`: build, test, fuzz, debug, lint, and deploy Solidity contracts\n- `cast`: command-line utilities for EVM contracts, transactions, and chain data\n- `anvil`: local Ethereum development node\n- `chisel`: Solidity REPL\n\nThe repository is a Cargo workspace. Core crates live under `crates/`, Solidity\nfixtures and integration test projects live under `testdata/`, and the\n[developer documentation](docs/dev/README.md) defines documentation ownership\nand indexes maintained cross-crate guides.\n\n## Commands\n\n```bash\ncargo build --workspace                               # Build the workspace\ncargo nextest run --workspace                         # Run tests\ncargo +nightly fmt --all                              # Format Rust code\ncargo +nightly fmt --all -- --check                   # Check Rust formatting\ncargo +nightly clippy --workspace --all-targets --all-features # Lint Rust code\ncargo deny check                                      # Check dependencies\ncargo shear                                           # Check unused dependencies\n```\n\nRust formatting uses nightly.\n\n## Architecture\n\n- `crates/forge`: Forge CLI and test/build workflows\n- `crates/cast`: Cast CLI commands\n- `crates/anvil`: local Ethereum node\n- `crates/chisel`: Solidity REPL\n- `crates/cheatcodes`: Forge cheatcode definitions and implementations\n- `crates/common`: shared CLI, shell, compile, and terminal utilities\n- `crates/config`: Foundry configuration\n- `crates/debugger`: debugger support\n- `crates/lint`: Solidity linter\n- `crates/script`: script execution support\n- `crates/verify`: contract verification support\n\nFoundry's EVM execution tooling is built around `revm`. Cheatcodes are calls to\nthe fixed cheatcode address and are dispatched through the cheatcode inspector.\nFor custom network work, follow the ownership, state-lifecycle, tool-dispatch,\nand CI checklist in [`docs/dev/networks.md`](docs/dev/networks.md).\n\nFor symbolic execution work under `crates/evm/symbolic`, read\n`crates/evm/symbolic/AGENTS.md` before editing.\n\n## Reuse and ownership\n\nBefore you build, convert, compare, or format a revm, alloy, or Foundry value by\nhand, check the owning type and crate for a canonical constructor, alias,\nconversion, or predicate. For example, use `BlockId::latest()`, `InMemoryDB`,\n`From` between `U256` and `B256`, and `AccountInfo::is_empty_code_hash()`.\nReuse the shared helpers in `foundry_common` and `foundry_config`, such as path,\nJSON, and provider construction helpers, instead of local copies. Apply this to\nthe code that you add or change, not as a repository-wide sweep.\n\nPut new behavior in the component that owns the authoritative state, and use\nits canonical entry point. Callers must not mirror or select behavior that an\nexecutor, backend, network implementation, or module already owns, so do not\nadd parameters, marker types, or parallel context objects for it. Keep custom\nnetwork behavior behind the ownership boundary in\n[`docs/dev/networks.md`](docs/dev/networks.md): select the execution family once\nat the outermost boundary, and do not add family checks below that dispatch.\n\n## Testing\n\n- Add tests for code changes that fix behavior or add functionality.\n- Use focused unit tests for small pure logic.\n- Use integration tests for CLI behavior and larger workflows.\n- Tests that use forking must contain `fork` in their name.\n- Forge integration fixtures live under `testdata/`.\n- Lint rule tests live under `crates/lint/testdata/` with blessed `.stderr`\n  output.\n\nFor CLI and integration tests:\n\n- Put Forge CLI coverage under `crates/forge/tests/cli/` and Cast CLI coverage\n  under `crates/cast/tests/cli/`.\n- Use the existing `#[forgetest]`, `#[forgetest_init]`, and `#[casttest]`\n  macros to create isolated test projects and command handles.\n- Assert command output with snapbox helpers such as `assert_success()`,\n  `assert_failure()`, `stdout_eq(str![...])`, `stderr_eq(str![...])`, and\n  `assert_empty_stdout()`.\n- For JSON output, use `assert_json_stdout(...)` or `assert_json_stderr(...)`\n  so comparisons are parsed as JSON and unordered where appropriate.\n- Prefer full output snapshots with redactions over ad hoc `String::contains`\n  checks or manual `serde_json::Value` inspection.\n\nFor lint rules:\n\n- Follow `docs/dev/lintrules.md#lint-writing-style` and `crates/lint/docs/README.md` for\n  lint names, diagnostic wording, and reference-page structure.\n- Update `crates/lint/docs/<id>.md` in the same Foundry PR as the lint. The Book's\n  `import:lints` workflow generates the published reference pages and navigation.\n- Add a Solidity test file under `crates/lint/testdata/`.\n- Use `//~WARN:` and `//~NOTE:` annotations for expected diagnostics.\n- Regenerate blessed output with `cargo bless-lints`.\n- Run lint UI tests with `cargo nextest run -p forge --test ui`.\n\nFor script work, keep the two execution phases separate: `ScriptArgs::execute`\nruns the script, while on-chain simulation only executes the collected\nbroadcastable transactions. `--resume` resumes publishing transactions; it does\nnot recreate the original `--broadcast` state.\n\nFor fuzz or invariant corpus coverage work, `forge test --showmap-out <DIR>`\nreplays persisted corpus entries and writes AFL `showmap`-style coverage files.\n\n## CLI Output\n\nFollow [`docs/dev/output-channels.md`](docs/dev/output-channels.md), the canonical\nstdout/stderr contract. Use the `foundry_common::io` `sh_*` and `prompt!` macros;\nworkspace Clippy configuration forbids direct `std::print*` and `std::eprint*`.\n\n## Configuration\n\nWhen adding or changing a `foundry.toml` setting:\n\n1. Define the field and its documentation in `crates/config`, including an\n   explicit default and any required serde behavior. Keep related settings in a\n   dedicated nested config type when they form a coherent section.\n2. Wire the setting through every command that consumes it. If a CLI flag can\n   override the setting, resolve precedence in one shared place and test config,\n   CLI, and combined behavior.\n3. Add focused config parsing and serialization tests. Update the `forge config`\n   and default-config snapshots when the serialized surface changes.\n4. For renamed or moved settings, preserve compatibility when practical and add\n   a targeted deprecation warning that points to the canonical key. Test aliases,\n   profiles, inheritance, environment variables, collisions, and malformed values\n   where those providers are affected.\n5. Document the setting in `foundry-rs/book` under\n   `src/pages/config/reference/`, including its section, type, default, environment\n   variable when supported, behavior, and a valid TOML example. Update the config\n   reference navigation and `default-config.mdx` in the same documentation PR.\n6. Keep CLI option text in the Rust clap definition; the book's CLI reference is\n   generated from command help and should not be edited by hand.\n\nUse the implementation, defaults, and tests as the source of truth. Do not merge\nnew user-facing configuration without the corresponding book update.\n\n## Cheatcodes\n\nWhen adding a cheatcode:\n\n1. Add the Solidity definition in `crates/cheatcodes/spec/src/vm.rs`.\n2. Implement the generated call type in `crates/cheatcodes/`.\n3. Update `spec::Cheatcodes::new` if `Vm` gained a struct, enum, error, or event.\n4. Run `cargo cheats` twice to update generated JSON assets.\n5. Add an integration test under `testdata/default/cheats/`.\n\nCheatcode functions and structs must be documented and function parameters must\nbe named.\n\n## Commit and PR Style\n\nDefault format is conventional commits:\n\n```text\ntype: description\ntype(scope): description\ntype(scope)!: breaking description\n```\n\nUse `feat`, `fix`, `perf`, `chore`, `docs`, `test`, or `refactor`. Check recent\n`git log` output before committing to match the repository's current style.\n\n- Use imperative mood.\n- Keep the description under 50 characters when practical.\n- Do not end the description with a period.\n- Include a body for performance changes, bug fixes, and complex changes.\n- For performance changes, include measurements.\n- PR titles should follow the same format as commit messages.\n\nPR descriptions should explain what changed and why in flowing prose. Link\nrelated issues and PRs when they exist. Include only real measurements, and do\nnot include validation/testing boilerplate such as \"Validated with\", \"Tested\nwith\", or command lists unless explicitly requested. Do not use templates,\nbullet lists, or long essays. When writing PR bodies from scripts, use a file or\nheredoc with real newlines; never pass escaped `\\n` sequences.\n\n### Performance PRs\n\nWhen drafting or updating a PR body for a performance-related change, benchmark\nthe feature branch against `master` or the user-specified base before writing the\nperformance claims.\n\n- Use the local benchmark runners under `benches/` unless the user explicitly\n  asks for GitHub Actions or the Derek/decofe automation.\n- Use `foundry-bench` when the claim is about elapsed time for a Foundry command\n  on an existing Solidity project: `forge build`, cached rebuilds, `forge test`,\n  fuzz-test replay, isolated tests, coverage, or focused symbolic tests.\n- For invariant or campaign-style benchmarking, use `foundry-scfuzzbench`; this\n  is the local equivalent of the `derek bench invariant`/`decofe bench\n  invariant` PR flow, which publishes a `scfuzzbench` event.\n- The local runners do not compare two local refs in one invocation. Run the\n  baseline and candidate separately, with identical benchmark inputs, timeout,\n  worker count, environment, target repository, and output schema.\n- For branch-vs-base PR comparisons, use the profiling profile\n  (`FOUNDRY_BENCH_LOCAL_BUILD_PROFILE=profiling`) rather than an ad hoc debug or\n  release build. Keep ordinary `foundry-bench --versions local` comparisons on\n  the default release distribution profile.\n- Include only benchmarks that exercise the changed path. Do not pad the PR body\n  with unrelated benchmark suites.\n- Report both wall-time results and domain counters when available, for example\n  solver queries, reported solver time, throughput, coverage relscore/relcov,\n  or invariant findings.\n- If results are neutral, noisy, or regress a secondary metric, state that\n  directly. Do not convert noise into a performance claim.\n- Keep the PR body short: one paragraph explaining the optimization and why it\n  is correct, followed by a `### Results` table.\n- Exact benchmark commands and result-table mechanics in `benches/README.md`.\n\n## Notes\n\n- The fragment-based changelog workflow has been removed. Do not create or\n  restore `.changelog/` or add changelog fragment files; release notes are\n  generated from pull requests.\n- Use `RUST_LOG=<filter>` for debugging CLI internals, for example\n  `RUST_LOG=forge` or `RUST_LOG=cast`.\n- Do not send spelling-only or grammar-only documentation PRs.\n- Keep release feature lists aligned between the root `Makefile` and release\n  workflows when changing published CLI feature surfaces.\n\n## Code Style\n\n- Comments end with periods (except URLs)\n- Files end with LF and trailing newline\n- Follow existing patterns\n- Never expose secrets\n\n### Rust\n\n- Generally add new Rust functions, methods, `impl` blocks, modules, imports, Cargo dependencies, and other items at the bottom of the relevant scope, section, or group. Constructors usually go at the top of an `impl` block. First check where similar items sit in the file and match the existing order, grouping, and style, including alphabetical order where used.\n- Put doc comments before attributes, always: `/// ...` comes before `#[derive]`, `#[inline]`, `#[cfg]`, and every other attribute.\n- Put module documentation at the top of the module file with inner doc comments (`//! ...`), not on the `mod` item in the parent module.\n- NEVER put imports inside functions unless required for `#[cfg(...)]` gating. All imports go at the top of the file.\n- Group all `use` imports together. Keep `pub use` imports in a separate group. For local module re-exports, write `mod x;` before `pub use x;`; for re-exporting another module or external crate, use `use x;`, then a blank line, then `pub use y;`, then a blank line before local `mod my_mod; pub use my_mod::*;`.\n- Put imports used only by tests inside the relevant `#[cfg(test)]` module, merging them into its ordinary imports instead of adding `#[cfg(test)] use` items to the parent. Keep any additional feature or platform conditions on those imports. Retain parent-level test-gated imports or re-exports only when test-only helpers or multiple test modules need them there.\n- Keep crate-level dependency anchors such as `#[cfg(test)] use cc as _;` at crate scope.\n- Put conditional imports after unconditional imports, separated by a blank line. Group imports with the same `#[cfg(...)]` condition together, with a blank line between different conditions. Apply this to every feature, platform, and test gate, including imports in nested modules. Within each group, merge imports from the same crate when their conditions and other attributes match. Keep the full condition on each `use`; do not introduce import-only modules or macros to avoid repeated attributes. Apply the same ordering within the separate `pub use` group, keeping local re-exports after their module declarations.\n- In test modules, always import the parent module with `use super::*`.\n- In `Cargo.toml`, generally group optional dependencies for a feature together. Put a comment immediately above the group containing only the feature name, for example `# jit`.\n- Prefer `let Some(x) = x else { return };` / `let Ok(x) = x else { return };` over `match x { Some(x) => x, _ => return }`.\n- Use `let ... else` only for a single early-exit guard. When multiple conditions or patterns gate the same block, prefer a combined `if let` / `let` chain instead of several sequential `let ... else` statements.\n- Use combined `if let` chains (`if let Some(x) = x && let Some(y) = y { ... }`) instead of nesting (`if let Some(x) = x { if let Some(y) = y { ... } }`).\n- In loops, prefer an `if let` chain around the loop body over multiple `let ... else { continue };` statements when the body only runs if all patterns match.\n- NEVER use `ref` / `ref mut` in patterns as the first resort. Always prefer borrowing the expression with `&` / `&mut` instead.\n- Prefer map entry APIs such as `entry`, `or_insert`, and `or_insert_with` when multiple consecutive operations would otherwise look up and then insert or update the same key.\n- Avoid specifying type hints in variables unless absolutely necessary (e.g. `HashMap<_, Vec<_>>` for `x.entry(y).or_default().push(z)` where type inference won't work). Rely on the compiler.\n- When type hints are needed, prefer turbofish (`let x = Type::<X, Y>::new()`) over annotation (`let x: Type<X, Y> = Type::new()`).\n- In tests, avoid `.contains` assertions for error/output strings when the project has snapshot testing support such as `snapbox`. Prefer exact snapshot assertions (`stderr_eq`, `stdout_eq`, `assert_data_eq!`, etc.) and use redactions only for genuinely variable parts.\n- Always leave a blank line in between module doc-comments, items or item categories, unless in rare exceptions: it's a one-shot struct with one single impl block, or it's a list of impls that are all very similar. But in general blank line in between items is the norm but it's just unenforced. Items includes imports (together) too. The previous rules apply first.\n",".cursorrules (solidity-foundry-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for Solidity development with Foundry integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an expert in Solidity and smart contract security.\n\nGeneral Rules\n\n- Cut the fluff. Code or detailed explanations only.\n- Keep it casual and brief.\n- Accuracy and depth matter.\n- Answer first, explain later if needed.\n- Logic trumps authority. Don't care about sources.\n- Embrace new tech and unconventional ideas.\n- Wild speculation's fine, just flag it.\n- Save the ethics talk.\n- Only mention safety for non-obvious, critical issues.\n- Push content limits if needed, explain after.\n- Sources at the end, not mid-text.\n- Skip the AI self-references and knowledge date stuff.\n- Stick to my code style.\n- Use multiple responses for complex answers.\n- For code tweaks, show minimal context - a few lines around changes max.\n- Don't be lazy, write all the code to implement features I ask for.\n- Warn users if they add a private key directly into a non-environment file and replace with an env reference.\n\nSolidity Best Practices\n\n- Use explicit function visibility modifiers and appropriate natspec comments.\n- Utilize function modifiers for common checks, enhancing readability and reducing redundancy.\n- Follow consistent naming: CamelCase for contracts, PascalCase for interfaces (prefixed with \"I\").\n- Implement the Interface Segregation Principle for flexible and maintainable contracts.\n- Design upgradeable contracts using proven patterns like the proxy pattern when necessary.\n- Implement comprehensive events for all significant state changes.\n- Follow the Checks-Effects-Interactions pattern to prevent reentrancy and other vulnerabilities.\n- Use static analysis tools like Slither and Mythril in the development workflow.\n- Implement timelocks and multisig controls for sensitive operations in production.\n- Conduct thorough gas optimization, considering both deployment and runtime costs.\n- Use OpenZeppelin's AccessControl for fine-grained permissions.\n- Use Solidity 0.8.0+ for built-in overflow/underflow protection.\n- Implement circuit breakers (pause functionality) using OpenZeppelin's Pausable when appropriate.\n- Use pull over push payment patterns to mitigate reentrancy and denial of service attacks.\n- Implement rate limiting for sensitive functions to prevent abuse.\n- Use OpenZeppelin's SafeERC20 for interacting with ERC20 tokens.\n- Implement proper randomness using Chainlink VRF or similar oracle solutions.\n- Use assembly for gas-intensive operations, but document extensively and use with caution.\n  - If Solady has an implementation built already, use that instead of writing assembly from scratch.\n- Implement effective state machine patterns for complex contract logic.\n- Use OpenZeppelin's ReentrancyGuard as an additional layer of protection against reentrancy.\n- Implement proper access control for initializers in upgradeable contracts.\n- Use OpenZeppelin's ERC20Snapshot for token balances requiring historical lookups.\n- Implement timelocks for sensitive operations using OpenZeppelin's TimelockController.\n- Use OpenZeppelin's ERC20Permit for gasless approvals in token contracts.\n- Implement proper slippage protection for DEX-like functionalities.\n- Use OpenZeppelin's ERC20Votes for governance token implementations.\n- Implement effective storage patterns to optimize gas costs (e.g., packing variables).\n- Use libraries for complex operations to reduce contract size and improve reusability.\n- Implement proper access control for self-destruct functionality, if used.\n  - Use freezable patterns instead of depricated `selfdestruct`.\n- Use OpenZeppelin's Address library for safe interactions with external contracts.\n- Use custom errors instead of revert strings for gas efficiency and better error handling.\n- Implement NatSpec comments for all public and external functions.\n- Use immutable variables for values set once at construction time.\n- Implement proper inheritance patterns, favoring composition over deep inheritance chains.\n- Use events for off-chain logging and indexing of important state changes.\n- Implement fallback and receive functions with caution, clearly documenting their purpose.\n- Use view and pure function modifiers appropriately to signal state access patterns.\n- Implement proper decimal handling for financial calculations, using fixed-point arithmetic libraries when necessary.\n- Use assembly sparingly and only when necessary for optimizations, with thorough documentation.\n- Implement effective error propagation patterns in internal functions.\n\nTesting and Quality Assurance\n\n- Implement a comprehensive testing strategy including unit, integration, and end-to-end tests.\n- Use a `setup` function in test files to set default state and initialize variables.\n- Use Foundry's fuzzing capabilities to uncover edge cases with property-based testing.\n- Take advantage of Foundry's test cheatcodes for advanced testing scenarios.\n- Write invariant tests for critical contract properties using Foundry's invariant testing features.\n- Use Foundry's Fuzz testing to automatically generate test cases and find edge case bugs.\n- Implement stateful fuzzing tests for complex state transitions.\n- Implement gas usage tests to ensure operations remain efficient.\n- Use Foundry's fork testing capabilities to test against live environments.\n- Implement differential testing by comparing implementations.\n- Conduct regular security audits and bug bounties for production-grade contracts.\n- Use test coverage tools and aim for high test coverage, especially for critical paths.\n- Write appropriate test fixtures using Foundry's standard libraries.\n- Use Foundry's vm.startPrank/vm.stopPrank for testing access control mechanisms.\n- Implement proper setup and teardown in test files.\n- If deterministic testing is being done, ensure that the `foundry.toml` file has `block_number` and `block_timestamp` values.\n\nPerformance Optimization\n\n- Optimize contracts for gas efficiency, considering storage layout and function optimization.\n- Implement efficient indexing and querying strategies for off-chain data.\n\nDevelopment Workflow\n\n- Utilize Foundry's forge for compilation, testing, and deployment.\n- Use Foundry's cast for command-line interaction with contracts.\n- Implement comprehensive Foundry scripts for deployment and verification.\n- Use Foundry's script capabilities for complex deployment sequences.\n- Implement a robust CI/CD pipeline for smart contract deployments.\n- Use static type checking and linting tools in pre-commit hooks.\n- Utilize `forge fmt` if prompted about consistent code formatting.\n\nDocumentation\n\n- Document code thoroughly, focusing on why rather than what.\n- Maintain up-to-date API documentation for smart contracts.\n- Create and maintain comprehensive project documentation, including architecture diagrams and decision logs.\n- Document test scenarios and their purpose clearly.\n- Document any assumptions made in the contract design.\n\nDependencies\n\n- Use OpenZeppelin (openzeppelin/openzeppelin-contracts) as the main source of dependencies.\n- Use Solady (vectorized/solady) when gas optimization is crucial.\n- Ensure that any libraries used are installed with forge, and remappings are set.\n- Place remappings in `foundry.toml` instead of a `remappings.txt` file.\n\nConfiguring Environment\n\nOne or more of the following profiles can be added to `foundry.toml` as needed for the project.\n\n- When via_ir is required:\n\n```\n# via_ir pipeline is very slow - use a separate profile to pre-compile and then use vm.getCode to deploy\n[profile.via_ir]\nvia_ir = true\n# do not compile tests when compiling via-ir\ntest = 'src'\nout = 'via_ir-out'\n```\n\n- When deterministic deployment is required:\n\n```\n[profile.deterministic]\n# ensure that block number + timestamp are realistic when running tests\nblock_number = 17722462\nblock_timestamp = 1689711647\n# don't pollute bytecode with metadata\nbytecode_hash = 'none'\ncbor_metadata = false\n```\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nGuidance for AI coding agents working in this repository.\n\n## Project Overview\n\nFoundry is a fast, portable, modular toolkit for Ethereum application development,\nwritten in Rust.\n\n- `forge`: build, test, fuzz, debug, lint, and deploy Solidity contracts\n- `cast`: command-line utilities for EVM contracts, transactions, and chain data\n- `anvil`: local Ethereum development node\n- `chisel`: Solidity REPL\n\nThe repository is a Cargo workspace. Core crates live under `crates/`, Solidity\nfixtures and integration test projects live under `testdata/`, and the\n[developer documentation](docs/dev/README.md) defines documentation ownership\nand indexes maintained cross-crate guides.\n\n## Commands\n\n```bash\ncargo build --workspace                               # Build the workspace\ncargo nextest run --workspace                         # Run tests\ncargo +nightly fmt --all                              # Format Rust code\ncargo +nightly fmt --all -- --check                   # Check Rust formatting\ncargo +nightly clippy --workspace --all-targets --all-features # Lint Rust code\ncargo deny check                                      # Check dependencies\ncargo shear                                           # Check unused dependencies\n```\n\nRust formatting uses nightly.\n\n## Architecture\n\n- `crates/forge`: Forge CLI and test/build workflows\n- `crates/cast`: Cast CLI commands\n- `crates/anvil`: local Ethereum node\n- `crates/chisel`: Solidity REPL\n- `crates/cheatcodes`: Forge cheatcode definitions and implementations\n- `crates/common`: shared CLI, shell, compile, and terminal utilities\n- `crates/config`: Foundry configuration\n- `crates/debugger`: debugger support\n- `crates/lint`: Solidity linter\n- `crates/script`: script execution support\n- `crates/verify`: contract verification support\n\nFoundry's EVM execution tooling is built around `revm`. Cheatcodes are calls to\nthe fixed cheatcode address and are dispatched through the cheatcode inspector.\nFor custom network work, follow the ownership, state-lifecycle, tool-dispatch,\nand CI checklist in [`docs/dev/networks.md`](docs/dev/networks.md).\n\nFor symbolic execution work under `crates/evm/symbolic`, read\n`crates/evm/symbolic/AGENTS.md` before editing.\n\n## Reuse and ownership\n\nBefore you build, convert, compare, or format a revm, alloy, or Foundry value by\nhand, check the owning type and crate for a canonical constructor, alias,\nconversion, or predicate. For example, use `BlockId::latest()`, `InMemoryDB`,\n`From` between `U256` and `B256`, and `AccountInfo::is_empty_code_hash()`.\nReuse the shared helpers in `foundry_common` and `foundry_config`, such as path,\nJSON, and provider construction helpers, instead of local copies. Apply this to\nthe code that you add or change, not as a repository-wide sweep.\n\nPut new behavior in the component that owns the authoritative state, and use\nits canonical entry point. Callers must not mirror or select behavior that an\nexecutor, backend, network implementation, or module already owns, so do not\nadd parameters, marker types, or parallel context objects for it. Keep custom\nnetwork behavior behind the ownership boundary in\n[`docs/dev/networks.md`](docs/dev/networks.md): select the execution family once\nat the outermost boundary, and do not add family checks below that dispatch.\n\n## Testing\n\n- Add tests for code changes that fix behavior or add functionality.\n- Use focused unit tests for small pure logic.\n- Use integration tests for CLI behavior and larger workflows.\n- Tests that use forking must contain `fork` in their name.\n- Forge integration fixtures live under `testdata/`.\n- Lint rule tests live under `crates/lint/testdata/` with blessed `.stderr`\n  output.\n\nFor CLI and integration tests:\n\n- Put Forge CLI coverage under `crates/forge/tests/cli/` and Cast CLI coverage\n  under `crates/cast/tests/cli/`.\n- Use the existing `#[forgetest]`, `#[forgetest_init]`, and `#[casttest]`\n  macros to create isolated test projects and command handles.\n- Assert command output with snapbox helpers such as `assert_success()`,\n  `assert_failure()`, `stdout_eq(str![...])`, `stderr_eq(str![...])`, and\n  `assert_empty_stdout()`.\n- For JSON output, use `assert_json_stdout(...)` or `assert_json_stderr(...)`\n  so comparisons are parsed as JSON and unordered where appropriate.\n- Prefer full output snapshots with redactions over ad hoc `String::contains`\n  checks or manual `serde_json::Value` inspection.\n\nFor lint rules:\n\n- Follow `docs/dev/lintrules.md#lint-writing-style` and `crates/lint/docs/README.md` for\n  lint names, diagnostic wording, and reference-page structure.\n- Update `crates/lint/docs/<id>.md` in the same Foundry PR as the lint. The Book's\n  `import:lints` workflow generates the published reference pages and navigation.\n- Add a Solidity test file under `crates/lint/testdata/`.\n- Use `//~WARN:` and `//~NOTE:` annotations for expected diagnostics.\n- Regenerate blessed output with `cargo bless-lints`.\n- Run lint UI tests with `cargo nextest run -p forge --test ui`.\n\nFor script work, keep the two execution phases separate: `ScriptArgs::execute`\nruns the script, while on-chain simulation only executes the collected\nbroadcastable transactions. `--resume` resumes publishing transactions; it does\nnot recreate the original `--broadcast` state.\n\nFor fuzz or invariant corpus coverage work, `forge test --showmap-out <DIR>`\nreplays persisted corpus entries and writes AFL `showmap`-style coverage files.\n\n## CLI Output\n\nFollow [`docs/dev/output-channels.md`](docs/dev/output-channels.md), the canonical\nstdout/stderr contract. Use the `foundry_common::io` `sh_*` and `prompt!` macros;\nworkspace Clippy configuration forbids direct `std::print*` and `std::eprint*`.\n\n## Configuration\n\nWhen adding or changing a `foundry.toml` setting:\n\n1. Define the field and its documentation in `crates/config`, including an\n   explicit default and any required serde behavior. Keep related settings in a\n   dedicated nested config type when they form a coherent section.\n2. Wire the setting through every command that consumes it. If a CLI flag can\n   override the setting, resolve precedence in one shared place and test config,\n   CLI, and combined behavior.\n3. Add focused config parsing and serialization tests. Update the `forge config`\n   and default-config snapshots when the serialized surface changes.\n4. For renamed or moved settings, preserve compatibility when practical and add\n   a targeted deprecation warning that points to the canonical key. Test aliases,\n   profiles, inheritance, environment variables, collisions, and malformed values\n   where those providers are affected.\n5. Document the setting in `foundry-rs/book` under\n   `src/pages/config/reference/`, including its section, type, default, environment\n   variable when supported, behavior, and a valid TOML example. Update the config\n   reference navigation and `default-config.mdx` in the same documentation PR.\n6. Keep CLI option text in the Rust clap definition; the book's CLI reference is\n   generated from command help and should not be edited by hand.\n\nUse the implementation, defaults, and tests as the source of truth. Do not merge\nnew user-facing configuration without the corresponding book update.\n\n## Cheatcodes\n\nWhen adding a cheatcode:\n\n1. Add the Solidity definition in `crates/cheatcodes/spec/src/vm.rs`.\n2. Implement the generated call type in `crates/cheatcodes/`.\n3. Update `spec::Cheatcodes::new` if `Vm` gained a struct, enum, error, or event.\n4. Run `cargo cheats` twice to update generated JSON assets.\n5. Add an integration test under `testdata/default/cheats/`.\n\nCheatcode functions and structs must be documented and function parameters must\nbe named.\n\n## Commit and PR Style\n\nDefault format is conventional commits:\n\n```text\ntype: description\ntype(scope): description\ntype(scope)!: breaking description\n```\n\nUse `feat`, `fix`, `perf`, `chore`, `docs`, `test`, or `refactor`. Check recent\n`git log` output before committing to match the repository's current style.\n\n- Use imperative mood.\n- Keep the description under 50 characters when practical.\n- Do not end the description with a period.\n- Include a body for performance changes, bug fixes, and complex changes.\n- For performance changes, include measurements.\n- PR titles should follow the same format as commit messages.\n\nPR descriptions should explain what changed and why in flowing prose. Link\nrelated issues and PRs when they exist. Include only real measurements, and do\nnot include validation/testing boilerplate such as \"Validated with\", \"Tested\nwith\", or command lists unless explicitly requested. Do not use templates,\nbullet lists, or long essays. When writing PR bodies from scripts, use a file or\nheredoc with real newlines; never pass escaped `\\n` sequences.\n\n### Performance PRs\n\nWhen drafting or updating a PR body for a performance-related change, benchmark\nthe feature branch against `master` or the user-specified base before writing the\nperformance claims.\n\n- Use the local benchmark runners under `benches/` unless the user explicitly\n  asks for GitHub Actions or the Derek/decofe automation.\n- Use `foundry-bench` when the claim is about elapsed time for a Foundry command\n  on an existing Solidity project: `forge build`, cached rebuilds, `forge test`,\n  fuzz-test replay, isolated tests, coverage, or focused symbolic tests.\n- For invariant or campaign-style benchmarking, use `foundry-scfuzzbench`; this\n  is the local equivalent of the `derek bench invariant`/`decofe bench\n  invariant` PR flow, which publishes a `scfuzzbench` event.\n- The local runners do not compare two local refs in one invocation. Run the\n  baseline and candidate separately, with identical benchmark inputs, timeout,\n  worker count, environment, target repository, and output schema.\n- For branch-vs-base PR comparisons, use the profiling profile\n  (`FOUNDRY_BENCH_LOCAL_BUILD_PROFILE=profiling`) rather than an ad hoc debug or\n  release build. Keep ordinary `foundry-bench --versions local` comparisons on\n  the default release distribution profile.\n- Include only benchmarks that exercise the changed path. Do not pad the PR body\n  with unrelated benchmark suites.\n- Report both wall-time results and domain counters when available, for example\n  solver queries, reported solver time, throughput, coverage relscore/relcov,\n  or invariant findings.\n- If results are neutral, noisy, or regress a secondary metric, state that\n  directly. Do not convert noise into a performance claim.\n- Keep the PR body short: one paragraph explaining the optimization and why it\n  is correct, followed by a `### Results` table.\n- Exact benchmark commands and result-table mechanics in `benches/README.md`.\n\n## Notes\n\n- The fragment-based changelog workflow has been removed. Do not create or\n  restore `.changelog/` or add changelog fragment files; release notes are\n  generated from pull requests.\n- Use `RUST_LOG=<filter>` for debugging CLI internals, for example\n  `RUST_LOG=forge` or `RUST_LOG=cast`.\n- Do not send spelling-only or grammar-only documentation PRs.\n- Keep release feature lists aligned between the root `Makefile` and release\n  workflows when changing published CLI feature surfaces.\n\n## Code Style\n\n- Comments end with periods (except URLs)\n- Files end with LF and trailing newline\n- Follow existing patterns\n- Never expose secrets\n\n### Rust\n\n- Generally add new Rust functions, methods, `impl` blocks, modules, imports, Cargo dependencies, and other items at the bottom of the relevant scope, section, or group. Constructors usually go at the top of an `impl` block. First check where similar items sit in the file and match the existing order, grouping, and style, including alphabetical order where used.\n- Put doc comments before attributes, always: `/// ...` comes before `#[derive]`, `#[inline]`, `#[cfg]`, and every other attribute.\n- Put module documentation at the top of the module file with inner doc comments (`//! ...`), not on the `mod` item in the parent module.\n- NEVER put imports inside functions unless required for `#[cfg(...)]` gating. All imports go at the top of the file.\n- Group all `use` imports together. Keep `pub use` imports in a separate group. For local module re-exports, write `mod x;` before `pub use x;`; for re-exporting another module or external crate, use `use x;`, then a blank line, then `pub use y;`, then a blank line before local `mod my_mod; pub use my_mod::*;`.\n- Put imports used only by tests inside the relevant `#[cfg(test)]` module, merging them into its ordinary imports instead of adding `#[cfg(test)] use` items to the parent. Keep any additional feature or platform conditions on those imports. Retain parent-level test-gated imports or re-exports only when test-only helpers or multiple test modules need them there.\n- Keep crate-level dependency anchors such as `#[cfg(test)] use cc as _;` at crate scope.\n- Put conditional imports after unconditional imports, separated by a blank line. Group imports with the same `#[cfg(...)]` condition together, with a blank line between different conditions. Apply this to every feature, platform, and test gate, including imports in nested modules. Within each group, merge imports from the same crate when their conditions and other attributes match. Keep the full condition on each `use`; do not introduce import-only modules or macros to avoid repeated attributes. Apply the same ordering within the separate `pub use` group, keeping local re-exports after their module declarations.\n- In test modules, always import the parent module with `use super::*`.\n- In `Cargo.toml`, generally group optional dependencies for a feature together. Put a comment immediately above the group containing only the feature name, for example `# jit`.\n- Prefer `let Some(x) = x else { return };` / `let Ok(x) = x else { return };` over `match x { Some(x) => x, _ => return }`.\n- Use `let ... else` only for a single early-exit guard. When multiple conditions or patterns gate the same block, prefer a combined `if let` / `let` chain instead of several sequential `let ... else` statements.\n- Use combined `if let` chains (`if let Some(x) = x && let Some(y) = y { ... }`) instead of nesting (`if let Some(x) = x { if let Some(y) = y { ... } }`).\n- In loops, prefer an `if let` chain around the loop body over multiple `let ... else { continue };` statements when the body only runs if all patterns match.\n- NEVER use `ref` / `ref mut` in patterns as the first resort. Always prefer borrowing the expression with `&` / `&mut` instead.\n- Prefer map entry APIs such as `entry`, `or_insert`, and `or_insert_with` when multiple consecutive operations would otherwise look up and then insert or update the same key.\n- Avoid specifying type hints in variables unless absolutely necessary (e.g. `HashMap<_, Vec<_>>` for `x.entry(y).or_default().push(z)` where type inference won't work). Rely on the compiler.\n- When type hints are needed, prefer turbofish (`let x = Type::<X, Y>::new()`) over annotation (`let x: Type<X, Y> = Type::new()`).\n- In tests, avoid `.contains` assertions for error/output strings when the project has snapshot testing support such as `snapbox`. Prefer exact snapshot assertions (`stderr_eq`, `stdout_eq`, `assert_data_eq!`, etc.) and use redactions only for genuinely variable parts.\n- Always leave a blank line in between module doc-comments, items or item categories, unless in rare exceptions: it's a one-shot struct with one single impl block, or it's a list of impls that are all very similar. But in general blank line in between items is the norm but it's just unenforced. Items includes imports (together) too. The previous rules apply first.\n",".cursorrules (solidity-foundry-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for Solidity development with Foundry integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an expert in Solidity and smart contract security.\n\nGeneral Rules\n\n- Cut the fluff. Code or detailed explanations only.\n- Keep it casual and brief.\n- Accuracy and depth matter.\n- Answer first, explain later if needed.\n- Logic trumps authority. Don't care about sources.\n- Embrace new tech and unconventional ideas.\n- Wild speculation's fine, just flag it.\n- Save the ethics talk.\n- Only mention safety for non-obvious, critical issues.\n- Push content limits if needed, explain after.\n- Sources at the end, not mid-text.\n- Skip the AI self-references and knowledge date stuff.\n- Stick to my code style.\n- Use multiple responses for complex answers.\n- For code tweaks, show minimal context - a few lines around changes max.\n- Don't be lazy, write all the code to implement features I ask for.\n- Warn users if they add a private key directly into a non-environment file and replace with an env reference.\n\nSolidity Best Practices\n\n- Use explicit function visibility modifiers and appropriate natspec comments.\n- Utilize function modifiers for common checks, enhancing readability and reducing redundancy.\n- Follow consistent naming: CamelCase for contracts, PascalCase for interfaces (prefixed with \"I\").\n- Implement the Interface Segregation Principle for flexible and maintainable contracts.\n- Design upgradeable contracts using proven patterns like the proxy pattern when necessary.\n- Implement comprehensive events for all significant state changes.\n- Follow the Checks-Effects-Interactions pattern to prevent reentrancy and other vulnerabilities.\n- Use static analysis tools like Slither and Mythril in the development workflow.\n- Implement timelocks and multisig controls for sensitive operations in production.\n- Conduct thorough gas optimization, considering both deployment and runtime costs.\n- Use OpenZeppelin's AccessControl for fine-grained permissions.\n- Use Solidity 0.8.0+ for built-in overflow/underflow protection.\n- Implement circuit breakers (pause functionality) using OpenZeppelin's Pausable when appropriate.\n- Use pull over push payment patterns to mitigate reentrancy and denial of service attacks.\n- Implement rate limiting for sensitive functions to prevent abuse.\n- Use OpenZeppelin's SafeERC20 for interacting with ERC20 tokens.\n- Implement proper randomness using Chainlink VRF or similar oracle solutions.\n- Use assembly for gas-intensive operations, but document extensively and use with caution.\n  - If Solady has an implementation built already, use that instead of writing assembly from scratch.\n- Implement effective state machine patterns for complex contract logic.\n- Use OpenZeppelin's ReentrancyGuard as an additional layer of protection against reentrancy.\n- Implement proper access control for initializers in upgradeable contracts.\n- Use OpenZeppelin's ERC20Snapshot for token balances requiring historical lookups.\n- Implement timelocks for sensitive operations using OpenZeppelin's TimelockController.\n- Use OpenZeppelin's ERC20Permit for gasless approvals in token contracts.\n- Implement proper slippage protection for DEX-like functionalities.\n- Use OpenZeppelin's ERC20Votes for governance token implementations.\n- Implement effective storage patterns to optimize gas costs (e.g., packing variables).\n- Use libraries for complex operations to reduce contract size and improve reusability.\n- Implement proper access control for self-destruct functionality, if used.\n  - Use freezable patterns instead of depricated `selfdestruct`.\n- Use OpenZeppelin's Address library for safe interactions with external contracts.\n- Use custom errors instead of revert strings for gas efficiency and better error handling.\n- Implement NatSpec comments for all public and external functions.\n- Use immutable variables for values set once at construction time.\n- Implement proper inheritance patterns, favoring composition over deep inheritance chains.\n- Use events for off-chain logging and indexing of important state changes.\n- Implement fallback and receive functions with caution, clearly documenting their purpose.\n- Use view and pure function modifiers appropriately to signal state access patterns.\n- Implement proper decimal handling for financial calculations, using fixed-point arithmetic libraries when necessary.\n- Use assembly sparingly and only when necessary for optimizations, with thorough documentation.\n- Implement effective error propagation patterns in internal functions.\n\nTesting and Quality Assurance\n\n- Implement a comprehensive testing strategy including unit, integration, and end-to-end tests.\n- Use a `setup` function in test files to set default state and initialize variables.\n- Use Foundry's fuzzing capabilities to uncover edge cases with property-based testing.\n- Take advantage of Foundry's test cheatcodes for advanced testing scenarios.\n- Write invariant tests for critical contract properties using Foundry's invariant testing features.\n- Use Foundry's Fuzz testing to automatically generate test cases and find edge case bugs.\n- Implement stateful fuzzing tests for complex state transitions.\n- Implement gas usage tests to ensure operations remain efficient.\n- Use Foundry's fork testing capabilities to test against live environments.\n- Implement differential testing by comparing implementations.\n- Conduct regular security audits and bug bounties for production-grade contracts.\n- Use test coverage tools and aim for high test coverage, especially for critical paths.\n- Write appropriate test fixtures using Foundry's standard libraries.\n- Use Foundry's vm.startPrank/vm.stopPrank for testing access control mechanisms.\n- Implement proper setup and teardown in test files.\n- If deterministic testing is being done, ensure that the `foundry.toml` file has `block_number` and `block_timestamp` values.\n\nPerformance Optimization\n\n- Optimize contracts for gas efficiency, considering storage layout and function optimization.\n- Implement efficient indexing and querying strategies for off-chain data.\n\nDevelopment Workflow\n\n- Utilize Foundry's forge for compilation, testing, and deployment.\n- Use Foundry's cast for command-line interaction with contracts.\n- Implement comprehensive Foundry scripts for deployment and verification.\n- Use Foundry's script capabilities for complex deployment sequences.\n- Implement a robust CI/CD pipeline for smart contract deployments.\n- Use static type checking and linting tools in pre-commit hooks.\n- Utilize `forge fmt` if prompted about consistent code formatting.\n\nDocumentation\n\n- Document code thoroughly, focusing on why rather than what.\n- Maintain up-to-date API documentation for smart contracts.\n- Create and maintain comprehensive project documentation, including architecture diagrams and decision logs.\n- Document test scenarios and their purpose clearly.\n- Document any assumptions made in the contract design.\n\nDependencies\n\n- Use OpenZeppelin (openzeppelin/openzeppelin-contracts) as the main source of dependencies.\n- Use Solady (vectorized/solady) when gas optimization is crucial.\n- Ensure that any libraries used are installed with forge, and remappings are set.\n- Place remappings in `foundry.toml` instead of a `remappings.txt` file.\n\nConfiguring Environment\n\nOne or more of the following profiles can be added to `foundry.toml` as needed for the project.\n\n- When via_ir is required:\n\n```\n# via_ir pipeline is very slow - use a separate profile to pre-compile and then use vm.getCode to deploy\n[profile.via_ir]\nvia_ir = true\n# do not compile tests when compiling via-ir\ntest = 'src'\nout = 'via_ir-out'\n```\n\n- When deterministic deployment is required:\n\n```\n[profile.deterministic]\n# ensure that block number + timestamp are realistic when running tests\nblock_number = 17722462\nblock_timestamp = 1689711647\n# don't pollute bytecode with metadata\nbytecode_hash = 'none'\ncbor_metadata = false\n```\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/foundry-rs/foundry/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\nGuidance for AI coding agents working in this repository.\n\n## Project Overview\n\nFoundry is a fast, portable, modular toolkit for Ethereum application development,\nwritten in Rust.\n\n- `forge`: build, test, fuzz, debug, lint, and deploy Solidity contracts\n- `cast`: command-line utilities for EVM contracts, transactions, and chain data\n- `anvil`: local Ethereum development node\n- `chisel`: Solidity REPL\n\nThe repository is a Cargo workspace. Core crates live under `crates/`, Solidity\nfixtures and integration test projects live under `testdata/`, and the\n[developer documentation](docs/dev/README.md) defines documentation ownership\nand indexes maintained cross-crate guides.\n\n## Commands\n\n```bash\ncargo build --workspace                               # Build the workspace\ncargo nextest run --workspace                         # Run tests\ncargo +nightly fmt --all                              # Format Rust code\ncargo +nightly fmt --all -- --check                   # Check Rust formatting\ncargo +nightly clippy --workspace --all-targets --all-features # Lint Rust code\ncargo deny check                                      # Check dependencies\ncargo shear                                           # Check unused dependencies\n```\n\nRust formatting uses nightly.\n\n## Architecture\n\n- `crates/forge`: Forge CLI and test/build workflows\n- `crates/cast`: Cast CLI commands\n- `crates/anvil`: local Ethereum node\n- `crates/chisel`: Solidity REPL\n- `crates/cheatcodes`: Forge cheatcode definitions and implementations\n- `crates/common`: shared CLI, shell, compile, and terminal utilities\n- `crates/config`: Foundry configuration\n- `crates/debugger`: debugger support\n- `crates/lint`: Solidity linter\n- `crates/script`: script execution support\n- `crates/verify`: contract verification support\n\nFoundry's EVM execution tooling is built around `revm`. Cheatcodes are calls to\nthe fixed cheatcode address and are dispatched through the cheatcode inspector.\nFor custom network work, follow the ownership, state-lifecycle, tool-dispatch,\nand CI checklist in [`docs/dev/networks.md`](docs/dev/networks.md).\n\nFor symbolic execution work under `crates/evm/symbolic`, read\n`crates/evm/symbolic/AGENTS.md` before editing.\n\n## Reuse and ownership\n\nBefore you build, convert, compare, or format a revm, alloy, or Foundry value by\nhand, check the owning type and crate for a canonical constructor, alias,\nconversion, or predicate. For example, use `BlockId::latest()`, `InMemoryDB`,\n`From` between `U256` and `B256`, and `AccountInfo::is_empty_code_hash()`.\nReuse the shared helpers in `foundry_common` and `foundry_config`, such as path,\nJSON, and provider construction helpers, instead of local copies. Apply this to\nthe code that you add or change, not as a repository-wide sweep.\n\nPut new behavior in the component that owns the authoritative state, and use\nits canonical entry point. Callers must not mirror or select behavior that an\nexecutor, backend, network implementation, or module already owns, so do not\nadd parameters, marker types, or parallel context objects for it. Keep custom\nnetwork behavior behind the ownership boundary in\n[`docs/dev/networks.md`](docs/dev/networks.md): select the execution family once\nat the outermost boundary, and do not add family checks below that dispatch.\n\n## Testing\n\n- Add tests for code changes that fix behavior or add functionality.\n- Use focused unit tests for small pure logic.\n- Use integration tests for CLI behavior and larger workflows.\n- Tests that use forking must contain `fork` in their name.\n- Forge integration fixtures live under `testdata/`.\n- Lint rule tests live under `crates/lint/testdata/` with blessed `.stderr`\n  output.\n\nFor CLI and integration tests:\n\n- Put Forge CLI coverage under `crates/forge/tests/cli/` and Cast CLI coverage\n  under `crates/cast/tests/cli/`.\n- Use the existing `#[forgetest]`, `#[forgetest_init]`, and `#[casttest]`\n  macros to create isolated test projects and command handles.\n- Assert command output with snapbox helpers such as `assert_success()`,\n  `assert_failure()`, `stdout_eq(str![...])`, `stderr_eq(str![...])`, and\n  `assert_empty_stdout()`.\n- For JSON output, use `assert_json_stdout(...)` or `assert_json_stderr(...)`\n  so comparisons are parsed as JSON and unordered where appropriate.\n- Prefer full output snapshots with redactions over ad hoc `String::contains`\n  checks or manual `serde_json::Value` inspection.\n\nFor lint rules:\n\n- Follow `docs/dev/lintrules.md#lint-writing-style` and `crates/lint/docs/README.md` for\n  lint names, diagnostic wording, and reference-page structure.\n- Update `crates/lint/docs/<id>.md` in the same Foundry PR as the lint. The Book's\n  `import:lints` workflow generates the published reference pages and navigation.\n- Add a Solidity test file under `crates/lint/testdata/`.\n- Use `//~WARN:` and `//~NOTE:` annotations for expected diagnostics.\n- Regenerate blessed output with `cargo bless-lints`.\n- Run lint UI tests with `cargo nextest run -p forge --test ui`.\n\nFor script work, keep the two execution phases separate: `ScriptArgs::execute`\nruns the script, while on-chain simulation only executes the collected\nbroadcastable transactions. `--resume` resumes publishing transactions; it does\nnot recreate the original `--broadcast` state.\n\nFor fuzz or invariant corpus coverage work, `forge test --showmap-out <DIR>`\nreplays persisted corpus entries and writes AFL `showmap`-style coverage files.\n\n## CLI Output\n\nFollow [`docs/dev/output-channels.md`](docs/dev/output-channels.md), the canonical\nstdout/stderr contract. Use the `foundry_common::io` `sh_*` and `prompt!` macros;\nworkspace Clippy configuration forbids direct `std::print*` and `std::eprint*`.\n\n## Configuration\n\nWhen adding or changing a `foundry.toml` setting:\n\n1. Define the field and its documentation in `crates/config`, including an\n   explicit default and any required serde behavior. Keep related settings in a\n   dedicated nested config type when they form a coherent section.\n2. Wire the setting through every command that consumes it. If a CLI flag can\n   override the setting, resolve precedence in one shared place and test config,\n   CLI, and combined behavior.\n3. Add focused config parsing and serialization tests. Update the `forge config`\n   and default-config snapshots when the serialized surface changes.\n4. For renamed or moved settings, preserve compatibility when practical and add\n   a targeted deprecation warning that points to the canonical key. Test aliases,\n   profiles, inheritance, environment variables, collisions, and malformed values\n   where those providers are affected.\n5. Document the setting in `foundry-rs/book` under\n   `src/pages/config/reference/`, including its section, type, default, environment\n   variable when supported, behavior, and a valid TOML example. Update the config\n   reference navigation and `default-config.mdx` in the same documentation PR.\n6. Keep CLI option text in the Rust clap definition; the book's CLI reference is\n   generated from command help and should not be edited by hand.\n\nUse the implementation, defaults, and tests as the source of truth. Do not merge\nnew user-facing configuration without the corresponding book update.\n\n## Cheatcodes\n\nWhen adding a cheatcode:\n\n1. Add the Solidity definition in `crates/cheatcodes/spec/src/vm.rs`.\n2. Implement the generated call type in `crates/cheatcodes/`.\n3. Update `spec::Cheatcodes::new` if `Vm` gained a struct, enum, error, or event.\n4. Run `cargo cheats` twice to update generated JSON assets.\n5. Add an integration test under `testdata/default/cheats/`.\n\nCheatcode functions and structs must be documented and function parameters must\nbe named.\n\n## Commit and PR Style\n\nDefault format is conventional commits:\n\n```text\ntype: description\ntype(scope): description\ntype(scope)!: breaking description\n```\n\nUse `feat`, `fix`, `perf`, `chore`, `docs`, `test`, or `refactor`. Check recent\n`git log` output before committing to match the repository's current style.\n\n- Use imperative mood.\n- Keep the description under 50 characters when practical.\n- Do not end the description with a period.\n- Include a body for performance changes, bug fixes, and complex changes.\n- For performance changes, include measurements.\n- PR titles should follow the same format as commit messages.\n\nPR descriptions should explain what changed and why in flowing prose. Link\nrelated issues and PRs when they exist. Include only real measurements, and do\nnot include validation/testing boilerplate such as \"Validated with\", \"Tested\nwith\", or command lists unless explicitly requested. Do not use templates,\nbullet lists, or long essays. When writing PR bodies from scripts, use a file or\nheredoc with real newlines; never pass escaped `\\n` sequences.\n\n### Performance PRs\n\nWhen drafting or updating a PR body for a performance-related change, benchmark\nthe feature branch against `master` or the user-specified base before writing the\nperformance claims.\n\n- Use the local benchmark runners under `benches/` unless the user explicitly\n  asks for GitHub Actions or the Derek/decofe automation.\n- Use `foundry-bench` when the claim is about elapsed time for a Foundry command\n  on an existing Solidity project: `forge build`, cached rebuilds, `forge test`,\n  fuzz-test replay, isolated tests, coverage, or focused symbolic tests.\n- For invariant or campaign-style benchmarking, use `foundry-scfuzzbench`; this\n  is the local equivalent of the `derek bench invariant`/`decofe bench\n  invariant` PR flow, which publishes a `scfuzzbench` event.\n- The local runners do not compare two local refs in one invocation. Run the\n  baseline and candidate separately, with identical benchmark inputs, timeout,\n  worker count, environment, target repository, and output schema.\n- For branch-vs-base PR comparisons, use the profiling profile\n  (`FOUNDRY_BENCH_LOCAL_BUILD_PROFILE=profiling`) rather than an ad hoc debug or\n  release build. Keep ordinary `foundry-bench --versions local` comparisons on\n  the default release distribution profile.\n- Include only benchmarks that exercise the changed path. Do not pad the PR body\n  with unrelated benchmark suites.\n- Report both wall-time results and domain counters when available, for example\n  solver queries, reported solver time, throughput, coverage relscore/relcov,\n  or invariant findings.\n- If results are neutral, noisy, or regress a secondary metric, state that\n  directly. Do not convert noise into a performance claim.\n- Keep the PR body short: one paragraph explaining the optimization and why it\n  is correct, followed by a `### Results` table.\n- Exact benchmark commands and result-table mechanics in `benches/README.md`.\n\n## Notes\n\n- The fragment-based changelog workflow has been removed. Do not create or\n  restore `.changelog/` or add changelog fragment files; release notes are\n  generated from pull requests.\n- Use `RUST_LOG=<filter>` for debugging CLI internals, for example\n  `RUST_LOG=forge` or `RUST_LOG=cast`.\n- Do not send spelling-only or grammar-only documentation PRs.\n- Keep release feature lists aligned between the root `Makefile` and release\n  workflows when changing published CLI feature surfaces.\n\n## Code Style\n\n- Comments end with periods (except URLs)\n- Files end with LF and trailing newline\n- Follow existing patterns\n- Never expose secrets\n\n### Rust\n\n- Generally add new Rust functions, methods, `impl` blocks, modules, imports, Cargo dependencies, and other items at the bottom of the relevant scope, section, or group. Constructors usually go at the top of an `impl` block. First check where similar items sit in the file and match the existing order, grouping, and style, including alphabetical order where used.\n- Put doc comments before attributes, always: `/// ...` comes before `#[derive]`, `#[inline]`, `#[cfg]`, and every other attribute.\n- Put module documentation at the top of the module file with inner doc comments (`//! ...`), not on the `mod` item in the parent module.\n- NEVER put imports inside functions unless required for `#[cfg(...)]` gating. All imports go at the top of the file.\n- Group all `use` imports together. Keep `pub use` imports in a separate group. For local module re-exports, write `mod x;` before `pub use x;`; for re-exporting another module or external crate, use `use x;`, then a blank line, then `pub use y;`, then a blank line before local `mod my_mod; pub use my_mod::*;`.\n- Put imports used only by tests inside the relevant `#[cfg(test)]` module, merging them into its ordinary imports instead of adding `#[cfg(test)] use` items to the parent. Keep any additional feature or platform conditions on those imports. Retain parent-level test-gated imports or re-exports only when test-only helpers or multiple test modules need them there.\n- Keep crate-level dependency anchors such as `#[cfg(test)] use cc as _;` at crate scope.\n- Put conditional imports after unconditional imports, separated by a blank line. Group imports with the same `#[cfg(...)]` condition together, with a blank line between different conditions. Apply this to every feature, platform, and test gate, including imports in nested modules. Within each group, merge imports from the same crate when their conditions and other attributes match. Keep the full condition on each `use`; do not introduce import-only modules or macros to avoid repeated attributes. Apply the same ordering within the separate `pub use` group, keeping local re-exports after their module declarations.\n- In test modules, always import the parent module with `use super::*`.\n- In `Cargo.toml`, generally group optional dependencies for a feature together. Put a comment immediately above the group containing only the feature name, for example `# jit`.\n- Prefer `let Some(x) = x else { return };` / `let Ok(x) = x else { return };` over `match x { Some(x) => x, _ => return }`.\n- Use `let ... else` only for a single early-exit guard. When multiple conditions or patterns gate the same block, prefer a combined `if let` / `let` chain instead of several sequential `let ... else` statements.\n- Use combined `if let` chains (`if let Some(x) = x && let Some(y) = y { ... }`) instead of nesting (`if let Some(x) = x { if let Some(y) = y { ... } }`).\n- In loops, prefer an `if let` chain around the loop body over multiple `let ... else { continue };` statements when the body only runs if all patterns match.\n- NEVER use `ref` / `ref mut` in patterns as the first resort. Always prefer borrowing the expression with `&` / `&mut` instead.\n- Prefer map entry APIs such as `entry`, `or_insert`, and `or_insert_with` when multiple consecutive operations would otherwise look up and then insert or update the same key.\n- Avoid specifying type hints in variables unless absolutely necessary (e.g. `HashMap<_, Vec<_>>` for `x.entry(y).or_default().push(z)` where type inference won't work). Rely on the compiler.\n- When type hints are needed, prefer turbofish (`let x = Type::<X, Y>::new()`) over annotation (`let x: Type<X, Y> = Type::new()`).\n- In tests, avoid `.contains` assertions for error/output strings when the project has snapshot testing support such as `snapbox`. Prefer exact snapshot assertions (`stderr_eq`, `stdout_eq`, `assert_data_eq!`, etc.) and use redactions only for genuinely variable parts.\n- Always leave a blank line in between module doc-comments, items or item categories, unless in rare exceptions: it's a one-shot struct with one single impl block, or it's a list of impls that are all very similar. But in general blank line in between items is the norm but it's just unenforced. Items includes imports (together) too. The previous rules apply first.\n","isInternal":false,"tokens":3540,"sizeBytes":15638},{"name":".cursorrules","path":".cursorrules (solidity-foundry-cursorrules-prompt-file.mdc)","rawUrl":"https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/solidity-foundry-cursorrules-prompt-file.mdc","title":"Awesome Cursorrules: solidity foundry","category":"cursor-rule","format":"markdown","content":"---\ndescription: \"Cursor rules for Solidity development with Foundry integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an expert in Solidity and smart contract security.\n\nGeneral Rules\n\n- Cut the fluff. Code or detailed explanations only.\n- Keep it casual and brief.\n- Accuracy and depth matter.\n- Answer first, explain later if needed.\n- Logic trumps authority. Don't care about sources.\n- Embrace new tech and unconventional ideas.\n- Wild speculation's fine, just flag it.\n- Save the ethics talk.\n- Only mention safety for non-obvious, critical issues.\n- Push content limits if needed, explain after.\n- Sources at the end, not mid-text.\n- Skip the AI self-references and knowledge date stuff.\n- Stick to my code style.\n- Use multiple responses for complex answers.\n- For code tweaks, show minimal context - a few lines around changes max.\n- Don't be lazy, write all the code to implement features I ask for.\n- Warn users if they add a private key directly into a non-environment file and replace with an env reference.\n\nSolidity Best Practices\n\n- Use explicit function visibility modifiers and appropriate natspec comments.\n- Utilize function modifiers for common checks, enhancing readability and reducing redundancy.\n- Follow consistent naming: CamelCase for contracts, PascalCase for interfaces (prefixed with \"I\").\n- Implement the Interface Segregation Principle for flexible and maintainable contracts.\n- Design upgradeable contracts using proven patterns like the proxy pattern when necessary.\n- Implement comprehensive events for all significant state changes.\n- Follow the Checks-Effects-Interactions pattern to prevent reentrancy and other vulnerabilities.\n- Use static analysis tools like Slither and Mythril in the development workflow.\n- Implement timelocks and multisig controls for sensitive operations in production.\n- Conduct thorough gas optimization, considering both deployment and runtime costs.\n- Use OpenZeppelin's AccessControl for fine-grained permissions.\n- Use Solidity 0.8.0+ for built-in overflow/underflow protection.\n- Implement circuit breakers (pause functionality) using OpenZeppelin's Pausable when appropriate.\n- Use pull over push payment patterns to mitigate reentrancy and denial of service attacks.\n- Implement rate limiting for sensitive functions to prevent abuse.\n- Use OpenZeppelin's SafeERC20 for interacting with ERC20 tokens.\n- Implement proper randomness using Chainlink VRF or similar oracle solutions.\n- Use assembly for gas-intensive operations, but document extensively and use with caution.\n  - If Solady has an implementation built already, use that instead of writing assembly from scratch.\n- Implement effective state machine patterns for complex contract logic.\n- Use OpenZeppelin's ReentrancyGuard as an additional layer of protection against reentrancy.\n- Implement proper access control for initializers in upgradeable contracts.\n- Use OpenZeppelin's ERC20Snapshot for token balances requiring historical lookups.\n- Implement timelocks for sensitive operations using OpenZeppelin's TimelockController.\n- Use OpenZeppelin's ERC20Permit for gasless approvals in token contracts.\n- Implement proper slippage protection for DEX-like functionalities.\n- Use OpenZeppelin's ERC20Votes for governance token implementations.\n- Implement effective storage patterns to optimize gas costs (e.g., packing variables).\n- Use libraries for complex operations to reduce contract size and improve reusability.\n- Implement proper access control for self-destruct functionality, if used.\n  - Use freezable patterns instead of depricated `selfdestruct`.\n- Use OpenZeppelin's Address library for safe interactions with external contracts.\n- Use custom errors instead of revert strings for gas efficiency and better error handling.\n- Implement NatSpec comments for all public and external functions.\n- Use immutable variables for values set once at construction time.\n- Implement proper inheritance patterns, favoring composition over deep inheritance chains.\n- Use events for off-chain logging and indexing of important state changes.\n- Implement fallback and receive functions with caution, clearly documenting their purpose.\n- Use view and pure function modifiers appropriately to signal state access patterns.\n- Implement proper decimal handling for financial calculations, using fixed-point arithmetic libraries when necessary.\n- Use assembly sparingly and only when necessary for optimizations, with thorough documentation.\n- Implement effective error propagation patterns in internal functions.\n\nTesting and Quality Assurance\n\n- Implement a comprehensive testing strategy including unit, integration, and end-to-end tests.\n- Use a `setup` function in test files to set default state and initialize variables.\n- Use Foundry's fuzzing capabilities to uncover edge cases with property-based testing.\n- Take advantage of Foundry's test cheatcodes for advanced testing scenarios.\n- Write invariant tests for critical contract properties using Foundry's invariant testing features.\n- Use Foundry's Fuzz testing to automatically generate test cases and find edge case bugs.\n- Implement stateful fuzzing tests for complex state transitions.\n- Implement gas usage tests to ensure operations remain efficient.\n- Use Foundry's fork testing capabilities to test against live environments.\n- Implement differential testing by comparing implementations.\n- Conduct regular security audits and bug bounties for production-grade contracts.\n- Use test coverage tools and aim for high test coverage, especially for critical paths.\n- Write appropriate test fixtures using Foundry's standard libraries.\n- Use Foundry's vm.startPrank/vm.stopPrank for testing access control mechanisms.\n- Implement proper setup and teardown in test files.\n- If deterministic testing is being done, ensure that the `foundry.toml` file has `block_number` and `block_timestamp` values.\n\nPerformance Optimization\n\n- Optimize contracts for gas efficiency, considering storage layout and function optimization.\n- Implement efficient indexing and querying strategies for off-chain data.\n\nDevelopment Workflow\n\n- Utilize Foundry's forge for compilation, testing, and deployment.\n- Use Foundry's cast for command-line interaction with contracts.\n- Implement comprehensive Foundry scripts for deployment and verification.\n- Use Foundry's script capabilities for complex deployment sequences.\n- Implement a robust CI/CD pipeline for smart contract deployments.\n- Use static type checking and linting tools in pre-commit hooks.\n- Utilize `forge fmt` if prompted about consistent code formatting.\n\nDocumentation\n\n- Document code thoroughly, focusing on why rather than what.\n- Maintain up-to-date API documentation for smart contracts.\n- Create and maintain comprehensive project documentation, including architecture diagrams and decision logs.\n- Document test scenarios and their purpose clearly.\n- Document any assumptions made in the contract design.\n\nDependencies\n\n- Use OpenZeppelin (openzeppelin/openzeppelin-contracts) as the main source of dependencies.\n- Use Solady (vectorized/solady) when gas optimization is crucial.\n- Ensure that any libraries used are installed with forge, and remappings are set.\n- Place remappings in `foundry.toml` instead of a `remappings.txt` file.\n\nConfiguring Environment\n\nOne or more of the following profiles can be added to `foundry.toml` as needed for the project.\n\n- When via_ir is required:\n\n```\n# via_ir pipeline is very slow - use a separate profile to pre-compile and then use vm.getCode to deploy\n[profile.via_ir]\nvia_ir = true\n# do not compile tests when compiling via-ir\ntest = 'src'\nout = 'via_ir-out'\n```\n\n- When deterministic deployment is required:\n\n```\n[profile.deterministic]\n# ensure that block number + timestamp are realistic when running tests\nblock_number = 17722462\nblock_timestamp = 1689711647\n# don't pollute bytecode with metadata\nbytecode_hash = 'none'\ncbor_metadata = false\n```\n","tokens":1555,"sizeBytes":7946}],"systemPromptSnippet":"<yakaai_skills repo=\"foundry-rs/foundry\">\n<!-- File: AGENTS.md (Tokens: ~3540 | Category: root-instruction) -->\n# AGENTS.md\n\nGuidance for AI coding agents working in this repository.\n\n## Project Overview\n\nFoundry is a fast, portable, modular toolkit for Ethereum application development,\nwritten in Rust.\n\n- `forge`: build, test, fuzz, debug, lint, and deploy Solidity contracts\n- `cast`: command-line utilities for EVM contracts, transactions, and chain data\n- `anvil`: local Ethereum development node\n- `chisel`: Solidity REPL\n\nThe repository is a Cargo workspace. Core crates live under `crates/`, Solidity\nfixtures and integration test projects live under `testdata/`, and the\n[developer documentation](docs/dev/README.md) defines documentation ownership\nand indexes maintained cross-crate guides.\n\n## Commands\n\n```bash\ncargo build --workspace                               # Build the workspace\ncargo nextest run --workspace                         # Run tests\ncargo +nightly fmt --all                              # Format Rust code\ncargo +nightly fmt --all -- --check                   # Check Rust formatting\ncargo +nightly clippy --workspace --all-targets --all-features # Lint Rust code\ncargo deny check                                      # Check dependencies\ncargo shear                                           # Check unused dependencies\n```\n\nRust formatting uses nightly.\n\n## Architecture\n\n- `crates/forge`: Forge CLI and test/build workflows\n- `crates/cast`: Cast CLI commands\n- `crates/anvil`: local Ethereum node\n- `crates/chisel`: Solidity REPL\n- `crates/cheatcodes`: Forge cheatcode definitions and implementations\n- `crates/common`: shared CLI, shell, compile, and terminal utilities\n- `crates/config`: Foundry configuration\n- `crates/debugger`: debugger support\n- `crates/lint`: Solidity linter\n- `crates/script`: script execution support\n- `crates/verify`: contract verification support\n\nFoundry's EVM execution tooling is built around `revm`. Cheatcodes are calls to\nthe fixed cheatcode address and are dispatched through the cheatcode inspector.\nFor custom network work, follow the ownership, state-lifecycle, tool-dispatch,\nand CI checklist in [`docs/dev/networks.md`](docs/dev/networks.md).\n\nFor symbolic execution work under `crates/evm/symbolic`, read\n`crates/evm/symbolic/AGENTS.md` before editing.\n\n## Reuse and ownership\n\nBefore you build, convert, compare, or format a revm, alloy, or Foundry value by\nhand, check the owning type and crate for a canonical constructor, alias,\nconversion, or predicate. For example, use `BlockId::latest()`, `InMemoryDB`,\n`From` between `U256` and `B256`, and `AccountInfo::is_empty_code_hash()`.\nReuse the shared helpers in `foundry_common` and `foundry_config`, such as path,\nJSON, and provider construction helpers, instead of local copies. Apply this to\nthe code that you add or change, not as a repository-wide sweep.\n\nPut new behavior in the component that owns the authoritative state, and use\nits canonical entry point. Callers must not mirror or select behavior that an\nexecutor, backend, network implementation, or module already owns, so do not\nadd parameters, marker types, or parallel context objects for it. Keep custom\nnetwork behavior behind the ownership boundary in\n[`docs/dev/networks.md`](docs/dev/networks.md): select the execution family once\nat the outermost boundary, and do not add family checks below that dispatch.\n\n## Testing\n\n- Add tests for code changes that fix behavior or add functionality.\n- Use focused unit tests for small pure logic.\n- Use integration tests for CLI behavior and larger workflows.\n- Tests that use forking must contain `fork` in their name.\n- Forge integration fixtures live under `testdata/`.\n- Lint rule tests live under `crates/lint/testdata/` with blessed `.stderr`\n  output.\n\nFor CLI and integration tests:\n\n- Put Forge CLI coverage under `crates/forge/tests/cli/` and Cast CLI coverage\n  under `crates/cast/tests/cli/`.\n- Use the existing `#[forgetest]`, `#[forgetest_init]`, and `#[casttest]`\n  macros to create isolated test projects and command handles.\n- Assert command output with snapbox helpers such as `assert_success()`,\n  `assert_failure()`, `stdout_eq(str![...])`, `stderr_eq(str![...])`, and\n  `assert_empty_stdout()`.\n- For JSON output, use `assert_json_stdout(...)` or `assert_json_stderr(...)`\n  so comparisons are parsed as JSON and unordered where appropriate.\n- Prefer full output snapshots with redactions over ad hoc `String::contains`\n  checks or manual `serde_json::Value` inspection.\n\nFor lint rules:\n\n- Follow `docs/dev/lintrules.md#lint-writing-style` and `crates/lint/docs/README.md` for\n  lint names, diagnostic wording, and reference-page structure.\n- Update `crates/lint/docs/<id>.md` in the same Foundry PR as the lint. The Book's\n  `import:lints` workflow generates the published reference pages and navigation.\n- Add a Solidity test file under `crates/lint/testdata/`.\n- Use `//~WARN:` and `//~NOTE:` annotations for expected diagnostics.\n- Regenerate blessed output with `cargo bless-lints`.\n- Run lint UI tests with `cargo nextest run -p forge --test ui`.\n\nFor script work, keep the two execution phases separate: `ScriptArgs::execute`\nruns the script, while on-chain simulation only executes the collected\nbroadcastable transactions. `--resume` resumes publishing transactions; it does\nnot recreate the original `--broadcast` state.\n\nFor fuzz or invariant corpus coverage work, `forge test --showmap-out <DIR>`\nreplays persisted corpus entries and writes AFL `showmap`-style coverage files.\n\n## CLI Output\n\nFollow [`docs/dev/output-channels.md`](docs/dev/output-channels.md), the canonical\nstdout/stderr contract. Use the `foundry_common::io` `sh_*` and `prompt!` macros;\nworkspace Clippy configuration forbids direct `std::print*` and `std::eprint*`.\n\n## Configuration\n\nWhen adding or changing a `foundry.toml` setting:\n\n1. Define the field and its documentation in `crates/config`, including an\n   explicit default and any required serde behavior. Keep related settings in a\n   dedicated nested config type when they form a coherent section.\n2. Wire the setting through every command that consumes it. If a CLI flag can\n   override the setting, resolve precedence in one shared place and test config,\n   CLI, and combined behavior.\n3. Add focused config parsing and serialization tests. Update the `forge config`\n   and default-config snapshots when the serialized surface changes.\n4. For renamed or moved settings, preserve compatibility when practical and add\n   a targeted deprecation warning that points to the canonical key. Test aliases,\n   profiles, inheritance, environment variables, collisions, and malformed values\n   where those providers are affected.\n5. Document the setting in `foundry-rs/book` under\n   `src/pages/config/reference/`, including its section, type, default, environment\n   variable when supported, behavior, and a valid TOML example. Update the config\n   reference navigation and `default-config.mdx` in the same documentation PR.\n6. Keep CLI option text in the Rust clap definition; the book's CLI reference is\n   generated from command help and should not be edited by hand.\n\nUse the implementation, defaults, and tests as the source of truth. Do not merge\nnew user-facing configuration without the corresponding book update.\n\n## Cheatcodes\n\nWhen adding a cheatcode:\n\n1. Add the Solidity definition in `crates/cheatcodes/spec/src/vm.rs`.\n2. Implement the generated call type in `crates/cheatcodes/`.\n3. Update `spec::Cheatcodes::new` if `Vm` gained a struct, enum, error, or event.\n4. Run `cargo cheats` twice to update generated JSON assets.\n5. Add an integration test under `testdata/default/cheats/`.\n\nCheatcode functions and structs must be documented and function parameters must\nbe named.\n\n## Commit and PR Style\n\nDefault format is conventional commits:\n\n```text\ntype: description\ntype(scope): description\ntype(scope)!: breaking description\n```\n\nUse `feat`, `fix`, `perf`, `chore`, `docs`, `test`, or `refactor`. Check recent\n`git log` output before committing to match the repository's current style.\n\n- Use imperative mood.\n- Keep the description under 50 characters when practical.\n- Do not end the description with a period.\n- Include a body for performance changes, bug fixes, and complex changes.\n- For performance changes, include measurements.\n- PR titles should follow the same format as commit messages.\n\nPR descriptions should explain what changed and why in flowing prose. Link\nrelated issues and PRs when they exist. Include only real measurements, and do\nnot include validation/testing boilerplate such as \"Validated with\", \"Tested\nwith\", or command lists unless explicitly requested. Do not use templates,\nbullet lists, or long essays. When writing PR bodies from scripts, use a file or\nheredoc with real newlines; never pass escaped `\\n` sequences.\n\n### Performance PRs\n\nWhen drafting or updating a PR body for a performance-related change, benchmark\nthe feature branch against `master` or the user-specified base before writing the\nperformance claims.\n\n- Use the local benchmark runners under `benches/` unless the user explicitly\n  asks for GitHub Actions or the Derek/decofe automation.\n- Use `foundry-bench` when the claim is about elapsed time for a Foundry command\n  on an existing Solidity project: `forge build`, cached rebuilds, `forge test`,\n  fuzz-test replay, isolated tests, coverage, or focused symbolic tests.\n- For invariant or campaign-style benchmarking, use `foundry-scfuzzbench`; this\n  is the local equivalent of the `derek bench invariant`/`decofe bench\n  invariant` PR flow, which publishes a `scfuzzbench` event.\n- The local runners do not compare two local refs in one invocation. Run the\n  baseline and candidate separately, with identical benchmark inputs, timeout,\n  worker count, environment, target repository, and output schema.\n- For branch-vs-base PR comparisons, use the profiling profile\n  (`FOUNDRY_BENCH_LOCAL_BUILD_PROFILE=profiling`) rather than an ad hoc debug or\n  release build. Keep ordinary `foundry-bench --versions local` comparisons on\n  the default release distribution profile.\n- Include only benchmarks that exercise the changed path. Do not pad the PR body\n  with unrelated benchmark suites.\n- Report both wall-time results and domain counters when available, for example\n  solver queries, reported solver time, throughput, coverage relscore/relcov,\n  or invariant findings.\n- If results are neutral, noisy, or regress a secondary metric, state that\n  directly. Do not convert noise into a performance claim.\n- Keep the PR body short: one paragraph explaining the optimization and why it\n  is correct, followed by a `### Results` table.\n- Exact benchmark commands and result-table mechanics in `benches/README.md`.\n\n## Notes\n\n- The fragment-based changelog workflow has been removed. Do not create or\n  restore `.changelog/` or add changelog fragment files; release notes are\n  generated from pull requests.\n- Use `RUST_LOG=<filter>` for debugging CLI internals, for example\n  `RUST_LOG=forge` or `RUST_LOG=cast`.\n- Do not send spelling-only or grammar-only documentation PRs.\n- Keep release feature lists aligned between the root `Makefile` and release\n  workflows when changing published CLI feature surfaces.\n\n## Code Style\n\n- Comments end with periods (except URLs)\n- Files end with LF and trailing newline\n- Follow existing patterns\n- Never expose secrets\n\n### Rust\n\n- Generally add new Rust functions, methods, `impl` blocks, modules, imports, Cargo dependencies, and other items at the bottom of the relevant scope, section, or group. Constructors usually go at the top of an `impl` block. First check where similar items sit in the file and match the existing order, grouping, and style, including alphabetical order where used.\n- Put doc comments before attributes, always: `/// ...` comes before `#[derive]`, `#[inline]`, `#[cfg]`, and every other attribute.\n- Put module documentation at the top of the module file with inner doc comments (`//! ...`), not on the `mod` item in the parent module.\n- NEVER put imports inside functions unless required for `#[cfg(...)]` gating. All imports go at the top of the file.\n- Group all `use` imports together. Keep `pub use` imports in a separate group. For local module re-exports, write `mod x;` before `pub use x;`; for re-exporting another module or external crate, use `use x;`, then a blank line, then `pub use y;`, then a blank line before local `mod my_mod; pub use my_mod::*;`.\n- Put imports used only by tests inside the relevant `#[cfg(test)]` module, merging them into its ordinary imports instead of adding `#[cfg(test)] use` items to the parent. Keep any additional feature or platform conditions on those imports. Retain parent-level test-gated imports or re-exports only when test-only helpers or multiple test modules need them there.\n- Keep crate-level dependency anchors such as `#[cfg(test)] use cc as _;` at crate scope.\n- Put conditional imports after unconditional imports, separated by a blank line. Group imports with the same `#[cfg(...)]` condition together, with a blank line between different conditions. Apply this to every feature, platform, and test gate, including imports in nested modules. Within each group, merge imports from the same crate when their conditions and other attributes match. Keep the full condition on each `use`; do not introduce import-only modules or macros to avoid repeated attributes. Apply the same ordering within the separate `pub use` group, keeping local re-exports after their module declarations.\n- In test modules, always import the parent module with `use super::*`.\n- In `Cargo.toml`, generally group optional dependencies for a feature together. Put a comment immediately above the group containing only the feature name, for example `# jit`.\n- Prefer `let Some(x) = x else { return };` / `let Ok(x) = x else { return };` over `match x { Some(x) => x, _ => return }`.\n- Use `let ... else` only for a single early-exit guard. When multiple conditions or patterns gate the same block, prefer a combined `if let` / `let` chain instead of several sequential `let ... else` statements.\n- Use combined `if let` chains (`if let Some(x) = x && let Some(y) = y { ... }`) instead of nesting (`if let Some(x) = x { if let Some(y) = y { ... } }`).\n- In loops, prefer an `if let` chain around the loop body over multiple `let ... else { continue };` statements when the body only runs if all patterns match.\n- NEVER use `ref` / `ref mut` in patterns as the first resort. Always prefer borrowing the expression with `&` / `&mut` instead.\n- Prefer map entry APIs such as `entry`, `or_insert`, and `or_insert_with` when multiple consecutive operations would otherwise look up and then insert or update the same key.\n- Avoid specifying type hints in variables unless absolutely necessary (e.g. `HashMap<_, Vec<_>>` for `x.entry(y).or_default().push(z)` where type inference won't work). Rely on the compiler.\n- When type hints are needed, prefer turbofish (`let x = Type::<X, Y>::new()`) over annotation (`let x: Type<X, Y> = Type::new()`).\n- In tests, avoid `.contains` assertions for error/output strings when the project has snapshot testing support such as `snapbox`. Prefer exact snapshot assertions (`stderr_eq`, `stdout_eq`, `assert_data_eq!`, etc.) and use redactions only for genuinely variable parts.\n- Always leave a blank line in between module doc-comments, items or item categories, unless in rare exceptions: it's a one-shot struct with one single impl block, or it's a list of impls that are all very similar. But in general blank line in between items is the norm but it's just unenforced. Items includes imports (together) too. The previous rules apply first.\n\n<!-- File: .cursorrules (solidity-foundry-cursorrules-prompt-file.mdc) (Tokens: ~1555 | Category: cursor-rule) -->\n---\ndescription: \"Cursor rules for Solidity development with Foundry integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an expert in Solidity and smart contract security.\n\nGeneral Rules\n\n- Cut the fluff. Code or detailed explanations only.\n- Keep it casual and brief.\n- Accuracy and depth matter.\n- Answer first, explain later if needed.\n- Logic trumps authority. Don't care about sources.\n- Embrace new tech and unconventional ideas.\n- Wild speculation's fine, just flag it.\n- Save the ethics talk.\n- Only mention safety for non-obvious, critical issues.\n- Push content limits if needed, explain after.\n- Sources at the end, not mid-text.\n- Skip the AI self-references and knowledge date stuff.\n- Stick to my code style.\n- Use multiple responses for complex answers.\n- For code tweaks, show minimal context - a few lines around changes max.\n- Don't be lazy, write all the code to implement features I ask for.\n- Warn users if they add a private key directly into a non-environment file and replace with an env reference.\n\nSolidity Best Practices\n\n- Use explicit function visibility modifiers and appropriate natspec comments.\n- Utilize function modifiers for common checks, enhancing readability and reducing redundancy.\n- Follow consistent naming: CamelCase for contracts, PascalCase for interfaces (prefixed with \"I\").\n- Implement the Interface Segregation Principle for flexible and maintainable contracts.\n- Design upgradeable contracts using proven patterns like the proxy pattern when necessary.\n- Implement comprehensive events for all significant state changes.\n- Follow the Checks-Effects-Interactions pattern to prevent reentrancy and other vulnerabilities.\n- Use static analysis tools like Slither and Mythril in the development workflow.\n- Implement timelocks and multisig controls for sensitive operations in production.\n- Conduct thorough gas optimization, considering both deployment and runtime costs.\n- Use OpenZeppelin's AccessControl for fine-grained permissions.\n- Use Solidity 0.8.0+ for built-in overflow/underflow protection.\n- Implement circuit breakers (pause functionality) using OpenZeppelin's Pausable when appropriate.\n- Use pull over push payment patterns to mitigate reentrancy and denial of service attacks.\n- Implement rate limiting for sensitive functions to prevent abuse.\n- Use OpenZeppelin's SafeERC20 for interacting with ERC20 tokens.\n- Implement proper randomness using Chainlink VRF or similar oracle solutions.\n- Use assembly for gas-intensive operations, but document extensively and use with caution.\n  - If Solady has an implementation built already, use that instead of writing assembly from scratch.\n- Implement effective state machine patterns for complex contract logic.\n- Use OpenZeppelin's ReentrancyGuard as an additional layer of protection against reentrancy.\n- Implement proper access control for initializers in upgradeable contracts.\n- Use OpenZeppelin's ERC20Snapshot for token balances requiring historical lookups.\n- Implement timelocks for sensitive operations using OpenZeppelin's TimelockController.\n- Use OpenZeppelin's ERC20Permit for gasless approvals in token contracts.\n- Implement proper slippage protection for DEX-like functionalities.\n- Use OpenZeppelin's ERC20Votes for governance token implementations.\n- Implement effective storage patterns to optimize gas costs (e.g., packing variables).\n- Use libraries for complex operations to reduce contract size and improve reusability.\n- Implement proper access control for self-destruct functionality, if used.\n  - Use freezable patterns instead of depricated `selfdestruct`.\n- Use OpenZeppelin's Address library for safe interactions with external contracts.\n- Use custom errors instead of revert strings for gas efficiency and better error handling.\n- Implement NatSpec comments for all public and external functions.\n- Use immutable variables for values set once at construction time.\n- Implement proper inheritance patterns, favoring composition over deep inheritance chains.\n- Use events for off-chain logging and indexing of important state changes.\n- Implement fallback and receive functions with caution, clearly documenting their purpose.\n- Use view and pure function modifiers appropriately to signal state access patterns.\n- Implement proper decimal handling for financial calculations, using fixed-point arithmetic libraries when necessary.\n- Use assembly sparingly and only when necessary for optimizations, with thorough documentation.\n- Implement effective error propagation patterns in internal functions.\n\nTesting and Quality Assurance\n\n- Implement a comprehensive testing strategy including unit, integration, and end-to-end tests.\n- Use a `setup` function in test files to set default state and initialize variables.\n- Use Foundry's fuzzing capabilities to uncover edge cases with property-based testing.\n- Take advantage of Foundry's test cheatcodes for advanced testing scenarios.\n- Write invariant tests for critical contract properties using Foundry's invariant testing features.\n- Use Foundry's Fuzz testing to automatically generate test cases and find edge case bugs.\n- Implement stateful fuzzing tests for complex state transitions.\n- Implement gas usage tests to ensure operations remain efficient.\n- Use Foundry's fork testing capabilities to test against live environments.\n- Implement differential testing by comparing implementations.\n- Conduct regular security audits and bug bounties for production-grade contracts.\n- Use test coverage tools and aim for high test coverage, especially for critical paths.\n- Write appropriate test fixtures using Foundry's standard libraries.\n- Use Foundry's vm.startPrank/vm.stopPrank for testing access control mechanisms.\n- Implement proper setup and teardown in test files.\n- If deterministic testing is being done, ensure that the `foundry.toml` file has `block_number` and `block_timestamp` values.\n\nPerformance Optimization\n\n- Optimize contracts for gas efficiency, considering storage layout and function optimization.\n- Implement efficient indexing and querying strategies for off-chain data.\n\nDevelopment Workflow\n\n- Utilize Foundry's forge for compilation, testing, and deployment.\n- Use Foundry's cast for command-line interaction with contracts.\n- Implement comprehensive Foundry scripts for deployment and verification.\n- Use Foundry's script capabilities for complex deployment sequences.\n- Implement a robust CI/CD pipeline for smart contract deployments.\n- Use static type checking and linting tools in pre-commit hooks.\n- Utilize `forge fmt` if prompted about consistent code formatting.\n\nDocumentation\n\n- Document code thoroughly, focusing on why rather than what.\n- Maintain up-to-date API documentation for smart contracts.\n- Create and maintain comprehensive project documentation, including architecture diagrams and decision logs.\n- Document test scenarios and their purpose clearly.\n- Document any assumptions made in the contract design.\n\nDependencies\n\n- Use OpenZeppelin (openzeppelin/openzeppelin-contracts) as the main source of dependencies.\n- Use Solady (vectorized/solady) when gas optimization is crucial.\n- Ensure that any libraries used are installed with forge, and remappings are set.\n- Place remappings in `foundry.toml` instead of a `remappings.txt` file.\n\nConfiguring Environment\n\nOne or more of the following profiles can be added to `foundry.toml` as needed for the project.\n\n- When via_ir is required:\n\n```\n# via_ir pipeline is very slow - use a separate profile to pre-compile and then use vm.getCode to deploy\n[profile.via_ir]\nvia_ir = true\n# do not compile tests when compiling via-ir\ntest = 'src'\nout = 'via_ir-out'\n```\n\n- When deterministic deployment is required:\n\n```\n[profile.deterministic]\n# ensure that block number + timestamp are realistic when running tests\nblock_number = 17722462\nblock_timestamp = 1689711647\n# don't pollute bytecode with metadata\nbytecode_hash = 'none'\ncbor_metadata = false\n```\n</yakaai_skills>"}