Polygon
polygon| Address format | EIP-55 checksummed hex, 0x… |
| Account path | m/44'/60'/0' — shared with Ethereum |
| Cloud stores | Ethereum's xpub. No separate key |
| Derivation | Yes M/0/{i} — public, no Edge required |
| Confirmations | 128 |
| Tokens | ERC-20. Native USDC only — the bridged USDC.e is not monitored |
| Explorer | https://polygonscan.com/tx/{txid} · https://polygonscan.com/address/{address} |
The address is Ethereum's
Coin type 60', so an address issued for eth receives on Polygon. No separate key, no separate
address. See Ethereum.
Why 128 confirmations
This is the number people query, so: Polygon PoS is a sidechain, not a rollup. Its security does not derive from Ethereum's consensus the way an L2's does — it has its own validator set and its own checkpointing, and a deep reorg is a different kind of event on it than on Ethereum.
Depth is the only lever available. 128 blocks at roughly two seconds each is about four minutes, which is fast in wall-clock terms for that much margin, and it is the figure that matches the checkpoint cadence closely enough to be safe.
deposit_detected fires at 1 confirmation, so you can show a pending balance within seconds.
deposit_confirmed fires at 128. Credit on the second. Four minutes of pending state is a product
problem to communicate, not a threshold to lower.
Thresholds are not configurable. See Deposits.
Fees — EIP-1559
fee = gasUnits × (baseFee × 2 + priorityFee)
Same model as Ethereum, with baseFeeGwei, priorityFeeGwei, maxFeeGwei and gasUnits. The fee
is paid in POL by the sending address, so INSUFFICIENT_GAS applies exactly as it does on
Ethereum — an ERC-20 deposit address holds tokens and no POL.
Polygon's priority fees have a practical floor of around 30 gwei that the network enforces socially rather than in consensus; the build accounts for it. Absolute costs are low.
One USDC, and a bridged one you should know about
A deposit to the bridged contract is not detected and not credited. It is still recoverable from your mnemonic — the funds are at an address you control — but ChainOS will not see it.
| Token | Contract | Decimals | Monitored |
|---|---|---|---|
USDT (reports USDT0) | 0xc2132D05D31c914a87C6611C10748AEb04B58e8F | 6 | yes |
| USDC (native) | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 | 6 | yes |
| USDC.e (bridged) | 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 | 6 | no |
| cNGN | 0x52828daa48C1a9A06F37500882b42daf0bE04C3B | 6 | yes |
USDC.e is the older bridged form, superseded by Circle's native issuance. ChainOS carried it as a
separate catalogue entry until registry v2 and no longer does: a bridged representation the issuer
will not redeem is not the same asset as the token it is named after, and crediting one as the other
is the error the catalogue exists to prevent. This is now the same call as on
Avalanche and Base.
What that means for your integration:
- Tell customers to send native USDC, and give them the contract rather than the word "USDC".
- Branch on
tokenContract, never ontokenSymbol. The contract is the identity. A symbol string comparison is exactly the check that breaks when a bridged form appears — and it is what makes a bridged deposit look like a real one. - If you hold a customer base that still deposits
USDC.e, ask and we will carry it. It goes through the same publication workflow as any other contract: verified against the chain, approved by two people, live in seconds.
Polygon USDT calls itself USDT0
The contract at 0xc2132D05D31c914a87C6611C10748AEb04B58e8F reports symbol() = "USDT0", not
USDT. It relabelled itself in place on 2025-08-27 as part of Tether's omnichain branding: the
implementation behind the proxy was upgraded, and the symbol and name changed with it.
Nothing else changed, and that is the important part. The address is the same, decimals() is still
6, and it is still Polygon's own child ERC-20 emitting ordinary ERC-20 Transfer events. Balances,
deposits and every integration against it were unaffected. ChainOS carries it as USDT with a
display label of USDT0, so tokenSymbol reads USDT and the portal shows you the label your
block explorer shows you.
It is also the second illustration of the rule above: a symbol is something an issuer can change on a Tuesday, and a contract address is not.
Balances
{ "confirmed": "1000000", "available": "1000000", "reserved": "0", "decimals": 6 }
available == confirmed. Nothing is immobilised on Polygon.
Operational notes
- Four minutes of pending is the design, not a fault. The most common support question on this chain is "why is my deposit still pending" from a customer who compared it to a BSC deposit that settled in eleven seconds. Say the number up front.
- Reverted transactions cost the fee.
- POL, not MATIC. The native token was renamed. Balances report POL; older documentation and some exchanges still say MATIC. Same asset.
- Polygon zkEVM is a different chain and is not supported. An address here is on Polygon PoS. A customer sending on zkEVM is sending to an address you control on a network nothing is monitoring — recoverable from your mnemonic, invisible to ChainOS.
- Which chains have a live endpoint is deployment state, not a property of Polygon. This page
does not say. A chain whose provider is unreachable or unconfigured still derives addresses, and
answers balances, fees and broadcast with
503 CHAIN_UNAVAILABLEuntil it is reachable again — so treat that status as transient and read the current answer from readiness rather than from documentation, which cannot know.