Rust Fund

AI First Flight #9
Beginner FriendlyRust
EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

`withdraw()` has no goal or deadline checks — creator can withdraw regardless of campaign success

Description

  • Normal: Per README, "Creators can withdraw funds once their campaign succeeds." This requires: (1) deadline passed, (2) goal met.

  • Bug: withdraw() has zero business logic validation — only has_one = creator:

// withdraw(): L90-105
pub fn withdraw(ctx: Context<FundWithdraw>) -> Result<()> {
let amount = ctx.accounts.fund.amount_raised;
// @> BUG: No deadline check, no goal check!
// Transfer amount from fund to creator...
}

Creator can withdraw immediately, even with 1% of goal raised.

Risk

  • Likelihood: Certain

  • Impact: HIGH — Goal threshold protection is absent. Enables trivial rug-pulls.

Proof of Concept

it("BUG H-02: Creator withdraws without meeting goal", async () => {
// Create fund: goal = 10 SOL. Contribute 0.5 SOL (5% of goal).
const balanceBefore = await provider.connection.getBalance(creator.publicKey);
await program.methods.withdraw().accounts({...}).rpc();
const balanceAfter = await provider.connection.getBalance(creator.publicKey);
// BUG: Creator got funds despite campaign failure
expect(balanceAfter).to.be.greaterThan(balanceBefore);
});

Run with: anchor test

Recommended Mitigation

pub fn withdraw(ctx: Context<FundWithdraw>) -> Result<()> {
+ // Check deadline passed
+ if ctx.accounts.fund.deadline == 0 { return Err(...); }
+ if ctx.accounts.fund.deadline > now { return Err(...); }
+ // Check goal met
+ if ctx.accounts.fund.amount_raised < ctx.accounts.fund.goal { return Err(...); }
// ... transfer ...
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 16 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!