heirloom-vault.clar is the single Clarity 4 contract that implements all Heirloom vault logic. There is no proxy, no upgradeability pattern, and no admin key. What is deployed is what runs.
Contract identity
| Property | Value |
|---|---|
| Language | Clarity 4 (epoch: latest) |
| Contract name | heirloom-vault-v10 |
| Deployer (testnet) | STZJWVYSKRYV1XBGS8BZ4F81E32RHBREQSE5WAJM |
| Full identifier (testnet) | STZJWVYSKRYV1XBGS8BZ4F81E32RHBREQSE5WAJM.heirloom-vault-v10 |
Stacks does not allow overwriting deployed contracts. If a new version is deployed, it must use a new contract name (e.g.,
heirloom-vault-v11). Each version is immutable once on-chain.What the contract does
The contract manages the full lifecycle of an inheritance vault:Vault creation
Registers a vault for the calling principal with a heartbeat interval, grace period, heir list with basis-point splits, and an optional guardian address.
Deposits
Accepts sBTC and USDCx from the vault owner. Uses Clarity 4
restrict-assets? with with-ft to enforce exact transfer amounts as post-conditions within the contract itself.Heartbeat
Records
stacks-block-time as last-heartbeat when the vault owner signs a transaction. Resets the countdown in any non-distributed state.Claims
Transfers each heir’s proportional share of sBTC and USDCx when the vault is claimable. Uses
as-contract? with with-ft for contract-authorized outbound transfers.Emergency withdrawal
Returns all vault assets to the owner instantly, closing the vault. Available at any time before full distribution.
Guardian pause
Allows the designated guardian to extend the effective deadline by 30 days during the grace period, once per vault lifetime.
Architecture
Data model
The contract stores four maps:vaults— keyed by owner principal, holds all vault configuration and balances.heirs— keyed by(owner, heir)pair, stores each heir’ssplit-bpsallocation.heir-list— keyed by owner principal, stores the ordered list of up to 10 heir addresses.heir-claimed— keyed by(owner, heir)pair, tracks whether each heir has claimed.
Access control
All authorization is enforced viatx-sender checks — there are no role registries or permission tables:
| Actor | Permitted actions |
|---|---|
Owner (tx-sender == vault key) | heartbeat, deposit-sbtc, deposit-usdcx, emergency-withdraw, update-heirs |
Heir (present in heirs map) | claim (only when vault is claimable) |
Guardian (tx-sender == vault.guardian) | guardian-pause (once, only during grace period) |
State computation
Vault state is not stored as an enum. There is no on-chainstate field. The get-vault-status read-only function derives state on every call from stacks-block-time and last-heartbeat:
elapsed = stacks-block-time − last-heartbeat and deadline = heartbeat-interval + grace-period + (2,592,000 if guardian-pause-used, else 0).
This means the state returned by get-vault-status is always current — no separate transaction is required to advance state, and there is no window where a vault appears active but is secretly claimable.
Clarity 4 features used
stacks-block-time
A Clarity 4 keyword that returns the current Stacks block timestamp as a uint. Used everywhere a timestamp is needed: recording last-heartbeat, computing elapsed, and deriving vault state.
stacks-block-time is a consensus-level value, it cannot be manipulated by the caller or a miner without controlling a block.
restrict-assets? with with-ft
Used in deposit-sbtc and deposit-usdcx to enforce post-conditions within the contract. This prevents callers from submitting transactions that transfer a different amount than the deposit function expects.
as-contract? with with-ft
Used in claim and emergency-withdraw to authorize outbound token transfers from the contract’s own balance. The contract itself becomes the tx-sender for the inner transfer call.
current-contract
Used as the recipient address in deposit calls so that the contract receives the transferred tokens into its own principal balance.
Clarity safety properties
Clarity’s language design provides guarantees that are directly relevant to a contract holding user funds:- Interpreted, not compiled — the source code you read on-chain is exactly what the network executes. There is no compiler that introduces unexpected behavior.
- Decidable — you can statically verify contract behavior before deployment. There are no unbounded loops or dynamic dispatch.
- Reentrancy-safe — Clarity prevents reentrant calls by design. A contract cannot call back into itself mid-execution, eliminating an entire class of DeFi exploits.
Vault re-creation
After a vault is fully distributed (all heirs claimed) or cancelled (owner calledemergency-withdraw), the owner may create a new vault from the same address. The contract allows this because it checks is-distributed before blocking creation:
reset-heir-claim so previous claim records do not block new heirs from claiming in the future.
