Summary
The Withdrawal function has no access control.
Vulnerability Details
The withdraw function does not enforce strict access control, allowing any user to potentially withdraw funds from a campaign.
Impact
Funds could be taken out by unauthorized users.
Tools Used
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> ProgramResult {
let campaign = &mut ctx.accounts.campaign;
if campaign.total_amount < amount {
return Err(ProgramError::InsufficientFunds);
}
invoke(
&system_instruction::transfer(
&campaign.key(),
&ctx.accounts.creator.key,
amount,
),
&[
campaign.to_account_info(),
ctx.accounts.creator.to_account_info(),
ctx.accounts.system_program.to_account_info(),
],
)?;
campaign.total_amount -= amount;
Ok(())
}
Recommendations
The withdraw function should only be called by the campaign creator.
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> ProgramResult {
let campaign = &mut ctx.accounts.campaign;
if campaign.creator != *ctx.accounts.creator.key {
return Err(ProgramError::Unauthorized);
}
if campaign.total_amount < amount {
return Err(ProgramError::InsufficientFunds);
}
invoke(
&system_instruction::transfer(
&campaign.key(),
&ctx.accounts.creator.key,
amount,
),
&[
campaign.to_account_info(),
ctx.accounts.creator.to_account_info(),
ctx.accounts.system_program.to_account_info(),
],
)?;
campaign.total_amount -= amount;
Ok(())
}