Most rug-pull alerts arrive too late. By the time a tool reports “liquidity pulled”, the liquidity is already gone. The alert is a post-mortem, not a warning. But a rug is a transaction, and every Ethereum transaction spends a few seconds in the public mempool before it is mined. That window is where the warning lives.
This is how we turned our rug detection from a post-mortem into a pre-rug alert.
A rug is just a transaction
A rug pull is rarely exotic. In the large majority of cases it is one of a handful of on-chain actions by whoever controls the token or its liquidity:
- a call to the Uniswap router’s
removeLiquidity/removeLiquidityETH(and the fee-on-transfer and permit variants), - an owner-only function that turns the token into a honeypot:
setFeeto 100%,blacklistevery holder,pausetransfers, flipenableTradingback off.
All of these are public function calls with well-known 4-byte selectors. We keep the full list: removeLiquidity is 0xbaa2abde, removeLiquidityETH is 0x02751cec, and so on for every overload, plus the owner-function signatures.
The mempool is the early-warning system
Here is the key fact: a transaction is broadcast to the mempool and propagates across nodes for a few seconds, sometimes much longer under congestion, before a validator includes it in a block. During that window the rug has not happened yet. It is pending. If you are watching, you can see it coming.
We run mempool watchers on three Ethereum nodes. For every pending transaction whose target is a token we already track as high-risk, we decode the calldata and match the selector. A pending removeLiquidity on a sketchy token, or a pending setFee from its owner, is an imminent rug. We do not wait for it to mine.
Keeping the signal meaningful
The hard part of any early-warning system is not detection, it is noise. Not every owner interaction is a rug. So the alert is filtered: it fires only on a pending liquidity removal, or on a critical or high-severity owner rug-function. A routine, low-signal admin call does not trip it. An alert you learn to ignore is worse than no alert.
We also only watch tokens our analyzers have already flagged as high-risk. A token that scored clean is not interesting to front-run, so it stays off the watchlist. That keeps the list small and the false-positive rate low.
What you get
When a pending rug is detected, two things happen in real time:
- an
imminent_rugevent on the WebSocket stream (wss://api.rektradar.io/v1/stream), - a
rug.imminentsigned webhook to any endpoint you have registered.
Both carry the token, the kind of action (liquidity_removal_pending or owner_function_pending), the severity, and the pending transaction hash. A trading bot can use those seconds to exit. A wallet can warn its user. A dashboard can light up red before the chart does.
import { RektRadar } from "@mik3fly-lab/rektradar-sdk";
import WebSocket from "ws";
const rr = new RektRadar({ apiKey: process.env.REKTRADAR_KEY });
rr.stream({
events: ["imminent_rug", "rug"],
WebSocket,
onMessage: (e) => {
if (e.type === "imminent_rug") exitPosition(e.data.token);
},
});
An honest note on the window
This is not magic, and we will not pretend otherwise. The warning is exactly as long as the transaction’s time in the public mempool, which is seconds, not minutes. A rug submitted with a high priority fee and mined in the very next block gives you almost nothing. Private mempools and direct-to-builder submissions skip the public mempool entirely, so a sophisticated rugger can hide.
What this catches is the large, ordinary majority of rugs that travel through the public mempool like every other transaction. For those, a few seconds of warning is the difference between getting out and getting rugged. That is worth shipping.
The real-time imminent_rug feed is part of the RektRadar API. Targeted token lookups are free; the live flow is delayed about ten minutes on a free key and real-time on a paid one. Start at rektradar.io/developers.