From 122f1b7bdd4b93fd643d165b26336ef35fb8d42c Mon Sep 17 00:00:00 2001 From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Mon, 27 Jul 2026 17:30:40 +0200 Subject: [PATCH] token-quote-coverage: re-add KyberSwap + ParaSwap (they DO emit, spec comment outdated) Prom on VPS confirms 5 providers with real 24h data: - KyberSwap: 981 attempts, 95.5% on Robinhood, 58.0% on BSC - ParaSwap: 314 attempts, 9.9% on BSC Also update per_chain_explainer (Robinhood cohort: 4 not 2), methodology chain-scope + endpoint list, FAQ EVM-only null-cell wording. --- benchmarks/token-quote-coverage.yml | 42 ++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/benchmarks/token-quote-coverage.yml b/benchmarks/token-quote-coverage.yml index 0e2f2900..2bcc7d42 100644 --- a/benchmarks/token-quote-coverage.yml +++ b/benchmarks/token-quote-coverage.yml @@ -23,7 +23,7 @@ per_chain_explainer: - slug: robinhood h2: "DEX aggregator coverage on Robinhood Chain" body: | - Robinhood Chain (chainId 4663) is Robinhood's EVM-compatible Layer 2, launched in 2025. Tokens launch and graduate via the Pons launchpad to Uniswap V3-based pools, with USDG as the primary stablecoin. Virtuals Protocol has also expanded to Robinhood, so the bench now probes both Pons-graduated tokens and Virtuals agents deployed on Robinhood. Two aggregators cover this chain: Mobula and Relay. {{best_name:chain:robinhood}} currently leads on Robinhood at {{best_p50:chain:robinhood}} coverage (24h). The leaderboard captures improvements in real time as aggregators deepen their Robinhood integration. + Robinhood Chain (chainId 4663) is Robinhood's EVM-compatible Layer 2, launched in 2025. Tokens launch and graduate via the Pons launchpad to Uniswap V3-based pools, with USDG as the primary stablecoin. Virtuals Protocol has also expanded to Robinhood, so the bench now probes both Pons-graduated tokens and Virtuals agents deployed on Robinhood. Four aggregators cover this chain: Mobula, KyberSwap, ParaSwap and Relay. {{best_name:chain:robinhood}} currently leads on Robinhood at {{best_p50:chain:robinhood}} coverage (24h). The leaderboard captures improvements in real time as aggregators deepen their Robinhood integration. category: Aggregators status: live @@ -68,14 +68,15 @@ abstract: | structural (it does not index Meteora DBC pool types) or temporary (it lags new Raydium pairs by a few minutes). The chain dimension narrows to a single chain for providers that are chain-specific - (Jupiter is Solana-only; Mobula and Relay cover all four chains). + (Jupiter is Solana-only; KyberSwap and ParaSwap are EVM-only on + Base + BNB + Robinhood; Mobula and Relay cover all four chains). methodology: - "Token discovery: five sources in parallel. (1) Dexscreener token-boosts: pump-fun (Solana) and pons (Robinhood). (2) Virtuals Protocol API: Virtuals agents on Base and Robinhood chain (virtuals). (3) GeckoTerminal BSC new_pools: four-meme. (4) GeckoTerminal Solana moonshot/pools: moonshot. (5) GeckoTerminal Solana meteora-dbc/pools: meteora-dbc. Boosted tokens from (1) are enriched via Dexscreener batch lookup to resolve dexId to venue labels." - "Quote probe: 1 USDC → token, fired in parallel to all in-scope providers with a 10s timeout. Input token is always USDC (native USDC on Solana and Base, bridged USDC.e on BNB). A probe is a coverage hit when the HTTP response is 2xx and the parsed outAmount field is a non-zero positive integer or decimal. All other outcomes (4xx, 5xx, no-route JSON, empty outAmount, timeout) record as misses." - - "Aggregator endpoints: Jupiter lite-api.jup.ag/swap/v1/quote (Solana), Mobula /api/2/swap/quoting (EVM + Solana, API key), Relay api.relay.link/quote (EVM + Solana, no key). Each adapter normalises chain identifiers, input/output decimals, and error response shapes before recording outcome." + - "Aggregator endpoints: Jupiter lite-api.jup.ag/swap/v1/quote (Solana), Mobula /api/2/swap/quoting (EVM + Solana, API key), Relay api.relay.link/quote (EVM + Solana, no key), KyberSwap aggregator-api.kyberswap.com/{chain}/api/v1/routes (EVM only, no key), ParaSwap apiv5.paraswap.io/prices (EVM only, no key). Each adapter normalises chain identifiers, input/output decimals, and error response shapes before recording outcome." - "Jupiter strictMode=false: queried without the curated-token filter so Jupiter will attempt routing for any token with a discoverable on-chain pool, matching how most wallets call the API. strictMode=true would trivially exclude new tokens and defeat the purpose of the benchmark." - - "Chain-scope enforcement: Jupiter probes Solana-only. Mobula and Relay probe all four chains (Solana, Base, BNB, Robinhood). Providers are never penalised for chains they do not support: null cells are excluded from cross-chain aggregates." + - "Chain-scope enforcement: Jupiter probes Solana-only. KyberSwap and ParaSwap probe EVM only (Base, BNB, Robinhood). Mobula and Relay probe all four chains including Solana. Providers are never penalised for chains they do not support: null cells are excluded from cross-chain aggregates." - "Coverage metric: Prometheus counters token_quote_coverage_success_total and token_quote_coverage_attempts_total carry labels {provider, venue, chain}. The bench queries compute increase(success[24h]) / increase(attempts[24h]) * 100 live at read time. No pre-aggregation; the ratio reflects exactly the tokens probed in the rolling window." - "Probe cadence and deduplication: each batch cycles through the current Dexscreener token-boosts feed. Tokens are not deduplicated across batches; the same token may appear in multiple 30-minute windows if it remains boosted. The score therefore reflects freshness of the aggregator's current routing graph, not historical coverage depth." - "Single origin: all probes originate from the eu-west OCB VPS. Regional latency is not a factor in this bench (the outcome is binary hit/miss, not latency). No region dimension in v1." @@ -102,7 +103,7 @@ faq: - q: "Why is Jupiter queried with strictMode=false?" a: "Jupiter's strictMode=true restricts quotes to verified tokens on its curated list, which defeats the purpose of a coverage bench targeting newly-launched tokens. strictMode=false instructs Jupiter to attempt routing for any token with an existing pool, matching how wallets typically call the API when displaying all tradeable tokens." - q: "What happens when a provider is chain-specific?" - a: "Jupiter is Solana-only and appears as null on EVM rows. Mobula and Relay cover all four chains including Solana. Null cells are excluded from cross-chain aggregates so chain-restricted providers are not penalized." + a: "Jupiter is Solana-only and appears as null on EVM rows. KyberSwap and ParaSwap are EVM-only and appear as null on Solana rows. Mobula and Relay cover all four chains including Solana. Null cells are excluded from cross-chain aggregates so chain-restricted providers are not penalized." source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/token-quote-coverage @@ -163,11 +164,6 @@ providers: sample_size: sum(increase(token_quote_coverage_attempts_total{provider="jupiter"}[24h])) series: sum(rate(token_quote_coverage_success_total{provider="jupiter"}[1h])) / sum(rate(token_quote_coverage_attempts_total{provider="jupiter"}[1h])) * 100 - # KyberSwap + ParaSwap declared in earlier revisions of this spec are - # currently not emitting on the harness (no token_quote_coverage_* - # metric with those provider labels in Prom). Removed from the public - # providers list until the harness ships probes for them, to avoid - # readers seeing a 5-provider claim that renders as 3. - slug: relay name: Relay tag: Multi-chain, Solana + Base + BNB + Robinhood, no key @@ -181,4 +177,30 @@ providers: sample_size: sum(increase(token_quote_coverage_attempts_total{provider="relay"}[24h])) series: sum(rate(token_quote_coverage_success_total{provider="relay"}[1h])) / sum(rate(token_quote_coverage_attempts_total{provider="relay"}[1h])) * 100 + - slug: kyberswap + name: KyberSwap + tag: EVM aggregator, Base + BNB + Robinhood, no key + formula: "Rolling 24h ratio for provider=kyberswap. EVM-only: Base, BNB Chain, Robinhood. No Solana support (structural, not a coverage gap). No API key required." + queries: + p50: sum(increase(token_quote_coverage_success_total{provider="kyberswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="kyberswap"}[24h])) * 100 + p90: sum(increase(token_quote_coverage_attempts_total{provider="kyberswap"}[24h])) + p99: sum(increase(token_quote_coverage_success_total{provider="kyberswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="kyberswap"}[24h])) * 100 + mean: sum(increase(token_quote_coverage_success_total{provider="kyberswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="kyberswap"}[24h])) * 100 + success: clamp_max(sum(increase(token_quote_coverage_success_total{provider="kyberswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="kyberswap"}[24h])), 1) + sample_size: sum(increase(token_quote_coverage_attempts_total{provider="kyberswap"}[24h])) + series: sum(rate(token_quote_coverage_success_total{provider="kyberswap"}[1h])) / sum(rate(token_quote_coverage_attempts_total{provider="kyberswap"}[1h])) * 100 + + - slug: paraswap + name: ParaSwap + tag: EVM aggregator, Base + BNB + Robinhood, no key + formula: "Rolling 24h ratio for provider=paraswap. EVM-only: Base, BNB Chain, Robinhood. No Solana support (structural). No API key required." + queries: + p50: sum(increase(token_quote_coverage_success_total{provider="paraswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="paraswap"}[24h])) * 100 + p90: sum(increase(token_quote_coverage_attempts_total{provider="paraswap"}[24h])) + p99: sum(increase(token_quote_coverage_success_total{provider="paraswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="paraswap"}[24h])) * 100 + mean: sum(increase(token_quote_coverage_success_total{provider="paraswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="paraswap"}[24h])) * 100 + success: clamp_max(sum(increase(token_quote_coverage_success_total{provider="paraswap"}[24h])) / sum(increase(token_quote_coverage_attempts_total{provider="paraswap"}[24h])), 1) + sample_size: sum(increase(token_quote_coverage_attempts_total{provider="paraswap"}[24h])) + series: sum(rate(token_quote_coverage_success_total{provider="paraswap"}[1h])) / sum(rate(token_quote_coverage_attempts_total{provider="paraswap"}[1h])) * 100 +