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-20 approval pitfalls — approve race (front-run), missing safeApprove, infinite approvals, approval-without-revoke, Permit2 misuse, max-approval to untrusted contracts. Activate on `approve`, `safeApprove`, `permit`, `forceApprove`, `Permit2`, `IERC20.allowance`.
$ npx -y skills add omermaksutii/RugProof --skill approval-issues --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/approval-issuesContext preview
The summary Claude sees to decide when to auto-load this skill.
Detect ERC-20 approval pitfalls — approve race (front-run), missing safeApprove, infinite approvals, approval-without-revoke, Permit2 misuse, max-approval to untrusted contracts. Activate on `approve`, `safeApprove`, `permit`, `forceApprove`, `Permit2`, `IERC20.allowance`.
name: approval-issues description: Detect ERC-20 approval pitfalls — approve race (front-run), missing safeApprove, infinite approvals, approval-without-revoke, Permit2 misuse, max-approval to untrusted contracts. Activate on `approve`, `safeApprove`, `permit`, `forceApprove`, `Permit2`, `IERC20.allowance`.
token.approve(spender, X); // later token.approve(spender, Y); // ← spender can front-run and drain X+Y
Use `forceApprove(spender, Y)` (OZ ≥4.9), or `decreaseAllowance` / `increaseAllowance`, or zero-first.
USDT requires approve-to-zero before approve-to-X. Use OZ `forceApprove`.
token.approve(router, type(uint256).max); // ← router is upgradeable, future impl can drain
Mitigate with allowance-per-action.
Vault → strategy infinite approval; if strategy is upgradeable or has a bug, vault funds drainable.
Permit2 signatures are bearer instruments — anyone with the sig can transfer. If the signed payload is logged or leaked, funds are drainable until the nonce is invalidated. Add a deadline.
try IERC20Permit(token).permit(owner, spender, ...) {} catch {}
token.transferFrom(owner, ...); // ← if permit fails, uses any stale allowanceCaller can grief by front-running permit. Acceptable IFF you then check the allowance is sufficient.
Some tokens treat `approve(0, x)` as a no-op or revert. Use the documented revoke method.
token.safeApprove(target, amount); target.swap(...); // ← allowance lingers; if `amount` was max, target keeps power
Set to 0 after each action, or use a single-tx wrapper.
Deployer can deploy attacker-controlled implementation that consumes the approval.
| Pattern | Severity | |---|---| | Persistent infinite approval to upgradeable router | **High** | | Approve race ignored, no `forceApprove` / `increaseAllowance` | **High** | | USDT-style approve without zero-reset | **High** | | Vault → strategy infinite allowance with mutable strategy | **High** | | Permit2 with no deadline | **High** | | Permit failure swallowed, allowance not re-checked | **Medium** | | Lingering allowance after one-shot router action | **High** |
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…