# eTao: per-subnet emission split (spec 481)

Each subnet owner sets how the subnet's alpha emission is split between owner, validators and miners. Root TAO stakers are paid their baseline share off the top of the validator share every block.

_Source: https://taostats.io/docs/concepts/protocol-changes/etao_

_Last reviewed: 2026-10-19_

> [!NOTE]
> **Live on mainnet (spec 481)**
>
> eTao is live on Finney from block **9,319,003** (2026-10-19 17:24:12 UTC), runtime spec **481**. The live runtime matches the published `v481` release build.

[eTao explained: interactive split simulator and per-subnet validator floors](https://s3.hippius.com/rufus/public/etao-explained.html)

## The short version

- The default split of a subnet's `alpha_out` is **18% owner, 41% validators, 41% miners**.
- Each subnet owner can choose a different split for their subnet, within fixed limits.
- **Root TAO stakers are paid their baseline share first.** Every block, root takes what it would earn on the subnet with the default split, off the top of the validator share. Alpha validators share the rest.
- A cut to the validator share comes out of **alpha stakers' dividends** and goes to miners and/or the owner.
- The pool side does not change: how much TAO and alpha is injected into a subnet's pool, prices and swaps are unaffected.

## Terms

| Term | Meaning |
|---|---|
| Emission weights | A subnet's five-slot split `[burn, recycle, owner, validator, miner]`. The slots add up to exactly 100%. |
| Validator share | Paid as dividends. Root TAO stakers are paid from it first, then alpha stakers. |
| TAO weight | How much one root TAO counts against one alpha. One network-wide value, `TaoWeight` (0.18), set by root. |
| Root baseline share | What root TAO stakers would earn from the subnet right now with the default 41% validator share. Recomputed every block. |
| Alpha issuance | All of the subnet's alpha: `SubnetAlphaIn` (pool) + `SubnetAlphaOut` (held and staked) + the protocol alpha reservoir. |

## The limits

| Slot | Default | Allowed |
|---|---|---|
| Owner | 18% | 0% to 33%. Lease subnets: at least 18%. |
| Validator | 41% | At most 50%, and above the subnet's live **root baseline share** (see below). |
| Miner | 41% | At least 33%. |
| Burn | 0% | Must be 0%. Reserved for a later runtime. |
| Recycle | 0% | Must be 0%. Reserved for a later runtime. |

- **Lease subnets.** A subnet registered through a crowdloan lease keeps the owner slot at 18% or more, so lease contributors' dividends cannot be cut below launch terms. The flag (`SubnetCreatedViaLease`) stays on after the lease ends.
- **Owner slot at 0%** turns the owner cut off. `owner_cut_enabled` is read-only: it is true when the owner slot is above 0%. The owner-cut auto-lock setting still applies to whatever the owner slot pays.
- **New subnets** start on 18 / 41 / 41.

## Setting the split

The subnet owner (or root) calls:

```
AdminUtils.sudo_set_subnet_emission_weights(netuid, uids, values)
```

- **Sparse update.** `uids` names slots (0 burn, 1 recycle, 2 owner, 3 validator, 4 miner) and `values` gives each new share as parts of `u64::MAX`. Owner, validator and miner slots that are not named keep their value. Lowering one slot means raising another in the same call, because the five must sum to exactly one.
- **Rate limit.** An owner can change a subnet's split once every **50,400 blocks** (about 7 days). The first change on a subnet is never rate-limited. The limit belongs to the subnet, so a new owner does not get a fresh window. Root is exempt.
- **Admin freeze window.** Both owner and root calls respect it, like other hyperparameter changes.
- **Errors.** Each rule has its own error, so a rejected call names the rule it broke: `OwnerEmissionAboveMaximum`, `LeasedSubnetOwnerCutBelowMinimum`, `ValidatorEmissionAboveMaximum`, `ValidatorEmissionTooLowToPreserveRoot`, `MinerEmissionBelowMinimum`, `BurnEmissionMustBeZero`, `RecycleEmissionMustBeZero`, `EmissionWeightsDoNotSumToOne`, `EmissionWeightsNotSettableOnRoot`.

`sudo_set_subnet_owner_cut` and `sudo_set_owner_cut_enabled` fail with `Deprecated`. Set the owner slot through `sudo_set_subnet_emission_weights` instead.

With btcli:

```bash
btcli subnets emission show --netuid 4                     # split, root's baseline and paid share, validator floor, next allowed change
btcli subnets emission set --netuid 4 --owner 18% --validator 20% --miner 62% --dry-run
btcli subnets emission set-value --netuid 4 --slot owner --value 0      # turn the owner cut off
```

`set-value` changes one slot and rescales the other two in their current ratio. `set` writes the full split. `--dry-run` previews the change without signing.

## How root is paid

Root TAO stakers are paid out of the validator share. Without a rule, an owner who cut the validator share from 41% to 20% would roughly halve root's income from that subnet. eTao pays root first instead.

Every block, for every subnet, the chain computes root's **baseline share** from live chain state:

$$
r = 0.41 \times \frac{x}{x + A}, \qquad x = \text{root TAO} \times \text{TaoWeight}
$$

where $A$ is the subnet's alpha issuance and 0.41 is the default validator share. Root is then paid

$$
\text{root alpha} = \min(V, r) \times \text{alpha\_out}
$$

off the top of the validator share $V$, and alpha validators share the rest, $(V - \min(V, r)) \times \text{alpha\_out}$. The owner and miner shares are not touched.

- **The owner cannot move root's payout.** Lowering the validator share from 41% to 20% takes all 21 points from alpha validators. Raising it pays only alpha validators more.
- **It tracks live state.** Because $r$ is recomputed every block, root's payout follows root stake, alpha issuance and `TaoWeight` with no call from anyone. A subnet on the default split pays root exactly the formula at 41%.
- **Everything else uses the global `TaoWeight`.** Stake weighting in consensus, the TAO/alpha split of validator dividends, parent/child contributions and pool injection all use the one network-wide value. There is no per-subnet TAO weight.

### The validator floor

The chain rejects a change with `ValidatorEmissionTooLowToPreserveRoot` when the new validator share is **at or below root's baseline share**, because alpha validators would get nothing. The floor is $r$ itself: the lowest accepted value is one part above it. With no root stake there is nothing to protect and any positive validator share is accepted.

The floor is different on every subnet and moves with root stake, the subnet's alpha issuance and `TaoWeight`. `btcli subnets emission show` prints the live value.

**Worked example (SN4, illustrative).** With about 5.44M TAO on root, about 6.46M alpha issued on SN4 and `TaoWeight` at 18%, root's baseline is about **5.40%** of SN4's emission, so the validator share can go down to anything above 5.40%. If the owner sets 18 / 20 / 62, root still earns 5.40% and alpha validators get 14.60% (down from 35.60%).

### The capped case

The floor is checked only when the split is set. The baseline keeps moving afterwards. If a subnet sets its validator share just above today's $r$ and $r$ later grows past it (root stake rises, issuance falls, or root raises `TaoWeight`), root's payout is **capped at the whole validator share**: root gets $V \times \text{alpha\_out}$ and alpha validators get **nothing** until the owner raises $V$. Root is exempt from the rate limit, so governance can fix a stuck subnet at once. The runtime API and `btcli subnets emission show` report both the baseline and the share actually paid, so a capped subnet is visible.

### Who pays

Root's slice is set by the baseline, so a cut to the validator share comes out of **alpha stakers**, and the difference goes to miners and/or the owner. The closer the validator share is to the floor, the closer alpha stakers' share is to zero.

## By role

- **Validators and alpha stakers.** Dividends come from what is left of the validator share after root's baseline. On a subnet whose owner lowers it, alpha dividends go down; root's slice does not move. Watch for `SubnetEmissionWeightsSet` events, and for subnets whose validator share has fallen to root's baseline (capped: alpha validators earn nothing there).
- **Miners.** The miner share is at least 33% and can grow to whatever is left after the owner share and the validator floor. Weight setting and incentive work as before; only the size of the miner bucket changes.
- **Root stakers.** On every subnet you are paid its baseline share, recomputed every block, before alpha validators see anything. Owners cannot move it. The only cap is the validator share itself.
- **Subnet owners.** One change per week per subnet, and the first one is free of the limit. Preview with `--dry-run` first, and leave headroom above the floor so the subnet does not become capped as the baseline moves.

## Chain data

| Item | What it holds |
|---|---|
| `SubnetEmissionWeights` (storage) | The subnet's five-slot split. |
| `SubnetCreatedViaLease` (storage) | True for subnets registered through a lease (owner floor 18%). |
| `SubnetOwnerCutAccrued` (storage) | Owner-cut alpha paid out so far. Deducted from the lock refund when the subnet dissolves. |
| `SubnetEmissionWeightsSet` (event) | `{ netuid, weights }` with the full split after a change. |
| `get_subnet_emission_weights` (runtime API) | The split, `root_baseline_share` (`r`), `root_share` (`min(V, r)`, what root is actually paid) and the lease flag. |

`get_subnet_hyperparams_v3` also reports `owner_emission`, `validator_emission` and `miner_emission`. `SubnetOwnerCut` and `OwnerCutEnabled` are kept as legacy read-only views.

## At the upgrade

The migration `seed_subnet_emission_weights_v1` copied each subnet's owner-cut setting into its new split:

- owner slot = the subnet's owner cut (0% if the owner cut was switched off);
- validator and miner slots = half of the rest each;
- `SubnetCreatedViaLease` set for subnets with a live lease.

127 of 128 subnets were seeded at 18 / 41 / 41 and pay exactly what they paid before the upgrade. **SN74**, whose owner cut was switched off, was seeded at **0 / 50 / 50**. Root is paid the 41% baseline there, not a share of 50%, so root's alpha from SN74 is about 18% lower than before the upgrade and SN74's alpha validators receive the difference.

## Sources

- [subtensor PR #3254](https://github.com/RaoFoundation/subtensor/pull/3254) (the split), [PR #3264](https://github.com/RaoFoundation/subtensor/pull/3264) (root paid off the top), and `docs/guides/etao.mdx` in RaoFoundation/subtensor.
- Code: `pallets/subtensor/src/subnets/emission_weights.rs`, `pallets/subtensor/src/coinbase/run_coinbase.rs`, `pallets/admin-utils/src/lib.rs` (`sudo_set_subnet_emission_weights`, call index 114), `pallets/subtensor/src/migrations/migrate_seed_subnet_emission_weights.rs`.
- Chain: Finney spec 481 from block 9,319,003; `SubnetEmissionWeights` and `TaoWeight` read on 2026-10-19.

> [!NOTE]
> **Previously**
>
> Runtime spec 480 (testnet only, never enacted on mainnet) kept root level by storing a per-subnet TAO weight (`SubnetTaoWeight`) at each split change. Spec 481 replaced it with the per-block baseline above and deleted the storage item. Mainnet went from 479 straight to 481.
