Skip to content

btorressz/construction_escrow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

construction_escrow

πŸ—οΈ Construction Escrow Protocol

🌐 Overview

The Construction Escrow Program is a Solana smart contract built with the Anchor framework.
It manages escrow accounts between buyers and sellers of construction materials, ensuring funds are only released after verified delivery.

It supports milestones, multi-oracle verification, time-locks, retention (holdbacks), NFT receipts, and dispute resolution.
A comprehensive TypeScript test suite is included to demonstrate account setup, PDA derivation, and step-by-step validation.

Note: This project was developed as a proof of concept for a client researching how construction escrow systems could be implemented on blockchain, specifically leveraging the Solana ecosystem. The goal was to explore transparency, automation, and trustless settlement for large-scale material contracts.


βš™οΈ Constants

  • MAX_ORACLES = 8 β†’ maximum number of oracles/verifiers per project.
  • MAX_MILESTONES = 10 β†’ maximum number of payment milestones.
  • QUORUM_MIN = 1 β†’ minimum quorum for oracle verification.

πŸ“¦ Accounts

πŸ”Ή Config

Holds global configuration for the protocol.
Fields:

  • authority β†’ current admin authority of the market.
  • pending_authority β†’ new authority waiting to be accepted.
  • treasury β†’ PDA that collects protocol fees.
  • insurance_treasury β†’ PDA that collects insurance fees.
  • fee_bps β†’ base protocol fee (basis points).
  • insurance_bps β†’ insurance fund fee (basis points).
  • retention_bps β†’ % held back as retention until warranty ends.
  • warranty_days β†’ warranty period in days.
  • quorum_m β†’ required quorum (M-of-N) for oracle verification.
  • arbiter β†’ designated dispute resolver.

πŸ”Ή Escrow

Represents a construction project escrow account.
Fields:

  • project_id β†’ unique identifier.
  • buyer, seller β†’ counterparties.
  • mint β†’ SPL token used for payment.
  • config β†’ reference to Config PDA.
  • amount β†’ total escrowed amount.
  • fee_bps, insurance_bps, retention_bps β†’ copied from Config at creation.
  • late_penalty_bps β†’ optional penalty for late delivery.
  • price_snapshot_1e6 β†’ price snapshot (USD notional, 6 decimals).
  • quorum_m β†’ quorum required for verification.
  • oracles β†’ array of oracle pubkeys.
  • state β†’ escrow state machine:
    • Open
    • Verified
    • PartiallyReleased
    • Released
    • Refunded
    • Dispute
  • created_ts, verified_ts, released_ts β†’ lifecycle timestamps.
  • verify_by_ts, deliver_by_ts β†’ deadlines.
  • warranty_end_ts β†’ timestamp when retention can be released.
  • milestones β†’ fixed array of milestone structs.
  • last_evidence_hash β†’ SHA-256 evidence (docs, photos).
  • attestations_count β†’ number of attestations attached.
  • cancel_requested_by β†’ if cancel was requested, stores who requested.
  • dispute_open β†’ flag for dispute state.
  • nft_enabled β†’ whether to issue an NFT receipt.
  • receipt_nft_mint β†’ mint address for NFT receipt.
  • in_transfer β†’ reentrancy guard.
  • retention_released β†’ true once retention is paid out.

πŸ”Ή Milestone

Represents a stage payment.
Fields:

  • id β†’ milestone index.
  • amount β†’ payment amount.
  • verified β†’ true once verified by oracles.
  • released β†’ true once funds are released.
  • verify_ts β†’ timestamp when verified.
  • evidence_hash β†’ SHA-256 hash of delivery evidence.

πŸ”Ή ProjectIndex

Maps project_id β†’ escrow PDA for quick lookups.


πŸ”Ή Attestation

Represents an external attestation (e.g., inspector note).
Fields:

  • escrow β†’ escrow it belongs to.
  • attester β†’ signer.
  • hash β†’ SHA-256 evidence hash.
  • uri96 β†’ optional URI prefix (truncated to 96 bytes).
  • ts β†’ timestamp.

πŸ› οΈ Instructions (Functions)

πŸ”§ Config & Authority

  • init_config β†’ initialize Config PDA.
  • update_fee_splits β†’ update fee % and insurance %.
  • transfer_market_authority_propose β†’ propose new authority.
  • transfer_market_authority_accept β†’ accept authority transfer.

πŸ’° Escrow Lifecycle

  • create_escrow(project_id, buyer, seller, amount, oracles, quorum_m, price_snapshot, nft_enabled)
    Creates a new escrow, transfers buyer’s tokens to a PDA vault.

  • set_deadlines(verify_by_ts, deliver_by_ts)
    Set verification and delivery deadlines.

  • mark_in_progress()
    Seller marks project as started.

  • expire_and_refund()
    Refund buyer if verification not done by deadline.


βœ… Verification & Milestones

  • verify_delivery(project_id)
    Verifies delivery using M-of-N oracle signatures.

  • add_milestone(amount, evidence_hash)
    Add a milestone with supporting evidence.

  • verify_milestone(milestone_id)
    Verify a milestone with oracle quorum.

  • release_for_milestone(milestone_id)
    Release funds for a verified milestone (fees + penalties applied).

  • release_payment()
    Release all remaining funds (minus retention).

  • release_retention()
    Release retention after warranty ends.


🚫 Cancel & Dispute

  • request_cancel() β†’ buyer/seller requests cancel.
  • approve_cancel() β†’ counterparty approves cancel β†’ buyer refunded.
  • open_dispute(reason_code, evidence_hash) β†’ open a dispute.
  • resolve_dispute(outcome, seller_pct_bps) β†’ arbiter resolves dispute (refund, release, split).

πŸ“œ Evidence & Compliance

  • attach_evidence(hash, uri) β†’ attach evidence to escrow.
  • add_attestation(hash, uri) β†’ add inspector or third-party attestation.

πŸͺͺ NFT Receipts

  • init_receipt_nft() β†’ mint a soulbound NFT as buyer’s receipt.
  • finalize_receipt_nft(burn: bool) β†’ burn or unfreeze NFT at final release.

πŸ”’ Authority & Oracles

  • update_oracles(new_oracles, new_quorum_m) β†’ update oracle set.
  • update_seller_dest(new_seller) β†’ update seller payout destination.

⏱️ Timeout Processing

  • process_timeouts(limit) β†’ cron-friendly function to auto-refund expired escrows.

πŸ§ͺ Tests (TypeScript)

The test suite demonstrates:

  1. Mint & ATA setup

    • Creates SPL mint and funds buyer.
    • Ensures all ATAs exist.
  2. Config initialization

    • Creates Config PDA with fees, retention, warranty.
  3. Escrow creation

    • Derives PDAs (escrow, vault_authority, project_index).
    • Transfers buyer tokens into vault.
  4. Milestone flow

    • Adds milestone, verifies with oracle quorum.
    • Releases funds, applying fees + insurance cut.
  5. Final release & retention

    • Releases payment to seller.
    • Holds retention until warranty ends, then releases.
  6. Failure case

    • Tries to release before verification β†’ fails with expected error logs.

βœ… Each step uses assertions and console logs to confirm state transitions and balances.
βœ… Program Derived Addresses (PDAs) are derived exactly as in Rust using seeds.
βœ… Errors are captured with try/catch and full transaction logs printed for debugging.


πŸ” Safety Features

  • Reentrancy Guard β†’ prevents double-spending during transfers.
  • Quorum Verification β†’ requires multiple oracle signatures.
  • Retention β†’ ensures buyer protection after delivery.
  • Dispute Resolution β†’ arbiter can refund, release, or split funds.
  • Timeout Refunds β†’ auto-refunds if deadlines expire.

πŸ“Š Example Flow

  1. πŸ›’ Buyer funds escrow.

  2. πŸ“¦ Seller marks project in progress.

  3. 🧾 Oracles verify delivery (or milestones).

  4. πŸ’Έ Funds released (fees + insurance deducted).

  5. ⏳ Retention held until warranty ends.

  6. πŸͺͺ Buyer receives NFT receipt.

  7. βš–οΈ If dispute, arbiter resolves with refund/release/split.


    🎯 Conclusion

This program is a robust escrow system for construction projects.
It combines milestone-based payments, oracle verification, retention, NFT receipts, and dispute resolution.

The provided TypeScript test shows full setup, execution, and debugging flow on Solana Playground.


About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors