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

Each subnet owner sets how the subnet's alpha emission is split between owner, validators and miners, while root TAO stakers keep their baseline share.

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

_Last reviewed: 2026-10-16_

> [!WARNING]
> **Not live on mainnet yet**
>
> eTao ships in runtime **spec 480** ([subtensor PR #3254](https://github.com/RaoFoundation/subtensor/pull/3254), merged 2026-10-15). Finney runs spec 479. At the upgrade every subnet keeps the split it has today until its owner changes it.

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

## The short version

- Today every subnet splits its `alpha_out` the same way: **18% owner, 41% validators, 41% miners**.
- With eTao, each subnet owner chooses the subnet's own split, within fixed limits.
- **Root TAO stakers keep earning what they earn now.** The chain adjusts the subnet's TAO weight so root's share stays at its baseline.
- 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 and alpha stakers both earn from it. |
| TAO weight | How much one root TAO counts against one alpha when the validator share is divided. The network-wide value is `TaoWeight`, set by root. |
| Subnet TAO weight | A subnet's own TAO weight (`SubnetTaoWeight`). It exists only on a subnet whose owner has moved the validator share away from 41%. Otherwise the subnet uses the network-wide `TaoWeight`. |
| 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 at least the subnet's live **validator floor** (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 now 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` now fail with `Deprecated`. Set the owner slot through `sudo_set_subnet_emission_weights` instead.

With btcli:

```bash
btcli subnets emission show --netuid 4                     # current split, live 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 stays level

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

Each block, root's share of a subnet's emission is:

$$
\text{root share} = V \times \frac{x}{x + A}, \qquad x = \text{root TAO} \times w
$$

where $V$ is the validator share, $A$ the subnet's alpha issuance and $w$ the TAO weight.

Every time a change is accepted, the chain:

1. **Works out root's baseline** from live chain state: what root would earn on this subnet right now with the default 41% validator share and the network-wide `TaoWeight`.
   $$
   r = 0.41 \times \frac{x_g}{x_g + A}, \qquad x_g = \text{root TAO} \times \text{TaoWeight}
   $$
2. **Solves the subnet TAO weight** that pays root exactly $r$ under the new validator share, and stores it in `SubnetTaoWeight`:
   $$
   w_s = \frac{r \times A}{(V_{new} - r) \times \text{root TAO}}
   $$

Lowering the validator share raises the subnet's TAO weight, and raising it lowers the weight. Root's alpha from the subnet does not move.

- **No ratchet.** The baseline uses only chain state at that block, never the old split or the old subnet TAO weight. Changing the split in several steps ends in the same place as one change.
- **Frozen between changes.** The subnet TAO weight is computed only when a change is accepted, not every block. Until the next change it does not follow later changes to the network-wide `TaoWeight`.
- **Back to 41% means back to the network-wide weight.** Setting the validator share to exactly 41% removes the `SubnetTaoWeight` entry.
- **Where it applies.** The subnet TAO weight is used on the consensus side only: root's portion of the validator share, the root/alpha dividend split, parent/child contributions and stake weighting in consensus. Pool injection keeps using the network-wide `TaoWeight`.

### The validator floor

The subnet TAO weight is capped at 100%: one root TAO never counts as more than one alpha. That puts a floor under the validator share:

$$
V_{min} = r \times \left(1 + \frac{A}{\text{root TAO}}\right)
$$

Below the floor, the chain rejects the change with `ValidatorEmissionTooLowToPreserveRoot`. 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, and the validator floor is about **11.81%**. If the owner sets 18 / 20 / 62, the subnet TAO weight moves from 18% to about 43.9%, and root still earns 5.40%.

### Who pays

Root's slice is fixed, so a cut to the validator share comes out of **alpha stakers**, and the difference goes to miners and/or the owner. Alpha stakers can't be cut to zero: at the floor, alpha stakers' share is root's share × (alpha issuance ÷ root TAO).

## By role

- **Validators and alpha stakers.** Dividends come from the validator share, which is no longer fixed at 41%. On a subnet whose owner lowers it, alpha dividends go down and the TAO-staker portion of each validator's dividends goes up. Watch for `SubnetEmissionWeightsSet` events on the subnets you validate or stake on.
- **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.** Your share of each subnet's emission is reset to its baseline whenever its owner changes the split.
- **Subnet owners.** One change per week per subnet, and the first one is free of the limit. Preview with `--dry-run` first.

## New chain data

| Item | What it holds |
|---|---|
| `SubnetEmissionWeights` (storage) | The subnet's five-slot split. |
| `SubnetTaoWeight` (storage) | The subnet TAO weight. No entry means the subnet uses `TaoWeight`. |
| `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, the subnet TAO weight in effect 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` copies each subnet's current owner-cut setting into its new split, so the first block after the upgrade pays exactly what the last block before it did:

- owner slot = the subnet's current owner cut (0% if the owner cut is switched off);
- validator and miner slots = half of the rest each;
- no `SubnetTaoWeight` entry, so every subnet follows the network-wide `TaoWeight`;
- `SubnetCreatedViaLease` set for subnets with a live lease.

## Sources

- [subtensor PR #3254](https://github.com/RaoFoundation/subtensor/pull/3254) and `docs/guides/etao.mdx` in RaoFoundation/subtensor.
- Code: `pallets/subtensor/src/subnets/emission_weights.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`.
