Web3.js Uniswap Issue – Transaction Reverted During `swapExactTokensForTokens` on UniswapV2Router02

nodejsuniswapweb3js

I am attempting to swap ETH for DAI using the Uniswap Router, but am facing a problem where the transaction gets reverted, along with the following message: Transaction has been reverted by the EVM.

I am testing this on the Rinkeby Testnet.

Here is the full message, along with the accompanying block information:

Transaction has been reverted by the EVM:
    {
      "blockHash": "0xfaa3effa60d646ef4db959cba460dac74aafd1c0b667c91758be71a735f949ce",
      "blockNumber": 9146763,
      "contractAddress": null,
      "cumulativeGasUsed": 1678679,
      "effectiveGasPrice": "0x3b9aca09",
      "from": "0xbd8b57fdbd794f125a9d6a3a7bd8958d46201b37",       
      "gasUsed": 30348,
      "logs": [],
      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "status": false,
      "to": "0x7a250d5630b4cf539739df2c5dacb4c659f2488d",
      "transactionHash": "0x7c5b33a7a751430ba0e0347a29b01a12db0b1da71a17a36deb4c773ea5ff483c",
      "transactionIndex": 6,
      "type": "0x0"
    }

      at Object.TransactionError (../node_modules/web3-core-helpers/lib/errors.js:87:21)
      at Object.TransactionRevertedWithoutReasonError (../node_modules/web3-core-helpers/lib/errors.js:98:21)
      at ../node_modules/web3-core-method/lib/index.js:394:57

I will also provide the NodeJS code I am running:

import Web3 from "web3";

const IERC20 = require('@uniswap/v2-periphery/build/IERC20.json')
const IPair = require('@uniswap/v2-core/build/IUniswapV2Pair.json')  
const IFactory = require('@uniswap/v2-core/build/IUniswapV2Factory.json')
const IRouter = require('@uniswap/v2-periphery/build/IUniswapV2Router02.json')

export class TransactionService {

async transact() {
    const privKey = "<privkey ommitted>";
    var web3 = new Web3('https://rinkeby.infura.io/v3/<infura-rinkeby-path>');
    var factory = new this.web3.eth.Contract(IFactory.abi, "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f");
    var address = "0xbd8B57fdBD794f125a9D6A3A7bd8958D46201b37";
    var daiExchangeAddress = "0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735";
    var ethExchangeAddress = '0xc778417E063141139Fce010982780140Aa0cD5Ab';
    var rinkebyRouterAddress = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
    var router = new this.web3.eth.Contract(IRouter.abi, rinkebyRouterAddress);
    var token0 = new this.web3.eth.Contract(IERC20.abi, ethExchangeAddress) //henceforth T0
    var token1 = new this.web3.eth.Contract(IERC20.abi, daiExchangeAddress) //and T1    
    var pair = new this.web3.eth.Contract(IPair.abi,
      (await factory.methods.getPair(token0.options.address, token1.options.address).call()));
    
      const gasPrice = await web3.eth.getGasPrice()
      const gasNeeded = (0.15*10**6)*2 
      const path = [token0.options.address,token1.options.address]
      var amountIn = 999999999999;
      var tx0 = {
        to: token0.options.address, 
        gas: gasNeeded, 
        data: token0.methods.approve(router.options.address,amountIn).encodeABI()
    }

    var signedTx0 = await web3.eth.accounts.signTransaction(tx0, privKey);
    var receipt0 = await web3.eth.sendSignedTransaction(signedTx0.rawTransaction)
    
    console.log(
        `Tx mined\n`+
        `Tx hash: ${receipt0.transactionHash}\n`
        )
    const tx1 = {
        to: router.options.address, 
        gas: gasNeeded,
        data: router.methods.swapExactTokensForTokens(
            amountIn,
            0,
            path,
            address,
            (Date.now() + 250)
        ).encodeABI()
    }

    var signedTx1 = await web3.eth.accounts.signTransaction(tx1, privKey);
    var receipt1 = await web3.eth.sendSignedTransaction(signedTx1.rawTransaction);
}

}

As you can see, there are two transactions made. Anapprove and a swapExactTokensForTokens. The contract ABI can be found here. Some documentation on the Router02 is here. The contract itself can be found here. Thank you for any help you can provide.

Best Answer

To call swapExactTokensForTokens the sender needs to have tokens at ethExchangeAddress contract.

The sender doesn't have so the transaction reverts with

Fail with error 'TransferHelper: TRANSFER_FROM_FAILED'

There are two options:

  • Use swapExactETHForTokens and send value with the transaction.
  • Wrap some ether in the contract using deposit from ethExchangeAddress.
Related Topic