1

I've been testing around UniswapV2 using hardhat and I always get this error when I try to add liquidity through the addLiquidity function on UniswapV2Router.

For the test, I deployed mock tokens, deployed UniswapV2Factory, then deployed Router.

here's the deployment code

const token = await ethers.getContractFactory("Token");
weth = await token.deploy('WETH', 'WETH', 6, owner.address);
mim = await token.deploy('MIM', 'MIM', 18, owner.address);
dai = await token.deploy('DAI', 'DAI', 18, owner.address);

const Factory = await ethers.getContractFactory("UniswapV2Factory");
const factory = await Factory.deploy(owner.address);

const Router = await ethers.getContractFactory("UniswapV2Router02");
const router = await Router.deploy(factory.address, weth.address);

const mim_100000000 = ethers.BigNumber.from("100000000000000000000000000");
const dai_100000000 = ethers.BigNumber.from("100000000000000000000000000");
await dai.approve(router.address, dai_100000000);
await mim.approve(router.address, mim_100000000);

await router.addLiquidity(mim.address, dai.address, mim_100000000, dai_100000000, mim_100000000, dai_100000000, owner.address, Date.now());

and it always produces this error:

Error: Transaction reverted: function call to a non-contract account
    at UniswapV2Router02.getReserves (contracts/libraries/UniswapV2Library.sol:31)
    at UniswapV2Router02._addLiquidity (contracts/UniswapV2Router02.sol:45)
    at UniswapV2Router02.addLiquidity (contracts/UniswapV2Router02.sol:71)
    at HardhatNode._mineBlockWithPendingTxs 

Can someone help please?

3

2 Answers 2

0

The error is getting triggered in line 45 of the router contract https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol#L45

It means that UniswapV2Library is not a correct contract reference inside the Smart Contract, so calling getReserves fails.

Looking at the code, you are not deploying and linking the library properly, so when it tries to call the function, it tries to call the function from address 0x0, giving that error.

You can find tons of docs on how to use libraries, I suggest this one to get started: https://www.tutorialspoint.com/solidity/solidity_libraries.htm

Although if what you want is just to make it work hardhat has tools to deploy and link libraries: https://hardhat.org/plugins/nomiclabs-hardhat-ethers#library-linking

Best of luck!

5
  • flattened the contract, integrating the library straight into the router does not work. github.com/prohimone/nenodex-core/blob/main/contracts/…
    – yoken
    Jun 3, 2022 at 7:18
  • Weird, the address created from createPair in the Factory contract is different from pairFor from the Router contract. I think this is the main reason it calls to a non-contract account or non existent contract.
    – yoken
    Jun 3, 2022 at 7:42
  • Are you sure it's the same error in the same line of code? Jun 3, 2022 at 12:15
  • yep it's this line (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(tokenA, tokenB)).getReserves(); from the getReserves function
    – yoken
    Jun 4, 2022 at 4:02
  • I'm stumped sorry, the error is the same, it's not getting the library's address. A dirty hack would be integrating the library as a regular contract and inherit from it to call it, but it's not a great solution Jun 6, 2022 at 9:45
3

There is an issue with createPair UniswapV2Library function. If UniswapV2Pair is changed, it will return different pair address, different hex

First solution:

The purpose of this function is to get the contract address for 2 tokens without calling any contract (pure function). The problem is the hex value init in code hash, this hash is just a keccak256() of your compiled contract UniswapV2Pair.sol

How to solve your problem ?

Very easy. Just find your bytecode from compiled contract, hash it and replace on the contract.

For Hardhat users:

  1. Find UniswapV2Pair.json in the artifacts folder
  2. Find the bytecode in the file
  3. Copy it on Keccak Online (Don't forget to change the input type to "hex" and delete the "0x" at the start)
  4. Hash it and copy the hash in the pairFor function

Second solution:

Change this function to this and it will work: enter image description here

import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
    function pairFor(address factory, address tokenA, address tokenB) internal view returns (address pair) {
        pair = IUniswapV2Factory(factory).getPair(tokenA,tokenB);
    }

Read more here: Testing Token with Uniswap liquidity provisioning using hardhat https://forum.openzeppelin.com/t/uniswap-fork-testing-hardhat/14472

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.