An exchange that credits an Ethereum deposit after one block is exposed for about 15 minutes, which is how long Ethereum takes to finalize. An exchange that makes customers wait 15 minutes on Arc is holding their money for about 1,800 blocks that could never have been reversed. Both mistakes come from using one confirmation rule for every chain.
The right rule differs by chain in kind as well as in number. Some chains hand you a finalized tag backed by slashable stake. Tron gives you a solidified block from a committee of 27 producers. Base and other rollups inherit finality from Ethereum through a batch that Ethereum then takes a quarter of an hour to finalize, and Bitcoin gives you nothing but probability.
This page puts the per-chain answers in one table, measured on 5 November 2026 against Dwellir's production endpoints, then shows a detection pipeline that survives a reorg on any of them. The finality and reorg explainers cover the underlying concepts. This post turns them into a deposit policy.
Three questions every deposit policy must answer
For every chain you accept deposits on, you need to know:
- Which signal means settled. A block tag, a solidified height, a finalized head, or a confirmation count.
- How long that signal takes behind the chain head, so you can set customer expectations and size your pending state.
- What the chain does when it changes its mind, and how your RPC layer tells you. On EVM chains that is the
removedfield on logs and a brokenparentHashchain.
The answers give you a ladder of states rather than a single threshold:
| Deposit state | What the customer can do | Signal to reach it |
|---|---|---|
| Seen | See it as pending in the UI | Transaction in latest |
| Credited for trading | Trade against it, no withdrawal | Block at or below safe, or the chain's equivalent |
| Settled | Withdraw, including to another chain | Block at or below finalized, or N confirmations on probabilistic chains |
The table below gives the signals and the measured distances for each chain.
The per-chain confirmation table
Every block number below comes from Dwellir endpoints between 19:55:53 and 19:56:56 UTC on 5 November 2026, read with eth_getBlockByNumber for the latest, safe and finalized tags or the chain's native equivalent. Lag is the block distance between latest and the tag at that instant, converted to time using the block time over the preceding 100 blocks. Lag moves within each chain's finality cycle, so treat each figure as one sample rather than a constant. The three tags were read one after another, so a chain with sub-second blocks can show a one-block skew between them, which is why HyperEVM shows 0 to 1 block. Base was read under two hours after its Denim upgrade activated on mainnet at 18:00 UTC, so its block time is 0.2 seconds, not the 2 seconds older guides assume.
| Chain | Block time | Finality mechanism | Settled signal | Measured lag: safe | Measured lag: finalized | Reorg exposure before the signal |
|---|---|---|---|---|---|---|
| Ethereum | 12 s | Casper FFG checkpoints | finalized tag | 41 blocks, about 8 min | 73 blocks, about 15 min | Head reorgs happen; 7 blocks on 25 May 2022 |
| Base | 0.2 s (Denim) | L1 batch finality | safe to credit, finalized to settle | 137 blocks, about 27 s | 4,458 blocks, about 15 min | Sequencer can reorg latest; safe only via an L1 reorg |
| Optimism | 2 s | L1 batch finality | safe to credit, finalized to settle | 91 blocks, about 3 min | 762 blocks, about 25 min | As Base |
| Arbitrum One | 0.25 s | L1 batch finality | finalized tag | 2,055 blocks, about 8.6 min | 3,501 blocks, about 14.6 min | latest is a sequencer promise |
| Robinhood Chain | 0.1 s | L1 batch finality (Arbitrum Orbit) | finalized tag | 5,235 blocks, about 8.7 min | 8,811 blocks, about 14.7 min | As Arbitrum |
| Polygon PoS | about 2 s | Heimdall v2 milestones | finalized tag | not supported, returns null | 2 blocks, about 4 s | 157-block reorg on 22 Feb 2023, before milestones |
| BNB Smart Chain | 0.75 s | BEP-126 fast finality | finalized tag | 1 block | 1 block, under 1 s | Falls back to probabilistic if fast finality stalls |
| Avalanche C-Chain | 0.8 s | Snowman, final on acceptance | finalized tag | 6 blocks, about 5 s | 6 blocks, about 5 s | None by design |
| Tron | 3 s | DPoS, 19 of 27 producers | walletsolidity/* or JSON-RPC finalized | not supported | 18 blocks, 54 s | Head can be replaced until solidified |
| HyperEVM | about 1 s | HyperBFT | finalized tag | 0 to 1 block | 0 to 1 block | None by design |
| HyperCore | no blocks; 0.2 s median latency | HyperBFT | userNonFundingLedgerUpdates | immediate | immediate | None by design |
| Polkadot | 6 s | GRANDPA | chain_getFinalizedHead | not applicable | 4 blocks, about 24 s | Best head can be reverted until GRANDPA finalizes it |
| Arc | 0.51 s | Malachite BFT | finalized tag | 0 blocks | 0 blocks | None by design |
| Stable | 0.7 s | StableBFT on CometBFT | finalized tag | 0 blocks | 0 blocks | None by design |
| Plasma | 1.0 s | PlasmaBFT | finalized tag | 2 blocks | 2 blocks, about 2 s | None after commit |
| Tempo | 0.54 s | Simplex | finalized tag | 0 blocks | 0 blocks | None by design |
| Bitcoin | about 10 min | Proof of work | N confirmations, 6 is standard | not applicable | 6 blocks, about 60 min | Probabilistic; 2-block reorg on 23 Mar 2026 |
| Sui | about 0.4 s | Mysticeti | Checkpointed transaction via gRPC or GraphQL | not applicable | under 1 s | None by design |

Three things stand out. The Ethereum family lands between 15 and 25 minutes on the same finalized tag, on L1 and on every rollup in the table, because all of them wait for the same Casper checkpoints; the rollups differ in what safe means and in a few minutes of batching and derivation, not in kind. The BFT chains (Arc, Stable, Tempo, HyperEVM, Avalanche, Plasma, BNB) return the same or nearly the same block for all three tags, so a confirmation counter adds latency and nothing else. And Polygon and Tron, which most deposit systems treat as EVM chains, return null for safe, which will crash a pipeline that assumes the tag always exists.
Ethereum: what safe means now depends on the beacon node
Ethereum's finalized tag is unambiguous. A block is finalized when two consecutive checkpoints have been justified by two thirds of staked ETH, and reverting one would cost at least a third of all stake. The gap behind the head cycles between about 64 and 95 blocks. That is why a single reading showed 73 blocks, and why a fixed "wait 64 blocks" rule is sometimes too early.
The safe tag used to be nearly as predictable: the last justified checkpoint, about one epoch behind the head. That changed in 2026. Lighthouse 8.3.0 (19 October 2026) ships the Fast Confirmation Rule behind a flag, and Lodestar is further along. With it enabled, safe advances every slot, about one slot or 12 seconds behind the head, assuming 75% of stake is honest and attestations arrive on time.
No slashing stands behind a fast-confirmed block. The 41-block reading shows Dwellir's Ethereum pool was still serving the classic checkpoint safe. A different provider, or the same provider after a client upgrade, may return a height 40 blocks newer under the same tag.
For a deposit pipeline that means two rules. Use safe for trading credit only if your risk team accepts that its meaning is provider-configured, and measure the lag yourself. Use finalized for anything you cannot reverse. The safe block and Fast Confirmation explainer covers the mechanism, and the FastConfirm rollout checklist shows how to verify what your endpoint returns.
OP Stack and Arbitrum: when finalized waits for Ethereum
On Base, Optimism, Arbitrum One and Robinhood Chain the sequencer orders transactions in under a second, but the chain is only as final as its data on Ethereum. That gives three levels, which all four chains expose through the same tags, with one difference in what safe means:
| Level | Tag | What it means | Measured on 5 Nov 2026 |
|---|---|---|---|
| Sequencer confirmed | latest | The sequencer has included the transaction and promised the order | One block time, 0.1 to 2 s, behind real time |
| Batch posted | safe | OP Stack: the batch is in an Ethereum block and the node has derived it. Arbitrum: the Ethereum block holding the batch is itself safe. Either way only an Ethereum reorg can undo it | Base 27 s, Optimism 3 min, Arbitrum 8.6 min, Robinhood 8.7 min |
| L1 finalized | finalized | The batch is in a finalized Ethereum block | Base 15 min, Optimism 25 min, Arbitrum 14.6 min, Robinhood 14.7 min |
The readings sit close to Ethereum's own 15 minutes because that is what every rollup waits for. An OP Stack block is final when the Ethereum block holding its batch is final, so the lag depends on how long the batch waited to be posted, how long Ethereum took to finalize it, and how far behind the node's derivation runs. Optimism's docs give 15 to 30 minutes as typical and 12 hours, the sequencing window, as the worst case; Arbitrum's equivalent is the 24-hour window after which a delayed-inbox message can be force-included. Circle's CCTP documentation puts the standard wait at about 65 Ethereum blocks after the batch posts.
All four rollup readings sit at or just under the low end of that range, and the ceiling is what matters for policy: a batch can legally wait up to 12 hours, so you cannot promise a rollup customer a settlement time from one reading. Measure the lag on your own endpoint over a day before you write a number into a help page.
Base changed shape the day of the reading. Its Denim upgrade activated on mainnet at 18:00 UTC on 5 November 2026 and replaced Flashblocks and the pending tag with canonical blocks every 200 ms, which is why Base's safe lag is 137 blocks but only 27 seconds. A deposit now appears in latest within about a fifth of a second, as sequencer-confirmed only, never as evidence for credit. A pipeline that still reads pending needs the Base Denim migration guide; the Flashblocks guide documents the state table Denim retired.
Arbitrum's documentation gives exchanges five rules that apply to every rollup here: settle deposits at finalized, with safe for revocable trading credit as your own risk call; do not use fixed block counts; detect reorgs by checking parentHash continuity; never rewind below finalized; and do not index against the sequencer's fast feed. Robinhood Chain inherits all of this as an Arbitrum Orbit chain, and its measured 0.1-second block time makes any block-count rule meaningless. Its safe and finalized lag in minutes matched Arbitrum One's almost exactly.
Chains where finality is a few blocks away
On the BFT and fast-finality chains, the three tags collapse. Arc, Stable and Tempo returned identical numbers for latest, safe and finalized, and HyperEVM was within one block. Plasma's finalized was 2 blocks behind, Polygon's 2, BNB Chain's 1 and Avalanche's 6 on Dwellir's pool. The deposit rule is the same on all of them: one receipt whose block number is at or below finalized is settled.
The chain-specific details:
- Polygon PoS finalizes through Heimdall v2 milestones, live since July 2025, in 2 to 5 seconds. Before milestones it suffered a 157-block reorg on 22 February 2023, which is why older deposit systems still wait 128 or 256 blocks. That wait is now pure latency.
safereturnsnull; usefinalized. - BNB Smart Chain documents finality of about 2 seconds under BEP-126 after the Maxwell upgrade, and the endpoint reading showed
finalizedone block behind the head. BNB Chain tells exchanges to usefinalized. If fast finality stalls, the chain falls back to probabilistic finality, so your pipeline should alert when thefinalizedheight stops advancing. - Avalanche C-Chain is final on acceptance, so the 6-block gap in the reading, about 5 seconds, is not a settlement window. It is most likely which node in the pool answered each of the three reads, the same read artefact that puts HyperEVM at 0 to 1 block. Treat
finalizedas the signal and ignore the count. - Hyperliquid settles HyperCore and HyperEVM in the same HyperBFT consensus, with a median end-to-end latency of 0.2 seconds. HyperEVM deposits use standard
eth_*calls. HyperCore deposits (USDC bridged in, spot transfers, internal sends) show up in the/infoendpoint'suserNonFundingLedgerUpdates, and the same name is a WebSocket channel. The HyperEVM developer guide covers how the two sides fit together. - Polkadot separates block production (BABE, 6-second slots) from finality (GRANDPA). Credit on
chain_getFinalizedHead, or subscribe tochain_subscribeFinalizedHeads, never on the best head. The reading had finality 4 blocks behind, about 24 seconds. - Arc, Stable, Plasma and Tempo are the new stablecoin settlement chains, and all four run BFT consensus with a permissioned or small validator set. Tempo's docs tell you to query
eth_getBlockByNumber("finalized"). The settlement guarantee rests on more than two thirds of a named validator set staying honest, rather than on elapsed time or burned stake. Handle that with per-chain deposit limits. A confirmation count the protocol does not need adds nothing.
Tron: use the solidity endpoints
Tron produces a block every 3 seconds from 27 elected Super Representatives. A block is solidified once 19 of the 27 producers have produced a block at or after it, its own producer included, which is Tron's SOLIDIFIED_THRESHOLD of 70% and why the reading below shows 18 blocks rather than 19, and the solidified height never rolls back. Tron's documentation tells you to read confirmation state from a solidity node, which Dwellir exposes as the walletsolidity/* HTTP paths next to the wallet/* head paths:
# Head block, can still be replaced
curl -sS -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/getnowblock \
-H 'content-type: application/json' -d '{}'
# Latest solidified block, cannot roll back
curl -sS -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/walletsolidity/getnowblock \
-H 'content-type: application/json' -d '{}'At the time of reading the head was block 87,744,961 and the solidified block was 87,744,943, 18 blocks and 54 seconds behind. The JSON-RPC finalized tag on the /jsonrpc path returned the same solidified height, so an EVM-style pipeline can use it. safe returns null. OKX's deposit help page, updated 10 September 2026, requires 19 confirmations for TRC-20 USDT, which is the solidification rule expressed as a count. For USDT specifically, the Tron energy and USDT transfer guide explains the fee side of the same flow.
Bitcoin: confirmations are the only signal
Bitcoin has no finality tag. The probability that a transaction is reversed falls with each block built on top of it, and 6 confirmations, about 60 minutes, is the long-standing standard because it drives an attacker with 10% of hashrate below a 0.1% success chance. Kraken's deposit page, updated 22 October 2026, waits 3 confirmations for BTC. The 2-block reorg at height 941,880 on 23 March 2026, involving three large pools, shows that one or two confirmations is a UI signal rather than a settlement one.
The usual answer is value tiers: credit small deposits at 1 to 3 confirmations and large ones at 6 or more, with thresholds tied to what a reversal would cost you rather than to a fixed number.
What Circle and the exchanges wait for
Few exchanges publish confirmation requirements; most show them only inside the deposit screen. Two public sources work as a benchmark. Circle's CCTP waits for these before attesting a USDC transfer, and its "standard" column is the one to read as settled:
| Chain | CCTP standard finality | Average time | CCTP fast finality |
|---|---|---|---|
| Ethereum | about 65 blocks | 15 to 19 min | 2 blocks, about 20 s |
| Arbitrum, Base, OP Mainnet | about 65 ETH blocks after the batch | 15 to 19 min | 1 block, about 8 s |
| Polygon PoS | 2 to 3 blocks | about 8 s | |
| Avalanche | 1 block | about 8 s | |
| BNB Smart Chain | 3 blocks | about 2 s | |
| HyperEVM | 1 block | about 5 s | |
| Plasma | 3 blocks | about 1 s | |
| Arc | 1 block | about 0.5 s | |
| Sui | 1 block | about 0.5 s |
The block counts and times are Circle's published figures, which include its own observation and attestation delay, so they do not reduce to the block times measured above.
OKX publishes two numbers: 32 confirmations for ERC-20 USDT and 19 for TRC-20 USDT. Both line up with protocol boundaries, one Ethereum epoch and Tron's solidification, rather than with round numbers. The pattern to copy is the alignment, not the counts: 32 Ethereum blocks is a justified checkpoint, short of the 64 to 95 blocks finality takes, so read the tags and, if a help page needs a count, derive it from the boundary you actually wait for.
A deposit pipeline that survives a reorg
The signals differ per chain. The pipeline around them does not. Six steps cover every EVM chain in the table. Tron fits the same path through its /jsonrpc endpoint. On Polkadot, Sui, HyperCore and Bitcoin the shape holds but the signals change: chain_subscribeFinalizedHeads, checkpoints, ledger updates that are final on arrival, and block height with hash in place of the tags, and the chain's own canonical-hash check in place of removed: true and eth_getLogs.
1. Watch heads and logs over WebSocket. Subscribe to newHeads for the chain tip and to logs filtered to your deposit addresses or to the ERC-20 Transfer topic. Polling eth_getBlockByNumber every block works on slow chains and gets expensive on 0.1-second ones. The WebSockets guide covers subscription types and limits.
2. Record every observation with its ancestry. Key deposits on (chain_id, tx_hash, log_index) and store block_number, block_hash and parent_hash for every block you process. Before processing block N, check that its parentHash equals the hash you stored for N-1. A mismatch is a reorg, and the stored hashes tell you how deep.
3. Promote state by comparing block numbers, not by counting. A transaction has no confirmation status of its own. Once per new head, read safe and finalized and promote every pending deposit whose block number is at or below them, after checking that the block at the deposit's height still carries the hash you stored, since a reorg can replace the block and let the height finalize anyway:
type Tag = "latest" | "safe" | "finalized";
type Block = { number: string; hash: string };
async function getBlock(rpc: string, at: Tag | number): Promise<Block | null> {
const res = await fetch(rpc, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0", id: 1, method: "eth_getBlockByNumber",
params: [typeof at === "number" ? "0x" + at.toString(16) : at, false],
}),
});
const { result } = await res.json();
return result ?? null; // null on Polygon and Tron for "safe"
}
const height = (b: Block | null) => (b ? parseInt(b.number, 16) : null);
export async function depositState(rpc: string, deposit: { block: number; blockHash: string }) {
const [safe, finalized, canonical] = await Promise.all([
getBlock(rpc, "safe"),
getBlock(rpc, "finalized"),
getBlock(rpc, deposit.block),
]);
// A reorg can replace the deposit's block and let the height finalize anyway.
// A null here is a lagging node or an RPC error, not a reorg: stay at "seen" and retry.
if (!canonical) return "seen";
if (canonical.hash !== deposit.blockHash) return "reverted";
const f = height(finalized), s = height(safe);
if (f !== null && deposit.block <= f) return "settled";
if (s !== null && deposit.block <= s) return "credited";
return "seen";
}Chains without a safe tag skip straight from seen to settled, which is the right behaviour on Polygon and Tron. On chains where all three tags are equal, a deposit is settled on its first evaluation.
4. Treat removed: true as a rollback, not a delete. After a reorg, log subscriptions re-send the logs of orphaned blocks with removed: true, then emit the new branch's logs. Mark the deposit reverted, keep the record, and let the new branch's log re-credit it if the chain included the transaction again. The same transaction can arrive three times; idempotent writes keyed as in step 2 make that harmless.
5. On reconnect, resubscribe first, then back-fill with an overlap. Persist the last processed block durably, including its hash. After a disconnect, open the new subscriptions before recovery so nothing falls between them. Then run eth_getLogs from a few blocks before your last durable block to the current head, dedupe against step 2, and check hash continuity across the gap, never rewinding below finalized. The eth_subscribe reconnect guide covers backoff, buffering and what the recovery costs per provider.
6. Alert when finality stops moving. On every chain, store the finalized height per poll and alert if it has not advanced within a few multiples of the expected lag. A stalled finalized height tells you about a BNB fast-finality fallback, a Polygon milestone incident like the one on 10 September 2025, or a provider node that has fallen behind, before it reaches your ledger.

Running this across chains on one provider
The pipeline above makes one safe and one finalized read per new head on every chain, plus a log subscription and occasional eth_getLogs back-fills. On a compute-unit provider each method carries a different weight, and the back-fills are the expensive part. Dwellir bills one credit per response on every method, including eth_getLogs, so a reorg-safe pipeline costs its request count and nothing else.
One Dwellir account serves every chain in the table: Ethereum, Base, Optimism, Arbitrum, Robinhood Chain, Polygon, BNB Chain, Avalanche, Tron with both wallet and walletsolidity paths, Hyperliquid on both sides, Polkadot, Arc, Stable, Plasma, Tempo, Bitcoin and Sui, with WebSocket endpoints on the EVM and Substrate chains. The public RPC endpoints hub lists each URL and chain ID. The multi-network wallet backend guide covers the other half of a custody stack, including checking eth_chainId before you trust any endpoint's answer. That check matters as much for a deposit pipeline as for a wallet.
If you are building or re-platforming exchange deposit infrastructure and want to talk through confirmation policy or dedicated capacity per chain, contact the Dwellir team. To start measuring the lags on your own chains, create an API key and run the three-tag read above.
Frequently asked questions
How many confirmations does an exchange need for an Ethereum deposit?
Stop counting blocks and read the finalized tag. On 5 November 2026 Dwellir's Ethereum endpoint reported finalized 73 blocks behind the head, about 15 minutes, and that gap swings between roughly 64 and 95 blocks within every finality cycle. OKX waits 32 confirmations for ERC-20 USDT, one epoch, and Circle's CCTP waits about 65 blocks, two epochs. Both are protocol boundaries expressed as counts, not round numbers.
Is the safe block tag enough to credit a deposit?
Only for credit you can take back, such as trading balance with withdrawals held. What safe means now depends on the provider's beacon node. With the classic rule it trails the head by about an epoch, 41 blocks in Dwellir's reading. With the Fast Confirmation Rule enabled in Lighthouse 8.3 or Lodestar it advances every slot, with no slashing behind it. Withdrawals and payouts should wait for finalized on every chain.
Why is finalized on Base and Optimism minutes behind the head?
Because an OP Stack chain is only final once the Ethereum block holding its batch is final, and that depends on when the batch was posted, when Ethereum finalized it and when the node derived it. On 5 November 2026 Base's finalized block was 4,458 blocks behind latest, about 15 minutes at Denim's 0.2-second block time, and Optimism's was 762 blocks, about 25 minutes. Optimism's docs give 15 to 30 minutes as typical and 12 hours, the sequencing window, as the worst case, so measure your own endpoint before promising a settlement time. safe, which means the batch has been posted, is the usual middle ground for crediting.
How do I detect a chain reorg over RPC?
Store the hash and parentHash of every block you process and check that each new block's parentHash equals the hash you stored for the previous height. A mismatch means a reorg. On log subscriptions, logs from orphaned blocks are re-sent with removed set to true. Rewind to the common ancestor, never below finalized, mark the affected deposits as reverted and re-scan.
Do chains with instant finality still need a confirmation count?
No. On Arc, Stable and Tempo the latest, safe and finalized tags returned the same block in Dwellir's readings, and HyperEVM, BNB Chain, Plasma and Polygon PoS were within one to two blocks. One receipt in a finalized block is enough. The trust you are placing is in a validator set rather than in elapsed time, so set deposit limits per chain with that in mind.
Sources
Block tag readings, Tron head and solidified blocks, Polkadot best and finalized heads, and 100-block timing samples were taken from Dwellir's production endpoints between 19:55:53 and 19:56:56 UTC on 5 November 2026. Third-party pages were checked the same day.
- Ethereum: Gasper, single-slot finality roadmap, Fast Confirmation Rule, Lighthouse v8.3.0 release notes, FCR client status, April 2026, May 2022 7-block reorg, Geth pub/sub and removed logs
- OP Stack: transaction statuses, Base Denim 200 ms blocks, Base network upgrades
- Arbitrum: finality and reorgs, the sequencer and force inclusion, Robinhood Chain mainnet
- Polygon: finality, 5-second finality upgrade, 157-block reorg, Feb 2023, September 2025 finality incident
- BNB Chain: BEP-126, Maxwell hard fork, sub-second finality and settlement
- Avalanche: performance and finality
- Tron: consensus and solidified blocks, Dwellir Tron docs
- Hyperliquid: HyperCore overview, dual-block architecture
- Polkadot: chain_getFinalizedHead
- Sui: consensus, JSON-RPC deprecation
- Bitcoin: March 2026 2-block reorg, double-spend probability analysis
- Stablecoin chains: Arc deterministic finality, Plasma consensus, Stable technical roadmap, Tempo consensus
- Settlement benchmarks: Circle CCTP finality and block confirmations, OKX deposit completion times, Kraken deposit processing times




