fix the claim refund donors - #55
Merged
Merged
Conversation
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.
claim_refund` does not refund donors whose only donations were Native XLM
closes #11
Description
Problem Statement
In CampaignContract::claim_refund (campaign/src/lib.rs), the per-asset refund loop is:
for asset in campaign.accepted_assets.iter() {⚠️ Native XLM donors silently skipped
let asset_address = match &asset.issuer {
Some(addr) => addr.clone(),
None => continue, //
};
...
}
The continue; drops any donor whose donations were entirely in Native XLM. Combined with Issue 1 (donors past the deadline can still donate if status is non-terminal) and Issue 2 (Native routes through accepted_assets[].issuer), there is a path where a Native-only donor believes they are entitled to a refund but receives nothing.
Why it matters
This is a direct failure of the documented refund contract. RefundNotPermitted is only returned when none of the eligibility checks pass. A Native-only donor whose refund is otherwise eligible will lose funds.
Expected Outcome
The per-asset refund loop must materialize the network's canonical wrapped-XLM contract address (introduced in Issue 2) and use it as the asset_address for any native donations. For multi-asset campaigns, each accepted asset gets a corresponding refund path.
Acceptance Criteria
New test test_claim_refund_native_xlm_donor that donates Native, cancels the campaign, and asserts successful refund with the canonical XLM contract address.
New test test_claim_refund_mixed_native_and_sac that donates both Native and a custom SAC, cancels the campaign, and asserts successful refunds for both.
Negative tests:
Campaign with no native XLM entry in accepted_assets rejects Native donations (the donation-side fix from Issue 2 complements this).
docs/events.md updates the refund_claimed event example with a Native contribution.
Implementation Notes
Pull out a fn xlm_token_address(env: &Env) -> Address returning the network-fixed canonical wrapped XLM. Use it in both donate and claim_refund.
Replace the inner continue with the same loop body but parameterized with the canonical XLM address for None issuer entries.
Affected Files / Modules
campaign/src/lib.rs (claim_refund)
campaign/src/types.rs (StellarAsset, xlm constants)
campaign/src/test/claim_refund_tests.rs (new tests)
campaign/src/test/refund_eligibility_tests.rs (mixed-asset test)
Dependencies — Depends on Issue 2 (canonical native XLM address).