Allocation
The exact rule a validator uses to place coloured value into outputs, with executed vectors for every case.
Protocol behavior Verified 2026-08-31
Describes the Atomicals protocol itself at the pinned reference revision. It does not promise that any product exposes it.
- Page ID
-
protocol/arc20/allocation - Normative authority
- Executed source code at a pinned revision
- Networks
- mainnet
- Documentation version
- 2026.08
- Activation boundary
- Custom coloring with the z operation is activation gated. Normal allocation is not.
- Audience
- developer, creator, holder
- Owner
- bitcoin-universe-docs
- Sources
-
- Atomicals ElectrumX
at
v1.5.2.0assign_expected_outputs_basic and calculate_outputs_to_color_for_ft_atomical_ids - Atomicals ElectrumX
at
v1.5.2.0
- Atomicals ElectrumX
at
- Known limitations
-
- The engine behind these vectors models normal allocation. It is explanatory and never a substitute for validating a concrete transaction against your target validator revision.
此内容尚不支持你的语言。
Allocation is the single most important rule in ARC-20. It decides which output receives which units, and what is destroyed.
The rule
Section titled “The rule”- Collect the coloured value carried by the transaction’s inputs, summed per token.
- Order the tokens. FIFO ordering uses the first input index that carries each token, then the Atomical ID. Legacy ordering uses the Atomical ID alone.
- For each token in that order, walk the outputs starting at the first slot not already used.
- Skip provably unspendable outputs entirely. They consume nothing.
- Assign an output only if its whole satoshi value fits in the value still to place.
- If it fits, that output is coloured for its full satoshi value, and the remaining value drops by that amount.
- If the next output does not fit, stop. Whatever is left is burned.
- If any token could not be placed cleanly, the builder discards the sequential plan and restarts every token from output zero.
- Coloured output totals can never exceed coloured input totals.
The allocation loop
For each token in order, the validator holds a running remaining value and walks the outputs from the first unused slot. Unspendable outputs are skipped without consuming anything. If the current output value is less than or equal to the remaining value, the output is coloured for its full satoshi value and the remaining value drops. If it is larger, the loop stops and whatever remains is burned. If the whole plan could not be made cleanly, every token restarts from output zero.
What “fits” means, precisely
Section titled “What “fits” means, precisely”An output fits when output.value <= remaining. Nothing is ever partially filled under normal
allocation. An output either takes its full satoshi value in units, or it takes nothing.
How coloured value is destroyed
A coloured input of 1200 satoshis is spent. Output zero is 700 satoshis and receives 700 units. The next eligible output is 546 satoshis, which is larger than the 500 units still to place, so it receives nothing and those 500 units are recorded as burned. The Bitcoin transaction is valid and confirms. Making output one 500 satoshis instead would have placed all the value cleanly.
Executed vectors
Section titled “Executed vectors”Every row below is computed at build time by the same engine the conformance tests run. The numbers on this page cannot drift from the vector set.
| Case | Coloured inputs | Result per output | Burned | Clean |
|---|---|---|---|---|
Clean split into two outputs clean-split | 1200 units at input 0 | out 0: 700 sats to 700 units; out 1: 500 sats to 500 units | none | yes |
Oversized next output burns the remainder oversized-next-output | 1200 units at input 0 | out 0: 700 sats to 700 units; out 1: 546 sats to 0 units | 500 units of TOKENA | no |
Whole lot into one output exact-single-output | 10000 units at input 0 | out 0: 10000 sats to 10000 units | none | yes |
First output larger than the whole lot first-output-too-large | 500 units at input 0 | out 0: 20000 sats to 0 units | 500 units of TOKENA | no |
Outputs run out before the value does too-few-outputs | 1200 units at input 0 | out 0: 700 sats to 700 units | 500 units of TOKENA | no |
Unspendable outputs are skipped, not funded unspendable-output-skipped | 1200 units at input 0 | out 0: 0 sats (unspendable) to 0 units; out 1: 700 sats to 700 units; out 2: 500 sats to 500 units | none | yes |
Combining two lots of the same token combine-two-lots | 700 units at input 0, 500 units at input 1 | out 0: 1200 sats to 1200 units | none | yes |
Two different tokens take sequential output slots two-tokens-sequential-slots | 700 units at input 0, 900 units at input 1 | out 0: 700 sats to 700 units; out 1: 900 sats to 900 units | none | yes |
A non-clean slot triggers the output zero fallback two-tokens-non-clean-fallback | 700 units at input 0, 400 units at input 1 | out 0: 700 sats to 700 units; out 1: 546 sats to 0 units | 400 units of TOKENB | no |
A remainder smaller than the change output burns dust-remainder-burns | 1200 units at input 0 | out 0: 1000 sats to 1000 units; out 1: 200 sats to 200 units | none | yes |
A change output larger than the remainder burns it change-output-too-large | 1200 units at input 0 | out 0: 1000 sats to 1000 units; out 1: 546 sats to 0 units | 200 units of TOKENA | no |
Custom coloring assigns a partial value to the last output custom-coloring-partial-fill | 1200 units at input 0 | out 0: 700 sats to 700 units; out 1: 546 sats to 500 units | none | no |
Exact single output, exact-cover era suite-exact-single-output | 11000 units at input 0 | out 0: 11000 sats to 11000 units | none | yes |
Partially coloured output, current era suite-partially-colored-carry-forward | 500 units at input 0 | out 0: 11000 sats to 500 units | none | no |
Eleven inputs consolidated into one small output suite-consolidation-burn | 1000 units at input 0, 1000 units at input 1, 1000 units at input 2, 1000 units at input 3, 1000 units at input 4, 1000 units at input 5, 1000 units at input 6, 1000 units at input 7, 1000 units at input 8, 1000 units at input 9, 1000 units at input 10 | out 0: 1000 sats to 1000 units | 10000 units of TOKENA | no |
One satoshi short destroys the whole balance suite-output-over-balance | 10999 units at input 0 | out 0: 11000 sats to 0 units | 10999 units of TOKENA | no |
One unit over the output value burns that unit suite-one-unit-over | 11001 units at input 0 | out 0: 11000 sats to 11000 units | 1 units of TOKENA | no |
Two lots merged into one output, one unit as fee suite-merged-inputs-single-output | 900 units at input 0, 555 units at input 1 | out 0: 1454 sats to 1454 units | 1 units of TOKENA | no |
A transaction carrying no tokens suite-no-atomicals | out 0: 1000 sats to 0 units | none | yes | |
Paying the fee out of coloured value burns it fee-taken-from-colored-value | 10000 units at input 0 | out 0: 3000 sats to 3000 units; out 1: 6800 sats to 6800 units | 200 units of TOKENA | no |
No output able to take colour only-unspendable-outputs | 5000 units at input 0 | out 0: 0 sats (unspendable) to 0 units | 5000 units of TOKENA | no |
Split skips a satoshi amount before colouring split-skip-amount | 3000 units at input 0 | out 0: 1000 sats to 0 units; out 1: 2000 sats to 2000 units | 1000 units of TOKENA | no |
Custom colouring clamps an over-request custom-color-over-request-clamped | 1000 units at input 0, 1000 units at input 0 | out 0: 1200 sats to 1000 units; out 1: 600 sats to 600 units; out 2: 600 sats to 400 units | none | no |
Custom colouring burns what the payload does not place custom-color-unassigned-value-burns | 1000 units at input 0 | out 0: 1000 sats to 400 units; out 1: 500 sats to 0 units | 600 units of TOKENA | no |
The vector set lives at conformance/vectors/arc20-allocation.json and its engine at
conformance/allocation.mjs. See conformance.
The output zero fallback
Section titled “The output zero fallback”Step eight surprises people. When the sequential plan cannot place a token cleanly, the reference builder throws away the whole plan and restarts every token from output zero. With more than one token in the transaction, that can move value you thought was settled and can burn a token that would otherwise have been fine.
The two-tokens-non-clean-fallback vector above shows it. Build transactions that never trigger
it.
No inflation
Section titled “No inflation”Coloured output totals can never exceed coloured input totals. A blueprint that tries is rejected. This is the one rule that cannot be worked around by output arrangement.
What changes the result
Section titled “What changes the result”| Input | Effect |
|---|---|
| Coloured input value | The total to place |
| Input order | Token ordering under FIFO |
| Output order | Which slot is considered next |
| Output satoshi values | Whether each output fits |
| Unspendable outputs | Skipped, consuming nothing |
| Active rule set | Whether custom coloring applies |
| Number of distinct tokens | Whether the fallback can trigger |