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 ERC-4337 account-abstraction bugs — validateUserOp storage-rule violations, paymaster postOp DoS, session-key scope bypasses, signature aggregation issues, EIP-7702 delegation risks. Activate on `validateUserOp`, `validatePaymasterUserOp`, `postOp`, `UserOperation`,
$ npx -y skills add omermaksutii/RugProof --skill erc4337-account-abstraction --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/erc4337-account-abstractionContext preview
The summary Claude sees to decide when to auto-load this skill.
Detect ERC-4337 account-abstraction bugs — validateUserOp storage-rule violations, paymaster postOp DoS, session-key scope bypasses, signature aggregation issues, EIP-7702 delegation risks. Activate on `validateUserOp`, `validatePaymasterUserOp`, `postOp`, `UserOperation`,
name: erc4337-account-abstraction description: Detect ERC-4337 account-abstraction bugs — validateUserOp storage-rule violations, paymaster postOp DoS, session-key scope bypasses, signature aggregation issues, EIP-7702 delegation risks. Activate on `validateUserOp`, `validatePaymasterUserOp`, `postOp`, `UserOperation`, `EntryPoint`, `IAccount`, `IPaymaster`, session-key modules, ERC-7579 modules, EIP-7702 authorization payloads.
ERC-4337 §6 forbids `SLOAD` on storage slots outside the wallet's own contract during validation. Bundlers reject non-compliant UserOps. Beyond compliance, accessing external state during validate is a *banner attack surface* (e.g. reading from an attacker-controlled contract).
function validateUserOp(...) external returns (uint256) {
uint256 x = IExternal(0xabc).read(); // ← violates storage rules + leaks attack surface
...
}function validateUserOp(...) external returns (uint256) {
// ← anyone can call directly, bypass bundler entirely
}function postOp(PostOpMode mode, bytes calldata ctx, uint256 actualGasCost) external {
require(...); // ← if this reverts in postOp, bundler is griefed; reputation system penalizes the paymaster
}`postOp` should be revert-free. Use try/catch or never revert.
Token-paying paymaster converts ERC20 → ETH at validate time. If oracle is spot AMM, sandwichable. See [[oracle-manipulation]].
Sponsorship sig replayable. See [[signature-replay]].
Session keys grant limited authority (allowed selectors, allowed targets, time bounds). Bypass paths:
EIP-7702 delegations replayable across chains if `chainId == 0` or missing chainId binding.
User signs an authorization to a contract address. If that contract is upgradeable / attacker-controlled, the EOA's nonce-aware delegated-call grants full control.
BLS-aggregated UserOps with `aggregator` field — if aggregator's verifier doesn't include chainId, cross-chain replay possible.
ERC-4337 uses 192-bit "nonce-key" for parallel UserOps. If multiple session keys / dapps share key 0, they serialize unnecessarily. Worse: if key encoding collides with another semantic, a stuck UserOp can DoS.
Meta-tx with permit can collide on nonces with regular UserOp.
ERC-7579 / ERC-6900 module install paths sometimes lack `onlyEntryPointOrOwner`. Install path → arbitrary module → arbitrary execution.
| Pattern | Severity | |---|---| | `validateUserOp` callable by non-EntryPoint | **Critical** | | Module install lacks auth check | **Critical** | | EIP-7702 missing chainId in authorization | **Critical** | | EIP-7702 delegation to mutable contract | **Critical** | | Paymaster postOp can revert | **High** | | Session-key scope bypass via multicall/fallback | **High** | | Storage-rule violation in validate | **High** | | Token-paymaster spot-oracle dependency | **High** | | Sponsorship-paymaster sig without nonce/deadline | **High** | | Aggregated sig missing chainId | **High** | | Nonce-key naming collision | **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
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…