← GUIDES
GUIDE · REFERENCE

Official USDT and USDC contract addresses by chain

Published 2026-09-09 · Updated

The canonical Tether and Circle contracts KYTGate reads, why only those count, and how a look-alike token gets past a symbol-based check.

Anyone can deploy a token and name it USDT. Explorers show the symbol, wallets show the balance, and a deposit flow that keys off the symbol will credit it. The only defence is to check the contract address that emitted the transfer against the issuer's official one. This page lists the official USDT and USDC contracts KYTGate uses, generated from the same list its issuer-freeze check reads. It also shows how to verify that a deposit is the real token, which KYTGate calls "transaction integrity".

Start free sandboxTalk to us50 screenings a month free, no card.

On this page

The canonical contracts

Nine contracts across seven chains: USDT (Tether) on Ethereum, Tron and Avalanche; USDC (Circle) on Ethereum, Base, Arbitrum, Polygon, Avalanche and OP Mainnet.

ChainTokenIssuerContract addressBlacklist readExplorer
EthereumUSDTTether0xdAC17F958D2ee523a2206206994597C13D831ec7isBlackListed(address)Etherscan ↗
Tron (TRC-20)USDTTetherTR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6tisBlackListed(address)Tronscan ↗
Avalanche C-ChainUSDTTether0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7isBlocked(address)Snowtrace ↗
EthereumUSDCCircle0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48isBlacklisted(address)Etherscan ↗
BaseUSDCCircle0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913isBlacklisted(address)Basescan ↗
Arbitrum OneUSDCCircle0xaf88d065e77c8cC2239327C5EDb3A432268e5831isBlacklisted(address)Arbiscan ↗
Polygon PoSUSDCCircle0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359isBlacklisted(address)Polygonscan ↗
Avalanche C-ChainUSDCCircle0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6EisBlacklisted(address)Snowtrace ↗
OP MainnetUSDCCircle0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85isBlacklisted(address)OP Etherscan ↗
solanaUSDCCircleEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1vtoken account state (mint freeze authority)—
solanaUSDTTetherEs9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYBtoken account state (mint freeze authority)—

These addresses come from the issuers' official publications and are configured in the product, never taken from user input. A change to this list is a code change, reviewed like any other. If an address here ever differs from the issuer's own page, the issuer's page takes precedence. Please tell us.

How to verify a deposit is the real token

Read the transaction receipt and require a Transfer log emitted by the canonical contract, to your address, for the expected amount.

A stablecoin transfer is a contract call, not a native coin movement. It emits a Transfer(from, to, value) event log, and the log's emitting address is the token contract. A deposit is the real token only if that emitting address equals the canonical contract for that chain. A matching symbol, name or explorer logo does not count.

KYTGate's transaction integrity check does this for kind: "transfer" subjects. It fetches the receipt and confirms the transaction exists and succeeded. Until the confirmation depth is reached it answers "too early" (HTTP 425) and stores nothing. It then looks for a Transfer log emitted by the canonical contract and screens that log's from address rather than the transaction signer. If you pass your deposit address as toAddress, that is the sender who paid it. Otherwise it is the only sender, when there is exactly one. The check does not compare the amount with what a webhook claimed. That is the job of reconciliation (POST /api/v1/reconcile). A missing or reverted transaction is a finding that sends the decision to review. If the check could not run, or the sender cannot be singled out, the decision is TECHNICAL_HOLD. Neither outcome is ever a credit.

Receipt log that passes integrity (Ethereum USDT)
  address: 0xdAC17F958D2ee523a2206206994597C13D831ec7   ← must equal the canonical contract
  topics[0]: Transfer(address,address,uint256)
  topics[1]: from  → the address that gets screened
  topics[2]: to    → must be your deposit address
  data:      value → compare with the claimed amount in reconciliation (6 decimals)

To verify by hand, open the transaction on the explorer, go to the logs tab and compare the log's address field character by character with the table above. Ignore the token name column.

Common fake-token tricks

Same symbol, near-identical address, a real transfer of a worthless token, or a zero-value transfer from a look-alike sender.

  • Same symbol, different contract. The simplest version is a token named "USDT" or "Tether USD" with 6 decimals, sent to your deposit address. Every field except the contract address looks right.
  • Address poisoning. The attacker sends dust from an address whose first and last characters match a legitimate counterparty, hoping a reviewer or an ops script copies it from history. Screening the log's full from address, rather than a shortened form, defeats it.
  • Real contract, wrong chain. Ethereum USDT's address means nothing on another chain. A token deployed at the "same" address elsewhere is unrelated. Verification is per chain.
  • Edited webhook. The transfer is real and canonical, but the amount or recipient in the notification was changed in transit, or the same hash is submitted twice. Reconciliation compares the chain to the claim, and the idempotency key stops the second credit.
  • Transaction signer as sender. The transaction was sent by a contract or a relayer, and the token came from another address inside it. Screening the signer screens the wrong party. The token log's from is what KYTGate screens.

Chains not covered

BNB Chain's Binance-Peg USDT/USDC have no issuer blacklist function; Solana has no comparable read in the current connector.

BNB Chain (BSC) is left out on purpose. The "USDT" and "USDC" there are Binance-Peg tokens issued by Binance, not by Tether or Circle, and their contracts expose no blacklist function. Reporting a freeze read that cannot exist would give a false sense of coverage. On BSC the issuerFreeze dimension therefore reports UNSUPPORTED and no read is made. The same applies to bridged variants on any chain.

Solana is screened for sanctions but has no issuer-freeze read in the current connector, and the coverage matrix states this on each screening. Bitcoin has no stablecoins to read. On every chain the product reports what it checked, dimension by dimension. A NO_ADVERSE_SIGNAL on a dimension that did not run is not a result.

Questions

What is the official USDT contract address on Ethereum?

0xdAC17F958D2ee523a2206206994597C13D831ec7, issued by Tether. On Tron the TRC-20 USDT contract is TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t. Only these emit real USDT transfers on those chains. Compare the emitting address of the Transfer log, not the token symbol.

How can I tell if a USDT deposit is fake?

Open the transaction on the explorer, look at the Transfer event log, and compare the log's emitting contract address with the official one for that chain, character by character. A matching symbol, name or logo proves nothing. KYTGate does this check automatically for transfer subjects and fails transaction integrity when the contract is not canonical.

Why does KYTGate not read a freeze on BNB Chain?

Because BSC USDT and USDC are Binance-Peg tokens whose contracts have no issuer blacklist function. There is nothing to read, so the issuerFreeze coverage dimension is reported as UNSUPPORTED on BSC instead of a made-up answer.

Which address gets sanctions-screened on a stablecoin deposit?

The from address in the canonical Transfer log (the token-level sender), not the transaction signer, which can be a contract or a relayer. Screening the signer would screen the wrong party.

Read more

Start free sandbox Talk to us