Repository navigation
Testing and Quality
Validation combines workspace tests, randomized scenarios, static checks, and live network exercises. Select checks that cover the changed behavior and record what each result establishes. Formal Verification describes the separate proof workflow.
Documentation changes need relevant formatting and link checks. Contract changes need linting, workspace tests, and focused regression coverage. Changes to arithmetic, authorization, accounting, risk, pricing, or strategies also need properties or adversarial cases that exercise the affected boundary.
Build contract fixtures first using Building and Contributing. The baseline contract checks are:
make fmt-check
cargo clippy --workspace --all-targets --features price-aggregator/testing -- -D warnings
make testmake test runs the whole workspace with price-aggregator/testing, including contract suites outside the shared harness. Running only the harness does not cover those suites. Avoid --all-features for ordinary tests: the certora feature has a separate compilation and proof path.
For contract artifact changes, make wasm-size-check builds deployment WASM and checks both size budgets and prohibited testing entrypoints. make access-control-check checks the declared authorization coverage of state-changing entrypoints. These checks complement behavioral tests.
The harness in tests/test-harness/ combines native contracts and WASM fixtures in a Soroban test environment. Controller, governance, and price-aggregator contracts run natively; pool and position-NFT contracts load WASM. Rebuild fixtures after changing their contracts.
The default fixture mocks authorization and disables resource limits. Dedicated authorization tests must configure realistic authorization, and resource tests must enable or measure the relevant limits. A passing default scenario alone does not establish those properties.
Use focused targets while developing:
make test-harness
make test-one FILE=controller
make test-match PATTERN=liquidation
make test-poolThe domain binaries include smoke_test, controller, governance, oracle, pool, strategy, composition, meta, and fuzz. Additional regression binaries cover specific behavior.
Tests run in parallel by default because each test owns its environment and snapshot. Set TEST_THREADS=1 when diagnosing interactions between tests. Property-test targets run serially.
Property tests generate contract scenarios and check invariants such as accounting conservation, liquidation arithmetic, authorization, and strategy settlement. The suite includes an exact rational reference for liquidation calculations and persists failing randomized cases in source-adjacent *.proptest-regressions files.
make proptest
make proptest-one TEST=prop_accounting_conservation PROPTEST_CASES=256The property targets use release mode. Each randomized module has its own default case count; PROPTEST_CASES overrides that count. Deterministic regression tests in the same binary do not become randomized when the override changes.
The separate tests/fuzz/ workspace uses libFuzzer through cargo-fuzz and nightly Rust:
make fuzz-build
make fuzz FUZZ_TIME=60
make fuzz-contract FUZZ_TIME=60make fuzz runs fp_math, rates_and_index, and fp_ops. make fuzz-contract runs flow_e2e, flow_strategy, pool_native, and aggregator. The time limit applies to each target.
Preserve and minimize a failing input before diagnosing it. A fuzz campaign establishes what its targets, seeds, inputs, and runtime exercise; it does not exhaust all protocol states.
Use these checks for a specific validation question:
| Check | Command | What the result shows |
|---|---|---|
| Miri | make miri-common |
Undefined-behavior checks for the selected pure fixed-point helpers. |
| Mutation testing |
make mutants-math, make mutants-pool
|
Whether the selected tests detect generated changes to arithmetic or pool code. |
| Broader mutation testing | make mutants |
Mutation checks across the configured contract and shared-code targets. |
| Coverage | make coverage-merged |
Instrumented source coverage across the configured contract suites and shared harness. |
| Scoped coverage |
make coverage-controller, make coverage-pool
|
Coverage for a selected contract. |
| Documentation | make docs-check |
Repository documentation links and source references resolve. |
Coverage output is written under target/coverage/. Coverage measures executed source, while mutation results help evaluate whether tests detect wrong behavior. Neither establishes protocol correctness on its own.
The keeper and lending exporter use separate Cargo workspaces. Run their checks through their own manifests when changing those services:
cargo test --manifest-path services/keeper/Cargo.toml
cargo test --manifest-path services/lending-exporter/Cargo.tomlThe scripts in tests/integration/ deploy contracts, fund test wallets, and submit real network transactions. They exercise integration with the Stellar CLI, RPC, price sources, and swap routes. Local harness results do not establish that those dependencies are reachable or configured correctly.
From the repository root, build integration artifacts and run the testnet lanes:
make integration-wasm
NETWORK=testnet RUN_TS=$(date +%Y%m%d-%H%M%S) bash tests/integration/scenarios/parallel_e2e.shThe default lanes are agg, liq, stress, flash, and blend. Each uses a separate run identifier and environment. E2E_LANES selects a narrower set for focused work.
The parallel runner checks process exits, completion markers, and each lane's recorded results. Unresolved failures, unexpected successes, and simulation errors fail the gate. Review the action log and expected failures as well as the final status; selecting fewer lanes narrows the evidence.
Workflows have branch and path filters, so inspect which jobs actually ran for the change.
| Workflow | Validation |
|---|---|
tests.yml |
Formatting, documentation checks, selected shell syntax checks, artifact checks, workspace tests, and linting. |
security.yml |
Authorization-coverage checks and Soroban security detectors. |
scout.yml |
Scout detector reports with the configured severity threshold. |
fuzz.yml |
Pull-request fuzz, property, Miri, and mutation checks; scheduled and manual campaigns. |
coverage.yml |
Coverage reports and comparison with the main-branch baseline. |
e2e.yml |
Manually dispatched testnet integration. |
A useful review record identifies the revision, selected checks, inputs or case counts, observed results, and limitations. Report skipped checks and environmental failures explicitly. Passing CI is evidence for the jobs that execute, not a substitute for reviewing assumptions or deployed configuration.
- Verification targets, harness fixtures, and property-test configuration.
- Testnet runner and CI workflows.
- Building and Contributing covers setup and review preparation. Continue to Formal Verification for proof evidence.
Learn
Use the protocol
- Managing Positions
- Risk and Liquidations
- Flash Loans and Strategies
- Flash Loans
- Strategies
- Vault Integration
Prices and administration
Integration and review
- Controller
- Central Pool
- Oracle Configuration
- Accounting and Numeric Domains
- Protocol Invariants
- Architecture Decisions
Contribute and verify