USDT on Tron and the energy bill: what sweeping TRC-20 deposits really costs
If you take stablecoins, a lot of your customers will want to pay in USDT on Tron. Transfers are cheap for them and most exchanges support withdrawals on it. Then you build the part that moves those deposits somewhere sa
If you take stablecoins, a lot of your customers will want to pay in USDT on Tron. Transfers are cheap for them and most exchanges support withdrawals on it. Then you build the part that moves those deposits somewhere safe, and you find out the cheap part was only cheap for the sender.
This post is about that second step: getting USDT out of per-customer deposit addresses and into a wallet you control, and why the cost of doing it on Tron behaves differently from what you might expect if you've only done this on EVM chains.
Two resources, not one gas price
On Ethereum-style chains you think in gas: a transaction uses some units, you pay a price per unit, done. Tron splits the cost into two resources:
- Bandwidth, which pays for the bytes of the transaction. Every account gets a small free daily allowance, and a plain TRX transfer usually fits inside it.
- Energy, which pays for running smart contract code. A USDT transfer is a call to the TRC-20 contract, so it needs energy, and quite a lot of it compared with a simple transfer.
If the account sending the transaction doesn't have enough energy, the network burns TRX from that account to cover the shortfall. That's the bit that surprises people. The fee isn't a fixed number you can read off a block explorer once and hard-code; it depends on how much energy the sender already has and on the network's current energy price.
You can get energy three ways: burn TRX each time, stake (freeze) TRX to receive energy that regenerates, or rent it from someone who has staked. Renting is often the cheapest option for a business that sweeps irregularly, because you don't have to lock up capital to stake.
Why sweeps make this worse
A checkout that gives every customer their own deposit address is the right design. It makes payments easy to match and stops one customer's payment being confused with another's. But it means money lands in many small places, and every one of them needs a contract call to move.
Some rough intuition, without pretending to exact numbers that change week to week:
- Sweeping a deposit costs about the same whether it holds $5 or $5,000. The energy is spent on the contract call, not on the amount.
- So the fee as a share of the amount is brutal for small deposits and close to irrelevant for large ones.
- If you sweep every deposit as soon as it confirms, you pay the full cost on every small order.
The usual answer is the same one you'd use on any chain: don't sweep immediately, sweep when it's worth it. Let deposits sit until the value justifies the cost, set a cap on what you're willing to pay, and batch the work.
What the sweeper needs to decide
When I sketch a sweep job on paper it ends up with four questions:
- Is there enough on this address to bother? A per-network minimum, expressed in dollars, not token units.
- What will it cost right now? Estimate energy and bandwidth, then price any shortfall.
- Is that under my cap? A ceiling per sweep, so a spike in energy prices pauses sweeping instead of eating the margin.
- Where does the energy come from? Burn, use staked energy, or rent.
The fourth question is the Tron-specific one. On EVM chains the gas has to come from somewhere too, usually a small hot wallet that tops up deposit addresses, but there's no rental market to think about.
Keep the hot wallet small and boring
Whatever pays for sweeps is a hot wallet: its key has to be available to an automated process. That's a risk you want to shrink, not eliminate by pretending it doesn't exist.
A few rules that hold up:
- The hot wallet only ever holds fuel. TRX for energy and bandwidth, ETH or the native coin for gas. Never customer funds.
- Only the process that sweeps (and, if you have one, the one that pays out) can unlock it. The web-facing API shouldn't be able to.
- Keep it encrypted at rest behind a passphrase, and keep the balance low enough that losing it would be annoying rather than serious.
- Alert when it runs low. A sweeper that silently stops because it ran out of TRX is a quiet way to end up with funds sitting on deposit addresses for weeks.
Where the money is allowed to go matters more than the fee
Fees are an operational cost. The destination is a security question. If a compromised server can change where sweeps go, every optimisation above is irrelevant.
This is the design choice we made in Coldtill. On Ethereum-style chains, Tron and Solana, each deposit address is a contract that can only send to the merchant's cold wallet, so the sweeper can trigger a sweep but can't choose a different destination. The sweep rules are per network with fee caps, funds move in batches when the value justifies the gas, and on Tron the sweeper can rent energy instead of burning TRX. The dashboard also shows funds still sitting on deposit addresses until they're swept, which is the number you actually want to watch.
If you'd rather read the code than my description, the gateway is on GitHub: Coldtill/self-hosted-crypto-payment-gateway. The product page with the full feature list is at coldtill.com.
A checklist if you're building this yourself
- Track deposits in base units as integers, and value them in dollars only for the sweep threshold.
- Estimate energy before each Tron sweep and price the shortfall at the current rate.
- Decide up front whether you'll burn, stake or rent, and make the choice a setting, not a code change.
- Put a per-sweep fee cap in place and log every sweep that was skipped because of it.
- Fund sweeps from a small, separate hot wallet that never touches customer money.
- Make the sweep destination something the server can't change.
- Show "money not yet swept" somewhere a human will see it.
Tron USDT is popular for good reasons, and it's worth supporting. Just budget for the second transaction, not only the first.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.