RustFund

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

H-1: Inadequate Deadline Check in Fund Withdrawal Function

Summary

The withdraw function in the rustfund program allows the fund creator to withdraw funds at any time without checking if the fundraising deadline has been reached. This behavior may be unintended and could lead to premature withdrawal before contributors expect funds to be locked or the goal to be met.

Vulnerability Details

The withdraw function does not verify whether the fundraising deadline has passed before allowing the fund creator to withdraw funds. In the current implementation:

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 is no condition ensuring that the deadline has been reached before allowing withdrawals. As a result, the fund creator can withdraw the funds at any time, even before contributors expect the fundraising process to be completed.

Impact

  • The fund creator can withdraw the funds before the deadline, potentially breaking trust with contributors.

  • If the purpose of the contract is to enforce a crowdfunding model where funds should only be accessed after a campaign deadline, this vulnerability defeats that purpose.

  • Contributors may expect funds to be locked until the deadline, but they can be withdrawn at any time, which could lead to potential misuse.

Tools Used

  • Manual code review

Recommendations

To mitigate this issue, modify the withdraw function to include a deadline check:

pub fn withdraw(ctx: Context<FundWithdraw>) -> Result<()> {
let fund = &ctx.accounts.fund;
let current_time = Clock::get().unwrap().unix_timestamp as u64;
if fund.deadline != 0 && current_time < fund.deadline {
return Err(ErrorCode::DeadlineNotReached.into());
}
let amount = fund.amount_raised;
**fund.to_account_info().try_borrow_mut_lamports()? =
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(())
}

By adding this verification, the contract ensures that withdrawals can only occur after the deadline has passed, preventing premature fund access by the creator.

Updates

Appeal created

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

No deadline check in `withdraw` function

Support

FAQs

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