Skip to content

fix(events): harden cancellation liveness#82

Merged
0xdevcollins merged 1 commit into
boundlessfi:testnetfrom
chigozzdevv:testnet
Jul 17, 2026
Merged

fix(events): harden cancellation liveness#82
0xdevcollins merged 1 commit into
boundlessfi:testnetfrom
chigozzdevv:testnet

Conversation

@chigozzdevv

@chigozzdevv chigozzdevv commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix cancellation liveness by removing the unbounded contributor scan and allowing anyone to progress an event after cancellation has started.

Also hardens the mainnet 1.1.0 → 1.2.0 upgrade workflow around the zero-event migration assumption and the existing 2-of-3 multisig.

Changes made

  • Maintain an O(1) per-event non-owner contribution total.
  • Update the total during event creation and add_funds.
  • Make start_cancel read the stored total instead of scanning contributors.
  • Make process_cancel_batch and finalize_cancel permissionless while the event is Cancelling.
  • Fail safely for legacy events with contributors but no stored aggregate.
  • Preserve support for empty legacy events.
  • Bump boundless-events from 1.1.0 to 1.2.0.
  • Add cancellation resource-usage, authorization, payout, and legacy-state tests.
  • Regenerate event snapshots for the new storage key.
  • Replace obsolete mainnet upgrade commands with guarded, multisig-compatible XDR preparation.
  • Update the mainnet runbook, audit report, threat model, and backlog.

Files changed

  • contracts/events/src/event_ops.rs
  • contracts/events/src/storage.rs
  • contracts/events/src/types.rs
  • contracts/events/src/errors.rs
  • contracts/events/src/admin.rs
  • contracts/events/src/lib.rs
  • contracts/events/src/tests/cancel_refund.rs
  • contracts/events/src/tests/admin.rs
  • contracts/events/Cargo.toml
  • Cargo.lock
  • deploy_mainnet.sh
  • docs/mainnet-deploy-runbook.md
  • docs/scout-audit-report.md
  • docs/threat-model.md
  • BACKLOG.md
  • Event test snapshots under contracts/events/test_snapshots/

Test coverage

  • Running total tracks repeated contributions and excludes owner top-ups.
  • start_cancel has constant ledger-read usage with 220 contributors.
  • The configured manager is still required to start cancellation.
  • A non-manager can process every refund batch and finalize cancellation.
  • Contributor refunds, owner residual, and fee-account deltas are asserted exactly.
  • Multiple-page and pro-rata refund behavior remains covered.
  • Missing legacy totals fail closed when contributors exist.
  • Empty legacy events initialize the total safely.

Verification

  • cargo test -p boundless-events cancel_refund — 18 passed
  • cargo test -p boundless-events — 185 passed
  • cargo test --all — 237 passed
  • cargo fmt --all -- --check — passed
  • git diff --check — passed
  • bash -n deploy_mainnet.sh — passed
  • Release WASM build — passed
    • Size: 51,456 bytes
    • SHA-256: abc3e60029ce340a31f66ceb22e92ddcc51ba439fb3447ce1da996c740e2a7b0

Mainnet upgrade safety

  • Require the contract to be paused before applying 1.2.0.
  • Verify that no event exists before proposal and immediately before apply.
  • Prepare simulated XDRs for sequential 2-of-3 multisig signing.
  • Refuse to unpause 1.2.0 until migration is verified.
  • Abort on unexpected contract state instead of relying on an unsafe assumption.

Closes #69

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 198 files, which is 98 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 55622d6b-78e6-4f23-b135-8dedefffdf43

📥 Commits

Reviewing files that changed from the base of the PR and between 862cb7d and dfc8cf8.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (198)
  • BACKLOG.md
  • contracts/events/Cargo.toml
  • contracts/events/src/admin.rs
  • contracts/events/src/errors.rs
  • contracts/events/src/event_ops.rs
  • contracts/events/src/lib.rs
  • contracts/events/src/storage.rs
  • contracts/events/src/tests/admin.rs
  • contracts/events/src/tests/cancel_refund.rs
  • contracts/events/src/types.rs
  • contracts/events/test_snapshots/tests/admin/apply_upgrade_after_expiry_reverts.1.json
  • contracts/events/test_snapshots/tests/admin/apply_upgrade_before_timelock_reverts.1.json
  • contracts/events/test_snapshots/tests/admin/cancel_pending_upgrade_clears_proposal.1.json
  • contracts/events/test_snapshots/tests/admin/cancel_with_no_pending_reverts.1.json
  • contracts/events/test_snapshots/tests/admin/id_base_encodes_deployment_sequence.1.json
  • contracts/events/test_snapshots/tests/admin/initializes_with_expected_config.1.json
  • contracts/events/test_snapshots/tests/admin/migrate_marks_current_version_and_blocks_replay.1.json
  • contracts/events/test_snapshots/tests/admin/pause_and_unpause_round_trip.1.json
  • contracts/events/test_snapshots/tests/admin/propose_upgrade_records_pending_and_emits.1.json
  • contracts/events/test_snapshots/tests/admin/propose_upgrade_rejects_empty_version.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_after_deadline_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_bootstraps_profile_and_records_applicant.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_on_cancelled_event_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_on_completed_event_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_on_nonexistent_event_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_on_wrong_pillar_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_requires_applicant_auth.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/apply_when_paused_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/create_rejects_multi_release_kind.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/duplicate_apply_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/replayed_apply_reverts_idempotently.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/replayed_withdraw_reverts_idempotently.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/withdraw_after_submit_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/withdraw_on_nonexistent_event_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/withdraw_removes_the_applicant.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/withdraw_requires_applicant_auth.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/withdraw_when_paused_reverts.1.json
  • contracts/events/test_snapshots/tests/bounty_pillar/withdraw_without_apply_reverts.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/add_funds_on_cancelling_event_reverts.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/cancel_prorata_splits_remaining_across_partners_no_owner_residual.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/contributor_amount_zeroed_after_cancel.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/finalize_cancel_before_all_batches_reverts.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/full_partner_then_residual_pays_partners_and_owner.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/missing_running_total_initializes_for_an_empty_event.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/missing_running_total_with_contributors_fails_closed.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/non_manager_cranks_and_finalizes_with_exact_payout_deltas.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/owner_only_cancel_settles_inline.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/owner_only_process_and_finalize_rejected_after_inline_settle.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/paged_cancel_processes_in_batches.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/process_cancel_batch_without_start_reverts.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/running_non_owner_total_tracks_repeated_contributions_but_not_owner_topups.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/start_cancel_on_already_cancelled_reverts.1.json
  • contracts/events/test_snapshots/tests/cancel_refund/start_cancel_on_nonexistent_event_reverts.1.json
  • contracts/events/test_snapshots/tests/contributions/add_funds_on_nonexistent_event_reverts.1.json
  • contracts/events/test_snapshots/tests/contributions/add_funds_paged_storage_round_trip.1.json
  • contracts/events/test_snapshots/tests/contributions/add_funds_to_cancelled_event_reverts.1.json
  • contracts/events/test_snapshots/tests/contributions/anyone_can_top_up_an_active_event.1.json
  • contracts/events/test_snapshots/tests/contributions/below_minimum_contribution_reverts.1.json
  • contracts/events/test_snapshots/tests/contributions/cancel_at_boundary_pays_partners_full_no_owner_residual.1.json
  • contracts/events/test_snapshots/tests/contributions/cancel_clears_contributor_amounts_so_replay_state_is_clean.1.json
  • contracts/events/test_snapshots/tests/contributions/cancel_with_no_contributors_refunds_owner_in_full.1.json
  • contracts/events/test_snapshots/tests/contributions/cancel_with_owner_top_up_keeps_owner_residual_correct.1.json
  • contracts/events/test_snapshots/tests/contributions/cancel_with_partner_pool_refunds_partners_then_owner_residual.1.json
  • contracts/events/test_snapshots/tests/contributions/multiple_top_ups_from_same_contributor_aggregate_and_dont_duplicate_list.1.json
  • contracts/events/test_snapshots/tests/contributions/owner_top_up_grows_escrow_without_recording_contribution_entry.1.json
  • contracts/events/test_snapshots/tests/contributions/paged_cancel_owner_only_settles_inside_start.1.json
  • contracts/events/test_snapshots/tests/contributions/paged_cancel_processes_in_batches.1.json
  • contracts/events/test_snapshots/tests/contributions/replayed_add_funds_reverts.1.json
  • contracts/events/test_snapshots/tests/contributions/zero_or_negative_contribution_reverts.1.json
  • contracts/events/test_snapshots/tests/cross_contract/add_funds_uses_event_override_not_global.1.json
  • contracts/events/test_snapshots/tests/cross_contract/bounty_submit_requires_prior_application.1.json
  • contracts/events/test_snapshots/tests/cross_contract/bounty_submit_succeeds_after_apply.1.json
  • contracts/events/test_snapshots/tests/cross_contract/cancel_after_select_winners_refunds_only_remaining.1.json
  • contracts/events/test_snapshots/tests/cross_contract/cancel_already_cancelled_reverts.1.json
  • contracts/events/test_snapshots/tests/cross_contract/cancel_refunds_remaining_escrow_to_owner.1.json
  • contracts/events/test_snapshots/tests/cross_contract/claim_milestone_final_milestone_marks_event_completed.1.json
  • contracts/events/test_snapshots/tests/cross_contract/claim_milestone_idempotent_per_recipient_and_milestone.1.json
  • contracts/events/test_snapshots/tests/cross_contract/claim_milestone_invalid_milestone_index_reverts.1.json
  • contracts/events/test_snapshots/tests/cross_contract/claim_milestone_pays_per_milestone_amount.1.json
  • contracts/events/test_snapshots/tests/cross_contract/claim_milestone_rejects_non_grant_events.1.json
  • contracts/events/test_snapshots/tests/cross_contract/create_event_charges_override_rate_when_provided.1.json
  • contracts/events/test_snapshots/tests/cross_contract/create_event_omitted_override_falls_back_to_global_default.1.json
  • contracts/events/test_snapshots/tests/cross_contract/create_event_rejects_override_above_max_fee_bps.1.json
  • contracts/events/test_snapshots/tests/cross_contract/create_event_with_waiver_charges_no_fee.1.json
  • contracts/events/test_snapshots/tests/cross_contract/grant_last_milestone_sweeps_rounding_residue.1.json
  • contracts/events/test_snapshots/tests/cross_contract/hackathon_submit_creates_anchor_without_prior_apply.1.json
  • contracts/events/test_snapshots/tests/cross_contract/manager_can_be_rotated.1.json
  • contracts/events/test_snapshots/tests/cross_contract/manager_defaults_to_owner_and_override_is_recorded.1.json
  • contracts/events/test_snapshots/tests/cross_contract/manager_override_can_select_winners.1.json
  • contracts/events/test_snapshots/tests/cross_contract/resubmit_preserves_original_submitted_at_and_updates_uri.1.json
  • contracts/events/test_snapshots/tests/cross_contract/select_winners_handles_multi_recipient_distribution.1.json
  • contracts/events/test_snapshots/tests/cross_contract/select_winners_pays_against_remaining_escrow_including_top_ups.1.json
  • contracts/events/test_snapshots/tests/cross_contract/select_winners_pays_recipient_and_bumps_profile.1.json
  • contracts/events/test_snapshots/tests/cross_contract/select_winners_rejects_duplicate_position.1.json
  • contracts/events/test_snapshots/tests/cross_contract/select_winners_rejects_second_call_winners_already_selected.1.json
  • contracts/events/test_snapshots/tests/cross_contract/select_winners_replayed_reverts.1.json
  • contracts/events/test_snapshots/tests/cross_contract/select_winners_requires_position_in_distribution.1.json
  • contracts/events/test_snapshots/tests/cross_contract/submit_replayed_reverts.1.json
  • contracts/events/test_snapshots/tests/cross_contract/withdraw_submission_removes_anchor.1.json
  • contracts/events/test_snapshots/tests/cross_contract/withdraw_submission_without_submission_reverts.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/backer_pays_exactly_pledge_and_creator_bears_fee.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/builder_top_up_does_not_appear_in_contributor_list.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/cancel_after_partial_claim_pro_rates_remaining.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/cancel_refunds_all_partners_no_owner_residual.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/cancel_with_no_contributions_just_marks_cancelled.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/claim_milestone_last_drains_dust_with_fee.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/claim_milestone_out_of_range_reverts.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/claim_milestone_replay_reverts.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/claim_milestone_splits_evenly_and_charges_fee_at_release.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/claim_milestone_with_empty_escrow_reverts.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/community_top_ups_raise_escrow_from_zero.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/create_rejects_distribution_with_multiple_positions.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/create_rejects_missing_deadline.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/create_rejects_single_release_kind.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/create_with_zero_owner_deposit_and_auto_registered_winner.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/crowdfunding_claim_milestone_requires_admin_auth.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/select_winners_on_crowdfunding_reverts.1.json
  • contracts/events/test_snapshots/tests/crowdfunding/submit_on_crowdfunding_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/add_funds_uses_event_override_bps.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/add_funds_zero_override_bps_charges_no_fee.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/crowdfunding_dynamic_milestone_split.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/crowdfunding_dynamic_rounding_no_dust.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/fee_account_accumulates_across_create_and_add_funds.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/fee_and_winner_balances_consistent.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/fee_rounding_on_odd_amounts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/fee_rounds_down_non_divisible_amount.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/global_fee_bps_used_when_no_override.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/grant_milestone_double_claim_rejected.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/grant_milestone_out_of_range_rejected.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/grant_milestone_pays_floored_per_milestone.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/large_budget_fee_does_not_overflow.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/mid_flight_global_bps_change_does_not_affect_override_event.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/multi_position_split_pays_correct_amounts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/override_at_max_bps_boundary_succeeds.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/override_bps_above_max_rejected.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/override_bps_used_on_create.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/partial_position_fill_leaves_residual_escrow.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/partner_funds_grow_winner_payout.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/replayed_create_event_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/replayed_select_winners_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/select_winners_duplicate_position_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/select_winners_empty_list_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/select_winners_invalid_position_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/select_winners_on_cancelled_event_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/select_winners_on_nonexistent_event_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/select_winners_twice_reverts.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/single_release_pays_full_escrow_for_100_percent.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/three_way_33_33_34_split_rounding.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/zero_global_bps_no_override_charges_no_fee.1.json
  • contracts/events/test_snapshots/tests/escrow_fee_math/zero_override_bps_skips_fee.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_already_claimed_reverts.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_earns_credits_and_bumps_reputation.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_last_sweeps_rounding_residue.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_marks_completed_on_last.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_on_single_release_reverts.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_op_replay_reverts.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_out_of_range_reverts.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_pays_fixed_per_milestone_amount.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/claim_milestone_without_being_winner_reverts.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/grant_create_with_multi_release_succeeds.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/grant_create_with_single_release_reverts.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/grant_create_with_zero_milestones_reverts.1.json
  • contracts/events/test_snapshots/tests/grant_pillar/two_winner_grant_each_claims_their_share.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/claim_milestone_on_single_release_hackathon_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/create_deposits_full_budget_and_takes_fee_at_deposit.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/create_rejects_missing_deadline.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/create_rejects_multi_release_kind.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/create_rejects_past_deadline.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/resubmit_keeps_original_timestamp_and_updates_uri.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_demands_owner_auth.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_duplicate_position_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_empty_set_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_multi_position_splits_by_distribution.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_on_completed_event_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_on_missing_event_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_position_not_in_distribution_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_replayed_op_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_second_call_reverts_winners_already_selected.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/select_winners_single_recipient_sweeps_escrow.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/submit_after_deadline_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/submit_open_without_prior_apply_creates_anchor.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/submit_replayed_op_reverts.1.json
  • contracts/events/test_snapshots/tests/hackathon_pillar/withdraw_submission_removes_anchor.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/create_event_with_deregistered_token_reverts.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/create_event_with_unsupported_token_reverts.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/deregister_removes_support.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/deregister_requires_admin_auth.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/deregister_unregistered_token_is_idempotent.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/deregister_without_admin_auth_reverts.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/multiple_tokens_registered_independently.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/register_makes_token_supported.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/register_requires_admin_auth.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/register_same_token_twice_is_idempotent.1.json
  • contracts/events/test_snapshots/tests/token_whitelist/register_without_admin_auth_reverts.1.json
  • deploy_mainnet.sh
  • docs/mainnet-deploy-runbook.md
  • docs/scout-audit-report.md
  • docs/threat-model.md

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Review on demand using usage pricing
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@0xdevcollins
0xdevcollins merged commit 3ab0845 into boundlessfi:testnet Jul 17, 2026
4 checks passed
0xdevcollins added a commit that referenced this pull request Jul 17, 2026
Committed Soroban test snapshots are derived artifacts (cargo test
regenerates them from any commit) and are not byte-reproducible across
runs, so they churned on every test run and inflated PR diffs past the
limits of the security scanners: on PR #82 both Almanax (diff too
large) and CodeRabbit (198 files) skipped review of a HIGH-severity
contract change because of snapshot noise.

Gitignore test_snapshots/, untrack the 238 committed files (kept on
disk locally), and update the CLAUDE.md hard rule so contributors
inspect regenerated snapshot diffs during review instead of
committing them.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

Cancellation liveness: unbounded start_cancel loop + manager-only refund crank

2 participants