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.
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
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).
- Status
- The idea
- Units & notation: DBTC, Bemands, bems
- Raw data (since 2009)
- Does difficulty track relative price?
- The price models (
backtest.py) lending.py— live protocol numbers- The reference contract (Rootstock)
- What this is, and what it is not
- Layout
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 pointt0— is a proxy for relative BTC price, unit-free.
A protocol loop (RBTC):
- Deposit BTC/RBTC → mint DBTC worth
S(t0) = D_s(t) / D_s(t0)(D_s = smoothed difficulty). - If smoother difficulty rises, return DBTC, take back RBTC, re-mint at the higher anchor → long the difficulty of the BTC network.
- 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.
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 (seedbtc/units.py).
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.
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):
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 (see04_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.pngshows the largest deviations cluster at 2011/2013/2017/2021 peaks and 2015/2018/2022 drawdowns;05_price_proxy.pngshows the reconstructed proxy price in log space:
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 abovebacktest.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)
out/backtest/01_values.png — top: the four price series (log). Bottom: rolling 90-day
annualised volatility of all four (log scale):
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.
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).
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.
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:
| 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/DBTCfalls 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.pngThe 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:
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.
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.
- 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). - 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: the2020-03-13spot 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. - USD value —
SmoothUSD = P0 × D_ratio^bwithP0frozen once at the anchor (P0 ≈ $456, today ≈ $89.7k), purely difficulty-driven thereafter. - Prices —
out/lending_price.pngshows 30-day & 12-month DBTC/USD and the difficulty ratio vs its floor (./.venv/bin/python lending.py)
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_sis the mean difficulty over the trailingwindow × 2016blocks (defaultwindow = 26≈ 1 year), computed by block interpolation: the newest period counts its partial blocks, the oldest period is filled to reach exactlywindow × 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 contributes2^224 / target(MaxTargetcancels 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 newestwindow + 1ring values plus the bridge'sgetBtcBlockchainBestChainHeight()(the block interpolation offset), then onelog2/exp2pair — no per-block storage, no timestamps. - Fractional exponent on-chain:
b ≈ 0.64is not an integer, so the contract ships a signed 64.64 fixed-point library (contracts/libraries/FixedPointMath.sol) forlog2/exp2/pow. - Getters
dbtcPerBtc()/btcPerDbtc()return 64.64 fixed point;anchor()freezesD_s0at mint time (anchorWeight = log2(area) − log2(blocks)).
solc --bin --optimize contracts/DBTCPrice.sol # compiles with solc 0.8.25- 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.
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")












