Skip to content

Deploy Uniswap

Overview

Uniswap is a decentralized exchange (DEX) protocol built on the Ethereum blockchain. Uniswap allows users to trade Ethereum-based tokens without the need for an intermediary or a centralized exchange. It uses a unique automated market maker (AMM) system to facilitate trades and provide liquidity to the platform.

Uniswap operates on a set of smart contracts that are open-source and decentralized, meaning they are not controlled by any centralized authority or entity. Instead, users interact directly with the smart contracts using their Ethereum wallets, and participate in the platform's liquidity provision and trading features.

A key feature of Uniswap is its unique AMM system, which uses a constant product formula to determine the price of tokens on the platform. This means that the price of a token is determined by the ratio of the token's supply to the supply of another token in a trading pair. This system allows users to trade tokens without relying on order books or centralized matching engines.

Another important feature of Uniswap is its liquidity provision system, which allows users to provide liquidity to the platform in exchange for a share of trading fees. This allows users to earn a passive income by contributing to the platform's liquidity and helping to facilitate trades between different tokens.

Uniswap has become one of the most popular decentralized exchanges on the Ethereum network, with a wide range of tokens and trading pairs available for users to trade. Its decentralized and open-source nature makes Uniswap a popular choice among cryptocurrency enthusiasts who value the principles of decentralization, transparency, and community governance.

Installation

  1. Refer to the above link to install NodeJS
  2. Create project dir and go there
    mkdir uniswap
    cd uniswap
    

Deploy Contracts

v3-core

  1. Clone repo from github
    git clone -n https://github.com/Uniswap/v3-core.git
    
  2. Go to v3-core directory
    cd v3-core 
    
  3. Checkout version
    git checkout -b wf d8b1c635c275d2a9450bd6a78f3fa2484fef73eb
    
  4. Install packages
    yarn install
    
  5. Go to Networks - RPC Endpoints page and check params
  6. Add Waterfall Network to hardhat.config.js file
    networks: {
      ...
      waterfall: {
        url: "https://rpc.testnet9.waterfall.network",
        chainId:  1501869,
        accounts: ['07201008f00b31de405a0af22ff04871044e027878929b7b47569ca76555ff09'], // Private key from your account
        from: '0xa7062A2Bd7270740f1d15ab70B3Dee189A87b6DE' // Your Deployer Account
      }
    }
    
  7. Create scripts directory
    mkdir scripts
    
  8. Create deploy.js file in scripts directory and past next code:
    async function main() {
      const UniswapV3Factory = await ethers.getContractFactory('UniswapV3Factory')
    
      // Start deployment, returning a promise that resolves to a contract object
      const uniswapV3Factory = await UniswapV3Factory.deploy()
      console.log('Contract deployed to address:', uniswapV3Factory.address);//0x61F5cC6C2792d7409FEC7ED4E798135e8fc26fD2
    }
    
    main()
      .then(() => process.exit(0))
      .catch((error) => {
        console.error(error)
        process.exit(1)
      })
    
  9. Deploy contract
    npx hardhat run --network waterfall scripts/deploy.js
    Compilation finished successfully
    Creating Typechain artifacts in directory typechain for target ethers-v5
    Successfully generated Typechain artifacts!
    Contract deployed to address: 0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E
    
  10. Save the contract address you received, you will need it later; eg: 0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E

  11. Exit to project directory

    cd ../
    

v3-periphery

  1. Clone repo from GitHub
    git clone -n https://github.com/Uniswap/v3-periphery.git
    
  2. Go to v3-periphery directory
    cd v3-periphery
    
  3. checkout version
    git checkout -b wf 6cce88e63e176af1ddb6cc56e029110289622317
    
  4. Install packages
    yarn install
    
  5. Go to Networks - RPC Endpoints page and check params
  6. Add Waterfall Network to hardhat.config.js file
    networks: {
      ...
      waterfall: {
        url: "https://rpc.testnet9.waterfall.network",
        chainId:  1501869,
        accounts: ['07201008f00b31de405a0af22ff04871044e027878929b7b47569ca76555ff09'], // Private key from your account
        from: '0xa7062A2Bd7270740f1d15ab70B3Dee189A87b6DE' // Your Deployer Account
      }
    }
    
  7. Create scripts directory
    mkdir scripts
    
  8. Create deploy.js file in scripts directory and past next code:
    const web3 = require('web3')
    async function main() {
      const factoryAdr = '0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E' // Use contract adress in previous step.
    
      const WWATER = await ethers.getContractFactory('WWATER')
      const _WWATER = await WWATER.deploy()
      wwaterAdr =  _WWATER.address
      console.log('WWATER deployed at:', wwaterAdr)
    
      const UniswapInterfaceMulticall = await ethers.getContractFactory('UniswapInterfaceMulticall')
      const _UniswapInterfaceMulticall = await UniswapInterfaceMulticall.deploy()
      console.log('UniswapInterfaceMulticall address:', _UniswapInterfaceMulticall.address)
    
      const Quoter = await ethers.getContractFactory('Quoter')
      const _Quoter = await Quoter.deploy(factoryAdr, wwaterAdr)
      console.log('Quoter address:', _Quoter.address)
    
      const nativeCurrencyLabelBytes = web3.utils.asciiToHex("WATER\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
      const NFTDescriptor = await ethers.getContractFactory('NFTDescriptor')
      const _NFTDescriptor = await NFTDescriptor.deploy()
      console.log('NFTDescriptor address:', _NFTDescriptor.address)
    
      const NonfungibleTokenPositionDescriptor = await ethers.getContractFactory('NonfungibleTokenPositionDescriptor', {
        libraries: {
          NFTDescriptor:  _NFTDescriptor.address
        }
      })
      const _NonfungibleTokenPositionDescriptor = await NonfungibleTokenPositionDescriptor.deploy(wwaterAdr, nativeCurrencyLabelBytes)
      console.log('NonfungibleTokenPositionDescriptor address:', _NonfungibleTokenPositionDescriptor.address)
      const NonfungibleTokenPositionDescriptorAddr = _NonfungibleTokenPositionDescriptor.address
    
    
      const NonfungiblePositionManager = await ethers.getContractFactory('NonfungiblePositionManager')
      const _NonfungiblePositionManager = await NonfungiblePositionManager.deploy(factoryAdr, wwaterAdr, NonfungibleTokenPositionDescriptorAddr)
      console.log('NonfungiblePositionManager address:', _NonfungiblePositionManager.address)
      const NonfungiblePositionManagerAddr = _NonfungiblePositionManager.address
    
      const SwapRouter = await ethers.getContractFactory('SwapRouter')
      const _SwapRouter = await SwapRouter.deploy(factoryAdr, wwaterAdr)
      console.log('SwapRouter address:', _SwapRouter.address)
    
    
      const V3Migrator = await ethers.getContractFactory('V3Migrator')
      const _V3Migrator = await V3Migrator.deploy(factoryAdr, wwaterAdr, NonfungiblePositionManagerAddr)
      console.log('V3Migrator address:', _V3Migrator.address)
    
    }
    
    main()
      .then(() => process.exit(0))
      .catch((error) => {
        console.error(error)
        process.exit(1)
      })
    
  9. Update factoryAdr const which you got when deploying v3-core contracts
  10. Create contracts/lens/WWATER.sol file and past next code:
    pragma solidity =0.7.6;
    
    contract WWATER {
      string public name     = "Wrapped Water";
      string public symbol   = "WWATER";
      uint8  public decimals = 18;
    
      event  Approval(address indexed src, address indexed guy, uint wad);
      event  Transfer(address indexed src, address indexed dst, uint wad);
      event  Deposit(address indexed dst, uint wad);
      event  Withdrawal(address indexed src, uint wad);
    
      mapping (address => uint)                       public  balanceOf;
      mapping (address => mapping (address => uint))  public  allowance;
    
      receive() external payable {
        deposit();
      }
      function deposit() public payable {
        balanceOf[msg.sender] += msg.value;
        emit Deposit(msg.sender, msg.value);
      }
      function withdraw(uint wad) public {
        require(balanceOf[msg.sender] >= wad);
        balanceOf[msg.sender] -= wad;
        msg.sender.transfer(wad);
        emit Withdrawal(msg.sender, wad);
      }
    
      function totalSupply() public view returns (uint) {
        return address(this).balance;
      }
    
      function approve(address guy, uint wad) public returns (bool) {
        allowance[msg.sender][guy] = wad;
        Approval(msg.sender, guy, wad);
        return true;
      }
    
      function transfer(address dst, uint wad) public returns (bool) {
        return transferFrom(msg.sender, dst, wad);
      }
    
      function transferFrom(address src, address dst, uint wad)
      public
      returns (bool)
      {
        require(balanceOf[src] >= wad);
    
        if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
          require(allowance[src][msg.sender] >= wad);
          allowance[src][msg.sender] -= wad;
        }
    
        balanceOf[src] -= wad;
        balanceOf[dst] += wad;
    
        emit Transfer(src, dst, wad);
    
        return true;
      }
    }
    
  11. Deploy contracts
    npx hardhat run --network waterfall scripts/deploy.js
    Compilation finished successfully
    Creating Typechain artifacts in directory typechain for target ethers-v5
    Successfully generated Typechain artifacts!
    WWATER deployed at: 0xe05FeCA8B752051B207f071D876B442cACC9bd2c
    UniswapInterfaceMulticall address: 0x0Ba145B472B04df34B20c249165bf1Ea726e888F
    Quoter address: 0xFed014fdb55180094093765276764FE21B67ed38
    NFTDescriptor address: 0x4c05686A968EF683Ea47eF67585ADC32563d00F8
    NonfungibleTokenPositionDescriptor address: 0x8864c400FA2CBB97e2fb41fb032007a790C24C35
    NonfungiblePositionManager address: 0x94e00D88e5C0087F0Dd3E42b5FcEA398259b52d7
    SwapRouter address: 0x33C432A9De272FcF70c8924F43793E250AffE886
    V3Migrator address: 0xA0246FD3af3Ea069bD3742Fe89eFf3e773CA09E4
    
  12. Save the retrieved contract addresses, you will need them later
  13. Exit to project directory
    cd ../
    

permit2

  1. Install Foundry

    Attention

    Please use this specific version for the download, as other versions may not function correctly.

    foundryup --version nightly-5b7e4cb3c882b28f3c32ba580de27ce7381f415a
    

  2. Clone repo from github

    git clone -n https://github.com/Uniswap/permit2.git
    

  3. Go to permit2 directory
    cd permit2
    
  4. Checkout version
    git checkout -b wf db96e06278b78123970183d28f502217bef156f4
    
  5. Prepare contract
    forge install
    
  6. Deploy contract
    forge create --rpc-url https://rpc.testnet9.waterfall.network --private-key [Your private key] src/Permit2.sol:Permit2
    Deployer: 0xa7e558Cc6efA1c41270eF4Aa227b3dd6B4a3951E
    Deployed to: 0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC
    Transaction hash: 0x5556c3a23fc79477991e16cb087a7528a1642861da1fce947bf5232f4a1d9bf0   
    
  7. Save the retrieved contract address, you will need it later
    eg: 0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC
  8. Exit to project directory
    cd ../
    

Universal-Router

  1. Install Foundry

    Attention

    Please use this specific version for the download, as other versions may not function correctly.

    foundryup --version nightly-5b7e4cb3c882b28f3c32ba580de27ce7381f415a
    

  2. Clone repo from Github

    git clone -n https://github.com/Uniswap/universal-router.git
    

  3. Go to universal-router directory
    cd universal-router
    
  4. Сheckout version
    git checkout -b wf 4104efca7dc786cec631a51030ffb28bd46e1e5e
    
  5. Install packages
    yarn install
    
  6. Prepare contract
    forge install
    
  7. Create DeployWaterfall.s.sol in script/deployParameters directory and paste next code:
    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8.15;
    
    import {DeployUniversalRouter} from '../DeployUniversalRouter.s.sol';
    import {RouterParameters} from 'contracts/base/RouterImmutables.sol';
    
    contract DeployWaterfall is DeployUniversalRouter {
      function setUp() public override {
        params = RouterParameters({
          permit2: 0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC,
          weth9: 0xe05FeCA8B752051B207f071D876B442cACC9bd2c,
          seaport: UNSUPPORTED_PROTOCOL,
          seaportV1_4: UNSUPPORTED_PROTOCOL,
          openseaConduit: UNSUPPORTED_PROTOCOL,
          nftxZap: UNSUPPORTED_PROTOCOL,
          x2y2: UNSUPPORTED_PROTOCOL,
          foundation: UNSUPPORTED_PROTOCOL,
          sudoswap: UNSUPPORTED_PROTOCOL,
          elementMarket: UNSUPPORTED_PROTOCOL,
          nft20Zap: UNSUPPORTED_PROTOCOL,
          cryptopunks: UNSUPPORTED_PROTOCOL,
          looksRareV2: UNSUPPORTED_PROTOCOL,
          routerRewardsDistributor: UNSUPPORTED_PROTOCOL,
          looksRareRewardsDistributor: UNSUPPORTED_PROTOCOL,
          looksRareToken: UNSUPPORTED_PROTOCOL,
          v2Factory: UNSUPPORTED_PROTOCOL,
          v3Factory: 0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E,
          pairInitCodeHash: 0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f,
          poolInitCodeHash: 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54
        });
      }
    }
    
  8. Change permit2, weth9(WWATER) and v3Factory(v3-core) addresses, which you got in previous steps
  9. Compile contracts
    forge build
    
  10. Deploy contract
    forge script --broadcast --rpc-url https://rpc.testnet9.waterfall.network --private-key [Your private key] --sig 'run()' script/deployParameters/DeployWaterfall.s.sol:DeployWaterfall
    == Return ==
    Universal Router Deployed: 0x37256428625e4ed086aaffd66805c86b9288f39a
    
  11. Save the gotten contract addresses, you will need the later
  12. Exit to project directory
    cd ../
    

UI

  1. Clone repo from Github
    git clone -n https://github.com/Uniswap/interface.git
    
  2. Go to interface directory
    cd interface
    
  3. Checkout version
    git checkout -b wf bc48b4fb0e1abb2c5961ecee3e8cc134dee6ac87
    
  4. Upload new file schema.graphql in interface/src/graphql/thegraph/schema.graphql.
  5. Upload new file schema.graphql in interface/src/graphql/data/schema.graphql.
  6. Remove polyfill
    yarn remove polyfill-object.fromentries
    
  7. Install packages
    yarn install
    
  8. Add polyfill
    yarn add polyfill-object.fromentries@^1.0.1
    
  9. Add support Waterfall network to src/constants/chains.ts file
    export enum SupportedChainId {
      ...
      WATERFALL =  1501869,
    }
    ...
    export const CHAIN_IDS_TO_NAMES = {
      ...
      [SupportedChainId.WATERFALL]: 'waterfall',
    }
    ...
    export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = [
      ...
      SupportedChainId.WATERFALL,
    ]
    ...
    export const L1_CHAIN_IDS = [
      ...
      SupportedChainId.WATERFALL,
    ]
    
  10. Add Waterfall Network info to src/constants/chainInfo.ts file
    const CHAIN_INFO: ChainInfoMap = {
      ...
      [SupportedChainId.WATERFALL]: {
        networkType: NetworkType.L1,
        blockWaitMsBeforeWarning: ms`10m`,
        docs: 'https://docs.waterfall.network/',
        explorer: 'https://explorer.testnet9.waterfall.network/',
        infoLink: 'https://waterfall.network/',
        label: 'Waterfall',
        logoUrl: 'https://explorer.testnet9.waterfall.network/favicon-152-precomposed.png',
        nativeCurrency: { name: 'Water', symbol: 'Water', decimals: 18 },
      },
    }
    
  11. Create tokens list like here: https://storage.waterfall.network/daps/uniswap/token-list-testnet9.json
    You should deploy WRC20 tokens.
  12. Add your tokens list to src/constants/lists.ts file
    ...
    const WATERFALL_LIST = 'https://storage.waterfall.network/daps/uniswap/token-list-testnet9.json'
    ...
    export const DEFAULT_ACTIVE_LIST_URLS: string[] = [UNI_LIST, WATERFALL_LIST]
    
  13. Add rpc url to src/constants/networks.ts file
    export const FALLBACK_URLS = {
      ...
      [SupportedChainId.WATERFALL]: [
        'https://rpc.testnet9.waterfall.network'
      ],
    }
    ...
    export const RPC_URLS = {
      ...
      [SupportedChainId.WATERFALL]: [...FALLBACK_URLS[SupportedChainId.WATERFALL]],
    }
    
  14. Add rpc provider to src/constants/providers.ts file
    export const RPC_PROVIDERS: { [key in SupportedChainId]: StaticJsonRpcProvider } = {
      ...
      [SupportedChainId.WATERFALL]: new AppJsonRpcProvider(SupportedChainId.WATERFALL),
    }
    
  15. Add explorer src/utils/anonymizeLink.ts

    const EXPLORER_HOSTNAMES: { [hostname: string]: true } = {
      ...
      'explorer.testnet9.waterfall.network': true,
    }
    
    src/utils/getExplorerLink.ts
    const BLOCK_EXPLORER_PREFIXES: { [chainId: number]: string } = {
      ...
      [SupportedChainId.WATERFALL]: 'https://explorer.testnet9.waterfall.network',
    }
    

  16. Add Waterfall Network selection in file src/components/NavBar/ChainSelector.tsx

    const NETWORK_SELECTOR_CHAINS = [
      ...
      SupportedChainId.WATERFALL,
    ]
    

  17. Change factory address node_modules/@uniswap/v3-sdk/dist/constants.d.ts
    export declare const FACTORY_ADDRESS = "0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E";
    
    node_modules/@uniswap/v3-sdk/dist/v3-sdk.cjs.development.js
    var FACTORY_ADDRESS = '0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E';
    
    node_modules/@uniswap/v3-sdk/dist/v3-sdk.esm.js
    var FACTORY_ADDRESS = '0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E';
    
  18. Update permit2-sdk module to add contract address which was deployed in previous step: node_modules/@uniswap/permit2-sdk/dist/constants.d.ts
    export declare const PERMIT2_ADDRESS = "0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC";
    
    node_modules/@uniswap/permit2-sdk/dist/permit2-sdk.cjs.development.js
    var PERMIT2_ADDRESS = '0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC';
    
    node_modules/@uniswap/permit2-sdk/dist/permit2-sdk.esm.js
    var PERMIT2_ADDRESS = '0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC';
    
  19. Add universal router and permit addresses in node_modules/@uniswap/universal-router-sdk/dist/universal-router-sdk.cjs.development.js and node_modules/@uniswap/universal-router-sdk/dist/universal-router-sdk.esm.js
    ...
    var UNIVERSAL_ROUTER_ADDRESS = function UNIVERSAL_ROUTER_ADDRESS(chainId) {
      switch (chainId) {
        ...
        case  1501869:
          // waterfall
          return '0x37256428625e4ed086aaffd66805c86b9288f39a';
        default:
          throw new Error("Universal Router not deployed on chain " + chainId);
      }
    };
    var WETH_ADDRESS = function WETH_ADDRESS(chainId) {
      switch (chainId) {
        ...
        case  1501869:
          //waterfall
          return '0xe05FeCA8B752051B207f071D876B442cACC9bd2c';
        default:
          throw new Error("WETH9 or UniversalRouter not deployed on chain " + chainId);
      }
    };
    var PERMIT2_ADDRESS = '0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC';
    
    in node_modules/@uniswap/universal-router-sdk/dist/utils/constants.d.ts
    export declare const PERMIT2_ADDRESS = "0x720D15aB16B1443016Fd267d00cCF87b9Becf1aC";
    
  20. Update contracts addresses in src/constants/addresses.ts file
    ...
    // Waterfall
    const WATERFALL_V3_CORE_FACTORY_ADDRESSES = '0x48A6024B11F67eaBD632d6C98d62B1eEa7D05c1E'
    const WATERFALL_V3_MIGRATOR_ADDRESSES = '0xA0246FD3af3Ea069bD3742Fe89eFf3e773CA09E4'
    const WATERFALL_MULTICALL_ADDRESS = '0x0Ba145B472B04df34B20c249165bf1Ea726e888F'
    const WATERFALL_QUOTER_ADDRESSES = '0xFed014fdb55180094093765276764FE21B67ed38'
    const WATERFALL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES = '0x94e00D88e5C0087F0Dd3E42b5FcEA398259b52d7'
    const WATERFALL_SWAP_ROUTER_ADDRESSES = '0x33C432A9De272FcF70c8924F43793E250AffE886'
    ...
    export const V3_CORE_FACTORY_ADDRESSES: AddressMap = {
      ...
      [SupportedChainId.WATERFALL]: WATERFALL_V3_CORE_FACTORY_ADDRESSES,
    }
    ...
    export const V3_MIGRATOR_ADDRESSES: AddressMap = {
      ...
      [SupportedChainId.WATERFALL]: WATERFALL_V3_MIGRATOR_ADDRESSES,
    }
    ...
    export const MULTICALL_ADDRESS: AddressMap = {
      ...
      [SupportedChainId.WATERFALL]: WATERFALL_MULTICALL_ADDRESS,
    }
    ...
    export const QUOTER_ADDRESSES: AddressMap = {
      ...
      [SupportedChainId.WATERFALL]: WATERFALL_QUOTER_ADDRESSES,
    }
    ...
    export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES: AddressMap = {
      ...
      [SupportedChainId.WATERFALL]: WATERFALL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
    }
    
  21. Go to src/constants/tokens.ts and add WRAPPED_NATIVE_CURRENCY
    export const WRAPPED_NATIVE_CURRENCY: { [chainId: number]: Token | undefined } = {
      ...
      [SupportedChainId.WATERFALL]: new Token(
        SupportedChainId.WATERFALL,
        '0xe05FeCA8B752051B207f071D876B442cACC9bd2c',
        18,
        'WWATER',
        'Wraped Water'
      ),
    }
    
  22. Start
    yarn run prepare
    yarn start