Per the specification, a contributor may refund only when the deadline has been reached and the goal was not met. refund checks neither the goal nor a properly-set deadline, and it never decrements the fund's tracked total:
Three defects compound here:
No goal check. A contributor can refund even on a successful campaign (goal met). Combined with the ungated withdraw, the creator and every contributor race for the same lamports — whoever calls first is paid and the loser's checked_sub reverts.
amount_raised is never decremented. After a refund the fund's real lamport balance drops but fund.amount_raised stays inflated. withdraw computes its payout from that stale, too-large value, so settlement no longer matches reality — it either reverts (griefing the creator) or, as contributions and refunds interleave, pays out against amounts that are no longer held.
deadline == 0 bypasses the guard entirely. The check is deadline != 0 && deadline > now. If the creator never calls set_deadline, deadline is 0, the condition short-circuits to false, and refunds are allowed immediately — a contributor can contribute and refund in the same slot, well before any intended deadline.
Impact: High. Broken refund/settlement accounting: refunds succeed on successful campaigns, the raised-total desyncs from the real balance and corrupts withdraw, and refunds are possible before any deadline. Contributor and creator funds are mis-settled.
Likelihood: High. All three paths are reachable with ordinary calls; the deadline == 0 bypass is the default state right after fund_create.
Require a finalized, failed campaign, and keep amount_raised in lockstep:
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.