I was checking Uniswap contracts github repo and I don't understand exactly how can they dynamically use any ERC20 tokens without importing the code or having the ERC20 token smart contract address.

I know that the magic is in this function, specially in assembly create2 function, but cannot understand it properly.

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
    emit PairCreated(token0, token1, pair, allPairs.length);

Could anyone provide further information?

1 Answer 1


createPair takes two ERC20 contract addresses as input, and returns the address of this pair. This address is deterministically calculated using the CREATE2 opcode. Therefore all information is inherently available and no addresses need to be hardcoded. getPair gets dynamically populated with pair addresses.

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.