Investigations

Four unusual things in the data, each checked against the pipeline first, then explained.

Every case follows the order an analyst should follow before explaining a metric move:

  1. Is it the data? Duplicates, missing blocks, rows written late or rewritten, formats that break joins.
  2. If not, what changed in behaviour? Who was involved, how many, new or regular, and whether one program is behind it.
  3. A verdict with its evidence, and what remains uncertain.

The checks run on the raw rows of only the days involved (scripts/investigate.py), and every result table is published in investigations/ on Hugging Face. Every number on this page is read from those tables when the site is built.

1. USDC and USDT failures jump to 19%

Real behaviour, not the pipeline: a wave of new automated senders

The alert. On 27 Nov 2025, 19.5% of direct USDC calls failed against a usual 0.36%, and 17.7% of USDT calls against 0.68%. On a payments team this is the approval-rate drop that gets escalated.

Check Result What it tells us
Duplicate rows on spike days 0 Not a double load
Missing or duplicate blocks on spike days 0 Nothing lost
Spike days the source rewrote later 27 Nov 2025, 28 Nov 2025, 29 Nov 2025, 3 Dec 2025, 4 Dec 2025, 5 Dec 2025 Failed and successful rows were rewritten alike (gap 3.3 points), so the rewrite did not create the failures
Calls from new senders (not seen on the ordinary days around the spike) 48% of all calls on spike days A new population of senders
USDT calls that used exactly the same gas 55,271 calls from 54,740 addresses on 27 Nov 2025, all 50,000 gas; 71% of all failed USDT calls on spike days One program with a fixed gas limit
USDT failure rate without those calls 17.71% → 0.71% They explain the USDT jump

Who failed. Split the senders in two. Regular senders also appear on the ordinary days around the spike; new senders appear only on spike days. About 48% of all direct calls on spike days came from new senders, and they failed far more often. Regular senders were hit on the worst day too (12.4% for USDC), but were back to 0.28% the next day.

Failure rate of direct calls by day: regular senders and new senders

One program. On 27 Nov 2025, 54,740 different addresses sent 55,271 USDT calls, about one each, and every one of them used exactly 50,000 gas. A failed call that runs out of gas uses all the gas it was given, so a round number repeated tens of thousands of times points to one program sending every call with the same fixed limit. 88% of the failing USDT senders that day made a single call, and only 12% also had a successful call that day. Remove those 50,000-gas calls and USDT’s failure rate that day is 0.71%, close to its usual level. USDC had no single fingerprint: its extra failures were ordinary reverts, in bulk, from new addresses.

Why then. Blocks got cheaper. Ethereum’s block gas limit went from 45 to 60 million on 25 November 2025 (The Block), and the Fusaka upgrade followed on 3 December. The average base fee on the worst day was 0.055 gwei against 0.37 in the days before, and transfers under 10 tokens rose from 24% to 39% of all transfers. Cheap blocks make mass automated sending cheap: Etherscan data reported by CryptoPotato shows USDT transfers under $0.01 rising about sevenfold in the 90 days after Fusaka, mostly address-poisoning campaigns. The data here shows the wave and its fingerprint; who ran it, and why, is not in the data.

What a payments analyst should take from it. This has the shape of a card-testing attack: thousands of new “customers” each make one failing attempt and drag the approval rate down, while returning customers are fine. Split new from returning senders before explaining the drop.

2. PYUSD failing up to 61% of the time

Bots, not users

The alert. Between 16 Aug 2024 and 16 Sep 2024, PYUSD had 23 days with its failure rate over three times normal, peaking at 61.3% on 1 Sep 2024 against a usual 0.09%.

Check Result What it tells us
Failure rate of regular senders on spike days 0.16% at most Real PYUSD users were not affected
Share of all failed calls on spike days that came from new senders 99.9% The failures came from newcomers
Failed calls that used exactly the same gas 99.8% of spike-day failures, all 64,474 gas The same failing call, repeated
Failure rate without those calls 0.15% at most Nothing else was failing
Addresses that failed on 90% or more of 5+ calls, on the peak day 64 A small fleet, not a crowd

PYUSD: failure rate of direct calls by day, regular senders and new senders

Verdict. A small group of new addresses kept sending the same call to PYUSD, and it kept failing. Regular users saw no change. PYUSD is a small token, so 64 addresses failing on almost every call were enough to push its headline failure rate to 61% on the worst day. A failure-rate KPI that does not separate repeat failing senders reports the bots, not the product.

3. 600 trillion PYUSD in one day

A real event, not a data bug

The alert. On 15 Oct 2025, PYUSD’s value moved was 600T tokens, about 5.99M times its median day. Every dashboard check would call this a units bug.

The evidence, from the data itself. At 19:12 UTC, 300T PYUSD were minted (sent from the zero address) to 0x2fb074…2d41a4, in transaction 0xc45dd1…f45634.

The same amount was burned back 22 minutes later (0xaa532a…c34f4b). Over the day 300T were minted and 300T burned, so the error cancelled out, and transfers between holders came to 858M tokens, against a median PYUSD day of 100M. Paxos, the issuer, confirmed a technical error (The Block).

A detail the news did not mention. 300T is exactly a million times 300M, and PYUSD has 6 decimal places. At 21:15 UTC the same address received a mint of exactly 300M PYUSD (0x5b4097…151abd). Earlier that day, at 15:04 UTC, exactly 300M PYUSD had been burned (0xe9faf1…e80db2). The data cannot prove intent, but the amounts are consistent with a mint of the right number entered in the wrong units: the decimals bug from the twin table, except that this time it really happened on-chain.

Mints and burns of 100 million PYUSD or more that day

Time (UTC) Event PYUSD Address Transaction
15:04 burn 300M 0x2fb074…2d41a4 0xe9faf1…e80db2
16:58 burn 230M 0xf845a0…2aabb7 0x29d371…220d30
19:12 mint 300T 0x2fb074…2d41a4 0xc45dd1…f45634
19:34 burn 300T 0x2fb074…2d41a4 0xaa532a…c34f4b
21:15 mint 300M 0x2fb074…2d41a4 0x5b4097…151abd

A catch on the way. The first version of this check found no mints at all. The transfer table stores addresses as 32-byte words (0x followed by 24 zeros and the address), while transactions store plain 20-byte addresses, so a comparison with the usual zero address silently matched nothing. The fix compares the last 40 characters. A join that returns nothing, without an error, is exactly the kind of fault this benchmark is built to plant.

4. Days the source rewrote after publishing

Pipeline: the upstream source changed past data

The alert. 61 of 1,004 days (6.1%) have rows written much later than the usual daily load.

Check Result What it tells us
Days with no row written within two days of the day itself 44 days; median 6.7 days later, worst 397 days Whole days delivered or replaced late
Days loaded on time, then patched 17 days; median 42 hours later, worst 48 days Part of the day rewritten afterwards
Same days in transfers, transactions and blocks yes The source reprocesses whole days, all tables together
Example of a patch 23 Oct 2024: 5,966 of 7,163 blocks (83%) rewritten Most of the day changed, not a few late rows

Token-transfer days: how long after the day its last rows were written (log scale)

What we cannot know. The source keeps only the latest version of each day, so what changed on these days is gone. For the whole-day cases we cannot even tell whether the day was missing until then or fully replaced. Any number for these days may differ from what a dashboard showed when the day was first loaded.

What it means. Load history matters. A warehouse that keeps a snapshot of each load could show exactly what changed and when; one that only keeps the latest data cannot. Until then, the data health page flags these days so that nobody explains a move on one of them without checking first.