0

I have a buy instruction for a token which initializes the user's token in the context and it runs absolutely fine the first time I run / call it. But on subsequent calls I get the following error:

  1) learning.solana
       Second Buy:
     Error: Transaction  resulted in an error.
Error processing Instruction 0: Provided owner is not allowed. Logs: 
[
  "Program xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx invoke [1]",
  "Program log: Instruction: Buy",
  "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [2]",
  "Program log: Create",
  "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 3459 of 188205 compute units",
  "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL failed: Provided owner is not allowed",
  "Program xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx consumed 15254 of 200000 compute units",
  "Program xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx failed: Provided owner is not allowed"
]. 
Catch the `SendTransactionError` and call `getLogs()` on it for full details.
      at sendWithErr (node_modules/anchor-bankrun/src/index.ts:77:10)
      at BankrunProvider.sendAndConfirm (node_modules/anchor-bankrun/src/index.ts:158:3)
      at MethodsBuilder.rpc [as _rpcFn] (node_modules/@coral-xyz/anchor/src/program/namespace/rpc.ts:29:16)

This is my context:

#[derive(Accounts)]
pub struct BuyContext<'info> {
    #[account(mut)]
    pub user: Signer<'info>,

    #[account(
        seeds = [GLOBAL_SEED_PREFIX.as_bytes()],
        bump,
    )]
    pub global: Account<'info, GlobalState>,

    #[account()]
    pub mint: Account<'info, Mint>,

    #[account(
        mut,
        seeds = [BONDING_CURVE_SEED_PREFIX.as_bytes(), mint.to_account_info().key.as_ref()],
        bump,
    )]
    pub bonding_curve: Account<'info, BondingCurve>,

    #[account(
        mut,
        associated_token::mint = mint,
        associated_token::authority = bonding_curve,
    )]
    pub bonding_curve_token_account: Account<'info, TokenAccount>,

    #[account(
        init,
        payer = user,
        associated_token::mint = mint,
        associated_token::authority = user,
    )]
    pub user_token_account: Account<'info, TokenAccount>,

    pub token_program: Program<'info, Token>,

    pub system_program: Program<'info, System>,

    pub associated_token_program: Program<'info, AssociatedToken>,
}

I have a sell instruction that has basically an identical struct that does work. The only diff is the init vs mut... so it must have something to do with that.

Diff screen shot.

enter image description here

Note: The buy definitely does work the first as in my test I query the token account balance and it has the appropriate number of tokens.

1 Answer 1

2

In anchor, when you are creating an account with init burt you are not sure if it already exists (like in the second buy, or for any associated token account) it's better to use init_if_needed. It will vet created only if it doesn't exist. This is a special feature which needs ro be activated in cargo toml

1
  • Thank you! I recall reading somewhere the the init would check for the accounts existence first and you didn't need anything special, that source was obviously wrong because is has fixed it. Thank you!
    – ten5peed
    Commented Nov 17 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.