Summary
The withdraw function allows the creator to withdraw funds at any time
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(())
}
Impact
The creator can withdraw funds before the fundraising deadline is reached, making fundraising pointless.
Tools Used
Manual review
Recommendations
pub fn withdraw(ctx: Context<FundWithdraw>) -> Result<()> {
let amount = ctx.accounts.fund.amount_raised;
require!(Clock::get()?.unix_timestamp >= ctx.accounts.fund.deadline, ErrorCode::DeadlineNotReached);
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
system_program::Transfer {
from: ctx.accounts.fund.to_account_info(),
to: ctx.accounts.creator.to_account_info(),
},
);
system_program::transfer(cpi_context, amount)?;
Ok(())
}