example-fork-detection
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on…
Detect initialization bugs in upgradeable contracts — missing `_disableInitializers()`, re-init attacks, parent-init not chained, constructor-vs-initializer confusion, public `initialize`. Activate on OZ Upgradeable, UUPS, Transparent proxy, Initializable, or any contract with
Claude Code
$ npx -y skills add omermaksutii/RugProof --skill initialization --agent claude-code
Codex
$ npx skills add omermaksutii/RugProof --skill initialization -a codex -y
Cursor
$ npx skills add omermaksutii/RugProof --skill initialization -a cursor -y
Gemini CLI
$ npx skills add omermaksutii/RugProof --skill initialization -a gemini-cli -y
GitHub Copilot
$ npx skills add omermaksutii/RugProof --skill initialization -a github-copilot -y
OpenCode
$ npx skills add omermaksutii/RugProof --skill initialization -a opencode -y
Windsurf
$ npx skills add omermaksutii/RugProof --skill initialization -a windsurf -y
name: initialization description: Detect initialization bugs in upgradeable contracts — missing `_disableInitializers()`, re-init attacks, parent-init not chained, constructor-vs-initializer confusion, public `initialize`. Activate on OZ Upgradeable, UUPS, Transparent proxy, Initializable, or any contract with `initialize` / `__init`.
contract Vault is Initializable, OwnableUpgradeable {
function initialize() external initializer {
__Ownable_init(msg.sender);
}
// ← no constructor disabling initializers
}Anyone can call `initialize` on the *implementation* address directly. Fix:
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() { _disableInitializers(); }Proxy deployment script forgets to call `initialize` atomically → attacker calls it first → owns the contract. Fix: deploy + initialize in same tx via factory or initializer-on-deploy proxy.
function reinitialize() external reinitializer(2) { // ← no auth
__Pausable_init();
}Add `onlyOwner` or `onlyProxyAdmin`.
function initialize() external initializer {
// __Pausable_init() missing — pausable state defaults to wrong values
}Verify every parent's `__X_init()` is chained.
constructor() OwnableUpgradeable() { owner = msg.sender; } // ← runs on impl, not proxyUpgradeable contracts must do setup in `initialize`, not constructor.
Devs sometimes write constructor logic expecting it to run on the proxy. It doesn't — constructor runs at deployment of the *implementation*, and the proxy never re-runs it.
EIP-1167 clones share implementation; each clone's `_initialized` slot starts at 0. If `initialize` has no auth, anyone can initialize a fresh clone before the deployer.
OZ v4: `_initialized` is uint8; v5: `_initialized` is uint64. Custom upgradeable contracts that don't use OZ may have bypassable guards.
| Pattern | Severity | |---|---| | Implementation init not disabled (anyone owns impl) | **Critical** | | Deployed proxy with public init un-called | **Critical** | | Re-initializer with no auth | **High** | | Clones with no atomic init | **High** | | Parent `__init` missing → broken inheritance | **High** | | Constructor used instead of initializer (upgradeable) | **High** | | Initializer parameter validation missing (e.g. zero-address admin) | **Medium** | | Initial state value seems wrong (defaults to 0) | **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…