Skip to content

feat(contracts): implement subscription contract invariant testing suite#292

Closed
morelucks wants to merge 3 commits intoSmartdevs17:mainfrom
morelucks:feat/invariant-testing-suite
Closed

feat(contracts): implement subscription contract invariant testing suite#292
morelucks wants to merge 3 commits intoSmartdevs17:mainfrom
morelucks:feat/invariant-testing-suite

Conversation

@morelucks
Copy link
Copy Markdown
Contributor

Summary

Implements a comprehensive invariant testing suite for the SubTrackr subscription contract, addressing #221.

What's included

Invariants defined (10 total)

# Name Description
1 PlanCountMonotonic get_plan_count() equals ghost counter and never decreases
2 SubscriptionCountMonotonic get_subscription_count() equals ghost counter and never decreases
3 TotalPaidConservation Each subscription's total_paid = sum of charges − approved refunds
4 PlanSubscriberCountAccuracy plan.subscriber_count matches ghost count of active/paused subs
5 PausedAtNonZeroWhenPaused If status == Paused then paused_at > 0 and pause_duration > 0
7 RefundAmountBounded refund_requested_amount <= total_paid for every subscription
9 TotalCollectedNonNegative Ghost total_collected is always >= 0
10 UserSubsIndexConsistency Every sub_id in user index resolves to a sub whose subscriber matches

Test layers (19 tests total)

  • Deterministic scenario tests — hand-crafted sequences covering every lifecycle transition: basic flow, multi-plan/subscriber, cancel, pause/resume, auto-resume, refund approve/reject, transfer, plan deactivation, multiple charges, all billing intervals, authorization rules
  • Property-based fuzz tests (proptest, 50 cases each) — random action sequences, plan count = create_plan calls, subscription count = subscribe calls, total_paid = price × charge_count
  • State-machine invariant tests (proptest, 30 cases) — weighted random full-lifecycle actions including pause, resume, cancel, refund, time advancement

Infrastructure

  • ContractHandler extended with real Stellar asset token contracts so charge_subscription token transfers work correctly in tests
  • [[test]] entries added to Cargo.toml for proper test binary registration
  • contracts/.gitignore updated to exclude generated test_snapshots/ and *.proptest-regressions files
  • New CI workflow .github/workflows/invariant-tests.yml runs invariant tests on every contracts/ change, with an extended 1000-case fuzz run on pushes to main/dev

Test results

test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Files changed

  • contracts/tests/invariants.rs — test entry point (all 3 layers)
  • contracts/tests/invariants/mod.rs — invariant definitions and assert_invariants()
  • contracts/tests/invariants/handler.rsContractHandler ghost-state wrapper
  • contracts/Cargo.toml[[test]] registrations
  • contracts/.gitignore — exclude generated files
  • .github/workflows/invariant-tests.yml — CI workflow

Closes #221

morelucks and others added 3 commits April 22, 2026 19:20
Closes Smartdevs17#221

- Define 10 key invariants covering plan/subscription count monotonicity,
  total_paid conservation, plan subscriber count accuracy, paused_at
  consistency, refund amount bounds, total_collected non-negativity, and
  user subscription index consistency
- Implement deterministic scenario tests for all lifecycle transitions:
  basic flow, multi-plan/subscriber, cancel, pause/resume, auto-resume,
  refund approve/reject, subscription transfer, plan deactivation,
  multiple charges, all billing intervals, and authorization rules
- Add property-based fuzz tests using proptest (50 cases each):
  random action sequences, plan count equals create_plan calls,
  subscription count equals subscribe calls, total_paid equals
  price x charge_count
- Add state-machine invariant tests (30 cases) covering the full
  lifecycle with weighted random actions including pause, resume,
  cancel, refund, and time advancement
- Register real Stellar asset token contracts in ContractHandler so
  charge_subscription token transfers succeed in tests
- Add [[test]] entries in Cargo.toml for invariants and integration_soroban
- Add .github/workflows/invariant-tests.yml CI job running invariant
  tests on every contracts/ change, with an extended 1000-case fuzz
  run on pushes to main/dev
- Update contracts/.gitignore to exclude generated test_snapshots/ and
  *.proptest-regressions files
@morelucks
Copy link
Copy Markdown
Contributor Author

@Smartdevs17 kindly review

@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Apr 23, 2026

@morelucks Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement subscription contract invariant testing suite

1 participant