There's a folk hypothesis on memecoin Twitter: when a smart-money wallet is the first of the tracked KOL set to buy a new token, more KOLs tend to follow, and the token tends to run. We have 38 days of kol_trades data — 491,119 buys across 85,760 distinct token mints from 426 tracked KOL wallets — so we can actually check.
This post is the backtest, the conclusions, and the new endpoint we shipped on top of it.
What "first KOL touch" actually means
A first KOL touch is the moment the first wallet in our tracked KOL set buys a given token mint. It is not the first on-chain buy of that token — sniper bots and the deployer's own wallets are almost always earlier. It is specifically the first time a wallet we already watch (and already score) appears as a buyer. That framing matters because it scopes the universe: we are not asking "is this token good," we are asking "given that a tracked smart-money wallet just bought this for the first time, do other tracked wallets follow." The signal is about attention propagation inside a known cohort, not about price directly.
That distinction is the reason the raw signal is noisy and the conditioned signal is not. Any single KOL touching a token tells you very little. Which KOL touched it, and whether that KOL has a history of touches that others swarm, is where the information lives.
The setup
For every (token_mint), find the first KOL buy. Then for each first-touch event, count how many other tracked KOLs bought the same token within 30 minutes, 60 minutes, and 4 hours. We restrict to first touches that happened at least 4 hours before the query so every event has a complete follow-on window.
That gives us 72,549 first-touch events across the 38d window.
Baseline — does the raw signal hold?
| Outcome | Rate |
|---|
| ≥1 follower in 30min | 34.3% |
| ≥2 followers in 60min | 20.2% |
| ≥3 followers in 60min | 13.1% |
| ≥5 followers in 4h | 7.0% |
| Avg followers in 4h | 1.08 |
So the raw "any first KOL touched a token" signal is noisy — about 80% go nowhere. That's worse than it looks because the universe includes a lot of noise (small KOLs, stablecoin pairs, infra tokens, etc.).
How to read a backtest like this
A few things to keep front of mind before you act on any of these rates:
- Everything here is a base rate, not a forecast. A "34.3% chance of ≥1 follower in 30 minutes" is the historical frequency over this 38-day window. It is the prior you start from, not a probability attached to the specific token in front of you.
- Compare every conditioned number against the unconditioned baseline, not against zero. A 47% swarm rate only means something because the baseline is 17%. The lift over baseline is the signal; the absolute number alone is not.
- Survivorship and selection cut both ways. The KOL set is a curated cohort, so these rates do not generalize to "any wallet." And the highest-frequency KOLs dominate the event count, so aggregate stats are weighted toward how they behave.
- A "follower" is a follow-on buy, not an outcome. None of these tables measure price. A swarm of three KOLs is a measure of coordinated attention, which historically precedes moves often enough to be tradeable — but the swarm is the thing being measured, not the return.
With that framing, the conditioning that follows is the part that actually matters.
Conditioning on the first KOL's quality
Now bucket by the first KOL's 7-day winrate (from mv_kol_scores):
| Winrate | n | %≥2 in 60m | %≥3 in 60m | %≥5 in 4h |
|---|
| 0–30% | 20,063 | 17.1% | 10.8% | 6.0% |
| 30–40% | 32,211 | 17.8% | 11.3% | 5.9% |
| 40–50% | 12,475 | 24.5% | 16.3% | 9.0% |
| 50–60% | 6,023 | 32.3% | 21.4% | 10.9% |
| 60–70% | 475 | 46.9% | 37.5% | 25.9% |
| 70+% | 718 | 21.7% | 14.1% | 7.4% |
The 60–70% winrate band is a sweet spot — first touches by these KOLs see a 2-KOL swarm 47% of the time vs 17% baseline. Almost 4× lift on the strict ≥5-follower bucket.
The 70+% band drops back. Counterintuitive but consistent: the highest-winrate KOLs tend to be tight scalpers who get in and out before others see the trade — they don't broadcast intent. So winrate alone is a U-shaped predictor.
The per-KOL "scout score" beats winrate buckets
Bucketing by aggregate winrate is a blunt instrument. Compute the swarm rate per individual KOL and the picture sharpens:
| KOL | first-touches (30d) | avg followers | %≥3 swarm | wr7d |
|---|
| Jijo | 331 | 4.15 | 51.1% | 67.5 |
| Pavel | 83 | 2.07 | 34.9% | 47.5 |
| The Doc | 170 | 2.23 | 32.9% | 42.6 |
| Trenchman | 105 | 2.15 | 32.4% | 43.1 |
| clukz | 214 | 2.57 | 30.8% | 49.5 |
| Cented | 2,852 | 1.92 | 26.4% | 58.0 |
| decu | 1,697 | 1.79 | 24.7% | 57.6 |
Jijo's first touch sees ≥3 follow-on KOLs 51% of the time versus a 13.7% baseline — 3.7× lift on a ≥30-event sample. The full leaderboard is live at /kol/scouts, and our walkthrough on using the Scout leaderboard, KOL consensus, and peak history for token discovery shows how to turn this data into entries.
We checked stability by splitting the 38d window into two 19-day halves and comparing per-KOL scout rates:
| Sample bucket | n_kols | Pearson r | Mean abs diff |
|---|
| n < 10 | 85 | 0.05 | ±13.8 pp |
| n = 10–19 | 42 | 0.56 | ±7.2 pp |
| n = 20–29 | 27 | 0.50 | ±6.4 pp |
| n ≥ 30 | 140 | 0.78 | ±4.3 pp |
n ≥ 30 is genuinely stable; below that, you're fitting noise. So the scout-tier classification (S/A/B/C) requires at least 30 first-touches in the 30-day window.
The split-half test is the most important defensive step in the whole analysis, and it is worth saying why. The temptation with a leaderboard like this is to rank every KOL by their headline swarm rate and trade the top of the list. But a KOL with five first-touches and a 60% swarm rate is indistinguishable from luck — the Pearson r of 0.05 at n < 10 says the first half of the window predicts essentially nothing about the second half. Only once you have ~30 events does the rate persist across time (r = 0.78), which is the difference between "this wallet has a real scouting edge" and "this wallet had a hot streak." When you read the leaderboard, the sample-size column is not a footnote — it is the confidence interval. Anchor on tier and event count, not on a single eye-catching percentage. The scout leaderboard and the side-by-side KOL comparison view both surface event counts alongside the rates for exactly this reason.
The latency problem (read this part)
When there is a follower, how long after the first touch does the second KOL arrive?
| Lead time | seconds |
|---|
| p25 | 4 |
| p50 | 12 |
| p75 | 41 |
Median lead time is 12 seconds. By the time a human reads an alert and signs a tx, p75 is gone. The signal is too fast for human-mediated trading. It's only useful as:
- A push event into a bot or copy-trade system (sub-second WebSocket / webhook delivery)
- A research / confirmation context ("the swarm started 8 minutes ago, here's what triggered it")
- A leaderboard / discovery surface (pick scouts whose wallets you want to watch directly)
If you're staring at a UI dashboard waiting for "Jijo just bought X" to flash, you've already lost.
The endpoint
We shipped this as GET /api/v1/kol/first-touches. Every first-KOL-touch event, filterable on the dimensions that mattered in the backtest:
# Fresh launches scouted by S/A-tier KOLs in the last 60 minutes
curl https://madeonsol.com/api/v1/kol/first-touches \
-H "Authorization: Bearer msk_..." \
-G --data-urlencode "preset=scout" \
--data-urlencode "limit=20"
Returns events with the first KOL's name, scout tier, scout score, winrate, strategy, and the token's age in minutes:
{
"events": [
{
"token_mint": "...",
"token_symbol": "...",
"first_buy_at": "2026-04-26T07:18:42Z",
"sol_amount": 1.234,
"tx_signature": "...",
"token_age_minutes": 7,
"first_kol": {
"name": "Jijo",
"winrate_7d": 67.5,
"strategy": "scalper",
"scout_tier": "S",
"scout_score": 51.1,
"n_first_touches_30d": 331
}
}
],
"count": 1,
"next_before": "2026-04-26T07:18:42Z",
"data_age_seconds": 4
}
Filters worth knowing: min_scout_tier=S|A|B|C, min_kol_winrate_7d, min_n_touches, strategy, token_age_max_min, min_first_buy_sol, mint_suffix=pump, since=<ISO>, before=<ISO>, include=followers_4h.
Don't poll. Push.
Given the 12-second median lead time, REST polling won't beat the swarm. Subscribe to the WebSocket channel instead:
import { MadeOnSolREST } from "madeonsol-x402";
const sdk = new MadeOnSolREST({ apiKey: "msk_..." });
// Get a stream token (Pro+)
const { token } = await fetch("/api/v1/stream/token", {
headers: { Authorization: "Bearer msk_..." }
}).then(r => r.json());
const ws = new WebSocket(`wss://madeonsol.com/ws/v1/stream?token=${token}`);
ws.onopen = () => {
ws.send(JSON.stringify({
type: "subscribe",
channels: ["kol:first_touches"],
filters: { min_scout_tier: "A", mint_suffix: "pump" }
}));
};
ws.onmessage = (msg) => {
const { event, data } = JSON.parse(msg.data);
if (event === "kol:first_touch") {
// Sub-second from on-chain trade to your handler
console.log(data.first_kol.name, "scouted", data.token_symbol);
}
};