[Ethereum] swapExactTokensForETHSupportingFeeOnTransferTokens fails for some tokens when called from script, but works when submitted from Pancakeswap

bscpancakeswapweb3.py

I have a simple code using web3.py that sells BEP20 tokens:

deadline = int(time.time()) + 1200;
nonce = w3.eth.get_transaction_count(w3.eth.default_account) 
sellTxn = self.web3Context.routerContract.functions.swapExactTokensForETHSupportingFeeOnTransferTokens(amountToSell, 1000000000000000, 
           [self.tokenAddress, self.web3Context.wrappedEthAddress], 
            account.address, deadline).buildTransaction({
              'chainId': self.web3Context.chainId,
              'nonce': nonce,
              'gas': w3.toHex(500000),
              'gasPrice': w3.toHex(int(w3.eth.gasPrice*2)),
         })

signed_sellTxn = account.signTransaction(sellTxn)
sell_txid = w3.toHex(self.web3Context.w3.eth.sendRawTransaction(signed_sellTxn.rawTransaction))
sellReceipt = w3.eth.wait_for_transaction_receipt(sell_txid)
...

It's all uses pancakeswap V2 stuff, like router address, WBNB address, etc.

It does work with majority of tokens I tried it with. However, occasionally it fails with

Fail with error 'TransferHelper: TRANSFER_FROM_FAILED'

The token is approved before hand. This code is not called if a token is not approved, and I also checked that the transaction to approve it was confirmed before the above code was executed.

If it happens with a particular token, it will be failing no matter how many times I try to run it.
However, if I sell manually using Pancakeswap, it works.

I compared the data I send with the data Pancakeswap sends, and I do not see any difference except in amountOutMin. When it works, however, I can even pass 0.

So, here is an example when the transaction fails:

Function: swapExactTokensForETHSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline)
0   amountIn        uint256     1001887138366157231924
1   amountOutMin    uint256     1000000000000000
2   path            address[]   ef155b9bcdbf4bd54143cf2ec7e47045cbbd2ebb
                                bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
3   to              address     3c94454135e91ab01bb4c1b816d4d6f9399b9a7d

And this is the transaction when it's submitted from Pancakeswap, and it works:

Function: swapExactTokensForETHSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline)
0   amountIn        uint256     1004644755416763858179
1   amountOutMin    uint256     24525898036735865
2   path            address[]   ef155b9bcdbf4bd54143cf2ec7e47045cbbd2ebb
                                bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
3   to              address     3c94454135e91ab01bb4c1b816d4d6f9399b9a7d

So, the only difference is the amountOutMin value.

What is the best way to troubleshoot or debug this? Is there anything specific to look for in the token's contract?

So far I've seen it with handful of tokens:
https://bscscan.com/address/0x0952ddffde60786497c7ced1f49b4a14cf527f76
https://bscscan.com/address/0x35ca09d3c28c24f1f32742ab91d794d2a524519e
https://bscscan.com/address/0xd55eb92c40b8e19f5ff97cbbbdb721889a7b034a
https://bscscan.com/address/0xd9f21eb27474981f419a0845ddfccc14e3fd4ecc
https://bscscan.com/address/0xe68efedf3e1c08af12de6bdec585f89794a75c52
https://bscscan.com/address/0xef155b9bcdbf4bd54143cf2ec7e47045cbbd2ebb

Thanks!

Best Answer

I had the same issue, the only solutions that I could think of are:

  1. Get the price of the token and calculate the slippage on the fly
  2. Set amountOutMin to 0, at first I thought it would give me 0 bnb but on all the tokens that I have used it, it only took the tax specified on the contract.
    token_tx = pancake.functions.swapExactTokensForETHSupportingFeeOnTransferTokens(tokens_amount,0 , path, reciever[0],expire ).buildTransaction(
        {
            'chainId':56,
            'gas': 500000,
            'gasPrice': web3.toWei(gas,'gwei'),
            'nonce':nonce,
        }
    )

My guess is that when you try to sell and the tokens received < amountOutMin it fails

Related Topic