Rust Fund

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

004_HIGH_refund-logic-flaw

Description

The refund function contains a logic error in its deadline check: if fund.deadline != 0 && .... This specifically excludes the case where deadline is 0, which allows refunds to be processed even if the deadline has not technically passed (since 0 is usually in the past, but the check is != 0). If a campaign is initialized with a deadline of 0 (or default), this check is bypassed entirely, allowing immediate refunds.

Risk

  • Severity: High

  • Likelihood: Medium

  • Impact: High

Impact Details:

  1. Premature Refunds: Contributors can withdraw funds immediately, draining the campaign before it has a chance to succeed.

  2. Logic Bypass: The intended temporal lock on funds is nullified.

Proof of Concept

Test demonstrating refund validity despite "active" (but zero-deadline) state.

#[tokio::test]
async fn test_refund_deadline_zero_exploit() {
// ... Setup fund with deadline = 0 ...
// 1. Contribute
// [Call contribute]
// 2. Attempt Refund immediately
// The check `if fund.deadline != 0 && ...` evaluates to false (bypass) because deadline is 0.
// So the function proceeds to refund.
let transaction = Transaction::new_with_payer(
&[instruction::refund(
&program_id,
&contributor.pubkey(),
)],
Some(&payer.pubkey()),
);
// 3. Verification
let result = banks_client.process_transaction(transaction).await;
assert!(result.is_ok(), "Refund succeeded despite no deadline expiration logic enforced.");
}

Recommended Mitigation Steps

Ensure the deadline check applies to all values, or enforce non-zero defaults.

Detailed Changes

pub fn refund(ctx: Context<Refund>) -> Result<()> {
let fund = &ctx.accounts.fund;
- if ctx.accounts.fund.deadline != 0 && ctx.accounts.fund.deadline > Clock::get().unwrap().unix_timestamp {
+ // Enforce deadline strictly. If deadline is 0, it counts as "past" (so refund ok?)
+ // OR if the intent is "0 means no deadline set yet (forever)", you must handle it.
+ // Assuming standard logic: Refund allowed ONLY after deadline.
+ if Clock::get().unwrap().unix_timestamp < ctx.accounts.fund.deadline {
return Err(ErrorCode::DeadlineNotReached.into());
}
// Refund logic...
Ok(())
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 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!