#[test]
fn test_withdraw_before_deadline_vulnerability() {
setup_syscall_stubs();
let fund_key = Pubkey::new_unique();
let creator_key = Pubkey::new_unique();
let program_id = crate::ID;
let mut fund_lamports = 100_000_000;
let mut fund_data = vec![0u8; 8 + Fund::INIT_SPACE];
let mut creator_lamports = 1_000_000_000;
let mut creator_data = vec![];
let initial_fund_state = Fund {
name: "Test Fund".to_string(),
description: "Desc".to_string(),
goal: 500,
deadline: 5000,
creator: creator_key,
amount_raised: 500,
dealine_set: true,
};
let mut writer = &mut fund_data[..];
initial_fund_state.try_serialize(&mut writer).unwrap();
let fund_info = AccountInfo::new(
&fund_key, false, true, &mut fund_lamports, &mut fund_data, &program_id, false, 0
);
let creator_info = AccountInfo::new(
&creator_key, true, true, &mut creator_lamports, &mut creator_data, &program_id, false, 0
);
let system_program_key = anchor_lang::solana_program::system_program::ID;
let bpf_loader_id = anchor_lang::solana_program::bpf_loader::id();
let mut system_program_lamports = 0;
let mut system_program_data = vec![];
let system_program_info = AccountInfo::new(
&system_program_key, false, false, &mut system_program_lamports, &mut system_program_data, &bpf_loader_id, true, 0
);
let fund_acc_final: Account<Fund> = Account::try_from(&fund_info).unwrap();
let creator_sig: Signer = Signer::try_from(&creator_info).unwrap();
let system_prog: Program<System> = Program::try_from(&system_program_info).unwrap();
let mut accounts = FundWithdraw {
fund: fund_acc_final,
creator: creator_sig,
system_program: system_prog,
};
let ctx = Context::new(
&program_id,
&mut accounts,
&[],
FundWithdrawBumps::default(),
);
let res = crate::rustfund::withdraw(ctx);
assert!(res.is_ok());
}
pub fn withdraw(ctx: Context<FundWithdraw>) -> Result<()> {
+ let fund = &ctx.accounts.fund;
+ let clock = Clock::get()?;
+
+ // Ensure the deadline has passed
+ require!(fund.deadline != 0 && clock.unix_timestamp >= fund.deadline as i64, ErrorCode::DeadlineNotReached);
+
+ // Ensure the funding goal was met
+ require!(fund.amount_raised >= fund.goal, ErrorCode::GoalNotMet);
let amount = ctx.accounts.fund.amount_raised;