RustFund

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

`contribution.amount` Is Never Updated in `contribute` function

Summary : In the contribute function, contribution.amount is initialized to zero for new contributors but is never updated to reflect the actual contributed amount. This causes the refund mechanism to always refund zero SOL, regardless of the actual contribution.

Vulnerability Details:

  1. A contributor calls contribute with amount = 100 SOL.

  2. The fund’s amount_raised increases by 100 SOL, but contribution.amount remains 0.

  3. When the contributor calls refund, the refund amount is 0 SOL, not 100 SOL.

Impact: - Contributors cannot claim their rightful refunds because the recorded contribution amount is always zero.

  • This effectively locks contributed funds in the contract, preventing legitimate refunds.

Tools Used :anchor test

it("Demonstrates contribution.amount is never updated", async () => {
const bugFundName = "BugDemoFund";
const [bugFundPDA] = await PublicKey.findProgramAddress(
[Buffer.from(bugFundName), creator.publicKey.toBuffer()],
program.programId
);
await program.methods
.fundCreate(bugFundName, description, goal)
.accounts({
fund: bugFundPDA,
creator: creator.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
})
.rpc();

const bugDeadline = new anchor.BN(Math.floor(Date.now() / 1000) + 60); // 60 sec
await program.methods
.setDeadline(bugDeadline)
.accounts({
fund: bugFundPDA,
creator: creator.publicKey,
})
.rpc();
const [bugContributionPDA] = await PublicKey.findProgramAddress(
[bugFundPDA.toBuffer(), provider.wallet.publicKey.toBuffer()],
program.programId
);
await program.methods
.contribute(contribution)
.accounts({
fund: bugFundPDA,
contributor: provider.wallet.publicKey,
contribution: bugContributionPDA,
systemProgram: anchor.web3.SystemProgram.programId,
})
.rpc();
const contributionAccount = await program.account.contribution.fetch(
bugContributionPDA
);
console.log("Contribution Amount:", contributionAccount.amount.toString());
expect(contributionAccount.amount.toNumber()).to.equal(0); // Bug: should be 0.5 SOL
await new Promise((resolve) => setTimeout(resolve, 65000)); // Wait 65 sec
const fundBalanceBefore = await provider.connection.getBalance(bugFundPDA);
await program.methods
.refund()
.accounts({
fund: bugFundPDA,
contribution: bugContributionPDA,
contributor: provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
})
.rpc();
const fundBalanceAfter = await provider.connection.getBalance(bugFundPDA);
console.log("Fund Balance Before Refund:", fundBalanceBefore);
console.log("Fund Balance After Refund:", fundBalanceAfter);
expect(fundBalanceBefore).to.equal(fundBalanceAfter); // No SOL refunded

});

Recommendations

  • Update contribution.amount to accumulate the contributed amount.

  • contribution.amount = contribution.amount.checked_add(amount).ok_or(ErrorCode::CalculationOverflow)?;

Updates

Appeal created

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