RustFund

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

Contribution amounts not tracked, breaking refund functionality

Description

The contribute function in the RustFund program fails to update the contribution.amount field after a successful contribution. This leads to a critical issue where the refund functionality becomes completely broken, as it relies on this value to determine how much SOL to return to contributors.

Proof of Concept

  1. User A creates a fund using fund_create

  2. User B contributes 1 SOL to the fund using contribute

  3. The contribute function transfers the SOL to the fund account and updates fund.amount_raised

  4. However, contribution.amount remains at 0 because it's never updated

  5. When User B tries to get a refund using refund, the function uses contribution.amount (which is 0)

  6. The refund function attempts to subtract 0 SOL from the fund and add 0 SOL to the contributor

  7. User B receives no refund despite having contributed 1 SOL

Relevant Code Snippets

// In contribute function
pub fn contribute(ctx: Context<FundContribute>, amount: u64) -> Result<()> {
// ... other code ...
// Initialize or update contribution record
if contribution.contributor == Pubkey::default() {
contribution.contributor = ctx.accounts.contributor.key();
contribution.fund = fund.key();
contribution.amount = 0;
}
// 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;
// Missing: contribution.amount += amount;
Ok(())
}
// In refund function
pub fn refund(ctx: Context<FundRefund>) -> Result<()> {
let amount = ctx.accounts.contribution.amount; // This will always be 0
// ... rest of refund logic ...
}

Recommendation

Update contribution amount after transfer (Recommended)

pub fn contribute(ctx: Context<FundContribute>, amount: u64) -> Result<()> {
// ... existing code ...
system_program::transfer(cpi_context, amount)?;
fund.amount_raised += amount;
+ contribution.amount += amount;
Ok(())
}

This issue is critical as it prevents users from getting their contributions refunded, effectively locking their funds in the contract.

Updates

Appeal created

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