1

Hello I get an issue when I try to perform a swap on a token-swap program deployed on devnet.

Error : Given pool token amount results in zero trading tokens

Transaction as an example : 21hYB5D2536E9jTbDzi9uRjCTso1sdAuiv6iJPksVHt12B158Tkx44jXA98yzSRRG7xCde3AehCzop9rd31cWKnV

The data sent in the instruction seems to be correctly encoded and the accounts passed to the program also.

I assume that the Error is triggered at this step in the program processor but I am not sure and I don't clearly see what is wrong since I used the js bindings.

https://github.com/solana-labs/solana-program-library/blob/73673b6b306ad03086e1cb4a2ec87d220686c306/token-swap/program/src/processor.rs#L482

My code below :

import * as React from "react";
import { Connection, PublicKey, Transaction } from "@solana/web3.js";
import { getAssociatedTokenAddress, TOKEN_PROGRAM_ID } from "@solana/spl-token";
import { SWAP_HOST_FEE_ADDRESS } from "utils/swap/ids";



const SWAP_ID = new PublicKey("3JueWRCHJKKrgzqyLKcQ1dh82WUCKCdrA7tJq6U72Z6F");

const HOST_FEE = new PublicKey("HfoTxFR1Tm6kGmWgYWD6J7YHVy1UwqSULUGVLXkJqaKN");

export async function useSwap(
  connection: Connection,
  publicKey: PublicKey,
  tokenSwap: string,
  mintA: PublicKey,
  AmountA: number,
  mintB: PublicKey,
  MinimumAmountB: number,
  tokenAccountA: PublicKey,
  tokenAccountB: PublicKey,
  mintPoolToken: PublicKey,
  feeAccount: PublicKey,
  sendTransaction: any
) {
  console.log(
    `Starting Swap of ${AmountA} ${mintA.toString()} to ${MinimumAmountB} ${mintB.toString()}`
  );

  const Swap = require("@solana/spl-token-swap");
  console.log(Swap)

  const transaction = new Transaction();

  const tokenAccountSwapPubKey = new PublicKey(tokenSwap); //The Token Swap publicKey
  //Swap authority derived from program address
  const [swapAuthority, bump] = await PublicKey.findProgramAddressSync(
    [tokenAccountSwapPubKey.toBuffer()],
    SWAP_ID
  );

  const userTokenAAccount = await getAssociatedTokenAddress(mintA, publicKey); //Token A user Account
  const userTokenBAccount = await getAssociatedTokenAddress(mintB, publicKey); //Token B user Account

  let instruction = Swap.TokenSwap.swapInstruction(
    tokenAccountSwapPubKey,
    swapAuthority,
    publicKey,
    userTokenAAccount,
    tokenAccountA,
    tokenAccountB,
    userTokenBAccount,
    mintPoolToken,
    feeAccount,
    HOST_FEE,
    SWAP_ID,
    TOKEN_PROGRAM_ID,
    TOKEN_PROGRAM_ID,
    TOKEN_PROGRAM_ID,
    AmountA,
    MinimumAmountB
  )

  
  console.log(instruction);

  //@solana/spl-token-swap package is not up to date with the last js binding required to interact with the contract. Token mints should be provided in account keys.
  instruction.keys.splice(9,0,{pubkey: mintA, isSigner: false, isWritable: false},{pubkey: mintB, isSigner: false, isWritable: false})
  console.log(instruction);
  transaction.add(instruction);

  const {
    context: { slot: minContextSlot },
    value: { blockhash, lastValidBlockHeight },
  } = await connection.getLatestBlockhashAndContext();

  const signature = await sendTransaction(transaction, connection, {
    skipPreflight: true,
  });
  console.log(signature);

  await connection.confirmTransaction({
    blockhash,
    lastValidBlockHeight,
    signature,
  });

  return signature;
}

EDIT :

Data from the TokenSwap I try to use to swap.

{
    "version": 1,
    "isInitialized": 1,
    "bumpSeed": 255,
    "poolTokenProgramId": {
        "type": "Buffer",
        "data": [
            6,
            221,
            246,
            225,
            215,
            101,
            161,
            147,
            217,
            203,
            225,
            70,
            206,
            235,
            121,
            172,
            28,
            180,
            133,
            237,
            95,
            91,
            55,
            145,
            58,
            140,
            245,
            133,
            126,
            255,
            0,
            169
        ]
    },
    "tokenAccountA": {
        "type": "Buffer",
        "data": [
            153,
            37,
            89,
            220,
            190,
            173,
            169,
            89,
            119,
            65,
            99,
            240,
            125,
            28,
            172,
            16,
            240,
            1,
            221,
            169,
            166,
            140,
            59,
            215,
            202,
            183,
            117,
            154,
            252,
            205,
            10,
            106
        ]
    },
    "tokenAccountB": {
        "type": "Buffer",
        "data": [
            12,
            8,
            115,
            203,
            111,
            160,
            225,
            153,
            215,
            210,
            115,
            245,
            9,
            225,
            62,
            73,
            20,
            105,
            137,
            121,
            141,
            16,
            12,
            93,
            91,
            15,
            108,
            91,
            70,
            223,
            222,
            118
        ]
    },
    "tokenPool": {
        "type": "Buffer",
        "data": [
            23,
            247,
            77,
            135,
            112,
            231,
            187,
            243,
            160,
            59,
            79,
            136,
            51,
            194,
            97,
            19,
            77,
            80,
            140,
            193,
            22,
            81,
            35,
            77,
            29,
            104,
            71,
            157,
            196,
            47,
            180,
            77
        ]
    },
    "mintA": {
        "type": "Buffer",
        "data": [
            59,
            68,
            44,
            179,
            145,
            33,
            87,
            241,
            58,
            147,
            61,
            1,
            52,
            40,
            45,
            3,
            43,
            95,
            254,
            205,
            1,
            162,
            219,
            241,
            183,
            121,
            6,
            8,
            223,
            0,
            46,
            167
        ]
    },
    "mintB": {
        "type": "Buffer",
        "data": [
            6,
            155,
            136,
            87,
            254,
            171,
            129,
            132,
            251,
            104,
            127,
            99,
            70,
            24,
            192,
            53,
            218,
            196,
            57,
            220,
            26,
            235,
            59,
            85,
            152,
            160,
            240,
            0,
            0,
            0,
            0,
            1
        ]
    },
    "feeAccount": {
        "type": "Buffer",
        "data": [
            18,
            36,
            93,
            153,
            18,
            6,
            183,
            36,
            146,
            142,
            94,
            101,
            118,
            141,
            35,
            189,
            211,
            30,
            172,
            178,
            192,
            82,
            125,
            17,
            180,
            174,
            97,
            128,
            216,
            14,
            132,
            72
        ]
    },
    "tradeFeeNumerator": {
        "type": "Buffer",
        "data": [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "tradeFeeDenominator": {
        "type": "Buffer",
        "data": [
            16,
            39,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "ownerTradeFeeNumerator": {
        "type": "Buffer",
        "data": [
            5,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "ownerTradeFeeDenominator": {
        "type": "Buffer",
        "data": [
            16,
            39,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "ownerWithdrawFeeNumerator": {
        "type": "Buffer",
        "data": [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "ownerWithdrawFeeDenominator": {
        "type": "Buffer",
        "data": [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "hostFeeNumerator": {
        "type": "Buffer",
        "data": [
            20,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "hostFeeDenominator": {
        "type": "Buffer",
        "data": [
            100,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    },
    "curveType": 0,
    "curveParameters": {
        "type": "Buffer",
        "data": [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    }
}

3 Answers 3

2
let result = token_swap
        .swap_curve()
        .swap(
            to_u128(actual_amount_in)?,
            to_u128(source_account.amount)?,
            to_u128(dest_account.amount)?,
            trade_direction,
            token_swap.fees(),
        )
        .ok_or(SwapError::ZeroTradingTokens)?;

This issue is come from this part on solana program.

I think you should run the initialize function first before processing the swap function.

3
  • Hello thank you for your feedback. The publickey is coming from my parent component formatted as a string that is why I transform it to a PublicKey before using it. I previously created the token swap and initialize it, when I fetch its status the isInitialized property which is set to 1.
    – Skelt
    Commented Mar 10, 2023 at 18:02
  • 1
    Could you please let me know the amountA and minimumtokenB? It seems you add 5 Wsol, and 15 USDC to the pool Commented Mar 10, 2023 at 19:26
  • Less than 1 for trial purpose
    – Skelt
    Commented Mar 13, 2023 at 17:34
0

I finally found the issue, as it was pointed out by @Doublers Kay the issue was coming from amountA and minimumtokenB. Those amount should be converted with appropriate token decimals to represent the correct amount in the program.

Example:

AmountA = amountA * Math.pow(10,decimalsA)

But know I have another issue I get the following error even if all of the Tokens are derived from Token Program. TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

Full logs : `Program 3JueWRCHJKKrgzqyLKcQ1dh82WUCKCdrA7tJq6U72Z6F invoke [1]
Program log: Instruction: Swap
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]
Program log: Instruction: TransferChecked
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 6200 of 177498 compute units
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success
Program log: Error: The provided token program does not match the token program expected by the swap
Program 3JueWRCHJKKrgzqyLKcQ1dh82WUCKCdrA7tJq6U72Z6F consumed 50853 of 200000 compute units
Program 3JueWRCHJKKrgzqyLKcQ1dh82WUCKCdrA7tJq6U72Z6F failed: custom program error: 0x18

Tx on Devnet for reference : UbKuT73hCo4aLg6UgoDYaaVys6grYF7rJzsPLQoiF88Zh2mAjVx5gNKj89S397DDZPYNcV2qFFibjQXmpJD8C24

2
  • hey did you ever find a solution to this? I have spent a few hours on this same issue myself and have not managed to find anything. I also checked owner ship of all related accounts passed in and they all match the correct ID afaict. If you have a solution I would be very very very grateful. Commented Jan 13 at 16:35
  • my best guess is that copying the program from testnet or devnet did something strange where perhaps token-2022 is being used? Commented Jan 13 at 16:36
0

Just remove the owner trade fee from swap pool, then I successfully performed swap instruction with following params:

TokenSwap.swapInstruction(
    tokenSwap.tokenSwap,
    tokenSwap.authority,
    userTransferAuthority.publicKey,
    userAccountA,
    tokenSwap.tokenAccountA,
    tokenSwap.tokenAccountB,
    userAccountB,
    tokenSwap.poolToken,
    tokenSwap.feeAccount,
    null,
    TOKEN_PROGRAM_ID,
    TOKEN_PROGRAM_ID,
    tokenSwap.swapProgramId,
    TOKEN_PROGRAM_ID,
    TOKEN_PROGRAM_ID,
    TOKEN_PROGRAM_ID,
    swapAmountIn,
    swapAmountOut,
  ),
),

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.