Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1c4af0f
fix: codex auth chain — un.defined.fi + utls + sidecar fallback (#1819)
Flotapponnier Aug 10, 2026
5ac8037
fix(codex-scraper): cap at 3 failures then disable to stop log spam (…
Flotapponnier Aug 11, 2026
fbe8b59
merge: dev -> main (bench 204 rebuild + all recent fixes) (#1919)
Flotapponnier Aug 13, 2026
6537638
fix(204): restore ExecBenchTable page (#1924)
Flotapponnier Aug 13, 2026
0b57389
revert: remove bench merges from prod — keep on staging only (#1929)
Flotapponnier Aug 13, 2026
a0c61a0
feat: bench 202 app-store-ratings cherry-pick to prod (#1935)
Flotapponnier Aug 13, 2026
7440ce4
fix: sitemap omits chain URLs on error to prevent smoke-gate 404s (#1…
Flotapponnier Aug 13, 2026
ad5ee17
fix: sitemap static fallback filters chains without bench YAML (#1938)
Flotapponnier Aug 13, 2026
dda54f6
fix: escape apostrophe in apps/exec page (lint) (#1939)
Flotapponnier Aug 13, 2026
15b2a53
fix: add missing logo manifest entries (pump-fun, gmgn, moonshot, bul…
Flotapponnier Aug 13, 2026
b52b619
merge: dev → main (full sync aug-13)
Flotapponnier Aug 13, 2026
01b1baa
Merge pull request #1942 from ChainBench/ship/dev-to-main-aug13
Flotapponnier Aug 13, 2026
e466600
fix: resolve 6 validate-specs errors from dev merge (em-dashes, blast…
Flotapponnier Aug 13, 2026
69a5915
fix: remove duplicate provider-registry entries from dev merge (#1944)
Flotapponnier Aug 13, 2026
a8e16a0
fix: remove duplicate logo-manifest and brand entries from dev merge …
Flotapponnier Aug 13, 2026
66e84c6
fix: add sol unit to views.ts and snapshot.ts (typecheck) (#1946)
Flotapponnier Aug 13, 2026
30682aa
fix: wrap Date.now() in useMemo (react-compiler lint) (#1947)
Flotapponnier Aug 13, 2026
1789d48
fix: move useMemo before early return (hooks rules) (#1948)
Flotapponnier Aug 13, 2026
5c61a43
fix: disable react-compiler for Date.now() in render (#1949)
Flotapponnier Aug 13, 2026
3845ec0
fix: use module-level NOW_MS constant instead of Date.now() in render…
Flotapponnier Aug 13, 2026
070143b
feat: inline Solana exec quality into /apps hub, remove /apps/exec su…
Flotapponnier Aug 15, 2026
292faaa
fix: guard data.platforms spread in ExecBenchTable against null
Flotapponnier Aug 15, 2026
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/blast-rpc.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -30,7 +30,7 @@ methodology:

findings:
- "{{best_name}} currently leads free Blast RPC at {{best_p50}} (`eth_getBlockByNumber` p50, 24h) across 4 measured providers."
- "`rpc.blast.io` posts ~2 ms in every region simultaneously. On-chain response headers confirm geo-distributed nodes: `blast_blast-mainnet_fra` from eu-west, `blast_blast-mainnet_sin` from Singapore, a US node from us-east. Blast runs RPC nodes inside the same GCP datacenters as our Railway probes, producing sub-2 ms figures that reflect co-located infrastructure rather than typical user latency. A user in Paris reaches the Frankfurt node in ~40 ms; a user outside GCP will see 30-100 ms depending on location. Heads are fresh per stale detection."
- "`rpc.blast.io` posts ~2 ms in every region. Response headers confirm geo-distributed GCP nodes co-located with our Railway probes (`blast_blast-mainnet_fra` from eu-west, `blast_blast-mainnet_sin` from Singapore, US node from us-east). Sub-2 ms reflects co-location, not real-world latency; outside GCP expect 30-100 ms. Heads are fresh per stale detection."
- "{{name:drpc}} ({{p50:drpc}}) is the honest-infrastructure comparison point: anycast consistency across the three regions with real node round trips behind it, the profile that wins it 10 of the 12 expansion chains."
- "{{name:tenderly}} sits at the expansion's familiar flat ~330 ms in all regions on Blast, single-origin routing on a gateway that is genuinely quick on the major chains."

Expand All@@ -44,7 +44,7 @@ faq:
- q: "How is Blast RPC latency measured here?"
a: "One identical JSON-RPC POST (`eth_getBlockByNumber`) every 60 seconds against each provider from each of 3 regions, with the same plain HTTP client. Wall-clock round-trip is recorded at millisecond precision; p50/p90/p99 are computed via Prometheus `quantile_over_time` over 24 hours. Responses are classified (`ok` / `http_err` / `jsonrpc_err` / `stale` / `timeout`) so an endpoint stuck on an old head or returning errors behind HTTP 200 is never ranked as fastest. The harness is open source and every number on this page is a public Prometheus query you can run yourself."
- q: "Is rpc.blast.io really that fast, or is something else going on?"
a: "Blast runs geo-distributed RPC nodes inside major cloud datacenters (GCP us-east, GCP europe-west4/Frankfurt, GCP asia-southeast1/Singapore). Our Railway probes run in the same three GCP regions, so each probe hits the co-located Blast node with a sub-LAN round trip. The `x-node-id` response header confirms this: `blast_blast-mainnet_fra` from eu-west, `blast_blast-mainnet_sin` from Singapore. The blocks are fresh — this is not a cache hit but the 1-2 ms figure reflects network co-location, not what a developer outside GCP infra will experience. From a typical residential connection or a non-GCP cloud, expect 30-100 ms."
a: "Blast runs geo-distributed RPC nodes inside major cloud datacenters (GCP us-east, GCP europe-west4/Frankfurt, GCP asia-southeast1/Singapore). Our Railway probes run in the same three GCP regions, so each probe hits the co-located Blast node with a sub-LAN round trip. The `x-node-id` response header confirms this: `blast_blast-mainnet_fra` from eu-west, `blast_blast-mainnet_sin` from Singapore. The blocks are fresh (not a cache hit) but the 1-2 ms figure reflects network co-location, not what a developer outside GCP infra will experience. From a typical residential connection or a non-GCP cloud, expect 30-100 ms."

source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/monad-rpc.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,7 +47,7 @@ methodology:

findings:
- "{{best_name}} currently leads the free Monad RPC field at {{best_p50}} (p50, 24h) across 5 measured providers."
- "{{name:monad-official}} answers at {{p50:monad-official}}. On-chain response headers (`x-node-id: monad_monad-mainnet_fra`) confirm geo-distributed nodes co-located with our Railway probes in GCP datacenters (Frankfurt for eu-west, equivalent US and Singapore nodes). The sub-2 ms figure reflects network co-location, not what a developer outside GCP infra will experience expect 30-120 ms from a typical connection. Rate-limit: 25 rps."
- "{{name:monad-official}} answers at {{p50:monad-official}}. On-chain response headers (`x-node-id: monad_monad-mainnet_fra`) confirm geo-distributed nodes co-located with our Railway probes in GCP datacenters (Frankfurt for eu-west, equivalent US and Singapore nodes). The sub-2 ms figure reflects network co-location, not what a developer outside GCP infra will experience; expect 30-120 ms from a typical connection. Rate-limit: 25 rps."
- "{{name:drpc}} sits at {{p50:drpc}} and {{name:tenderly}} at {{p50:tenderly}}: the multi-chain gateways reached Monad within weeks of mainnet, but route through their global meshes rather than chain-local nodes."
- "{{name:bloxroute}} at {{p50:bloxroute}} is the outlier entry: a BDN operator exposing a keyless endpoint, unusual for a company whose core product is paid low-latency access."

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/perp-cost-slope.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,7 +88,7 @@ per_chain_explainer:

findings:
- "{{name:gains}} and {{name:gmx}} always score 1.00 by construction, not by performance: oracle-priced venues charge a flat percentage of notional with no orderbook, so the $1M all-in is identical to the $1k all-in in basis points regardless of market conditions. Their top leaderboard position reflects fee structure, not execution quality."
- "Among orderbook venues, {{name:hyperliquid}} sits at {{p50:hyperliquid}} cost slope (24h avg) the lowest impact in the cohort at $1M notional, driven by the deepest onchain book."
- "Among orderbook venues, {{name:hyperliquid}} sits at {{p50:hyperliquid}} cost slope (24h avg), the lowest impact in the cohort at $1M notional, driven by the deepest onchain book."
- "Venues showing N/A in the slope column cannot reliably fill a $1M market order. The fill-rate panel shows what fraction of measurement cycles the $1M tier was successfully absorbed."
- "The cost slope is asset-specific: use the chain tabs to compare ETH (deepest books), BTC (tightest books) and SOL (thinnest books) separately."

Expand Down
18 changes: 18 additions & 0 deletions benchmarks/trading-app-execution.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,6 +57,24 @@ faq:
- 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."

providers:
- slug: axiom
name: Axiom
- slug: gmgn
name: GMGN
- slug: trojan
name: Trojan
- slug: maestro
name: Maestro
- slug: pump-fun
name: pump.fun
- slug: photon
name: Photon
- slug: bullx
name: BullX
- slug: banana-gun
name: Banana Gun

# No prometheus section -- this bench uses a custom page renderer
# at src/app/benchmarks/trading-app-execution/page.tsx that reads
# directly from the exec REST API (exec.openchainbench.com).
77 changes: 0 additions & 77 deletions src/app/apps/exec/page.tsx

This file was deleted.

36 changes: 29 additions & 7 deletions src/app/apps/page.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,6 +10,7 @@ import { TRADING_APPS } from "@/lib/trading-apps-config";
import { fetchDeFiLlamaData } from "@/lib/defillama";
import { TradingAppsLeaderboard, type UnifiedAppRow } from "@/components/trading-apps-leaderboard";
import { RevenueSummary } from "@/components/revenue-summary";
import { SolanaExecTable } from "@/components/solana-exec-table";
import Link from "next/link";

const DESCRIPTION =
Expand DownExpand Up@@ -38,7 +39,6 @@ export default async function AppsHubPage() {
fetchDeFiLlamaData(dlSlugMap),
]);

// Market share = each platform's DL 24h fees / cohort total (active only)
const activeDlTotal = TRADING_APPS.filter((a) => !a.inactive && a.defillamaSlug)
.reduce((sum, a) => sum + (dlData.get(a.id)?.total24h ?? 0), 0);

Expand DownExpand Up@@ -69,22 +69,18 @@ export default async function AppsHubPage() {
const wData = solRow.windows[w];
if (wData) {
if (meta.solanaFeeIsUSDC) {
// Fees collected in USDC (6 dec): raw units / 1e6 = USD directly
solanaFees = wData.sumPlatformFeeLamports / 1e6;
} else if (solPrice !== null) {
solanaFees = wData.sumPlatformFeeLamports / 1e9 * solPrice;
}
}
}

// FOMO: supplement on-chain fees with off-chain relay fees from Dune
// (relay accounts for ~96% of FOMO's actual revenue)
if (meta.id === "fomo" && fomoRelay) {
const relayFee = w === "24h" ? fomoRelay.fees24h : w === "7d" ? fomoRelay.fees7d : fomoRelay.fees30d;
solanaFees = (solanaFees ?? 0) + relayFee;
}

// EVM: 24h adds native ETH/BNB in USD; 7d/30d stable only (no historical prices).
const evmStable = (chain: typeof ethChain) =>
!chain ? null : w === "24h" ? chain.stable24h : w === "7d" ? chain.stable7d : chain.stable30d;
const evmNative = (chain: typeof ethChain) =>
Expand DownExpand Up@@ -165,6 +161,32 @@ export default async function AppsHubPage() {
</div>
)}

<div className="mt-10 border-t border-rule pt-8">
<h2 className="text-lg font-semibold text-ink mb-1">Solana execution quality</h2>
<p className="text-sm text-ink-soft mb-6">
Priority fees, Jito bundle rates, and platform fees per transaction — measured passively from on-chain data.
</p>
<SolanaExecTable
platforms={solanaData?.platforms ?? []}
updatedAt={solanaData?.updatedAt ?? null}
/>
<div className="mt-4 text-xs text-ink-muted leading-relaxed max-w-2xl space-y-1.5">
<p>
<strong>Priority fee</strong> = total tx fee minus the 5 000-lamport base fee per signature.
</p>
<p>
<strong>CU price</strong> = priority fee ÷ compute units consumed (microlamports/CU). p50/p95 shows median and tail pressure.
</p>
<p>
<strong>Jito rate</strong> = fraction of transactions tipping a Jito tip account. Higher = more MEV-sensitive routing.
</p>
<p>
<strong>Platform fee</strong> = avg SOL to the platform fee account per transaction.
Source: Helius enhanced transaction API. No synthetic trades, no on-chain footprint.
</p>
</div>
</div>

<div className="mt-10 border-t border-rule pt-8">
<p className="text-xs font-medium text-ink-muted uppercase tracking-wide mb-3">Related benchmarks</p>
<div className="flex flex-wrap gap-3">
Expand All@@ -187,8 +209,8 @@ export default async function AppsHubPage() {
>
<span className="text-lg">⚡</span>
<div>
<p className="text-sm font-medium text-ink group-hover:text-accent transition-colors">Execution Quality</p>
<p className="text-xs text-ink-muted">Priority fees, Jito rates, platform fees</p>
<p className="text-sm font-medium text-ink group-hover:text-accent transition-colors">Execution Quality Bench</p>
<p className="text-xs text-ink-muted">Priority fees, Jito rates, platform fees — full dataset</p>
</div>
<svg className="ml-auto text-ink-faint group-hover:text-ink-muted transition-colors" width="14" height="14" viewBox="0 0 12 12" fill="none" aria-hidden="true">
<path d="M3.5 3H2a1 1 0 00-1 1v6a1 1 0 001 1h6a1 1 0 001-1V8.5M7 1h4m0 0v4m0-4L5.5 6.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/>
Expand Down
12 changes: 6 additions & 6 deletions src/components/exec-bench-table.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,7 @@ import { useState } from "react";
import type { ExecLeaderboardResponse } from "@/lib/solana-exec";
import { PLATFORM_DISPLAY, lamportsToSOL, fmtCUPrice } from "@/lib/solana-exec";

const NOW_MS = Date.now();
const WINDOWS = ["24h", "7d", "30d"] as const;
type Window = (typeof WINDOWS)[number];

Expand All@@ -28,6 +29,10 @@ export function ExecBenchTable({
data: ExecLeaderboardResponse | null;
}) {
const [win, setWin] = useState<Window>("24h");
const stale =
data?.updatedAt
? NOW_MS - new Date(data.updatedAt).getTime() > 3 * 60 * 60 * 1000
: false;

if (!data) {
return (
Expand All@@ -37,16 +42,11 @@ export function ExecBenchTable({
);
}

const sorted = [...data.platforms].sort(
const sorted = [...(data.platforms ?? [])].sort(
(a, b) =>
(b.windows[win]?.txCount ?? 0) - (a.windows[win]?.txCount ?? 0),
);

const stale =
data.updatedAt
? Date.now() - new Date(data.updatedAt).getTime() > 3 * 60 * 60 * 1000
: false;

return (
<div className="card rounded-xl overflow-hidden">
<div className="px-4 sm:px-6 pt-4 pb-0 flex items-end justify-between gap-4 flex-wrap border-b border-rule">
Expand Down
Loading
Loading