Soroban (Stellar) smart contracts for the ACBU (African Currency Basket Unit) stablecoin platform.
- Minting Contract (
acbu_minting) β Converts USDC, fiat deposits, and S-token baskets into ACBU - Burning Contract (
acbu_burning) β Redeems ACBU back to fiat currency or S-tokens - Oracle Contract (
acbu_oracle) β Aggregates exchange rates from multiple validators - Reserve Tracker Contract (
acbu_reserve_tracker) β Tracks and verifies reserve balances - Savings Vault Contract (
acbu_savings_vault) β Interest-bearing savings accounts for ACBU - Lending Pool Contract (
acbu_lending_pool) β Peer-to-peer ACBU lending - Escrow Contract (
acbu_escrow) β Conditional and time-locked ACBU transfers - Multisig Contract (
acbu_multisig) β M-of-N threshold authorization for admin actions
The eight contracts are divided into three logical layers:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER / FRONTEND β
ββββββββββββββ¬βββββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββββββββ
β β β β
βββββββββΌβββββββ βββββΌβββββββ ββΌβββββββββ ββΌββββββββββββββ
β Minting β β Burning β β Savings β β Lending β
β Contract β β Contract β β Vault β β Pool β
ββββββββ¬ββββββββ ββββββ¬ββββββ ββββββ¬βββββ ββββββββ¬ββββββββ
β β β β
β ββββββΌβββββββββββββββββββββββ β
β β Escrow Contract β β
β βββββββββββββββββββββββββββββ β
β β
ββββββββΌβββββββββββββββββββββββββββββββββββββββββββΌββββββββ
β INFRASTRUCTURE LAYER β
β βββββββββββββββββββββ βββββββββββββββββββββββββββββ β
β β Oracle Contract β β Reserve Tracker Contract β β
β βββββββββββββββββββββ βββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββ
β SHARED / GOVERNANCE LAYER β
β ββββββββββββββββββββββββββ ββββββββββββββββββββββββ β
β β Multisig Contract β β Shared Library β β
β β (M-of-N admin auth) β β (types, utilities) β β
β ββββββββββββββββββββββββββ ββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
User
β
β 1. Transfer USDC to MintingContract vault
βΌ
MintingContract
β 2. Query ACBU/USD rate βββββββββββββββΊ OracleContract
β 3. Verify reserves sufficient βββββββββββββββΊ ReserveTrackerContract
β β
β 4. Oracle rate βββ
β 5. Calculate ACBU amount (rate Γ USDC, minus fee)
β 6. Mint ACBU to user βββββββββββββββΊ ACBU Token Contract
β 7. Emit MintEvent
βΌ
User receives ACBU
User
β
β 1. Transfer ACBU to BurningContract
βΌ
BurningContract
β 2. Query currency/USD rate βββββββββββββββΊ OracleContract
β 3. Verify reserves sufficient βββββββββββββββΊ ReserveTrackerContract
β 4. Burn ACBU from user βββββββββββββββΊ ACBU Token Contract
β 5a. S-token redemption:
β transfer_from vault βββββββββββββββΊ S-Token Contract (vault allowance)
β 5b. Fiat redemption:
β emit BurnEvent βββββββββββββββΊ Off-chain withdrawal processor
β 6. Emit BurnEvent
βΌ
User receives S-tokens or fiat (via backend)
External Data Sources (e.g. Chainlink, Pyth, CEX APIs)
β
β Each validator submits an independent rate
βΌ
OracleContract.update_rate() (validator-gated, multisig-authorized)
β
β 1. Verify caller is a registered validator
β 2. Check update interval has elapsed
β 3. Store new rate from this validator
β 4. Compute median across β₯3 validator submissions
β 5. Outlier detection: reject if >3% deviation from median
β 6. Emergency path: if move >5%, require N-of-M validator consensus
β 7. Emit RateUpdateEvent (or EmergencyBypassEvent)
βΌ
Consumers: MintingContract, BurningContract, ReserveTrackerContract
Admin / Custodian
β
β 1. Submit reserve attestation (Merkle proof of off-chain reserves)
βΌ
ReserveTrackerContract
β 2. Verify proof and custodian identity
β 3. Update reserve balances per currency
β 4. Cross-check value_usd against Oracle rates βββΊ OracleContract
βΌ
MintingContract / BurningContract
β 5. Call is_sufficient() before each mint or burn
β β Ensures reserve_usd β₯ acbu_supply Γ min_ratio
βΌ
Gate: transaction proceeds only if reserves are adequate
User
βββΊ deposit(amount) βββΊ SavingsVault stores balance + timestamp
βββΊ lock(amount, term) βββΊ SavingsVault records lock period, higher rate
βββΊ withdraw(amount) βββΊ SavingsVault calculates accrued interest,
transfers principal + interest to user
Lender
βββΊ deposit(amount) βββΊ LendingPool records lender liquidity
Borrower + Lender (dual authorization)
βββΊ borrow(lender, amount) βββΊ LendingPool transfers ACBU to borrower,
records LoanData (uncollateralized)
Borrower
βββΊ repay(loan_id, amount) βββΊ LendingPool transfers ACBU back,
updates loan balance
Lender
βββΊ withdraw(amount) βββΊ LendingPool transfers principal + interest
Creator
βββΊ create_escrow(beneficiary, amount, conditions)
β
βΌ
EscrowContract holds ACBU
β
βββββββ΄ββββββββββββββββββββββ
β Admin / condition met β Admin cancels
βΌ βΌ
release_escrow() cancel_escrow()
β β
βΌ βΌ
Beneficiary receives ACBU Creator refunded
Proposer (any signer)
βββΊ propose(action, params) βββΊ MultisigContract stores proposal + nonce
Signers (M-of-N required)
βββΊ approve(proposal_id) βββΊ MultisigContract records approvals
Any signer (once threshold met)
βββΊ execute(proposal_id) βββΊ MultisigContract dispatches admin action
to target contract (e.g. add_validator,
set_fee_rate, upgrade contract)
| Caller | Callee | Method | Purpose |
|---|---|---|---|
| MintingContract | OracleContract | get_acbu_usd_rate |
ACBU/USD rate for mint calculation |
| MintingContract | OracleContract | get_rate |
Per-currency rate for basket mints |
| MintingContract | ReserveTracker | is_sufficient |
Reserve adequacy check before mint |
| BurningContract | OracleContract | get_rate |
Per-currency rate for burn payout |
| BurningContract | ReserveTracker | is_sufficient |
Reserve adequacy check before burn |
| ReserveTracker | OracleContract | get_rate |
Validate reserve value_usd integrity |
| ReserveTracker | ACBU Token | total_supply |
Compare supply against reserves |
| Caller | Callee | Action | Direction |
|---|---|---|---|
| MintingContract | ACBU Token | mint(user, amount) |
Creates new ACBU |
| BurningContract | ACBU Token | burn(user, amount) |
Destroys ACBU |
| BurningContract | S-Token Vault | transfer_from(vault, user) |
Vault allowance pull model |
| MintingContract | USDC Token | receive deposit (push model) | User pushes USDC in advance |
| Contract | Admin actions gated by | Validator actions gated by |
|---|---|---|
| OracleContract | Multisig (timelock) | Validator allowlist |
| ReserveTracker | Multisig (timelock) | Custodian address |
| MintingContract | Multisig (timelock) | Operator address |
| BurningContract | Multisig (timelock) | n/a |
| SavingsVault | Admin address | n/a |
| LendingPool | Admin address | n/a |
| EscrowContract | Admin address | n/a |
| MultisigContract | M-of-N signers | n/a |
All contracts import from the shared crate:
shared/
βββ ContractError β common error enum
βββ CurrencyCode β currency type (e.g. "USD", "NGN")
βββ RateData β oracle rate struct
βββ ReserveData β reserve balance struct
βββ reentrancy_guard β re-entrancy protection helper
βββ MintEvent β standardised mint event type
βββ BurnEvent β standardised burn event type
βββ constants β DECIMALS, BASIS_POINTS, MAX_VALIDATORS, β¦
- Rust 1.87.0 (pinned in
rust-toolchain.toml) - Soroban CLI (
cargo install --locked soroban-cli) - Stellar account with XLM for deployment fees
You can use the Makefile for common commands.
# Build all contracts in the workspace
make build
# Build a specific contract
make build-minting# Run all tests in the workspace
make test
# Run tests for a specific contract
make test-mintingexport STELLAR_SECRET_KEY="your-secret-key"
make deploy-testnetexport STELLAR_SECRET_KEY="your-secret-key"
make deploy-mainnetAfter cloning, run:
make setup-hooksThis configures the pre-commit hook for WASM integrity checks.
After deployment, contract addresses are saved to .soroban/deployment_{network}.json
.
βββ acbu_minting/ # Minting contract
βββ acbu_burning/ # Burning contract
βββ acbu_oracle/ # Oracle contract
βββ acbu_reserve_tracker/ # Reserve tracker contract
βββ acbu_savings_vault/ # Savings vault contract
βββ acbu_lending_pool/ # Lending pool contract
βββ acbu_escrow/ # Escrow contract
βββ acbu_multisig/ # Multisig shared contract
βββ shared/ # Shared types and utilities
βββ scripts/ # Deployment scripts
βββ docs/ # Documentation
βββ tests/ # Integration tests
- Create contract directory:
mkdir new_contract - Add to workspace
Cargo.tomlmembers - Create
Cargo.tomlandsrc/lib.rs - Update deployment scripts
- All admin functions require multisig (3 of 5)
- Rate limits on transactions
- Circuit breakers for anomalies
- Time locks for critical operations
- docs/CONTRACTS.md β detailed per-contract function reference
- docs/ERROR_CODES.md β full error code listing
- DEPLOYMENT.md β deployment instructions
- INTEGRATION.md β integration guide for external consumers