Skip to main content
A Vault is the foundational treasury contract in FlowGuard. Every streaming, distribution, or governance covenant links back to a Vault via vaultId. The Vault enforces multi-party control over funds without any custodian.

How Vaults Work

Key Parameters

ParameterTypeDescription
vaultIdbytes32Unique identifier linking covenants to this vault
requiredApprovalsintM in M-of-N (currently max 2-of-3 pre-Loops CHIP)
signer1Hashbytes20hash160 of signer 1 pubkey
signer2Hashbytes20hash160 of signer 2 pubkey
signer3Hashbytes20hash160 of signer 3 pubkey
periodDurationintSeconds per spending period (0 = no period cap)
periodCapintMax satoshis spendable per period (0 = unlimited)
recipientCapintMax satoshis per single spend (0 = unlimited)
allowlistEnabledint1 = only allowedAddr1/2/3 can receive funds
allowedAddr1/2/3bytes20Recipient allowlist (up to 3 addresses pre-Loops CHIP)

NFT State Layout (32 bytes)

Byte 0:    version (uint8)
Byte 1:    status  (0=ACTIVE, 1=PAUSED, 2=EMERGENCY_LOCK, 3=MIGRATING)
Bytes 2-4: rolesMask (3 bytes)
Bytes 5-8: current_period_id (uint32)
Bytes 9-16: spent_this_period (uint64, satoshis)
Bytes 17-24: last_update_timestamp (uint64, unix seconds)
Bytes 25-31: reserved

Functions

Called by any M signers simultaneously. Verifies two distinct signers from the registered set, enforces period cap, recipient cap, and allowlist. Automatically rolls the period forward if periodDuration has elapsed.
spend(sig sig1, pubkey pubkey1, sig sig2, pubkey pubkey2,
      bytes32 proposalId, bytes20 recipientHash, int payoutAmount,
      int newPeriodId, int newSpent)
Any registered signer can call this after periodDuration has elapsed. Resets spent_this_period to 0 and increments current_period_id. Does not move any funds.
Any single registered signer can pause the vault immediately. Use for fast incident response. Resume requires M-of-N.
Requires M-of-N signers. Transitions status from PAUSED back to ACTIVE.
Requires all 3 registered signers simultaneously. Transitions to EMERGENCY_LOCK. No spending path is available from this state in the current contract version.
Emergency lock is irreversible in the current contract version. Deploy a new vault if recovery is needed after an emergency lock.

Spending Roles

WhoCan Do
Any single signerpause(), unlockPeriod()
M-of-N signersspend(), resume()
All N signersemergencyLock()
No oneOverride covenant math, skip period cap
Pre-Loops CHIP, the vault hardcodes a maximum of 3 signers. Post-Loops CHIP activation will allow arbitrary N via dynamic signer arrays.