Summary
refund function not checking if the goal was reached.
Vulnerability Details
refund
function does not check if the goal was reached, so even if it was reached but the owner didn't withdrawl the money yet depositors could get them back.
https://github.com/CodeHawks-Contests/2025-03-rustfund/blob/main/programs/rustfund/src/lib.rs#L66-L88
pub fn refund(ctx: Context<FundRefund>) -> Result<()> {
let amount = ctx.accounts.contribution.amount;
if ctx.accounts.fund.deadline != 0 && ctx.accounts.fund.deadline > Clock::get().unwrap().unix_timestamp.try_into().unwrap() {
return Err(ErrorCode::DeadlineNotReached.into());
}
**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)?;
ctx.accounts.contribution.amount = 0;
Ok(())
}
Impact
the idea of crowdfunding is that contributors can only recover their money if the deadline or the goal was reached but even if the goal was reached contributors can still get their money back.
Tools Used
manual
Recommendations
check if goal of the crowdfunding was reached, if not allow for refund