example-fork-detection
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on…
Detect Diamond (EIP-2535) bugs — facet selector collisions, init-vs-upgrade safety, storage-namespace collisions, facet selfdestruct paths, missing facet cuts. Activate on Diamond imports, DiamondCut, IDiamondLoupe, IDiamondCut, LibDiamond, facet patterns.
Claude Code
$ npx -y skills add omermaksutii/RugProof --skill diamond-eip2535 --agent claude-code
Codex
$ npx skills add omermaksutii/RugProof --skill diamond-eip2535 -a codex -y
Cursor
$ npx skills add omermaksutii/RugProof --skill diamond-eip2535 -a cursor -y
Gemini CLI
$ npx skills add omermaksutii/RugProof --skill diamond-eip2535 -a gemini-cli -y
GitHub Copilot
$ npx skills add omermaksutii/RugProof --skill diamond-eip2535 -a github-copilot -y
OpenCode
$ npx skills add omermaksutii/RugProof --skill diamond-eip2535 -a opencode -y
Windsurf
$ npx skills add omermaksutii/RugProof --skill diamond-eip2535 -a windsurf -y
name: diamond-eip2535 description: Detect Diamond (EIP-2535) bugs — facet selector collisions, init-vs-upgrade safety, storage-namespace collisions, facet selfdestruct paths, missing facet cuts. Activate on Diamond imports, DiamondCut, IDiamondLoupe, IDiamondCut, LibDiamond, facet patterns.
Two facets implementing the same 4-byte selector (e.g. `function foo()` and `function bar(uint256)` that hash to the same selector). Diamond routes to the last-cut facet, but during a cut, the *old* version may be reachable.
Two facets using the same `bytes32 STORAGE_POSITION` slot prefix.
library LibA { bytes32 constant POS = keccak256("rugproof.a"); }
library LibB { bytes32 constant POS = keccak256("rugproof.a"); } // ← collisionUse unique namespace strings per facet.
Diamond init runs once via `delegatecall` to an Init contract. Re-running init after diamond-cut → can re-initialize values or run dangerous code. See [[initialization]].
function diamondCut(FacetCut[] calldata cuts, address init, bytes calldata data) external {
// ← no owner check
}Anyone can add/remove/replace facets.
Facet contract removed from blockchain (selfdestructed pre-6780, or simply deauthorized), but selectors still point to the old address → reverts.
A malicious facet replacement can hijack the entire diamond. Centralization risk depends on `diamondCut` authority.
Pre-Cancun: a facet calling `selfdestruct` deletes itself, breaking the diamond. Post-Cancun (EIP-6780): only delete-in-deploy-tx. Existing facets still risky if deployed before. See [[selfdestruct-eip6780]].
Without Loupe, off-chain consumers can't introspect facets. Soft requirement.
Internal functions in a facet aren't callable through the diamond (only externals are routed). Devs sometimes mistake the contracts.
`init` delegate-call during diamond-cut can reenter. Lock during cut.
If multiple facets share a storage struct, modifying struct fields requires coordinated upgrades. Refactoring one facet's view of the struct breaks others.
| Pattern | Severity | |---|---| | `diamondCut` lacks owner check | **Critical** | | Selector collision (or missed verification) | **Critical** | | Storage namespace collision | **Critical** | | Init function callable post-deploy | **High** | | Removing facet leaves dangling selectors | **High** | | Facet selfdestruct path (pre-6780 deploy) | **High** | | Missing Loupe | **Medium** | | Internal function mis-exposed | **Medium** |
Rugproof your code before someone else does. 🌐 Live site: omermaksutii.github.io/RugProof 📦 Latest: v1.0.0 — 45 commands · 23 agents · 45 skills · 13 MCP servers · tested, offline-first, with rule packs, a benchmark, non-EVM coverage, and post-deploy
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on…
Detect unsafe assumptions about Solady's gas-optimized ERC20/ERC2612 permit and DN404 metadata. Solady's ERC20 uses custom…
Detect front-runnable ownership initialization in Solady Ownable / OwnableRoles. Solady's `_initializeOwner` is a guarded…
Detect Solady SafeTransferLib calls that assume the token has code. SafeTransferLib.safeTransfer/safeTransferFrom/safeApprove…
Detect Uniswap V4 hooks that fail to settle currency deltas with the PoolManager. Every credit/debit a hook creates…
Detect Uniswap V4 hooks whose address-encoded permission flags don't match the callbacks the hook actually implements. In V4 the…
Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys)…
Clean and finalize authorized natural-language text intended for readers by auditing suspicious invisible Unicode and rewriting…