Skip to content

[#706] test: add invariant proptest for revenue_pool admin transfer - #792

Merged
greatest0fallt1me merged 1 commit into
CalloraOrg:mainfrom
broda-spendy:issue-706
Jul 27, 2026
Merged

[#706] test: add invariant proptest for revenue_pool admin transfer#792
greatest0fallt1me merged 1 commit into
CalloraOrg:mainfrom
broda-spendy:issue-706

Conversation

@broda-spendy

Copy link
Copy Markdown

Summary

Closes #706. The existing contracts/revenue_pool/tests/proptest.rs covers the balance/distribution state machine (Fund/Schedule/Distribute/BatchDistribute/Pause/Unpause/SetMaxDistribute) but has no coverage at all for the admin two-step transfer flow (set_admin / accept_admin / claim_admin / cancel_admin_transfer). The issue's suggested path (contracts/admin/tests/proptest.rs) doesn't exist as a directory in this repo — admin logic actually lives in each contract's own src/admin.rs and lib.rs. This PR targets revenue_pool specifically, since it already depends on proptest and has an established tests/proptest.rs convention to follow.

What changed

Adds contracts/revenue_pool/tests/proptest_admin.rs:

  • New invariant tested: the contract's admin only ever changes to the address most recently nominated via a successful set_admin call from the current admin, and only via a subsequent successful accept_admin/claim_admin call from that exact nominee. No other caller or entrypoint can ever change who the admin is.
  • A shadow model of expected admin/pending_admin state is maintained purely in the test, updated only when the real call that would legitimately produce that change both runs and does not panic.
  • Exercises set_admin, accept_admin, claim_admin (the documented legacy alias — must behave identically), and cancel_admin_transfer, with both legitimate and impostor callers drawn from a small shared address pool (so proptest can meaningfully explore adversarial combinations, not just always-fresh addresses).
  • After every single action in an arbitrary sequence of 1–64 actions, asserts the live contract's get_admin()/get_pending_admin() exactly match the shadow model.
  • Follows the exact conventions of the existing tests/proptest.rs: env.mock_all_auths(), Address::generate, catch_unwind+AssertUnwindSafe around calls that may legitimately panic, proptest! with ProptestConfig::with_cases.

Verification note (please confirm in CI)

This sandbox's toolchain (Ubuntu apt rustc 1.75) hits the same edition2024 wall via soroban-sdk's transitive crypto deps as the other Soroban repos I've worked on, since network policy blocks rust-lang.org/rustup, so a full cargo check/test could not be run here.

What I did verify instead:

  • Read the actual admin.rs/lib.rs source directly (set_admin/accept_admin/claim_admin/cancel_admin_transfer/get_admin/get_pending_admin signatures and panic conditions) rather than assuming them
  • Matched the exact reference-vs-clone patterns already used in the sibling tests/proptest.rs file
  • Ran the file through rustfmt directly (rustfmt --edition 2021 --check passes cleanly), confirming the file is syntactically valid Rust and correctly formatted, even though it doesn't confirm full type-checking

Would appreciate a CI run / local build confirmation given the above.

Closes #706

…nue_pool admin transfer

The existing contracts/revenue_pool/tests/proptest.rs covers the
balance/distribution state machine (Fund/Schedule/Distribute/
BatchDistribute/Pause/Unpause/SetMaxDistribute) but has no coverage at
all for the admin two-step transfer flow (set_admin / accept_admin /
claim_admin / cancel_admin_transfer). The issue's suggested path
(contracts/admin/tests/proptest.rs) doesn't exist as a directory in
this repo - admin logic actually lives in each contract's own
src/admin.rs and lib.rs (this PR targets revenue_pool specifically,
since it already depends on proptest and has an established
tests/proptest.rs convention to follow).

Adds contracts/revenue_pool/tests/proptest_admin.rs:

- New invariant: the contract's admin field only ever changes to the
  address most recently nominated via a successful set_admin call from
  the current admin, and only via a subsequent successful
  accept_admin/claim_admin call from that exact nominee. No other
  caller or entrypoint can ever change who the admin is
- A shadow model of expected admin/pending_admin state is maintained
  purely in the test, updated only when the real call that would
  legitimately produce that change both runs and does not panic
- Exercises set_admin, accept_admin, claim_admin (the documented legacy
  alias - must behave identically), and cancel_admin_transfer, with
  both legitimate and impostor callers drawn from a small shared
  address pool (so proptest can meaningfully explore adversarial
  combinations, not just always-fresh addresses)
- After every single action in an arbitrary sequence of 1-64 actions,
  asserts the live contract's get_admin()/get_pending_admin() exactly
  match the shadow model
- Follows the exact conventions of the existing tests/proptest.rs:
  env.mock_all_auths(), Address::generate, catch_unwind+AssertUnwindSafe
  around calls that may legitimately panic, proptest! with
  ProptestConfig::with_cases

Verification note: this sandbox's toolchain (Ubuntu apt rustc 1.75)
hits the same edition2024 wall via soroban-sdk's transitive crypto
deps as the other Soroban repos worked on in this session (network
policy blocks rust-lang.org/rustup), so a full cargo check/test could
not be run here. What was verified instead: read the actual
admin.rs/lib.rs source directly (set_admin/accept_admin/claim_admin/
cancel_admin_transfer/get_admin/get_pending_admin signatures and
panic conditions) rather than assuming them, matched the exact
reference-vs-clone patterns already used in the sibling
tests/proptest.rs file, and ran the file through rustfmt directly
(rustfmt --edition 2021 --check passes cleanly), confirming the file
is syntactically valid Rust and correctly formatted, even though it
doesn't confirm full type-checking. Please confirm via CI.

Closes CalloraOrg#706
@drips-wave

drips-wave Bot commented Jul 27, 2026

Copy link
Copy Markdown

@broda-spendy 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

@greatest0fallt1me
greatest0fallt1me merged commit 0c25a0b into CalloraOrg:main Jul 27, 2026
1 of 6 checks passed
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.

Add invariant proptest for admin

3 participants