Skip to main content
This vault’s exit leaf is a NUMS key that nobody can sign. If the operator is unavailable, holders have no exit path: their virtual outputs cannot be spent, renewed, or exited. See Exit.
A tokenized vault pools deposits and issues each depositor one share token per sat. Holders redeem shares through a proposal that a guardian can veto. The vault is one contract that plays four roles, each its own output: a deposit address, the pool, a withdrawal address, and a staging output. The pool holds the vault’s control token on every spend. The operator lets an asset’s supply grow only when the transaction also spends its control asset, so only a spend of the pool can issue shares. Every path pins how many shares it issues or burns. The prediction market’s vault does this:
contracts/src/market_vault.ark @ c0b063f

Deposit

The deposit address names where the shares arrive. It is this contract with kind 0. Anyone sends sats to it, and the first deposit opens the pool. When the payment arrives, one spend consumes the whole output. 330 sats stay on the share output, and the first deposit leaves 330 sats in the pool as its carrier. The rest is one share per sat. A later deposit is another send to the same address. It keeps 330 sats on the new share output, and the rest is one share per sat. The pool keeps the control token and continues. An asset sent to that address cannot move.

Share

A share is a token on the script that the deposit address named. One share is one sat above the pool carrier. The share is the claim. The pool does not know the holder’s key, and no spend asks for the holder’s signature. The pool issues shares on the deposit path only and burns them on the disburse path only. A share moves like any other asset, so a claim changes hands without a spend of the pool.

Withdrawal

The holder sends shares to the withdrawal address. The address is the proposal. It is this contract with kind 2. The constructor names the payout scripts and the one split. The output carries 330 sats and exactly that split. For a redemption, that is the holder’s own script. For a pot, it is first, second, and third place. The send is the authorization, and the pool does not ask who sent it.

Staging

The next spend seals the proposal in a staging output. The sats leave the pool, and the shares sit beside them. The shares are not burned yet.

Veto

A guardian can only cancel. The cancel returns the sats to the pool and the shares to the script named in the constructor. The guardian cannot take the sats and cannot change the split.

Disburse

If nobody cancels, the split is paid to the named scripts and the shares burn, one sat per share. Anyone can build this spend, because a covenant needs only the operator’s and the emulator’s signatures. Building the burn is not a vote. The guardian’s veto is the only decision in the script.

Clocks

The contract enforces no deadlines. The application decides when deposits close and how long the guardian has to veto. disburse has no timelock, so anyone can disburse as soon as the staging output exists. A veto window holds only if every party that can build the disburse waits for it.

Contract

The constructor names one share script and one split. kind is 0 for the deposit, 1 for the pool, 2 for the withdrawal, and 3 for staging. A second split is a second vault. shareScript, holderScript, and the payout scripts are 32-byte witness programs. Set guardian and noExitKey before you fund. noExitKey is the BIP341 NUMS point, so nobody can sign the exit. An unused place is 0, place 2 and place 3 pay more than 330 sats, and place 1 also receives the 330 carrier. open and arrive issue the shares, propose seals staging, veto needs the guardian, and disburse pays the split and burns the shares.
tokenized.ark
unilateral is the NUMS exit leaf (Exit).