RustFund

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

Contributions Are Not Properly Tracked

Summary

The contribute function does not properly update individual contributors' records. While funds are successfully transferred to the campaign, the contribution.amount field is never incremented. This contradicts the documentation, which states:

"Users can contribute SOL to any active campaign."

Since contributions are not tracked correctly, contributors may not be able to request refunds correctly later.

Vulnerability Details

  • The function initializes a contribution record if it does not exist but does not increment the amount contributed when a contributor makes multiple contributions.

  • This could lead to inaccurate refund calculations since the contract would not correctly track how much a user contributed.

Proof of Concept

  • A user contributes 5 SOL to a campaign.

  • The user contributes another 5 SOL later.

  • Due to the missing update, their total recorded contribution remains 5 SOL instead of 10 SOL.

  • If they attempt a refund, they may only receive 5 SOL even though they contributed 10 SOL.

The Impact Code

pub fn contribute(ctx: Context<FundContribute>, amount: u64) -> Result<()> {
let fund = &mut ctx.accounts.fund;
let contribution = &mut ctx.accounts.contribution;
if fund.deadline != 0 && fund.deadline < Clock::get().unwrap().unix_timestamp.try_into().unwrap() {
return Err(ErrorCode::DeadlineReached.into());
}
if contribution.contributor == Pubkey::default() {
contribution.contributor = ctx.accounts.contributor.key();
contribution.fund = fund.key()
contribution.amount = 0; // This should be incremented, but it's not
}
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 should be updated
Ok(())
}

Impact

  • Contributors' contributions are not accurately recorded, which may lead to incorrect refund amounts.

  • If multiple contributions are made, only the first one is considered.

  • This violates the documented expectation that users can continuously contribute SOL to a campaign.

Tools Used

Manual code review

Recommendations

Update the contribute function to increment the contributor's recorded amount each time they contribute:

contribution.amount += amount;

So the corrected function would be:

if contribution.contributor == Pubkey::default() {
contribution.contributor = ctx.accounts.contributor.key();
contribution.fund = fund.key();
}
contribution.amount += amount; //Properly track the total contribution
Updates

Appeal created

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