example-fork-detection
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on `<your trigger keywords or…
Detect missing or incorrect access control — missing modifiers, wrong role checks, privileged function exposure, public initializers, and role-escalation paths. Activate on any function that mutates state, transfers funds, mints tokens, sets admin parameters, upgrades
$ npx -y skills add omermaksutii/RugProof --skill access-control --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/access-controlContext preview
The summary Claude sees to decide when to auto-load this skill.
Detect missing or incorrect access control — missing modifiers, wrong role checks, privileged function exposure, public initializers, and role-escalation paths. Activate on any function that mutates state, transfers funds, mints tokens, sets admin parameters, upgrades
name: access-control description: Detect missing or incorrect access control — missing modifiers, wrong role checks, privileged function exposure, public initializers, and role-escalation paths. Activate on any function that mutates state, transfers funds, mints tokens, sets admin parameters, upgrades implementations, or pauses/unpauses.
Any state-mutating function. In particular:
function mint(address to, uint256 amount) external {
_mint(to, amount); // ← anyone can mint
}function setFee(uint256 fee) external {
require(msg.sender == owner || hasRole(USER, msg.sender)); // ← USER role can set fee
fee_ = fee;
}function initialize(address admin) public { // ← no initializer guard, anyone can re-init
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}**See also:** [[initialization]]
require(tx.origin == owner); // ← phishable via intermediate contract
Sometimes a setter is internal but a public wrapper exists with weak checks. Search for "alternate paths" to the same state slot.
`DEFAULT_ADMIN_ROLE` can grant itself any role. If the admin is an EOA, a single key compromises everything. Look for renounceable admin patterns or multi-sig requirements.
function rescue(IERC20 token) external onlyOwner {
token.transfer(owner, token.balanceOf(address(this))); // ← sweeps any token incl. user deposits
}Critical if it can sweep user deposits, Medium if only stuck airdrops.
| Pattern | Severity | |---|---| | Privileged mint/burn with no auth | **Critical** | | Public `initialize` on a deployed proxy | **Critical** | | Owner sweep that includes user deposits | **Critical** | | Wrong role guards a sensitive op | **High** | | `tx.origin` auth | **High** | | Centralized single-key admin with no timelock | **High** *(see [[centralization-risk]])* | | Renounced ownership but admin role retained | **Medium** | | Missing zero-address check on role grant | **Low** |
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
Repo: omermaksutii/RugProof
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on `<your trigger keywords or…
Detect unsafe assumptions about Solady's gas-optimized ERC20/ERC2612 permit and DN404 metadata. Solady's ERC20 uses custom storage slots, returns bools via…
Detect front-runnable ownership initialization in Solady Ownable / OwnableRoles. Solady's `_initializeOwner` is a guarded one-time setter (it reverts with…
Detect Solady SafeTransferLib calls that assume the token has code. SafeTransferLib.safeTransfer/safeTransferFrom/safeApprove deliberately skip the EXTCODESIZE…
Detect Uniswap V4 hooks that fail to settle currency deltas with the PoolManager. Every credit/debit a hook creates (BeforeSwapDelta, afterSwap hookDelta,…
Detect Uniswap V4 hooks whose address-encoded permission flags don't match the callbacks the hook actually implements. In V4 the hook's permissions live in the…