Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
bf06c9f
chore(circle): add proptest 1.x dev-dependency for property-based tes…
Sep 16, 2026
c60f581
test(proptest): scaffold proptest_harness.rs module with cfg(test) guard
Sep 16, 2026
6375a78
test(proptest): define CircleParams struct for parameterized circle c…
Sep 16, 2026
93dffd4
test(proptest): implement arb_capacity strategy producing values in […
Sep 16, 2026
5499c45
test(proptest): implement arb_contribution strategy for bounded depos…
Sep 16, 2026
b8677ad
test(proptest): implement arb_round_seconds strategy spanning 1s to 3…
Sep 16, 2026
f02a266
test(proptest): compose arb_circle_params strategy using prop_compose…
Sep 16, 2026
052dbef
test(proptest): define RoundAction enum covering Pay, Default, and De…
Sep 16, 2026
20bb622
test(proptest): implement arb_round_action with weighted action distr…
Sep 16, 2026
11e8793
test(proptest): implement arb_all_actions strategy for capacity x cap…
Sep 16, 2026
acc7202
test(proptest): define MemberLedger struct for action tracking during…
Sep 16, 2026
4e16aea
test(proptest): implement setup phase in run_circle_scenario with tok…
Sep 16, 2026
0a7bbf3
test(proptest): calculate per-member token mint budget to prevent tes…
Sep 16, 2026
db0dd6d
test(proptest): instantiate mock Stellar asset client and mint member…
Sep 16, 2026
e488633
test(proptest): initialize Circle contract client with generated para…
Sep 16, 2026
48bf30e
test(proptest): capture baseline token balances before join for conse…
Sep 16, 2026
2f56c3c
test(proptest): execute join loop for all members asserting initial d…
Sep 16, 2026
fb51888
test(proptest): execute round execution loop simulating member actions
Sep 16, 2026
a95fc81
test(proptest): dispatch on-time contributions for RoundAction::Pay m…
Sep 16, 2026
55e7083
test(proptest): simulate member defaults by advancing past round_ends_at
Sep 16, 2026
6b803f4
test(proptest): advance ledger timestamp past round deadline to permi…
Sep 16, 2026
3a79409
test(proptest): invoke client.settle to test pool settlement and reci…
Sep 16, 2026
56867e4
test(proptest): implement top_up restoration for DefaultThenTopUp act…
Sep 16, 2026
f2a1c59
test(proptest): use try_top_up to handle idempotent or conditional de…
Sep 16, 2026
209c82a
test(proptest): verify circle status is Complete after all rounds fin…
Sep 16, 2026
5ebf2d7
test(proptest): verify every member received their payout exactly onc…
Sep 16, 2026
5f2a70c
test(proptest): execute withdraw_deposit phase for all remaining memb…
Sep 16, 2026
187d477
test(proptest): assert contract token balance is zero after all withd…
Sep 16, 2026
9901901
test(proptest): assert token conservation invariant across all partic…
Sep 16, 2026
49d3649
test(proptest): format informative counterexample diagnostics on inva…
Sep 16, 2026
0d6dc55
test(proptest): add prop_accounting_is_sound for generalized random e…
Sep 16, 2026
e86546f
test(proptest): configure proptest test runner with case limits and m…
Sep 16, 2026
ee43c48
test(proptest): add prop_happy_path_always_balances property test
Sep 16, 2026
6fb6c53
test(proptest): verify zero deposit drawdown when all members pay on …
Sep 16, 2026
b42b0ff
test(proptest): add prop_all_default_every_round property test
Sep 16, 2026
df589bc
test(proptest): verify deposit exhaustion and delinquency under persi…
Sep 16, 2026
ae7881d
test(proptest): assert contract balance remains zero even under total…
Sep 16, 2026
cb59c69
test(proptest): add prop_single_rotating_defaulter property test
Sep 16, 2026
cb1d363
test(proptest): verify round-robin default handling across all member…
Sep 16, 2026
22edb09
test(proptest): add prop_default_then_top_up_every_round property test
Sep 16, 2026
6ccce95
test(proptest): stress deposit top_up mechanism and balance accounting
Sep 16, 2026
9fc27d1
test(proptest): verify Soroban authorization mocking across multi-mem…
Sep 16, 2026
3f37e71
test(proptest): prevent integer overflow in test parameter generation
Sep 16, 2026
f2f6af2
test(proptest): optimize shrink tree navigation for quick counterexam…
Sep 16, 2026
c93e07c
test(proptest): document invariant definitions and mathematical proof…
Sep 16, 2026
b27e106
test(proptest): cross-verify property test assertions against scenari…
Sep 16, 2026
ec5267d
test(proptest): add test execution guidance with PROPTEST_CASES env var
Sep 16, 2026
c517965
test(proptest): ensure compatibility with Soroban SDK test environment
Sep 16, 2026
d0c765a
docs(proptest): document property-based testing harness and invariant…
Sep 16, 2026
47b4f7b
feat(circle): integrate proptest harness into lib.rs and update proje…
Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,38 @@ The suite covers the full lifecycle, both default paths, the authorisation
boundary, and an accounting invariant asserting that after a complete cycle
every member is square to the stroop and the contract holds nothing.

### Property-based testing

In addition to the hand-written scenarios, `contracts/circle/src/proptest_harness.rs`
runs a property-based harness using [proptest](https://docs.rs/proptest). It
generates random circles — varying member counts (3–24), contribution sizes
(1–1 000 000 stroops), round durations (1 s – 30 days) — and executes full
lifecycles with random per-member, per-round actions:

| Action | Meaning |
|--------|---------|
| `Pay` | Member contributes on time |
| `Default` | Member skips; deposit covers the gap (or is exhausted) |
| `DefaultThenTopUp` | Member skips then calls `top_up` to restore the deposit |

After every run the harness asserts four invariants:

| ID | Invariant |
|----|-----------|
| I-1 | `status == Complete` after the last round |
| I-2 | Every member's `received` flag is `true` |
| I-3 | Contract token balance is `0` after all withdrawals |
| I-4 | Token conservation: `Σ balance_after == Σ balance_before_join` |

Counterexamples are shrunk automatically by proptest to the smallest failing
input. If the harness finds a bug, the output names the violated invariant and
the exact `CircleParams` and action matrix that triggered it.

```sh
cargo test -p circlefi-circle # runs scenario tests + property tests
PROPTEST_CASES=1000 cargo test # run more cases for a deeper search
```

## Licence

Apache-2.0.
1 change: 1 addition & 0 deletions contracts/circle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ soroban-sdk = "27"

[dev-dependencies]
soroban-sdk = { version = "27", features = ["testutils"] }
proptest = "1"

[features]
testutils = ["soroban-sdk/testutils"]
3 changes: 3 additions & 0 deletions contracts/circle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,3 +499,6 @@ impl Circle {
}

mod test;

#[cfg(test)]
mod proptest_harness;
Loading