See also: STATUS_MAPPING.md for cross-layer status mapping · EVENTS.md for event schema · WORKFLOWS.md for state transitions
This document outlines the core data structures and key-value storage layout of the VaultixEscrow smart contract.
The primary structure returned by public query entrypoints.
pub struct Escrow {
pub depositor: Address,
pub recipient: Address,
pub token_address: Address,
pub total_amount: i128,
pub total_released: i128,
pub milestones: Vec<Milestone>,
pub status: EscrowStatus,
pub deadline: u64,
pub resolution: Resolution,
pub threshold_amount: i128,
pub required_signatures: u32,
pub collected_signatures: Vec<Address>,
pub metadata_hash: BytesN<32>,
}The internal persisted representation for the current escrow storage layout.
- Stored under
("esc2", escrow_id)asEscrowEntryV2. - Includes the packed escrow state, fee override metadata, and all fields required for migration.
- When a legacy
Escrowentry exists under("escrow", escrow_id), the contract migrates it lazily on first access. - A companion version marker is stored under
("escver", escrow_id)as au8.
struct EscrowEntryV2 {
depositor: Address,
recipient: Address,
token_address: Address,
total_amount: i128,
total_released: i128,
milestones: Vec<Milestone>,
packed_state: u32,
deadline: u64,
threshold_amount: i128,
required_signatures: u32,
collected_signatures: Vec<Address>,
fee_override_bps: i128,
metadata_hash: BytesN<32>,
}- On-chain
metadata_hashis exactly 32 raw bytes. - Off-chain clients should represent the same value as lowercase 64-character hex.
- The canonical bytes are the SHA-256 digest bytes, not the CID string bytes.
- For IPFS references, clients should decode the CID multihash and extract the 32-byte
sha2-256digest. - The all-zero digest is rejected as malformed input.
- Preferred display form:
ipfs://<cid>. - Preferred write path: CIDv1 base32 using
sha2-256. - Interop rule: backend/frontend normalize either a raw 32-byte hex digest or an IPFS CID into the same lowercase 64-character hex string, then pass those bytes on-chain.
- Determinism requirement: the metadata payload must be serialized identically before upload; otherwise a new CID and digest will be produced.
Represents an individual chunk of the total payout.
pub struct Milestone {
pub amount: i128, // The payout amount for this milestone
pub status: MilestoneStatus, // Pending, Released, or Disputed
pub description: Symbol, // Short description or identifier
}Represents a pending two-step admin transfer (see "Admin Transfer (Two-Step
Handshake)" in README.md).
pub struct AdminProposal {
pub new_admin: Address, // Address waiting to become admin
pub expires_at: u64, // Ledger timestamp after which accept_admin() fails
}Enumerates all the potential states an Escrow can be in:
Created: Initialized but unfunded.Active: Funded and active.Completed: All milestones released.Cancelled: Terminated early, funds refunded.Disputed: Frozen due to a dispute.Resolved: Settlement reached via arbitration.Expired: Deadline passed, funds refunded to depositor.
Used to pause the contract's standard workflows.
Active: Contract functioning normally.Paused: Circuit breaker engaged; deposits/releases halted.
The contract utilizes both Instance and Persistent storage on Soroban.
Holds global configuration data required frequently.
treasury(Symbol): (Address) The fee collection address.fee_bps(Symbol): (i128) The global default fee in basis points.state(Symbol): (ContractState) Current operational state (Active/Paused).
Holds longer-term state, retaining data specifically for individual escrows and specific roles.
admin(Symbol): (Address) The contract admin.admprop(Symbol): (AdminProposal) Pending two-step admin transfer created bypropose_admin; expires (becomes un-acceptable) afterADMIN_PROPOSAL_WINDOW_SECSledger seconds and is removed on a successfulaccept_adminor acancel_admin_proposal.operator(Symbol): (Address) The emergency operator.arbitrator(Symbol): (Address) The dispute resolution arbitrator.("escrow", id: u64): (Escrow) Legacy escrow record format, migrated on access.("esc2", id: u64): (EscrowEntryV2) Current escrow record format with packed state and fee override metadata.("escver", id: u64): (u8) Explicit V2 escrow version marker companion value.("tokfee", token: Address): (i128) A token-specific fee BPS override.("escfee", escrow_id: u64): (i128) An escrow-specific fee BPS override.("dispev", escrow_id: u64): (BytesN<32>) Evidence digest recorded byraise_dispute, written only for disputed escrows and given the same TTL as the escrow entry.("disprev", escrow_id: u64): (BytesN<32>) Optional resolution evidence digest recorded by the arbitrator inresolve_dispute.