2
// SPDX-License-Identifier: MIT
pragma solidity ^0.5.16;

import "https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol";
contract TestERC20 {

    address public _pair = address(0);
    constructor() public {
        
    }

    function getPreAddress() public view returns (
        address, address
    ) {
      address factory = address(this);
      address token0 = 0xCAFE000000000000000000000000000000000000; // change me!
      address token1 = 0xF00D000000000000000000000000000000000000; // change me!

      address pair = address(uint(keccak256(abi.encodePacked(
        hex'ff',
        factory,
        keccak256(abi.encodePacked(token0, token1)),
        hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f'
      ))));      
      return (pair, _pair);
  }

  function createPair() public {
      require(_pair == address(0), 'Pair already created');
      address token0 = 0xCAFE000000000000000000000000000000000000; // change me!
      address token1 = 0xF00D000000000000000000000000000000000000; // change me!
      bytes memory bytecode = type(UniswapV2Pair).creationCode;
      bytes32 salt = keccak256(abi.encodePacked(token0, token1));
      address dep;
      assembly {
            dep := create2(0, add(bytecode, 32), mload(bytecode), salt)
        }
      _pair = dep;
  }
}

I tried to deploy the UniswapV2Pair contract and compare the calculated address and deployed address.

Unfortunately, two addresses are different.

After create pair by createPair(), getPreAddress() return different two address.

How can I create the Pair and pre-get the pair address?

2 Answers 2

2
 address pair = address(uint(keccak256(abi.encodePacked(
        hex'ff',
        factory,
        keccak256(abi.encodePacked(token0, token1)),
        keccak256(type(UniswapV2Pair).creationCode)
        // hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f'
      ))));

Please update the code like this.

2
  • Thanks, it works for me.
    – hobbydev
    Mar 15 at 17:40
  • doesn't work with solidity 0.8.*
    – redigaffi
    Apr 17 at 9:27
2
function getCreate2Address(
  factoryAddress,
  [tokenA, tokenB],
  bytecode
) {
  const [token0, token1] = tokenA < tokenB ? [tokenA, tokenB] : [tokenB, tokenA]
  const create2Inputs = [
    '0xff',
    factoryAddress,
    keccak256(solidityPack(['address', 'address'], [token0, token1])),
    keccak256(bytecode)
  ]
  const sanitizedInputs = `0x${create2Inputs.map(i => i.slice(2)).join('')}`
  return getAddress(`0x${keccak256(sanitizedInputs).slice(-40)}`)
}

The deployed contract address could be calculated.

This is a JavaScript JavaScript function to calculate the contract address deployed by create2 code.

1
  • It's working, but I hope to predict the address in the smart contract.
    – hobbydev
    Mar 15 at 9:12

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.