example-fork-detection
TEMPLATE — replace with the description of your rule. Should activate on the specific code patterns your fork has. Activate on…
Detect cross-chain messaging bugs — replay protection gaps, untrusted-remote acceptance, default-config inheritance, validator-set misconfig, force-include vulnerabilities, chainId / domain-separator omissions. Activate on `_lzReceive`, `ccipReceive`, `handle` (Hyperlane),
Claude Code
$ npx -y skills add omermaksutii/RugProof --skill cross-chain-messaging --agent claude-code
Codex
$ npx skills add omermaksutii/RugProof --skill cross-chain-messaging -a codex -y
Cursor
$ npx skills add omermaksutii/RugProof --skill cross-chain-messaging -a cursor -y
Gemini CLI
$ npx skills add omermaksutii/RugProof --skill cross-chain-messaging -a gemini-cli -y
GitHub Copilot
$ npx skills add omermaksutii/RugProof --skill cross-chain-messaging -a github-copilot -y
OpenCode
$ npx skills add omermaksutii/RugProof --skill cross-chain-messaging -a opencode -y
Windsurf
$ npx skills add omermaksutii/RugProof --skill cross-chain-messaging -a windsurf -y
name: cross-chain-messaging description: Detect cross-chain messaging bugs — replay protection gaps, untrusted-remote acceptance, default-config inheritance, validator-set misconfig, force-include vulnerabilities, chainId / domain-separator omissions. Activate on `_lzReceive`, `ccipReceive`, `handle` (Hyperlane), `receiveMessage`, `verifyVAA`, IRouterClient, IMailbox, EndpointV2, OApp/OFT, LayerZero / CCIP / Hyperlane / Wormhole / Axelar / Polyhedra integration code.
function _lzReceive(bytes calldata srcAddr, bytes calldata payload) internal {
// no allowlist of trusted remote
_executeMint(payload); // ← any chain can mint
}Required: `require(trustedRemote[srcChainId] == srcAddr)`.
function ccipReceive(Any2EVMMessage calldata m) external { // ← public, no router check
_execute(m.data);
}Required: `require(msg.sender == address(router))`.
Hyperlane's default ISM is permissive. Apps must set their own. If `handle` is called by mailbox without app-side validation, anyone can spoof messages.
function complete(bytes calldata vaa) external {
IWormhole.VM memory vm = wormhole.parseAndVerifyVM(vaa);
_mint(vm.payload.to, vm.payload.amount); // ← no per-VAA seen check
}Required: track `usedVAAs[vm.hash] = true` after first use.
Same payload accepted on multiple destination chains. Include destination `chainId` in the signed/verified payload.
Application doesn't set explicit DVN set (LayerZero V2) or ISM (Hyperlane). Default configs are often weak. Look for explicit `setSendLibrary`, `setReceiveLibrary`, `setEnforcedOptions`, `setInterchainSecurityModule`.
LayerZero EIDs ≠ chainIds. CCIP uses chainSelectors. Map wrong → message goes to wrong chain or stuck forever.
Receiver runs out of gas → message stuck (LayerZero V2 retry semantics).
Anyone can force-include an L1→L2 transaction. If app assumes only sequencer can trigger certain flows, force-include breaks the assumption.
Optimism: 7-day challenge. Arbitrum: 7-day. App that assumes funds arrive instantly L2→L1 → invariant broken.
Single pause for all routes vs per-route → over- or under-blast-radius.
`_lzReceive` triggering a compose call back into `lzCompose` re-enters during the same message. Treat composed messages as reentrant calls.
If `setTrustedRemote` is `onlyOwner` and owner is an EOA, the bridge can be silently rerouted. See [[centralization-risk]].
| Pattern | Severity | |---|---| | Receive function accepts any remote | **Critical** | | Receive function callable directly (not router/mailbox) | **Critical** | | VAA / message not marked seen → double-spend | **Critical** | | Cross-chain replay (no destination chainId binding) | **Critical** | | Default ISM / DVN config (no app-side override) | **High** | | chainId/EID/chainSelector mapping mistake | **High** | | Compose reentrancy in LayerZero V2 | **High** | | Force-include L1→L2 assumption | **High** | | L2→L1 withdrawal-delay assumption | **Medium** | | Single-key trusted-remote update authority | **High** | | Insufficient gas in send → message stuck | **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
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…