1

I have codes for transfer USDC from ATA to PDA and PDA to ATA. Also i have counter for people to be able create PDAs more than one. Counter was u8 at before. Then i realized one people only can create PDA 0-255 then i have updated u8 to u32. After then i can't get USDC from PDA to ATA.

Error is: Cross-program invocation with unauthorized signer or writable account.

I guess it caused by i couldn't create seed correctly in usdctoreciever function.

Here is codes transfer:

         let assigned_counter_info = &ctx.accounts.statepda.assigned_counter.to_be_bytes();
        let bump_vector = _bump1.to_le_bytes();
        let amount = ctx.accounts.statepda.pda_total_amount;
        //let dep = &mut ctx.accounts.deposit_token_account.key();
        let sender = ctx.accounts.statepda.owner;
        let inner = vec![
            sender.as_ref(),
            assigned_counter_info.as_ref(),
            sender.as_ref(),
            STATE_TAG,
            bump_vector.as_ref(),
        ];
        let outer = vec![inner.as_slice()];

            let transfer_instruction = Transfer {
                from: ctx.accounts.tokenpda.to_account_info(),
                to: ctx.accounts.wallet_to_deposit_to.to_account_info(),
                authority: ctx.accounts.statepda.to_account_info(),
            };

            let cpi_ctx = CpiContext::new_with_signer(
                ctx.accounts.token_program.to_account_info(),
                transfer_instruction,
                outer.as_slice(),
            );

            msg!("trasnfer call start");
            anchor_spl::token::transfer(cpi_ctx, amount)?;

Here is state account init:

    #[account(
            init,
            payer = owner,
            seeds=[owner.key.as_ref(),&(counter_pda.count + 1).to_le_bytes(),owner.key().as_ref(),STATE_TAG],
            bump,
            space=8 + 1 + 8 + 32 + 32 + 14 + 4 + 33 + 1 + 32 + 8,

        )]
    statepda: Account<'info, State>,

this one init for token:

    #[account(
            init,
            seeds = [owner.key.as_ref(),&(statepda.assigned_counter).to_le_bytes() ,owner.key().as_ref()],
            bump,
            payer = owner,
            token::mint = mint,
            token::authority = statepda,
        )]
    pub tokenpda: Account<'info, TokenAccount>,

2 Answers 2

1

From your code, you are initializing a token account and not an Associated Token Account.

Although, not secure, The first change I would recommend is using init_if_needed constraint to avoid account already initialized errors

Second, change the ATA initialization to this

    #[account(
        init_if_needed,
        payer = owner,
        associated_token::mint = mint,
        associated_token::authority = state_pda,
    )]
    pub tokenpda: Account<'info, TokenAccount>,

You can then avoid using the seeds and instead call the getAssociatedTokenAddressSync from the JS/TS solana/spl-token package like this

let tokenpda = getAssociatedTokenAddressSync(
                    mint,
                    statepda,
                    true
                ),

The final change would be regarding transferring the token and using the statepda as the authority

let bump = &[statepda.bump]; // assuming in you statepda account you created a field called bump. Significantly reduces CUs used
let signer_seeds = &[&[owner.key.as_ref(),&(counter_pda.count + 1).to_le_bytes(),owner.key().as_ref(),STATE_TAG, bump][..]];

 let cpi_ctx = CpiContext::new_with_signer(
                ctx.accounts.token_program.to_account_info(),
                transfer_instruction,
                signer_seeds,
            );

4
  • 1
    i guess you forget to add "bump" into signer_seeds ? Commented May 22 at 19:29
  • now i getting Provided seeds do not result in a valid address but problem may caused by not empty state_pda? state_pdate hold some data ? i need your help @jimii Commented May 22 at 20:24
  • update the signer seeds with the pda seeds for statepda. Maybe I missed something. Are you setting the bump correctly? could you also share the statepda address?
    – Jimii
    Commented May 22 at 20:47
  • actually it's a little bit classified could you please share you discord or telegram adress i really want to show you all codes bro @Jimii Commented May 23 at 16:22
0

ctx.accounts.wallet_to_deposit_to.to_account_info()

is this marked #[account(mut)] in your Context?

1
  • yes everythink was working till i've changed counter u8 to u32 Commented May 22 at 19:10

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.