example-fork-detection
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on…
Detect ignored external-call return values — silent failures from low-level call/delegatecall/staticcall, ignored ERC20 transfer return values, return-data length issues. Activate on `.call`, `.delegatecall`, `.staticcall`, `.send`, `transfer`/`transferFrom` (without SafeERC20),
Claude Code
$ npx -y skills add omermaksutii/RugProof --skill unchecked-calls --agent claude-code
Codex
$ npx skills add omermaksutii/RugProof --skill unchecked-calls -a codex -y
Cursor
$ npx skills add omermaksutii/RugProof --skill unchecked-calls -a cursor -y
Gemini CLI
$ npx skills add omermaksutii/RugProof --skill unchecked-calls -a gemini-cli -y
GitHub Copilot
$ npx skills add omermaksutii/RugProof --skill unchecked-calls -a github-copilot -y
OpenCode
$ npx skills add omermaksutii/RugProof --skill unchecked-calls -a opencode -y
Windsurf
$ npx skills add omermaksutii/RugProof --skill unchecked-calls -a windsurf -y
name: unchecked-calls description: Detect ignored external-call return values — silent failures from low-level call/delegatecall/staticcall, ignored ERC20 transfer return values, return-data length issues. Activate on `.call`, `.delegatecall`, `.staticcall`, `.send`, `transfer`/`transferFrom` (without SafeERC20), and any function returning `bool` whose return is discarded.
(bool ok,) = target.call(data); // ← ok unused // or worse: target.call(data); // ← Solidity ≥0.5 still allows this with warning
Always `require(ok, "call failed");` unless an intentional best-effort.
USDT and other non-conformant tokens don't return `bool`. Naive call:
IERC20(usdt).transfer(to, amt); // ← reverts on USDT due to ABI mismatch
Use OZ `SafeERC20`'s `safeTransfer` which handles missing return values.
Even compliant ERC20 returning `false` instead of reverting is silently passed:
bool ok = token.transfer(to, amt); // ← ok unused, returns false on failure
try external.call() { /* … */ }
catch { /* silently ignored */ }Without inspecting `catch (bytes memory reason)`, you lose all info; transitioning a critical revert into a silent success is a bug.
(bool ok,) = target.call(data); require(ok);
`ok = true` even if `target` is an EOA with no contract — `call` returns true. Add `target.code.length > 0` check.
If `permit` reverts (because it was already used), the consuming transferFrom continues with a stale allowance. Use `try`/`catch` only to skip the permit reuse case.
Some routers continue on per-call failure. If a treasury sweeps via multicall, a single failed call could drop revenue.
Forwarding 2300 gas is brittle on Berachain/Arbitrum/etc. — see [[dos-vectors]].
| Pattern | Severity | |---|---| | `.call` ignored, leads to silent fund loss | **Critical** | | Non-SafeERC20 with USDT/non-conformant token | **High** | | `target.call` without code-length check | **High** | | Try-catch swallows revert without inspection | **High** | | Multicall fail-skip on revenue path | **High** | | `.transfer` (2300 gas) on L2 / to smart-wallet receivers | **Medium** | | Best-effort fire-and-forget event hook | **Low** *(document intent)* |
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…