# Stablecoin Freeze Tracker — USDT & USDC Blacklist (`amlconsensus/stablecoin-freeze-tracker`) Actor

Every address ever frozen by Tether or Circle across Ethereum, Tron, Polygon and Arbitrum — with freeze dates, current status and destroyed amounts. ~13,000 addresses, rebuilt from contract events.

- **URL**: https://apify.com/amlconsensus/stablecoin-freeze-tracker.md
- **Developed by:** [Rinat Galimov](https://apify.com/amlconsensus) (community)
- **Categories:** Developer tools, News, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Stablecoin Freeze Tracker — USDT & USDC blacklist

Every address ever frozen by **Tether** or **Circle** on Ethereum, with freeze
dates, current status, and how much was destroyed.

USDT and USDC are centralised tokens. The issuer can blacklist an address, after
which its balance can never move again — and Tether can go further and destroy
the balance outright. These actions happen on-chain, so the record is public.
It is just not published anywhere you can actually use.

This Actor reconstructs the full list from contract events and hands it to you
as a clean dataset.

### What you get

### Chains covered

| Chain | Token | Why |
|---|---|---|
| **Ethereum** | USDT + USDC | both issuers blacklist heavily here |
| **Tron** | USDT | the largest USDT deployment in the world |
| **Polygon** | USDC | Circle only |
| **Arbitrum** | USDC | Circle only |

Coverage is decided by where blacklists actually exist and get used, not by
where the tokens are listed. Bitcoin, Litecoin, Dogecoin and XRP have no
programmable issuer blacklist at all. And a finding worth knowing: **USDT on
Polygon and Arbitrum has never been blacklisted once** — Tether enforces on
Ethereum and Tron, and leaves its other EVM deployments alone.

### What you get

| Field | Meaning |
|---|---|
| `address` | The blacklisted address |
| `chain` | Ethereum, Tron, Polygon or Arbitrum One |
| `issuer` | `USDT` (Tether) or `USDC` (Circle) |
| `status` | `frozen` — still blacklisted · `unfrozen` — later released |
| `frozen_at` | UTC timestamp of the blacklist transaction |
| `frozen_block` | Ethereum block number |
| `unfrozen_at` | When it was released, if it ever was |
| `funds_destroyed` | Whether Tether burned the balance |
| `destroyed_amount` | How much was destroyed, in tokens |
| `tx_hash` | The on-chain transaction, so you can verify every row |
| `explorer_url` | Direct link to that transaction in the chain's explorer |

Current scale: **~13,000 addresses** across four chains — Tron 8,100, Ethereum
3,900, Arbitrum 520, Polygon 520 — of which **~11,300 are still frozen**. Tether
has destroyed **over $1.35 billion** outright across ~2,300 of them. Addresses
that were blacklisted and later released are kept too, marked `unfrozen`.

### Use it three ways

**1. Export the whole blacklist.** Leave the input empty and get every frozen
address. Good for seeding your own screening database.

**2. Check your own addresses.** Put addresses into `checkAddresses` and each
one comes back with its status — including `not_blacklisted` when it is clean.
Useful before accepting a payment or onboarding a counterparty.

**3. Watch for new freezes.** Set `sinceDate` and schedule the Actor daily. You
get only what was frozen after that date — an early warning that a counterparty,
a pool, or a bridge has been touched.

### Input

```json
{
  "chains": ["ethereum", "tron", "polygon", "arbitrum"],
  "issuers": ["USDT", "USDC"],
  "statusFilter": "frozen",
  "checkAddresses": [],
  "sinceDate": "",
  "maxItems": 0
}
```

All fields are optional. `statusFilter` accepts `frozen`, `unfrozen` or `all`.

### Why this data is worth having

A frozen address is a dead end: funds sitting on it are unrecoverable. If a
counterparty pays you from an address that later gets blacklisted, or you route
through a service that does, the exposure is yours. Exchanges and payment
processors screen against these lists — most people trading against them cannot.

Freezes also cluster. A newly frozen address often shares counterparties with
addresses frozen days earlier, which makes the time-ordered list more useful
than a plain snapshot.

### How it works

Read straight from contract events, with no third-party risk database in
between:

| Issuer | Event | Meaning |
|---|---|---|
| USDT | `AddedBlackList(address)` | blacklisted |
| USDT | `RemovedBlackList(address)` | released |
| USDT | `DestroyedBlackFunds(address,uint256)` | balance destroyed |
| USDC | `Blacklisted(address)` | blacklisted |
| USDC | `UnBlacklisted(address)` | released |

Every row carries its `tx_hash` and an explorer link, so nothing here has to be
taken on trust.

One filter worth naming: issuers also blacklist **their own token contract** to
destroy tokens users mistakenly sent to it. Those are real events but not frozen
wallets, so they are excluded — otherwise the destroyed totals would be inflated
by tens of millions.

### Notes and limits

- **Four chains, not all of them.** BSC, Base, Optimism and Avalanche do run
  blacklists, but their historical logs are not available on a free indexer tier
  — they are planned, not silently dropped.
- **A blacklist is not a verdict.** Issuers freeze on law-enforcement requests,
  court orders, and their own investigations. Treat a hit as a strong signal to
  investigate, not as proof of wrongdoing.
- An address can be frozen, released, and frozen again. The dataset keeps the
  first freeze and reflects the latest status.
- Needs an Etherscan API key for the EVM chains. A free one from
  [etherscan.io/apis](https://etherscan.io/apis) is enough; supply it in the
  input if you run this often and want your own rate limit.
- Tron reads from TronGrid, which allows about one request per second without a
  key — so Tron takes a few minutes. A free key from
  [trongrid.io](https://www.trongrid.io) removes that.

### Who builds this

Made by [AMLConsensus](https://amlconsensus.com) — wallet screening that checks
an address against several independent sources at once (OFAC SDN, issuer freeze
lists, sanctions oracles, open blacklists) and shows which source flagged what,
instead of returning one vendor's number.

Questions, bulk volume, or a dataset you need that isn't here:
**support@amlconsensus.com**

# Actor input Schema

## `chains` (type: `array`):

Blacklists only exist where the issuer runs a contract that has one — and only Ethereum and Tron see heavy use. USDT on Polygon and Arbitrum has never been blacklisted once.

## `issuers` (type: `array`):

Which stablecoin issuers to include. USDT is Tether, USDC is Circle — both on Ethereum mainnet.

## `statusFilter` (type: `string`):

Frozen — currently blacklisted. Unfrozen — was blacklisted but later released. All — full history.

## `checkAddresses` (type: `array`):

Optional. Paste addresses to check against the blacklist instead of exporting the whole dataset. Each one is returned with its freeze status.

## `sinceDate` (type: `string`):

Optional. Only include addresses frozen on or after this date (YYYY-MM-DD). Useful for scheduled runs that track new freezes.

## `maxItems` (type: `integer`):

Cap the number of records. 0 means no limit.

## `etherscanApiKey` (type: `string`):

Leave empty to use the built-in key. Supply your own free Etherscan key if you run this often and want your own rate limit.

## `tronGridApiKey` (type: `string`):

Only affects the Tron chain. Without a key TronGrid allows roughly one request per second, so Tron takes a few minutes. A free key from trongrid.io removes that.

## Actor input object example

```json
{
  "chains": [
    "ethereum",
    "tron",
    "polygon",
    "arbitrum"
  ],
  "issuers": [
    "USDT",
    "USDC"
  ],
  "statusFilter": "frozen",
  "checkAddresses": [],
  "maxItems": 0
}
```

# Actor output Schema

## `frozenAddresses` (type: `string`):

Every matching address with issuer, freeze date, current status and destroyed amount.

## `frozenAddressesCsv` (type: `string`):

The same dataset as CSV, ready for a spreadsheet or a screening database import.

## `datasetInConsole` (type: `string`):

Browse and filter the results in the Apify Console.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "chains": [
        "ethereum",
        "tron",
        "polygon",
        "arbitrum"
    ],
    "issuers": [
        "USDT",
        "USDC"
    ],
    "checkAddresses": [],
    "sinceDate": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("amlconsensus/stablecoin-freeze-tracker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "chains": [
        "ethereum",
        "tron",
        "polygon",
        "arbitrum",
    ],
    "issuers": [
        "USDT",
        "USDC",
    ],
    "checkAddresses": [],
    "sinceDate": "",
}

# Run the Actor and wait for it to finish
run = client.actor("amlconsensus/stablecoin-freeze-tracker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "chains": [
    "ethereum",
    "tron",
    "polygon",
    "arbitrum"
  ],
  "issuers": [
    "USDT",
    "USDC"
  ],
  "checkAddresses": [],
  "sinceDate": ""
}' |
apify call amlconsensus/stablecoin-freeze-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,amlconsensus/stablecoin-freeze-tracker"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/X8fiSgb3xkTrsg1JE/builds/5keLT5R7kmMC0Moyv/openapi.json
