Skip to content

Commit

Permalink
lang: associated_token constraints don't work when setting `token_p…
Browse files Browse the repository at this point in the history
…rogram` (coral-xyz#2603)

Co-authored-by: acheron <acheroncrypto@gmail.com>
  • Loading branch information
wjthieme and acheroncrypto authored Aug 23, 2023
1 parent 6f9f7d9 commit a7205af
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 99 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- client: Compile with Solana `1.14` ([#2572](https://github.com/coral-xyz/anchor/pull/2572)).
- cli: Fix `anchor build --no-docs` adding docs to the IDL ([#2575](https://github.com/coral-xyz/anchor/pull/2575)).
- ts: Load workspace programs on-demand rather than loading all of them at once ([#2579](https://github.com/coral-xyz/anchor/pull/2579)).
- lang: Fix `associated_token::token_program` constraint ([#2603](https://github.com/coral-xyz/anchor/pull/2603)).

### Breaking

Expand Down
14 changes: 12 additions & 2 deletions lang/syn/src/codegen/accounts/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ fn generate_constraint_init_group(
return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintAssociatedTokenTokenProgram).with_account_name(#name_str).with_pubkeys((*owner_program, #token_program.key())));
}

if pa.key() != ::anchor_spl::associated_token::get_associated_token_address(&#owner.key(), &#mint.key()) {
if pa.key() != ::anchor_spl::associated_token::get_associated_token_address_with_program_id(&#owner.key(), &#mint.key(), &#token_program.key()) {
return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::AccountNotAssociatedTokenAccount).with_account_name(#name_str));
}
}
Expand Down Expand Up @@ -913,6 +913,7 @@ fn generate_constraint_associated_token(
let name_str = name.to_string();
let wallet_address = &c.wallet;
let spl_token_mint_address = &c.mint;

let mut optional_check_scope = OptionalCheckScope::new_with_field(accs, name);
let wallet_address_optional_check = optional_check_scope.generate_check(wallet_address);
let spl_token_mint_address_optional_check =
Expand All @@ -921,6 +922,7 @@ fn generate_constraint_associated_token(
#wallet_address_optional_check
#spl_token_mint_address_optional_check
};

let token_program_check = match &c.token_program {
Some(token_program) => {
let token_program_optional_check = optional_check_scope.generate_check(token_program);
Expand All @@ -931,6 +933,14 @@ fn generate_constraint_associated_token(
}
None => quote! {},
};
let get_associated_token_address = match &c.token_program {
Some(token_program) => quote! {
::anchor_spl::associated_token::get_associated_token_address_with_program_id(&wallet_address, &#spl_token_mint_address.key(), &#token_program.key())
},
None => quote! {
::anchor_spl::associated_token::get_associated_token_address(&wallet_address, &#spl_token_mint_address.key())
},
};

quote! {
{
Expand All @@ -942,7 +952,7 @@ fn generate_constraint_associated_token(
if my_owner != wallet_address {
return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str).with_pubkeys((my_owner, wallet_address)));
}
let __associated_token_address = ::anchor_spl::associated_token::get_associated_token_address(&wallet_address, &#spl_token_mint_address.key());
let __associated_token_address = #get_associated_token_address;
let my_key = #name.key();
if my_key != __associated_token_address {
return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintAssociated).with_account_name(#name_str).with_pubkeys((my_key, __associated_token_address)));
Expand Down
15 changes: 8 additions & 7 deletions tests/misc/programs/misc-optional/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::account::*;
use anchor_lang::prelude::*;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token::{Mint, Token, TokenAccount};
use anchor_spl::token_interface::{Mint as MintInterface, TokenAccount as TokenAccountInterface};

#[derive(Accounts)]
pub struct TestTokenSeedsInit<'info> {
Expand Down Expand Up @@ -55,8 +56,8 @@ pub struct TestInitAssociatedTokenWithTokenProgram<'info> {
associated_token::authority = payer,
associated_token::token_program = associated_token_token_program,
)]
pub token: Option<Account<'info, TokenAccount>>,
pub mint: Option<Account<'info, Mint>>,
pub token: Option<InterfaceAccount<'info, TokenAccountInterface>>,
pub mint: Option<InterfaceAccount<'info, MintInterface>>,
#[account(mut)]
pub payer: Option<Signer<'info>>,
pub system_program: Option<Program<'info, System>>,
Expand Down Expand Up @@ -242,7 +243,7 @@ pub struct TestInitMintWithTokenProgram<'info> {
mint::freeze_authority = payer,
mint::token_program = mint_token_program,
)]
pub mint: Option<Account<'info, Mint>>,
pub mint: Option<InterfaceAccount<'info, MintInterface>>,
#[account(mut)]
pub payer: Option<Signer<'info>>,
pub system_program: Option<Program<'info, System>>,
Expand Down Expand Up @@ -439,8 +440,8 @@ pub struct TestInitAssociatedTokenIfNeededWithTokenProgram<'info> {
associated_token::authority = authority,
associated_token::token_program = associated_token_token_program,
)]
pub token: Option<Account<'info, TokenAccount>>,
pub mint: Option<Account<'info, Mint>>,
pub token: Option<InterfaceAccount<'info, TokenAccountInterface>>,
pub mint: Option<InterfaceAccount<'info, MintInterface>>,
#[account(mut)]
pub payer: Option<Signer<'info>>,
pub system_program: Option<Program<'info, System>>,
Expand Down Expand Up @@ -685,8 +686,8 @@ pub struct TestAssociatedTokenWithTokenProgramConstraint<'info> {
associated_token::authority = authority,
associated_token::token_program = associated_token_token_program,
)]
pub token: Option<Account<'info, TokenAccount>>,
pub mint: Account<'info, Mint>,
pub token: Option<InterfaceAccount<'info, TokenAccountInterface>>,
pub mint: InterfaceAccount<'info, MintInterface>,
/// CHECK: ignore
pub authority: AccountInfo<'info>,
/// CHECK: ignore
Expand Down
15 changes: 8 additions & 7 deletions tests/misc/programs/misc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::account::*;
use anchor_lang::prelude::*;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token::{Mint, Token, TokenAccount};
use anchor_spl::token_interface::{Mint as MintInterface, TokenAccount as TokenAccountInterface};

#[derive(Accounts)]
pub struct TestTokenSeedsInit<'info> {
Expand Down Expand Up @@ -56,8 +57,8 @@ pub struct TestInitAssociatedTokenWithTokenProgram<'info> {
associated_token::authority = payer,
associated_token::token_program = associated_token_token_program,
)]
pub token: Account<'info, TokenAccount>,
pub mint: Account<'info, Mint>,
pub token: InterfaceAccount<'info, TokenAccountInterface>,
pub mint: InterfaceAccount<'info, MintInterface>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
Expand Down Expand Up @@ -240,7 +241,7 @@ pub struct TestInitMintWithTokenProgram<'info> {
mint::freeze_authority = payer,
mint::token_program = mint_token_program,
)]
pub mint: Account<'info, Mint>,
pub mint: InterfaceAccount<'info, MintInterface>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
Expand Down Expand Up @@ -445,8 +446,8 @@ pub struct TestInitAssociatedTokenIfNeededWithTokenProgram<'info> {
associated_token::authority = authority,
associated_token::token_program = associated_token_token_program,
)]
pub token: Account<'info, TokenAccount>,
pub mint: Account<'info, Mint>,
pub token: InterfaceAccount<'info, TokenAccountInterface>,
pub mint: InterfaceAccount<'info, MintInterface>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
Expand Down Expand Up @@ -700,8 +701,8 @@ pub struct TestAssociatedTokenWithTokenProgramConstraint<'info> {
associated_token::authority = authority,
associated_token::token_program = associated_token_token_program,
)]
pub token: Account<'info, TokenAccount>,
pub mint: Account<'info, Mint>,
pub token: InterfaceAccount<'info, TokenAccountInterface>,
pub mint: InterfaceAccount<'info, MintInterface>,
/// CHECK: ignore
pub authority: AccountInfo<'info>,
/// CHECK: ignore
Expand Down
Loading

0 comments on commit a7205af

Please sign in to comment.