Bittensor Shorts — Technical Reference

v3.6.1 Specification Mapping (PR #2764, DESIGN.md §1–17)

Notation Map (Spec → Subtensor)

How specification symbols bind to subtensor runtime identifiers:

Spec Meaning Subtensor Binding
T Live TAO reserve SubnetTAO::::get(netuid)
A Live alpha reserve SubnetAlphaIn::::get(netuid)
Tref Conservative TAO ref (blocks same-block pump) min(SubnetTAO, pEMA·A_live) (derived)
pEMA EMA price (TAO/alpha) SubnetMovingPrice (4-week halving period)
P Floor (max loss) ShortPosition.p_floor: TaoBalance
C Collateral (computed only) C = P + N (derived at open, not stored)
R(t) Retained buffer (decays) ShortPosition.r_stored × decay_factor
E(t) Escrow (decays) ShortPosition.e_stored × decay_factor
Q Fixed alpha liability ShortPosition.q_liability: AlphaBalance
B Footprint (Λ·C) ShortPosition.b_stored: TaoBalance
S Aggregate active footprint ShortAgg.b_sigma
ΩS Decay accumulator (subnet) ShortAgg.omega: U64F64
Ωentry Decay snapshot (per-position) ShortPosition.omega_entry: U64F64
Λ Base LTV (governance) ShortBaseLtv: U64F64 (default 0.50)
κS Footprint cap (governance) ShortKappa: U64F64 (conservative start)
dmin, dmax Decay bounds (daily) DecayMin, DecayMax (default 0.001–0.015/day)
Rdust Dust threshold (TAO) ShortDust (default 1 TAO)

Open-Short Closed Forms

At open, given collateral C, pool TAO T, pool alpha A, governance params Λ and κS:

Step 1: Effective LTV

λ_eff = Λ / (1 + Λ)
Reject if λ_eff ≤ 0

Converts base LTV to effective (leverage multiple). Default: 0.50 → 0.33 effective.

Step 2: Solve Collateral → Principal + Proceeds

N = T·λ_eff / (2 + λ_eff)
C = P + N
Reject if N ≤ 0 or 4N > T (domain: reserves must not be drained)

Quadratic formula; N is proceeds from selling alpha into pool.

Step 3: Solve Coverage Ratio

ϕ = (1 − √(1 − 4N/T)) / 2
Reject if ϕ < 0 or ϕ > ϕ_cap (implicit cap from footprint κ_S)

Step 4: Quantities

Q = ϕ · A            (fixed alpha liability at open)
E = N / (1 − ϕ)      (escrow; ratio locked by ϕ)
B = Λ · C            (footprint)
Reject if S + B > κ_S · T_ref   (subnet capacity check)

Step 5: Reserve Mutation

SubnetTAO -= (N + E)       (removed from pool)
ShortPosition.p_floor = P
ShortPosition.r_stored = N  (R₀ = N)
ShortPosition.e_stored = E
ShortPosition.q_liability = Q
ShortPosition.b_stored = B
ShortPosition.omega_entry = ShortAgg.omega  (snapshot)

Continuous Decay

Per-Block Tick (O(1) per subnet with active shorts)

In block_step() after run_coinbase():

for each netuid with ShortAgg.b_sigma > 0:
  u = min(1, b_sigma / (κ_S · T_ref))  // utilization
  d_day = d_min + (d_max - d_min)·u²   // daily decay rate
  g = (1 - d_day) ^ (1 / blocks_per_day)  // per-block factor
  
  // Apply decay to aggregates
  r_sigma *= g;  e_sigma *= g;  b_sigma *= g
  omega += -ln(g)  // accumulator tick
  
  // Restore TAO to pool
  restoration_zap(netuid, dR + dE)
  where dR = r_sigma·(1-g), dE = e_sigma·(1-g)
Materialization: When a position is accessed (close, top-up, default), scale its stored values by f = exp(-(omega - omega_entry)) and update omega_entry = omega. Both R and E decay using the same factor.

Decay Bounds

Daily decay rate:  d_day ∈ [d_min, d_max]
Default values:    d_min = 0.001 (0.1%/day)
                   d_max = 0.015 (1.5%/day)
Utilization:       u = min(1, active_footprint / (κ_S · T_ref))
Applied decay:     d_day = d_min + (d_max - d_min) · u²

Close Paths

Path 1: do_close_short (Trader Brings Alpha)

Trader repays fraction ρ of liability Q from their staked alpha balance:

Input:   ρ ∈ (0, 1], price_limit
Materialize:  R, E *= decay_factor
Validate:  coldkey holds at least ρQ alpha
Transfer:  ρQ alpha from coldkey→pool
Pool mutation:  SubnetAlphaIn += ρQ
Settlement zap:  balanced add of ρE to TAO side
Payout:  Send ρ(P + R) back to coldkey
Update:  position P, Q, R, E, B reduced pro-rata; aggregates updated

Path 2: do_close_short_self (Protocol AMM-Buys)

Protocol buys ρQ alpha via AMM (spot price), trader pays difference:

Input:   ρ ∈ (0, 1], price_limit
Materialize:  R, E *= decay_factor
Swap:  K = sim_swap(GetAlphaForTao, ρQ)  (TAO cost to buy ρQ)
Payout:  Send max(0, ρ(P + R) − K) back to coldkey
Update:  as above

Path 3: Force Close (Default)

When R + E < R_dust (permissionless poke via do_default_short):

Materialize:  R, E *= decay_factor
Check:  R + E < R_dust
Restore:  restoration_zap(netuid, R + E)  (both go back to pool)
Recycle:  recycle_tao(coldkey, P)  (principal burned)
Clear:   position dropped, aggregates updated, Q liability extinguished
Payout on force close: 0 TAO. Trader loses entire principal. This is the default condition.

Storage Layout

ShortPosition Struct

pub struct ShortPosition {
  pub p_floor: TaoBalance,      // principal floor (max loss)
  pub q_liability: AlphaBalance, // fixed alpha debt
  pub r_stored: TaoBalance,      // buffer at last materialization
  pub e_stored: TaoBalance,      // escrow at last materialization
  pub b_stored: TaoBalance,      // footprint at last materialization
  pub omega_entry: U64F64,       // decay accumulator snapshot
  pub opened_at: u64,            // block (telemetry)
}

Merged per (netuid, coldkey). Same-side opens merge via re-solve.

ShortAgg Struct

pub struct ShortAgg {
  pub r_sigma: TaoBalance,       // sum of current R across all shorts
  pub e_sigma: TaoBalance,       // sum of current E
  pub b_sigma: TaoBalance,       // sum of current B (active footprint S)
  pub q_sigma: AlphaBalance,     // sum of fixed liabilities (open interest)
  pub omega: U64F64,             // cumulative decay accumulator
}

Governance Parameters

Storage Type Default
ShortsEnabled bool false (flipped via governance after trading-games gate)
ShortBaseLtv U64F64 0.50
ShortKappa U64F64 conservative start; ramped post-launch
DecayMin U64F64 0.001
DecayMax U64F64 0.015
ShortDust TaoBalance 1 TAO

Extrinsics (Shorts Launch)

Call Index Extrinsic Authoritative Fn
139 open_short(netuid, hotkey, position_input, price_limit) do_open_short
140 top_up_short(netuid, amount) do_top_up_short
141 close_short(netuid, fraction, price_limit) do_close_short
142 default_short(coldkey, netuid) do_default_short

Reserve Accounting Model

All pool impact is expressed as mutations to SubnetTAO and SubnetAlphaIn:

At Open

SubnetTAO -= (N + E) — TAO removed from pool, price impact upward (alpha becomes relatively scarcer)

Per-Block Restoration

SubnetTAO += (dR + dE) — decayed portions returned to pool, price drifts back down

At Close

SubnetAlphaIn += ρQ — alpha repaid by trader (or bought via AMM), escrow portion settled balanced

At Default

SubnetTAO += (R + E) — both returned to pool; principal P is recycled (burned outside reserves)

Conservation invariant: Over the lifecycle of a short, total TAO returned to SubnetTAO (via restoration + close settlement + default restoration) plus recycled floor, equals the N + E removed at open plus P posted, minus equity paid to trader.

Terminal Dereg Settlement

When a subnet is deregistered, shorts are settled before alpha base destruction:

for each (coldkey, netuid) short:
  Materialize position
  K_D(Q) = max(K_spot_last, Q · pEMA)  // terminal liability value
  equity = max(0, P + R − K_D)
  Pay equity to coldkey (if any)
  Recycle min(P + R, K_D) via recycle_tao
  Extinguish Q
  Clear position

References

For a conceptual walkthrough, see the Explainer. For interactive simulation, see the Simulator.