Configuration
Hashi keeps its onchain configuration in two key-value stores on the Hashi
object, distinguished by when a change takes effect:
- Instant config (
config): values apply the moment the proposal that changes them executes. Deposit and withdrawal minimums, the confirmation threshold, the pause flag, and the guardian settings live here. - Epoch config (
epoch_config): each reconfiguration copies the whole store onto the committee it forms, and nodes read these values from their committee's pinned copy. A change lands in the next committee formed after the proposal executes and never alters the active committee. The MPC parameters live here.
UpdateConfig (instant) and UpdateEpochConfig (epoch) tune existing
parameters. Both require 2/3 of committee weight, accept only
keys that already exist in their store, and reject a change of value type.
AddConfig introduces new keys; it names the store and is insert-only
(see Adding a parameter and
Governance Actions).
Configuration keys at a glance
Every key documented below, with its type and default where one exists:
| Key | Type | Default | Section |
|---|---|---|---|
bitcoin_deposit_minimum | u64 | 30000 | Parameters |
bitcoin_deposit_time_delay_ms | u64 | 600000 | Parameters |
bitcoin_withdrawal_minimum | u64 | 30000 | Parameters |
bitcoin_confirmation_threshold | u64 | 6 | Parameters |
paused | bool | false | Parameters |
reconfig_hold | bool | false | Parameters |
withdrawal_cancellation_cooldown_ms | u64 | 3600000 | Parameters |
governance_emergency_pause_threshold_bps | u64 | 500 | Parameters |
governance_emergency_unpause_threshold_bps | u64 | 6667 | Parameters |
mpc_max_faulty_in_basis_points | u64 | 3333 | MPC parameters |
mpc_weight_reduction_allowed_delta | u64 | 800 | MPC parameters |
mpc_nonce_accumulation_window_ms | u64 | 2000 | MPC parameters |
guardian_url | string | Set at launch | Read-only or genesis-only parameters |
guardian_node_url | string | Set at launch | Read-only or genesis-only parameters |
bitcoin_chain_id | address | Pinned at launch | Read-only or genesis-only parameters |
guardian_btc_public_key | bytes | Pinned at launch | Read-only or genesis-only parameters |
The epoch config refuses the retired keys mpc_threshold_in_basis_points and
mpc_nonce_generation_protocol. deposit_minimum and worst_case_network_fee
are derived values, computed from the keys above rather than
stored.
Parameters
bitcoin_deposit_minimum
| Key | bitcoin_deposit_minimum |
| Type | u64 |
| Default | 30000 |
| Unit | satoshis |
| Floor | 546 (dust relay minimum) |
The minimum deposit amount in satoshis. The contract rejects deposits below this value
onchain. The effective value is always at least 546 sats to prevent creating
unspendable UTXOs.
bitcoin_deposit_time_delay_ms
| Key | bitcoin_deposit_time_delay_ms |
| Type | u64 |
| Default | 600000 (10 minutes) |
| Unit | milliseconds |
The minimum time that must elapse between the committee approving a deposit
(approve_deposit) and anyone confirming it (confirm_deposit). Provides
a window in which operators can detect a fraudulent or erroneous approval and
pause the service before the contract mints any hBTC. See the
deposit flow for how this delay fits into the overall
process. hashi launch --bitcoin-deposit-time-delay-ms can set a different
starting value; on Sui Mainnet it refuses one below the default.
bitcoin_withdrawal_minimum
| Key | bitcoin_withdrawal_minimum |
| Type | u64 |
| Default | 30000 |
| Unit | satoshis |
| Floor | 547 (dust relay minimum + 1) |
The minimum total withdrawal amount in satoshis. Hashi derives
worst_case_network_fee as max(bitcoin_withdrawal_minimum, 547) - 546, which caps the
per-user miner fee deduction. Because the effective withdrawal minimum is never
below the 547 floor, the worst-case network fee is always at least 1 sat,
even if governance sets bitcoin_withdrawal_minimum lower.
bitcoin_confirmation_threshold
| Key | bitcoin_confirmation_threshold |
| Type | u64 |
| Default | 6 |
| Unit | blocks |
The number of Bitcoin block confirmations nodes require before approving a
deposit (at least 100 for a coinbase output, matching Bitcoin's own coinbase
maturity rule rather than a Hashi-specific override) and before confirming a
withdrawal transaction. Guards against chain reorganizations.
hashi launch --bitcoin-confirmation-threshold can set a different starting
value; on Sui Mainnet it refuses one below the default.
paused
| Key | paused |
| Type | bool |
| Default | false |
When true, the contract refuses new deposit and withdrawal requests, and every step
that advances a queued request aborts. Each node also refuses to sign for deposits and
withdrawals (not in the 1.0 releases). Requests already in the queue resume
processing when governance unpauses the system, but users can still cancel withdrawal
requests after the cooldown, and deposit requests can still expire.
Reconfiguration and governance actions are not affected. Anyone can still broadcast a
withdrawal fully signed before the pause, and a committee member can still finish one the
guardian already signed. The pause doesn't stop the guardian; its operator can stop it
separately.
reconfig_hold
| Key | reconfig_hold |
| Type | bool |
| Default | false |
When true, start_reconfig aborts on chain, so no new committee can form.
This is how governance keeps the last committed committee serving after an
abort or a missed Sui epoch boundary,
for example while operators fix the cause of a stall so the replacement does
not stall the same way. The flag gates only committee formation: a reconfiguration
already pending still completes or aborts as usual, and deposits and
withdrawals continue. Nodes read the flag and do not submit
start_reconfig while it is set; they report it as hashi_reconfig_hold.
Set and cleared with an UpdateConfig proposal. Clearing it lifts the gate
but does not itself start a reconfiguration: nodes submit start_reconfig on
a Sui epoch change, on an abort, and at startup, so the replacement waits for
the next Sui epoch change unless an operator runs
hashi committee start-reconfig.
withdrawal_cancellation_cooldown_ms
| Key | withdrawal_cancellation_cooldown_ms |
| Type | u64 |
| Default | 3600000 (1 hour) |
| Unit | milliseconds |
The minimum time a withdrawal request must remain in the queue before the user can cancel it. Prevents users from using rapid submit-cancel cycles to interfere with processing.
governance_emergency_pause_threshold_bps
| Key | governance_emergency_pause_threshold_bps |
| Type | u64 |
| Default | 500 (5%) |
| Unit | basis points of committee voting weight |
The vote threshold for an emergency pause proposal. Deliberately low so a
small fraction of the committee can quickly halt deposit and withdrawal
processing when something looks wrong. One basis point is one hundredth of a
percent of total committee voting weight, so 500 is 5% of that weight and
10000 would be all of it.
governance_emergency_unpause_threshold_bps
| Key | governance_emergency_unpause_threshold_bps |
| Type | u64 |
| Default | 6667 (66.67%, about two thirds) |
| Unit | basis points of committee voting weight |
The vote threshold for the unpause variant of the same proposal. Resuming operation requires a supermajority.
MPC parameters
The MPC parameters live in the epoch config, and UpdateEpochConfig tunes
them. Reconfiguration pins the store onto each committee it forms, so a change
mid-epoch never affects the active committee; new values take effect when the
next committee forms. The contract checks each key's range when a member
creates a proposal and again when it executes. It checks the rule that
mpc_weight_reduction_allowed_delta stays below
mpc_max_faulty_in_basis_points only at execution, on the
resulting store, so move both keys in one proposal when one would cross the
other. The epoch config also refuses the retired keys
mpc_threshold_in_basis_points and mpc_nonce_generation_protocol.
At execution, the proposal checks this invariant on the resulting epoch config:
mpc_weight_reduction_allowed_delta < mpc_max_faulty_in_basis_points
mpc_max_faulty_in_basis_points
| Key | mpc_max_faulty_in_basis_points |
| Type | u64 |
| Default | 3333 |
| Valid range | 1 to 3333, and above mpc_weight_reduction_allowed_delta |
| Unit | basis points of committee voting weight |
The assumed upper bound on faulty (offline or adversarial) committee weight. Hashi derives the MPC protocol parameters under the assumption that at most this fraction of weight misbehaves.
mpc_weight_reduction_allowed_delta
| Key | mpc_weight_reduction_allowed_delta |
| Type | u64 |
| Default | 800 |
| Valid range | 0 up to, but not including, mpc_max_faulty_in_basis_points |
| Unit | basis points |
Committee voting weights are proportionally reduced (compressed) before the
MPC protocol runs, because each unit of weight corresponds to a share and
protocol cost scales with total shares. Reduction necessarily distorts
relative voting power; this parameter bounds the distortion, allowing the
effective fault-tolerance assumption to shift by at most this many basis
points relative to the unreduced committee. 0 still allows a reduction, but
only one with no liveness slack: any set of members that could reach a
threshold before reduction still can. Members' relative weights can still
change.
mpc_nonce_accumulation_window_ms
| Key | mpc_nonce_accumulation_window_ms |
| Type | u64 |
| Default | 2000 |
| Valid range | 0 to 10000 |
| Unit | milliseconds |
How long nodes keep collecting nonce dealer certificates after the certified
dealers reach the W − f weight floor.
Read-only or genesis-only parameters
bitcoin_chain_id
| Key | bitcoin_chain_id |
| Type | address |
The 32-byte Bitcoin chain identifier as defined by
BIP-122
(the genesis block hash). Set at launch (finish_publish) and not updatable
through the UpdateConfig proposal.
guardian_btc_public_key
| Key | guardian_btc_public_key |
| Type | bytes |
The guardian's x-only BTC public key (32 bytes), pinned at launch
(finish_publish). Every 2-of-2 deposit address derives from it, so it
is write-once and not updatable through the UpdateConfig proposal. The
guardian's URLs remain governable: guardian_url, its public endpoint, and
guardian_node_url, the endpoint nodes call. A node resolves
guardian_node_url once, so it picks up a change only after a restart.
Derived values
Hashi computes several values from the configurable parameters above rather than storing them directly. They are not config keys: read the underlying keys and apply the formulas below.
deposit_minimum
deposit_minimum = max(bitcoin_deposit_minimum, 546)
The minimum deposit amount. With defaults: 30,000 sats.
worst_case_network_fee
worst_case_network_fee = max(bitcoin_withdrawal_minimum, 547) - 546
The largest share of a withdrawal transaction's miner fee that each request in
it might pay, derived from bitcoin_withdrawal_minimum minus the dust
threshold. With defaults: 30,000 - 546 = 29,454 sats per request.
Adding a parameter without a package upgrade
The Move package reads only the keys documented on this page; any other key
is opaque to it, and the node software consumes it. To make a node-side
setting governable, pass an AddConfig proposal naming the key, its initial
value (which fixes the key's type for later updates), and the store: the epoch
config when every node must agree on the value for the whole epoch, the
instant config otherwise. A node reads an absent key as its built-in default,
so you can add the key before or after the node release that consumes it.