{"id":25237193,"url":"https://github.com/perimetersec/fuzzlib","last_synced_at":"2025-10-06T13:54:30.408Z","repository":{"id":213098534,"uuid":"733024799","full_name":"perimetersec/fuzzlib","owner":"perimetersec","description":"General purpose unopinionated Solidity fuzzing library for stateful and stateless fuzzing","archived":false,"fork":false,"pushed_at":"2025-07-18T13:18:18.000Z","size":133,"stargazers_count":52,"open_issues_count":10,"forks_count":14,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-16T09:59:42.356Z","etag":null,"topics":["echidna","evm","foundry","fuzzing","library","medusa","solidity"],"latest_commit_sha":null,"homepage":"https://www.perimetersec.io","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/perimetersec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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":"2023-12-18T11:49:42.000Z","updated_at":"2025-09-05T10:07:59.000Z","dependencies_parsed_at":"2023-12-21T01:11:44.691Z","dependency_job_id":"ed5b1fba-d5c1-41b2-a509-615d2a9836df","html_url":"https://github.com/perimetersec/fuzzlib","commit_stats":null,"previous_names":["perimetersec/fuzzlib"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/perimetersec/fuzzlib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perimetersec%2Ffuzzlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perimetersec%2Ffuzzlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perimetersec%2Ffuzzlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perimetersec%2Ffuzzlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/perimetersec","download_url":"https://codeload.github.com/perimetersec/fuzzlib/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perimetersec%2Ffuzzlib/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278621837,"owners_count":26017253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["echidna","evm","foundry","fuzzing","library","medusa","solidity"],"created_at":"2025-02-11T15:33:37.918Z","updated_at":"2025-10-06T13:54:30.390Z","avatar_url":"https://github.com/perimetersec.png","language":"Solidity","funding_links":[],"categories":["Tooling"],"sub_categories":["Libraries \u0026 Frameworks"],"readme":"# Fuzzlib\n\nGeneral purpose unopinionated Solidity fuzzing library for stateful and stateless fuzzing. Compatible with Echidna, Medusa, and Foundry.\n\nProvides common utilities for fuzz testing through a simple `fl` namespace: assertions, value clamping, logging, math operations, and more.\n\n## Key Features\n\n- **Basic Assertions**: Helpers for common test conditions and equality checks \n- **Advanced Assertions**: Utilities like error handling via `errAllow` for expected failures\n- **Value Clamping**: Clamp values to ranges with uniform distribution for better fuzzing\n- **Logging Utilities**: Unified logging for debugging and tracing\n- **Math Utilities**: Operations like min, max, absolute value, and difference calculations\n- **Random Utilities**: Fisher-Yates array shuffling\n- **Function Call Helpers**: Utilities for making function calls with actor pranking\n- **Comprehensive Testing**: Extensive test suite with both unit and fuzz tests\n- **Well-Documented**: Clear and complete, following OpenZeppelin-style conventions\n\n## Installation\n\n### Using Foundry\n\n```bash\nforge install perimetersec/fuzzlib\n```\n\n### Using Soldeer\n\n```bash\nsoldeer install perimetersec-fuzzlib~1.0.0\n```\n\n### Using npm\n\n```bash\nnpm install @perimetersec/fuzzlib\n```\n\nAdd to your `remappings.txt`:\n```\nfuzzlib/=lib/fuzzlib/src/\n```\n\n## Quick Start\n\nCreate a simple fuzzing test by extending `FuzzBase`:\n\n```solidity\nimport {FuzzBase} from \"fuzzlib/FuzzBase.sol\";\n\ncontract MyFuzzer is FuzzBase {\n    function testMath(uint256 a, uint256 b) public {\n        // Clamp inputs to reasonable ranges\n        uint256 x = fl.clamp(a, 0, 1000);\n        uint256 y = fl.clamp(b, 0, 1000);\n         \n        // Log for debugging\n        fl.log(\"Testing max function. x =\", x);\n        fl.log(\"Testing max function. y =\", y);\n       \n        // Test mathematical properties\n        fl.gte(fl.max(x, y), x, \"Max should be \u003e= x\");\n        fl.gte(fl.max(x, y), y, \"Max should be \u003e= y\");\n    }\n}\n```\n\n\n## Function Reference\n\n### Basic Assertions\n\n```solidity\n// Fundamental assertions\nfl.t(exists, \"Property X exists\");\nfl.eq(result, 100, \"Result should equal 100\");\nfl.neq(userA, userB, \"Users should be different\");\n\n// Comparison assertions\nfl.gt(balance, 1000, \"Balance should be greater than 1000\");\nfl.gte(amount, 50, \"Amount should be greater than or equal to 50\");\nfl.lt(fee, 100, \"Fee should be less than 100\");\nfl.lte(price, 500, \"Price should be less than or equal to 500\");\n```\n\n### Advanced Assertions\n\n```solidity\n// Allow specific require messages\nstring[] memory allowedMessages = new string[](1);\nallowedMessages[0] = \"Insufficient balance\";\nfl.errAllow(errorData, allowedMessages, \"Message X should be allowed\");\n\n// Allow specific custom errors\nbytes4[] memory allowedErrors = new bytes4[](1);\nallowedErrors[0] = CustomError.selector;\nfl.errAllow(errorSelector, allowedErrors, \"Error X should be allowed\");\n\n// Combined error handling\nfl.errAllow(errorData, allowedMessages, allowedErrors, \"Either should be allowed\");\n```\n\n### Value Clamping\n\n```solidity\n// Value clamping with uniform distribution\nuint256 clamped = fl.clamp(inputValue, 0, 100);\n\n// Clamp to greater than value\nuint256 clampedGt = fl.clampGt(inputValue, 50);\n\n// Clamp to greater than or equal\nuint256 clampedGte = fl.clampGte(inputValue, 50);\n\n// Clamp to less than value\nuint256 clampedLt = fl.clampLt(inputValue, 100);\n\n// Clamp to less than or equal\nuint256 clampedLte = fl.clampLte(inputValue, 100);\n```\n\n### Logging\n\n```solidity\n// Simple logging\nfl.log(\"Testing scenario\");\n\n// Logging with values\nfl.log(\"Balance:\", balance);\nfl.log(\"User count:\", 42);\n\n// Failure logging\nfl.logFail(\"This test failed\");\nfl.logFail(\"Invalid amount:\", amount);\n```\n\n### Math Utilities\n\n```solidity\n// Min/max operations\nuint256 maximum = fl.max(150, 300);\nint256 minimum = fl.min(-50, 25);\n\n// Absolute value and difference\nuint256 absolute = fl.abs(-42);\nuint256 difference = fl.diff(100, 75);\n```\n\n### Random Utilities\n\n```solidity\n// Shuffle arrays\nuint256[] memory array = new uint256[](10);\nfl.shuffleArray(array, entropy);\n```\n\n### Function Call Helpers\n\n```solidity\n// Make function calls\nbytes memory result = fl.doFunctionCall(\n    address(target),\n    abi.encodeWithSignature(\"getValue()\"),\n    msg.sender  // actor\n);\n\n// Calls with automatic pranking\n(bool success, bytes memory data) = fl.doFunctionCall(\n    address(target),\n    abi.encodeWithSignature(\"transfer(address,uint256)\", recipient, amount),\n    sender\n);\n\n// Static calls (view functions)\n(bool success, bytes memory data) = fl.doFunctionStaticCall(\n    address(target),\n    abi.encodeWithSignature(\"balanceOf(address)\", user)\n);\n```\n\n## Known Limitations\n\n- **Signed Integer Clamping**: Limited to `int128` range to avoid overflow issues in range calculations\n- **Gas Optimization**: Library prioritizes functionality over gas optimization\n- **Function Selector Clashing**: If the error selector clashes with `Error(string)` when using errAllow, unexpected behavior may happen\n\n\n## Roadmap\n\n- [ ] Support for more platforms\n- [ ] Add more helper functions\n- [ ] Performance optimizations\n\n\n## Contributing\n\nWe welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.\n\n\n## License\n\nThis project is licensed under the GNU General Public License v3.0. See the [LICENSE](LICENSE) file for details.\n\nSome portions of this code are modified from [Crytic Properties](https://github.com/crytic/properties/blob/main/contracts/util/PropertiesHelper.sol), which is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).\n\nSome portions of this code are modified from [OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol), which is licensed under the MIT License.\n\n\n## Disclaimer\n\nThis software is provided as-is without warranty. The main branch contains new and experimental features that may be unstable. For production use, we recommend using official tagged releases which have been thoroughly tested. While we are not responsible for any bugs or issues, we maintain a bug bounty program that applies to official releases only.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperimetersec%2Ffuzzlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperimetersec%2Ffuzzlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperimetersec%2Ffuzzlib/lists"}