{"id":24489814,"url":"https://github.com/bluntbrain/invariant-testing-foundry","last_synced_at":"2026-02-17T10:34:26.417Z","repository":{"id":270660853,"uuid":"911062017","full_name":"bluntbrain/invariant-testing-foundry","owner":"bluntbrain","description":"A comprehensive guide to Foundry's testing capabilities including Fuzz Testing and Invariant Testing","archived":false,"fork":false,"pushed_at":"2025-01-03T08:38:27.000Z","size":126,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-09T01:09:18.405Z","etag":null,"topics":["foundry","fuzzing","invariants","solidity"],"latest_commit_sha":null,"homepage":"https://bluntbrain.vercel.app/","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluntbrain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-01-02T06:44:29.000Z","updated_at":"2025-01-05T02:01:17.000Z","dependencies_parsed_at":"2025-01-05T14:14:41.524Z","dependency_job_id":null,"html_url":"https://github.com/bluntbrain/invariant-testing-foundry","commit_stats":null,"previous_names":["bluntbrain/invariant-testing-foundry"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bluntbrain/invariant-testing-foundry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Finvariant-testing-foundry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Finvariant-testing-foundry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Finvariant-testing-foundry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Finvariant-testing-foundry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluntbrain","download_url":"https://codeload.github.com/bluntbrain/invariant-testing-foundry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Finvariant-testing-foundry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29540134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T08:11:05.436Z","status":"ssl_error","status_checked_at":"2026-02-17T08:09:38.860Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["foundry","fuzzing","invariants","solidity"],"created_at":"2025-01-21T17:16:10.325Z","updated_at":"2026-02-17T10:34:26.348Z","avatar_url":"https://github.com/bluntbrain.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Smart Contract Testing Examples\n\u003e A comprehensive guide to Foundry's testing capabilities including Fuzz Testing and Invariant Testing\n\n## Overview\nThis repository demonstrates different testing methodologies in Foundry, focusing on:\n- Fuzz Testing\n- Invariant Testing\n- Stateless vs Stateful Testing\n- Handler-based Testing\n\n## Test Structure\n\n### 1. Mock Contracts\n- `MockUSDC.sol`: Basic ERC20 implementation for testing\n- `MockWETH.sol`: WETH implementation with deposit/withdraw\n- `YieldERC20.sol`: ERC20 with fee mechanism (10% fee every 10 transactions)\n\n### 2. Testing Approaches\n\n#### A. Fuzz Testing\n- Automatically generates random inputs\n- Tests function behavior across many scenarios\n- Example: `testInvariantBreakHard(uint256 randomAmount)`\n```solidity\nfunction testInvariantBreakHard(uint256 randomAmount) public {\n    vm.assume(randomAmount \u003c startingAmount);\n    // Test deposit/withdraw cycles\n}\n```\n\n#### B. Invariant Testing\nTwo main approaches:\n\n1. **Stateless Testing**\n- Tests individual function calls\n- No state maintained between calls\n- Limited in catching complex bugs\n```solidity\n// Example in StatelessFuzzCatchesTest.t.sol\n```\n\n2. **Stateful Testing**\n- Maintains state between function calls\n- Tests sequences of operations\n- Better at finding complex bugs\n```solidity\n// Example in StatefulFuzzCatchesTest.t.sol\n```\n\n#### C. Handler Pattern\nLocated in `test/invariant/HandlerStatefulFuzz/`\n\n1. **Handler Contract**\n- Controls test flow\n- Bounds input values\n- Manages function sequences\n```solidity\nfunction depositYeildERC20(uint256 _amount) public {\n    uint256 amount = bound(_amount, 0, yeildERC20.balanceOf(owner));\n    // ... deposit logic\n}\n```\n\n2. **Invariant Tests with Handler**\n```solidity\ncontract InvariantBreakHardTest {\n    function setUp() public {\n        // Setup handler and target selectors\n        targetSelector(FuzzSelector({\n            addr: address(handler),\n            selectors: selectors\n        }));\n    }\n}\n```\n\n## Key Features\n\n### Invariant Properties Tested\n- Token balances after operations\n- Ownership consistency\n- Fee mechanism correctness\n\n### Test Coverage\n- Deposit/Withdraw cycles\n- Fee calculations\n- Balance tracking\n- Owner operations\n\n## Running Tests\n\n```bash\n# Run all tests\nforge test\n\n# Run specific test file\nforge test --match-path test/invariant/HandlerStatefulFuzz/Invariant.t.sol\n\n# Run with verbosity\nforge test -vvv\n```\n\n## Key Learnings\n1. Simple fuzz testing may miss complex bugs\n2. Stateful testing with handlers provides better coverage\n3. Invariant testing helps verify persistent properties\n4. Handlers help control test flow and bound inputs\n\n## Project Structure\n```\n├── src/\n│   └── HandlerStatefulFuzzCatches.sol\n├── test/\n│   ├── mocks/\n│   │   ├── MockUSDC.sol\n│   │   ├── MockWETH.sol\n│   │   └── YeildERC20.sol\n│   └── invariant/\n│       └── HandlerStatefulFuzz/\n│           ├── Handler.t.sol\n│           ├── Invariant.t.sol\n│           └── InvariantFail.t.sol\n```\n\n## Dependencies\n- Foundry\n- OpenZeppelin Contracts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluntbrain%2Finvariant-testing-foundry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluntbrain%2Finvariant-testing-foundry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluntbrain%2Finvariant-testing-foundry/lists"}