Skip to content

Deploy Uniswap V2 Core with EVM

Polkadot Hub supports two execution paths for running smart contracts: PVM (which compiles Solidity to the Polkadot Virtual Machine via the revive compiler) and EVM (powered by REVM, a Rust implementation of the Ethereum Virtual Machine, which runs standard EVM bytecode with zero modifications). This tutorial follows the EVM path.

With EVM, you deploy the same unmodified Solidity contracts using the same standard Hardhat toolchain you already know. No special compiler plugins, no contract rewrites, and no porting effort. If your project compiles with vanilla Hardhat, it runs on Polkadot Hub through EVM.

This tutorial walks you through cloning, compiling, testing, and deploying Uniswap V2 on Polkadot Hub using Hardhat and TypeScript. By the end, you will have a fully functioning UniswapV2Factory contract deployed to the Polkadot Hub TestNet.

Before starting, make sure you have:

  • Node.js v22.0.0 or later and npm installed
  • Basic understanding of Solidity and TypeScript
  • Familiarity with the Hardhat development environment
  • Some test tokens to cover transaction fees, obtained from the Polkadot faucet (see Get Test Tokens for a guide to using the faucet)
  • A wallet with a private key for signing transactions
  • Basic understanding of how AMMs and liquidity pools work

Start by cloning the EVM Hardhat examples repository, which contains the Uniswap V2 Core project with a standard Hardhat and TypeScript configuration:

  1. Clone the repository and navigate to the Uniswap V2 project:

    Terminal window
    git clone https://github.com/polkadot-developers/revm-hardhat-examples.git
    cd revm-hardhat-examples
    git checkout b0a8627059a9d9cb759682310219557550186bc4
    cd uniswap-v2-core-hardhat/
  2. Install the required dependencies:

    Terminal window
    npm install
  3. Compile the contracts:

    Terminal window
    npx hardhat compile

    If the compilation is successful, you should see output similar to the following:

    npx hardhat compile Downloading solc 0.5.16 Compiling 12 Solidity files Successfully compiled 12 Solidity files

    After running this command, the compiled artifacts (ABI and bytecode) appear in the artifacts directory.

This project uses Hardhat Configuration Variables to manage private keys securely. Unlike .env files, configuration variables are stored outside your project directory and are never at risk of being committed to version control.

To set your private key for TestNet deployment, run:

Terminal window
npx hardhat vars set TESTNET_PRIVATE_KEY

When prompted, paste your private key. Hardhat stores it securely and makes it available through vars.get("TESTNET_PRIVATE_KEY") in the configuration file.

The hardhat.config.ts file references the variable conditionally, so the project works without it for local development:

networks: {
localNode: {
url: "http://127.0.0.1:8545",
},
polkadotTestnet: {
url: "https://services.polkadothub-rpc.com/testnet",
accounts: vars.has("TESTNET_PRIVATE_KEY")
? [vars.get("TESTNET_PRIVATE_KEY")]
: [],
},
},

Before interacting with the contracts, it is essential to understand the core architecture that powers Uniswap V2. This model forms the basis of nearly every modern DEX implementation and operates under automated market making, token pair liquidity pools, and deterministic pricing principles.

At the heart of Uniswap V2 lies a simple but powerful system composed of two major smart contracts:

  • Factory contract: Acts as a registry and creator of new trading pairs. When two ERC-20 tokens are to be traded, the Factory contract generates a new Pair contract that manages that specific token pair's liquidity pool. It tracks all deployed pairs and ensures uniqueness, so no duplicate pools can exist for the same token combination.
  • Pair contract: Each Pair contract is a decentralized liquidity pool that holds reserves of two ERC-20 tokens. These contracts implement the core AMM logic, maintaining a constant product invariant (x * y = k) to facilitate swaps and price determination. Users contribute tokens to these pools in return for LP (liquidity provider) tokens, which represent their proportional share of the reserves.

This architecture enables Uniswap to be highly modular, trustless, and extensible. By distributing responsibilities across these components, developers and users can engage with the protocol in a composable and predictable manner.

The project scaffolding is as follows:

uniswap-v2-core-hardhat/
├── contracts/
│ ├── interfaces/
│ │ ├── IERC20.sol
│ │ ├── IUniswapV2Callee.sol
│ │ ├── IUniswapV2ERC20.sol
│ │ ├── IUniswapV2Factory.sol
│ │ └── IUniswapV2Pair.sol
│ ├── libraries/
│ │ ├── Math.sol
│ │ ├── SafeMath.sol
│ │ └── UQ112x112.sol
│ ├── test/
│ │ └── ERC20.sol
│ ├── UniswapV2ERC20.sol
│ ├── UniswapV2Factory.sol
│ └── UniswapV2Pair.sol
├── ignition/
│ └── modules/
│ └── UniswapV2Factory.ts
├── scripts/
│ └── deploy.ts
├── test/
│ ├── shared/
│ │ └── utilities.ts
│ ├── UniswapV2ERC20.test.ts
│ ├── UniswapV2Factory.test.ts
│ └── UniswapV2Pair.test.ts
├── hardhat.config.ts
├── package.json
└── tsconfig.json

Key differences from a typical Ethereum Hardhat project are minimal. The Solidity contracts are the original Uniswap V2 source (Solidity 0.5.16) with no modifications. The test files use TypeScript (.test.ts) and avoid loadFixture for compatibility with the Polkadot execution environment.

The project includes a comprehensive test suite with 28 tests across three test files covering ERC-20 functionality, factory operations, and pair contract interactions including liquidity management and swaps.

To run the tests locally:

  1. Start the local development node. Follow the steps in the Local Development Node guide to set it up.

  2. In a new terminal, run the test suite against the local node:

    Terminal window
    npx hardhat test --network localNode

    The tests are configured with a 120-second Mocha timeout to accommodate Polkadot network block times. The result should look similar to the following:

    npx hardhat test --network localNode Compiling 12 Solidity files Successfully compiled 12 Solidity files UniswapV2ERC20 ✔ name, symbol, decimals, totalSupply, balanceOf, DOMAIN_SEPARATOR, PERMIT_TYPEHASH (41ms) ✔ approve (4983ms) ✔ transfer (5047ms) ✔ transfer:fail ✔ transferFrom (6104ms) ✔ transferFrom:max (6138ms) UniswapV2Factory ✔ feeTo, feeToSetter, allPairsLength ✔ createPair (168ms) ✔ createPair:reverse (1198ms) ✔ setFeeTo (1112ms) ✔ setFeeToSetter (1099ms) UniswapV2Pair ✔ mint (11208ms) ✔ getInputPrice:0 (12374ms) ✔ getInputPrice:1 (17382ms) ✔ getInputPrice:2 (17401ms) ✔ getInputPrice:3 (17488ms) ✔ getInputPrice:4 (17433ms) ✔ getInputPrice:5 (17378ms) ✔ getInputPrice:6 (13427ms) ✔ optimistic:0 (17431ms) ✔ optimistic:1 (17730ms) ✔ optimistic:2 (17441ms) ✔ optimistic:3 (21409ms) ✔ swap:token0 (12449ms) ✔ swap:token1 (17415ms) ✔ burn (17474ms) ✔ feeTo:off (23684ms) ✔ feeTo:on (24775ms) 28 passing (12m)

After successfully testing the contracts, you can deploy them to the Polkadot Hub TestNet using Hardhat Ignition. The Ignition module at ignition/modules/UniswapV2Factory.ts deploys the UniswapV2Factory contract.

Make sure you have configured your private key and that your account has test tokens. Then run:

Terminal window
npx hardhat ignition deploy ./ignition/modules/UniswapV2Factory.ts --network polkadotTestnet

When prompted, confirm the target network name and chain ID. Ignition deploys the Factory contract and prints the deployed address. The output should look similar to the following:

npx hardhat ignition deploy ./ignition/modules/UniswapV2Factory.ts --network polkadotTestnet ✔ Confirm deploy to network polkadotTestnet (420420417)? … yes   Hardhat Ignition 🚀   Deploying [ UniswapV2FactoryModule ]   Batch #1 Executed UniswapV2FactoryModule#UniswapV2Factory   [ UniswapV2FactoryModule ] successfully deployed 🚀   Deployed Addresses   UniswapV2FactoryModule#UniswapV2Factory - 0x85b108660f47caDfAB9e0503104C08C1c96e0DA9
  • Deploy Uniswap V2 Periphery


    Deploy Router contracts for user-facing swaps, liquidity management, and WETH wrapping on top of V2 Core.

    → Get Started

  • Hardhat on Polkadot


    Learn how to create, compile, test, and deploy smart contracts on Polkadot Hub using Hardhat.

    → Reference

  • Local Development Node


    Set up and run a local development node for testing your smart contracts against Polkadot.

    → Set Up

Last updated: