RustFund

First Flight #36
Beginner FriendlyRust
100 EXP
View results
Submission Details
Severity: medium
Invalid

Front-Running Attack (Manipulated Contribution Timing)

Summary:

The contribute function does not prevent front-running, allowing attackers to artificially inflate a fund's total balance just before the fund creator withdraws. This could lead to unexpected fund balances and refund issues.

Vulnerability Details

Vulnerable Code:

pub fn contribute(ctx: Context<FundContribute>, amount: u64) -> Result<()> {
let fund = &mut ctx.accounts.fund;
let contribution = &mut ctx.accounts.contribution;
if fund.deadline != 0 && fund.deadline < Clock::get().unwrap().unix_timestamp.try_into().unwrap() {
return Err(ErrorCode::DeadlineReached.into());
}
// Transfer SOL from contributor to fund account
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
system_program::Transfer {
from: ctx.accounts.contributor.to_account_info(),
to: fund.to_account_info(),
},
);
system_program::transfer(cpi_context, amount)?;
fund.amount_raised += amount;
Ok(())
}

Issue:

  • Attackers can donate at the last second before a fund creator withdraws.

  • This creates unexpected balances, which may lead to refund complications or misuse of extra funds.

Impact

Creators might withdraw more than expected, leading to incorrect fund allocation.

  • Donors might be tricked into believing a goal was met when it was artificially inflated.

  • Scammers can manipulate funding totals, potentially misleading other users.

Tools Used

Manually

Recommendations

Fixed Code:

pub fn contribute(ctx: Context<FundContribute>, amount: u64) -> Result<()> {
let fund = &mut ctx.accounts.fund;
let contribution = &mut ctx.accounts.contribution;
let current_timestamp = Clock::get()?.unix_timestamp;
require!(current_timestamp < fund.deadline, ErrorCode::DeadlineReached);
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
system_program::Transfer {
from: ctx.accounts.contributor.to_account_info(),
to: fund.to_account_info(),
},
);
system_program::transfer(cpi_context, amount)?;
fund.amount_raised = fund.amount_raised.checked_add(amount).ok_or(ErrorCode::CalculationOverflow)?;
Ok(())
}

}

Updates

Lead Judging Commences

bube Lead Judge
5 months ago

Appeal created

bube Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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