Methodology
Every number maps to a contract call or an API field. If a figure cannot be recomputed from public data, it is not shown.
Every metric and its source
| Metric | Formula | Unit | Label | Contract / event | API field |
|---|---|---|---|---|---|
| Coverage (cycle) | pool ÷ obligation, over the cycle's computed distributions | × | onchain | pox5-reader::get-coverage-for-cycle(cycle) → coverage-bps | /metrics/current coverage · /metrics/cycles/:n coverage |
| Headroom | 1 − obligation ÷ pool | % | onchain | pox5-reader::get-coverage-summary → headroom-bps | /metrics/current headroom |
| Obligation per interval | Σ over active bonds of shares × target-rate ÷ 10000 ÷ 50 (pox-5 L2266) | sats | onchain | pox5-reader::get-obligation-per-interval(cycle) | /metrics/current obligation_per_interval |
| Bond payout order | descending stx-value-ratio, ties to the lower bond index | bonds | onchain | pox5-reader::get-bond-payout-order(cycle) | /bonds/order |
| Reserve | pox-5 reserve-balance | sats | onchain | pox5-reader::get-reserve | /metrics/current reserve |
| Hypothetical cover | reserve ÷ (2 × obligation per interval) | cycles | onchain | pox5-reader::get-reserve-cover-cycles(cycle) | /metrics/current reserve_cover |
| Pending pool | sBTC balance − staked − reserve − accounted (never aborts) | sats | onchain | pox5-reader::get-pending-pool | /metrics/current pending_pool |
| Pool per distribution | gross-accrued-rewards | sats | mirrored | calculate-rewards event; risk-feed gross-pool-sats | /intervals gross_pool |
| Owed per distribution | Σ target-yield of bond-distribution events | sats | mirrored | bond-distribution events; risk-feed bond-target-sats | /intervals obligation |
| Coverage per distribution | pool ÷ owed; n/a when nothing is owed | × | mirrored | risk-feed coverage-bps (derived on-chain from posted inputs) | /intervals coverage |
| Reserve deposit and state | reserve-deposit; > 0 → not drawing, 0 → flat | sats | mirrored | calculate-rewards event; equals the reserve delta in pox-5 state | /intervals reserve_deposit · /metrics/current reserve_state |
| STX-only realised yield | total-stx-staker-rewards ÷ cycle-staked-ustx × 1e6 | sats/STX | mirrored | calculate-rewards event; risk-feed stx-yield-sats-per-stx-e9 | /intervals stx_only_yield |
| STX-only APY (BTC terms) | yield × 50 ÷ STX/BTC price at the distribution | % | mirrored | price: CoinGecko hourly (Coinbase STX-USD/BTC-USD fallback), stored with source and timestamp | /intervals stx_only_apy_btc |
| Cliff price | price × obligation ÷ pool (assumes miner bids scale with price) | sats/STX | mirrored | risk-feed cliff-sats-per-stx-e6 | /metrics/current cliff.price |
| Stress results | pool × (1 − commit drop) × (1 − price drop), split in pox-5 order | sats, ×, % | hypothetical | /stress; pox5-reader::simulate-waterfall for the current book | /stress |
How pox-5 pays out
- Once per distribution interval (1,050 Bitcoin blocks, two per reward cycle) anyone may call calculate-rewards. The sBTC received since the last call is the gross pool.
- Bonds are paid first, in descending stx-value-ratio; ties go to the lower bond index (L2285–2299). Each gets min(target, what is left).
- Within a bond, rewards are flat per token: every staked sat earns the same (L2304–2309).
- 15% of what remains goes to the reserve (L2190); STX-only stakers get the other 85%.
- The reserve never pays bonds. transfer-from-reserve (L2696) is private and never called; that needs a SIP. In a shortfall the reserve stays flat.
Line numbers refer to the deployed source, identical to stacks-core tag 4.0.1 (commit 62e03cc).
The zero-yield cliff
The headline is price-free: the pool can fall by 1 − 1/coverage before bonds absorb all of it. Converting that to a sats/STX price assumes miner BTC bids scale with the STX price. They only roughly do: pool per sat/STX of price ranged 0.58M–0.89M sats across distributions 282–286.
friedger's ~171 sats/STX, reproduced (hypothetical)
3,000 BTC × 3% ÷ (1,000 STX/block × 52,560 blocks/year) = 171.23 sats/STX
Inputs are the SIP's hypothetical launch book (forum post #14). The same inputs give his 1.65× coverage at 282 sats/STX.
3,000 BTC at today's pool (hypothetical)
price × 180,000,000 sats ÷ latest pool
180,000,000 sats = 3,000 BTC × 3% ÷ 50, the book's obligation per interval.
Where the pool comes from
Under PoX-5 every Stacks block-commit pays one output to the sBTC deposit address; nothing is burned. In distribution 286, 705 of 1,050 Bitcoin blocks carried commits (five miners, 332,500 sats per block); the other 345 had no sortition. The stress test's miner-commit drop cuts that total directly. Evidence.
How the data is verified
Each distribution is located by reading last-reward-compute-height at historical chain tips (call-read ?tip=), taken from its calculate-rewards transaction, and recomputed independently from pox-5 state just before and after that block: the reserve delta and rewards-per-token × shares. So far every distribution matches within 2 sats and the reserve delta matches exactly. The indexer does not use the deprecated contract-events endpoint.
Contracts
- pox5-reader · mainnet · onchain figures, read-only, holds no fundsdeploying
- risk-feed-trait · mainnet · interface implemented by pox5-readerdeploying
- risk-feed · testnet · mirrored per-distribution records with raw inputsST24MYZSDF0TAVZ452R2TJY3RCQAVT3KR0FJHYCAJ.risk-feed
- risk-feed-trait · testnet · interface implemented by risk-feedST24MYZSDF0TAVZ452R2TJY3RCQAVT3KR0FJHYCAJ.risk-feed-trait
- coverage-guard · testnet · example consumer: ok / pausedST24MYZSDF0TAVZ452R2TJY3RCQAVT3KR0FJHYCAJ.coverage-guard
- pox-5 · mainnet · the Bitcoin Staking boot contractSP000000000000000000002Q6VF78.pox-5
Testnet feed values mirror mainnet data.
Site metacenter.0xo.in · API metacenter.0xo.in/api · source GitHub