Official and verified Tether (USDT) and Circle (USDC) smart contract addresses on TRON, Ethereum, BSC, Polygon, Arbitrum, Base, Optimism, Avalanche, Solana, TON, and Stellar. Avoid scams and link each token to its block explorer.
This document is the canonical reference for any developer, merchant, or auditor who needs to verify the real smart contract address of USDT or USDC on the blockchains that TronDealer supports. We consolidate in one place the contracts officially issued by Tether and Circle, with a direct link to each network's block explorer and a note on decimals, so you never fall for a clone token or a scam.
Attackers publish tokens with the same ticker (USDT, USDC) but a different address, hoping someone will send real funds or accept payments in a token with no backing. The only way to prevent that is to confirm the contract address before signing a transaction, wiring up a webhook, or showing a QR code to a customer.
A crypto payment gateway is only as secure as its token allowlist. If you accept transfers to an address without validating it matches the official contract, you're opening the door to:
The canonical list below is exactly what our gateway uses internally to scan deposits. Use it as the allowlist in your own system.
Official issuer: Tether Holdings Limited. On-chain symbol: USDT. 1:1 backing with reserves reported quarterly.
| Network | Contract address | Decimals | Explorer |
|---|---|---|---|
| Ethereum | 0xdAC17F958D2ee523a2206206994597C13D831ec7 | 6 | etherscan.io |
| BSC (Binance Smart Chain) | 0x55d398326f99059fF775485246999027B3197955 | 18 | bscscan.com |
| Polygon | 0xc2132D05D31c914a87C6611C10748AEb04B58e8F | 6 | polygonscan.com |
| Arbitrum One | |
USDT uses 6 decimals on every network except BSC, where it uses 18. If your integration hardcodes 6 decimals, balances on BSC will be off by a factor of 10¹². TronDealer's config (CHAINS.bsc.tokens.USDT.decimals = 18) handles this automatically.
| Network | Contract address | Decimals | Explorer |
|---|---|---|---|
| TRON | TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t | 6 | tronscan.org |
USDT on TRON (TRC20) moves the highest daily volume of any Tether deployment. It's the go-to for Hispanic and LatAm markets thanks to its very low fees, which is why TronDealer integrates energy renting to make transfers even cheaper.
| Network | Mint address | Decimals | Explorer |
|---|---|---|---|
| Solana | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB | 6 | solscan.io |
| Network | Jetton Master | Decimals | Explorer |
|---|---|---|---|
| TON | EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs | 6 | tonscan.org |
On TON, USDT is implemented as a Jetton: there's a master contract (the issuer) and each holder has their own jetton wallet derived from it. TronDealer resolves the jetton wallet from the owner address using @ton/ton.
Official issuer: Circle Internet Financial. On-chain symbol: USDC. Fully backed and audited monthly.
| Network | Contract address | Decimals | Explorer |
|---|---|---|---|
| Ethereum | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | 6 | etherscan.io |
| BSC | 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d | 18 | bscscan.com |
| Polygon (Native) | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 | 6 | polygonscan.com |
| Arbitrum (Native) | |
Polygon, Arbitrum, and Optimism each have two versions of USDC. The table above lists the Native USDC issued directly by Circle — the one you should use for new integrations and the one supported by CCTP (Cross-Chain Transfer Protocol). The bridged USDC.e (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 on Polygon, for example) is legacy and being phased out. TronDealer only scans Native USDC on these networks.
| Network | Contract address | Decimals | Explorer |
|---|---|---|---|
| TRON | TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8 | 6 | tronscan.org |
| Network | Mint address | Decimals | Explorer |
|---|---|---|---|
| Solana | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | 6 | solscan.io |
| Network | Asset code | Issuer | Explorer |
|---|---|---|---|
| Stellar | USDC | GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN | stellar.expert |
On Stellar, an asset is identified by the (code, issuer) pair. Any Stellar address can issue an asset with code "USDC" — that's why the issuer is the real identifier. Only the one issued by GA5ZSEJY... is backed by Circle.
Beyond USDT and USDC, TronDealer supports regional and EUR-denominated stablecoins on specific networks.
| Network | Contract address | Decimals | Explorer |
|---|---|---|---|
| Base | 0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42 | 6 | basescan.org |
| Network | Contract address | Decimals | Explorer |
|---|---|---|---|
| Rootstock (RSK) | 0xe700691dA7b9851F2F35f8b8182c69c53CcaD9Db | 18 | explorer.rootstock.io |
DoC (Dollar on Chain) is a 1:1 USD-collateralized stablecoin backed by rBTC, the native currency of Rootstock (the EVM network secured by Bitcoin miners).
The canonical way to check that an address is a live ERC-20 is to call its view methods (symbol, decimals, totalSupply) and compare them to the expected values.
If symbol returns anything other than USDT or USDC, or the call fails because there's no ABI at that address, that's a clear signal the address is not the official contract.
If you're building your own deposit scanner or wallet, we recommend hardcoding the allowlist instead of relying on dynamic config. It's one less attack surface:
export const STABLECOINS = {
bsc: {
USDT: { address: '0x55d398326f99059fF775485246999027B3197955', decimals: 18 },
USDC: { address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', decimals: 18 },
},
eth: {
USDT: { address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', decimals: 6 },
USDC: { address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', decimals: 6 },
},
pol: {
USDT: { address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', decimals: 6 },
USDC: { address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', decimals: 6 },
},
arb: {
USDT: { address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', decimals: 6 },
USDC: { address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', decimals:
This structure is exactly what TronDealer uses internally (CHAINS in app/utils/v2-config.js) to filter Transfer logs in its deposit scanner.
If your goal is to accept payments in any of these stablecoins without writing your own on-chain scanner, configuring RPCs, or managing gas, the fastest path is to use the TronDealer API directly. The full flow — registration, wallet assignment, HMAC webhooks, and automatic sweep — is covered in the 6-step integration guide.
If you just need to validate contracts in your dApp or wallet, this page is your source of truth. Bookmark it, keep the allowlist up to date, and never accept an address that isn't listed here without cross-checking against Tether Transparency or Circle.
| 6 |
| arbiscan.io |
| Base | 0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2 | 6 | basescan.org |
| Optimism | 0x94b008aA00579c1307B0EF2c499aD98a8ce58e58 | 6 | optimistic.etherscan.io |
| Avalanche C-Chain | 0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7 | 6 | snowtrace.io |
| 6 |
| arbiscan.io |
| Base | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | 6 | basescan.org |
| Optimism (Native) | 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85 | 6 | optimistic.etherscan.io |
| Avalanche C-Chain | 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E | 6 | snowtrace.io |
import { ethers } from 'ethers'
const ERC20_ABI = [
'function symbol() view returns (string)',
'function decimals() view returns (uint8)',
'function totalSupply() view returns (uint256)',
'function balanceOf(address) view returns (uint256)',
]
const provider = new ethers.JsonRpcProvider(process.env.ETH_RPC_URL)
const usdt = new ethers.Contract(
'0xdAC17F958D2ee523a2206206994597C13D831ec7',
ERC20_ABI,
provider
)
const [symbol, decimals, supply] = await Promise.all([
usdt.symbol(),
usdt.decimals(),
usdt.totalSupply(),
])
console.log({ symbol, decimals, supply })
// { symbol: 'USDT', decimals: 6n, supply: ...n }