Skip to content

Latest commit

 

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DBTC · Bemand

Bemand — Bitcoin demand, ticker DBTC — a low-volatility lending/accounting unit derived from Bitcoin network difficulty. Difficulty is an independent, on-chain, fiat-agnostic signal for BTC demand: the protocol needs no price oracle and no fiat. The app unit is the bem (10^-6 DBTC), written Ƃ1.00 — 1 DBTC = 1,000,000 bems, read like sats & BTC but exactly metric. Still very much research, model-first.

Status

The law was fitted once (on the data that existed 2026-08-16) and is then immutable: DBTC/USD = P0 × (D_s/D0)^b, b=0.673473, P0=$455.91, D0=5.46e10, 26-period block smoothing, reference date 2016-01-01. Only network difficulty and ECB FX move. Is it holding?

Updated 2026-09-25 13:34 UTC · data 2026-09-24 / spot 2026-09-25 · law set 2026-08-16

1 DBTC = $89,593 · spot BTC = $84,385 · Ƃ1.00 = $0.09

track

DBTC/USD realised volatility is ~0.17% (90d) — an order of magnitude calmer than the basket of fiat currencies it can be quoted in (basket/USD ~4.9%). The unit behaves like a near-fixed peg: it tracks spot's long-run level, but barely wiggles day to day.

Regenerate with python track.py (--force re-downloads).

Contents

The idea

Bitcoin's difficulty is set by the network itself (every 2016 blocks) purely from the hashing power miners are spending. It is not a price measured in any currency and needs no trusted oracle. The claim:

D(t) / D(t0) — smoothed network difficulty normalised to a reference point t0 — is a proxy for relative BTC price, unit-free.

A protocol loop (RBTC):

  1. Deposit BTC/RBTC → mint DBTC worth S(t0) = D_s(t) / D_s(t0) (D_s = smoothed difficulty).
  2. If smoother difficulty rises, return DBTC, take back RBTC, re-mint at the higher anchor → long the difficulty of the BTC network.
  3. If smoothed difficulty falls sharply below mint level, the vault is liquidated.

Because difficulty is a pure protocol-internal measure, DBTC can be accounted in USD via its 50WMA/200WMA analogue for reference, but the protocol value never depends on an external feed.

Units & notation: DBTC, Bemands, bems

DBTC (the ticker) is a Bemand — Bitcoin demand. The unit apps use is the bem, the metric microDBTC:

unit value description
1 DBTC 1,000,000 bem the whole token (used for protocol/lending math)
1 bem 10^-6 DBTC the app unit, formatted Ƃ1.00

Read the pairing exactly like sats & BTC, but without the 10^-8 quirk: bems are exactly metric (micro, 10^-6), so the prefix, the number of decimals and the name all agree. The glyph is Ƃ (U+0182, "BCU") and sits before the amount — Ƃ1.00.

  • On-chain (EVM): an ERC-20 with decimals() = 18, so 1 DBTC = 10^18 base units and 1 bem = 10^12 base units (a picobem). The bem is the app/accounting unit (Ƃ1.00), but it is not atomic on-chain: fractions of a bem — down to 10^-12 — are fully transactable, exactly like fractional USDT/USD amounts. Apps render two decimals and round only at display time.
  • Oracle precision: the reference contract returns 64.64 fixed point (resolution 2^-64 ≈ 5.4×10^-20, ~10^13× finer than a bem; one quantum ≈ 0.054 base units), so a ratio → base-units conversion rounds to < 1 base unit — effectively exact.
  • Scale today: 1 DBTC ≈ $89.6k ⇒ Ƃ1.00 ≈ $0.09, so everyday prices land in the tens–thousands of Ƃ with ~0.1¢ per 0.01 Ƃ — JPY-like magnitudes with cent-grade granularity.
  • Glyph caveat: Ƃ is a rare codepoint — many system fonts fall back to tofu, so apps should bundle a font/variant that contains it (see dbtc/units.py).

Raw data (since 2009)

raw data

Both series span 2009→today (daily, blockchain.info). Price spans $0 → ~$65k, difficulty spans 1 → ~110T: two power-law-ish curves. The two track each other well on a log scale — that visual correlation is the entire thesis. → main.py, dbtc/plot.py chart_raw.

Does difficulty track relative price? (analysis, main.py)

Normalised log-ratios

The analysis picks a reference t0, computes ln(price/price_t0) and ln(diff_sm/diff_sm_t0) for every day, and asks how well the two move together (02_ratios_log.png, 03_regression.png):

norm log-ratios vs t0

regression ln(price_ratio) ~ ln(diff_ratio)

Fit (full-sample, best window):

Now smoothing windows are measured in difficulty periods (2016 blocks, ~2 weeks each) instead of calendar days — the same unit the reference contract uses. 26 periods ≈ 1 year; the flagship default is 26 periods ≈ 1 year (see below).

smoothing corr R² slope b median |err|
1p .972 .945 .49 54%
4p .971 .943 .49 54%
8p .970 .941 .48 54%
13p .969 .939 .47 54%
26p .968 .936 .47 56%
52p .969 .938 .46 54%

Readings:

  • correlation ≈ 0.97 regardless of window — difficulty is a real proxy for relative price, even over daily data. Smoothing barely matters: the protocol already steps difficulty inherently every ~2 weeks.
  • The fitted exponent b ≈ 0.49 (price ∝ difficulty^0.49): doubling difficulty → ~1.4× price. Consistent across all windows (see 04_window_metrics.png).
  • R² ≈ 0.94 but median |err| ≈ 54% — the two are correlated, not tightly explained. At peaks difficulty overshoots (ebullient hashing) and at drawdowns it lags (capacity exit), so a level bet on difficulty carries ~±50% noise. 06_deviation.png shows the largest deviations cluster at 2011/2013/2017/2021 peaks and 2015/2018/2022 drawdowns; 05_price_proxy.png shows the reconstructed proxy price in log space:

price proxy from smoothed difficulty

pred/actual ratio = collateral guardrail

rolling correlation

Fit-quality vs the smoothing window (04_window_metrics.png) is essentially a flat line: once per-block stepping exists, extra smoothing buys nothing and loses nothing. That keeps the protocol simple (raw difficulty, no WMA parameter to tune).

./.venv/bin/python main.py            # re-download if stale, fit, plot all of the above

The price models (backtest.py)

backtest.py answers "what if we launched N years ago?". Four candidate USD prices for 1 DBTC, all normalised to a common launch anchor (SMA-350):

  • DBTC — pure difficulty-derived (the real design: s0 = base · (D/D0)^b)
  • wma (≈50w) — SMA-350 of spot, the accounting anchor DBTC is meant to track
  • wma200 (≈200w) — SMA-1400, the long-run reference line (chart only, not a scenario)
  • spot — raw BTC/USD (conventional crypto payment baseline)

Candidate values, and their volatility

out/backtest/01_values.png — top: the four price series (log). Bottom: rolling 90-day annualised volatility of all four (log scale):

candidate prices + rolling volatility

The headline result: DBTC is dramatically smooth. Rolling vol peaks in the early 2012​–2015 era at ~10–20% for all series, but after ~2018 DBTC sits reliably at ~0.1–0.5% (block-interpolated, --smooth 26) while spot and even the 50w/200w SMAs swing 30–80%. DBTC's daily moves stay tiny because the block-window mean drifts continuously — the old retarget-day step (~2.8% single-day jump) is gone — so it is a genuine ultra-low-vol stable accounting unit — at the cost of trailing spot's returns.

Run and see: ./.venv/bin/python backtest.py --years 10 → regenerates out/backtest/*.png, and ./.venv/bin/python main.py the analysis set.

Merchant: a USD-priced business accepting DBTC

merchant cashflows

A business that passes revenue straight through (prices in USD, restocks in USD monthly) has only its working-capital buffer exposed. Top panel: the $1 float's USD value. Bottom: cumulative wealth vs USDT baseline.

Key figure: DBTC holds the float's max drawdown at only −1.1% vs −75% for spot (the 50w SMA anchor sits between at −54%). A monthly-converted merchant is effectively neutral-to-mildly-positive, because DBTC barely ever draws down (05_float_sensitivity.png shows bigger floats magnify both win and risk).

Salary: a worker paid fixed DBTC/month

salary panel

A yearly-re-signing salary lands at ~1.3x USDT — DBTC behaves like a gently-upward, low-vol USDT (income std ~0.4 $/mo). A fixed lead contract captures the underlying asset appreciation, but inherits its full swings. 06_cumulative.png collapses this to cumulative multiple-vs-USDT across the four model×renewal combos.

Choosing the smoothing window (block-interpolated)

Since 2016 the DBTC price law uses a block-interpolated difficulty mean D_s: the window is W × 2016 blocks, and within a period the window slides one block at a time (linear interpolation on the two edge periods, full interior periods) — so the price drifts smoothly across a retarget instead of snapping. This is what kills the old retarget-day jumps: the previous (period-averaged) model put 100% of daily price movement on retarget days (single-day jumps up to ~2.8% at 52p); the block version has max daily move ≈ 0.4% and rolling 90d vol of ~0.1%.

out/backtest/10_window_vol.png sweeps DBTC's rolling-90d annualized volatility against W (--smooth, difficulty periods) with the 200wma/spot references:

vol vs smoothing window W

W (periods) ~years median 90d vol DBTC price max DD smooth-diff max DD (floor) min spot/DBTC
13p 0.5 0.46% −10.2% −15.0% 0.30
26p 1.0 0.22% −1.2% −1.7% 0.32
52p 2.0 0.13% 0.0% 0.0% 0.29
78p 3.0 0.09% 0.0% 0.0% 0.28
104p 4.0 0.08% 0.0% 0.0% 0.28

Block interpolation flattens the story:

  • Vol & floors improve monotonically with W — at 26p DBTC's 90d vol is already below the 200wma (0.22% vs 0.19%); at 52p+ the price has no historical drawdown at all (worst smoothed-difficulty drawdown ≈ 0.0%), i.e. effectively monotonic. There is no longer a "too big W" penalty on the difficulty side.
  • The spot/DBTC tail is the only thing that gets worse with W — a wider, flatter window stands further above the market at a spot crash (min spot/DBTC falls 0.32 → 0.28), and that is what sets the collateral requirement, not difficulty itself.

Recommendation: W = 26p (≈ 1 year). It gives sub-200wma volatility (0.22% vs 0.19%) with only a −1.7% worst-ever smoothed-difficulty drawdown since 2016, and keeps the spot/DBTC tail at its best (min 0.32, the fewest collateral needed). It's the fastest window that still washes out retarget steps, so the price responds to the difficulty trend with the least lag — a one-year lookback rather than two.

./.venv/bin/python backtest.py          # defaults to --smooth 26 → prints the sweep + 10_window_vol.png

Collateral & liquidation (lending.py)

The vault's liquidation trigger is pure difficulty: you're liquidated when smoothed difficulty falls to (1/CR)^(1/b) of its mint-time level (≈ −19.5% at CR=3). With block-interpolated smoothing the worst cases become tiny by ~1y windows:

smoothing W worst month worst 12-mo months < launch max price DD
13p −3.3% +3.7% 0% −10.2%
26p −0.6% +11.5% 0% −1.2%
39p 0.0% +16.1% 0% 0.0%
52p +0.4% +19.7% 0% 0.0%
78p +0.7% +25.6% 0% 0.0%

At 26p the smoothed-difficulty path since 2016 barely ever draws down (worst −1.7%, 2021-08), so the pure difficulty floor never comes close. The real risk is the spot/difficulty spread: at the worst point spot/DBTC fell to ≈0.32× while smoothed difficulty kept climbing. That deviation — not difficulty — sets the collateral requirement:

collateral ratio over time

Across W (07_w_sweep.png, 08_merchant_window.png): 26p+ keeps worst-month drawdowns ≤ ~1%, and the never-liquidation backing is driven by how much smooth spot/DBTC diverges. Anchored 2016 you need ≈3.1x backing for "never" at 26p (fewer than at 52/78p — the tighter window tracks spot more closely); the switch is that "never" depends sensitively on the anchor epoch, because difficulty's level can drift relative to spot (see table + charts at 07_w_sweep.png, 08).

Run: ./.venv/bin/python backtest.py --since 2016-01-01 --smooth 26 — prints all metrics.

lending.py — live protocol numbers

Frozen defaults: anchor 2016-01-01, smoothing 26 periods, law b=0.673473, P0=$455.91 (all read from data/frozen_law.json — fitted once on the cached data, never re-fitted), CR 3.0. Once frozen, USD is never consulted at runtime; every number below is difficulty arithmetic.

  1. Mint — per 1 locked BTC, mint = (D_ratio)^b / CR. Today ≈ 65.4 DBTC/BTC (D_s ratio ≈ 2,549, b ≈ 0.673, CR=3).
  2. Liquidation — pure-difficulty floor at (1/CR)^(1/b) ≈ 19.5% of mint difficulty: since 2016 the 26p-smoothed difficulty's worst drawdown was −1.7% (2021-08), so the floor is nowhere near being hit. The binding tail is the USD view: the 2020-03-13 spot crash was the worst spot/DBTC deviation (min ≈ 0.32) → at CR=3 that leaves only ~−5% margin; at CR=2.5 it's negative — the thin spot deviation, not difficulty, is the real risk.
  3. USD value — SmoothUSD = P0 × D_ratio^b with P0 frozen once at the anchor (P0 ≈ $456, today ≈ $89.7k), purely difficulty-driven thereafter.
  4. Prices — out/lending_price.png shows 30-day & 12-month DBTC/USD and the difficulty ratio vs its floor (./.venv/bin/python lending.py)

lending price history

The reference contract (Rootstock)

contracts/DBTCPrice.sol is a minimal, self-contained oracle that turns this whole thesis into on-chain arithmetic without any external price feed. It reads Bitcoin difficulty directly from the RSK Bridge (getBtcBlockchainBestChainHeight / getBtcBlockchainBlockHeaderByHeight), parses each period's first-epoch compact nBits target, and prices DBTC with the fitted power law on a block-interpolated mean:

DBTC per BTC = (D_s / D_s0)^b        BTC per DBTC = 1 / (D_s / D_s0)^b     (CR = 1)
  • It smooths exactly like the Python model (analyze.sliding_smoothed_diff). D_s is the mean difficulty over the trailing window × 2016 blocks (default window = 26 ≈ 1 year), computed by block interpolation: the newest period counts its partial blocks, the oldest period is filled to reach exactly window × 2016, and every interior period counts a full 2016. The window slides one block at a time, so the price drifts continuously and has no retarget-day jump — the same weighted-mean the Python side computes, so on-chain and Python agree by construction.
  • No full header decode and no oracle: since target = MaxTarget / difficulty, each period contributes 2^224 / target (MaxTarget cancels in the ratio). refresh() stores the newest period's difficulty in a small ring (cap = window + 2) and only talks to the bridge when the best height enters a new 2016-block epoch; a long gap is backfilled one read per missed epoch.
  • Price reads are cheap: difficultyRatio() needs the newest window + 1 ring values plus the bridge's getBtcBlockchainBestChainHeight() (the block interpolation offset), then one log2/exp2 pair — no per-block storage, no timestamps.
  • Fractional exponent on-chain: b ≈ 0.64 is not an integer, so the contract ships a signed 64.64 fixed-point library (contracts/libraries/FixedPointMath.sol) for log2/exp2/pow.
  • Getters dbtcPerBtc() / btcPerDbtc() return 64.64 fixed point; anchor() freezes D_s0 at mint time (anchorWeight = log2(area) − log2(blocks)).
solc --bin --optimize contracts/DBTCPrice.sol   # compiles with solc 0.8.25

What this is, and what it is not

  • DBTC is a stable-ish, difficulty-anchored accounting unit — ~50–200× lower vol than spot since ~2016, difficulty-derived (no external price feed required to compute). At the 26-period block-interpolated default the smoothed difficulty since 2016 has barely drawn down (worst −1.7%), and wider windows remove it entirely — so it is genuinely low-vol — but the level can still drift relative to spot (see collateral tables).
  • It is not a get-wealthy instrument: over a bull decade margins clearly trail spot (04_table.png, 06_cumulative.png). The pitch is low-volatile stable pricing, not alpha.
  • No fees/slippage/liquidation mechanics/S-M pool dynamics are modelled — clean value-evenness math only.
  • The difficulty law itself (price ∝ difficulty^b) has ±~55% median noise near peaks; liquidation triggers must tolerate that.

Layout

main.py                  # download → analyse (difficulty vs price) → plot
backtest.py              # "what-if we launched N years ago" + merchant/collateral sweeps
lending.py               # live: mint / liquidation / USD value / 30d+12m prices
track.py                 # refreshes feeds → rewrites the Status block + out/track.png (volatility chart)
dbtc/analyze.py     # load data, smoothing windows, OLS fit, metrics
dbtc/units.py       # units & notation: bem = 10^-6 DBTC, Ƃ formatting
dbtc/frozen.py      # the ONE fitted law (b, a, P0, D0); compute once, store, never refit
dbtc/fx.py         # ECB daily FX (Frankfurter) cached in data/fx.json
dbtc/backtest.py   # value models + cashflow simulators + merchant/collateral metrics
dbtc/plot.py       # analysis charts → out/*.png
dbtc/download.py     # blockchain.info fetcher, cache-staleness by last data point
contracts/DBTCPrice.sol      # reference Rootstock oracle (diff → DBTC/BTC, see above)
contracts/libraries/FixedPointMath.sol  # 64.64 fixed-point pow for the ^b law
data/                    # cached blockchain.info + ECB JSON (auto-refreshed)
data/frozen_law.json     # the immutable law used by lending.py and track.py
out/*.png                # committed charts referenced by this README
out/track.png            # the live-tracker chart (regenerated by track.py)
out/backtest/10_window_vol.png   # W-sweep → the 26-period default (see "Choosing the window")

About

DBTC · Bemand (Ƃ · bems) "Bitcoin demand": a low-volatility accounting unit minted from Bitcoin network difficulty, no external price oracle needed and no fiat dependency.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages