4

I have an instruction which transfers tokens, pnft and closes the account. I get the above error when I call the instruction from the frontend.

Here's the instruction code

pub fn handler(ctx: Context<Repay>, interest_amount: u64) -> Result<()> {
    let loan_account = &mut ctx.accounts.loan_account;
    loan_account.status = LoanStatus::Repaid;
    loan_account.end_time = Clock::get()?.unix_timestamp;

    let amount = loan_account.terms.principal + interest_amount;

    // transfer principal + interest from borrower to lender
    anchor_lang::system_program::transfer(
        CpiContext::new(
            ctx.accounts.system_program.to_account_info(),
            anchor_lang::system_program::Transfer {
                from: ctx.accounts.borrower.to_account_info(),
                to: ctx.accounts.lender.to_account_info(),
            },
        ),
        amount,
    )?;

    // transfer pnft from loan vault to borrower
    let transfer_ix = TransferBuilder::new()
        .metadata(ctx.accounts.metadata.key())
        .mint(ctx.accounts.nft_mint.key())
        .authority(ctx.accounts.vault_authority.key())
        .payer(ctx.accounts.borrower.key())
        .token(ctx.accounts.loan_nft_vault.key())
        .token_owner(ctx.accounts.vault_authority.key())
        .destination(ctx.accounts.borrower_nft_account.key())
        .destination_owner(ctx.accounts.borrower.key())
        .owner_token_record(ctx.accounts.owner_token_record.key())
        .destination_token_record(ctx.accounts.destination_token_record.key())
        .edition(ctx.accounts.edition.key())
        .authorization_rules(ctx.accounts.auth_rules.key())
        .authorization_rules_program(ctx.accounts.auth_rules_program.key())
        .build(TransferArgs::V1 {
            amount: 1,
            authorization_data: None,
        })
        .unwrap()
        .instruction();

    msg!("setting transfer ix accounts");

    let transfer_infos = vec![
        ctx.accounts.metadata.to_account_info(),
        ctx.accounts.nft_mint.to_account_info(),
        ctx.accounts.vault_authority.to_account_info(),
        ctx.accounts.loan_nft_vault.to_account_info(),
        ctx.accounts.borrower_nft_account.to_account_info(),
        ctx.accounts.borrower.to_account_info(),
        ctx.accounts.owner_token_record.to_account_info(),
        ctx.accounts.destination_token_record.to_account_info(),
        ctx.accounts.edition.to_account_info(),
        ctx.accounts.auth_rules.to_account_info(),
        ctx.accounts.auth_rules_program.to_account_info(),
        ctx.accounts.sysvar_instructions.to_account_info(),
        ctx.accounts.token_program.to_account_info(),
        ctx.accounts.associated_token_program.to_account_info(),
        ctx.accounts.system_program.to_account_info(),
    ];

    msg!("invoking transfer ix");
    invoke_signed(
        &transfer_ix,
        &transfer_infos,
        &[&[
            VAULT_AUTHORITY_SEED.as_bytes(),
            &[ctx.accounts.loan_account.vault_authority_bump],
        ]],
    )?;

    // close loan nft token account
    anchor_spl::token::close_account(CpiContext::new_with_signer(
        ctx.accounts.token_program.to_account_info(),
        anchor_spl::token::CloseAccount {
            account: ctx.accounts.loan_nft_vault.to_account_info(),
            destination: ctx.accounts.borrower.to_account_info(),
            authority: ctx.accounts.vault_authority.to_account_info(),
        },
        &[&[
            VAULT_AUTHORITY_SEED.as_bytes(),
            &[ctx.accounts.loan_account.vault_authority_bump],
        ]],
    ))?;

    Ok(())
}

1 Answer 1

7

You can add a setComputeUnitLimit() instruction to the transaction:

import {
  Transaction,
  ComputeBudgetProgram,
} from "@solana/web3.js";

let tx = new Transaction();
// needs to be the first instruction
// experiment with this number to find one where the transaction succeeds.
tx.add(ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }));

// add other instructions
tx.add(...);
4
  • this solved the issue. thanks.
    – denimcodes
    Commented Sep 12, 2023 at 10:04
  • Glad to help :) Commented Sep 13, 2023 at 18:24
  • any idea on how to do that using anchor? Commented Mar 26 at 14:53
  • @Dinaiscoding you should be able to use the transaction interface of anchor to get a transaction you can add the instruction to. Commented Mar 30 at 11:40

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.