fix(rewards): harden direct close lifecycle and revoke accounting#32
Open
fix(rewards): harden direct close lifecycle and revoke accounting#32
Conversation
Add direct-distribution tombstones so a closed direct distribution cannot be recreated at the same PDA, and wire close/create instruction accounts accordingly. Also allow closing direct recipient accounts after the parent direct distribution is closed and keep merkle claim claimed_amount in sync for non-vested revoke flows.
Update direct distribution create/close web instruction builders to derive and include the tombstone PDA required by the generated client types after the direct tombstone hardening change.
…mbstone PDA Replace the separate DirectDistributionTombstone PDA with an in-place state flip on the distribution PDA itself. On close, the distribution's discriminator byte is rewritten to DirectDistributionClosed (1-byte data = bump), the account is resized from 130 bytes down to 3 bytes, and the freed rent is refunded to the authority. On create, the first byte is inspected — if it matches DirectDistributionClosed::DISCRIMINATOR, the instruction returns DistributionPermanentlyClosed. Benefits over the tombstone approach: - No extra account passed in each create/close transaction - No extra PDA seed derivation - Simpler mental model — closed is just a state of the same PDA - Smaller transaction size close_direct_recipient detects closed distributions by checking the discriminator byte instead of the account owner (the PDA now always stays program-owned). IDL: CloseDirectDistribution lost tombstone + system_program accounts (8 total); CreateDirectDistribution lost tombstone account (11 total). Net -157 lines of code. All 407 unit + 207 integration tests pass.
Replace inline discriminator-byte checks in create_distribution and
close_recipient processors with a single `DirectDistribution::is_closed`
method. The method takes an AccountView and program ID, returns true
iff the account is program-owned and its first byte matches the
DirectDistributionClosed discriminator.
Callers are clearer about intent ("is this distribution closed?") and
the byte-layout detail is encapsulated on the type that owns it.
…t helpers Pull the state-flip logic out of the close_direct_distribution processor: - Add DirectDistribution::close_in_place(account, rent_recipient) which overwrites the account header with DirectDistributionClosed's discriminator + version, resizes the account to the closed marker's length, and refunds freed rent to the recipient. - Add refund_excess_rent(account, recipient, new_size) as a general-purpose utility in pda_utils.rs for any program-owned account that was resized down and needs its excess lamports returned. Processor drops ~15 lines of state-flip + rent-refund bookkeeping to a single call.
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.
Summary
CloseDirectDistributionand requiretombstone+system_programaccounts in direct create/close flowsCloseDirectRecipientto succeed after the parent distribution account is closedMerkleClaim.claimed_amountcorrectly when a claim account existsTest Plan
just buildcargo test -p tests-rewards-program test_create_direct_distribution -- --nocapturecargo test -p tests-rewards-program test_close_direct_distribution -- --nocapturecargo test -p tests-rewards-program test_close_direct_recipient -- --nocapturecargo test -p tests-rewards-program test_revoke_merkle_claim -- --nocapturecargo test -p rewards-program