User Story:
As a donor, I want to request a refund when a campaign is cancelled or fails, under clearly defined on-chain rules, so that my funds aren't stranded.
Acceptance Criteria:
- Eligibility, exposed as a view function: campaign
Cancelled, OR Ended with zero milestones released AND within the refund window; documented in contract comments
fn request_refund(env, donor): donor.require_auth(), re-validates eligibility server-side, checks non-zero donor balance, transfers the donor's contributed amount back, clears the donor's record, emits refund_issued
- Tests: refund from a cancelled campaign, refund attempt on an active campaign (panics), double-refund attempt
User Story:
As a donor, I want to request a refund when a campaign is cancelled or fails, under clearly defined on-chain rules, so that my funds aren't stranded.
Acceptance Criteria:
Cancelled, OREndedwith zero milestones released AND within the refund window; documented in contract commentsfn request_refund(env, donor):donor.require_auth(), re-validates eligibility server-side, checks non-zero donor balance, transfers the donor's contributed amount back, clears the donor's record, emitsrefund_issued