Skip to content

fix(specs): add multisig bounds assumptions and fix signers_count range#183

Open
Stevengre wants to merge 4 commits intoproofsfrom
fix/multisig-spec-signers-bounds
Open

fix(specs): add multisig bounds assumptions and fix signers_count range#183
Stevengre wants to merge 4 commits intoproofsfrom
fix/multisig-spec-signers-bounds

Conversation

@Stevengre
Copy link

Summary

  • Add 1 <= m <= MAX_SIGNERS and 1 <= n <= MAX_SIGNERS assumptions to test_process_thaw_account_multisig and test_process_freeze_account_multisig specs, matching the invariants enforced by initialize_multisig
  • Fix spec bug in inner_test_validate_owner: signers_count was iterating all multisig.signers slots instead of signers[0..n], diverging from the implementation (processor.rs:1006)

Details

Assumptions

The symbolic multisig cheatcode does not constrain m or n. Without assumptions, the prover explores unreachable states:

  • N == 0, M == 0: leads to assert_failed_inner stuck leaves (11 instances)
  • N > MAX_SIGNERS: leads to slice OOB stuck leaf

Spec fix

signers_count in both expected_validate_owner_result and inner_test_validate_owner used multisig.signers.iter() (all MAX_SIGNERS slots) instead of multisig.signers[0..multisig.n as usize].iter(). When m > n (e.g., N=1, M=2), the spec counted extra signer slots as valid matches, expecting Ok(()) while the implementation returned Err(MissingRequiredSignature).

The unsigned_exists check was intentionally left using multisig.signers.iter() (all slots) since it is a stricter constraint that does not cause spec/impl divergence.

Test plan

  • test_process_thaw_account_multisig proof: ✅ PASSED (275 nodes, 0 stuck, 8344s total)
  • test_process_freeze_account_multisig proof: same fix applied, pending verification

Closes #181

🤖 Generated with Claude Code

Stevengre and others added 2 commits March 16, 2026 02:21
Add `1 <= m <= MAX_SIGNERS` and `1 <= n <= MAX_SIGNERS` assumptions to
thaw_account_multisig and freeze_account_multisig specs. These match the
invariants enforced by `initialize_multisig` and eliminate stuck leaves
from unreachable symbolic states (N==0 and N>MAX_SIGNERS).

Fix spec bug in `inner_test_validate_owner`: `signers_count` was
iterating over all `multisig.signers` slots instead of only
`signers[0..n]`, diverging from the implementation
(`processor.rs:1006`) which uses `multisig.signers[0..multisig.n as
usize]`. When m > n, the spec counted extra uninitialized slots as
valid matches, inflating the count and incorrectly expecting Ok(())
while the implementation returned MissingRequiredSignature.

Closes #181

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Stevengre Stevengre self-assigned this Mar 17, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b54c2925a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Stevengre Stevengre marked this pull request as draft March 17, 2026 10:43
Stevengre and others added 2 commits March 17, 2026 10:49
Add `1 <= m <= MAX_SIGNERS` and `1 <= n <= MAX_SIGNERS` assumptions to
all remaining multisig specs that use cheatcode_multisig. These match
the invariants enforced by `initialize_multisig` and prevent the prover
from exploring unreachable symbolic states.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MAX_SIGNERS is already u8, so `as u8` triggers clippy::unnecessary_cast
which fails CI lint with --deny=warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Stevengre Stevengre marked this pull request as ready for review March 17, 2026 12:59
@Stevengre Stevengre requested review from dkcumming and mariaKt March 17, 2026 12:59
@Stevengre
Copy link
Author

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@mariaKt mariaKt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Collaborator

@dkcumming dkcumming left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, it would be good if before merge we could add an explanation to VERIFCATION_GUIDE.md about these assumptions

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.

[spl-token] test_process_thaw_account_multisig: stuck/failing leaf from unconstrained symbolic multisig

3 participants