1

I am trying to create a simple DAI/ETH swapper which lets me swap some DAI for ETH using Uniswap Router V2. I am creating it using React and uniswapSDK. So far, I have managed to connect to my Metamask wallet, get the ABI for the Uniswap contract so I can invoke the method.

However, I am finding it difficult to understand how do I approve this method before calling it? I understand that sending a transaction over the chain needs to first signed, then be called. I am not sure 'how' to approve it? This is my code till now for swapping

export const makeSwap = async (
  contract: any,
  account: any,
  library: any,
  amount: any
) => {
  const DAI: Token = await Fetcher.fetchTokenData(chainId, DAItokenAddress);
  const pair: Pair = await Fetcher.fetchPairData(DAI, WETH[chainId]);
  const route: Route = new Route([pair], DAI);
  const trade = new Trade(
    route,
    new TokenAmount(DAI, library.utils.toWei(amount)),
    TradeType.EXACT_INPUT
  );

  const slippageTolerance = new Percent("50", "10000"); //0.5%
  const amountOutMin = ethers.BigNumber.from(
    trade.minimumAmountOut(slippageTolerance).raw.toString()
  ).toHexString();
  const path = [DAI.address, WETH[chainId].address];
  const to = account;
  const deadline = Math.floor(Date.now() / 1000) + 60 * 1;
  const value = ethers.BigNumber.from(
    trade.inputAmount.raw.toString()
  ).toHexString();
  await contract.methods.approve(value, account);
  const tx = await contract.methods
    .swapExactTokensForETH(value, amountOutMin, path, to, deadline)
    .call();


   //Fails above this line


  console.log(`Transaction hash: ${tx.hash}`);
  const receipt = await tx.wait();
  console.log(`Transaction was mined in block ${receipt.blockNumber}`);
};

Thank you for your help!

2 Answers 2

1

First of all .call() is used when you need to read data from the contract. As you need to send a transaction so use .send() instead for .swapExactTokensForETH.

For this to work, you need to approve the Uniswap Router to send DAI from our account.

await daiContract.methods.approve(UniswapRouterAddress, tokenAmount).send();
4
  • Thanks for your help and clalrification. I changed my code according to your recommendation, now it says The method eth_signTransaction does not exist/is not available. I am connected to an Infura node so I assume this is because I can't expose my private key to it. Do you know what other ways are there? I tried using web3.eth.signTransaction and it replied with the same thing :/ If you could help me out, I would be really grateful. Thanks again!
    – LoXatoR
    Aug 28, 2021 at 17:57
  • Update: Changing the provider has let me sign it. So next step would be calling swapExactTokensForETH right? Is there anything I need to send along with the transaction?
    – LoXatoR
    Aug 28, 2021 at 18:22
  • Your clarification about send() vs call() cleared a lot of things. Finally got it to work and successfully sent a few transactions. Thanks a lot!
    – LoXatoR
    Aug 28, 2021 at 22:00
  • Glad you were able to figure it out. Aug 29, 2021 at 18:04
0

You need to call the DAI contract with approve(UniRouterAddress, amount) not sure about the syntax since im not familiar at all with web3.js but i think you can figure it out ( if this helps understanding better in solidity that would be IERC20(DAIContractAddress).approve(UniRouterAddress, amount) )

3
  • So I see the DAI approve takes an account and a uint256 wad which I assume is the amount. I have send the UniRouterAddress and amount, it returns true. After that I tried to invoke the UniRouterAddress but it fails saying Uncaught (in promise) Error: Returned error: execution reverted: TransferHelper: TRANSFER_FROM_FAILED. There was no metamask pop up to approve it or anything
    – LoXatoR
    Aug 28, 2021 at 13:04
  • There should have been one. Note that the approval ans the actual swap are 2 different transactions
    – Foxxxey
    Aug 28, 2021 at 13:11
  • So I am making two instances of two contracts to get their methods, uniContract and daiContract, and calling it like this await daiContract.methods.approve(UNISWAP_TOKEN_ADDRESS, value).call(); Both contracts were initiated from the same Web3 instance. I am not sure what I am doing wrong. When I tried to call approve on etherscan for the DAI approve method metamask did pop up asking for approval
    – LoXatoR
    Aug 28, 2021 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.