example-fork-detection
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on…
Detect reentrancy vulnerabilities — classic, cross-function, and cross-contract (especially read-only reentrancy). Activate whenever Solidity/Vyper code performs external calls, low-level call/transfer/send, ERC-721 safeTransfer with a receiver hook, or any pattern where control
Claude Code
$ npx -y skills add omermaksutii/RugProof --skill reentrancy --agent claude-code
Codex
$ npx skills add omermaksutii/RugProof --skill reentrancy -a codex -y
Cursor
$ npx skills add omermaksutii/RugProof --skill reentrancy -a cursor -y
Gemini CLI
$ npx skills add omermaksutii/RugProof --skill reentrancy -a gemini-cli -y
GitHub Copilot
$ npx skills add omermaksutii/RugProof --skill reentrancy -a github-copilot -y
OpenCode
$ npx skills add omermaksutii/RugProof --skill reentrancy -a opencode -y
Windsurf
$ npx skills add omermaksutii/RugProof --skill reentrancy -a windsurf -y
name: reentrancy description: Detect reentrancy vulnerabilities — classic, cross-function, and cross-contract (especially read-only reentrancy). Activate whenever Solidity/Vyper code performs external calls, low-level call/transfer/send, ERC-721 safeTransfer with a receiver hook, or any pattern where control flow leaves the contract before state finalization.
Trigger on any of:
function withdraw() external {
uint256 amt = balance[msg.sender];
(bool ok,) = msg.sender.call{value: amt}(""); // ← external call
require(ok);
balance[msg.sender] = 0; // ← state update AFTER call
}**Signal:** state mutation after external call. CEI (Checks-Effects-Interactions) violated.
Two functions sharing state where one calls externally and the other reads/mutates the same state. Attacker re-enters via the second function.
Contract A updates state, calls B; B calls back into a *different* contract C that reads A's stale state.
Victim contract reads `getReserves()` / `getPrice()` from a pool mid-callback, before the pool finalizes its state. Example: Curve pools, Balancer vaults, Uniswap V2 mid-`removeLiquidity`.
// Pool callback hits this view function before pool state is consistent.
function priceOf(address token) external view returns (uint256) {
return pool.getVirtualPrice(); // ← stale during reentrant call
}`_safeTransfer` calls `onERC721Received` on the recipient — if recipient is a contract, it can re-enter.
| Pattern | Severity | Notes | |---|---|---| | Funds-draining classic reentrancy | **Critical** | Direct loss of funds, no preconditions | | Cross-function with shared balance state | **High** | Requires specific call sequence | | Read-only reentrancy on price/oracle read | **High** | Common pattern, often missed | | Reentrancy gated by `onlyOwner` / trusted role | **Medium** | Centralization-bounded | | ERC-777 hook with no state-after-call writes | **Low** | Defense-in-depth issue | | Single-actor self-reentrancy with no value flow | **Info** | |
1. **CEI ordering** — effects before interactions, always. 2. **`nonReentrant` modifier** (`ReentrancyGuard` from OpenZeppelin). Add per-function. 3. **For read-only reentrancy** — guard the *view* function too, or use a separate "settled price" cache that only updates outside callbacks. Curve's solution: `withdraw_admin_fees` lock, Balancer's `ensureNotInVaultContext`. 4. **Pull over push payments** — let users withdraw rather than pushing transfers. 5. **Token whitelist** — avoid ERC-777 and rebasing tokens in untested paths.
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…