The news

On November 6, 2026, FinCEN issued an order that bars US financial institutions from processing funds transfers involving the exchange MEXC Global. Treasury alleges the exchange facilitated at least $16 billion in transactions linked to sanctions evasion and cybercrime. The order takes effect 30 days after it is published in the Federal Register. (FinCEN release, Cointelegraph)

Cointelegraph's article cited DefiLlama for MEXC's total assets that day: about $4.48 billion. I wanted to see that number move, so I wrote a script that reads the same data.

Where the data comes from

DefiLlama tracks exchange wallets that the exchanges themselves have disclosed. The public endpoint https://api.llama.fi/protocol/<slug> returns a chainTvls object with one time series per chain. Two kinds of keys matter:

  • plain chain names (Bitcoin, Ethereum, Solana…) hold third-party assets in the disclosed wallets
  • keys containing OwnTokens hold the exchange's own token, which says little about customer reserves, so the script drops them

The series can hold more than one point for the current day (midnight plus the latest reading), so the script keeps the last value per chain per day before adding chains together. My first version summed every point and showed today's reserves at nearly double, which is a good bug to know about if you use this API.

The script

// reserve-watch.mjs // usage: node reserve-watch.mjs <defillama-slug> [days=10] const [slug = 'mexc', daysArg = '10'] = process.argv.slice(2); const days = Number(daysArg); const res = await fetch(`https://api.llama.fi/protocol/${slug}`); if (!res.ok) throw new Error(`DefiLlama answered ${res.status} for "${slug}"`); const p = await res.json(); const byDay = new Map(); for (const [chain, data] of Object.entries(p.chainTvls)) { if (chain.includes('OwnTokens')) continue; const last = new Map(); for (const { date, totalLiquidityUSD } of data.tvl) last.set(new Date(date * 1000).toISOString().slice(0, 10), totalLiquidityUSD); for (const [day, v] of last) byDay.set(day, (byDay.get(day) || 0) + v); } const rows = [...byDay.entries()].sort(([a], [b]) => a.localeCompare(b)).slice(-days); const base = rows[0][1]; const usd = (n) => `$${(n / 1e9).toFixed(2)}B`; console.log(`${p.name}: tracked reserves without its own token, last ${rows.length} days`); for (const [day, total] of rows) { const pct = ((total / base - 1) * 100).toFixed(1); console.log(`${day} ${usd(total).padStart(8)} ${pct >= 0 ? '+' : ''}${pct}%`); } 

It needs Node 18 or newer for the built-in fetch and top-level await in an .mjs file. No dependencies.

Output

Run on November 10, 2026:

MEXC: tracked reserves without its own token, last 10 days 2026-11-01 $4.48B +0.0% 2026-11-02 $4.53B +1.1% 2026-11-03 $4.50B +0.6% 2026-11-04 $4.52B +0.9% 2026-11-05 $4.58B +2.3% 2026-11-06 $4.48B +0.1% 2026-11-07 $4.43B -1.0% 2026-11-08 $4.24B -5.3% 2026-11-09 $4.17B -6.8% 2026-11-10 $4.17B -6.8% 

The November 6 row matches the $4.48B Cointelegraph quoted, which is a decent check that the filtering is right.

Reading it honestly

These are USD values, so they move with prices as well as with deposits and withdrawals. Crypto prices fell during the same days, which means the drop from $4.48B to $4.17B can't be read as a withdrawal total. To separate the two you'd use the tokens field, which holds amounts per token, and price them yourself at a fixed date. That's the natural next step if you extend this.

The data also covers only the wallets an exchange chose to disclose. It gives a floor on what the exchange holds, and it doesn't replace an audit.

Try it on others

Any CEX slug on DefiLlama works: node reserve-watch.mjs binance-cex 14, node reserve-watch.mjs okx 30. Slugs are in the URL of each exchange's page on defillama.com.

What other public signals do you watch when an exchange is in the news?