Soroban smart contracts powering the StellarSend global money transfer platform. All contracts are written in Rust and deployed on the Stellar network.
- Architecture Overview
- Contracts
- Getting Started
- Building
- Testing
- Deployment
- Contract API Reference
- Events
- Security
- Contributing
- License
┌─────────────────────────────────────────────────────────┐
│ User / dApp │
└──────────────────────┬──────────────────────────────────┘
│ send_payment / send_path_payment
▼
┌─────────────────────────────────────────────────────────┐
│ stellar_send (Entry Point) │
│ │
│ • Validates sender + amount │
│ • Deducts protocol fee (bps) │
│ • Routes payment to recipient │
│ • Emits PaymentSent / PathPaymentSent events │
└─────────┬───────────────────────────┬───────────────────┘
│ forward fee │ DEX path swap
▼ ▼
┌──────────────────────┐ ┌─────────────────────────────┐
│ fee_collector │ │ token_bridge │
│ │ │ │
│ • Accumulates fees │ │ • wrap / unwrap assets │
│ • Admin withdrawal │ │ • Enables cross-asset │
│ • Per-token totals │ │ path payments │
└──────────────────────┘ └─────────────────────────────┘
The system is intentionally modular: stellar_send is the only contract that end users interact with directly. fee_collector and token_bridge are infrastructure contracts managed by the protocol admin.
Path: contracts/stellar_send/
The main entry point for the StellarSend protocol. Supports direct token transfers and DEX path payments between any Stellar addresses.
| Feature | Description |
|---|---|
| Direct payments | Transfer any SEP-41 token from sender to recipient |
| Path payments | Route through the Stellar DEX for cross-asset transfers |
| Fee deduction | Protocol fee in basis points (bps), deducted at source |
| Pause / unpause | Admin can halt new payments in an emergency |
| Payment records | Every transfer is stored on-ledger for auditability |
| Admin rotation | Two-step admin handover (propose → accept) |
Key data types:
pub struct ContractConfig {
pub admin: Address,
pub fee_bps: u32, // 100 bps = 1%
pub fee_collector: Address,
pub active: bool,
pub min_amount: i128,
pub max_amount: i128,
}
pub struct PaymentRecord {
pub from: Address,
pub to: Address,
pub token: Address,
pub net_amount: i128,
pub fee_amount: i128,
pub memo: String,
pub ledger: u32,
}Path: contracts/fee_collector/
Receives protocol fees forwarded by stellar_send and allows the treasury admin to withdraw accumulated balances.
| Feature | Description |
|---|---|
| Fee accounting | Tracks lifetime totals collected per token |
| Withdrawal | Admin-only; supports arbitrary recipient |
| Treasury management | Treasury address updatable by admin |
| Period limits | Configurable withdrawal limit per epoch |
| Multi-token | Operates on any SEP-41 token |
Path: contracts/token_bridge/
A lightweight wrap / unwrap bridge for non-native Stellar assets. Users deposit an underlying token and receive an equal amount of wrapped tokens, enabling cross-asset path payments through the StellarSend DEX flow.
| Feature | Description |
|---|---|
| wrap | Deposit underlying → receive wrapped balance |
| unwrap | Burn wrapped balance → receive underlying |
| Bridge fee | Configurable bps fee on wrap operations |
| Supply cap | Configurable maximum wrapped supply |
| Pause / unpause | Admin can halt wrapping in an emergency |
| Admin rotation | Two-step admin handover |
| Tool | Version | Install |
|---|---|---|
| Rust | stable (see rust-toolchain.toml) |
curl https://sh.rustup.rs -sSf | sh |
| Soroban CLI | ≥ 21.0.0 | cargo install --locked soroban-cli |
| wasm32 target | — | rustup target add wasm32-unknown-unknown |
git clone https://github.com/StellarSend/contracts.git
cd contractsThe workspace Cargo.toml pins all dependency versions. No additional install step is required.
Build all contracts to WASM:
make build
# or directly:
bash scripts/build.shIndividual contract:
soroban contract build --package stellar_send
soroban contract build --package fee_collector
soroban contract build --package token_bridgeCompiled WASM files are written to target/wasm32-unknown-unknown/release/.
Run the full test suite:
make test
# or:
bash scripts/test.shIndividual contract tests:
cargo test -p stellar_send
cargo test -p fee_collector
cargo test -p token_bridgeRun with output:
cargo test -p stellar_send -- --nocapture# Set environment
export STELLAR_NETWORK=testnet
export STELLAR_RPC_URL=https://soroban-testnet.stellar.org
export STELLAR_ACCOUNT=<your-secret-key>
# Deploy fee_collector first (stellar_send depends on its address)
bash scripts/deploy.sh fee_collector
# Deploy token_bridge
bash scripts/deploy.sh token_bridge
# Deploy stellar_send, passing fee_collector address
bash scripts/deploy.sh stellar_send <fee_collector_address>Same steps as testnet; update STELLAR_NETWORK=mainnet and STELLAR_RPC_URL=https://horizon.stellar.org.
Note: Mainnet deployments require a multi-sig admin key. Refer to the Security section.
Initialise the contract. Must be called exactly once by admin.
fee_bps: Protocol fee in basis points. Range:0..=10_000.fee_collector: Address of the deployedfee_collectorcontract.
Transfer amount of token from from to to. The protocol fee is deducted from amount before transfer.
Requires auth from: from
send_path_payment(from, to, send_token, send_amount, dest_token, min_dest_amount, path) → Result<i128, StellarSendError>
Route a payment through the Stellar DEX. The fee is deducted from send_amount before the swap is attempted.
Requires auth from: from
Update the protocol fee. Admin only.
Halt or resume new payments. Admin only.
Propose a new admin (step 1 of 2). Current admin only.
Complete the admin rotation (step 2 of 2). Proposed admin only.
Return current configuration.
Retrieve a stored payment record by sender address and sequence number.
Record fee receipt. The token transfer must already have been made by stellar_send.
Withdraw fees to recipient. Admin only.
Return current token balance held by the contract.
Return the lifetime total of fees collected in token.
Deposit amount of underlying token; credit wrapped balance.
Burn amount of wrapped balance; return underlying tokens.
All contracts emit structured events consumable by the Horizon API or Soroban event subscriptions.
| Contract | Topic | Data |
|---|---|---|
| stellar_send | payment_sent |
(from, to, token, net_amount, fee_amount, memo) |
| stellar_send | path_payment_sent |
(from, to, send_token, send_amount, dest_token, dest_amount, fee_amount) |
| stellar_send | fee_updated |
(old_bps, new_bps) |
| stellar_send | paused / unpaused |
ledger |
| fee_collector | fee_received |
(token, amount) |
| fee_collector | fee_withdrawn |
(token, recipient, amount) |
| token_bridge | wrapped |
(underlying, amount) |
| token_bridge | unwrapped |
(underlying, amount) |
Subscribe to events via Horizon:
soroban events --contract-id <CONTRACT_ID> --network testnet- All admin keys should be multi-sig accounts on mainnet.
- Admin rotation uses a two-step propose/accept pattern to prevent key loss.
- The
fee_collectortreasury address is separate from the admin key.
| Contract | Auditor | Status |
|---|---|---|
| stellar_send | — | In progress |
| fee_collector | — | In progress |
| token_bridge | — | In progress |
Please report security issues privately via email to security@stellarsend.io. Do not open a public issue for a security vulnerability. See SECURITY.md for our responsible disclosure policy.
We welcome contributions! Please read CONTRIBUTING.md before opening a pull request.
- Fork the repo
- Create a feature branch:
git checkout -b feat/my-feature - Make your changes and add tests
- Run
make test— all tests must pass - Open a PR against
main
MIT © 2026 StellarSend. See LICENSE for full text.