1

I am trying to create a staking program. When I test this code out, I get the subjected error:

use anchor_lang::prelude::*;
use anchor_spl::token::{self, Mint, Token, TokenAccount, Transfer as SplTransfer};
use solana_program::system_instruction;

// This is your program's public key and it will update
// automatically when you build the project.
declare_id!("CXVv68e6ofmf4HF5myUCMP8YifhD69toz4PEeBrn6gkX");

#[program]
pub mod Staking {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        Ok(())
    }

}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init_if_needed,
        payer = signer,
        seeds = [b"vault".as_ref()],
        bump,
        token::mint = mint,
        token::authority = token_vault_account
    )]
    pub token_vault_account: Account<'info, TokenAccount>,

    #[account(mut)]
    pub signer: Signer<'info>,

    pub mint: Account<'info, Mint>,
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
}

test

import {
  createMint,
  createAssociatedTokenAccount,
  mintTo,
  TOKEN_PROGRAM_ID,
} from "@solana/spl-token";

describe("Staking", () => {
  it("initializes", async () => {
    // Generate keypairs for the new accounts
    const payer = pg.wallet.keypair;

    // Create a new mint and initialize it
    const mintKp = new web3.Keypair();
    const mint = await createMint(
      pg.program.provider.connection,
      pg.wallet.keypair,
      payer.publicKey,
      null,
      0
    );

    //Create Vault PDA
    const [VAULT] = await anchor.web3.PublicKey.findProgramAddress(
      [Buffer.from("vault")],
      pg.program.programId
    );

    const txHash = await pg.program.methods
      .initialize()
      .accounts({
        mint: mint,
        tokenVaultAccount: VAULT,
        signer: payer,
      })
      .rpc();
    console.log(`https://explorer.solana.com/tx/${txHash}?cluster=devnet`);
    await pg.connection.confirmTransaction(txHash, "finalized");
  });
});

1 Answer 1

1

At the top of my head some issues that come up

  1. token::authority = token_vault_account - You are trying to set the token vault's authority as itself, yet this account hasn't been initialized.

  2. I generally see this as an anti-pattern to the Associated Token Account design and would advocate for that approach when doing escrow-based programs

As such your Accounts struct would change like this

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

    #[account(
        init_if_needed,
        payer = signer,
        associated_token::mint = mint,
        associated_token::authority = escrow_manager,
    )]
    pub token_vault_account: Account<'info, TokenAccount>,

    #[account(
        init_if_needed, 
        payer = signer,
        space = 8 + 64 
        seeds = [b"admin".as_ref()],
        bump,
    )]
    pub escrow_manager: Account<'info, EscrowManager>

    pub mint: Account<'info, Mint>,
    pub token_program: Program<'info, Token>,
    pub associated_token_program: Program<'info, AssociatedToken>,
    pub system_program: Program<'info, System>,
}

Then in your client side when deriving the ATA Vault Account,

   export const findEscrowManagerAddress = (): PublicKey => {
    return PublicKey.findProgramAddressSync(
        [Buffer.from("admin")],
        PROGRAM_ID
    )[0];
    };

    const txHash = await pg.program.methods
      .initialize()
      .accounts({
        mint: mint, 
        EscrowManager: findEscrowMangerAddress()
        tokenVaultAccount: getAssociatedTokenAddressSync(
                    mint,
                    findEscrowManagerAddress(),
                    true
                ),
        signer: payer,
        tokenProgram: TOKEN_PROGRAM_ID,
        systemProgram: SystemProgram.programId,
        associatedTokenProgram: ASSOCIATED_PROGRAM_ID,
      })
      .rpc();
1
  • Hey Jimii. Thanks again. I was following a tutorial on YouTube for this. I'll try it out and post the update.
    – Anas
    Commented Jun 2 at 22:27

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.