Skip to content
PortunaPortunaPortunaDocsTestnet

First and repeat sweeps

The first sweep of a deposit address carries its signed authorization: the same transaction sets the delegate on the address and sweeps it. After that, repeat sweeps need no authorization. The kind of a swept sweep tells which it was:

kindWhat the deposit address neededClassic benchmark
repeatnothing: it was already delegatedtop-up and transfer from an address with an account (existing)
firstits delegate, set in this batch; it already had an account on the chain: it had sent transactions or held native cointhe same (existing)
first_newits delegate, set in this batch, which also created its account: it held only tokensa top-up that creates the account, then the transfer (new)

You do not have to track which addresses are delegated: you can send an authorization with every request. The service uses it only when the address needs it and ignores it otherwise.

Under the Glamsterdam gas rules (EIP-8037), which Sepolia already runs and Ethereum mainnet is expected to adopt, the first touch of an address that holds only tokens creates its account for 183,600 gas, in any scheme: classically the gas top-up creates it, here the delegation does. Repeat sweeps are where batching pays off:

USDT, gas per address on SepoliaClassic: top-up + transferBatch of 10Batch of 50
first sweep (first_new)237,233246,398243,687
repeat sweep53,63320,24618,078

So the service pays off most on permanent deposit addresses, which your users top up again and again. For one-time addresses (a new address per invoice) there is no gas saving, but the operational ones remain: no gas top-ups, no leftover dust, one transaction per batch. Under the earlier gas rules (Ethereum mainnet today, BSC) the new and existing benchmarks are the same.

An authorization is signed for the deposit address’s current nonce: 0 for an address that has never sent a transaction. If the address sends any transaction before its first sweep goes on chain, the nonce moves on and the authorization no longer works. The sweep is then rejected with stale_authorization: sign a new one with the current nonce and send the sweep again.

amount in POST /v1/sweeps is optional:

  • without amount, the sweep moves the whole balance of the token the address holds when the batch executes;
  • with amount, exactly that amount, in the token’s smallest units (1 = 0.000001 USDT on Ethereum), down to a single unit.

Before sending, the service simulates the batch. A sweep that would fail there, for example of an address with no balance or less than amount, is rejected with would_fail.

A token balance does not live in the address but in the token contract, as an “address → amount” entry. When the balance drops to zero, the entry is deleted, and your user’s next deposit creates it again: one of the most expensive operations under EIP-8037, 97,920 gas, paid by the user who sends the tokens.

Sweep the whole balanceKeep 1 unit
Your user’s next deposit to the address (their gas)~126,000~28,000
Repeat sweep in a batch of 10 (your gas)~20,000~24,500

Keeping one unit costs you about 4,000 gas more per sweep, as the chain no longer refunds the deleted entry, and makes every next deposit of your users about 4.5 times cheaper. The unit itself is 0.000001 USDT per address.

  • For all sweeps: PATCH /v1/settings with {"keep_one_unit": true}. It is off by default.
  • For one sweep: keep_one_unit in POST /v1/sweeps, which overrides the setting either way.

With the flag a sweep moves at most the balance minus one unit: without amount, all but one unit; with amount, that amount but no more than the balance minus one. The service reads the balance when it prepares the batch, and funds that arrive later wait for the next sweep. If there is nothing above the one unit, the sweep is rejected with nothing_to_sweep. The flag does not apply to the native coin: its sweep always moves what was asked.

The service puts the queued sweeps of one hot wallet into one batch, up to the chain’s batch size: 50 on Sepolia and 200 on BSC testnet. A batch that would not fit into one transaction’s gas limit goes in parts, without costing the sweeps any attempts.

The batch overhead is shared by its addresses, so bigger batches are cheaper per address, and a batch of one saves little. Send sweep requests in bursts, for example every few minutes for everything that arrived, rather than one at a time with pauses in between.