token-fundraiser: let a maker retire a failed raise and raise again#107
Open
mikemaccana wants to merge 2 commits into
Open
token-fundraiser: let a maker retire a failed raise and raise again#107mikemaccana wants to merge 2 commits into
mikemaccana wants to merge 2 commits into
Conversation
The Fundraiser PDA is derived from the maker's key alone, so a failed fundraiser's surviving account locked its maker out of ever raising again. Add a close_fundraiser handler: after the deadline, when the target was missed and every contribution has been refunded, the maker sweeps any direct vault donations to their own token account, closes the vault and the fundraiser (recovering both rent deposits), and can then initialize a fresh fundraiser. New error variant RefundsOutstanding guards against stranding unrefunded contributions. Also add the two missing contribution-cap tests (single contribution over the 10% cap; cumulative contributions over it) and five tests covering every branch of the close path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MjDPoqwPYDGnLoMoXsto8r
The second initialize in the close-then-raise-again test was byte-identical to the first (same accounts, data, and blockhash), so LiteSVM rejected it as already processed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MjDPoqwPYDGnLoMoXsto8r
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.
What
Adds a
close_fundraiserinstruction handler to the Anchor token-fundraiser, plus tests.Why
The
FundraiserPDA is derived fromb"fundraiser"+ the maker's key alone. After a failed raise nothing ever closed that account:check_contributions(the only closing handler) is permanently barred byTargetNotMetonce refunds draincurrent_amount, so a maker whose raise failed was locked out of ever raising again from that wallet — and the vault plus fundraiser rent was stranded with it.How
close_fundraiser(maker-signed) requires, in order:elapsed_days >= duration— elseFundraiserNotEndedcurrent_amount < amount_to_raise— elseTargetMet(a successful raise exits throughcheck_contributions, which already closes these accounts)current_amount == 0— elseRefundsOutstanding(new error variant; closing the vault earlier would strand the remaining refunds)Anything left in the vault at that point is a direct donation outside the program's accounting; it is swept to
maker_atarather than burned with the account. The vault closes viaclose_account, the fundraiser viaclose = maker, and the maker can theninitializea fresh fundraiser at the same PDA.Tests
test_close_fundraiser_after_failed_raise_allows_a_new_raise— the full retire-then-raise-again lifecycletest_close_fundraiser_before_deadline_failstest_close_fundraiser_when_target_met_failstest_close_fundraiser_with_unrefunded_contributions_failstest_close_fundraiser_sweeps_direct_donations_to_makertest_contribute_above_cap_failsandtest_cumulative_contributions_above_cap_failcargo check --testspasses locally; the sandbox's network policy blocks the platform-tools download so the SBF build and LiteSVM run could not be executed locally — the Anchor CI workflow is the test gate for this PR.README (new handler documented in lifecycle prose, testing section updated) and CHANGELOG updated. The Quasar port is not touched — it has materially different validation semantics (no caps, exact-second deadlines) and is tracked separately.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MjDPoqwPYDGnLoMoXsto8r
Generated by Claude Code