feat: slashing tests, multi-sig withdrawals, search utilities (#362 #367 #368 #353)#391
Merged
codebestia merged 7 commits intoJul 2, 2026
Conversation
…ocol#362 Add tests/test_feature_225.rs with 46 tests covering: - Happy-path: single/majority backer approval, sequential milestone releases, mixed votes, pledge tracking, goal_reached flag - Unauthorized access: non-backer vote, double vote, locked milestone release, release without majority, double release, pre-deadline release, goal-not-met release, execute_campaign blocked in milestone mode, invalid index panics, invalid milestone sum/zero-entry panics, majority rejection - Event emission: MilestoneUnlocked, MilestoneVoteCast, MilestoneReleased, CampaignExecuted, RefundClaimed, BatchRefundProcessed - Storage rollback: failed release state preserved, duplicate vote tally unchanged, double-init preserves original state, post-deadline contribute does not mutate raised amount - Edge cases: no milestones set, approval exactly at 50% threshold, one-unit-above majority, zero/negative/invalid amounts, uninitialized contract accessors, single 100% milestone, many small milestones, batch refund with no contributors, off-by-one index bounds
…Protocol#367 New DataKey variants (types.rs): MultiSigThreshold(Address), MultiSigSigners, MultiSigQuorum, WithdrawalProposal(u64), WithdrawalProposalCount, WithdrawalApproval(u64, Address) New types (types.rs): WithdrawalProposalStatus enum (Pending/Executed/Cancelled) WithdrawalProposal struct (id, merchant, token, amount, recipient, approvals, status, created_at, updated_at, note) MultiSigConfig struct (threshold, signers, quorum) New errors (errors.rs): BelowMultiSigThreshold, MultiSigSignersNotSet, InvalidQuorum, NotASigner, AlreadyApproved, ProposalNotFound, ProposalNotPending, QuorumNotReached, NotProposer, ThresholdNotSet New events (events.rs): MultiSigThresholdSetEvent, MultiSigConfiguredEvent, WithdrawalProposedEvent, WithdrawalApprovedEvent, WithdrawalExecutedEvent, WithdrawalCancelledEvent — each with full structural metadata New component (components/multisig_withdrawal.rs): set_multisig_threshold, get_multisig_threshold, configure_multisig, get_signers, get_quorum, propose_withdrawal, approve_withdrawal (auto-executes at quorum via MerchantAccountWithdrawClient), cancel_withdrawal, get_withdrawal_proposal, has_approved, get_proposal_count ShadeTrait interface (interface.rs): 9 new public functions exposed Shade impl (shade.rs): delegate all 9 functions to multisig_component, guarded by pausable_component::assert_not_paused
…ol#368 Add src/tests/test_feature_231.rs with 57 tests covering: Happy-path (11): set/get threshold, configure multisig stores quorum, pending proposal fields, proposal IDs increment, single approval at quorum-1 executes, two approvals at quorum-2 executes, approval count before quorum, has_approved reflects votes, merchant cancel, admin cancel, threshold update, multisig reconfiguration Unauthorized/malicious (18): non-admin cannot set threshold or configure multisig, non-signer cannot approve, double vote rejected, stranger cannot cancel, below-threshold proposal rejected, zero-amount rejected, approve/cancel nonexistent proposal, approve cancelled/executed proposal, cancel executed proposal, quorum=0 panics, quorum>signers panics, empty signer list panics, exact-threshold boundary accepted, non-merchant cannot propose, propose without multisig configured panics Event emission (7): threshold set, multisig configured, withdrawal proposed, approval pre-quorum, execution at quorum emits >=2 events, cancellation, multiple proposals emit distinct events Storage rollback (4): duplicate vote does not increment count, failed proposal does not advance counter, failed cancel leaves status Pending, bad configure does not overwrite good config Edge cases (17): proposal count zero initially, has_approved false for unknown proposal, get_threshold unset panics, threshold=0 rejects proposals, quorum==signer_count requires all, large amount no overflow, multiple proposals isolated, cancel one does not affect other, 1-of-1 executes, get nonexistent proposal panics, threshold increase blocks old amount, paused blocks propose/approve/cancel, note stored correctly, timestamps recorded on proposal Register in src/tests/mod.rs
…l#353 New filter types (types.rs): SubscriptionPlanFilter (merchant, active, token) SubscriptionFilter (plan_id, customer, status) EventFilter (merchant, cancelled, start_date, end_date, min_available) WithdrawalProposalFilter (merchant, status, token, created_after) PageInfo (count, next_cursor, has_next_page) InvoicePage (items, page_info) MerchantPage (items, page_info) New events (events.rs): InvoiceSearchExecutedEvent (caller, result_count, has_next_page, timestamp) SubscriptionPlanSearchExecutedEvent (caller, result_count, timestamp) EventSearchExecutedEvent (caller, result_count, timestamp) WithdrawalProposalSearchExecutedEvent (caller, result_count, timestamp) New component (components/search.rs, 492 lines): search_invoices_paginated — cursor-based pagination over InvoiceFilter search_merchants_paginated — cursor-based pagination over MerchantFilter search_subscription_plans — filter plans by merchant/active/token search_subscriptions — filter by plan_id/customer/status search_events — filter by merchant/cancelled/date/seats search_withdrawal_proposals — filter by merchant/status/token/created_after find_merchant_id — address → merchant ID lookup ShadeTrait interface (interface.rs): 7 new public methods Shade impl (shade.rs): 7 new delegations to search_component
|
@gregemax 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! 🚀 |
codebestia
approved these changes
Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Implements four sequential tasks across the crowdfund and shade contracts: comprehensive test suites for the slashing mechanism and multi-sig withdrawal feature, the full multi-sig massive withdrawal implementation, and on-chain search/filtering utilities.
Type of Change
Related Issues
Fixes #362
Fixes #367
Fixes #368
Fixes #353
Changes Made
#362 – Slashing Mechanism Tests (crowdfund)
contracts/crowdfund/tests/test_feature_225.rs— 46 tests: happy-path, unauthorized access, event emission, storage rollback, edge cases#367 – Multi-Sig Requirements for Massive Withdrawals (shade)
types.rs— 6 new DataKey variants, WithdrawalProposalStatus, WithdrawalProposal, MultiSigConfigerrors.rs— 10 new error codes (55–64)events.rs— 6 detailed events: threshold set, config, proposed, approved, executed, cancelledcomponents/multisig_withdrawal.rs— 326-line component with atomic quorum executioninterface.rs— 9 new ShadeTrait methodsshade.rs— 9 new contractimpl delegations#368 – Multi-Sig Withdrawal Tests (shade)
src/tests/test_feature_231.rs— 57 tests: happy-path (11), unauthorized (18), events (7), rollback (4), edge cases (17)src/tests/mod.rs— registered test_feature_231#353 – On-Chain Search and Filtering Utilities (shade)
types.rs— 7 new types: SubscriptionPlanFilter, SubscriptionFilter, EventFilter, WithdrawalProposalFilter, PageInfo, InvoicePage, MerchantPageevents.rs— 4 search-executed events for off-chain indexingcomponents/search.rs— 492-line component: paginated invoice/merchant search, subscription plan/subscription/event/withdrawal proposal filteringinterface.rs— 7 new ShadeTrait methodsshade.rs— 7 new contractimpl delegationsTesting
Test coverage added: 46 tests (crowdfund slashing) + 57 tests (shade multi-sig) = 103 new tests
Checklist
Additional Notes
Four individual commits on branch
feat/task-362-225-362-slashing-tests:08c62eetest(crowdfund): slashing mechanism tests Create Comprehensive Tests for Slashing Mechanism #362c1fb8b3feat(shade): multi-sig massive withdrawals Add Multi-Sig Requirements for Massive Withdrawals #36763fd223test(shade): multi-sig withdrawal tests Create Comprehensive Tests for Multi-Sig Withdrawals #368a0838b7feat(shade): on-chain search and filtering utilities Add On-Chain Search and Filtering Utilities #353