Guides

Root Reborn

Validator baskets — why root yield stopped being force-sold, how the fund works, and the btcli commands to allocate, trade, and claim.

View as Markdown

Root Reborn (runtime v441) turns the root network from a passive dividend pipe into a competitive allocation layer. Root stake's yield used to be sold to TAO mechanically, every block, the moment it arrived. Now it accumulates in baskets — per-validator, escrowed index funds of subnet alpha, held where they were earned and reshaped only by each validator's trades — and is realized only when a staker claims.

The share unit of a basket is a beta token: a stable count that grows with accruals and shrinks on claim, while its TAO value moves with the holdings. Beta tokens covers the representation, the owed formula, and the raw-versus-display scale.

This replaces the old per-subnet claimable system and retires set_root_claim_type. The claim_root(subnets) call keeps its SCALE signature for old clients, but subnets is ignored and the call claims fund-level across every validator; prefer claim-root-with-hotkey for a single validator. Root staking itself is unchanged: moving TAO in and out of root stake is not a pool swap — no fee, no slippage, no MEV exposure. For the thesis and live network numbers, see the v441 release notes.

Why it exists

TAO is a productive asset. The chain provides liquidity to its subnets and takes a share of each one's token emission back — the root proportion, paid in subnet alpha to root (netuid 0) stakers. Before v441 the protocol sold that alpha for TAO on arrival, which had three structural costs:

  • Constant sell pressure. Every subnet token absorbed a mechanical, price-insensitive sell stream, distorting price discovery.
  • Burned option value. Ownership in early-stage subnets was converted to short-term TAO flow on a schedule nobody chose.
  • Forced realization. Stakers received a continuous stream of taxable events they could not defer.

Off-chain validator "basket" products already reinvested root yield and outperformed the passive path — proving demand, but as manual, fee-bearing, non-comparable one-offs. Root Reborn makes the mechanism native, standardized, and competitive.

How the fund works

Each root validator runs a single fund. Every epoch, its root alpha dividend on each subnet is credited straight into the fund's holding on that subnet — no sell, no redeploy, no target vector. The validator reshapes the fund only by trading one holding for another with swap-basket. Root stakers accrue an entitlement to the fund in proportion to their root stake; a claim pays it out as TAO staked back to root.

  • Holdings are real stake. Positions are ordinary stake entries held by a chain-owned escrow account (a pallet sub-account with no private key — it cannot act, sign, or be stolen). Because they are real stake on the validator, they keep compounding with the validator's own dividends.
  • Entitlement is a fund fraction, never specific alpha. A staker's claim is a fraction of the whole fund, not of any particular subnet position. That decoupling lets holdings be rebalanced — or converted to TAO when a subnet dissolves — without touching anyone's entitlement.
  • NAV is realizable, not spot. The fund is valued at what selling its holdings would actually fetch at current pool depth, net of fees. A thin pool cannot inflate book value; deposit pricing and redemption sizing use the same quote.
  • Deposits price at NAV. New dividends and direct deposits enter at the fund's pre-deposit value, so existing holders are neither diluted nor gifted, and each deposit bears its own swap slippage.
  • Claims are proportional. A claim redeems the staker's owed fraction of every holding pro-rata, preserving fund composition.
  • Inflows never change composition. Dividends accumulate in place: each subnet's dividend is credited into the fund's holding on that subnet. The protocol executes zero trades (no swap fees, no slippage, no mechanical sell pressure), so an untraded basket is the emission-weighted portfolio the dividends themselves describe. A direct deposit (btcli root allocate) is split across the fund's current holdings by value, so it buys exactly the exposure the fund already has; a deposit into a fund with no holdings yet is held as the fund's TAO cash slot (netuid 0). There is no target vector for inflows to chase.
  • Only trades move composition. Since runtime v461 a validator reshapes its fund with swap-basket, selling one holding (or TAO cash) for another under price, budget, liquidity, and concentration guardrails — no single holding may end a buy above the BasketConcentrationCap share of fund NAV (1/16 at launch). See Basket trading.

Root validators are transparent fund managers: holdings and trades are public, fund NAV and lifetime return are queryable, and the scoreboard is who made their stakers the most TAO.

Becoming a root validator

Admission is burn-based: your coldkey pays the root burn price and the hotkey is registered — no prior stake required. The price is demand-set like subnet registration: each registration bumps it (~×1.26) and it decays back toward the current MinBurn floor with a ~72-minute half-life, so entry costs at least that floor when the network is quiet and more under registration pressure.

btcli subnets burn-cost 0                        # current root registration price
btcli subnets register --netuid 0 --dry-run      # preview fee and effects
btcli subnets register --netuid 0 -w my_coldkey -H my_hotkey  # register this hotkey
await client.execute(bt.RootRegister(), wallet)

Steps to a working fund:

  1. Register (root-register). The burn is recycled out of issuance; registrations are rate-limited per block and per root tempo. The hotkey is also auto-childkeyed to every existing subnet owner (100% of stake weight on that subnet), unless you opted out with set_auto_parent_delegation_enabled(false) first. New subnets later do the same for every root validator that has not opted out.
  2. Stake your seat. Root seats are limited (64): when the network is full, each new registration prunes the lowest-staked non-immune member (ImmunityPeriod). A seat with no stake behind it earns nothing and is the first to be evicted after that window, so add root TAO to your own hotkey right away (btcli stake add --netuid 0 --amount ... --hotkey <your hotkey>).
  3. Earn. Registration marks the hotkey as a delegate with the default 18% take; each epoch your dividends land in the basket as alpha on the subnets they were earned on, and your stakers accrue the rest pro-rata.
  4. Shape the basket, if you want to, with btcli root swap (next section). Nothing is required: an untraded fund simply holds what it earned.

Losing the seat is not catastrophic: eviction never touches stake or basket state, and re-registering only costs the burn again. Stakers keep their principal and accrued entitlement throughout.

For validators: shape the basket

There is no weight vector to set. Root Reborn launched with every fund on the accumulate-in-place strategy, and runtime v461 made that the only inflow rule: dividends land where they were earned, deposits mirror the current holdings, and the validator changes composition only by trading. The retired set_root_weights call, its RootWeightSettingDisabled gate, and the validator-root-weights read are gone; see History of set_root_weights.

Trade with your coldkey (or a BasketTrading proxy): sell amount of one holding — or TAO from the fund's cash slot, netuid 0 — and buy another with the proceeds. Fund shares, rates, and every staker's entitlement are untouched; only the composition of the escrow holdings changes.

btcli root swap needs the SDK release that ships with runtime v461, which is live on testnet and not on mainnet yet. Install pip install "bittensor==11.3.0rc47" and add -n test; the stable release on PyPI does not have the command, and 11.3.0rc46 shipped a broken btcli. On testnet also pass --no-mev-shield: the MEV shield's validator-side reveal runs on mainnet only, so a shielded swap on testnet is accepted but never executes. On mainnet leave that flag off; swaps shield by default. See Before you start in the Basket trading guide.

btcli root list 5F... -n test                                 # holdings, NAV, lifetime return
btcli root swap --hotkey 5F... --from 4 --to 8 --amount 100 -n test --no-mev-shield   # sell 100 α of subnet 4, buy subnet 8
btcli root swap --hotkey 5F... --from 0 --to 8 --amount 50 -n test --no-mev-shield    # deploy 50 τ of cash into subnet 8
btcli root swap --hotkey 5F... --from 8 --to 0 --amount all -n test --no-mev-shield   # take profit into cash
intent = bt.SwapBasket(hotkey_ss58="5F...", origin_netuid=4, dest_netuid=8, amount=100.0)
await client.execute(intent, wallet)

Every trade runs under the guardrails described in Basket trading: each AMM leg must fill within 2% of the subnet's moving and spot price, the TAO through the middle draws from a daily turnover bucket, the destination holding may not end above the BasketLiquidityCap share of its pool's alpha reserve, and it may not end above the BasketConcentrationCap share of fund NAV (BasketConcentrationCapExceeded) — 1/16 at launch, so a traded fund spreads across at least 16 holdings. Inspect the fund with validator-basket and validator-basket-nav.

For stakers: accrue and claim

Two ways in. btcli stake add --netuid 0 puts principal on a validator; dividends then accrue as β. btcli root allocate deploys TAO into the fund now and credits β immediately (you bear entry slippage). btcli presents root positions in TAO: staked is your principal on netuid 0, accrued is your β marked at the realizable quote. btcli stake list and btcli wallet overview show the accrued basket yield under the total; auto-claim is off, so realize it with btcli root claim. Per-validator breakdown is btcli root list --mine.

btcli stake list                                  # positions + accrued basket yield
btcli wallet overview                             # same yield line on the wallet view
btcli root list                                   # fund leaderboard: NAV, rate vs index
btcli root list 5F...                             # one fund in detail + your position
btcli root list --mine                            # staked + accrued τ per validator
btcli root allocate --amount 100 --hotkey 5F...  # buy β now
btcli stake remove --netuid 0 --hotkey 5F... --amount 40   # principal only; yield stays owed
btcli stake remove --netuid 0 --hotkey 5F... --amount all --claim  # claim all, then unstake
btcli root claim --dry-run --hotkey 5F...         # reserved vs spent fee, vs accrued
btcli root claim                                  # pick wallet → validator → claim
btcli root claim --hotkey 5F...                   # claim accrued into root stake

Unstake (btcli stake remove --netuid 0) returns principal. Basket yield stays owed. After a root unstake, btcli tells you if yield is still sitting there and offers btcli root claim. When RootStakeUnlockInterval is zero, pass --claim on the unstake to redeem that validator's whole entitlement first, then unstake in one batch. That is not a proportional payout: unstaking 40% still claims 100% of the basket. The chain has no "pay out 40% of the basket" call. When the interval is nonzero, the atomic form is unavailable because the claim starts a new hold window. Claim first, wait out the full interval, then unstake separately.

btcli root claim realizes accrued yield into root stake on that validator — principal is never touched, and there is no partial claim. To withdraw τ to free balance afterwards, unstake normally with btcli stake remove --netuid 0. Under the hood a claim uses claim-root-with-hotkey (and the unstake remove-stake).

owed = await client.read(
    "root_basket_owed_breakdown",
    coldkey_ss58=wallet.coldkeypub.ss58_address,
)
await client.execute(bt.ClaimRootWithHotkey(hotkey_ss58=validator_hotkey), wallet)
# coldkey-wide (compat): await client.execute(bt.ClaimRoot(subnets=[0]), wallet)

claim-root-with-hotkey takes the validator hotkey: it redeems your accrued entitlement on that validator only as a pro-rata slice of its basket (alpha holdings are sold to TAO at the pool price), and stakes the proceeds back to root on the same validator. claim-root still exists for old clients — it keeps the pre-basket subnets argument (ignored) and walks every validator the coldkey root-stakes to.

  • Claim threshold. Per-validator payouts below the network threshold (default 500,000 rao = τ0.0005, at most τ0.01; read it with root-claim-threshold) are skipped — the entitlement keeps accruing and pays out once it clears. There is no deadline and nothing expires.
  • Claim fee. The inclusion fee scales with how many ALPHA types the basket holds. The chain reserves a 129-unit envelope for a single-validator claim and the full 256-unit envelope for a coldkey-wide claim, then refunds the unused part after. Admission counts only root-relevant validator hotkeys plus their stored basket rows; unrelated subnet stakes are filtered instead of being multiplied by the total network count. Classifying the staking-hotkey vector is separately capped at 256 relationships. The amount you actually spend follows the holdings scanned and redeemed (around τ0.057 on a full 128-holding basket). btcli root claim --dry-run shows reserved versus spent, compares the spent fee to accrued yield, warns if the claim loses money, and refuses if free TAO cannot cover the reserved amount.
  • Owed is a live quote. root-basket-owed marks your entitlement at current pool prices, so the number moves with the market — a claim realizes whatever the pools pay at execution time.
  • Dust self-consolidates, and fees follow real work. Any basket holding worth less than the claim threshold — too small to pay any claimant — is folded into the fund's root (TAO) slot as a side effect of the next claim, deleting the holding. A position bought with swap-basket is far above the threshold at entry, so only a collapsed one is ever swept. The transaction fee is charged by what the claim actually did: redeemed and consolidated holdings pay full weight, holdings merely scanned pay a small per-row cost — so a fund littered with dust positions gets cheaper to claim after its first claim, not more expensive forever.

What existing root stakers should know

  • Nothing to do on upgrade. Your root stake keeps earning; anything you had accrued under the old claim system was migrated into basket entitlement on the same validator (details below).
  • Your validator is now a fund manager. What your yield is held in is their basket — the subnets they earn on, reshaped by their trades — and it differs per validator. Inspect it before — and while — you delegate: btcli root list 5F... shows holdings, NAV, and lifetime return. If you disagree with how they trade, claim out and allocate to a different validator; your principal moves at face value.
  • Accrued yield is market-priced. Until claimed, your entitlement is a slice of a fund holding subnet alpha: its TAO quote moves with the pools. Principal is unaffected — it stays plain TAO on netuid 0.
  • Claiming compounds, holding defers. A claim converts entitlement to root stake (a realization event); unclaimed entitlement just keeps accruing — there is no deadline and nothing expires.
  • Withdrawals can have a hold window. If the network sets RootStakeUnlockInterval, root stake is locked for that many blocks after your last stake change (anti-sniping around epoch boundaries). A claim also refreshes that window, so atomic claim-then-unstake is unavailable whenever the interval is nonzero. Claim without withdrawing, wait out the full hold, then unstake separately.

Queries and runtime APIs

Every read is available under btcli query, the SDK (client.read(...)), and as betaBasket_* RPC methods for integrators:

ReadWhat it returns
root-basket-owedTotal TAO a coldkey would realize by claiming now
root-basket-owed-breakdownThe same, itemized per validator hotkey
validator-basketA validator's holdings: (netuid, alpha, TAO value) rows
validator-basket-navA validator's fund NAV in TAO
root-basket-total-navNetwork-wide basket NAV
root-claim-thresholdThe minimum per-validator claim payout

Since v450 the runtime also computes the standardized pricing layer itself — the basket index, each fund's index-spliced display price, its staker yield and total-return stake price, and display-denominated positions (see Beta tokens for what these mean). Integrators read them from five betaBasket runtime APIs: get_all_beta_pricing (the whole leaderboard marked against one index sweep), get_beta_pricing, get_beta_index (the live bag and stake index levels), and get_beta_position / get_beta_portfolio (a staker's positions in display units, where display_beta × display_price is the position's value). On upgraded nodes btcli root list passes these numbers straight through, so every consumer of the chain shows the same price, yield, and index.

History of set_root_weights

The name is reused; the economic purpose is not.

The historical set_root_weights extrinsic was added as an active call in commit 4fac11ea5 on 2024-04-15, at call index 8. A root validator's coldkey submitted subnet weights for its hotkey; those weights were aggregated by root stake and passed through rank/trust/consensus to set the global emission allocation between subnets. It became a deprecated no-op in commit 2303a8d07 on 2024-07-18, was renamed to set_tao_weights in 1e2437b9, and was removed in August 2025 (d57ebd4a2).

Root Reborn reintroduced set_root_weights in b3de5f31e on 2026-06-15 with new arguments and semantics (call index 146): the hotkey publishes a basket distribution vector for its own fund, not a vote on network-wide emission. Runtime v450 opened the network-wide gate and pinned a 1/16 concentration cap on the vector.

Runtime v461 removed it again. Weights only ever decided how an already-earned dividend was deployed; they never decided what a validator earned. With swap-basket giving validators direct control of composition, a passive target vector that every inflow chased was redundant and made deposits harder to reason about, so v461 made accumulate-in-place the only inflow rule: dividends land on the subnet they were earned on, direct deposits mirror the current holdings, and only trades move composition. The 1/16 concentration rule survives as BasketConcentrationCap, the guardrail on swap-basket buys. Stored vectors were cleared by the upgrade; funds kept every holding they had.

Migrating from v437

The per-subnet claim model is retired, and the v441 upgrade migrates all previously accrued claimable alpha into basket holdings — nothing is lost, it simply becomes fund entitlement on the same validator.

  • claim_root(subnets) keeps the same SCALE signature for old clients; the subnets set is ignored and the call claims every validator basket-level. Prefer claim-root-with-hotkey for a single validator.
  • set_root_claim_type (Swap / Keep / KeepSubnets) is removed: payouts are always TAO staked back to root. To hold subnet alpha, stake on the subnet directly.
  • sudo_set_num_root_claims is removed; the automatic per-block claim sweep is replaced by explicit claims against the fund.
  • Hotkey and coldkey swaps carry basket state (holdings, entitlements, watermarks) to the new key; subnet dissolution converts that subnet's basket holdings into TAO (root stake) inside each fund.