2

Recently, UniswapV2 got deployed on other chains using the same addresses and the same bytecode. But all transactions are getting reverted, and the reason is simple : the uniswap’s factory is using create2 in order to create pools, but for given token’s address pair, they get deployed at a different address than they would be deployed on the Ethereum mainnet.

When the Uniswap router attempts to call a pool, it computes the address of the would be pool for Ethereum, but as the pool exists at a different address than the real one, it reverts.

Now the create2’s eip tell nothing about Chainid… So what makes a contract with the same arguments and caller getting a different deployment address between Ethereum and bsc for example ?

2

2 Answers 2

3

Although the contracts were deployed at the same address their configuration is not identical.

  • Main, WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
  • BSC, WETH = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c

Now the function that creates the pair uses WETH to generate the salt parameter then the resulting address will have a different address.

function createPair(address tokenA, address tokenB) external returns (address pair) {
    require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
    (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS');
    require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient
    bytes memory bytecode = type(UniswapV2Pair).creationCode;
    bytes32 salt = keccak256(abi.encodePacked(token0, token1));
    assembly {
        pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
    }
    IUniswapV2Pair(pair).initialize(token0, token1);
    getPair[token0][token1] = pair;
    getPair[token1][token0] = pair; // populate mapping in the reverse direction
    allPairs.push(pair);
    emit PairCreated(token0, token1, pair, allPairs.length);
}

But that is not the cause of the crash. The function createPair returns 0xa30dfc9ccec02e57e3b0272b4f09fde66410042b, so the token pair was successfully created.

The problems is the function pairFor returns a different address 0x1bca13dfcc28383040c8b3a8f453fadf7ff2b362.

// calculates the CREATE2 address for a pair without making any external calls
function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
    (address token0, address token1) = sortTokens(tokenA, tokenB);
    pair = address(uint(keccak256(abi.encodePacked(
            hex'ff',
            factory,
            keccak256(abi.encodePacked(token0, token1)),
            hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash
        ))));
}

The more likely cause of the failure is the init code hash. If you are using a different solc version or compiler configuration the bytecode will be different and the expected addresses will not match the deployed addresses.

3
  • I used the wrapper contract as standard token in bscscan.com/…. As compiled configuration and bytecode is the same, there’s no reasons pairFor should generate a different address, yet as I explain in my question it’s what’s happening. Feb 15 at 17:58
  • @user2284570 Compiler configuration is not the same. On BSC it is configured with 200 runs, and for mainnet it is 999999.
    – Ismael
    Feb 15 at 19:02
  • The generate bytecode remains identical : it’s just more runs don’t change the compiled result. Do you have an idea for that begginner’s question ethereum.stackexchange.com/q/159866 ? Feb 15 at 19:05
1

To have the same address on a deployment all the arguments must match.

From a wallet the nonce also have to be the same.

From a contract there is most likely one argument that is not the same. The chain id is one argument that will always change so if the deployment uses it the address will change.

1
  • Chainid isn’t part of the create2 address computation nor are the nonces… Yet, the address are different. Feb 14 at 15:37

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.