RustFund

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

Missing Contribution Amount Tracking in RustFund

Summary

A critical vulnerability has been identified in the RustFund crowdfunding platform. The contribute function fails to track individual contribution amounts properly, which causes users to lose funds when requesting refunds. This is a high-severity issue that could lead to permanent loss of user funds.

Vulnerability Details

The RustFund smart contract has a critical accounting error in the contribute function. While the contract correctly tracks the total amount raised in the fund, it fails to update individual contribution records. When a user requests a refund, the contract only returns the amount stored in their contribution record, which remains at 0 (or its initial value).

pub fn contribute(ctx: Context<FundContribute>, amount: u64) -> Result<()> {
let fund = &mut ctx.accounts.fund;
let contribution = &mut ctx.accounts.contribution;
// ...validation code...
// Initialize contribution record if new
if contribution.contributor == Pubkey::default() {
contribution.contributor = ctx.accounts.contributor.key();
contribution.fund = fund.key();
contribution.amount = 0; // Initialize to 0
}
// Transfer SOL
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;
// MISSING: contribution.amount += amount;
Ok(())
}

Attack Path:

  1. A user creates a new contribution by calling the contribute function

  2. The contract tracks the total amount_raised but fails to update contribution.amount

  3. The user attempts to get a refund by calling the refund function

  4. The refund function uses contribution.amount (which is still 0) to determine the refund amount

  5. The user receives 0 SOL back despite having contributed funds

Impact

Fund Theft: When users request refunds, they will only get back the amount stored in their contribution record (0 SOL), not their actual contributed amount. This effectively allows the smart contract to keep all contributed funds.

Locked Funds: All contributions become permanently locked in the contract if the deadline is reached, as the refund function can only return the tracked contribution amount.

Trust Violation: The crowdfunding platform advertises a refund mechanism that doesn't work, misleading users about the safety of their contributions.

Tools Used

Static code analysis of Solana/Anchor Rust program

Manual review of fund management functions

Recommendations

Add the missing tracking code to the contribute function:

pub fn contribute(ctx: Context<FundContribute>, amount: u64) -> Result<()> {
// ...existing code...
fund.amount_raised += amount;
contribution.amount += amount; // Add this line
Ok(())
}
Updates

Appeal created

bube Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Contribution amount is not updated

Support

FAQs

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