Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions benchmarks/trading-platform-wallets.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# OpenChainBench. Bench 208

slug: trading-platform-wallets
number: "208"
title: "Daily active wallets per trading platform: GMGN vs Axiom vs Fomo vs pump.fun, live"
seo_title: "Daily active wallets by trading platform 2026: GMGN vs Axiom vs Fomo vs pump.fun"
seo_description: "{{best_name}} leads trading platforms with {{best_p50}} unique active wallets in 24h. GMGN vs Axiom vs Fomo vs Trojan vs BasedBot ranked by real user count, live from Dune community datasets."
subtitle: Live count of unique wallets that traded through each platform in the last complete day. Sourced from Dune community datasets, refreshed every 4 hours. Reveals real user base vs bot-inflated transaction counts.

category: Trading
status: live
metric: Active wallets 24h
unit: count
higher_is_better: true

disclaimer: |
Wallet counts are unique wallets per platform per day from Dune community datasets (cross-chain). A wallet using two platforms is counted in each; counts are not mutually exclusive. Includes bots, MEV searchers, and multi-wallet traders. pump.fun wallets come from dataset_pumpapp_sol_daily only (not relay); relay wallets would overlap with pumpapp and double-count. Data represents the most recent complete day, refreshed every 4 hours.

seo_intro: |
Daily active wallet count is the clearest signal of real platform usage, filtering out
the noise from bots that inflate transaction counts. GMGN consistently leads on wallet
count among trading terminals, reflecting its broad AI copy-trading user base across
multiple chains. Axiom and Fomo compete closely behind. pump.fun naturally dominates
in absolute numbers due to its launchpad mechanic attracting thousands of new wallets
daily across sniping bots and retail buyers. Trojan and Photon serve smaller but
more concentrated user bases with higher average positions. This benchmark tracks
unique active wallets per platform live from Dune community datasets, updated every
4 hours.

abstract: |
The dune-platform-volume harness queries Dune community datasets
(dune.adam_tehc_co.dataset_*_daily) every 4 hours. The wallets column in each
dataset provides the count of unique wallet addresses that executed at least one
swap through the platform on the given day. For multi-chain platforms (GMGN,
Axiom, BasedBot, Terminal) the count is summed across all blockchains. For Fomo
and Trojan, the count is Solana-only. pump.fun uses dataset_pumpapp_sol_daily
wallets only. The metric is exposed as dune_platform_wallets_24h per platform.

methodology:
- "Source: Dune community datasets (dataset_*_daily). wallets column = unique wallet addresses per platform per day."
- "Poll cadence: harness queries Dune every 4 hours; Prometheus scrapes :2112/metrics every 60 seconds."
- "Cross-chain: GMGN, Axiom, BasedBot, Terminal sum wallets across all blockchains. Fomo and Trojan are Solana-only datasets."
- "pump.fun: dataset_pumpapp_sol_daily wallets only (pumpapp frontend). Relay dataset wallets not added to avoid double-counting wallets active on both."
- "Includes all wallets: bots, MEV searchers, and automated traders are counted. Not a human-only metric."
- "Not mutually exclusive: a wallet using GMGN and Axiom on the same day is counted in both platforms."

findings:
- "{{best_name}} leads trading platforms with {{best_p50}} unique active wallets in 24h."
- "GMGN leads terminals by wallet count, driven by its broad AI copy-trading and multi-chain reach."
- "pump.fun's wallet count reflects daily launchpad activity — thousands of new wallets snipe each token launch."
- "Comparing wallet count to txns per platform reveals the bot ratio: platforms with 50x more txns than wallets have heavy automated activity."

source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/dune-platform-volume

prometheus:
window: 24h
freshness_metric: dune_platform_wallets_24h

faq:
- q: "What does active wallet count measure?"
a: "Active wallets is the number of unique blockchain addresses that executed at least one swap through the platform during the day. It is a proxy for daily active users, though one human can control many wallets and bots count as wallets."
- q: "How is this different from swap transaction count (bench 207)?"
a: "Swap tx count (dune_platform_txns_24h) counts every individual swap. Active wallets counts unique addresses. A bot executing 500 swaps in one day contributes 500 to tx count but only 1 to wallet count. The ratio txns/wallets is a proxy for trading frequency per user and bot intensity."
- q: "Why is pump.fun's wallet count from pumpapp only and not relay?"
a: "The relay dataset (dataset_pumpfun_relay_daily) covers cross-chain relay swaps where pump.fun tokens are bought on EVM chains via relay. Wallets on relay likely overlap significantly with pumpapp wallets. Adding them would double-count users active on both. We use pumpapp as the primary dataset for pump.fun wallet counts."
- q: "Are wallet counts comparable across platforms?"
a: "Approximately. Each dataset counts unique addresses per day per platform independently. Cross-chain platforms (GMGN, Axiom) sum wallets across chains, so the same wallet on Solana and BNB would be counted twice. Single-chain platforms like Fomo and Trojan are Solana-only. The cross-chain sum slightly overstates unique humans for multi-chain platforms."

providers:
- slug: pump-fun
name: pump.fun
tag: "Solana meme launchpad"
formula: "Unique wallets on pump.fun's app (dataset_pumpapp_sol_daily), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="pump-fun"}
p90: dune_platform_wallets_24h{platform="pump-fun"}
p99: dune_platform_wallets_24h{platform="pump-fun"}
mean: dune_platform_wallets_24h{platform="pump-fun"}
success: dune_platform_volume_health{platform="pump-fun"}
sample_size: dune_platform_wallets_24h{platform="pump-fun"}
series: dune_platform_wallets_24h{platform="pump-fun"}

- slug: gmgn
name: GMGN
tag: "AI trading terminal, multi-chain"
formula: "Unique wallets across all chains (dataset_gmgn_daily, cross-chain sum), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="gmgn"}
p90: dune_platform_wallets_24h{platform="gmgn"}
p99: dune_platform_wallets_24h{platform="gmgn"}
mean: dune_platform_wallets_24h{platform="gmgn"}
success: dune_platform_volume_health{platform="gmgn"}
sample_size: dune_platform_wallets_24h{platform="gmgn"}
series: dune_platform_wallets_24h{platform="gmgn"}

- slug: axiom
name: Axiom
tag: "Web trading terminal, multi-chain"
formula: "Unique wallets across all chains (dataset_axiom_daily, cross-chain sum), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="axiom"}
p90: dune_platform_wallets_24h{platform="axiom"}
p99: dune_platform_wallets_24h{platform="axiom"}
mean: dune_platform_wallets_24h{platform="axiom"}
success: dune_platform_volume_health{platform="axiom"}
sample_size: dune_platform_wallets_24h{platform="axiom"}
series: dune_platform_wallets_24h{platform="axiom"}

- slug: fomo
name: Fomo
tag: "Solana trading platform"
formula: "Unique wallets on Solana (dataset_fomo_sol_daily), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="fomo"}
p90: dune_platform_wallets_24h{platform="fomo"}
p99: dune_platform_wallets_24h{platform="fomo"}
mean: dune_platform_wallets_24h{platform="fomo"}
success: dune_platform_volume_health{platform="fomo"}
sample_size: dune_platform_wallets_24h{platform="fomo"}
series: dune_platform_wallets_24h{platform="fomo"}

- slug: trojan
name: Trojan
tag: "Telegram trading bot on Solana"
formula: "Unique wallets on Solana (dataset_trojan_daily), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="trojan"}
p90: dune_platform_wallets_24h{platform="trojan"}
p99: dune_platform_wallets_24h{platform="trojan"}
mean: dune_platform_wallets_24h{platform="trojan"}
success: dune_platform_volume_health{platform="trojan"}
sample_size: dune_platform_wallets_24h{platform="trojan"}
series: dune_platform_wallets_24h{platform="trojan"}

- slug: photon
name: Photon
tag: "Solana trading terminal"
formula: "Unique wallets on Solana (dataset_photon_daily), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="photon"}
p90: dune_platform_wallets_24h{platform="photon"}
p99: dune_platform_wallets_24h{platform="photon"}
mean: dune_platform_wallets_24h{platform="photon"}
success: dune_platform_volume_health{platform="photon"}
sample_size: dune_platform_wallets_24h{platform="photon"}
series: dune_platform_wallets_24h{platform="photon"}

- slug: padre
name: Terminal
tag: "pump.fun's own trading app (formerly Padre)"
formula: "Unique wallets across all chains (dataset_terminal_daily, cross-chain sum), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="padre"}
p90: dune_platform_wallets_24h{platform="padre"}
p99: dune_platform_wallets_24h{platform="padre"}
mean: dune_platform_wallets_24h{platform="padre"}
success: dune_platform_volume_health{platform="padre"}
sample_size: dune_platform_wallets_24h{platform="padre"}
series: dune_platform_wallets_24h{platform="padre"}

- slug: basedbot
name: BasedBot
tag: "Multi-chain trading bot"
formula: "Unique wallets across all chains (dataset_basedbot_daily, cross-chain sum), latest complete day."
queries:
p50: dune_platform_wallets_24h{platform="basedbot"}
p90: dune_platform_wallets_24h{platform="basedbot"}
p99: dune_platform_wallets_24h{platform="basedbot"}
mean: dune_platform_wallets_24h{platform="basedbot"}
success: dune_platform_volume_health{platform="basedbot"}
sample_size: dune_platform_wallets_24h{platform="basedbot"}
series: dune_platform_wallets_24h{platform="basedbot"}
30 changes: 16 additions & 14 deletions harnesses/dune-platform-volume/cmd/script/dune.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,36 @@ import (
// All others sum across all blockchains for latest available day.
const querySQL = `
WITH latest AS (
SELECT 'gmgn' AS platform, SUM(volume_usd) AS volume_usd, SUM(CAST(txns AS BIGINT)) AS txns, SUM(CAST(fees_usd AS DOUBLE)) AS fees_usd
SELECT 'gmgn' AS platform, SUM(volume_usd) AS volume_usd, SUM(CAST(txns AS BIGINT)) AS txns, SUM(CAST(fees_usd AS DOUBLE)) AS fees_usd, SUM(CAST(wallets AS BIGINT)) AS wallets
FROM dune.adam_tehc_co.dataset_gmgn_daily WHERE day = (SELECT MAX(day) FROM dune.adam_tehc_co.dataset_gmgn_daily)
UNION ALL
SELECT 'axiom', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE))
SELECT 'axiom', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE)), SUM(CAST(wallets AS BIGINT))
FROM dune.adam_tehc_co.dataset_axiom_daily WHERE day = (SELECT MAX(day) FROM dune.adam_tehc_co.dataset_axiom_daily)
UNION ALL
SELECT 'trojan', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE))
SELECT 'trojan', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE)), SUM(CAST(wallets AS BIGINT))
FROM dune.adam_tehc_co.dataset_trojan_daily WHERE day = (SELECT MAX(day) FROM dune.adam_tehc_co.dataset_trojan_daily)
UNION ALL
SELECT 'padre', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE))
SELECT 'padre', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE)), SUM(CAST(wallets AS BIGINT))
FROM dune.adam_tehc_co.dataset_terminal_daily WHERE day = (SELECT MAX(day) FROM dune.adam_tehc_co.dataset_terminal_daily)
UNION ALL
SELECT 'photon', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE))
SELECT 'photon', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE)), SUM(CAST(wallets AS BIGINT))
FROM dune.adam_tehc_co.dataset_photon_daily WHERE day = (SELECT MAX(day) FROM dune.adam_tehc_co.dataset_photon_daily)
UNION ALL
SELECT 'basedbot', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE))
SELECT 'basedbot', SUM(volume_usd), SUM(CAST(txns AS BIGINT)), SUM(CAST(fees_usd AS DOUBLE)), SUM(CAST(wallets AS BIGINT))
FROM dune.adam_tehc_co.dataset_basedbot_daily WHERE day = (SELECT MAX(day) FROM dune.adam_tehc_co.dataset_basedbot_daily)
UNION ALL
SELECT 'fomo', volume_usd, CAST(txns AS BIGINT), CAST(fees_usd AS DOUBLE)
SELECT 'fomo', volume_usd, CAST(txns AS BIGINT), CAST(fees_usd AS DOUBLE), CAST(wallets AS BIGINT)
FROM dune.adam_tehc_co.dataset_fomo_sol_daily WHERE day = (SELECT MAX(day) FROM dune.adam_tehc_co.dataset_fomo_sol_daily)
UNION ALL
SELECT 'pump-fun',
COALESCE((SELECT SUM(volume_usd) FROM dune.adam_tehc_co.dataset_pumpapp_sol_daily WHERE day=(SELECT MAX(day) FROM dune.adam_tehc_co.dataset_pumpapp_sol_daily)),0)
+ COALESCE((SELECT SUM(volume_usd) FROM dune.adam_tehc_co.dataset_pumpfun_relay_daily WHERE day=(SELECT MAX(day) FROM dune.adam_tehc_co.dataset_pumpfun_relay_daily) AND req_class='swap'),0),
COALESCE((SELECT SUM(CAST(txns AS BIGINT)) FROM dune.adam_tehc_co.dataset_pumpapp_sol_daily WHERE day=(SELECT MAX(day) FROM dune.adam_tehc_co.dataset_pumpapp_sol_daily)),0)
+ COALESCE((SELECT SUM(CAST(txns AS BIGINT)) FROM dune.adam_tehc_co.dataset_pumpfun_relay_daily WHERE day=(SELECT MAX(day) FROM dune.adam_tehc_co.dataset_pumpfun_relay_daily) AND req_class='swap'),0),
CAST(0 AS DOUBLE)
CAST(0 AS DOUBLE),
COALESCE((SELECT SUM(CAST(wallets AS BIGINT)) FROM dune.adam_tehc_co.dataset_pumpapp_sol_daily WHERE day=(SELECT MAX(day) FROM dune.adam_tehc_co.dataset_pumpapp_sol_daily)),0)
)
SELECT platform, volume_usd, txns, fees_usd,
SELECT platform, volume_usd, txns, fees_usd, wallets,
CASE WHEN txns > 0 THEN volume_usd / txns ELSE NULL END AS avg_trade_usd,
CASE WHEN volume_usd > 0 THEN fees_usd / volume_usd * 100 ELSE 0.0 END AS fee_rate_pct
FROM latest ORDER BY volume_usd DESC
Expand All @@ -60,12 +61,13 @@ type duneClient struct {
}

type duneRow struct {
Platform string `json:"platform"`
VolumeUSD float64 `json:"volume_usd"`
Txns float64 `json:"txns"`
FeesUSD float64 `json:"fees_usd"`
Platform string `json:"platform"`
VolumeUSD float64 `json:"volume_usd"`
Txns float64 `json:"txns"`
FeesUSD float64 `json:"fees_usd"`
Wallets float64 `json:"wallets"`
AvgTradeUSD float64 `json:"avg_trade_usd"`
FeeRatePct float64 `json:"fee_rate_pct"`
FeeRatePct float64 `json:"fee_rate_pct"`
}

func newDuneClient(apiKey string) *duneClient {
Expand Down
9 changes: 9 additions & 0 deletions harnesses/dune-platform-volume/cmd/script/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ var (
Help: "Observed fee take rate in percent per platform (fees_usd / volume_usd * 100, Dune community datasets).",
}, []string{"platform"})

platformWallets = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "dune_platform_wallets_24h",
Help: "Unique active wallets per platform for the latest complete day (Dune community datasets).",
}, []string{"platform"})

platformHealth = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "dune_platform_volume_health",
Help: "1 if this platform returned data in the last Dune poll.",
Expand All @@ -46,6 +51,7 @@ func init() {
platformFeesUSD,
platformAvgTrade,
platformFeeRate,
platformWallets,
platformHealth,
)
}
Expand All @@ -62,6 +68,9 @@ func publishRows(rows []duneRow) {
platformAvgTrade.WithLabelValues(r.Platform).Set(r.AvgTradeUSD)
}
platformFeeRate.WithLabelValues(r.Platform).Set(r.FeeRatePct)
if r.Wallets > 0 {
platformWallets.WithLabelValues(r.Platform).Set(r.Wallets)
}
platformHealth.WithLabelValues(r.Platform).Set(1)
}
}
Expand Down
17 changes: 16 additions & 1 deletion src/app/trading-apps/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const BENCH_SLUGS = [
"solana-dex-volume",
"solana-unique-traders",
"solana-avg-trade-size",
"trading-platform-wallets",
"solana-launchpad-wars",
"memecoin-platforms",
"app-store-ratings",
Expand Down Expand Up @@ -69,6 +70,14 @@ const COLUMNS = [
tip: "24h volume ÷ trade count via Mobula. Includes bots and MEV — platforms with heavy bot sniping (notably pump.fun) show lower averages than human-only baselines.",
higherBetter: true,
},
{
key: "wallets" as const,
label: "Active Wallets",
bench: "trading-platform-wallets",
fmt: fmtCount,
tip: "Unique wallets that traded through the platform in the last complete day (Dune community datasets). Cross-chain for GMGN/Axiom/BasedBot/Terminal. Better signal of real user base than raw tx count.",
higherBetter: true,
},
{
key: "feeRate" as const,
label: "Fee Rate",
Expand Down Expand Up @@ -130,6 +139,7 @@ const GROUPS = [
{ slug: "solana-dex-volume", title: "DEX volume & protocol revenue" },
{ slug: "solana-unique-traders", title: "Swap transactions" },
{ slug: "solana-avg-trade-size", title: "Average trade size" },
{ slug: "trading-platform-wallets", title: "Daily active wallets" },
],
},
{
Expand All @@ -147,18 +157,20 @@ const GROUPS = [
] as const;

export default async function TradingAppsHubPage() {
const [volBench, tradersBench, tradeSizeBench, feeBench, ratingsBench] =
const [volBench, tradersBench, tradeSizeBench, walletsBench, feeBench, ratingsBench] =
await Promise.all([
getBenchmark("solana-trading-platform-wars"),
getBenchmark("solana-unique-traders"),
getBenchmark("solana-avg-trade-size"),
getBenchmark("trading-platform-wallets"),
getBenchmark("memecoin-platforms"),
getBenchmark("app-store-ratings"),
]);

const volIdx = indexBySlug(volBench?.results);
const tradersIdx = indexBySlug(tradersBench?.results);
const tradeSizeIdx = indexBySlug(tradeSizeBench?.results);
const walletsIdx = indexBySlug(walletsBench?.results);
const feeIdx = indexBySlug(feeBench?.results);
const ratingIdx = indexBySlug(ratingsBench?.results);

Expand All @@ -168,6 +180,7 @@ export default async function TradingAppsHubPage() {
volume: number | null;
traders: number | null;
tradeSize: number | null;
wallets: number | null;
feeRate: number | null;
rating: number | null;
};
Expand All @@ -178,6 +191,7 @@ export default async function TradingAppsHubPage() {
volume: volIdx[p.slug] ?? null,
traders: tradersIdx[p.slug] ?? null,
tradeSize: tradeSizeIdx[p.slug] ?? null,
wallets: walletsIdx[p.slug] ?? null,
feeRate: feeIdx[p.slug] ?? null,
rating: ratingIdx[p.slug] ?? null,
})).sort((a, b) => (b.volume ?? -1) - (a.volume ?? -1));
Expand Down Expand Up @@ -431,6 +445,7 @@ export default async function TradingAppsHubPage() {
acq. Apr 2025). Swap transaction counts from Dune
Analytics (pump.fun: dex-level; terminals: fee-wallet detection).
Average trade size = volume ÷ trade count, includes bots and MEV.
Active wallets = unique wallet addresses per platform per day (Dune community datasets); cross-chain for GMGN/Axiom/BasedBot/Terminal.
Fee rate = on-chain fee revenue ÷ fee-paying volume (Dune tx join);
FOMO via DeFiLlama. App store ratings from the Apple iTunes lookup API.
All harnesses open source on{" "}
Expand Down
Loading