The withdraw
function can be called at any time, without checking whether the crowdfunding is finished or the funding goal is met. This allows the creator to withdraw funds early, which may trap later contributors’ money.
In the current implementation, the withdraw
function directly calculates the withdrawal amount using let amount = ctx.accounts.fund.amount_raised
, Then it transfers this amount from the fund to the creator — without any checks, no check for whether the deadline has passed, and no check for whether the goal has been reached.
That means the creator can withdraw before the campaign ends, even when the raised amount is below the goal.
Now imagine someone contributes after the creator has already withdrawn funds. Because amount_raised
wasn’t updated, the contract still thinks there’s more money than there actually is. If the fund’s real balance is lower than amount_raised, the refund will fail — and the user’s money gets stuck in the contract.
If the creator withdraws early and amount_raised
is not updated properly, later contributors might not be able to get their money back. Since the contract believes there’s more money than there actually is, refund attempts can fail — leaving users’ funds permanently stuck in the contract.
Manual review
Add proper checks in the withdraw function to make sure the funding goal has been reached and that the amount_raised
hasn’t already been withdrawn or emptied.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.