safe pda creation to avoid lamport dos attacks

This commit is contained in:
Hardhat Chad
2024-03-08 16:47:05 +00:00
parent 4dfd101c26
commit 9f744cd24d
3 changed files with 238 additions and 23 deletions

View File

@@ -15,21 +15,66 @@ pub(crate) fn create_pda<'a, 'info>(
payer: &'a AccountInfo<'info>,
) -> ProgramResult {
let rent = Rent::get()?;
solana_program::program::invoke_signed(
&solana_program::system_instruction::create_account(
payer.key,
target_account.key,
rent.minimum_balance(space as usize),
space as u64,
owner,
),
&[
payer.clone(),
target_account.clone(),
system_program.clone(),
],
&[pda_seeds],
)?;
if target_account.lamports().eq(&0) {
// If balance is zero, create account
solana_program::program::invoke_signed(
&solana_program::system_instruction::create_account(
payer.key,
target_account.key,
rent.minimum_balance(space),
space as u64,
owner,
),
&[
payer.clone(),
target_account.clone(),
system_program.clone(),
],
&[pda_seeds],
)?;
} else {
// Otherwise, if balance is nonzero:
// 1) transfer sufficient lamports for rent exemption
let rent_exempt_balance = rent
.minimum_balance(space)
.saturating_sub(target_account.lamports());
if rent_exempt_balance.gt(&0) {
solana_program::program::invoke(
&solana_program::system_instruction::transfer(
payer.key,
target_account.key,
rent_exempt_balance,
),
&[
payer.as_ref().clone(),
target_account.as_ref().clone(),
system_program.as_ref().clone(),
],
)?;
}
// 2) allocate space for the account
solana_program::program::invoke_signed(
&solana_program::system_instruction::allocate(target_account.key, space as u64),
&[
target_account.as_ref().clone(),
system_program.as_ref().clone(),
],
&[pda_seeds],
)?;
// 3) assign our program as the owner
solana_program::program::invoke_signed(
&solana_program::system_instruction::assign(target_account.key, owner),
&[
target_account.as_ref().clone(),
system_program.as_ref().clone(),
],
&[pda_seeds],
)?;
}
Ok(())
}