Description
The refund
and withdraw
functions directly manipulate lamports (SOL) using try_borrow_mut_lamports()
, bypassing Solana’s native system_program::transfer
logic. This approach is error-prone and violates best practices for handling SOL transfers.
Impact
Fund Loss: Incorrect lamport arithmetic (e.g., underflow/overflow) can corrupt balances.
Reentrancy Risks: Manual lamport updates lack atomicity, opening vectors for exploits.
Protocol Instability: Direct manipulation bypasses system-level security checks.
Affected Code
**ctx.accounts.fund.to_account_info().try_borrow_mut_lamports()? =
ctx.accounts.fund.lamports().checked_sub(amount)?;
**ctx.accounts.contributor.to_account_info().try_borrow_mut_lamports()? =
ctx.accounts.contributor.lamports().checked_add(amount)?;
**ctx.accounts.fund.to_account_info().try_borrow_mut_lamports()? =
ctx.accounts.fund.lamports().checked_sub(amount)?;
**ctx.accounts.creator.to_account_info().try_borrow_mut_lamports()? =
ctx.accounts.creator.lamports().checked_add(amount)?;
Recommendation
Replace manual lamport updates with system_program::transfer
for secure SOL movements:
For refund()
:
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)?;
For withdraw()
:
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.creator.to_account_info(),
},
);
system_program::transfer(cpi_context, amount)?;