Production-ready Soroban smart contract for USDC remittance platform on Stellar blockchain.
SwiftRemit is an escrow-based remittance system that enables secure cross-border money transfers using USDC stablecoin. The platform connects senders with registered agents who handle fiat payouts, with the smart contract managing escrow, fee collection, and settlement.
- Escrow-Based Transfers: Secure USDC deposits held in contract until payout confirmation
- Agent Network: Registered agents handle fiat distribution off-chain
- Automated Fee Collection: Platform fees calculated and accumulated automatically
- Lifecycle State Management: Remittances tracked through 5 states (Pending, Processing, Completed, Cancelled, Failed) with enforced transitions
- Authorization Security: Role-based access control for all operations
- Event Emission: Comprehensive event logging for off-chain monitoring
- Cancellation Support: Senders can cancel pending remittances with full refund
- Admin Controls: Platform fee management and fee withdrawal capabilities
- lib.rs: Main contract implementation with all public functions
- types.rs: Data structures (Remittance, RemittanceStatus)
- transitions.rs: State transition validation and enforcement
- storage.rs: Persistent and instance storage management
- errors.rs: Custom error types for contract operations
- events.rs: Event emission functions for monitoring
- test.rs: Comprehensive test suite with 15+ test cases
- test_transitions.rs: Lifecycle transition tests
- Instance Storage: Admin, USDC token, fee configuration, counters, accumulated fees
- Persistent Storage: Individual remittances, agent registrations
Fees are calculated in basis points (bps):
- 250 bps = 2.5%
- 500 bps = 5.0%
- Formula:
fee = amount * fee_bps / 10000
initialize(admin, usdc_token, fee_bps)- One-time contract initializationregister_agent(agent)- Add agent to approved list (admin only)remove_agent(agent)- Remove agent from approved list (admin only)update_fee(fee_bps)- Update platform fee percentage (admin only)withdraw_fees(to)- Withdraw accumulated fees (admin only)
create_remittance(sender, agent, amount)- Create new remittance (sender auth required)start_processing(remittance_id)- Mark remittance as being processed (agent auth required)confirm_payout(remittance_id)- Confirm fiat payout (agent auth required)mark_failed(remittance_id)- Mark payout as failed with refund (agent auth required)cancel_remittance(remittance_id)- Cancel pending remittance (sender auth required)
get_remittance(remittance_id)- Retrieve remittance detailsget_accumulated_fees()- Check total platform fees collectedis_agent_registered(agent)- Verify agent registration statusget_platform_fee_bps()- Get current fee percentage
- Authorization Checks: All state-changing operations require proper authorization
- Status Validation: Prevents double confirmation and invalid state transitions
- Overflow Protection: Safe math operations with overflow checks
- Agent Verification: Only registered agents can receive payouts
- Ownership Validation: Senders can only cancel their own remittances
The contract includes comprehensive tests covering:
- ✅ Initialization and configuration
- ✅ Agent registration and removal
- ✅ Fee updates and validation
- ✅ Remittance creation with proper token transfers
- ✅ Payout confirmation and fee accumulation
- ✅ Cancellation logic and refunds
- ✅ Fee withdrawal by admin
- ✅ Authorization enforcement
- ✅ Error conditions (invalid amounts, unauthorized access, double confirmation)
- ✅ Event emission verification
- ✅ Multiple remittances handling
- ✅ Fee calculation accuracy
Run tests with:
cargo testRun the deployment script to build, deploy, and initialize everything automatically:
Linux/macOS:
chmod +x deploy.sh
./deploy.sh
# To deploy to a specific network (default: testnet):
./deploy.sh mainnetWindows (PowerShell):
.\deploy.ps1
# To deploy to a specific network (default: testnet):
.\deploy.ps1 -Network mainnetThis will:
- Build and optimize the contract
- Create/fund a
deployeridentity - Deploy the contract and a mock USDC token
- Initialize the contract
- Save contract IDs to
.env.local
If you prefer to run steps manually:
cd SwiftRemit
cargo build --target wasm32-unknown-unknown --release
soroban contract optimize --wasm target/wasm32-unknown-unknown/release/swiftremit.wasmsoroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/swiftremit.optimized.wasm \
--source deployer \
--network testnetsoroban contract invoke \
--id <CONTRACT_ID> \
--source deployer \
--network testnet \
-- \
initialize \
--admin <ADMIN_ADDRESS> \
--usdc_token <USDC_TOKEN_ADDRESS> \
--fee_bps 250See DEPLOYMENT.md for complete deployment instructions.
SwiftRemit enforces strict state transitions to ensure remittance integrity:
- Pending: Initial state after creation
- Processing: Agent has started working on the payout
- Completed: Successfully settled (terminal)
- Cancelled: Cancelled by sender (terminal)
- Failed: Payout failed with refund (terminal)
Pending → Processing → Completed (successful flow)
Pending → Cancelled (early cancellation)
Processing → Failed (failed payout)
- Remittances must go through
Processingbefore completion - Senders can only cancel
Pendingremittances - Terminal states (Completed, Cancelled, Failed) cannot be changed
- All transitions emit events for monitoring
See LIFECYCLE_TRANSITIONS.md for complete documentation
-
Admin Setup
- Deploy contract
- Initialize with admin address, USDC token, and fee percentage
- Register trusted agents
-
Create Remittance
- Sender approves USDC transfer to contract
- Sender calls
create_remittancewith agent and amount - Contract transfers USDC from sender to escrow
- Remittance ID returned for tracking (status: Pending)
-
Agent Payout
- Agent calls
start_processingto signal work has begun (status: Processing) - Agent pays out fiat to recipient off-chain
- Agent calls
confirm_payoutwith remittance ID (status: Completed) - Contract transfers USDC minus fee to agent
- Fee added to accumulated platform fees
- Agent calls
-
Alternative Flows
- Early Cancellation: Sender calls
cancel_remittancewhile Pending - Failed Payout: Agent calls
mark_failedduring Processing (full refund)
- Early Cancellation: Sender calls
-
Fee Management
- Admin monitors accumulated fees
- Admin calls
withdraw_feesto collect platform revenue
| Code | Error | Description |
|---|---|---|
| 1 | AlreadyInitialized | Contract already initialized |
| 2 | NotInitialized | Contract not initialized |
| 3 | InvalidAmount | Amount must be greater than 0 |
| 4 | InvalidFeeBps | Fee must be between 0-10000 bps |
| 5 | AgentNotRegistered | Agent not in approved list |
| 6 | RemittanceNotFound | Remittance ID does not exist |
| 7 | InvalidStatus | Operation not allowed in current status |
| 8 | Overflow | Arithmetic overflow detected |
| 9 | NoFeesToWithdraw | No accumulated fees available |
The contract emits events for monitoring:
created- New remittance createdcompleted- Payout confirmed and settledcancelled- Remittance cancelled by senderagent_reg- Agent registeredagent_rem- Agent removedfee_upd- Platform fee updatedfees_with- Fees withdrawn by admin
soroban-sdk = "21.7.0"- Latest Soroban SDK
MIT
For issues and questions:
- GitHub Issues: Create an issue
- Stellar Discord: https://discord.gg/stellar
- Documentation: See DEPLOYMENT.md
Contributions welcome! Please ensure:
- All tests pass:
cargo test - Code follows Rust best practices
- New features include tests
- Documentation is updated
- Multi-currency support
- Batch remittance processing
- Agent reputation system
- Dispute resolution mechanism
- Time-locked escrow options
- Integration with fiat on/off ramps
SwiftRemit is a Soroban smart contract built in Rust that enables secure, escrow-based USDC remittances on the Stellar network.
The contract allows users to send USDC into escrow, assigns registered payout agents, and releases funds once off-chain fiat payment is confirmed. A configurable platform fee is automatically deducted and retained by the protocol.
This project is designed for emerging markets where stablecoin remittance rails can significantly reduce cross-border payment costs.
SwiftRemit implements a simple escrow flow:
- A sender creates a remittance by depositing USDC.
- A registered agent pays the recipient in local fiat off-chain.
- The agent confirms payout on-chain.
- The contract releases USDC to the agent minus a platform fee.
- The platform accumulates fees for withdrawal by the admin.
The system is designed to be secure, transparent, and modular.
- Escrow-based remittance logic
- Agent registration system
- Configurable platform fee (basis points model)
- Secure authorization using Soroban Address auth
- Protection against double confirmation
- Cancellation mechanism for pending remittances
- Accumulated fee withdrawal by admin
- Full unit test coverage
The contract stores:
- Remittance records
- Registered agents
- Admin address
- Platform fee configuration
- Accumulated platform fees
- USDC token address
Each remittance includes:
- Unique ID
- Sender address
- Agent address
- Amount
- Fee
- Status (Pending, Completed, Cancelled)
Platform fees are calculated using basis points: