Blockchain deposits & withdrawals

Crypto custody & compliance · engineering reference

Blockchain deposits & withdrawals

A transaction hash is evidence, not an identity. Start with the chain’s own finality model, then build controls that catch missing, duplicate, and orphaned ledger postings.

VOLATILE CLAIMS: DATE-TAGGEDPRINT: LANDSCAPE TABLES

Start here if this is new

This sheet covers the two moments a business actually touches a blockchain: money arriving, and money leaving. Both are conversations with a system you do not control and cannot roll back, and every rule below follows from that.

How many confirmations before I credit a deposit?

There is no universal number, and six is a convention rather than a derivation. The real question is what an attacker would have to spend to reverse a block against what you just credited. A chain with a small security budget needs more confirmations than Bitcoin, not fewer because its blocks are fast.

Why do ten workers jam on one hot wallet?

Account-model nonces are strictly sequential per address, so two workers that read the same next value both submit and one of them loses. You need a single writer handing out nonces, and you get throughput by sharding across several hot addresses rather than by parallelising one.

Why does sweeping a USDT deposit need ETH?

Moving a token out of a deposit address is a transaction sent from that address, and it needs the chain's native coin for gas. Nobody sends you ETH when they send you USDT, so every token sweep is a funding problem with a transfer attached.

Can I guarantee a withdrawal sends exactly once?

No. Exactly-once does not exist against a system you cannot transact with atomically. What you build instead is at-least-once delivery, an idempotency key so a retry returns the original transaction, and a reconciler that keeps comparing your ledger against the chain.

If you remember one lineRecord the intent before you sign it. A signed transaction your system has no record of is the worst state in the pipeline.

Per-chain finality policy

The numbers that matter are chain-specific. Copying a confirmation count from one chain to another is a common cause of bad credits.

Credit states5observed → settled
Bitcoin1 · 3 · 6blocks by value tier
Ethereumsafeor finalized, never head
Solana400 msslot target
On reorgREVERSEfreeze affected funds
Audit keyhash + heightnot a bare count

Deposit pipeline

Four components, one continuous loop. The reconciler is the backstop — it does not wait for an incident report to tighten the confirmation policy.

Deposit pipeline from listeners to reconciler Chain listeners feed raw events into a confirmation policy gate. Events that clear the gate post an idempotent credit. The reconciler compares posted credits against chain state and feeds mismatches back to tighten or pause the confirmation policy. Listeners Confirmation policy Idempotent credit Reconciler webhook + block poll value-tiered safe/final gate dedup by transfer ID chain vs ledger diff raw tx / block event credit decision ledger posting mismatch → freeze credit / tighten confirmation policy
The forward path credits a deposit; the dashed path is the reconciler pulling the policy tighter the moment a posted credit stops matching chain state.

Value-tiered credit states

Record the block hash, height or slot, status, adapter version, and policy version for every decision. A confirmation count on its own is not enough to audit activity across chains.

StateCustomer balanceWithdrawalRequired evidence
ObservedHidden / pendingBlockedTransaction parsed; asset identity validated
ProvisionalMay displayBlockedCanonical block at adapter-defined safe depth
CreditedAvailable by value tierRisk hold may remainChain-native safe/final state
SettledAvailableAllowed by policyReconciled ledger posting + final chain evidence
OrphanedREVERSEFreeze derived fundsPreviously observed block left canonical chain

Block cadence spans three orders of magnitude

This uses a log axis because a text column hides the gap between a 400 ms slot and a 10-minute target. Cadence is not finality; it only sets the clock that the finality rule runs on.

1s10s1 min10 min
Solana~400 ms slot target
Avalanche C-Chainsub-second to seconds
Polygon PoS (Bor)~2 s
Tron~3 s
Ethereum12 s slot
Litecoin~2.5 min target
Bitcoin~10 min target

Credit state machine

At every state, decide balance visibility and withdrawal eligibility separately.

Credit state machine from observed to settled, with the orphaned branch A deposit moves from observed to provisional to credited to settled. At any point before settlement the block can leave the canonical chain, which sends the deposit to the orphaned state and reverses the customer balance. ObservedProvisional CreditedSettled hiddenmay display available by tierwithdrawable safe depthfinal state reconciled Orphaned block left the canonical chain → REVERSE and freeze derived funds Withdrawal stays blocked until the chain-native final state is reached
A deposit can leave the canonical chain before settlement. That is why credit and withdrawals need separate gates.

Finality register

Cadences are protocol targets or typical ranges, not SLAs. Your production adapter should query live network state and support an incident override. Last checked August 2026.

ChainConsensusCadenceNative vocabularyCredit ruleCritical caveat
BitcoinPoW · probabilistic~10 min targetmempool → block depth1 / 3 / 6 blocks by valueNo protocol-final state
EthereumPoS · economic finality12 s slothead → safe → finalizedUse safe or finalizedFinality normally spans epochs; query the node
SolanaPoS + Tower BFT~400 ms slot targetprocessed → confirmed → finalizedUse commitment parameter explicitlyFinalized means max lockout / rooted
TronDPoS / SR~3 slatest → solidifiedCredit only solidified for withdrawalResource and SR behavior differ from EVM
BNB Smart ChainPoSANetwork-upgrade dependentlatest → finalizedUse finality RPC where supportedNever hard-code an old block interval
Polygon PoSHeimdall/Bor + Ethereum checkpoints~2 s BorBor inclusion → checkpointSeparate fast credit from bridge exitPoS reorg and L1 checkpoint are different states
Avalanche C-ChainSnowman · accepted finalitySub-second to secondsprocessing → acceptedRequire acceptedDo not add Bitcoin-style confirmations mechanically
LitecoinPoW · probabilistic~2.5 min targetblock depthValue-tiered depthSecurity budget differs from Bitcoin
DogecoinPoW · probabilistic~1 min targetblock depthValue-tiered depthMerged mining does not make depth policies identical
Bitcoin CashPoW · probabilistic~10 min targetblock depthValue-tiered depthDeep-reorg history requires incident override
XRP LedgerFederated consensus~3–5 s ledgeropen → validatedCredit validated ledger onlyDestination tag is part of deposit identity
StellarSCP · deterministicUsually secondspending → successful ledgerSuccessful ledger closeMemo is part of deposit identity
CardanoOuroboros · probabilistic~20 s slotblock depthNode/venue risk policySettlement assurance grows with depth
Cosmos SDK / CometBFTBFT · deterministicChain configuredcommitCommitted blockValidator-set and chain halts dominate
TezosPoS with finalityProtocol-version dependenthead → finalizedUse finalized levelUpgrade can change timing parameters
AptosJolteon/DiemBFTSub-second targetpending → executedCommitted executionExpiration timestamp is operationally significant
SuiNarwhal/Bullshark lineagePath dependenteffects certified/checkpointedCheckpointed for external creditFast-path and consensus-path semantics differ
TONPoS shardedShard/masterchain dependentincluded → masterchain confirmedObserve masterchain stateShard routing and memo identity matter

What a chain's status field is actually claiming

Each row is a distinct claim about the network's state, not a synonym for "confirmed." Map your adapter's polled field to one of these rows explicitly — don't assume latest or head means the same thing across chains.

ChainStateWhat it actually meansCan revert?
Ethereumhead / latestCurrent winner under LMD-GHOST fork choiceYes, normally
safeBlock judged safe against reorg under honest-majority and network-synchrony assumptionsOnly under abnormal/adversarial conditions
justifiedCheckpoint has ≥2/3 stake supporting the FFG linkVery difficult, but technically yes
finalizedCasper FFG has finalized the checkpointRequires ≥1/3 stake to violate safety (and get slashed), or extraordinary social intervention
SolanaprocessedYour RPC node processed a block containing the transactionYes
confirmed≥66% of stake voted for the blockExtremely unlikely
finalizedTower BFT lockout has reached maximum depth — traditionally 31+ confirmed descendantsEffectively deterministic under BFT assumptions
TronheadBlock produced by a Super RepresentativeYes
solidified≥19 of the 27 active SRs have progressed to that height or beyondTreated as irreversible
Cosmos SDK / CometBFTcommitted>2/3 of voting power precommitted the blockFinal immediately, under the <1/3 Byzantine assumption
BitcoinN confirmationsBlock has N−1 blocks mined on top of itAlways theoretically yes

Finality vocabulary & Layer 2

Probabilistic depth

Each additional PoW block makes a reversal more expensive, but it never creates a protocol-final flag.

Concrete use: You might show a 1-block provisional credit while holding a large BTC deposit’s withdrawal availability until 6 blocks.

Failure mode: Using the same count for Dogecoin and Bitcoin ignores their different security budgets.

Economic finality

Reversing a PoS checkpoint requires an exceptional consensus failure and exposes validators to slashing.

Concrete use: On Ethereum, request safe for lower latency or finalized for the strongest standard RPC state.

Failure mode: The JSON-RPC latest tag is not a finality promise.

Optimistic rollup

A sequencer receipt, L1 data publication, and challenge-window completion are three distinct points in the process.

Concrete use: You may credit a small Arbitrum deposit after L1 inclusion, while keeping a bridge-dependent withdrawal locked until the relevant protocol state.

Failure mode: An L2 cannot be more final than the L1 data and state it inherits.

ZK rollup

An accepted L1 validity proof establishes state correctness. Data availability and L1 finality are still separate questions.

Concrete use: Track batch inclusion, proof verification, and L1 finalized block as independent fields.

Failure mode: A sequencer UI saying final does not prove L1 settlement.

Withdrawal pipeline

Screening can reject before a key ever signs. Everything after signing is chain-specific plumbing; everything before it is policy.

Withdrawal pipeline from intent to settlement A withdrawal intent passes through screening and policy checks, then signing, then broadcast, then a tracker that watches for inclusion and replacement, then settlement. Screening can instead route the intent to a blocked state held for manual review. Intent Screening Policy Signing customer / ops request sanctions + velocity limits + approvals nonce / UTXO allocator review request cleared checks approved amount Blocked sanctions / velocity hold signed tx Broadcast Tracker Settle submit to network poll inclusion / replace ledger closed + notified hash accepted
Screening can reject an intent outright. Once signed, the tracker owns replacement/CPFP until the chain's own finality rule is satisfied.

EVM nonce runbook

Single-writer allocator

Use one durable allocator to lease sequential nonces for each hot address. Workers should never independently poll for the next value.

Concrete use: Lease nonce 418 for 60 seconds, persist request ID and fee fields, then mark broadcast by transaction hash.

Failure mode: Two workers reading pending can assign the same nonce.

Gap handling

One missing nonce blocks every transaction that follows it from the same address.

Concrete use: If 418 is stuck and 419–425 are queued, replace 418 first; do not keep adding higher nonces.

Failure mode: A gap can look like seven unrelated provider failures.

Replacement

Resubmit the same nonce for the same intent, with a sufficiently higher effective fee.

Concrete use: Keep maxPriorityFeePerGas and maxFeePerGas under a policy ceiling, then reconcile whichever hash lands.

Failure mode: A replacement creates multiple hashes for one withdrawal intent.

Throughput sharding

Because nonce serialization is per sender, throughput comes from multiple funded hot addresses.

Concrete use: Route withdrawals predictably across 8 addresses, while keeping one writer for each address.

Failure mode: Sharding multiplies gas, reconciliation, policy, and rebalancing surfaces.

UTXO operations

The fee examples illustrate the arithmetic; they are not fee recommendations. Query a current node estimator and enforce a maximum fee policy.

OperationControlWorked valueDo not
Coin selectionMinimize input cost, change, and privacy leakageAt 20 sat/vB, a 68-vB input costs ~1,360 sat to spendSelect nominal value without effective value
BatchingOne transaction, many outputs10 P2WPKH outputs avoid repeating 10 transaction overheadsMix incompatible urgency or screening states
RBFReplace an opt-in unconfirmed transactionSame inputs; higher fee; preserve withdrawal identityCredit both hashes
CPFPSpend a low-fee parent output with a high-fee childPackage feerate must clear the targetAssume every output is spendable
ConsolidationMerge small UTXOs during low-fee windowsOnly consolidate inputs whose future fee saving exceeds current costCreate one operationally catastrophic mega-UTXO
Descriptor scanDerive monitored addresses with an explicit rangePersist last-used index and scan beyond configured lookaheadRely on an implicit gap limit

Gas station & deposit hazards

Token sweep funding

An address holding tokens still needs the chain’s native asset to pay execution fees.

Concrete use: Detect USDC, estimate sweep gas, fund only the bounded amount, then sweep and reconcile both transactions.

Failure mode: Pre-funding every address strands native asset and expands attack value.

Contract identity

The chain and token contract identify an asset. Its symbol and decimals are display metadata.

Concrete use: Credit only the allowlisted Ethereum USDC contract and read its configured 6 decimals.

Failure mode: A fake token can emit the same symbol and Transfer event.

Memo / destination tag

Some chains route many users through one address, so the tag is part of the account key.

Concrete use: Store (chain,address,tag) and hold unmatched XRP deposits for operations review.

Failure mode: Address-only indexing miscredits or strands deposits.

Address poisoning

Zero-value or dust transfers can plant a lookalike address in a user’s history.

Concrete use: Never populate destinations from recent on-chain counterparties; use authenticated address books.

Failure mode: Prefix/suffix visual checks are weak against generated lookalikes.

Transfer semantics

Fee-on-transfer tokens, rebasing, and contract-originated moves can break simple amount assumptions.

Concrete use: Credit the observed balance delta after finality, not the requested calldata amount.

Failure mode: Transaction success does not imply the expected token amount arrived.

Reconciliation break taxonomy

Your balance tolerance should be zero. Put timing differences in explicit in-flight accounts, not in an unexplained reconciliation allowance.

MismatchDetectionLikely causeFirst response
On-chain, no ledgerFinalized inbound absent internallyIndexer/webhook lossPause auto-sweep; backfill by block range
Ledger, no chainBroadcast intent has no accepted hashTimeout/crash before broadcastQuery provider by idempotency ID before retry
Duplicate creditSame transfer identity posted twiceAt-least-once deliveryReverse duplicate journal entry; fix uniqueness key
Orphaned creditCredited block no longer canonicalReorgFreeze derived availability; post compensating entry
Amount mismatchObserved delta differs from ledger amountDecimals/fee-on-transferQuarantine asset adapter
Wrong networkSupported address, unsupported chainUser routing errorDo not automate recovery; assess key/control path
Fee driftOn-chain fee ≠ booked expenseReplacement or estimator errorAttach all hashes to one intent and settle actual fee
In-flight snapshotInvariant break clears next cycleTiming boundaryModel in-flight account explicitly; do not use tolerance

Common mistakes & incident checklist

Run this list before enabling a new chain or asset.

  1. Use an internal immutable transaction ID as the key; treat every chain hash as an output/version.
  2. Record requested, safe, and finalized block identifiers—not just a confirmation count.
  3. Centralize nonce allocation and expose lease, gap, replacement, and expiry telemetry.
  4. Check native-fee balance before token sweep and cap automated funding.
  5. Persist chain + contract + address + tag/memo + log index as deposit identity.
  6. Verify token contract and decimals; measure balance delta for unusual tokens.
  7. Make webhook consumers idempotent and back them with block-range polling.
  8. Raise confirmation policy during consensus incidents; never wait for a code deploy.
  9. Alert before descriptor/lookahead exhaustion and test skipped-address recovery.
  10. Reconcile more frequently than the shortest customer withdrawal SLA.

Observed incident register

If a primary record does not establish a trustworthy depth, do not invent one. No number is safer than a false confirmation rule.

Network / dateObserved eventEvidenceEngineering consequence
Bitcoin · 2013-03-110.8/0.7 consensus split from Berkeley DB lock behaviorBIP 50: fork at height 225,430; experimental double-spend documentedSuspend on node-version disagreement; height is not a unique ID
Bitcoin · 2013-08-16Unpatched nodes forked at block 252,451BIP 50 resolution recordTrack consensus alerts and client versions, not depth alone
Ethereum Classic · 2020-07-31Successful 51% reorganization attackProject historyStatic confirmation policy can become obsolete during attack
Ethereum Classic · 2020-08-06Third successful 51% reorganization attackRepeated within one weekPause can be safer than adding a few blocks
Ethereum Classic · 2020-08-29Fourth successful 51% reorganization attackRepeated in same monthSecurity budget and incident state govern policy

Value-at-risk policy pattern

Set bands from your loss tolerance and the chain’s attack economics. Never treat one confirmation count as an inherent property of every asset.

TierCreditWithdrawalIncident overlay
LowProvisional at conservative safe levelHold until settledRaise or pause automatically
MediumChain-native safe/final stateAdditional risk/KYT holdManual release during instability
HighStrongest final state + independent node agreementHuman approval after reconciliationPause on fork/finality alarm

Primary sources & scope

We checked the operational and volatile claims against these first-party documents on 2026-08-31. The examples illustrate controls; they are not legal, investment, or vendor-selection advice.