The refund and withdraw functions in the RustFund program directly manipulate the lamport balance of the fund account (via try_borrow_mut_lamports()) to transfer SOL to contributors/creators. But:
No check is performed to ensure the fund account’s remaining lamports meet Solana’s rent-exempt minimum balance after the transfer.
If the transfer reduces the fund account’s lamports below the rent-exempt threshold, the account is automatically closed by the Solana network. This deletes all critical data (e.g., contribution records, campaign details, deadline status) and renders core platform functionality (refunds, withdrawals) permanently non-functional.
Likelihood:
The code does not:
Fetch the current rent parameters (via Rent::get()?).
Calculate the rent-exempt minimum balance for the fund account (based on its data size: Rent::minimum_balance(fund.data_len())).
Validate that fund.lamports() - transfer_amount >= minimum_balance before modifying lamports.
Impact:
Impact 1: Permanent Loss of Campaign Data
If the fund account is closed:
All Contribution records (linking contributors to their donated amounts) are lost → contributors cannot prove their donations and cannot claim refunds.
Campaign metadata (name, description, goal, deadline) is deleted → creators cannot verify campaign status or withdraw funds even if the goal was met.
Impact 2: Irreversible Fund Loss
If the fund account is closed, remaining lamports (unrefunded/withdrawn funds) are sent to the account’s owner (e.g., the creator), but contributors lose access to their funds (no records to prove eligibility for refunds).
In worst-case scenarios, the closed account cannot be recovered, leading to permanent loss of all funds in the campaign.
## Description The `refund` function in the provided code directly manipulates the lamports of accounts using `try_borrow_mut_lamports()`. This approach bypasses the Solana runtime's safety checks, leading to potential security vulnerabilities and program instability. ## Vulnerability Details In the `refund` function, lamports are transferred between accounts by directly adjusting their balances:   ```Rust **ctx.accounts.fund.to_account_info().try_borrow_mut_lamports()? = ctx.accounts.fund.to_account_info().lamports().checked_sub(amount).ok_or(ProgramError::InsufficientFunds)?; **ctx.accounts.contributor.to_account_info().try_borrow_mut_lamports()? = ctx.accounts.contributor.to_account_info().lamports().checked_add(amount).ok_or(ErrorCode::CalculationOverflow)?; ``` This method of direct lamport manipulation can lead to several issues: 1. **Bypassing Rent Exemption Checks:** Accounts in Solana must maintain a minimum balance to be rent-exempt. Directly reducing an account's lamports without verifying rent exemption can result in the account being marked for deletion by the Solana runtime. 2. **Ownership Constraints:** Only the owning program of an account can modify its data and lamport balance. Direct manipulation without proper checks can violate these constraints, leading to program errors. 3. **Lack of Atomicity:** Direct lamport transfers lack the atomic transaction guarantees provided by the system program's transfer instruction, potentially leading to inconsistent states in case of program interruptions. ## Impact Exploiting this vulnerability can result in unauthorized fund transfers, violation of Solana's account ownership rules, and potential loss of funds due to accounts becoming non-rent-exempt. ## Recommendations Replace the direct lamport manipulation with Solana's system program transfer instruction to ensure safe and compliant fund transfers in refund() & withdraw() functions:   ```Rust 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)?; ``` This approach leverages Solana's native mechanisms for transferring lamports, ensuring adherence to the platform's safety and security protocols.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.