Skip to content

Deploy Uniswap

Overview

Uniswap is a decentralized exchange (DEX) protocol built on the Ethereum blockchain that 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 that they are not controlled by any centralized authority or entity. Instead, users can interact with the smart contracts directly using their Ethereum wallets and participate in the platform's liquidity provision and trading features.

One of the key features 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 and the supply of the other token in the trading pair. This system allows users to trade tokens without the need for 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 the trading fees. This means that users can 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 has made it a popular choice among cryptocurrency enthusiasts who value the principles of decentralization, transparency, and community governance.

Demo

You can try uniswap demo there:

Installation

  1. Refer to the 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
    git checkout d8b1c635c275d2a9450bd6a78f3fa2484fef73eb
    
  2. Go to v3-core directory
    cd v3-core 
    
  3. Install packages
    yarn install
    
  4. Go to Networks - RPC Endpoints page and check params
  5. Add Waterfall Network to hardhat.config.js file
    networks: {
      ...
      waterfall: {
        url: "https://rpc.waterfall.network/rpc",
        chainId: 333777333,
        accounts: ['07201008f00b31de405a0af22ff04871044e027878929b7b47569ca76555ff09'], // Private key from your account
        from: '0xa7062A2Bd7270740f1d15ab70B3Dee189A87b6DE', // Your Deployer Account
        gasPrice: 20000000000,
        gas: 3000000,
      }
    }
    
  6. Create scripts directory
    mkdir scripts
    
  7. 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);//0xb96eb0A6cE4c5C258413E09d5E575966245cAf9F
    }
    
    main()
      .then(() => process.exit(0))
      .catch((error) => {
        console.error(error)
        process.exit(1)
      })
    
  8. 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: 0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4
    
  9. Save the gotten contract address, you will need it later eg: 0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4
  10. Exit to project directory
    cd ../
    

v3-periphery

  1. Clone repo from github
    git clone -n https://github.com/Uniswap/v3-periphery.git
    git checkout 6cce88e63e176af1ddb6cc56e029110289622317
    
  2. Go to v3-periphery directory
    cd v3-periphery
    
  3. Install packages
    yarn install
    
  4. Go to Networks - RPC Endpoints page and check params
  5. Add Waterfall Network to hardhat.config.js file
    networks: {
      ...
      waterfall: {
        url: "https://rpc.waterfall.network/rpc",
        chainId: 333777333,
        accounts: ['07201008f00b31de405a0af22ff04871044e027878929b7b47569ca76555ff09'], // Private key from your account
        from: '0xa7062A2Bd7270740f1d15ab70B3Dee189A87b6DE', // Your Deployer Account
        gasPrice: 20000000000,
        gas: 3000000,
      }
    }
    
  6. Create scripts directory
    mkdir scripts
    
  7. Create deploy.js file in scripts directory and past next code:
    const web3 = require('web3')
    async function main() {
      const factoryAdr = '0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4'
    
      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)
      })
    
  8. Update factoryAdr const which you had when deploy v3-core contracts
  9. 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;
      }
    }
    
  10. 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: 0xe748d811b30F140CC18423Ab3244804efE508a93
    UniswapInterfaceMulticall address: 0x671787Cf37c82FBb786C74Cb36c46d6867b6bA71
    Quoter address: 0x1bB7a05C8e22ebe1d1B38Eefd3803Fc1602fE3F7
    NFTDescriptor address: 0xd474986Ed0E49A0088e9852984973822612c8C09
    NonfungibleTokenPositionDescriptor address: 0xB9cF42F49D8d86F96133e5f1311427aeb26354C8
    NonfungiblePositionManager address: 0x7056652b61f0C39261c2DA41CF81C414366145C5
    SwapRouter address: 0x876C9Ec93eB5Eb74719A3874344c05706FaFD5C5
    V3Migrator address: 0x9d8A58A91398a3f92654501C1c95D9AAC9B9dcec
    
  11. Save the gotten contracts addresses, you will need the later
  12. Exit to project directory
    cd ../
    

permit2

  1. Install Founadry
  2. Clone repo from github
    git clone -n https://github.com/Uniswap/permit2.git
    git checkout db96e06278b78123970183d28f502217bef156f4
    
  3. Go to permit2 directory
    cd permit2
    
  4. Prepare contract
    forge install
    
  5. Deploy contract
    forge create --rpc-url https://rpc.waterfall.network/rpc --private-key [Your private key] src/Permit2.sol:Permit2
    Deployer: 0xa7e558Cc6efA1c41270eF4Aa227b3dd6B4a3951E
    Deployed to: 0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb
    Transaction hash: 0x67d1ba0f63ecbccd0dfff015c393c658bbf89cc851f953fe0eda2ff698f126e8
    
  6. Save the gotten contract address, you will need it later
    eg: 0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb
  7. Exit to project directory
    cd ../
    

universal-router

  1. Install Founadry
  2. Clone repo from github
    git clone -n https://github.com/Uniswap/universal-router.git
    git checkout 4104efca7dc786cec631a51030ffb28bd46e1e5e
    
  3. Go to universal-router directory
    cd universal-router
    
  4. Install packages
    yarn install
    
  5. Prepare contract
    forge install
    
  6. 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: 0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb,
          weth9: 0xe748d811b30F140CC18423Ab3244804efE508a93,
          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: 0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4,
          pairInitCodeHash: 0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f,
          poolInitCodeHash: 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54
        });
      }
    }
    
  7. Change permit2, weth9(WWATER) and v3Factory addresses which we got in previous steps
  8. Compile contracts
    forge build
    
  9. Deploy contract
    forge script --broadcast --rpc-url https://rpc.waterfall.network/rpc --private-key [Your private key] --sig 'run()' script/deployParameters/DeployWaterfall.s.sol:DeployWaterfall
    == Return ==
    router: contract UniversalRouter 0x51B21B2a088270C0Cb9092ba5d9562792ab9Fe91
    
  10. Save the gotten contracts addresses, you will need the later
  11. Exit to project directory
    cd ../
    

UI

  1. Clone repo from github
    git clone -n https://github.com/Uniswap/interface.git
    git checkout bc48b4fb0e1abb2c5961ecee3e8cc134dee6ac87
    
  2. Go to interface directory
    cd interface
    
  3. Install packages
    yarn install
    
  4. Add support Waterfall network to src/constants/chains.ts file
    export enum SupportedChainId {
      ...
      WATERFALL = 333777333,
    }
    ...
    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,
    ]
    
  5. Add Waterfall Network info to src/constants/chainInfo.ts file
    const CHAIN_INFO: ChainInfoMap = {
      ...
      [SupportedChainId.WATERFALL]: {
        networkType: NetworkType.L1,
        blockWaitMsBeforeWarning: ms`10m`,
        docs: 'https://waterfall.network/',
        explorer: 'https://explorer.waterfall.network/',
        infoLink: 'https://waterfall.network/',
        label: 'Waterfall',
        logoUrl: 'https://explorer.waterfall.network/favicon-152-precomposed.png',
        nativeCurrency: { name: 'Water', symbol: 'Water', decimals: 18 },
      },
    }
    
  6. Create tokens list like there https://download.nextcloud.in.ua/testnet-tokens.json
    You should deploy WRC20 tokens.
  7. Add your tokens list to src/constants/lists.ts file
    ...
    const WATERFALL_LIST = 'https://download.nextcloud.in.ua/testnet-tokens.json'
    ...
    export const DEFAULT_ACTIVE_LIST_URLS: string[] = [UNI_LIST, WATERFALL_LIST]
    
  8. Add rpc url to src/constants/networks.ts file
    export const FALLBACK_URLS = {
      ...
      [SupportedChainId.WATERFALL]: [
        'https://rpc.waterfall.network/rpc'
      ],
    }
    ...
    export const RPC_URLS = {
      ...
      [SupportedChainId.WATERFALL]: [...FALLBACK_URLS[SupportedChainId.WATERFALL]],
    }
    
  9. Add rpc provider to src/constants/providers.ts file
    export const RPC_PROVIDERS: { [key in SupportedChainId]: StaticJsonRpcProvider } = {
      ...
      [SupportedChainId.WATERFALL]: new AppJsonRpcProvider(SupportedChainId.WATERFALL),
    }
    
  10. Add explorer src/utils/anonymizeLink.ts

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

  11. Add Waterfall Networ selection in file src/components/NavBar/ChainSelector.tsx

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

  12. Change factory address node_modules/@uniswap/v3-sdk/dist/constants.d.ts
    export declare const FACTORY_ADDRESS = "0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4";
    
    node_modules/@uniswap/v3-sdk/dist/v3-sdk.cjs.development.js
    var FACTORY_ADDRESS = '0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4';
    
    node_modules/@uniswap/v3-sdk/dist/v3-sdk.esm.js
    var FACTORY_ADDRESS = '0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4';
    
  13. Update permit2-sdk module to add contract address which was deployed in previus step node_modules/@uniswap/permit2-sdk/dist/constants.d.ts
    export declare const PERMIT2_ADDRESS = "0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb";
    
    node_modules/@uniswap/permit2-sdk/dist/permit2-sdk.cjs.development.js
    var PERMIT2_ADDRESS = '0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb';
    
    node_modules/@uniswap/permit2-sdk/dist/permit2-sdk.esm.js
    var PERMIT2_ADDRESS = '0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb';
    
  14. 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 333777333:
          // waterfall
          return '0x51B21B2a088270C0Cb9092ba5d9562792ab9Fe91';
        default:
          throw new Error("Universal Router not deployed on chain " + chainId);
      }
    };
    var WETH_ADDRESS = function WETH_ADDRESS(chainId) {
      switch (chainId) {
        ...
        case 333777333:
          //waterfall
          return '0xe748d811b30F140CC18423Ab3244804efE508a93';
        default:
          throw new Error("WETH9 or UniversalRouter not deployed on chain " + chainId);
      }
    };
    var PERMIT2_ADDRESS = '0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb';
    
    in node_modules/@uniswap/universal-router-sdk/dist/utils/constants.d.ts
    export declare const PERMIT2_ADDRESS = "0xD63366aCeB4dE27B732EC874F8daa2935Be7b6fb";
    
  15. Update contracts addresses in src/constants/addresses.ts file
    ...
    // Waterfall
    const WATERFALL_V3_CORE_FACTORY_ADDRESSES = '0xc03617E3c4f48680Cb0F9f607DAc1C1e24a5E0d4'
    const WATERFALL_V3_MIGRATOR_ADDRESSES = '0x9d8A58A91398a3f92654501C1c95D9AAC9B9dcec'
    const WATERFALL_MULTICALL_ADDRESS = '0x671787Cf37c82FBb786C74Cb36c46d6867b6bA71'
    const WATERFALL_QUOTER_ADDRESSES = '0x1bB7a05C8e22ebe1d1B38Eefd3803Fc1602fE3F7'
    const WATERFALL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES = '0x7056652b61f0C39261c2DA41CF81C414366145C5'
    const WATERFALL_SWAP_ROUTER_ADDRESSES = '0x876C9Ec93eB5Eb74719A3874344c05706FaFD5C5'
    ...
    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,
    }
    
  16. 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,
        '0xe748d811b30F140CC18423Ab3244804efE508a93',
        18,
        'WWATER',
        'Wraped Water'
      ),
    }
    
  17. Start
    yarn run prepare
    yarn start