Skip to content
Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

212 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

StellarSettle Logo

StellarSettle Smart Contracts

Soroban smart contracts powering decentralized invoice financing on Stellar

License: MIT Stellar Rust CI Coverage Status

πŸ“‹ Overview

This repository contains the core Soroban smart contracts that power StellarSettle's decentralized invoice financing platform. These contracts handle:

  • Invoice Escrow: Secure escrow creation, funding, and settlement
  • Invoice Tokens: SEP-41 compliant tokenization of invoices
  • Payment Distribution: Lifecycle-driven payout fan-out for seller, investor, and platform fee
  • Emergency Pause: Admin-controlled stop switches for escrow and token operations

πŸ—οΈ Architecture

contracts/
β”œβ”€β”€ invoice-escrow/       # Main escrow contract
β”œβ”€β”€ invoice-token/        # Invoice tokenization (SEP-41)
└── payment-distributor/  # Settlement & distribution logic

πŸš€ Quick Start

Prerequisites

  • Rust 1.74+
  • Soroban CLI
  • Stellar account (testnet/mainnet)

Windows: Rust uses the MSVC toolchain by default. Install Visual Studio Build Tools with the β€œDesktop development with C++” workload so link.exe is available. (VS Code alone is not sufficient.)

Installation

# Install Soroban CLI
cargo install --locked soroban-cli --features opt

# Install dependencies
cargo build

# Run tests
cargo test

# Build contracts
soroban contract build

Deployment

Repeatable deployment scripts live in scripts/. See the How to run scripts section below for full instructions.

The scripts deploy and initialise all three contracts, then wire invoice-escrow to payment-distributor so settlement and refund payouts run through the distributor flow by default.

πŸ“š Contract Documentation

Invoice Escrow Contract

// Create new invoice escrow
pub fn create_escrow(
    env: Env,
    invoice_id: Symbol,
    seller: Address,
    amount: i128,
    due_date: u64,
    payment_token: Address
)

// Fund escrow (investor buys invoice)
pub fn fund_escrow(
    env: Env,
    invoice_id: Symbol,
    buyer: Address
)

// Record payment and distribute funds
pub fn record_payment(
    env: Env,
    invoice_id: Symbol,
    payer: Address,
    amount: i128
)

Full API documentation: docs/API.md

πŸ“œ How to run scripts

1. Prerequisites

  • Soroban CLI installed (cargo install --locked soroban-cli --features opt)
  • Contracts compiled: soroban contract build

2. Configure environment variables

# Copy the template and fill in your values
cp .env.example .env
$EDITOR .env   # set STELLAR_SECRET_KEY, ADMIN_PUBLIC_KEY, STELLAR_NETWORK, etc.

See .env.example for the full list of variables and their descriptions.

⚠️ Never commit .env to version control. It is already listed in .gitignore.

3a. Bash (macOS / Linux)

# Run from the repo root
bash scripts/deploy.sh

The script:

  1. Loads .env automatically
  2. Validates all required variables and WASM paths
  3. Deploys invoice-token, invoice-escrow, and payment-distributor in order
  4. Calls initialize on each contract with the configured arguments
  5. Calls invoice-escrow.set_payment_distributor(...) to enable distributor-based payouts
  6. Prints a summary of deployed contract IDs

3b. PowerShell (Windows)

# Allow script execution for this session (if not already set)
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

# Run from the repo root
.\scripts\deploy.ps1

The PowerShell script is functionally equivalent to the Bash script above.

Re-using existing contract IDs

If a contract is already deployed and only needs re-initialisation, set its ID in .env:

INVOICE_ESCROW_CONTRACT_ID=C...
INVOICE_TOKEN_CONTRACT_ID=C...
PAYMENT_DISTRIBUTOR_CONTRACT_ID=C...

The deploy step is skipped for any contract whose ID is pre-filled; initialize is still called, and the escrow-to-distributor wiring step still runs.

πŸ§ͺ Testing

# Run all tests
cargo test

# Run specific contract tests
cargo test --package invoice-escrow

# Run with output
cargo test -- --nocapture

# Coverage report
cargo tarpaulin --out Html

πŸ”’ Security

  • Audit Status: Smart contracts audit prep in progress. Formal security audit schedule trackable via SECURITY.md.
  • Automated Analysis: Continuous security scanning via GitHub Actions (Cargo Audit, Clippy, Tarpaulin).
  • Responsible Disclosure: Please report security vulnerabilities to security@stellarsettle.com. See SECURITY.md for vulnerability disclosure guidelines.
  • Bug Bounty Program: Active community bounties managed via GitHub Issues & Opire.

πŸ“Š Contract Addresses

Contract IDs are dynamically generated at the end of each deploy.sh / deploy.ps1 execution and persisted to .env.

Testnet

Refer to .env.example and your local .env configuration generated after running:

# Execute deployment script to generate contract IDs
bash scripts/deploy.sh

Contract IDs generated upon deployment:

  • Invoice Escrow: INVOICE_ESCROW_CONTRACT_ID (see .env)
  • Invoice Token: INVOICE_TOKEN_CONTRACT_ID (see .env)
  • Payment Distributor: PAYMENT_DISTRIBUTOR_CONTRACT_ID (see .env)

Mainnet

  • Scheduled after audit completion and formal security sign-off.

🀝 Contributing

We welcome contributions! Please read our Contributing Guide before submitting a Pull Request.

Important: All Pull Requests must target the dev branch. See our branching workflow for details.

πŸ“„ License

MIT License - see LICENSE file for details

πŸ”— Links


Implemented initial updates to the test suite to align with the new soroban-sdk 27.x ContractEvents API:

Replaced direct events.last() calls with events.events().last() where appropriate. Updated length checks to use .events().len(). Adjusted iterator usage for event verification, switching to .events().iter() and .events().rev() as needed. Modified event loop logic to work with the new slice‑based API (events_after.get(i)). These changes address the compilation errors caused by the breaking API change. Further refactoring may be needed for remaining events.last() and iterator patterns.

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages