Ive been reading other results but none of them fits my situation*

I cannot resolve this issue for a while. When im running this script:

  • WBNB to DOGE - Works.
  • DOGE to WBNB - Fails.

What am I doing wrong?

  1. im registering the amountIn with (router.getAmountsOut())
  2. im approving the token combination with the amountIn (Token.approve())
    const pair = [TOKENS.DOGE, TOKENS.WBNB]
    const amountIn = ethers.utils.parseUnits(val, 'ether')
    const amounts = await router.getAmountsOut(amountIn, pair);
    const amountOutMin = amounts[1].sub(amounts[1].div(15))

    const gasPrice = ethers.utils.parseUnits('5', 'gwei')
    const gasLimit = 2000000

    // Token = Token(TOKENS.DOGE)
    await Token.approve( pancakeRouter, amountIn, { gasLimit, gasPrice } )

    const buyTx = await router.swapExactTokensForTokens(
      Math.floor(Date.now() / 1000) + 60 * 10,
      { gasLimit, gasPrice }


  reason: 'transaction failed',
  transactionHash: '0xabd9862116711eacaa109d4a832c87e947af666745186b51cce7fe864a310c96',

2 Answers 2


Step 1:

Get the ABI of the token (contract), that is an interface of all available methods you can use of that token.

On bscscan you can signup for an api then you can query for the ABI of each token. Api url looks similar like: https://api.bscscan.com/api?module=contract&action=getabi&address=[TOKEN ADDRESS HERE]&apikey=[YOUR API KEY HERE] and store it to a var ABI or something.

// I use axios for HTTP get request

const ABI = await axios.get(`https://api.bscscan.com/api?module=contract&action=getabi&address=[TOKENADDRESS]&apikey=[YOURAPIKEYHERE]`);

Step 2:

Get the decimals of that contract, I do that in NodeJS:

var Contract = require('web3-eth-contract');

// This is the websocket url of a bsc node

var contractDecimals = new Contract(ABI, 'token address');
var decimals = await contractDecimals.methods.decimals().call();

Step 3: Prepare the value to approve of selling

// I use the ethers API here
const ethers = require('ethers');

// Get the balance of your wallet
const balance = await contract.balanceOf([YOUR WALLET ADDRESS HERE]);

// approval with the decimals of the token
const valueToApprove = ethers.utils.parseUnits(balance.toString(), decimals);

Step 4: Approve the sell (You know how that works)

Step 5: Sell!

        [TokenToSellHere, [WBNBAddress HERE]],
        recipient, // Your wallet
        Math.floor(Date.now() / 1000) + 60 * 2, // 2 minutes from the current Unix time
            gasPrice: ethers.utils.parseUnits(5', 'gwei'),
            gasLimit: 450000

That's it!

  • Had so many things that could go wrong with this one (such as node getting out of sync). Thank you
    – Max Svidlo
    Nov 21, 2021 at 12:42
  • I'm glad I could help! Nov 22, 2021 at 14:41

Doge has 8 decimals. You need to specify it.

Also I think it is better to use a different method than router.swapExactTokensForTokens

  • How can I achieve that? Before executing the transaction im validating my wallet contents. As also, i've checked the value thats actually been sent to the transaction and the value looks ok
    – Max Svidlo
    Nov 14, 2021 at 9:36
  • well it appear that I already handle such case: const balance = await Token.balanceOf(wallet.address) const formattedBalance = ethers.utils.formatUnits(balance)
    – Max Svidlo
    Nov 14, 2021 at 14:21
  • 1
    How I do that is in a couple of steps: see my next comprehensive answer Nov 15, 2021 at 12:04

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.