Four Soroban smart contracts powering the TrusTrove trade finance protocol on Stellar.
Live App · App Repo · Stellar Explorer
TrusTrove is a decentralized trade finance protocol on Stellar. SMEs tokenize unpaid invoices and receive immediate USDC funding from a shared liquidity pool. Liquidity providers deposit USDC and earn yield from discount fees when invoices repay. No banks, no brokers — four Soroban smart contracts handle everything.
| Name | Role | GitHub | Telegram | |
|---|---|---|---|---|
| Fuhad (K1NGD4VID) | Founder & Lead Developer | @k1ngd4vid | @k1ngd4vid |
Join the contributor community: t.me/trusttrove
Tracks verified SME issuers and buyers. Every other contract calls is_verified() before allowing any action.
initialize(admin)
register_issuer(address, metadata) → bool
register_buyer(address, metadata) → bool
is_verified(address) → bool
get_profile(address) → Profile
revoke(address) → bool
Manages the full invoice lifecycle. Enforces valid state transitions. Emits events consumed by the Go indexer.
Created → Listed → Funded → Active → Confirmed → Repaid
↘ Defaulted
create(issuer, buyer, face_value, due_date) → invoice_id
list_for_financing(invoice_id, discount_bps) → bool
mark_funded(invoice_id, funded_amount) → bool ← pool_contract only
mark_shipped(invoice_id) → bool
confirm_delivery(invoice_id, confirmer) → bool ← dual confirmation required
repay(invoice_id) → bool
trigger_default(invoice_id) → bool
get(invoice_id) → Invoice
get_by_status(status) → Vec<Invoice>
get_by_issuer(address) → Vec<Invoice>
Holds USDC between pool funding and issuer payout. Only callable by pool_contract.
lock(invoice_id, amount) → bool
release_to_issuer(invoice_id) → bool
release_to_pool(invoice_id, repayment_amount) → bool
handle_default(invoice_id) → bool
get_locked(invoice_id) → u128
USDC liquidity pool with share-based LP accounting. Share price grows as invoices repay.
deposit(lp, usdc_amount) → shares
withdraw(lp, shares) → usdc_amount
fund_invoice(invoice_id) → bool
receive_repayment(invoice_id, amount) → bool ← invoice_contract only
handle_default(invoice_id) → bool
get_stats() → PoolStats
get_lp_position(address) → LPPosition
| Contract | Address |
|---|---|
| registry_contract | CABGWVIZFF62FG67ZGFEP67NEEY4WYTMFURDMFTKKNRDAFPKPOJDTN4C |
| invoice_contract | CA4O3MR7LWHRSUDBNU6FY6UDFFYBN7TGBZXBDZB4OYYXFYXIFJ6RJF6B |
| escrow_contract | CAJWGUKDTTC3SKN4RAAY72J4DVIIYSCFHX6GIMNTT22ABMISJK4GBCEH |
| pool_contract | CAKEWH7SJCXGV2MH2WZYIX3QDPTSSBQFXYVYBOWAGLNBBZMPLE2US6CS |
Verify on Stellar Expert Testnet
- Rust 1.85.0 (required — other versions either have WASM bugs or are blocked by Stellar CLI)
- Stellar CLI (latest)
rustup toolchain install 1.85.0
rustup target add wasm32v1-none --toolchain 1.85.0git clone https://github.com/TrusTrove/TrusTrove-contract.git
cd TrusTrove-contract
rustup run 1.85.0 stellar contract buildcargo test --workspace# Create and fund a deployer account
bash scripts/setup-testnet.sh
# Fund via browser: https://friendbot.stellar.org/?addr=YOUR_ADDRESS
# Deploy all four contracts
bash scripts/deploy.shThe deploy script prints all four contract IDs at the end. Paste them into TrusTrove-app/.env.local.
We welcome contributions from Rust and Soroban developers. Read CONTRIBUTING.md before opening a PR.
Issues are labeled by contract and complexity:
complexity:low— isolated function or test, good entry pointcomplexity:medium— touches contract logic and storagecomplexity:high— cross-contract interactions or new mechanics
- All amounts use
u128in stroops (1 USDC = 10,000,000) - All timestamps use
u64Unix seconds - Every
persistent().set()must be followed byextend_ttl() - Use
panic_with_error!with typed errors — no barepanic!orunwrap()in production paths
feat(registry): add batch issuer registration function
fix(pool): guard against division by zero when total_shares is 0
test(invoice): add full lifecycle integration test
If you have questions, reach us on Telegram: t.me/trusttrove
MIT
