Soroban smart contract for LiquiFact: holds investor funds for a tokenized invoice until settlement, supports investor payout claims after settlement, and includes governance-controlled compliance and attestation features.
This repo is a Cargo workspace containing a single contract crate:
escrow/→ the Soroban contractliquifact_escrow.
At a high level, each escrow instance represents one invoice funding round and supports a lifecycle:
-
Initialize (
init)- Configures:
admin(governance-controlled)sme_address(beneficiary receiving liquidity on settlement)- invoice identifier (
invoice_id) - funding parameters (
amount,yield_bps,maturity) - bound contracts/addresses:
funding_token(SEP-41) +treasury - optional features: registry hint, tiered yield ladder, contribution floor, investor caps, allowlist gating, legal-hold clear delay, funding deadline
- Configures:
-
Fund (
fund,fund_with_commitment,fund_batch)- Investors add principal while the escrow is open.
- Supports:
- per-investor maximum cap (
max_per_investor) - optional global cap on distinct funders (
max_unique_investors) - optional minimum contribution per call (
min_contribution) - optional investor allowlist gate
- optional tiered yield/commitment lock discipline via first-deposit-only configuration
- per-investor maximum cap (
- When
funded_amount >= funding_target, escrow transitions to funded and writes a write-once pro-rata snapshot (FundingCloseSnapshot).
-
Settle (
partial_settle,settle)- SME finalizes the deal after funding is reached.
- If configured, settlement requires ledger time to be past
maturity. - Legal hold blocks settlement.
-
Withdraw (
withdraw)- SME pulls the funded liquidity when the escrow is in the correct state.
- Legal hold blocks withdrawal.
-
Investor payout claims (
claim_investor_payout)- After settlement, investors claim that they are eligible for a payout.
- Claim gating includes optional commitment lock expiration (ledger timestamp based).
- The per-investor “claimed” marker is idempotent and prevents event re-emission.
-
Cancel + Refund (
cancel_funding,refund)- Admin can cancel only when open.
- Investors can refund their principal in the cancelled state.
-
Treasury dust sweep (
sweep_terminal_dust)- Treasury can sweep bounded “residue” tokens from this contract only in terminal states (settled/withdrawn/cancelled).
- For cancelled escrows, a liability floor ensures sweeps cannot pull below outstanding investor obligations.
admin: controls governance actions (legal hold, allowlist configuration, cap lowering, admin handover, etc.).sme_address: authorizes settlement/withdraw flows; also beneficiary rotation.investor: authorizes funding and payout claim.treasury: authorizes dust sweep.
- An admin can activate
LegalHoldto block settlement, SME withdrawal, investor claims, etc. - Clearing requires the current admin authorization.
- No built-in break-glass bypass—production deployments should use a governed/multisig admin.
- Cross-contract token movement is performed only through a funding token address set at
init. - Transfers are enforced with strict SEP-41-style balance delta checks:
- sender balance decreases by exactly
amount - recipient (treasury) balance increases by exactly
amount
- sender balance decreases by exactly
- Fee-on-transfer, rebasing, and hook-modifying tokens are treated as out-of-scope and should fail at the balance-check boundary.
- The contract provides
compute_investor_payout(env, investor)implementing the authoritative pro-rata formula documented indocs/escrow-pro-rata.md. - A write-once
FundingCloseSnapshotanchors denominators for fairness and determinism.
SCHEMA_VERSIONis stored on-chain underDataKey::Version.- Current schema version: 6.
migrateis intentionally not implemented in the current release; it aborts with typed errors in all current paths.
-
Lifecycle & funding:
initfundfund_with_commitmentfund_batchpartial_settlesettle
-
SME and investor flows:
withdrawclaim_investor_payout
-
Admin/governance & compliance:
set_legal_hold,clear_legal_holdrequest_clear_legal_holdset_allowlist_active,set_investor_allowlisted,set_investors_allowlistedlower_max_unique_investorsrotate_beneficiarypropose_admin,accept_admincancel_funding
-
Token maintenance:
sweep_terminal_dust
-
Attestation / audit logging:
bind_primary_attestation_hashappend_attestation_digestrevoke_attestation_digest
-
Read APIs:
get_escrow,get_escrow_summaryget_contributionget_funding_close_snapshotget_versionget_legal_hold,get_*helperscompute_investor_payout
This is a Rust + Soroban contract crate.
Typical commands:
cargo build
cargo testFor WASM builds:
rustup target add wasm32v1-none
cargo build --target wasm32v1-none --release -p liquifact_escrowThe docs/ folder contains operator and audit-oriented documentation, including:
- security checklists and the auth model (
docs/escrow-security-checklist.md,docs/adr/ADR-002-auth-boundaries.md) - pro-rata payout math and rounding (
docs/escrow-pro-rata.md) - legal hold details (
docs/escrow-legal-hold.md) - token integration assumptions (
docs/ESCROW_TOKEN_INTEGRATION_CHECKLIST.md) - operator deployment runbooks (
docs/OPERATOR_RUNBOOK.md) - EVM/Soroban mental model and storage/TTL notes
The repository is MIT licensed.