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 10 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.

Give us feedback!