0

I'm trying to create unit tests for a token using Hardhat and run them locally. The token uses Uniswap to swap for ETH.

Before each unit test, I...

  1. Deploy WETH, UniswapV2Factory, and UniswapV2Router02.
  2. Deploy my token
    • The token's constructor calls uniswapFactory.createPair(this, weth)

This all works properly and I'm able to run tests with my token.

However, one of my unit tests calls a function that ends up calling:

***Stack Trace***
UniswapV2Router02._swapSupportingFeeOnTransferTokens
UniswapV2Router02.swapExactTokensForEthSupportingFeeOnTransferTokens

https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol#L321

When it gets to line 329, it errors out with Transaction reverted: function call to a non-contract account

Reference:
Create Pair code: https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Factory.sol#L23


I assume this means that the pair's address is not a contract that deployed locally.

What else do I need to do in order to get my pair to be a working contract?

I thought createPair() would be enough.

7
  • Have you tried console.log of the pair address (using Hardhat/console.sol)? Or, as an easiest alternative, have you considered forking mainnet and using the existing Uniswap deployment? Nov 24 at 9:50
  • + add more precision in what you deployed, both UniswapV2Router01 and 02 ? Nov 24 at 9:50
  • @DrGorilla.eth I have updated to mention I am using V2Router02. I've also verified that when I first create the pair in my constructor, it does successfully call pair.initialize(). However, the pair address that gets created in my constructor (which uses Factory.createPair()) is different than the pair address that gets created from swapExactTokensForEthSupportingFeeOnTransferTokens (which calls UniswapLibrary.pairFor())
    – EEE
    Nov 25 at 0:50
  • Pair address can be computed (that's what pairFor does iirc), to do so, you need the matching bytecode hash -> are you mixing "vanilla" uniswap and, for instance, pancakeswap ? Their bytecode is not identical, meaning pair addresses will not be the same Nov 25 at 10:51
  • 1
    @DrGorilla.eth Thanks. Yeah, you were right that the hash I was using in pairFor was not correct. Not sure why because I got the code directly from the github. But I was able to find the hash I needed by using ethers.utils.keccak256(UniswapV2Pair.bytecode);. If you want to add your comment as an answer, then I can mark it if you'd like.
    – EEE
    Nov 26 at 14:30
1

Factory.createPair() will effectively deploy your pair contract, while when using UniswapLibrary.pairFor(), you will get the theoretical address of any potential pair, based on the uniswapV2Pair bytecode keccak256 hash (the "INIT_CODE" in get_pair()). If this hash differs than the one based on your actual deployment (ie an "old" value stayed hard-coded), createPair and pairFor will return different values.

See https://www.ethereum.stackexchange.com/a/112709/68134 for similar concept in V3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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