RustFund

First Flight #36
Beginner FriendlyRust
100 EXP
View results
Submission Details
Severity: high
Valid

(Medium) Lack of withdrawal condition check

Summary

The withdraw function allows the creator of a fund to withdraw all raised funds (amount_raised) without any checks on whether the campaign was successful (i.e., reached its goal) or whether the deadline has passed. This allows for premature and potentially malicious withdrawals.

Vulnerability Details

The withdraw function (programs/rustfund/src/lib.rs, simply transfers the entire amount_raised from the fund account to the creator account:

pub fn withdraw(ctx: Context<FundWithdraw>) -> Result<()> {
let amount = ctx.accounts.fund.amount_raised;
**ctx.accounts.fund.to_account_info().try_borrow_mut_lamports()? =
ctx.accounts.fund.to_account_info().lamports()
.checked_sub(amount)
.ok_or(ProgramError::InsufficientFunds)?;
**ctx.accounts.creator.to_account_info().try_borrow_mut_lamports()? =
ctx.accounts.creator.to_account_info().lamports()
.checked_add(amount)
.ok_or(ErrorCode::CalculationOverflow)?;
Ok(())
}

There are no checks to ensure that:

  1. fund.amount_raised >= fund.goal (the campaign was successful)

  2. Clock::get().unwrap().unix_timestamp >= fund.deadline (the deadline has passed)

Impact

  • Medium: The creator can withdraw funds before the campaign is supposed to end, potentially defrauding contributors who believed their funds would only be used if the goal was reached. This breaks the trust model of the crowdfunding platform.

Tools Used

  • Manual code review

Recommendations

Add checks to the withdraw function to ensure that the withdrawal is only allowed if the campaign has met its goal AND the deadline has passed.

if ctx.accounts.fund.amount_raised < ctx.accounts.fund.goal {
return Err(ErrorCode::GoalNotReached.into()); // Add GoalNotReached to your ErrorCode enum
}
if Clock::get().unwrap().unix_timestamp < ctx.accounts.fund.deadline {
return Err(ErrorCode::DeadlineNotReached.into());
}

You will need to define GoalNotReached error:

#[error_code]
pub enum ErrorCode {
// ... other errors ...
#[msg("Funding goal not reached")]
GoalNotReached,
}
Updates

Appeal created

bube Lead Judge 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

No deadline check in `withdraw` function

No goal achievement check in `withdraw` function

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.