0

I am trying to swap ETH to any other coin on Remix IDE and using Uniswap V3 on Goerli Testnet. I am able to deploy the contract but the moment I am trying the swap function, it says execution reverted. The following is the error message:

Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Returned error: {"jsonrpc":"2.0","error":"execution reverted: Must pass non 0 ETH amount","id":12194645375530}

Following is the code that I am trying:

    // SPDX-License-Identifier: MIT
pragma solidity =0.7.6;
pragma abicoder v2;

import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol";
import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/IQuoter.sol";

interface IUniswapRouter is ISwapRouter {
    function refundETH() external payable;
}

contract Uniswap3 {
  IUniswapRouter public constant uniswapRouter = IUniswapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
  IQuoter public constant quoter = IQuoter(0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6);
  address private constant multiDaiKovan = 0xdc31Ee1784292379Fbb2964b3B9C4124D8F89C60;  // add address DAI token in the required testnet
  address private constant WETH9 = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6;   // add address WETH token in the required testnet

  function convertExactEthToDai() external payable {
    uint256 deadline = block.timestamp + 15;
    address tokenIn = WETH9;
    address tokenOut = multiDaiKovan;
    uint24 fee = 3000;
    address recipient = msg.sender;
    uint256 amountIn = msg.value;
    uint256 amountOutMinimum = 1;
    uint160 sqrtPriceLimitX96 = 0;

    ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams(
        tokenIn,
        tokenOut,
        fee,
        recipient,
        deadline,
        amountIn,
        amountOutMinimum,
        sqrtPriceLimitX96
    );

    uniswapRouter.exactInputSingle{ value: msg.value }(params);
    uniswapRouter.refundETH();

    // refund leftover ETH to user
    (bool success,) = msg.sender.call{ value: address(this).balance }("");
    require(success, "refund failed");
}

  
  function convertEthToExactDai(uint256 daiAmount) external payable {
    require(daiAmount > 0, "Must pass non 0 DAI amount");
    require(msg.value > 0, "Must pass non 0 ETH amount");
      
    uint256 deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
    address tokenIn = WETH9;
    address tokenOut = multiDaiKovan;
    uint24 fee = 3000;
    address recipient = msg.sender;
    uint256 amountOut = daiAmount;
    uint256 amountInMaximum = msg.value;
    uint160 sqrtPriceLimitX96 = 0;

    ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(
        tokenIn,
        tokenOut,
        fee,
        recipient,
        deadline,
        amountOut,
        amountInMaximum,
        sqrtPriceLimitX96
    );

    uniswapRouter.exactOutputSingle{ value: msg.value }(params);
    uniswapRouter.refundETH();

    // refund leftover ETH to user
    (bool success,) = msg.sender.call{ value: address(this).balance }("");
    require(success, "refund failed");
  }
  
  // do not used on-chain, gas inefficient!
  function getEstimatedETHforDAI(uint daiAmount) external payable returns (uint256) {
    address tokenIn = WETH9;
    address tokenOut = multiDaiKovan;
    uint24 fee = 3000;
    uint160 sqrtPriceLimitX96 = 0;

    return quoter.quoteExactOutputSingle(
        tokenIn,
        tokenOut,
        fee,
        daiAmount,
        sqrtPriceLimitX96
    );
  }
  
  // important to receive ETH
  receive() payable external {}
}

I expected the result that the particular amount of DAI should be deposited to my account. A solution would be appreciated.

2
  • Could it be that you are using the Goerli fork that comes with Remix? It has never worked well for me, it is better to use Hardhat or Anvil.
    – ceseshi
    Commented Jul 6, 2023 at 10:18
  • @rasyidred could you expand on your point Commented Sep 25, 2023 at 13:59

3 Answers 3

0

Use http://buildbear.io/ and create your own Testnet by forking Ethereum, Polygon, Binance, Optimism, Arbitrum, Fantom, and Avalanche chains, allowing you to test Uniswap on the actual Mainnet state.

0

The pools don't support eth, where eth is used it has to be wrapped first. With v3 there is a statement in the pay function which is called during the swap:

    if (token == WETH9 && address(this).balance >= value)
      // pay with WETH9
      IWETH9(WETH9).deposit{value: value}(); // wrap only what is needed to pay
      IWETH9(WETH9).transfer(recipient, value);

Send the eth value with the call (you are missing this), and use the 'weth' (wrapped native) token address (which you have hardcoded).

In Remix using your code without changes, that might look like: enter image description here

0

You cannot exactly swap ETH for DAI, that's why the ERC-20 version of ETH, Wrapped ETH (WETH) comes in. The pools only consist of two ERC-20 tokens, and ETH is the native token in Ethereum network.

Update: it seems like you follow this tutorial link. I happened to find this tutorial. I tried and it worked. It is better to test the contract on a forked mainnet instead of on the testnets. You can use Foundry or Hardhat.

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.