Documentation

Fees, dust and UTXO growth — design v3

Status: the storage mass (consensus + mempool policy + the fee in the wallet) is implemented — internal/chain/storagemass.go, mempool.go, wallet.go; the tests are in storagemass_test.go. A minimum fee under congestion (a congestion floor) is not in yet.

What this has to solve. New coins often cannot send reliably and are not protected against dust spam. The requirement: fair, low and predictable fees — like BSC, not like ETH. A fee that surprises people puts them off mining and off sending.

v1 (a dust limit + a cap on the increase + a burned base fee as in EIP-1559) is superseded. The reason: a base fee that grows exponentially is exactly the “ETH” feeling we do not want, and dust does not need it anyway — value-based mass (KIP-9) solves that better.

1. What happened elsewhere

chain when what how they solved it
Litecoin 8/2019 dust of 0.00000546 LTC to ~300,000 addresses — tracking + pool advertising nothing in consensus; the advice “do not spend the dust”
Kaspa 9/2023 5 tx/block, each 1 → 238 outputs: +1,185 coins/block, ~5 GB/day, the UTXO set 8 M → 62 M KIP-9 storage mass in consensus
Bitcoin 2023–2025 Ordinals/BRC-20: the UTXO set 84 M → 169 M, ~49 % of coins below 1,000 sat nothing; the dust limit is only policy and the growth is irreversible
Monero 3/2024 spam from 25 k to 140 k tx/day (an attempt at deanonymization) a dynamic block size with a reward penalty
EVM chains 11–12/2023 inscriptions: Arbitrum a 78 min outage, Polygon fees +6,900 %, Fantom +8,990 % the cheap chains got congested and the fees shot up for everyone
Solana 4–6/2022 bots at 6 M tx/s during NFT mints → a 7 h outage QUIC, stake-weighted QoS, priority fees
Dogecoin 2021 the fixed 1 DOGE fee became expensive as the price rose the fee was lowered to 0.01 DOGE (policy)
BSC 2024–2025 — the minimum gas gradually 3 → 1 → 0.1 → 0.05 gwei (~$0.005/tx)

The lessons:

  1. Dust that cannot be worked around is only solved by consensus (Kaspa yes, Bitcoin no — and Bitcoin carries it forever).
  2. A fixed dust limit is not enough — what matters is how many coins and of what value are created; KIP-9 measures that directly.
  3. A fee denominated in units of the coin has to be changeable without a fork, because the coin’s price changes (Dogecoin, BSC).
  4. Full blocks are an auction and fees rise in one everywhere — what matters is that ordinary traffic stays cheap.

2. The rules

R1 · Storage mass per KIP-9 — consensus

storage_mass(tx) = C × ( Σ_o 1/o  −  |I|² / Σ_i i )⁺
relaxed, if |O| ≤ |I| ≤ 2 or |O| = 1:   C × ( Σ_o 1/o − Σ_i 1/i )⁺

o and i are the values of the outputs and the inputs in cogs, C = 10⁸ in consensus, and data outputs do not count. A block has to satisfy Σ storage_mass ≤ 64,000, 16,000 of it kept for the coinbase (alongside the cap of 96 kB of bytes).

  • Normal outputs cost almost nothing (an output of 1 POWM = 1 unit), small ones more (0.0001 POWM = 10,000), dust does not fit at all (1 cog = 10⁸).
  • Consolidating coins has zero mass. Whoever moves many coins pays only for the bytes.
  • An attack is quadratically expensive: the number of coins grows only with the square root of the budget.
  • It applies to a miner too — it is a block rule, not a mempool one.
  • In integers: C / o by integer division, |I|² × C / Σ i in 128 bits.

A separate dust limit in consensus is not needed — the smallest output that fits into a block at all is C / 64,000 ≈ 1,563 cogs, and a transaction from the mempool, which gets 48,000 of it, cannot go below ≈ 2,084 cogs.

Why C in consensus is not stricter (v2 had 10⁹): the constant is in POWM, not in dollars. At 10⁹ and a price of $1,000, a $1 payout would cost $0.10 and only 25 such payouts would fit in a block; at $10,000 it would be unusable. And there is an asymmetry: C can be tightened by a soft fork, relaxed only by a hard fork. That is why consensus starts in the middle (10⁸) and the strictness at a low price is supplied by policy (R2).

R2 · Fees like on BSC — policy, not consensus

  • The fee = the bottom rate × max(bytes, storage_mass_policy), where the storage mass for the fee is computed with its own constant C_pol in the node: 10⁹ at the start (while POWM is cheap and spam is cheap in dollars), later 10⁸ — changed by a node release without a fork, just like the bottom rate. The block cap is always computed with the consensus C.
  • The bottom rate stays 1 cog per unit (= today’s 1,000 cogs/kB). It is in the mempool’s policy, so it can be lowered by a node release without a fork when the price of POWM rises — the way BSC lowers gas.
  • Under congestion the excess over the bottom rate decides (an ordinary auction). Nothing is burned, and there is no exponentially growing base fee.

An admitted trade-off: a miner can fill their own block for free. The damage is bounded — at most 96 kB of history per block (a burden only for archival nodes, see a pruned node) and no UTXO inflation, because R1 applies to them too.

R3 · The transaction limits are unchanged

MaxTxInputs 1,000 (a tx of ~107 kB). Big transfers are handled by the wallet splitting them into several transactions.

3. What that does at launch (the bottom rate 1 cog/unit, C_pol = 10⁹, the consensus C = 10⁸)

who the fee
a payment of 10 POWM 0.000002 POWM
a payment of 0.5 POWM 0.000002 POWM
a small payment of 0.01 POWM 0.00001 POWM
a pool: 500 miners at 1 POWM each 0.0002 POWM
a pool: 500 miners at 0.1 POWM each 0.0005 POWM
a pool: 500 miners at 0.01 POWM each 0.005 POWM (it fits; while POWM is cheap, policy makes small payouts more expensive)
consolidating 1,000 rewards into one 0.0011 POWM (storage mass 0)
an attack like the one on Kaspa (1 → 238 × 0.0001 POWM) does not fit into a block

UTXO inflation if every block’s storage mass were filled for a whole year (the hard consensus cap C = 10⁸, which applies to a miner too):

the attacker’s budget coins per year disk
10,000 POWM 26 M 2.4 GB
100,000 POWM 82 M 7.5 GB
1,000,000 POWM 259 M 23.6 GB
today, with no limit ~1.5 billion ~143 GB, for ~690 POWM in fees

3b. Price scenarios (the consensus C = 10⁸, policy 10⁹ below $1, then 10⁸)

POWM price an ordinary payment a $1 payout (how many/block, the fee) a $20 payout an attack with 100k POWM (purchase + fees)
$0.001 ~$0 6,000, ~$0 6,000, ~$0 7.5 GB/year for ~$107
$0.1 ~$0 6,000, ~$0 6,000, ~$0 7.5 GB/year for ~$10,700
$10 ~$0 6,000, ~$0 6,000, ~$0 7.5 GB/year for ~$1 M
$100 $0.0002 2,560, $0.0001 6,000, ~$0 7.5 GB/year for ~$10 M
$1,000 $0.002 256, $0.01 5,120, $0.0005 7.5 GB/year for ~$100 M
$10,000 $0.02 25, $1 512, $0.05 7.5 GB/year for ~$1 bn

A miner with 10 % of the hashrate and 1 M POWM (paying the fees to themselves): ~2.4 GB/year. With a compact coin encoding (~45 B instead of 91 B) all the GB figures are roughly halved.

The weak spot: right after the launch, when POWM is worth fractions of a cent, 7.5 GB/year costs ~$100–1,000. It is mitigated by the fact that 100k POWM is ~13 % of the whole mined supply in the first month (hard to buy), that the attacker’s coins stay locked in their outputs, and that if it were abused, C can be tightened by a soft fork.

At a high price: above ~$1,000 lower the bottom rate (policy) — that needs a finer unit (e.g. thousandths of a cog per unit); above $1,000 pools raise their payout threshold (at $10,000 ~$20), which is common with Bitcoin too.

4. What changes where

Consensus (internal/chain) — StorageMass(tx, coins), the per-block Σ cap, tests (the KIP-9 examples and the boundaries included), fuzzing. The mempool and the template — the rate over max(bytes, storage_mass), the template respects both caps. The wallet and the RPC — computing the fee with the mass, the 1,000-input cap with splitting, consolidate, an optional fee, getfeeinfo; later opt-in RBF and CPFP. The explorer — the storage mass on a transaction. The documents — SPEC §2.3, AUDIT; a recommended payout threshold for pools.

5. Open

  1. C = 10⁸ in consensus, C_pol 10⁹ → 10⁸ in policy, a cap of 64,000 per block.
  2. The payout threshold for pools: up to $1,000/POWM $1 is enough, at $10,000 ~$20.
  3. A decentralized pool (POOL-SHARECHAIN) with 512 outputs in the coinbase — the coinbase is subject to R1, so small payouts in it are limited just the same.

Sources