From 77b5567e47f846c6693218f41d0de9dd78849b46 Mon Sep 17 00:00:00 2001 From: Jon Saad-Falcon <41205309+jonsaadfalcon@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:58:36 -0700 Subject: [PATCH] fix: recompute leaderboard energy/FLOPs from tokens, cap dollar savings Energy and FLOPs are now derived from total_tokens on the leaderboard display using Claude Opus 4.6 constants, rather than trusting submitted DB values. This prevents gaming (e.g. TotallyNoire submitting 14B Wh from 15M tokens). Dollar savings are clamped at the theoretical max ($25/1M tokens) on both the leaderboard and frontend submission side. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/javascripts/leaderboard.js | 42 +++++++++++++++++++++------------ frontend/src/App.tsx | 5 +++- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/docs/javascripts/leaderboard.js b/docs/javascripts/leaderboard.js index 742b398a..093a3022 100644 --- a/docs/javascripts/leaderboard.js +++ b/docs/javascripts/leaderboard.js @@ -9,20 +9,27 @@ var allRows = []; var currentPage = 0; - // No-KV-cache formula: FLOPs = params_b * 1e9 * N * (N+1) - // Reference values only (GPT-5.3 constants) — recompute functions below - // are defined but not called; the leaderboard displays database values directly. - var DEFAULT_PARAMS_B = 137; - var ENERGY_WH_PER_FLOP = 0.4 / (1000 * 3e12); + // Claude Opus 4.6 constants — recompute energy and FLOPs from + // total_tokens so submitted values cannot be gamed. + var CLAUDE_PARAMS_B = 137; + var CLAUDE_FLOPS_PER_TOKEN = 4.0e12; + var CLAUDE_WH_PER_FLOP = 0.5 / (1000 * CLAUDE_FLOPS_PER_TOKEN); + // Max possible $/token: all tokens are output at $25/1M + var MAX_DOLLAR_PER_TOKEN = 25.0 / 1e6; - function recomputeFlopsNoKvCache(totalTokens) { + function recomputeFlops(totalTokens) { var n = Number(totalTokens) || 0; if (n <= 0) return 0; - return DEFAULT_PARAMS_B * 1e9 * n * (n + 1); + return 2.0 * CLAUDE_PARAMS_B * 1e9 * n; } - function recomputeEnergyNoKvCache(flops) { - return flops * ENERGY_WH_PER_FLOP; + function recomputeEnergy(totalTokens) { + return recomputeFlops(totalTokens) * CLAUDE_WH_PER_FLOP; + } + + function clampDollars(dollarSavings, totalTokens) { + var max = (Number(totalTokens) || 0) * MAX_DOLLAR_PER_TOKEN; + return Math.min(Number(dollarSavings) || 0, max); } function escapeHtml(s) { @@ -58,15 +65,19 @@ var medal = rank === 1 ? "\uD83E\uDD47" : rank === 2 ? "\uD83E\uDD48" : rank === 3 ? "\uD83E\uDD49" : ""; var row = pageRows[j]; + var tokens = Number(row.total_tokens || 0); + var dollars = clampDollars(row.dollar_savings, tokens); + var flops = recomputeFlops(tokens); + var energyWh = recomputeEnergy(tokens); html += "" + '' + (medal || rank) + "" + '' + escapeHtml(row.display_name) + "" + - '$' + Number(row.dollar_savings || 0).toFixed(4) + "" + - '' + Number(row.energy_wh_saved || 0).toFixed(2) + "" + - '' + fmtLarge(Number(row.flops_saved || 0)) + "" + + '$' + dollars.toFixed(4) + "" + + '' + energyWh.toFixed(2) + "" + + '' + fmtLarge(flops) + "" + '' + Number(row.total_calls || 0).toLocaleString() + "" + - '' + Number(row.total_tokens || 0).toLocaleString() + "" + + '' + tokens.toLocaleString() + "" + ""; } tbody.innerHTML = html; @@ -141,9 +152,10 @@ var totalRequests = 0; var totalTokens = 0; for (var i = 0; i < rows.length; i++) { - totalDollars += Number(rows[i].dollar_savings || 0); + var t = Number(rows[i].total_tokens || 0); + totalDollars += clampDollars(rows[i].dollar_savings, t); totalRequests += Number(rows[i].total_calls || 0); - totalTokens += Number(rows[i].total_tokens || 0); + totalTokens += t; } var elMembers = document.getElementById("stat-members"); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e627931f..c6ccf928 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -71,6 +71,9 @@ export default function App() { (p) => p.provider === 'claude-opus-4.6', ); const dollarSavings = claudeEntry ? claudeEntry.total_cost : 0; + // Cap at theoretical max ($25/1M output tokens) to prevent spoofed values + const maxDollars = (data.total_tokens * 25) / 1_000_000; + const clampedDollars = Math.min(dollarSavings, maxDollars); const energySaved = data.per_provider.reduce( (sum, p) => sum + (p.energy_wh || 0), 0, @@ -85,7 +88,7 @@ export default function App() { email: optInEmail, total_calls: data.total_calls, total_tokens: data.total_tokens, - dollar_savings: dollarSavings, + dollar_savings: clampedDollars, energy_wh_saved: energySaved, flops_saved: flopsSaved, token_counting_version: data.token_counting_version ?? 1,