Use the scaffold generator to create a new contract crate already wired with the shared Pausable, Initializable, and StorageTrait conventions:
# From the repository root
./stellar-swipe/scripts/scaffold_contract.sh <contract_name>./stellar-swipe/scripts/scaffold_contract.sh reward_distributorThis creates:
stellar-swipe/contracts/reward_distributor/
├── Cargo.toml # depends on soroban-sdk + stellar-swipe-common
└── src/
├── lib.rs # initialize / pause / unpause / storage_write / storage_read
└── tests.rs # starter tests covering init, pause, storage round-trip
The workspace Cargo.toml is updated automatically to include the new crate.
cd stellar-swipe
cargo test -p stellar-swipe-reward-distributor
cargo clippy -p stellar-swipe-reward-distributor -- -D warningsBoth should pass with no manual fixes required.
| Feature | Implementation |
|---|---|
| Initializable guard | initialize() panics/returns error on double-init |
| Pausable | pause() / unpause() / is_paused() with events |
| StorageTrait pattern | storage_write(key, value) / storage_read(key) blocked while paused |
| Starter test file | tests.rs with 5 tests covering all three features |
Extend DataKey and {ContractName}Error with your contract-specific variants
before adding business logic.
Financial amounts (fees, P&L, balances, stakes — anything denominated in a
Stellar 7-decimal i128) must not use raw +, -, *, / operators, since
those panic on overflow in debug builds and wrap or panic unpredictably
otherwise (Soroban release profile sets overflow-checks = true).
Use stellar_swipe_common::Amount instead:
use stellar_swipe_common::Amount;
let total = Amount::new(a).checked_add(Amount::new(b))?; // Result<Amount, AmountError>
let fee = principal.checked_mul_rate(fee_bps, 10_000)?; // principal * fee_bps / 10_000Amount intentionally has no Add/Sub/Mul/Div impls, so attempting
amount_a + amount_b is a compile error. Functions that perform financial
arithmetic should additionally carry #[warn(clippy::arithmetic_side_effects)]
on the function item — CI runs cargo clippy --workspace --all-targets -- -D warnings, so any raw arithmetic introduced inside that function fails the
build (see contracts/fee_collector/src/rebates.rs::record_trade_volume and
contracts/user_portfolio/src/queries.rs::compute_get_pnl for examples).
This is scoped per-function rather than per-crate because the workspace sets
clippy::all = "allow" broadly (issue #599) — a crate-wide deny would also
flag unrelated, already-safe loop/index arithmetic across these large crates.