RustFund

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

Unrestricted Withdrawals (Rug Pull Risk)

Summary
The withdraw() function does not check if the funding goal was met or if the deadline has passed.
This allows the campaign creator to withdraw funds at any time, even before the campaign ends.

Vulnerability Details
Function logic fails to check if the funding goal was met or if the deadline has passed. The absence of this makes it possible for contributed funds to be withdrawn early which is against the rules.

Impact

I could think of two impacts:
1. Malicious fund creators can withdraw contributed funds early and disappear (rug pull).
2. Legitimate contributors are left without refunds, even if the campaign failed.

Tools Used
1. Manual Review

POC

Steps to Exploit

1. Create a campaign with goal = 10 SOL.
2. Contributors send only 5 SOL (goal not met).
3. Before the deadline, the creator calls withdraw() and takes 5 SOL.
4. The campaign fails, but the creator has already withdrawn the money.

Flaw in withdraw()

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(())
}

Recommendations

1. Require that the funding goal is met before withdrawal.

2. Ensure withdrawal is only possible after the deadline.

Fix:

if fund.deadline > Clock::get()?.unix_timestamp.try_into().unwrap() {
return Err(ErrorCode::CampaignNotEnded.into());
}
if fund.amount_raised < fund.goal {
return Err(ErrorCode::FundingGoalNotMet.into());
}
Updates

Appeal created

bube Lead Judge 6 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.