Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 928bb76

Browse files
Henry-Emvines
andauthored
Create the ATA account in one CPI call (unless it already has lamports in it) (#2325)
* create account in one cpi call unless already has lamports * move create PDA account to its own function * clippy Co-authored-by: = <nonsense> Co-authored-by: Michael Vines <[email protected]>
1 parent 515285e commit 928bb76

File tree

1 file changed

+64
-45
lines changed

1 file changed

+64
-45
lines changed

associated-token-account/program/src/processor.rs

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -48,53 +48,16 @@ pub fn process_instruction(
4848
&[bump_seed],
4949
];
5050

51-
// Fund the associated token account with the minimum balance to be rent exempt
5251
let rent = &Rent::from_account_info(rent_sysvar_info)?;
53-
let required_lamports = rent
54-
.minimum_balance(spl_token::state::Account::LEN)
55-
.max(1)
56-
.saturating_sub(associated_token_account_info.lamports());
5752

58-
if required_lamports > 0 {
59-
msg!(
60-
"Transfer {} lamports to the associated token account",
61-
required_lamports
62-
);
63-
invoke(
64-
&system_instruction::transfer(
65-
funder_info.key,
66-
associated_token_account_info.key,
67-
required_lamports,
68-
),
69-
&[
70-
funder_info.clone(),
71-
associated_token_account_info.clone(),
72-
system_program_info.clone(),
73-
],
74-
)?;
75-
}
76-
77-
msg!("Allocate space for the associated token account");
78-
invoke_signed(
79-
&system_instruction::allocate(
80-
associated_token_account_info.key,
81-
spl_token::state::Account::LEN as u64,
82-
),
83-
&[
84-
associated_token_account_info.clone(),
85-
system_program_info.clone(),
86-
],
87-
&[associated_token_account_signer_seeds],
88-
)?;
89-
90-
msg!("Assign the associated token account to the SPL Token program");
91-
invoke_signed(
92-
&system_instruction::assign(associated_token_account_info.key, spl_token_program_id),
93-
&[
94-
associated_token_account_info.clone(),
95-
system_program_info.clone(),
96-
],
97-
&[associated_token_account_signer_seeds],
53+
create_pda_account(
54+
funder_info,
55+
rent,
56+
spl_token::state::Account::LEN,
57+
&spl_token::id(),
58+
system_program_info,
59+
associated_token_account_info,
60+
associated_token_account_signer_seeds,
9861
)?;
9962

10063
msg!("Initialize the associated token account");
@@ -114,3 +77,59 @@ pub fn process_instruction(
11477
],
11578
)
11679
}
80+
81+
fn create_pda_account<'a>(
82+
funder: &AccountInfo<'a>,
83+
rent: &Rent,
84+
space: usize,
85+
owner: &Pubkey,
86+
system_program: &AccountInfo<'a>,
87+
new_pda_account: &AccountInfo<'a>,
88+
new_pda_signer_seeds: &[&[u8]],
89+
) -> ProgramResult {
90+
if new_pda_account.lamports() > 0 {
91+
let required_lamports = rent
92+
.minimum_balance(space)
93+
.max(1)
94+
.saturating_sub(new_pda_account.lamports());
95+
96+
if required_lamports > 0 {
97+
invoke(
98+
&system_instruction::transfer(funder.key, new_pda_account.key, required_lamports),
99+
&[
100+
funder.clone(),
101+
new_pda_account.clone(),
102+
system_program.clone(),
103+
],
104+
)?;
105+
}
106+
107+
invoke_signed(
108+
&system_instruction::allocate(new_pda_account.key, space as u64),
109+
&[new_pda_account.clone(), system_program.clone()],
110+
&[new_pda_signer_seeds],
111+
)?;
112+
113+
invoke_signed(
114+
&system_instruction::assign(new_pda_account.key, owner),
115+
&[new_pda_account.clone(), system_program.clone()],
116+
&[new_pda_signer_seeds],
117+
)
118+
} else {
119+
invoke_signed(
120+
&system_instruction::create_account(
121+
funder.key,
122+
new_pda_account.key,
123+
rent.minimum_balance(space).max(1),
124+
space as u64,
125+
owner,
126+
),
127+
&[
128+
funder.clone(),
129+
new_pda_account.clone(),
130+
system_program.clone(),
131+
],
132+
&[new_pda_signer_seeds],
133+
)
134+
}
135+
}

0 commit comments

Comments
 (0)