Stellar Soroban smart contracts for the RemitWise remittance platform.
This workspace contains the core smart contracts that power RemitWise's post-remittance financial planning features:
- remittance_split: Automatically splits remittances into spending, savings, bills, and insurance
- savings_goals: Goal-based savings with target dates and locked funds
- bill_payments: Automated bill payment tracking and scheduling
- insurance: Micro-insurance policy management and premium payments
- family_wallet: Family governance, multisig approvals, and emergency transfer controls
- remitwise-common: Shared types and utilities used across contracts
A common crate containing shared types, enums, and constants used across multiple contracts.
Shared Types:
Category: Financial categories (Spending, Savings, Bills, Insurance)FamilyRole: Access control roles (Owner, Admin, Member, Viewer)CoverageType: Insurance coverage types (Health, Life, Property, Auto, Liability)EventCategory&EventPriority: Event logging categories and priorities
Shared Constants:
- Pagination limits (
DEFAULT_PAGE_LIMIT,MAX_PAGE_LIMIT) - Storage TTL values (
INSTANCE_LIFETIME_THRESHOLD,ARCHIVE_LIFETIME_THRESHOLD, etc.) - Contract versioning (
CONTRACT_VERSION) - Batch operation limits (
MAX_BATCH_SIZE)
Shared Utilities:
clamp_limit(): Helper for pagination limit validationRemitwiseEvents: Standardized event emission withemit()andemit_batch()methods
A custom Rust CLI is provided for interacting with the contracts without a UI.
See cli/README.md for usage instructions.
- indexer: TypeScript event indexer for off-chain querying and analytics (Documentation)
- analytics: On-chain analytics and reporting
- orchestrator: Cross-contract coordination
- reporting: Financial reporting and insights
- Rust (latest stable version)
- Stellar CLI (soroban-cli)
- Cargo
These contracts have been developed and tested with the following versions:
- Soroban SDK:
21.0.0 - Soroban CLI:
21.0.0 - Rust Toolchain:
stable(withwasm32-unknown-unknownandwasm32v1-nonetargets) - Protocol Version: Compatible with Stellar Protocol 20+ (Soroban Phase 1)
- Network: Testnet and Mainnet ready
| Component | Version | Status | Notes |
|---|---|---|---|
| soroban-sdk | 21.0.0 | ✅ Tested | Current stable release |
| soroban-cli | 21.0.0 | ✅ Tested | Matches SDK version |
| Protocol 20 | - | ✅ Compatible | Soroban Phase 1 features |
| Protocol 21+ | - | Should be compatible, validation recommended |
When a new Soroban SDK or protocol version is released, follow these steps to validate and upgrade:
Check the Soroban SDK releases for:
- Breaking changes in contract APIs
- New features or optimizations
- Deprecated functions
- Protocol version requirements
Update the SDK version in all contract Cargo.toml files:
[dependencies]
soroban-sdk = "X.Y.Z"
[dev-dependencies]
soroban-sdk = { version = "X.Y.Z", features = ["testutils"] }Contracts to update:
remittance_split/Cargo.tomlsavings_goals/Cargo.tomlbill_payments/Cargo.tomlinsurance/Cargo.tomlfamily_wallet/Cargo.tomldata_migration/Cargo.tomlreporting/Cargo.tomlorchestrator/Cargo.toml
cargo install --locked --version X.Y.Z soroban-cliVerify installation:
soroban version# Clean build artifacts
cargo clean
# Run all tests
cargo test
# Run gas benchmarks to check for performance regressions
./scripts/run_gas_benchmarks.shDeploy contracts to testnet and run integration tests:
# Build optimized contracts
cargo build --release --target wasm32-unknown-unknown
# Deploy to testnet
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/<contract_name>.wasm \
--source <your-key> \
--network testnet
# Test contract interactions
soroban contract invoke \
--id <contract-id> \
--source <your-key> \
--network testnet \
-- <function-name> <args>Common breaking changes to watch for:
- Storage API changes: TTL management, archival patterns
- Event emission: Topic structure or data format changes
- Authorization: Auth context or signature verification changes
- Numeric types: Changes to
i128,u128, or fixed-point math - Contract lifecycle: Initialization or upgrade patterns
After successful validation:
- Update this compatibility section with new versions
- Document any migration steps in
DEPLOYMENT.md - Update code examples if APIs changed
- Regenerate contract bindings if needed
No breaking changes from previous stable releases affecting these contracts.
- Protocol 21+: May introduce new storage pricing or TTL requirements
- SDK 22.0.0+: Monitor for changes to contract storage patterns, event APIs, or authorization flows
The contracts are designed to be compatible with:
- Testnet: Currently running Protocol 20+
- Mainnet: Currently running Protocol 20+
Check current network protocol versions:
# Testnet
soroban network container logs stellar 2>&1 | grep "protocol version"
# Or via RPC
curl -X POST https://soroban-testnet.stellar.org \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getNetwork","params":[]}'Build Errors After Upgrade:
# Clear all caches
cargo clean
rm -rf target/
rm Cargo.lock
# Rebuild
cargo build --release --target wasm32-unknown-unknownTest Failures:
- Check for deprecated test utilities in SDK release notes
- Verify mock contract behavior hasn't changed
- Review event emission format changes
Deployment Issues:
- Ensure CLI version matches SDK version
- Verify network is running compatible protocol version
- Check for new deployment flags or requirements
If you encounter issues with a specific Soroban version:
- Check existing GitHub Issues
- Verify your environment matches tested versions
- Create a minimal reproduction case
- Report with version details and error logs
- UPGRADE_GUIDE.md - Comprehensive upgrade procedures and version-specific migration guides
- VERSION_COMPATIBILITY.md - Detailed compatibility matrix and testing status
- COMPATIBILITY_QUICK_REFERENCE.md - Quick reference for common compatibility tasks
- .github/SOROBAN_VERSION_CHECKLIST.md - Validation checklist for new versions
# Install Soroban CLI
cargo install --locked --version 21.0.0 soroban-cli
# Build all contracts
cargo build --release --target wasm32-unknown-unknownThe workspace includes runnable examples for each contract in the examples/ directory. These examples demonstrate basic read and write operations using the Soroban SDK test environment.
To run an example, use cargo run --example <example_name>:
| Contract | Example Command |
|---|---|
| Remittance Split | cargo run --example remittance_split_example |
| Savings Goals | cargo run --example savings_goals_example |
| Bill Payments | cargo run --example bill_payments_example |
| Insurance | cargo run --example insurance_example |
| Family Wallet | cargo run --example family_wallet_example |
| Reporting | cargo run --example reporting_example |
| Orchestrator | cargo run --example orchestrator_example |
Note
These examples run in a mocked environment and do not require a connection to a Stellar network.
- Family Wallet Design (as implemented)
- Frontend Integration Notes
- Storage Layout Reference
- Event Indexer - Off-chain event indexing and querying
- Tagging Feature - Tag-based organization system
- Threat Model - Security analysis and mitigations
- Security Review Summary
Handles automatic allocation of remittance funds into different categories.
Key Functions:
initialize_split: Set percentage allocation (spending, savings, bills, insurance)get_split: Get current split configurationcalculate_split: Calculate actual amounts from total remittance
Events:
SplitInitializedEvent: Emitted when split configuration is initializedspending_percent,savings_percent,bills_percent,insurance_percent,timestamp
SplitCalculatedEvent: Emitted when split amounts are calculatedtotal_amount,spending_amount,savings_amount,bills_amount,insurance_amount,timestamp
Manages goal-based savings with target dates.
Key Functions:
create_goal: Create a new savings goal (education, medical, etc.)add_to_goal: Add funds to a goalget_goal: Get goal detailsis_goal_completed: Check if goal target is reachedarchive_completed_goals: Archive completed goals to reduce storageget_archived_goals: Query archived goalsrestore_goal: Restore archived goal to active storagecleanup_old_archives: Permanently delete old archivesget_storage_stats: Get storage usage statistics
Events:
GoalCreatedEvent: Emitted when a new savings goal is createdgoal_id,name,target_amount,target_date,timestamp
FundsAddedEvent: Emitted when funds are added to a goalgoal_id,amount,new_total,timestamp
GoalCompletedEvent: Emitted when a goal reaches its target amountgoal_id,name,final_amount,timestamp
Tracks and manages bill payments with recurring support.
Key Functions:
-
create_bill: Create a new bill (electricity, school fees, etc.) with optionalexternal_ref -
create_bill: Create a new bill (electricity, school fees, etc.) -
pay_bill: Mark a bill as paid and create next recurring bill if applicable -
set_external_ref: Owner-only update/clear for billexternal_ref -
get_unpaid_bills: Get all unpaid bills -
get_total_unpaid: Get total amount of unpaid bills -
archive_paid_bills: Archive paid bills to reduce storage -
get_archived_bills: Query archived bills -
restore_bill: Restore archived bill to active storage -
bulk_cleanup_bills: Permanently delete old archives -
get_storage_stats: Get storage usage statistics
Events:
BillCreatedEvent: Emitted when a new bill is createdbill_id,name,amount,due_date,recurring,timestamp
BillPaidEvent: Emitted when a bill is marked as paidbill_id,name,amount,timestamp
RecurringBillCreatedEvent: Emitted when a recurring bill generates the next billbill_id,parent_bill_id,name,amount,due_date,timestamp
Manages micro-insurance policies and premium payments.
Key Functions:
-
create_policy: Create a new insurance policy with optionalexternal_ref -
create_policy: Create a new insurance policy -
pay_premium: Pay monthly premium -
set_external_ref: Owner-only update/clear for policyexternal_ref -
get_active_policies: Get all active policies -
get_total_monthly_premium: Calculate total monthly premium cost -
deactivate_policy: Deactivate an insurance policy
Bill and insurance events include external_ref where applicable for off-chain linking.
Events:
PolicyCreatedEvent: Emitted when a new insurance policy is createdpolicy_id,name,coverage_type,monthly_premium,coverage_amount,timestamp
PremiumPaidEvent: Emitted when a premium is paidpolicy_id,name,amount,next_payment_date,timestamp
PolicyDeactivatedEvent: Emitted when a policy is deactivatedpolicy_id,name,timestamp
Bill and insurance events include external_ref where applicable for off-chain linking.
Manages family roles, spending controls, multisig approvals, and emergency transfer policies.
Key Functions:
init: Initialize owner, members, default multisig configs, and emergency settingsadd_member/update_spending_limit: Manage role assignments and per-member spending limitsconfigure_multisig,propose_transaction,sign_transaction: Configure and execute multisig-gated actionswithdraw: Execute direct or multisig withdrawal depending on configured thresholdconfigure_emergency,set_emergency_mode,propose_emergency_transfer: Configure and run emergency transfer pathspause,unpause,set_pause_admin: Operational control switchesarchive_old_transactions,cleanup_expired_pending,get_storage_stats: Storage maintenance and observability
For full design details, see docs/family-wallet-design.md.
All contracts emit events for important state changes, enabling real-time tracking and frontend integration. Events follow Soroban best practices and include:
- Relevant IDs: All events include the ID of the entity being acted upon
- Amounts: Financial events include transaction amounts
- Timestamps: All events include the ledger timestamp for accurate tracking
- Context Data: Additional contextual information (names, dates, etc.)
Each contract uses short symbol topics for efficient event identification:
- Remittance Split:
init,calc - Savings Goals:
created,added,completed - Bill Payments:
created,paid,recurring - Insurance:
created,paid,deactive - Family Wallet:
added/member,updated/limit,emerg/*,wallet/*
Events can be queried from the Stellar network using the Soroban SDK or via the Horizon API for frontend integration. Each event structure is exported and can be decoded using the contract's schema.
Run tests for all contracts:
cargo testRun tests for a specific contract:
cd remittance_split
cargo testMulti-contract integration tests verify that all contracts work together correctly:
# Run all integration tests
cargo test -p integration_tests
# Run with output
cargo test -p integration_tests -- --nocaptureThe integration tests simulate real user flows:
- Deploy all contracts (remittance_split, savings_goals, bill_payments, insurance)
- Initialize split configuration
- Create goals, bills, and policies
- Calculate split and verify amounts align with expectations
See integration_tests/README.md for detailed documentation.
Verify that allocations across contracts are consistent with remittance splits:
python3 scripts/verify_cross_contract_invariants.pySee scripts/README_INVARIANT_TESTS.md for details.
cargo test -p remittance_splitexercises the USDC distribution logic with a mocked Stellar Asset Contract (env.register_stellar_asset_contract_v2) and built-in auth mocking.- The suite covers minting the payer account, splitting across spending/savings/bills/insurance, and asserting balances along with the new allocation metadata helper.
- The same command is intended for CI so it runs without manual setup; re-run locally whenever split logic changes or new USDC paths are added.
RemitWise includes a comprehensive gas benchmarking harness for tracking and optimizing contract performance.
Run all benchmarks and generate a JSON report:
./scripts/run_gas_benchmarks.shThis creates gas_results.json with CPU and memory costs for all contract operations.
Compare current results against baseline to detect performance regressions:
./scripts/compare_gas_results.sh benchmarks/baseline.json gas_results.jsonThe comparison fails if CPU or memory increases exceed configured thresholds (default 10%).
After verifying optimizations:
./scripts/update_baseline.sh- Benchmarking Guide: Complete benchmarking documentation
- Gas Optimization Guide: Optimization strategies and best practices
- Baseline Results: Current performance baseline
- Threshold Configuration: Regression detection thresholds
Gas benchmarks run automatically in CI on every push and pull request. Results are:
- Compared against baseline for regression detection
- Uploaded as artifacts (retained for 30 days)
- Posted as PR comments with comparison details
To view CI results:
- Go to Actions tab in GitHub
- Select a workflow run
- Download the
gas-benchmarksartifact - View
gas_results.jsonfor metrics
Run benchmarks for a specific contract:
RUST_TEST_THREADS=1 cargo test -p bill_payments --test gas_bench -- --nocapture
RUST_TEST_THREADS=1 cargo test -p savings_goals --test gas_bench -- --nocapture
RUST_TEST_THREADS=1 cargo test -p insurance --test gas_bench -- --nocapture
RUST_TEST_THREADS=1 cargo test -p family_wallet --test gas_bench -- --nocapture
RUST_TEST_THREADS=1 cargo test -p remittance_split --test gas_bench -- --nocaptureThe fastest way to deploy all contracts with sensible defaults:
# Deploy to testnet with default settings
./scripts/bootstrap_deploy.sh testnet deployer
# Skip building if contracts are already built
SKIP_BUILD=1 ./scripts/bootstrap_deploy.sh testnet deployer
# Deploy to mainnet
./scripts/bootstrap_deploy.sh mainnet deployer
# Custom output file location
OUTPUT_FILE=./my-contracts.json ./scripts/bootstrap_deploy.sh testnet deployerThe bootstrap script will:
- Build all WASM artifacts (unless SKIP_BUILD=1)
- Deploy each contract via soroban-cli
- Initialize contracts with sensible defaults:
- Remittance split: 50% spending, 30% savings, 15% bills, 5% insurance
- One example savings goal
- One example bill
- One example insurance policy
- Output contract IDs in a JSON file (default:
deployed-contracts.json)
The generated JSON file can be easily consumed by frontend/backend:
{
"network": "testnet",
"deployer": "GXXXXXXX...",
"deployed_at": "2024-01-15T10:30:00Z",
"contracts": {
"remittance_split": "CXXXXXXX...",
"savings_goals": "CXXXXXXX...",
"bill_payments": "CXXXXXXX...",
"insurance": "CXXXXXXX...",
"family_wallet": "CXXXXXXX...",
"reporting": "CXXXXXXX...",
"orchestrator": "CXXXXXXX..."
}
}See the Deployment Guide for comprehensive manual deployment instructions.
Quick deploy to testnet:
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/remittance_split.wasm \
--source <your-key> \
--network testnetID and record-count operating limits (including u32 overflow analysis and monitoring alerts) are documented in the Operational Limits and Monitoring section of ARCHITECTURE.md.
This is a basic MVP implementation. Future enhancements:
- Integration with Stellar Asset Contract (USDC)
- Cross-contract calls for automated allocation
- Multi-signature support for family wallets
- Emergency mode with priority processing
A comprehensive security review and threat model is available in THREAT_MODEL.md. This document identifies:
- Critical Assets: User funds, configuration, identity, and data
- Threat Scenarios: Unauthorized access, reentrancy, DoS, economic attacks
- Existing Mitigations: Authorization patterns, pause mechanisms, input validation
- Security Gaps: Areas requiring immediate attention before mainnet deployment
Key Security Issues:
- [SECURITY-001] Add Authorization to Reporting Contract Queries (HIGH)
- [SECURITY-002] Implement Reentrancy Protection in Orchestrator (HIGH)
- [SECURITY-003] Add Rate Limiting to Emergency Transfers (HIGH)
- [SECURITY-004] Replace Checksum with Cryptographic Hash (MEDIUM)
- [SECURITY-005] Implement Storage Bounds and Entity Limits (MEDIUM)
See the .github/ISSUE_TEMPLATE directory for detailed security issue descriptions.
When integrating with these contracts:
- Always verify caller authorization before performing sensitive operations
- Monitor events for suspicious activity patterns
- Implement rate limiting at the application layer
- Use multi-signature for high-value operations
- Regular security audits before major releases
- Incident response plan for security events
If you discover a security vulnerability, please email [email protected] instead of using the public issue tracker.
MIT