RustFund

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

refund() & withdraw() Functions Does Not Subtract Refunded Amount from Fund Raised

Summary

In the refund, withdraw functions, when a contributor successfully claims a refund or withdraw respectevely, the contract does not subtract the refunded amount from fund.amount_raised. This oversight can lead to incorrect accounting of the funds raised by the campaign, potentially allowing multiple refund claims and inaccurate campaign state.

Vulnerability Details

When a contributor receives a refund or creator withdraw the amount, the contract transfers the funds from the fund account to the users account using direct lamport manipulation. However, the code does not update the fund.amount_raised variable to reflect that the funds have been refunded. As a result, the recorded amount raised remains unchanged even after funds are withdrawn, which can lead to:

  • Double refunds or repeated refund or withdraw claims by the same contributor or creator respectively.

  • Misleading campaign data where the fund appears to have more funds than it actually does.

  • Potential depletion of the fund balance without proper accounting.

Impact

  • Financial Inconsistency: The campaign's total raised amount becomes inaccurate, making it unclear how much funding is actually available or has been refunded.

  • Security Risk: Malicious users could exploit this flaw by triggering multiple refunds, draining the campaign funds.

  • Trust Issues: Incorrect fund accounting undermines trust in the platform's ability to manage contributions and refunds properly.

Tools Used

  • Manual code review

  • Static analysis of contract logic

Recommendations

  • Update Fund Amount: Modify the refund function to subtract the refunded amount from fund.amount_raised once the refund is processed. For example:

    pub fn refund(ctx: Context<FundRefund>) -> Result<()> {
    // ---- Funtion logic ----
    fund.amount_raised = fund.amount_raised.checked_sub(amount).ok_or(ProgramError::InsufficientFunds)?;
    }
    pub fn withdraw(ctx: Context<FundWithdraw>>) -> Result<()> {
    // ---- Funtion logic ----
    fund.amount_raised = fund.amount_raised.checked_sub(amount).ok_or(ProgramError::InsufficientFunds)?;
    }
  • Ensure Atomicity: Ensure that both the lamport transfer and the update to fund.amount_raised occur atomically to prevent race conditions.

  • By incorporating these changes, the refund mechanism will maintain accurate accounting of the campaign's raised funds and prevent potential exploitation through repeated refund claims.

Updates

Appeal created

bube Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

`amount_raised` is not reset to 0 in `withdraw` function

`amount_raised` not updated in `refund` function

Support

FAQs

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