Jasperan
Jasperan

Reputation: 3786

Uniswap method getAmountsOut() returns wrong value when using Hardhat mainnet fork

In my hardhat test, I'm using Uniswap's getAmountsOut to get the price of ETH in USD (using DAI). It currently returns $2766 as the price of ETH which is correct. Here's my test which successfully fetches the price:

require('dotenv').config()
const { ethers } = require("hardhat");

const UNISWAPV2_ROUTER02_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
const UNISWAPV2_ROUTER02_ABI = [{ "inputs": [{ "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "address[]", "name": "path", "type": "address[]" }], "name": "getAmountsOut", "outputs": [{ "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }]

const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f";
const WETH_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";

describe("eth-price-test", function () {
    it("Test fetch Eth price", async function () {
        const provider = new ethers.providers.WebSocketProvider(process.env.INFURA_WEB_SOCKET)
        const wallet = new ethers.Wallet(process.env.ETH_PRIVATE_KEY, provider)
        const signer = wallet.provider.getSigner(wallet.address)
        let uniswap = new ethers.Contract(
            UNISWAPV2_ROUTER02_ADDRESS,
            UNISWAPV2_ROUTER02_ABI,
            signer,
        );

        const amountEth = await uniswap.getAmountsOut(
            1,
            [WETH_ADDRESS, DAI_ADDRESS]
        )

        console.log(`1 Eth = ${amountEth[1].toString()} USD`)
    });
});

However when I use the signer connected to Hardhat's mainnet fork, the price returned is $3993 which is much higher. I get the signer like so:

signer = ethers.provider.getSigner(process.env.ETH_PUBLIC_KEY)
let uniswap = new ethers.Contract(
  UNISWAPV2_ROUTER02_ADDRESS,
  UNISWAPV2_ROUTER02_ABI,
  signer,
);

And here's the relevant part of my hardhat.config.js for reference:

module.exports = {
  solidity: "0.5.0",
  networks: {
    hardhat: {
      forking: {
        url: process.env.ALCHEMY_URL
      }
    }
  }
};

Any idea why there's a huge price difference? Even if I peg the mainnet fork to different blocks, it always returns $3993...

Thanks in advance!

Upvotes: 1

Views: 1763

Answers (1)

Jasperan
Jasperan

Reputation: 3786

I found a fix! By using ethers.provider when deploying the Uniswap contract instead of signer, getAmountsOut() will correctly fetch the price of Eth using the pegged block.

let uniswap = new ethers.Contract(
  UNISWAPV2_ROUTER02_ADDRESS,
  UNISWAPV2_ROUTER02_ABI,
  ethers.provider // using provider instead of signer here
);

Upvotes: 0

Related Questions