How should Bitcoin exchanges complete their UTXO consolidations and what factors should they consider i.e. regularity, fixed or variable intervals, consolidate into how many UTXOs etc?
Exchanges tend to have a much higher transaction volume than other entities, both inbound and outbound. Since payment batching greatly simplifies liquidity management and reduces the overhead per withdrawal by requiring only a single change output and a small number of inputs per transaction, many exchanges can operate their withdrawal wallets on a small count of UTXOs, but tend to grow their UTXO pool over time. Since every UTXO needs to be spent eventually to make use of the funds, the size of the UTXO pool as well as the output types it’s composed of translate to a corresponding future blockspace allocation.
An exchange has several goals in their UTXO management. They want to:
- Minimize funds in their hot wallet to curb exposure to hacks
- Maintain sufficient liquidity to send transactions throughout a sequence of slow blocks
- Maintain a variety of UTXO amounts in case the wallet tries to make changeless transactions
- Be able to service occasional larger withdrawals
- Process withdrawals in a timely fashion for good customer experience and to minimizing support tickets
- Minimize the on-going cost of their wallet operation
- Minimize future blockspace obligations by delimiting UTXO pool growth
A wallet operator should identify the minimum necessary funds, the minimum useful amount for a UTXO and the minimum count of useful UTXOs to be able to timely serve withdrawal requests (including occasional larger withdrawals) and to bridge slow blocks. These metrics depend on the volume of the exchange’s operation and will shift over time. Beyond these operational needs, all other goals align with minimizing the UTXO count and funds in the hot wallet.
Flow of Funds in Wallet Setup
Two common wallet structures involve either receiving deposits to a warm wallet and restocking a hot wallet for withdrawals from the warm wallet, and receiving deposits directly to the hot wallet. I have more comprehensively described these two schemas in my article UTXO Management for Enterprise Wallets.
In either of these setups, the wallet operator should automate absorption of excessive deposits: when funds in the deposit wallets exceed the acceptable risk limit, the system should automatically create a transaction to move the excess of the funds to cold storage. (Obviously, the wallet should be locked down in a way that only the preset destination wallets can be paid with the automated transactions, and neither change outputs nor excessive fees can be used to extract funds.) Since this operation should conclude in a timely fashion, it is usually implemented as a regular send operation using the same coin selection and feerate estimation as withdrawal transactions.
Some of the exchange’s wallets (especially the deposit wallet) may accumulate a large count of UTXOs. Having a variety of amounts in the wallet increases the chances of changeless transactions, but with the common imbalance of inbound deposit transactions compared to the less frequent batched withdrawal transactions, especially UTXOs with lower amounts will end up not getting used for a long time. While some exchanges notoriously make all of their consolidation transactions once every three months, overpaying frighteningly and monopolizing blockspace, it is easy to automate an on-going consolidation process.
The goal in a consolidation transaction is opportunistically spend a lot of inputs when blockspace is abundant in order to reduce the amount of blockspace that must be bid on in the future at an uncertain feerate. Since consolidation transactions are inherently sent at a low feerate, they may take a lot of time to get confirmed. The wallet operator should take care that outputs from consolidation transactions are not eligible to be used as inputs for withdrawal or absorption transactions. Those high-priority child transactions would either get stuck, or if they CPFP the consolidation transaction to a competitive feerate, waste a lot of fees unnecessarily. Further, the wallet operator should not have too many consolidation transactions in flight at the same time, since this reduces the liquidity and flexibility of the wallet.
A simple approach for an automatic consolidation process would be to check once per hour:
- is there already a consolidation tx in flight?
- if not, are there 200+ UTXOs that have more than 2,000 confirmations and less than the “useful amount”?
- if so, submit a consolidation tx with the 200 oldest UTXOs from the above set as inputs at a feerate that might confirm within 24h
This approach makes sure that the wallet does not flood the mempool with consolidation transactions, may perform multiple consolidation transactions in a lull (e.g. weekend or over night), would consistently delimit the wallet’s future blockspace obligation for most wallets, not tie up undue liquidity, gives each UTXO a chance to be picked organically before considering them for consolidation, and be fairly cost-efficient. Only consolidating UTXOs older than two weeks also usually prevents overconsolidation and helps maintain a healthy minimum UTXO count. Naturally, this process would pause whenever the feerates exceed the chosen consolidation feerate, but since the wallet consistently compact’s its UTXO pool, the wallet should be well-prepared for a feerate peak.
If the wallet becomes too fragmented such that withdrawal transactions take many inputs, it may be useful to additionally have a process that automatically produces a consolidation transaction with a slightly higher feerate that picks the largest amounts from the eligible UTXOs instead of the oldest.
If the system registers a persistent growth of the UTXO count, e.g. by the total UTXO count in the wallet exceeding a multiple of the minimum count of useful UTXOs, the wallet should automatically generate a consolidation transaction.
Assuming that the wallet is below its upper bound for funding, the wallet could just pay to itself otherwise it could sweep funds into the cold storage wallet. The consolidation should not go to the withdrawal wallet, since it would make it harder to keep the available liquidity within bounds, and stocking up the withdrawal wallet after some big withdrawals can be an urgent matter.
- To minimize the future blockspace of consolidating these UTXOs, deposits should be received to an output type that minimizes the input weight. At the time of writing this is P2TR.
Every user including exchanges are free to consolidate UTXO as they want.
Although its better to do it during weekends and use low fee rate: https://bitcoinops.org/en/xapo-utxo-consolidation/