I want to close the PDA account only on specif condition. Macro [account(mut, close = <target_account>)]
does not work in this case because it will always be triggered after instruction completion. Also security should also be taken into account in order to avoid sealevel-attacks
. I followed the instruction provided here but I am not sure what is the purpose of force_defund
instruction and how to integrate it with my code:
#[derive(Accounts)]
pub struct Debt<'info> {
pub user: SystemAccount<'info>,
#[account(
mut,
seeds = [b"vault".as_ref(), player.key().as_ref()],
bump = vault.bump
)]
pub user_vault: Account<'info, Vault>,
#[account(mut)]
pub vault: SystemAccount<'info>,
pub system_program: Program<'info, System>,
}
impl Debt<'_> {
pub fn debt(ctx: Context<Self>) -> Result<()> {
ctx.accounts.user_vault.calculate_debt();
if ctx.accounts.user_vault.result == Status::Inactive {
// CLOSING SECURELY THE USER VAULT PDA ACCOUNT
**ctx.accounts.user.to_account_info().try_borrow_mut_lamports()? +=
**ctx.accounts.user_vault.to_account_info().try_borrow_lamports()?;
**ctx.accounts.user_vault.to_account_info().try_borrow_mut_lamports()? = 0;
let user_vault_account = ctx.accounts.user_vault.to_account_info();
let mut data = user_vault_account.try_borrow_mut_data()?;
for byte in data.deref_mut().iter_mut() {
*byte = 0;
}
let dst: &mut [u8] = &mut data;
let mut cursor = Cursor::new(dst);
cursor.write_all(&CLOSED_ACCOUNT_DISCRIMINATOR).unwrap();
}
// DO SOME OTHER STUFF
Ok(())
}
}