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

Commit 89aa947

Browse files
authored
associated-token-account: Fail idempotent for non-ata (#2903)
1 parent ab4b9fb commit 89aa947

File tree

3 files changed

+76
-12
lines changed

3 files changed

+76
-12
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ fn process_create_associated_token_account(
7272
let spl_token_program_info = next_account_info(account_info_iter)?;
7373
let spl_token_program_id = spl_token_program_info.key;
7474

75+
let (associated_token_address, bump_seed) = get_associated_token_address_and_bump_seed_internal(
76+
wallet_account_info.key,
77+
spl_token_mint_info.key,
78+
program_id,
79+
spl_token_program_id,
80+
);
81+
if associated_token_address != *associated_token_account_info.key {
82+
msg!("Error: Associated address does not match seed derivation");
83+
return Err(ProgramError::InvalidSeeds);
84+
}
85+
7586
if create_mode == CreateMode::Idempotent
7687
&& associated_token_account_info.owner == spl_token_program_id
7788
{
@@ -94,17 +105,6 @@ fn process_create_associated_token_account(
94105

95106
let rent = Rent::get()?;
96107

97-
let (associated_token_address, bump_seed) = get_associated_token_address_and_bump_seed_internal(
98-
wallet_account_info.key,
99-
spl_token_mint_info.key,
100-
program_id,
101-
spl_token_program_id,
102-
);
103-
if associated_token_address != *associated_token_account_info.key {
104-
msg!("Error: Associated address does not match seed derivation");
105-
return Err(ProgramError::InvalidSeeds);
106-
}
107-
108108
let associated_token_account_signer_seeds: &[&[_]] = &[
109109
&wallet_account_info.key.to_bytes(),
110110
&spl_token_program_id.to_bytes(),

associated-token-account/program/tests/create_idempotent.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use {
1111
program_option::COption,
1212
program_pack::Pack,
1313
signature::Signer,
14+
signer::keypair::Keypair,
15+
system_instruction::create_account,
1416
transaction::{Transaction, TransactionError},
1517
},
1618
spl_associated_token_account::{
@@ -22,6 +24,7 @@ use {
2224
},
2325
spl_token::{
2426
extension::ExtensionType,
27+
instruction::initialize_account,
2528
state::{Account, AccountState},
2629
},
2730
};
@@ -173,3 +176,64 @@ async fn fail_account_exists_with_wrong_owner() {
173176
)
174177
);
175178
}
179+
180+
#[tokio::test]
181+
async fn fail_non_ata() {
182+
let token_mint_address = Pubkey::new_unique();
183+
let (mut banks_client, payer, recent_blockhash) =
184+
program_test(token_mint_address, true).start().await;
185+
186+
let rent = banks_client.get_rent().await.unwrap();
187+
let token_account_len = ExtensionType::get_account_len::<spl_token::state::Account>(&[
188+
ExtensionType::ImmutableOwner,
189+
]);
190+
let token_account_balance = rent.minimum_balance(token_account_len);
191+
192+
let wallet_address = Pubkey::new_unique();
193+
let account = Keypair::new();
194+
let transaction = Transaction::new_signed_with_payer(
195+
&[
196+
create_account(
197+
&payer.pubkey(),
198+
&account.pubkey(),
199+
token_account_balance,
200+
token_account_len as u64,
201+
&spl_token::id(),
202+
),
203+
initialize_account(
204+
&spl_token::id(),
205+
&account.pubkey(),
206+
&token_mint_address,
207+
&wallet_address,
208+
)
209+
.unwrap(),
210+
],
211+
Some(&payer.pubkey()),
212+
&[&payer, &account],
213+
recent_blockhash,
214+
);
215+
banks_client.process_transaction(transaction).await.unwrap();
216+
217+
let mut instruction = create_associated_token_account_idempotent(
218+
&payer.pubkey(),
219+
&wallet_address,
220+
&token_mint_address,
221+
&spl_token::id(),
222+
);
223+
instruction.accounts[1] = AccountMeta::new(account.pubkey(), false); // <-- Invalid associated_account_address
224+
225+
let transaction = Transaction::new_signed_with_payer(
226+
&[instruction],
227+
Some(&payer.pubkey()),
228+
&[&payer],
229+
recent_blockhash,
230+
);
231+
assert_eq!(
232+
banks_client
233+
.process_transaction(transaction)
234+
.await
235+
.unwrap_err()
236+
.unwrap(),
237+
TransactionError::InstructionError(0, InstructionError::InvalidSeeds)
238+
);
239+
}

associated-token-account/program/tests/process_create_associated_token_account.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ async fn test_create_account_mismatch() {
213213
.await
214214
.unwrap_err()
215215
.unwrap(),
216-
TransactionError::InstructionError(0, InstructionError::IllegalOwner)
216+
TransactionError::InstructionError(0, InstructionError::InvalidSeeds)
217217
);
218218

219219
let mut instruction = create_associated_token_account(

0 commit comments

Comments
 (0)