Skip to main content
added 2 characters in body
Source Link
Void
  • 416
  • 1
  • 5
  • 16

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 {
            // CLOSECLOSING 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(())
    }
}

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 {
            // CLOSE 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(())
    }
}

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(())
    }
}
added 10 characters in body
Source Link
Void
  • 416
  • 1
  • 5
  • 16

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.playcalculate_debt();

        if ctx.accounts.user_vault.result == Status::Inactive {
            // CLOSE 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(())
    }
}

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.play();

        if ctx.accounts.user_vault.result == Status::Inactive {
            // CLOSE 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(())
    }
}

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 {
            // CLOSE 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(())
    }
}
Source Link
Void
  • 416
  • 1
  • 5
  • 16

Close PDA account dynamically and conditionally in secure way

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.play();

        if ctx.accounts.user_vault.result == Status::Inactive {
            // CLOSE 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(())
    }
}