RustFund

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

Reentrancy Vulnerability

Summary

The refund funtion allows attacks throug improper state managment

Vulnerability Details

The contribution amount is reset after the refund but before the transfer completes

Impact

An attacker can repeatedly drain funds from the contract

Proof Of Concept:

// Attack scenario:
1. Contribute to campaign
2. Set up malicious contract that:
- Calls refund
- Re-enters before state update
- Repeats until funds depleted

Tools Used

Manual review

Recommendations

Implement checks-effects-interactions pattern

pub fn refund(ctx: Context<FundRefund>) -> Result<()> {
let contribution = &mut ctx.accounts.contribution;
let amount = contribution.amount;
// Reset contribution first
contribution.amount = 0;
// Then perform transfer
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
system_program::Transfer {
from: ctx.accounts.fund.to_account_info(),
to: ctx.accounts.contributor.to_account_info(),
},
);
system_program::transfer(cpi_context, amount)?;
Ok(())
}
Updates

Appeal created

bube Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

[Invalid] Reentrancy in refund

The reentrancy risk on Solana is highly eliminated. The `try_borrow_mut_lamports` ensures that only one reference to an account exists at a time. Also, once the fund’s lamports are borrowed mutably, no other transaction can modify them until the borrow is released. This means the function will reset the `amount` before the next call.

Support

FAQs

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