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
4 changes: 2 additions & 2 deletions benchmarks/solana-avg-trade-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ methodology:
- "Average swap size: solana_platform_volume_24h_usd / solana_platform_trades_24h, computed in PromQL."
- "Attribution: Mobula assigns each on-chain swap to a platform via referral tags, program IDs and memo fields embedded in transactions. Each swap is attributed to exactly one platform."
- "Bot inclusion: all attributed swaps are counted including bots and MEV. Platforms with high bot activity (notably pump.fun snipers) show lower average sizes than human-only baselines would suggest."
- "pump.fun: sourced from byLaunchpad (bonding-curve swaps on pump.fun's own site, $123M+ on Aug 13 2026 confirming bonding-curve volume persists under the fee-free model). Trades routed through GMGN or Axiom to pump.fun tokens count under those platforms. Mobula documents trades as swap-level count (not fee-event gated); whether zero-fee swaps post August 7 are indexed identically is an implementation detail not confirmed by docs pending Mobula support response."
- "pump.fun: sourced from byLaunchpad (bonding-curve swaps on pump.fun's own site, $123M+ on Aug 13 2026 confirming bonding-curve volume persists under the fee-free model). Trades routed through GMGN or Axiom to pump.fun tokens count under those platforms. Mobula documents trades as swap-level count (not fee-event gated); whether zero-fee swaps post August 7 are indexed identically is an implementation detail not confirmed by docs, pending Mobula support response."
- "Meteora DBC excluded: Meteora DBC counts LP provision events and micro-rebalances as trades, making its avg size of ~$12 not comparable to pure swap activity."

findings:
- "{{best_name}} attracts the largest average swap at ${{best_p50}} per transaction."
- "pump.fun has the smallest average swap size in the set, dominated by bot sniping and micro-cap degen retail flow on its bonding-curve launchpad."
- "GMGN and Trojan consistently lead on average swap size, serving more sophisticated traders with larger position sizes. Note: Mobula's volume attribution for GMGN and Trojan is broader than fee-paying volume (only ~8% of attributed volume generates a fee event per bench 203), so average size comparisons with pump.fun should be treated as directional."
- "Fomo sits mid-market between retail launchpad activity and professional terminals."
- "Trade count tells the other story: pump.fun processes more trades per day than all other platforms combined. Mobula defines trades as swap-level count; whether zero-fee bonding-curve swaps post August 7 are included identically is unconfirmed pending Mobula support."
- "Trade count tells the other story: pump.fun processes more trades per day than all other platforms combined. Mobula defines trades as swap-level count; whether zero-fee bonding-curve swaps post August 7 are included identically is unconfirmed, pending Mobula support."

source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/solana-launchpad-wars

Expand Down
6 changes: 3 additions & 3 deletions benchmarks/solana-unique-traders.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ unit: count
higher_is_better: true

disclaimer: |
The metric counts unique transaction IDs (not unique wallet addresses) whose transactions touched a known platform fee wallet in the rolling 24h window. This is a proxy for unique daily active traders; the actual unique-wallet count is typically 3-10x lower since active traders execute multiple trades per day. Counts include bots, MEV searchers, and multi-wallet traders. A transaction that touches two platform fee wallets is counted in both. pump.fun tracking relies on its 9 on-chain fee wallets; since pump.fun cut bonding-curve trading fees to 0% on 2026-08-07, its count reflects only transactions generating graduation and creator fees and substantially understates true trading activity.
Counts unique tx_ids touching a platform fee wallet in the rolling 24h window, not unique wallets. Actual unique-wallet count is 3-10x lower since active traders execute multiple trades per day. Includes bots, MEV searchers, and multi-wallet traders. A tx touching two fee wallets is counted in both. pump.fun is substantially undercounted since its bonding-curve trading fees were cut to 0% on 2026-08-07; its count now reflects only graduation and creator fee events.

seo_intro: |
GMGN leads Solana trading terminals by unique daily active wallets, serving a broad
Expand Down Expand Up @@ -77,7 +77,7 @@ providers:
- slug: pump-fun
name: pump.fun
tag: "Solana meme launchpad"
formula: "Unique wallet addresses (distinct fee_payer) whose transaction touched a pump.fun fee wallet in the last 24h (Dune: solana.account_activity, hourly refresh). Substantially undercounted post 2026-08-07 due to zero-fee policy."
formula: "Unique tx count touching pump.fun fee wallets in the last 24h (Dune: solana.account_activity, hourly). Undercounted post 2026-08-07 due to zero bonding-curve fee."
queries:
p50: solana_platform_unique_traders_24h{platform="pump-fun"}
p90: solana_platform_unique_traders_24h{platform="pump-fun"}
Expand Down Expand Up @@ -116,7 +116,7 @@ providers:
- slug: fomo
name: Fomo
tag: "Solana mobile trading app"
formula: "Unique tx count for transactions where Fomo's USDC fee wallet received a positive USDC inflow in the last 24h (Dune: solana.account_activity token_balance_owner match, hourly refresh). Captures on-chain per-trade Jupiter referral fee events; off-chain relay fees excluded."
formula: "Unique tx count where Fomo's fee wallet (token_balance_owner match) received USDC inflow in the last 24h (Dune: solana.account_activity, hourly). On-chain Jupiter referral fees only; off-chain relay excluded."
queries:
p50: solana_platform_unique_traders_24h{platform="fomo"}
p90: solana_platform_unique_traders_24h{platform="fomo"}
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/zetachain-rpc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ methodology:
- "Chain scope: every query on this page is pinned to `chain=\"zetachain\"`. Provider coverage: 1 no-key endpoint (Thirdweb). BlockPI returned 404; AllThatNode DNS is dead."

findings:
- "Provider coverage is critically limited: only Thirdweb (`7000.rpc.thirdweb.com`) is configured, and its current success rate from our probes is below 1% the endpoint responds to one-off requests but blocks sustained per-IP probing. Latency figures reflect the rare successful call and do not represent reliable availability. BlockPI and AllThatNode are dead for ZetaChain; no other free keyless endpoint was found operational at audit time."
- "Provider coverage is critically limited: only Thirdweb (`7000.rpc.thirdweb.com`) is configured, and its current success rate from our probes is below 1%; the endpoint responds to one-off requests but blocks sustained per-IP probing. Latency figures reflect the rare successful call and do not represent reliable availability. BlockPI and AllThatNode are dead for ZetaChain; no other free keyless endpoint was found operational at audit time."
- "Manual use of `7000.rpc.thirdweb.com` works for individual calls. The 0.5% probe success rate is an artifact of rate-limiting against our fixed Railway probe IPs, not a general outage."

faq:
Expand Down
151 changes: 76 additions & 75 deletions src/app/benchmarks/trading-app-execution/page.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,56 @@
import type { Metadata } from "next";
import { readFileSync } from "fs";
import { join } from "path";
import yaml from "js-yaml";
import Link from "next/link";
import { pageMetadata } from "@/lib/page-metadata";
import { safeJsonLd, buildBreadcrumbJsonLd, buildFaqPageJsonLd } from "@/lib/jsonld";
import { SITE } from "@/data/site";
import { fetchExecLeaderboard } from "@/lib/solana-exec";
import { fetchEVMRevenue } from "@/lib/evm-exec";
import { ExecChainTabs } from "@/components/exec-chain-tabs";
import { ExecBenchTable } from "@/components/exec-bench-table";

export const revalidate = 60;

type BenchMeta = {
faq: { q: string; a: string }[];
methodology: string[];
findings: string[];
subtitle: string;
};

function loadBenchMeta(): BenchMeta {
const raw = readFileSync(
join(process.cwd(), "benchmarks/trading-app-execution.yml"),
"utf-8",
);
return yaml.load(raw) as BenchMeta;
}

export const metadata: Metadata = pageMetadata({
path: "/benchmarks/trading-app-execution",
title: "Trading App Execution Quality: Axiom vs GMGN vs Trojan vs Maestro | OpenChainBench",
title:
"Trading App Execution Quality: Axiom vs GMGN vs Trojan vs Maestro | OpenChainBench",
description:
"Compare on-chain execution quality for Solana trading apps: avg platform fee, priority fee, Jito bundle rate, CU price. Axiom vs GMGN vs Trojan vs Maestro, measured passively from fee accounts, updated hourly.",
"Compare on-chain execution quality for Solana trading apps: Jito rate, CU price, priority fee, platform fee. Axiom vs GMGN vs Trojan vs Maestro, measured passively from fee accounts.",
});

const FAQ = [
{
q: "What is platform fee vs priority fee?",
a: "Priority fee is paid to Solana validators to compete for block space; it does not go to the trading app. Platform fee is the SOL transferred to the trading app's own fee wallet per transaction, which is the actual revenue the platform captures from each trade.",
},
{
q: "How is transaction count measured?",
a: "Tx count comes from getSignaturesForAddress on the platform's fee wallet(s), giving the total number of transactions that sent fees to that address. This is the full population count, not a sample; the 100-tx sample is used only for fee amount and CU metrics.",
},
{
q: "Why does Trojan show a near-zero Jito rate?",
a: "Trojan does not appear to use Jito MEV bundles for its standard execution path, consistent with its design as a Telegram bot that prioritises simplicity over MEV protection.",
},
{
q: "Why are EVM revenues lower than Solana revenues?",
a: "Most platforms primarily target Solana users. EVM fee collection varies: some platforms charge mostly in native ETH/BNB via internal transactions which are not traceable without a trace API. The EVM figures reflect directly visible USDC and native transfers only.",
},
{
q: "How often is data updated?",
a: "Solana metrics update every 5 minutes (materialiser cycle). EVM revenue updates block-by-block continuously. The timestamp in the table header reflects the last materialiser run.",
},
{
q: "Which platforms are tracked on EVM chains?",
a: "GMGN, Maestro, and Banana Gun are tracked on Ethereum. GMGN, Maestro, Axiom, and Banana Gun are tracked on BSC. GMGN, Maestro, and Banana Gun are tracked on Base. pump.fun Terminal is tracked on all three EVM chains.",
},
];

export default async function TradingAppExecutionPage() {
const [solanaData, evmData] = await Promise.all([
const [data, meta] = await Promise.all([
fetchExecLeaderboard(),
fetchEVMRevenue(),
Promise.resolve(loadBenchMeta()),
]);

const breadcrumb = buildBreadcrumbJsonLd([
{ name: "Home", item: SITE.url },
{ name: "Benchmarks", item: `${SITE.url}/benchmarks` },
{ name: "Trading App Execution", item: `${SITE.url}/benchmarks/trading-app-execution` },
{
name: "Trading App Execution",
item: `${SITE.url}/benchmarks/trading-app-execution`,
},
]);

const faqJsonLd = buildFaqPageJsonLd(
FAQ,
meta.faq,
`${SITE.url}/benchmarks/trading-app-execution`,
);

Expand All @@ -65,24 +59,36 @@ export default async function TradingAppExecutionPage() {
<script
type="application/ld+json"
// biome-ignore lint/security/noDangerouslySetInnerHtml: serialized via safeJsonLd
dangerouslySetInnerHTML={{ __html: safeJsonLd({ "@context": "https://schema.org", ...breadcrumb }) }}
/>
<script
type="application/ld+json"
// biome-ignore lint/security/noDangerouslySetInnerHtml: serialized via safeJsonLd
dangerouslySetInnerHTML={{ __html: safeJsonLd(faqJsonLd) }}
dangerouslySetInnerHTML={{
__html: safeJsonLd({
"@context": "https://schema.org",
...breadcrumb,
}),
}}
/>
{faqJsonLd && (
<script
type="application/ld+json"
// biome-ignore lint/security/noDangerouslySetInnerHtml: serialized via safeJsonLd
dangerouslySetInnerHTML={{ __html: safeJsonLd(faqJsonLd) }}
/>
)}

{/* Breadcrumb */}
<nav className="flex items-center gap-1.5 text-xs text-ink-muted mb-6 font-mono">
<Link href="/" className="hover:text-ink-soft transition-colors">Home</Link>
<Link href="/" className="hover:text-ink-soft transition-colors">
Home
</Link>
<span>/</span>
<Link href="/benchmarks" className="hover:text-ink-soft transition-colors">Benchmarks</Link>
<Link
href="/benchmarks"
className="hover:text-ink-soft transition-colors"
>
Benchmarks
</Link>
<span>/</span>
<span className="text-ink">Trading App Execution</span>
</nav>

{/* Header */}
<div className="flex items-start gap-3 flex-wrap">
<span
className="inline-flex items-center px-2.5 py-0.5 rounded-full text-[11px] font-medium text-white shrink-0 mt-0.5"
Expand All @@ -100,37 +106,29 @@ export default async function TradingAppExecutionPage() {
Trading app execution quality.
</h1>
<p className="mt-4 max-w-2xl text-base text-ink-soft leading-snug">
Passive on-chain execution metrics for the top Solana trading apps and Telegram bots.
Priority fee, Jito rate, CU price, and platform fee per transaction, measured directly
from fee accounts, no synthetic trades. EVM chain revenue on the chain tabs below.
{meta.subtitle}
</p>

<div className="mt-10">
<ExecChainTabs solanaData={solanaData} evmData={evmData} />
<ExecBenchTable data={data} />
</div>

{/* Methodology */}
<div className="mt-10 border-t border-rule pt-8 text-xs text-ink-muted leading-relaxed max-w-2xl space-y-2">
<p className="text-xs font-medium text-ink-muted uppercase tracking-wide mb-3">Methodology</p>
<p>
<strong>Priority fee</strong> = total transaction fee minus the 5 000-lamport base fee per signature. Paid to validators, not to the platform.
</p>
<p>
<strong>CU price</strong> = priority fee ÷ compute units consumed (microlamports/CU). p50/p95 shows median and tail pressure on each platform.
</p>
<p>
<strong>Jito rate</strong> = fraction of transactions tipping one of the 8 official Jito tip accounts. Higher = more MEV-sensitive routing.
</p>
<p>
<strong>Platform fee</strong> = average SOL transferred to the platform's fee account per incoming transaction. This is actual protocol revenue per trade.
<p className="text-xs font-medium text-ink-muted uppercase tracking-wide mb-3">
Methodology
</p>
<p>
<strong>Tx count</strong> = total transactions at the fee wallet over the window (getSignaturesForAddress), not a sample. Fee metrics use a 100-tx sample per poll.
</p>
<p>
<strong>EVM</strong> = USDC (ERC-20) + native ETH/BNB direct transfers to each platform's fee address. Base chain: USDC only (no free trace API). Updated block-by-block.
</p>
<p className="text-ink-faint">
{meta.methodology.map((item, i) => {
const colonIdx = item.indexOf(": ");
if (colonIdx === -1) return <p key={i}>{item}</p>;
const label = item.slice(0, colonIdx);
const rest = item.slice(colonIdx + 2);
return (
<p key={i}>
<strong>{label}</strong>: {rest}
</p>
);
})}
<p className="text-ink-faint mt-3">
Source:{" "}
<a
href="https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/solana-exec"
Expand All @@ -144,11 +142,12 @@ export default async function TradingAppExecutionPage() {
</p>
</div>

{/* FAQ */}
<div className="mt-10 border-t border-rule pt-8 max-w-2xl">
<p className="text-xs font-medium text-ink-muted uppercase tracking-wide mb-5">FAQ</p>
<p className="text-xs font-medium text-ink-muted uppercase tracking-wide mb-5">
FAQ
</p>
<div className="space-y-6">
{FAQ.map((item) => (
{meta.faq.map((item) => (
<div key={item.q}>
<p className="font-medium text-sm text-ink mb-1">{item.q}</p>
<p className="text-sm text-ink-soft leading-relaxed">{item.a}</p>
Expand All @@ -157,10 +156,12 @@ export default async function TradingAppExecutionPage() {
</div>
</div>

{/* Back link */}
<div className="mt-10 pt-6 border-t border-rule">
<Link href="/apps" className="text-sm text-ink-muted hover:text-ink-soft transition-colors">
← Back to trading app revenue
<Link
href="/apps"
className="text-sm text-ink-muted hover:text-ink-soft transition-colors"
>
Back to trading app revenue
</Link>
</div>
</article>
Expand Down
Loading