From 679e92bca8592623f865e915327ae7a6dcfe66cc Mon Sep 17 00:00:00 2001
From: Rahil Bhavan
-
+ Unavailable: the event-log source did not respond and no last good series is stored. +
+ ) : ( +Circle, Tether, PayPal, BlackRock and Ondo, on Ethereum since January 2023. Where the money sits by chain, and what weekly issuance did around the Fed's rate cuts.
-
- Ethereum event logs. Circle CCTP transfers ({formatUsdCompact(s.cctpBridgedUsd)} of USDC mints and burns) are excluded: moving USDC between chains is not - issuance. USDC is {Math.round(s.usdcShareOfGross * 100)}% of the total and is mostly market-maker churn; its net is negative on Ethereum because holders + Ethereum event logs. The total is {formatTrillions(s.grossUsd)} because Circle CCTP transfers ({formatUsdCompact(s.cctpBridgedUsd)} of USDC mints and burns) are excluded: moving USDC between chains is not + issuance. Counting them gives {formatTrillions(s.grossWithCctpUsd)}. USDC is {Math.round(s.usdcShareOfGross * 100)}% of the total and is mostly market-maker churn; its net is negative on Ethereum because holders redeem there and mint natively elsewhere, while its circulating supply on all chains grew.
diff --git a/src/app/page.tsx b/src/app/page.tsx index 03edbbe..2e0f4a8 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,7 +3,7 @@ import { formatUsdCompact, formatNumberCompact, formatPercent } from '@/lib/form import { getWeeklyFlows } from '@/lib/weeklyFlows'; import { formatWeek, fourWeekStats, weeklySeries } from '@/lib/flowStats'; import { getChainTVL, toLiquidityCells } from '@/lib/chainSupply'; -import { combinedSource } from '@/lib/dataSource'; +import { cachedAsOf, combinedSource } from '@/lib/dataSource'; import { MetricCard } from '@/components/ui/MetricCard'; import { TopHoldersChart } from '@/components/dashboard/TopHoldersChart'; import { FlowCharts } from '@/components/flows/FlowCharts'; @@ -37,11 +37,11 @@ export default async function DashboardPage() { const stats = fourWeekStats(flows.rows); // formatPercent keeps one decimal of a percent: anything that rounds to 0.0% is flat. const trend = stats.volumeTrend === null ? null : Math.round(stats.volumeTrend * 1000) / 1000; - const prefix = flows.dataSource === 'mocked' ? '~' : ''; + const prefix = flows.dataSource === 'cached' ? '~' : ''; const totalTvlUsd = chainRows.reduce((sum, r) => sum + r.tvlUsd, 0); const tvlSource = combinedSource(chainRows); - // MetricCard adds '~' itself only when fully mocked; a mixed total needs it too. - const tvlPrefix = tvlSource === 'estimated' && chainRows.some((r) => r.dataSource === 'mocked') ? '~' : ''; + // MetricCard adds '~' itself only when fully cached; a mixed total needs it too. + const tvlPrefix = tvlSource === 'estimated' && chainRows.some((r) => r.dataSource === 'cached') ? '~' : ''; return (
- Five issuers, {formatUsdCompact(s.grossUsd)} of mints and redemptions on Ethereum. In the Fed's two easing episodes the two largest stablecoins
+ Five issuers, about $1T of mints and redemptions on Ethereum.{' '}
+ That is {formatTrillions(s.grossUsd)} after removing {formatUsdCompact(s.cctpBridgedUsd)} of Circle CCTP transfers, which only move USDC between chains; counting them gives {formatTrillions(s.grossWithCctpUsd)}. In the Fed's two easing episodes the two largest stablecoins
grew faster than their own norm in 2024 (USDC {sd(zDuring(r, 'USDC', 0))}, USDT {sd(zDuring(r, 'USDT', 0))}) while the Treasury-backed funds ran below theirs (BUIDL {sd(zDuring(r, 'BUIDL', 0))}, OUSG {sd(zDuring(r, 'OUSG', 0))}). 2025 only
half repeated it: BUIDL fell further ({sd(zDuring(r, 'BUIDL', 1))}, the weakest window in its history) and USDT stayed above average ({sd(zDuring(r, 'USDT', 1))}), but USDC fell back to average and OUSG recovered. With two episodes, this
is a pattern to watch, not evidence of cause.
diff --git a/src/components/dashboard/ChainBreakdown.tsx b/src/components/dashboard/ChainBreakdown.tsx
index a620728..7692a2d 100644
--- a/src/components/dashboard/ChainBreakdown.tsx
+++ b/src/components/dashboard/ChainBreakdown.tsx
@@ -1,7 +1,7 @@
'use client';
import type { Chain, ChainTVL } from '@/lib/types';
-import { combinedSource } from '@/lib/dataSource';
+import { cachedAsOf, combinedSource } from '@/lib/dataSource';
import { DataSourceBadge } from '@/components/ui/DataSourceBadge';
import { formatUsdCompact, formatPercent } from '@/lib/format';
@@ -26,16 +26,16 @@ const CHAIN_COLORS: Record
Chain breakdown
-
- Ethereum only. Names come from a manual address registry, then Blockscout public tags; unlabeled wallets show their address. + Ethereum (OUSG and USDY) and Stellar (USDY). Names come from a manual address registry, then Blockscout public tags; unlabeled wallets show their address.
+ Unavailable: the holder sources did not respond and no last good value is stored. +
+ )} + {GROUPS.map(({ chain, token, label }) => { + const rows = data.filter((d) => d.token === token && d.chain === chain).sort((a, b) => b.balance - a.balance); if (!rows.length) return null; const total = rows.reduce((sum, d) => sum + d.tvlUsd, 0); return ( -| - {token} ({formatUsdCompact(total)} in top {rows.length}) + {label} ({formatUsdCompact(total)} in top {rows.length}) | Balance | Value | @@ -43,12 +57,12 @@ export function TopHoldersChart({ data }: TopHoldersChartProps) {
|---|---|---|
| @@ -62,7 +76,7 @@ export function TopHoldersChart({ data }: TopHoldersChartProps) { {prefix}{formatUsdCompact(row.tvlUsd)} |
- |