• ABOUT

  • WHITEPAPER

  • DOCS

  • DISCORD

  • WALLET

  • EXPLORE

Etao

Subnets choose their emission split · Runtime v480 · October 2026

Two pie charts. Before Etao: 18% owner, 41% validators with root TAO stakers taking 5.4% of emission from that slot, 41% miners. With Etao, an SN4-style subnet lowers validators to 20% and raises miners to 62%; root's 5.4% slice is unchanged because the subnet's TAO weight moves from 18% to 43.9%.

Before Etao every subnet paid the same fixed split. With Etao the owner moves the dial — here an SN4-style subnet pays miners 62% instead of 41% — and root TAO stakers' slice of the pie does not move. Illustrative numbers.

Introduction

Etao hands every subnet owner the dial that has been welded shut since launch: how the subnet's alpha emission is divided. Until now every subnet paid the same split — 18% to the owner, 41% to validators, 41% to miners. From spec 480 a subnet that lives on its miners can pay them 62%. A subnet that needs deep validation can push validators to the 50% cap. An owner who wants to signal commitment can set their own cut to zero.

One extrinsic, one rate limit, five rules, and a guarantee underneath all of it: root TAO stakers are paid exactly what they would be on an untouched subnet, whatever the owner picks. The guarantee is not a promise; it is arithmetic the chain runs at every change.

Etao ships to mainnet as a sudo runtime upgrade from main. Payouts in the first post-upgrade block are identical to the last pre-upgrade block; nothing moves until an owner moves it. The complete, standalone release note — every rule, error, storage item and worked CLI example — is the Etao release guide.

Why

Subnets are not alike. Some are miner-heavy compute markets where validation is cheap and the scarce resource is miner effort. Some are judgment-heavy and need validators to spend real money to score work. Some are owner-run products where the owner cut funds the team; others want that cut gone so every token flows to participants. A single fixed split cannot serve all of them, and until now the only knob — the owner cut — was a global sudo setting, the same for every subnet.

The obstacle to letting owners move the validator share was root. Root TAO stakers are paid from the validator slot of every subnet. Cut that slot from 41% to 20% and, with nothing else changing, root's income from the subnet would halve: owners could tax a network-wide stakeholder to pay their own participants. Etao removes that coupling. The validator slot becomes a choice about validators, and root's payout is pinned to a baseline the owner cannot move.

The emission weight vector

Every subnet now carries a five-slot vector [burn, recycle, owner, validator, miner]. Each slot is a u64 share of u64::MAX, so the five slots sum to exactly one with no rounding dust. Per block, alpha_out × owner accrues to the owner, alpha_out × validator to the validator bucket and alpha_out × miner to the miner bucket.

SlotPaid toRule in v1
burnnothing — alpha is destroyedmust be 0 (reserved)
recyclenothing — alpha returns to the unissued poolmust be 0 (reserved)
ownerthe subnet owner's hotkey0% to 33%; lease-created subnets at least 18%
validatorvalidator dividends (root TAO stakers are paid from this slot)at most 50%, and high enough that root's baseline share is reachable
minerminer incentiveat least 33%

The setter is AdminUtils.sudo_set_subnet_emission_weights(netuid, uids, values). It is sparse: name the slots you want to change and their new shares; the others keep their value. The merged vector must pass every rule, and each rule has its own error so a rejection names the constraint. Callers are the subnet owner coldkey or root. Owners may change a subnet's vector once every 50,400 blocks (about seven days). The limit is keyed by subnet, not by coldkey, so handing a subnet to a new owner does not reset it; a subnet's first change is free, and root is exempt.

How root stays whole

Root TAO is weighted against alpha by a TAO weight w. Each block, the alpha root stakers receive from a subnet is

root_alpha = V × x / (x + A) × alpha_out        with x = root_tao × w

where V is the validator slot and A the subnet's alpha issuance. Before Etao, w was the single global TaoWeight and V was fixed everywhere.

Etao gives every subnet its own effective TAO weight w_s (SubnetTaoWeight), used on the consensus side of that subnet only: the root share carved out of the validator slot, the TAO-versus-alpha split of validator dividends, and the stake weighting inside Yuma Consensus. Every accepted set call solves w_s once, at that block, from live chain values and the new validator slot alone:

# 1. root's baseline share of this subnet's emission
r     = V0 × x_g / (x_g + A)      x_g = root_tao × TaoWeight (global)
                                   V0  = validator share of the default vector (0.41)

# 2. the weight that pays r under the new validator slot
x_new = r × A / (V_new − r)
w_s   = x_new / root_tao

# rejected with ValidatorEmissionTooLowToPreserveRoot if V_new ≤ r or w_s > 1
# equivalently, the validator floor at this block is
V_min = r × (1 + A / root_tao)

So the block after any change, root TAO stakers earn from the subnet exactly what an untouched subnet would pay them at that block. Lowering V raises w_s; raising V lowers it; the alpha root receives does not move. Two properties follow from anchoring to a fresh baseline rather than to root's current share:

  • No ratchet. The solve never reads the old vector or the old w_s. An owner who raises V while the subnet is young and lowers it after issuance grows — or the reverse — ends up with the same w_s and the same root share as an owner who made the final change in one step. Root's payout is a function of the chain's state, not of the owner's history.
  • Back to default means back to global. Setting V to exactly V0 clears the per-subnet entry, so the subnet follows the global TaoWeight again. A subnet that has never changed its validator share has no entry at all.

Between sets w_s is frozen — never recomputed per block. The weight is capped at one (root TAO never counts more than 1:1 against alpha), so not every V is reachable: on a mainnet subnet with 5.44M TAO on root, 6.46M alpha issued and TaoWeight = 0.18, root's baseline is about 5.4% of emission and the validator slot can go down to about 11.8%. The floor moves with root stake, issuance and the global weight, so btcli subnets emission show prints the live value and every write checks it locally before anything is signed.

What does not change. The pool side never sees w_s. tao_in, alpha_in, the alpha-injection cap and RootProp use the global TaoWeight, exactly as before. Changing a subnet's vector changes how its alpha is distributed; it does not change how much TAO or alpha is injected into its pool, prices, swaps, or the emission the subnet receives.

Migration and compatibility

The upgrade runs one migration, seed_subnet_emission_weights_v1, which seeds every live subnet from its legacy owner-cut state so that the first post-upgrade block pays out exactly what the last pre-upgrade block did:

  • owner is the legacy SubnetOwnerCut when OwnerCutEnabled was true, else 0; validator is half the remainder; miner is what is left, absorbing the rounding ulp.
  • No SubnetTaoWeight entry is written, so every subnet keeps following the global TaoWeight until its owner changes the vector.
  • SubnetCreatedViaLease is set for subnets with a live lease mapping, and SubnetOwnerCutAccrued is seeded to the exact deduction the legacy lock refund applied — including subnets already mid-dissolution — so no refund changes.

New subnets are seeded with the default vector [0, 0, 18%, 41%, 41%]. Dissolving a subnet clears its vector, weight, lease marker, accrued owner cut and rate-limit key, so a reused netuid starts clean.

Deprecated extrinsics. sudo_set_subnet_owner_cut and sudo_set_owner_cut_enabled keep their call indices and signatures but always return Deprecated. Set the owner slot — including to zero — through sudo_set_subnet_emission_weights instead. SubnetOwnerCut and OwnerCutEnabled remain readable as legacy views but are no longer written.

New chain surface

  • Storage: SubnetEmissionWeights (the vector), SubnetTaoWeight (Option<u64>; absent = follows global), SubnetCreatedViaLease, SubnetOwnerCutAccrued.
  • Event: SubtensorModule.SubnetEmissionWeightsSet { netuid, weights } with the full post-merge vector.
  • Rate limit: OwnerHyperparamUpdate(Hyperparameter::EmissionWeights) keyed by subnet in LastRateLimitedBlock; constant SubnetEmissionWeightsRateLimit = 50_400.
  • Runtime API: SubnetInfoRuntimeApi.get_subnet_emission_weights(netuid) (API version 3); get_subnet_hyperparams_v3 adds owner_emission, validator_emission and miner_emission.
  • EVM (subnet precompile, index 2051): setSubnetEmissionWeights(netuid, uids, values) and getSubnetEmissionWeights(netuid) returning the vector and the lease flag.
  • Python SDK: the subnet_emission_weights read (vector, shares, effective and global TAO weight, root's current and baseline share, the live validator floor, rate-limit state), the SetSubnetEmissionWeights intent with a structured before/after preview, and the pure rules module bittensor.emission_weights.
  • CLI: btcli subnets emission with show, set, set-value, increase and decrease; --json and --dry-run everywhere; fixed exit codes (0 done, 1 missing subnet or blocked, 2 rule violation).

For subnet owners

Look before you touch. The Allowed table is live for this block:

btcli subnets emission show --netuid 4

Vector
      owner  18.00%
  validator  41.00%
      miner  41.00%

Root
  root share of emission  5.4015%
     root baseline share  5.4015%
    effective tao weight  18.00%      follows the global TaoWeight (18.00%)
       next owner change  now         first change; owners may change once per 50,400 blocks

Allowed
      owner  0.00% to 33.00%
  validator  11.8093% to 50.0000%   the floor is where root's baseline share needs a TAO weight of 100%
      miner  >= 33.00%

Preview with --dry-run; the plan shows the before/after vector, root's share before and after, and the TAO weight move:

btcli subnets emission set --netuid 4 --owner 18% --validator 20% --miner 62% --dry-run

dry run: set emission weights on netuid 4: owner=18.00% validator=20.00% miner=62.00%
  effect  vector: owner 18.00% / validator 41.00% / miner 41.00% -> owner 18.00% / validator 20.00% / miner 62.00%
  effect  root earns 5.4015% of this subnet's emission now and 5.4015% after (its baseline:
          default validator share, global TaoWeight); the subnet's TAO weight moves 18.00% -> 43.89%

Then drop --dry-run, or nudge one slot at a time:

btcli subnets emission increase  --netuid 4 --slot miner --by 5%
btcli subnets emission decrease  --netuid 4 --slot owner --by 0.02
btcli subnets emission set-value --netuid 4 --slot owner --value 0    # owner cut off

A rejected vector exits 2 before anything is signed and names the rule and the allowed range:

error: the chain would reject this change: ValidatorEmissionTooLowToPreserveRoot: validator (slot 3)
       is 5.0000%; ... right now the validator share must be at least about 11.8093%
  note: allowed on subnet 4 right now: validator 11.8093% to 50.0000%
  help: btcli subnets emission show --netuid 4 prints the vector and every allowed range

Notes by role

  • Validators. Your dividends come from the validator slot. Where an owner lowers it, the alpha paid to validators and their alpha stakers goes down and the subnet's effective TAO weight goes up, tilting the TAO-versus-alpha split of dividends toward TAO stakers. The floor guarantees the slot can never starve root; nothing guarantees it stays at 41%. Watch SubnetEmissionWeightsSet events.
  • Miners. The miner slot is at least 33% and can grow to whatever is left after the owner slot and the validator floor. Weight setting, incentive and the epoch are unchanged; only the size of the bucket moves.
  • Root TAO stakers. Your share of every subnet's emission is pinned to its baseline at every change the owner makes, and it cannot be moved by sequencing changes. The global TaoWeight remains the governance lever over root's weight.
  • Subnet owners. One change per week per subnet; the first is free of the limit. Lease-created subnets cannot drop the owner slot below 18%. Every btcli write validates locally and shows the exact floor, so test with --dry-run first.
  • Integrators. Read the vector through the runtime API or the SDK read; treat SubnetOwnerCut / OwnerCutEnabled as legacy views; expect SubnetEmissionWeightsSet events and Deprecated from the two retired extrinsics.

Release details

Runtime spec_version 480, transaction_version unchanged. Delivered to mainnet as a sudo runtime upgrade from main. Migration seed_subnet_emission_weights_v1, idempotent. Reference pages: Etao release guide (the complete standalone note), Emission weights (the concept page), set-subnet-emission-weights, subnet-emission-weights, validator_emission, and the source in emission_weights.rs.