Skip to content

USDhb

USDhb is a dollar that lives inside HardBasis. This page is the whole of it: what it is, how minting and redeeming work, what backs it, what sUSDhb actually is, and how to check every claim on this page yourself.

Open USDhb on the live testnet →

What it is

The page says it this way, and this page does not say it differently:

A dollar that lives inside HardBasis. Turn sats into USDhb when you want to step out of bitcoin's swings, and back into sats whenever you like. Every USDhb is backed by exactly one $1 short the engine holds, and you can check that live, right here.

USDhb is not issued against a pile of dollars in a bank. It is minted as the byproduct of a fully collateralized short that the engine opens at the same moment, in the same transaction. One USDhb, one fully backed short worth a dollar. That is the entire mechanism, and the rest of this page is what follows from it.

Minting and redeeming

Get a price. You ask for a quote and the engine prices it when you ask (POST /v1/usdhb/quotes). The quote is signed and held for a fixed window that the engine publishes as params.quoteTtlMs on GET /v1/usdhb; the page counts that window down beside the quote and marks it EXPIRED when it runs out. Nothing is committed while a quote is open.

Confirm. Accepting the quote is one transaction (POST /v1/usdhb/mints): sats in, the hedge opened, USDhb credited. There is no window in which one of those has happened and the others have not. If the price moved out from under the quote the mint is refused with usdhb_requote and a fresh quote comes back in the refusal, so you re-confirm rather than start over.

Redeeming is the same shape in reverse (POST /v1/usdhb/redemptions): USDhb in, the hedge closed, sats out, one transaction. A redemption never waits on a halt. If the price it would use is stale it queues and pays at the next fresh one rather than refusing you.

Whole units on testnet. Testnet v1 mints and redeems whole USDhb only. A fractional amount is refused before you can submit it, not after.

The quote's four lines, in the order the ticket shows them:

linewhat it is
You pay (or You receive)the sats moving, at this quote
Included feethe fee, already inside the number above, not added to it
Bitcoin pricethe price the quote was struck at
Backed bythe short the mint will open, in contracts

The fee is stated as included rather than appended because that is what it is: the sats figure above it is what leaves your balance.

The backing

Supply equals contracts, checked on every update. Every USDhb is matched by one $1 short. The engine re-checks this identity on every commit, not on a schedule, and publishes the result as backingIdentityHolds on GET /v1/usdhb. An identity that only holds between checks is not an identity, which is why the check rides the transaction rather than a sweep.

The page carries one headline for the state of that backing, and it says which of three things is true:

headlinebeside itwhat it means
FULLY BACKEDverified <age>the identity holds and the issuer's supply matched the ledger
FULLY BACKEDnot yet verifiedthe identity holds; nothing has been checked against an issuer yet
BACKED · UNVERIFIEDverification failed <age>the identity holds, but the last check against the issuer failed

The headline never stands alone: the chip beside it carries the age of the check, so a reader can see how fresh the claim is rather than taking the word for it. The third row is not a downgrade of the backing. The shorts are still there and the identity still holds; what failed is the comparison against the issuer's own supply figure, and that failure is shown rather than smoothed over. It is also the state that halts new mints, which is covered below.

The reserve is the engine's own sats buffer behind the hedge, published as reserveMsat with the target and floor it is measured against. The page shows it standing against those two, so a reserve below its floor reads as below its floor.

sUSDhb, honestly

Staking USDhb gives you sUSDhb, and sUSDhb is the junior tranche. The page says what that means without dressing it up:

sUSDhb earns when the hedge collects funding and absorbs the cost when it pays, so it can go up or down. Your plain USDhb is never touched.

There is no rate on this page, and there is none on the product, because there is no rate to state. What sUSDhb is worth is a share price the engine publishes; funding moves it in both directions.

Unstaking cools. An unstake (POST /v1/usdhb/unstake) waits out a cooldown that the engine publishes as staking.unstakeCooldownMs, and then releases at the share price AT RELEASE, in every halt mode. The figure the ticket previews is today's price, not the figure you will get. Unstake is not halt gated: releases proceed whatever else is stopped.

Shares are floor(USDhb x 1e9 / share price), taken from the served share price. Staking is POST /v1/usdhb/stake; what is cooling is on GET /v1/usdhb/unstakes.

Verifying it yourself

The public payload is public.GET /v1/usdhb needs no key. Supply, the hedge contracts and margin, the reserve, the staking pool and share price, the halt flag and its reason, the attestation and its timestamp: everything the page shows, from one snapshot, so the figures you read are consistent with each other rather than assembled from separate reads.

Your own inclusion proof is keyed. Verify my inclusion on the page calls GET /v1/por/proof?asset=usdhb and returns a Merkle inclusion proof of your USDhb balance in the published liability tree. It is a button on the page rather than a link because the route authenticates from the x-api-key header only: a new tab would answer 401, and an API key must never travel in a URL. Verify the proof locally against the published root and you have checked that your balance is inside the total, without trusting the response that carried it.

The freeze log is a log.GET /v1/usdhb/freezes lists every freeze, with a count on the page beside it. A frozen balance is a fact about the system and belongs in the open.

Your own USDhb history is on GET /v1/usdhb/activity, and the site-wide reserves picture is on Trust & Proof of Reserves.

Halts

When the engine halts USDhb mints, the page says so in the mint card and the stake card, in one sentence:

New mints and stakes are halted by the engine <reason>. Redemptions and unstakes still work, and funding keeps settling into sUSDhb.

Read the scope literally, because each clause was written against something that was previously said wrong:

  • Stakes stop too. A stake is a mint class flow and the engine refuses it with usdhb_mints_halted. The stake card warns before the click rather than after it.
  • Redemptions and unstake releases continue. Neither is halt gated.
  • The waterfall's yield mints continue, which is why total supply can move while the page says mints are halted. That is not a contradiction; it is the reason "mints are halted" needs the rest of the sentence.

mintsHalted and mintsHaltedReason are on GET /v1/usdhb with the same scope stated in the field's own description.

A halt does not clear itself. When the attestation check is what halted them, mints are halted until the check passes and an operator resumes them. There is no self clear, so a passing attestation alone is not the signal to watch for.

Testnet notes

Everything above is running on testnet, and testnet USDhb has no value. Sign up is open, and an account is all you need: USDhb lives inside one.

Test sats come from the faucet (POST /v1/faucet), which is rate limited per hour. When you have used your grants the response says so and tells you to try again next hour; it is a limit, not a failure.

The token rail is not live yet. USDhb balances are engine side today, and the page marks the Spark token row as not issued rather than showing an identifier that does not exist.

Program policy v1 · numbers current as of 2026-09-11

Testnet: test sats have no value. Nothing on this page is an offer, a solicitation, or advice.

Program policy v1 · numbers current as of 2026-09-11
Testnet: test sats have no value. Nothing here is an offer, a solicitation, or advice.