@ethersproject/providers#JsonRpcProvider JavaScript Examples

The following examples show how to use @ethersproject/providers#JsonRpcProvider. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From acy-dex-interface with MIT License 6 votes vote down vote up
export function getProvider(library, chainId) {
  if (library) {
    return library.getSigner();
  }
  // let provider;
  // provider = _.sample(RPC_PROVIDERS[chainId]);
  // return new ethers.providers.StaticJsonRpcProvider(provider, { chainId });
  return new JsonRpcProvider('https://arb1.arbitrum.io/rpc');
}
Example #2
Source File: UserSigner.js    From Tai-Shang-NFT-Wallet with MIT License 6 votes vote down vote up
parseProviderOrSigner = async providerOrSigner => {
  let signer = undefined;
  let provider;
  let providerNetwork;
  if (providerOrSigner && (providerOrSigner instanceof JsonRpcProvider || providerOrSigner instanceof Web3Provider)) {
    const accounts = await providerOrSigner.listAccounts();
    if (accounts && accounts.length > 0) {
      signer = providerOrSigner.getSigner();
    }
    provider = providerOrSigner;
    providerNetwork = await providerOrSigner.getNetwork();
  }
  if (!signer && providerOrSigner instanceof Signer) {
    signer = providerOrSigner;
    provider = signer.provider;
    providerNetwork = provider && (await provider.getNetwork());
  }
  return { signer, provider, providerNetwork };
}
Example #3
Source File: constants.js    From acy-dex-interface with MIT License 5 votes vote down vote up
tempLibrary = new JsonRpcProvider('https://arb1.arbitrum.io/rpc')
Example #4
Source File: index.js    From acy-dex-interface with MIT License 5 votes vote down vote up
defaultLibrary = new JsonRpcProvider('https://bsc-dataseed1.defibit.io/')
Example #5
Source File: index.js    From acy-dex-interface with MIT License 4 votes vote down vote up
SwapComponent = props => {

  const {
    account,
    library,
    chainId,
    tokenList: INITIAL_TOKEN_LIST,
    farmSetting: { INITIAL_ALLOWED_SLIPPAGE },
    perpetuals
  } = useConstantLoader(props);

  const {
    swapOption: mode,
    setSwapOption: setMode,
    activeToken0,
    setActiveToken0,
    activeToken1,
    setActiveToken1,

    toTokenAddress,
    setToTokenAddress,
    fromTokenAddress,
    setFromTokenAddress,

    positionsMap,
    pendingTxns,
    setPendingTxns,
    savedIsPnlInLeverage,
    approveOrderBook,
    isWaitingForPluginApproval,
    setIsWaitingForPluginApproval,
    isPluginApproving,
    isConfirming,
    setIsConfirming,
    isPendingConfirmation,
    setIsPendingConfirmation,
    isBuying,
    setIsBuying,
    onChangeMode,
    swapTokenAddress,
    setSwapTokenAddress,
    glp_isWaitingForApproval,
    glp_setIsWaitingForApproval,
    orders,
    minExecutionFee
  } = props;

  const connectWalletByLocalStorage = useConnectWallet();
  const { active, activate } = useWeb3React();

  const [type, setType] = useState(MARKET);
  const [fromValue, setFromValue] = useState("");
  const [toValue, setToValue] = useState("");
  const [anchorOnFromAmount, setAnchorOnFromAmount] = useState(true);
  const [isApproving, setIsApproving] = useState(false);
  const [isWaitingForApproval, setIsWaitingForApproval] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  // const [isConfirming, setIsConfirming] = useState(false);
  const [modalError, setModalError] = useState(false);
  const [ordersToaOpen, setOrdersToaOpen] = useState(false);
  const [isHigherSlippageAllowed, setIsHigherSlippageAllowed] = useState(false);


  const savedSlippageAmount = getSavedSlippageAmount(chainId)

  let allowedSlippage = savedSlippageAmount;
  if (isHigherSlippageAllowed) {
    allowedSlippage = DEFAULT_HIGHER_SLIPPAGE_AMOUNT;
  }

  const tokens = perpetuals.tokenList;
  const whitelistedTokens = tokens.filter(t => t.symbol !== "USDG")
  const stableTokens = tokens.filter(token => token.isStable);
  const indexTokens = whitelistedTokens.filter(token => !token.isStable && !token.isWrapped);
  const shortableTokens = indexTokens.filter(token => token.isShortable);
  let toTokens = tokens;

  const isLong = mode === LONG;
  const isShort = mode === SHORT;

  if (isLong) {
    toTokens = indexTokens;
  }
  if (isShort) {
    toTokens = shortableTokens;
  }

  // const [fromTokenAddress, setFromTokenAddress] = useState("0x0000000000000000000000000000000000000000");
  const initialToToken = perpetuals.getTokenBySymBol("BTC").address;
  console.log("initialToToken: ", initialToToken, chainId)
  // const [toTokenAddress, setToTokenAddress] = useState(initialToToken);
  // const [fromTokenInfo, setFromTokenInfo] = useState();
  // const [toTokenInfo, setToTokenInfo] = useState();
  // const [fees, setFees] = useState(0.1);
  // const [leverage, setLeverage] = useState(5);
  // const [isLeverageSliderEnabled, setIsLeverageSliderEnabled] = useState(true);
  // const [entryPriceLimit, setEntryPriceLimit] = useState(0);
  // const [priceValue, setPriceValue] = useState('');
  // const [shortCollateralAddress, setShortCollateralAddress] = useState('0xf97f4df75117a78c1A5a0DBb814Af92458539FB4');
  // const [isWaitingForPluginApproval, setIsWaitingForPluginApproval] = useState(false);


  const tokenAddresses = tokens.map(token => token.address)
  const readerAddress = perpetuals.getContract("Reader")
  const vaultAddress = perpetuals.getContract("Vault")
  const usdgAddress = perpetuals.getContract("USDG")
  const nativeTokenAddress = perpetuals.getContract("NATIVE_TOKEN")
  const routerAddress = perpetuals.getContract("Router")
  const orderBookAddress = perpetuals.getContract("OrderBook")
  const glpManagerAddress = perpetuals.getContract("GlpManager")
  const glpAddress = perpetuals.getContract("GLP")

  const { farmSetting: { RPC_URL }} = useConstantLoader();
  const provider = new JsonRpcProvider(RPC_URL, chainId);

  const { data: tokenBalances, mutate: updateTokenBalances } = useSWR([chainId, readerAddress, "getTokenBalances", account || PLACEHOLDER_ACCOUNT], {
    fetcher: fetcher(library, Reader, [tokenAddresses]),
  })
  const whitelistedTokenAddresses = whitelistedTokens.map(token => token.address)
  const { data: vaultTokenInfo, mutate: updateVaultTokenInfo } = useSWR([chainId, readerAddress, "getFullVaultTokenInfo"], {
    fetcher: fetcher(library, Reader, [vaultAddress, nativeTokenAddress, expandDecimals(1, 18), whitelistedTokenAddresses]),
  })
  const { data: fundingRateInfo, mutate: updateFundingRateInfo } = useSWR([chainId, readerAddress, "getFundingRates"], {
    fetcher: fetcher(library, Reader, [vaultAddress, nativeTokenAddress, whitelistedTokenAddresses]),
  })
  const { data: totalTokenWeights, mutate: updateTotalTokenWeights } = useSWR([chainId, vaultAddress, "totalTokenWeights"], {
    fetcher: fetcher(library, Vault),
  })
  const { data: usdgSupply, mutate: updateUsdgSupply } = useSWR([chainId, usdgAddress, "totalSupply"], {
    fetcher: fetcher(library, Glp),
  })
  const { data: orderBookApproved, mutate: updateOrderBookApproved } = useSWR([chainId, routerAddress, "approvedPlugins", account || PLACEHOLDER_ACCOUNT, orderBookAddress], {
    fetcher: fetcher(library, Router)
  });
  console.log("test orderbook approved: ", routerAddress, account, orderBookAddress, orderBookApproved)

  useEffect(() => {
    if (active) {
      function onBlock() {
        updateVaultTokenInfo()
        updateTokenBalances()
        // updatePositionData(undefined, true)
        updateFundingRateInfo()
        updateTotalTokenWeights()
        updateUsdgSupply()
        updateOrderBookApproved()
      }
      library.on('block', onBlock)
      return () => {
        library.removeListener('block', onBlock)
      }
    }
  }, [active, library, chainId,
      updateVaultTokenInfo, updateTokenBalances, updateFundingRateInfo, updateTotalTokenWeights, updateUsdgSupply,
      updateOrderBookApproved])

  const tokenAllowanceAddress = fromTokenAddress === AddressZero ? nativeTokenAddress : fromTokenAddress;
  const { data: tokenAllowance, mutate: updateTokenAllowance } = useSWR([chainId, tokenAllowanceAddress, "allowance", account || PLACEHOLDER_ACCOUNT, routerAddress], {
    fetcher: fetcher(library, Glp)
  });

  console.log("test needOrderBookApproval: ", type!==MARKET, !orderBookApproved)
  const needOrderBookApproval = type !== MARKET && !orderBookApproved;
  const prevNeedOrderBookApproval = usePrevious(needOrderBookApproval);

  useEffect(() => {
    if (
      !needOrderBookApproval &&
      prevNeedOrderBookApproval &&
      isWaitingForPluginApproval
    ) {
      setIsWaitingForPluginApproval(false);
      helperToast.success(<div>Orders enabled!</div>);
    }
  }, [
    needOrderBookApproval,
    prevNeedOrderBookApproval,
    setIsWaitingForPluginApproval,
    isWaitingForPluginApproval
  ]);



  const [triggerPriceValue, setTriggerPriceValue] = useState("");
  const triggerPriceUsd = type === MARKET ? 0 : parseValue(triggerPriceValue, USD_DECIMALS);
  const onTriggerPriceChange = evt => {
    setTriggerPriceValue(evt.target.value || "");
  };
  const onTriggerRatioChange = evt => {
    setTriggerRatioValue(evt.target.value || "");
  };

  

  // default collateral address on ARBITRUM
  
  const [shortCollateralAddress, setShortCollateralAddress] = useState(fromTokenAddress);

  const infoTokens = getInfoTokens(tokens, tokenBalances, whitelistedTokens, vaultTokenInfo, fundingRateInfo)
  console.log("test multichain: tokens", infoTokens, tokens)
  const fromToken = perpetuals.getToken(fromTokenAddress);
  const toToken = perpetuals.getToken(toTokenAddress);
  
  const shortCollateralToken = getTokenInfo(infoTokens, shortCollateralAddress);
  const fromTokenInfo = getTokenInfo(infoTokens, fromTokenAddress);
  const toTokenInfo = getTokenInfo(infoTokens, toTokenAddress);

  const fromBalance = fromTokenInfo ? fromTokenInfo.balance : bigNumberify(0);
  const toBalance = toTokenInfo ? toTokenInfo.balance : bigNumberify(0);

  const fromAmount = parseValue(fromValue, fromToken && fromToken.decimals);
  const toAmount = parseValue(toValue, toToken && toToken.decimals);

  const isPotentialWrap = (fromToken.isNative && toToken.isWrapped) || (fromToken.isWrapped && toToken.isNative);
  const isWrapOrUnwrap = mode === SWAP && isPotentialWrap;
  const needApproval =
    fromTokenAddress !== AddressZero &&
    tokenAllowance &&
    fromAmount &&
    fromAmount.gt(tokenAllowance) &&
    !isWrapOrUnwrap;
  console.log("needApproval? ", needApproval)
  const prevFromTokenAddress = usePrevious(fromTokenAddress);
  const prevNeedApproval = usePrevious(needApproval);
  const prevToTokenAddress = usePrevious(toTokenAddress);

  const fromUsdMin = getUsd(fromAmount, fromTokenAddress, false, infoTokens);
  const toUsdMax = getUsd(toAmount, toTokenAddress, true, infoTokens, type, triggerPriceUsd);

  const indexTokenAddress = toTokenAddress === AddressZero ? nativeTokenAddress : toTokenAddress;
  // const collateralTokenAddress = isLong
  //   ? indexTokenAddress
  //   : shortCollateralAddress;
  const collateralTokenAddress = shortCollateralAddress;
  const collateralToken = perpetuals.getToken(collateralTokenAddress);

  const [triggerRatioValue, setTriggerRatioValue] = useState("");
  const triggerRatioInverted = useMemo(() => {
    return isTriggerRatioInverted(fromTokenInfo, toTokenInfo);
  }, [toTokenInfo, fromTokenInfo]);
  const triggerRatio = useMemo(() => {
    if (!triggerRatioValue) {
      return bigNumberify(0);
    }
    let ratio = parseValue(triggerRatioValue, USD_DECIMALS);
    if (ratio.eq(0)) {
      return bigNumberify(0);
    }
    if (triggerRatioInverted) {
      ratio = PRECISION.mul(PRECISION).div(ratio);
    }
    return ratio;
  }, [triggerRatioValue, triggerRatioInverted]);

  const getTokenLabel = () => {
    if (isLong) {
      return "Long";
    }
    return "Short";
  };

  const leverageMarks = {
    // 0.1: {
    //   style: { color: '#b5b6b6', },
    //   label: '0.1x'
    // },
    1: {
      style: { color: '#b5b6b6', },
      label: '1x'
    },
    // 2: {
    //   style: { color: '#b5b6b6', },
    //   label: '2x'
    // },
    5: {
      style: { color: '#b5b6b6', },
      label: '5x'
    },
    10: {
      style: { color: '#b5b6b6', },
      label: '10x'
    },
    15: {
      style: { color: '#b5b6b6', },
      label: '15x'
    },
    20: {
      style: { color: '#b5b6b6', },
      label: '20x'
    },
    25: {
      style: { color: '#b5b6b6', },
      label: '25x'
    },
    30: {
      style: { color: '#b5b6b6', },
      label: '30x'
    }
  };

  const [leverageOption, setLeverageOption] = useLocalStorageSerializeKey([chainId, "Exchange-swap-leverage-option"], "2");
  useEffect(() => console.log("leverageOption ", leverageOption), [leverageOption])
  const [isLeverageSliderEnabled, setIsLeverageSliderEnabled] = useLocalStorageSerializeKey([chainId, "Exchange-swap-leverage-slider-enabled"], true);
  const hasLeverageOption = isLeverageSliderEnabled && !isNaN(parseFloat(leverageOption));

  useEffect(() => {
    if (
      fromToken &&
      fromTokenAddress === prevFromTokenAddress &&
      !needApproval &&
      prevNeedApproval &&
      isWaitingForApproval
    ) {
      setIsWaitingForApproval(false);
      helperToast.success(<div>{fromToken.symbol} approved!</div>);
    }
  }, [
    fromTokenAddress,
    prevFromTokenAddress,
    needApproval,
    prevNeedApproval,
    setIsWaitingForApproval,
    fromToken.symbol,
    isWaitingForApproval,
    fromToken
  ]);

  useEffect(() => {
    if (!toTokens.find(token => token.address === toTokenAddress)) {
      setToTokenAddress(mode, toTokens[0].address);
    }
  }, [mode, toTokens, toTokenAddress, setToTokenAddress]);

  useEffect(() => {
    if (active) {
      function onBlock() {
        console.log("onBlock, updateTokenAllowance");
        updateTokenAllowance(undefined, true);
      }
      library.on("block", onBlock);
      return () => {
        library.removeListener("block", onBlock);
      };
    }
  }, [active, library, updateTokenAllowance]);

  useEffect(() => {
    if (mode !== SHORT) {
      return;
    }
    if (toTokenAddress === prevToTokenAddress) {
      return;
    }
    for (let i = 0; i < stableTokens.length; i++) {
      const stableToken = stableTokens[i];
      const key = getPositionKey(
        stableToken.address,
        toTokenAddress,
        false,
        nativeTokenAddress
      );
      const position = positionsMap[key];
      if (position && position.size && position.size.gt(0)) {
        setShortCollateralAddress(position.collateralToken.address);
        return;
      }
    }
  }, [
    toTokenAddress,
    prevToTokenAddress,
    mode,
    positionsMap,
    stableTokens,
    nativeTokenAddress,
    shortCollateralAddress,
    setShortCollateralAddress
  ]);

  useEffect(() => {
    const updateLeverageAmounts = () => {
      if (!hasLeverageOption) {
        return;
      }
      if (anchorOnFromAmount) {
        if (!fromAmount) {
          setToValue("");
          return;
        }

        const toTokenInfo = getTokenInfo(infoTokens, toTokenAddress);
        if (
          toTokenInfo &&
          toTokenInfo.maxPrice &&
          fromUsdMin &&
          fromUsdMin.gt(0)
        ) {
          const leverageMultiplier = parseInt(
            leverageOption * BASIS_POINTS_DIVISOR
          );
          const toTokenPriceUsd =
            type !== MARKET && triggerPriceUsd && triggerPriceUsd.gt(0)
              ? triggerPriceUsd
              : toTokenInfo.maxPrice;

          const { feeBasisPoints } = getNextToAmount(
            chainId,
            fromAmount,
            fromTokenAddress,
            collateralTokenAddress,
            infoTokens,
            undefined,
            undefined,
            usdgSupply,
            totalTokenWeights
          );

          let fromUsdMinAfterFee = fromUsdMin;
          if (feeBasisPoints) {
            fromUsdMinAfterFee = fromUsdMin
              .mul(BASIS_POINTS_DIVISOR - feeBasisPoints)
              .div(BASIS_POINTS_DIVISOR);
          }

          const toNumerator = fromUsdMinAfterFee.mul(leverageMultiplier).mul(BASIS_POINTS_DIVISOR)
          const toDenominator = bigNumberify(MARGIN_FEE_BASIS_POINTS).mul(leverageMultiplier).add(bigNumberify(BASIS_POINTS_DIVISOR).mul(BASIS_POINTS_DIVISOR))

          const nextToUsd = toNumerator.div(toDenominator)

          const nextToAmount = nextToUsd
            .mul(expandDecimals(1, toToken.decimals))
            .div(toTokenPriceUsd);

          const nextToValue = formatAmountFree(
            nextToAmount,
            toToken.decimals,
            toToken.decimals
          );

          setToValue(nextToValue);
        }
        return;
      }

      if (!toAmount) {
        setFromValue("");
        return;
      }

      const fromTokenInfo = getTokenInfo(infoTokens, fromTokenAddress);
      if (
        fromTokenInfo &&
        fromTokenInfo.minPrice &&
        toUsdMax &&
        toUsdMax.gt(0)
      ) {
        const leverageMultiplier = parseInt(
          leverageOption * BASIS_POINTS_DIVISOR
        );

        const baseFromAmountUsd = toUsdMax
          .mul(BASIS_POINTS_DIVISOR)
          .div(leverageMultiplier);

        let fees = toUsdMax
          .mul(MARGIN_FEE_BASIS_POINTS)
          .div(BASIS_POINTS_DIVISOR);

        const { feeBasisPoints } = getNextToAmount(
          chainId,
          fromAmount,
          fromTokenAddress,
          collateralTokenAddress,
          infoTokens,
          undefined,
          undefined,
          usdgSupply,
          totalTokenWeights
        );

        if (feeBasisPoints) {
          const swapFees = baseFromAmountUsd
            .mul(feeBasisPoints)
            .div(BASIS_POINTS_DIVISOR);
          fees = fees.add(swapFees);
        }

        const nextFromUsd = baseFromAmountUsd.add(fees);

        const nextFromAmount = nextFromUsd
          .mul(expandDecimals(1, fromToken.decimals))
          .div(fromTokenInfo.minPrice);

        const nextFromValue = formatAmountFree(
          nextFromAmount,
          fromToken.decimals,
          fromToken.decimals
        );

        setFromValue(nextFromValue);
      }
    };

    if (isLong || isShort) {
      updateLeverageAmounts();
    }
  }, [
    mode,
    type,
    anchorOnFromAmount,
    fromAmount,
    toAmount,
    fromToken,
    toToken,
    fromTokenAddress,
    toTokenAddress,
    infoTokens,
    leverageOption,
    fromUsdMin,
    toUsdMax,
    triggerPriceUsd,
    triggerRatio,
    hasLeverageOption,
    usdgSupply,
    totalTokenWeights,
    chainId,
    collateralTokenAddress,
    indexTokenAddress
  ]);

  let entryMarkPrice;
  let exitMarkPrice;
  if (toTokenInfo) {
    entryMarkPrice =
      isLong ? toTokenInfo.maxPrice : toTokenInfo.minPrice;
    exitMarkPrice =
      isLong ? toTokenInfo.minPrice : toTokenInfo.maxPrice;
  }

  let leverage = bigNumberify(0);
  if (fromUsdMin && toUsdMax && fromUsdMin.gt(0)) {
    const fees = toUsdMax.mul(MARGIN_FEE_BASIS_POINTS).div(BASIS_POINTS_DIVISOR);
    if (fromUsdMin.sub(fees).gt(0)) {
      leverage = toUsdMax.mul(BASIS_POINTS_DIVISOR).div(fromUsdMin.sub(fees));
    }
  }

  let nextAveragePrice = type === MARKET ? entryMarkPrice : triggerPriceUsd;
  if (hasExistingPosition) {
    let nextDelta
    let nextHasProfit

    if (type === MARKET) {
      nextDelta = existingPosition.delta;
      nextHasProfit = existingPosition.hasProfit;
    } else {
      const data = calculatePositionDelta(
        triggerPriceUsd || bigNumberify(0),
        existingPosition
      );
      nextDelta = data.delta;
      nextHasProfit = data.hasProfit;
    }

    nextAveragePrice = getNextAveragePrice({
      size: existingPosition.size,
      sizeDelta: toUsdMax,
      hasProfit: nextHasProfit,
      delta: nextDelta,
      nextPrice: type === MARKET ? entryMarkPrice : triggerPriceUsd,
      isLong: mode === LONG
    });
  }

  let positionKey;
  if (isLong) {
    positionKey = getPositionKey(
      toTokenAddress,
      toTokenAddress,
      true,
      nativeTokenAddress
    );
  }
  if (isShort) {
    positionKey = getPositionKey(
      shortCollateralAddress,
      toTokenAddress,
      false,
      nativeTokenAddress
    );
  }

  const existingPosition = positionKey ? positionsMap[positionKey] : undefined;
  const hasExistingPosition = existingPosition && existingPosition.size && existingPosition.size.gt(0);

  const liquidationPrice = getLiquidationPrice({
    isLong: mode === LONG,
    size: hasExistingPosition ? existingPosition.size : bigNumberify(0),
    collateral: hasExistingPosition
      ? existingPosition.collateral
      : bigNumberify(0),
    averagePrice: nextAveragePrice,
    entryFundingRate: hasExistingPosition
      ? existingPosition.entryFundingRate
      : bigNumberify(0),
    cumulativeFundingRate: hasExistingPosition
      ? existingPosition.cumulativeFundingRate
      : bigNumberify(0),
    sizeDelta: toUsdMax,
    collateralDelta: fromUsdMin,
    increaseCollateral: true,
    increaseSize: true
  });

  const existingLiquidationPrice = existingPosition
    ? getLiquidationPrice(existingPosition)
    : undefined;
  let displayLiquidationPrice = liquidationPrice
    ? liquidationPrice
    : existingLiquidationPrice;

  if (hasExistingPosition) {
    const collateralDelta = fromUsdMin ? fromUsdMin : bigNumberify(0);
    const sizeDelta = toUsdMax ? toUsdMax : bigNumberify(0);
    leverage = getLeverage({
      size: existingPosition.size,
      sizeDelta,
      collateral: existingPosition.collateral,
      collateralDelta,
      increaseCollateral: true,
      entryFundingRate: existingPosition.entryFundingRate,
      cumulativeFundingRate: existingPosition.cumulativeFundingRate,
      increaseSize: true,
      hasProfit: existingPosition.hasProfit,
      delta: existingPosition.delta,
      includeDelta: savedIsPnlInLeverage
    });
  } else if (hasLeverageOption) {
    leverage = bigNumberify(parseInt(leverageOption * BASIS_POINTS_DIVISOR));
  }

  const selectFromToken = symbol => {
    const token = getTokenfromSymbol(tokens, symbol)
    setFromTokenAddress(mode, token.address);
    console.log("update from token: ", symbol, token, mode);
    setActiveToken0((tokens.filter(ele => ele.symbol === symbol))[0]);
    setIsWaitingForApproval(false);
    if (isShort) {
      console.log("is short and changed short collateral token to ", token.address)
      setShortCollateralAddress(token.address);
    }
  };

  const getToUsdAmount = () => {

  }

  useEffect(() => {
    console.log("update from token 1: ", fromTokenAddress)
  }, [fromTokenAddress])

  useEffect(() => {
    const fromToken = getTokenfromSymbol(tokens, activeToken0.symbol)
    const toToken = getTokenfromSymbol(tokens, activeToken1.symbol)

    setFromTokenAddress(mode, fromToken.address);
    setToTokenAddress(mode, toToken.address);

  }, [activeToken0, activeToken1])

  console.log("show this")
  const selectToToken = symbol => {
    const token = getTokenfromSymbol(tokens, symbol)
    console.log("selectToToken symbol and address", symbol, token.address)
    setToTokenAddress(mode, token.address);
    setActiveToken1((tokens.filter(ele => ele.symbol === symbol))[0]);
  };

  const onFromValueChange = e => {
    setAnchorOnFromAmount(true);
    setFromValue(e.target.value);
  };

  const onToValueChange = e => {
    setAnchorOnFromAmount(false);
    setToValue(e.target.value);
  };

  const createIncreaseOrder = () => {
    console.log("inside createIncreaseOrder")
    let path = [fromTokenAddress];

    if (path[0] === USDG_ADDRESS) {
      if (isLong) {
        const stableToken = getMostAbundantStableToken(chainId, infoTokens);
        path.push(stableToken.address);
      } else {
        path.push(shortCollateralAddress);
      }
    }

    const minOut = 0;
    const indexToken = perpetuals.getToken(indexTokenAddress);
    const successMsg = `
      Created limit order for ${indexToken.symbol} ${isLong ? "Long" : "Short"}: ${formatAmount(toUsdMax, USD_DECIMALS, 2)} USD!`;
    return Api.createIncreaseOrder(
      chainId,
      library,
      nativeTokenAddress,
      path,
      fromAmount,
      indexTokenAddress,
      minOut,
      toUsdMax,
      collateralTokenAddress,
      isLong,
      triggerPriceUsd,
      {
        pendingTxns,
        setPendingTxns,
        sentMsg: "Limit order submitted!",
        successMsg,
        failMsg: "Limit order creation failed.",
      }
    )
      .then(() => {
        setIsConfirming(false);
      })
      .finally(() => {
        setIsSubmitting(false);
        setIsPendingConfirmation(false);
      });
  };

  // refers to gmx 9c6b4a8 commit
  const increasePosition = async () => {
    console.log("try to increasePosition");
    setIsSubmitting(true);
    const tokenAddress0 = fromTokenAddress === AddressZero ? nativeTokenAddress : fromTokenAddress;
    const indexTokenAddress = toTokenAddress === AddressZero ? nativeTokenAddress : toTokenAddress;
    let path = [indexTokenAddress]; // assume long
    if (toTokenAddress !== fromTokenAddress) {
      path = [tokenAddress0];
    }

    if (fromTokenAddress === AddressZero && toTokenAddress === nativeTokenAddress) {
      path = [nativeTokenAddress];
    }

    if (fromTokenAddress === nativeTokenAddress && toTokenAddress === AddressZero) {
      path = [nativeTokenAddress];
    }

    if (isShort) {
      path = [shortCollateralAddress];
      if (tokenAddress0 !== shortCollateralAddress) {
        path = [tokenAddress0, shortCollateralAddress];
      }
    }

    const refPrice = isLong ? toTokenInfo.maxPrice : toTokenInfo.minPrice;
    const priceBasisPoints = isLong ? BASIS_POINTS_DIVISOR + allowedSlippage : BASIS_POINTS_DIVISOR - allowedSlippage;
    const priceLimit = refPrice.mul(priceBasisPoints).div(BASIS_POINTS_DIVISOR);

    const boundedFromAmount = fromAmount ? fromAmount : bigNumberify(0);

    if (fromAmount && fromAmount.gt(0) && fromTokenAddress === USDG_ADDRESS && isLong) {
      const { amount: nextToAmount, path: multiPath } = getNextToAmount(
        chainId,
        fromAmount,
        fromTokenAddress,
        indexTokenAddress,
        infoTokens,
        undefined,
        undefined,
        usdgSupply,
        totalTokenWeights
      );
      if (nextToAmount.eq(0)) {
        helperToast.error("Insufficient liquidity");
        return;
      }
      if (multiPath) {
        path = replaceNativeTokenAddress(multiPath);
      }
    }

    let params = [
      path, // _path
      indexTokenAddress, // _indexToken
      boundedFromAmount, // _amountIn
      0, // _minOut
      toUsdMax, // _sizeDelta
      isLong, // _isLong
      priceLimit, // _acceptablePrice
    ];

    let method = "increasePosition";	
    let value = bigNumberify(0);	
    if (fromTokenAddress === AddressZero) {	
      method = "increasePositionETH";	
      value = boundedFromAmount;	
      params = [path, indexTokenAddress, 0, toUsdMax, isLong, priceLimit];
    }

    if (shouldRaiseGasError(getTokenInfo(infoTokens, fromTokenAddress), fromAmount)) {
      setIsSubmitting(false);
      setIsPendingConfirmation(false);
      helperToast.error(
        `Leave at least ${formatAmount(DUST_BNB, 18, 3)} ${getConstant(chainId, "nativeTokenSymbol")} for gas`
      );
      return;
    }

    console.log("increasePosition 2: ", params);
    const contract = new ethers.Contract(routerAddress, Router.abi, library.getSigner());
    const indexToken = getTokenInfo(infoTokens, indexTokenAddress);
    const tokenSymbol = indexToken.isWrapped ? getConstant(chainId, "nativeTokenSymbol") : indexToken.symbol;
    const successMsg = `Requested increase of ${tokenSymbol} ${isLong ? "Long" : "Short"} by ${formatAmount(
      toUsdMax,
      USD_DECIMALS,
      2
    )} USD.`;
    Api.callContract(chainId, contract, method, params, {
      value,
      setPendingTxns,
      sentMsg: `${isLong ? "Long" : "Short"} submitted.`,
      failMsg: `${isLong ? "Long" : "Short"} failed.`,
      successMsg,
    })
      .then(async () => {
        setIsConfirming(false);
        
      })
      .finally(() => {
        setIsConfirming(false);
        setIsSubmitting(false);
        setIsPendingConfirmation(false);
      });
  };

  const onConfirmationClick = () => {
    if (!account) {
      connectWalletByLocalStorage()
      return;
    }

    if (needOrderBookApproval) {
      approveOrderBook();
      // return;
    }

    setIsPendingConfirmation(true);

    if (type === LIMIT) {
      createIncreaseOrder();
      return;
    }

    increasePosition();
  };

  const perpetualMode = [LONG, SHORT, POOL];
  const perpetualType = [MARKET, LIMIT]

  // LONG or SHORT or POOL
  const modeSelect = (input) => {
    setMode(input);
    onChangeMode(input);
  }

  // MARKET or LIMIT
  const typeSelect = input => {
    setType(input);
  }

  const switchTokens = () => {
    if (fromAmount && toAmount) {
      if (anchorOnFromAmount) {
        setToValue(formatAmountFree(fromAmount, fromToken.decimals, 8));
      } else {
        setFromValue(formatAmountFree(toAmount, toToken.decimals, 8));
      }
      setAnchorOnFromAmount(!anchorOnFromAmount);
    }
    setIsWaitingForApproval(false);

    setFromTokenAddress(mode, toTokenAddress)
    setToTokenAddress(mode, fromTokenAddress)
  };

  const getLeverageError = useCallback(() => {
    if (!toAmount || toAmount.eq(0)) {
      return ["Enter an amount"];
    }

    let toTokenInfo = getTokenInfo(infoTokens, toTokenAddress);
    if (toTokenInfo && toTokenInfo.isStable) {
      return [
        `${isLong ? "Longing" : "Shorting"} ${toTokenInfo.symbol
        } not supported`
      ];
    }

    const fromTokenInfo = getTokenInfo(infoTokens, fromTokenAddress);
    if (
      fromTokenInfo &&
      fromTokenInfo.balance &&
      fromAmount &&
      fromAmount.gt(fromTokenInfo.balance)
    ) {
      return [`Insufficient ${fromTokenInfo.symbol} balance`];
    }

    if (leverage && leverage.eq(0)) {
      return ["Enter an amount"];
    }
    if (type !== MARKET && (!triggerPriceValue || triggerPriceUsd.eq(0))) {
      return ["Enter a price"];
    }

    if (
      !hasExistingPosition &&
      fromUsdMin &&
      fromUsdMin.lt(expandDecimals(10, USD_DECIMALS))
    ) {
      return ["Min order: 10 USD"];
    }

    if (leverage && leverage.lt(0.1 * BASIS_POINTS_DIVISOR)) {
      return ["Min leverage: 0.1x"];
    }

    if (leverage && leverage.gt(30.5 * BASIS_POINTS_DIVISOR)) {
      return ["Max leverage: 30.5x"];
    }

    if (type !== MARKET && entryMarkPrice && triggerPriceUsd) {
      if (isLong && entryMarkPrice.lt(triggerPriceUsd)) {
        return ["Price above Mark Price"];
      }
      if (mode !== LONG && entryMarkPrice.gt(triggerPriceUsd)) {
        return ["Price below Mark Price"];
      }
    }

    if (isLong) {
      
      if (fromTokenAddress !== toTokenAddress) {
        const { amount: swapAmount } = getNextToAmount(
          chainId,
          toAmount,
          toTokenAddress,
          fromTokenAddress,
          infoTokens,
          undefined,
          undefined,
          usdgSupply,
          totalTokenWeights
        );
        
        // requiredAmount = requiredAmount.add(swapAmount);
        let requiredAmount = fromAmount.mul(parseInt(leverageOption*100)).div(100);
        if (
          toToken &&
          toTokenAddress !== USDG_ADDRESS &&
          fromTokenInfo.availableAmount &&
          requiredAmount.gt(fromTokenInfo.availableAmount)
        ) {
          return ["Insufficient liquidity"];
        }

        if (
          toTokenInfo.poolAmount &&
          toTokenInfo.bufferAmount &&
          toTokenInfo.bufferAmount.gt(toTokenInfo.poolAmount.sub(swapAmount))
        ) {
          return ["Insufficient liquidity", true, "BUFFER"];
        }

        if (
          fromUsdMin &&
          fromTokenInfo.maxUsdgAmount &&
          fromTokenInfo.maxUsdgAmount.gt(0) &&
          fromTokenInfo.minPrice &&
          fromTokenInfo.usdgAmount
        ) {
          const usdgFromAmount = adjustForDecimals(
            fromUsdMin,
            USD_DECIMALS,
            USDG_DECIMALS
          );
          const nextUsdgAmount = fromTokenInfo.usdgAmount.add(usdgFromAmount);
          if (nextUsdgAmount.gt(fromTokenInfo.maxUsdgAmount)) {
            return [
              `${fromTokenInfo.symbol} pool exceeded, try different token`,
              true,
              "MAX_USDG"
            ];
          }
        }
      }
    }

    if (isShort) {
      let stableTokenAmount = bigNumberify(0);
      if (
        fromTokenAddress !== shortCollateralAddress &&
        fromAmount &&
        fromAmount.gt(0)
      ) {
        const { amount: nextToAmount } = getNextToAmount(
          chainId,
          fromAmount,
          fromTokenAddress,
          shortCollateralAddress,
          infoTokens,
          undefined,
          undefined,
          usdgSupply,
          totalTokenWeights
        );
        stableTokenAmount = nextToAmount;
        if (stableTokenAmount.gt(shortCollateralToken.availableAmount)) {
          return [`Insufficient liquidity, change "Profits In" 1`];
        }

        if (
          shortCollateralToken.bufferAmount &&
          shortCollateralToken.poolAmount &&
          shortCollateralToken.bufferAmount.gt(
            shortCollateralToken.poolAmount.sub(stableTokenAmount)
          )
        ) {
          // suggest swapping to collateralToken
          return [
            `Insufficient liquidity, change "Profits In" 2`,
            true,
            "BUFFER"
          ];
        }

        if (
          fromTokenInfo.maxUsdgAmount &&
          fromTokenInfo.maxUsdgAmount.gt(0) &&
          fromTokenInfo.minPrice &&
          fromTokenInfo.usdgAmount
        ) {
          const usdgFromAmount = adjustForDecimals(
            fromUsdMin,
            USD_DECIMALS,
            USDG_DECIMALS
          );
          const nextUsdgAmount = fromTokenInfo.usdgAmount.add(usdgFromAmount);
          if (nextUsdgAmount.gt(fromTokenInfo.maxUsdgAmount)) {
            return [
              `${fromTokenInfo.symbol} pool exceeded, try different token`,
              true,
              "MAX_USDG"
            ];
          }
        }
      }
      if (
        !shortCollateralToken ||
        !fromTokenInfo ||
        !toTokenInfo ||
        !toTokenInfo.maxPrice ||
        !shortCollateralToken.availableAmount
      ) {
        return ["Fetching token info..."];
      }

      const sizeUsd = toAmount
        .mul(toTokenInfo.maxPrice)
        .div(expandDecimals(1, toTokenInfo.decimals));
      const sizeTokens = sizeUsd
        .mul(expandDecimals(1, shortCollateralToken.decimals))
        .div(shortCollateralToken.minPrice);
      // no more this short limits
      // if (toTokenInfo.maxAvailableShort && toTokenInfo.maxAvailableShort.gt(0) && sizeUsd.gt(toTokenInfo.maxAvailableShort)) {
      //   return [`Max ${toTokenInfo.symbol} short exceeded`]
      // }
      console.log("DEBUG HERE3:", stableTokenAmount, sizeTokens.toString(), shortCollateralToken)
      stableTokenAmount = stableTokenAmount.add(sizeTokens)
      if (stableTokenAmount.gt(shortCollateralToken.availableAmount)) {
        return [`Insufficient liquidity, change "Profits In" 3`];
      }
    }

    return [false];
  }, [
    chainId,
    fromAmount,
    fromTokenAddress,
    fromUsdMin,
    // hasExistingPosition,
    infoTokens,
    leverage,
    shortCollateralAddress,
    shortCollateralToken,
    toAmount,
    toToken,
    toTokenAddress,
    totalTokenWeights,
    triggerPriceUsd,
    triggerPriceValue,
    usdgSupply,
    entryMarkPrice
  ]);

  const isPrimaryEnabled = () => {
    if (!active) { return true }
    if (mode !== POOL) {
      const [error, modal] = getLeverageError()
      if (error && !modal) { return false }
    }
    if (needOrderBookApproval && isWaitingForPluginApproval) { return false }
    if ((needApproval && isWaitingForApproval) || isApproving) { return false }
    if (isApproving) { return false }
    if (isSubmitting) { return false }
    return true;
  };

  const getPrimaryText = () => {
    if (!active) { return "Connect Wallet"; }
    if (mode !== POOL) {
      const [error, modal] = getLeverageError()
      if (error && !modal) { return error }
    }

    if (needApproval && isWaitingForApproval) {
      return "Waiting for Approval";
    }
    if (isApproving) {
      return `Approving ${fromToken.symbol}...`;
    }
    if (needApproval) {
      return `Approve ${fromToken.symbol}`;
    }

    if (needOrderBookApproval && isWaitingForPluginApproval) {
      return "Enabling Orders...";
    }
    if (isPluginApproving) {
      return "Enabling Orders...";
    }
    if (needOrderBookApproval) {
      return "Enable Orders";
    }

    if (type !== MARKET)
      return `Create ${type} Order`;

    if (isLong) {
      const indexTokenInfo = getTokenInfo(infoTokens, toTokenAddress);
      if (indexTokenInfo && indexTokenInfo.minPrice) {
        const { amount: nextToAmount } = getNextToAmount(
          chainId,
          fromAmount,
          fromTokenAddress,
          indexTokenAddress,
          infoTokens,
          undefined,
          undefined,
          usdgSupply,
          totalTokenWeights
        );
        const nextToAmountUsd = nextToAmount
          .mul(indexTokenInfo.minPrice)
          .div(expandDecimals(1, indexTokenInfo.decimals));
        if (
          fromTokenAddress === USDG_ADDRESS &&
          nextToAmountUsd.lt(fromUsdMin.mul(98).div(100))
        ) {
          return "High USDG Slippage, Long Anyway";
        }
      }
      return `Long ${toToken.symbol}`;
    }

    return `Short ${toToken.symbol}`;
  };

  function approveFromToken() {
    approveTokens({
      setIsApproving,
      library,
      tokenAddress: fromToken.address,
      spender: routerAddress,
      chainId,
      onApproveSubmitted: () => {
        setIsWaitingForApproval(true);
      },
      infoTokens,
      getTokenInfo,
      pendingTxns
    });
  }

  const onClickPrimary = () => {
    if (!account) {
      connectWalletByLocalStorage()
      return;
    }

    // TODO terms and condition pop up, we dont have it now
    if (needOrderBookApproval) {
      setOrdersToaOpen(true);
      // return;
    }

    if (needApproval) {
      approveFromToken();
      return;
    }

    if (mode !== POOL) {
      const [, modal, errorCode] = getLeverageError()
      if (modal) {
        setModalError(errorCode);
        return;
      }
    }

    setIsConfirming(true);
  };

  let hasZeroBorrowFee = false;
  let borrowFeeText;
  if (isLong && toTokenInfo && toTokenInfo.fundingRate) {
    borrowFeeText = formatAmount(toTokenInfo.fundingRate, 4, 4) + "% / 1h";
  }
  if (isShort && shortCollateralToken && shortCollateralToken.fundingRate) {
    borrowFeeText =
      formatAmount(shortCollateralToken.fundingRate, 4, 4) + "% / 1h";
  }

  let fees;
  let feesUsd;
  let feeBps;
  let swapFees;
  let positionFee;
  if (mode === SWAP) {
    if (fromAmount) {
      const { feeBasisPoints } = getNextToAmount(
        chainId,
        fromAmount,
        fromTokenAddress,
        toTokenAddress,
        infoTokens,
        undefined,
        undefined,
        usdgSupply,
        totalTokenWeights
      );
      if (feeBasisPoints !== undefined) {
        fees = fromAmount.mul(feeBasisPoints).div(BASIS_POINTS_DIVISOR);
        const feeTokenPrice =
          fromTokenInfo.address === USDG_ADDRESS
            ? expandDecimals(1, USD_DECIMALS)
            : fromTokenInfo.maxPrice;
        feesUsd = fees
          .mul(feeTokenPrice)
          .div(expandDecimals(1, fromTokenInfo.decimals));
      }
      feeBps = feeBasisPoints;
    }
  } else if (toUsdMax) {
    positionFee = toUsdMax
      .mul(MARGIN_FEE_BASIS_POINTS)
      .div(BASIS_POINTS_DIVISOR);
    feesUsd = positionFee;

    const { feeBasisPoints } = getNextToAmount(
      chainId,
      fromAmount,
      fromTokenAddress,
      collateralTokenAddress,
      infoTokens,
      undefined,
      undefined,
      usdgSupply,
      totalTokenWeights
    );
    if (feeBasisPoints) {
      swapFees = fromUsdMin.mul(feeBasisPoints).div(BASIS_POINTS_DIVISOR);
      feesUsd = feesUsd.add(swapFees);
    }
    feeBps = feeBasisPoints;
  }

  let payBalance = "$0.00"
  let receiveBalance = "$0.00"
  if (fromUsdMin) {
    payBalance = `$${formatAmount(fromUsdMin, USD_DECIMALS, 2, true, 0)}`
  }
  if (toUsdMax) {
    receiveBalance = `$${formatAmount(toUsdMax, USD_DECIMALS, 2, true)}`
  }

  // Glp Swap Component
  // const tokensForBalanceAndSupplyQuery = [stakedGlpTrackerAddress, usdgAddress]
  // const { data: balancesAndSupplies, mutate: updateBalancesAndSupplies } = useSWR([chainId, readerAddress, "getTokenBalancesWithSupplies", account || PLACEHOLDER_ACCOUNT], {
  //   fetcher: fetcher(library, ReaderV2, [tokensForBalanceAndSupplyQuery]),
  // })
  // const { data: aums, mutate: updateAums } = useSWR([chainId, glpManagerAddress, "getAums"], {
  //   fetcher: fetcher(library, GlpManager),
  // })
  const { data: glpBalance, mutate: updateGlpBalance } = useSWR([chainId, glpAddress, "balanceOf", account || PLACEHOLDER_ACCOUNT], {
    fetcher: fetcher(library, Glp),
  })
  // const { data: glpBalance, mutate: updateGlpBalance } = useSWR([chainId, feeGlpTrackerAddress, "stakedAmounts", account || PLACEHOLDER_ACCOUNT], {
  //   fetcher: fetcher(library, RewardTracker),
  // })
  // const { data: reservedAmount, mutate: updateReservedAmount } = useSWR([chainId, glpVesterAddress, "pairAmounts", account || PLACEHOLDER_ACCOUNT], {
  //   fetcher: fetcher(library, Vester),
  // })
  // const { gmxPrice, mutate: updateGmxPrice } = useGmxPrice(chainId, { arbitrum: library }, active)
  // const rewardTrackersForStakingInfo = [ stakedGlpTrackerAddress, feeGlpTrackerAddress ]
  // const { data: stakingInfo, mutate: updateStakingInfo } = useSWR([chainId, rewardReaderAddress, "getStakingInfo", account || PLACEHOLDER_ACCOUNT], {
  //   fetcher: fetcher(library, RewardReader, [rewardTrackersForStakingInfo]),
  // })

  const { data: glpSupply, mutate: updateGlpSupply } = useSWR([chainId, glpAddress, "totalSupply"], {
    fetcher: fetcher(library, Glp),
  })
  // const glpSupply = balancesAndSupplies ? balancesAndSupplies[1] : bigNumberify(0)
  // const glp_usdgSupply = balancesAndSupplies ? balancesAndSupplies[3] : bigNumberify(0)
  // let aum
  // if (aums && aums.length > 0) {
  //   aum = isBuying ? aums[0] : aums[1]
  // }
  const { data: aumInUsdg, mutate: updateAumInUsdg } = useSWR([chainId, glpManagerAddress, "getAumInUsda", true], {
    fetcher: fetcher(library, GlpManager),
  })
  const glpPrice = (aumInUsdg && aumInUsdg.gt(0) && glpSupply && glpSupply.gt(0) ) ? aumInUsdg.mul(expandDecimals(1, GLP_DECIMALS)).div(glpSupply) : expandDecimals(1, USD_DECIMALS)
  // const glpPrice = (aum && aum.gt(0) && glpSupply.gt(0)) ? aum.mul(expandDecimals(1, GLP_DECIMALS)).div(glpSupply) : expandDecimals(1, USD_DECIMALS)
  let glpBalanceUsd
  if (glpBalance) {
    glpBalanceUsd = glpBalance.mul(glpPrice).div(expandDecimals(1, GLP_DECIMALS))
  }
  const glpSupplyUsd = glpSupply ? glpSupply.mul(glpPrice).div(expandDecimals(1, GLP_DECIMALS)) : bigNumberify(0)
  const glp_infoTokens = getInfoTokens(tokens, tokenBalances, whitelistedTokens, vaultTokenInfo, undefined)

  return (
    <div className={styles.mainContent}>
      <AcyPerpetualCard style={{ backgroundColor: 'transparent' }}>
        <div className={styles.modeSelector}>
          <PerpetualTabs
            option={mode}
            options={perpetualMode}
            onChange={modeSelect}
          />
        </div>

        {mode !== POOL ?
          <>
            <div className={styles.typeSelector}>
              <PerpetualTabs
                option={type}
                options={perpetualType}
                type="inline"
                onChange={typeSelect}
                style={{height:'30px'}}
              />
            </div>

            <BuyInputSection
              token={fromToken}
              tokenlist={tokens.filter(token => !token.isWrapped)}
              topLeftLabel="Pay"
              balance={payBalance}
              topRightLabel='Balance: '
              tokenBalance={formatAmount(fromBalance, fromToken.decimals, 4, true)}
              inputValue={fromValue}
              onInputValueChange={onFromValueChange}
              onSelectToken={selectFromToken}
            />

            {/* <div className={styles.arrow} onClick={switchTokens}>
              <Icon style={{ fontSize: '16px' }} type="arrow-down" />
            </div> */}

            <BuyInputSection
              token={toToken}
              tokenlist={toTokens}
              topLeftLabel={getTokenLabel()}
              balance={receiveBalance}
              // topRightLabel={leverageLabel}
              // tokenBalance={leverageValue}
              inputValue={toValue}
              onInputValueChange={onToValueChange}
              onSelectToken={selectToToken}
            />

            {type === LIMIT &&
              <div className={styles.priceBox}>
                <PriceBox
                  priceValue={triggerPriceValue}
                  onChange={onTriggerPriceChange}
                  markOnClick={() => {
                    setTriggerPriceValue(
                      formatAmountFree(entryMarkPrice, USD_DECIMALS, 2)
                    );
                  }}
                  mark={formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)}
                />
              </div>
            }

            {/* Leverage Slider */}
            {(isLong || isShort) &&
              <AcyDescriptions>
                <div className={styles.leverageContainer}>
                  <div className={styles.slippageContainer}>
                    <div className={styles.leverageLabel}>
                      <span>Leverage</span>
                      {isLeverageSliderEnabled &&
                        <div className={styles.leverageInputContainer}>
                          <button
                            className={styles.leverageButton}
                            onClick={() => {
                              if (leverageOption > 0.1) {
                                setLeverageOption((parseFloat(leverageOption) - 0.1).toFixed(1))
                              }
                            }}
                          >
                            <span> - </span>
                          </button>
                          <input
                            type="number"
                            min={0.1}
                            max={30.5}
                            value={leverageOption}
                            onChange={e => {
                              let val = parseFloat(e.target.value.replace(/^(-)*(\d+)\.(\d).*$/, '$1$2.$3')).toFixed(1)
                              if (val >= 0.1 && val <= 30.5) {
                                setLeverageOption(val)
                              }
                            }}
                            className={styles.leverageInput}
                          />
                          <button
                            className={styles.leverageButton}
                            onClick={() => {
                              if (leverageOption < 30.5) {
                                setLeverageOption((parseFloat(leverageOption) + 0.1).toFixed(1))
                              }
                            }}
                          >
                            <span> + </span>
                          </button>
                        </div>
                      }
                    </div>
                    {/* <div className={styles.checkbox}>
                      <StyledCheckbox
                        checked={isLeverageSliderEnabled}
                        onChange={() => {
                          setIsLeverageSliderEnabled(!isLeverageSliderEnabled)
                        }}
                      />
                    </div> */}
                  </div>
                  {isLeverageSliderEnabled &&
                    <span className={styles.leverageSlider}>
                      <StyledSlider
                        min={0.1}
                        max={30.5}
                        step={0.1}
                        marks={leverageMarks}
                        value={leverageOption}
                        onChange={value => setLeverageOption(value)}
                        defaultValue={leverageOption}
                        style={{ color: 'red' }}
                      />
                    </span>
                  }
                </div>
              </AcyDescriptions>
            }

            <div className={styles.centerButton}>
              <AcyPerpetualButton
                // <AcyButton
                style={{ marginTop: '25px' }}
                onClick={onClickPrimary}
                disabled={!isPrimaryEnabled()}
              >
                {getPrimaryText()}
              </AcyPerpetualButton>
              {/* </AcyButton> */}
            </div>
          </> :
          <>
            <GlpSwapBox
              isBuying={isBuying}
              setIsBuying={setIsBuying}
              swapTokenAddress={swapTokenAddress}
              setSwapTokenAddress={setSwapTokenAddress}
              isWaitingForApproval={glp_isWaitingForApproval}
              setIsWaitingForApproval={glp_setIsWaitingForApproval}
              setPendingTxns={setPendingTxns}
            />
          </>
        }

      </AcyPerpetualCard>

      {/* Long/Short Detail card  */}
      {(isLong || isShort) &&
        <>
          <AcyPerpetualCard style={{ backgroundColor: 'transparent', padding: '10px' }}>

            {/* Profits In */}
            {isLong && (
              <div className={styles.detailCard}>
                <div className={styles.label}>Profits In</div>
                <div className={styles.value}>{fromToken.symbol}</div>
              </div>
            )}
            {isShort && (
              <div className={styles.detailCard}>
                <div className={styles.label}>Profits In</div>
                <div className={styles.TooltipHandle}>
                  <span>{shortCollateralToken.symbol}</span>
                </div>
              </div>
            )}

            {/* Leverage */}
            <div className={styles.detailCard}>
              <div className={styles.label}>Leverage</div>
              <div className={styles.value}>
                {hasExistingPosition &&
                  toAmount &&
                  toAmount.gt(0) &&
                  `${formatAmount(existingPosition.leverage, 4, 2)}x →`
                }
                {toAmount &&
                  leverage &&
                  leverage.gt(0) &&
                  `${formatAmount(leverage, 4, 2)}x`}
                {!toAmount && leverage && leverage.gt(0) && `-`}
                {leverage && leverage.eq(0) && `-`}
              </div>
            </div>

            {/* Entry Price */}
            <div className={styles.detailCard}>
              <div className={styles.label}>Entry Price</div>
              <div className={styles.value}>
                {hasExistingPosition &&
                  toAmount &&
                  toAmount.gt(0) &&
                  `$${formatAmount(existingPosition.averagePrice, USD_DECIMALS, 2, true)} →`
                }
                {nextAveragePrice &&
                  `$${formatAmount(nextAveragePrice, USD_DECIMALS, 2, true)}`}
                {!nextAveragePrice && `-`}
              </div>
            </div>

            {/* Liq. Price */}
            <div className={styles.detailCard}>
              <div className={styles.label}>Liq. Price</div>
              <div className={styles.value}>
                {hasExistingPosition &&
                  toAmount &&
                  toAmount.gt(0) &&
                  `$${formatAmount(existingLiquidationPrice, USD_DECIMALS, 2, true)} →`
                }
                {toAmount && displayLiquidationPrice &&
                  `$${formatAmount(displayLiquidationPrice, USD_DECIMALS, 2, true)}`
                }
                {!toAmount && displayLiquidationPrice && `-`}
                {!displayLiquidationPrice && `-`}
              </div>
            </div>

            {/* Fees */}
            <div className={styles.detailCard}>
              <div className={styles.label}>Fees</div>
              <div className={styles.value}>
                {!feesUsd && "-"}
                {feesUsd &&
                  <Tooltip
                    placement='bottomLeft'
                    color='#b5b5b6'
                    mouseEnterDelay={0.5}
                    title={() => {
                      return (
                        <>
                          {swapFees && (
                            <div>
                              {collateralToken.symbol} is required for
                              collateral.
                              <br /><br />
                              Swap {fromToken.symbol} to{" "}
                              {collateralToken.symbol} Fee: $
                              {formatAmount(swapFees, USD_DECIMALS, 2, true)}
                              <br /><br />
                            </div>
                          )}
                          <div>
                            Position Fee (0.08% of position size): $
                            {formatAmount(positionFee, USD_DECIMALS, 2, true)}
                          </div>
                        </>
                      )
                    }}
                  >
                    <div className={styles.TooltipHandle}>
                      ${formatAmount(feesUsd, USD_DECIMALS, 2, true)}
                    </div>
                  </Tooltip>
                }
              </div>
            </div>

            {/* Entry Price */}
            <div className={styles.detailCard}>
              <div className={styles.label}>Entry Price</div>
              <Tooltip
                placement='bottomLeft'
                color='#b5b5b6'
                mouseEnterDelay={0.5}
                title={() => {
                  return (
                    <>
                      The position will be opened at{" "}
                      {formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)} USD
                      with a max slippage of{" "}
                      {parseFloat(savedSlippageAmount / 100.0).toFixed(2)}%.
                      <br /><br />
                      The slippage amount can be configured under Settings,
                      found by clicking on your address at the top right of the
                      page after connecting your wallet.
                      <br /><br />
                      <a href="https://gmxio.gitbook.io/gmx/trading#opening-a-position" target="_blank" rel="noopener noreferrer">
                        More Info
                      </a>
                    </>
                  )
                }}
              >
                <div className={styles.TooltipHandle}>
                  {`${formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)} USD`}
                </div>
              </Tooltip>
            </div>

            {/* Exit Price */}
            <div className={styles.detailCard}>
              <div className={styles.label}>Exit Price</div>
              <Tooltip
                placement='bottomLeft'
                color='#b5b5b6'
                mouseEnterDelay={0.5}
                title={() => {
                  return (
                    <>
                      If you have an existing position, the position will be
                      closed at{" "}
                      {formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)} USD.
                      <br /><br />
                      This exit price will change with the price of the asset.
                      <br /><br />
                      <a href="https://gmxio.gitbook.io/gmx/trading#opening-a-position" target="_blank" rel="noopener noreferrer">
                        More Info
                      </a>
                    </>
                  )
                }}
              >
                <div className={styles.TooltipHandle}>
                  {`${formatAmount(exitMarkPrice, USD_DECIMALS, 2, true)} USD`}
                </div>
              </Tooltip>
            </div>

            {/* Borrow Fee */}
            <div className={styles.detailCard}>
              <div className={styles.label}>Borrow Fee</div>
              <Tooltip
                placement='bottomLeft'
                color='#b5b5b6'
                mouseEnterDelay={0.5}
                title={() => {
                  return (
                    <>
                      {hasZeroBorrowFee && (
                        <div>
                          {isLong &&
                            "There are more shorts than longs, borrow fees for longing is currently zero"}
                          {isShort &&
                            "There are more longs than shorts, borrow fees for shorting is currently zero"}
                        </div>
                      )}
                      {!hasZeroBorrowFee && (
                        <div>
                          The borrow fee is calculated as (assets borrowed) /
                          (total assets in pool) * 0.01% per hour.
                          <br /><br />
                          {isShort &&
                            `You can change the "Profits In" token above to find lower fees`}
                        </div>
                      )}
                      <br />
                      <a href="https://gmxio.gitbook.io/gmx/trading#opening-a-position" target="_blank" rel="noopener noreferrer">
                        More Info
                      </a>
                    </>
                  )
                }}
              >
                <div className={styles.TooltipHandle}>
                  {borrowFeeText}
                </div>
              </Tooltip>
            </div>

            {/* Available Liquidity */}
            {isShort && toTokenInfo.maxAvailableShort && toTokenInfo.maxAvailableShort.gt(0) &&
              <div className={styles.detailCard}>
                <div className={styles.label}>Available Liquidity</div>
                <Tooltip
                  placement='bottomLeft'
                  color='#b5b5b6'
                  mouseEnterDelay={0.5}
                  title={() => {
                    return (
                      <>
                        Max {toTokenInfo.symbol} short capacity: ${formatAmount(toTokenInfo.maxGlobalShortSize, USD_DECIMALS, 2, true)}
                        <br /><br />
                        Current {toTokenInfo.symbol} shorts: ${formatAmount(toTokenInfo.globalShortSize, USD_DECIMALS, 2, true)}
                        <br />
                      </>
                    )
                  }}
                >
                  <div className={styles.TooltipHandle}>
                    {formatAmount(toTokenInfo.maxAvailableShort, USD_DECIMALS, 2, true)}
                  </div>
                </Tooltip>
              </div>
            }

          </AcyPerpetualCard>
        </>
      }

      {/* Swap detail box */}
      {mode === POOL &&
        <>
          <GlpSwapDetailBox
            isBuying={isBuying}
            setIsBuying={setIsBuying}
            tokens={tokens}
            infoTokens={glp_infoTokens}
            glpPrice={glpPrice}
            glpBalance={glpBalance}
            glpBalanceUsd={glpBalanceUsd}
            // reservedAmount={reservedAmount}
            // reserveAmountUsd={reserveAmountUsd}
            // stakingInfo={stakingInfo}
            glpSupply={glpSupply}
            glpSupplyUsd={glpSupplyUsd}
          // gmxPrice={gmxPrice}
          />
        </>
      }


      {isConfirming && (
        <ConfirmationBox
          fromToken={fromToken}
          fromTokenInfo={fromTokenInfo}
          toToken={toToken}
          toTokenInfo={toTokenInfo}
          isLong={isLong}
          isMarketOrder={type === MARKET}
          type={type}
          isHigherSlippageAllowed={isHigherSlippageAllowed}
          setIsHigherSlippageAllowed={setIsHigherSlippageAllowed}
          isShort={isShort}
          toAmount={toAmount}
          fromAmount={fromAmount}
          onConfirmationClick={onConfirmationClick}
          setIsConfirming={setIsConfirming}
          shortCollateralAddress={shortCollateralAddress}
          hasExistingPosition={hasExistingPosition}
          leverage={leverage}
          existingPosition={existingPosition}
          existingLiquidationPrice={existingLiquidationPrice}
          displayLiquidationPrice={displayLiquidationPrice}
          shortCollateralToken={shortCollateralToken}
          isPendingConfirmation={isPendingConfirmation}
          triggerPriceUsd={triggerPriceUsd}
          triggerRatio={triggerRatio}
          fees={fees}
          feesUsd={feesUsd}
          isSubmitting={isSubmitting}
          fromUsdMin={fromUsdMin}
          toUsdMax={toUsdMax}
          nextAveragePrice={nextAveragePrice}
          collateralTokenAddress={collateralTokenAddress}
          feeBps={feeBps}
          chainId={chainId}
          orders={orders}
        />
      )}

    </div>
  );
}
Example #6
Source File: Farms.js    From acy-dex-interface with MIT License 4 votes vote down vote up
Farms = (props) => {
  // useWeb3React hook will listen to wallet connection.
  // if wallet is connected, account, chainId, library, and activate will not be not be undefined.
  // const { account, chainId, library, activate, active } = useWeb3React();
  const {account, library, chainId, tokenList: supportedTokens} = useConstantLoader();
  const { activate } = useWeb3React();
  // const [account, setAccount] = useState();
  const INITIAL_ROW_NUMBER = 20;

  const [farmsContent, setFarmsContent] = useState([]);
  const [currentBlock, setCurrentBlock] = useState(0);
  const [currentTableRow, setCurrentTableRow] = useState([]);
  const [tableRow, setTableRow] = useState([]);
  const [selectedTable, setSelectedTable] = useState(0);
  const [searchInput, setSearchInput] = useState('');
  const [tableTitle, setTableTitle] = useState('All Farms');
  const [tableSubtitle, setTableSubtitle] = useState('Stake your LP tokens and earn token rewards');
  const [rowNumber, setRowNumber] = useState(INITIAL_ROW_NUMBER);
  const [hideDao, setHideDao] = useState(true);
  const [tokenFilter, setTokenFilter] = useState(false);
  const [daoDataSource, setDaoDataSource] = useState(SampleStakeHistoryData);
  const [walletConnected, setWalletConnected] = useState();
  
  const [isMyFarms, setIsMyFarms] = useState(false);
  const [harvestAcy, setHarvestAcy] = useState();
  const [balanceAcy, setBalanceAcy] = useState();
  const [stakeACY, setStakeACY] = useState();

  const [isLoadingPool, setIsLoadingPool] = useState(true);
  const [isLoadingHarvest, setIsLoadingHarvest] = useState(true);
  const [isLoadingBalance, setIsLoadingBalance] = useState(true);
  
  const [isConnected, setIsConnected] = useState(false); // set this after run activate
  const [activeEnded, setActiveEnded] = useState(true);

  const [notLogginFarmContent, setNotLogginFarmContent] = useState();


  // method to activate metamask wallet.
  // calling this method for the first time will cause metamask to pop up,
  // and require user to approve this connection.
  const connectWalletByLocalStorage = useConnectWallet();
  const connectWallet = async () =>  {
    connectWalletByLocalStorage();
  };

  //function to get logo URI
  function getLogoURIWithSymbol(symbol) {
    for (let j = 0; j < supportedTokens.length; j++) {
      if (symbol === supportedTokens[j].symbol) {
        return supportedTokens[j].logoURI;
      }
    }
    return null;
  }
  function getTokenDetail(symbol) {
    for (let j = 0; j < supportedTokens.length; j++) {
      if (symbol === supportedTokens[j].symbol) {
        return supportedTokens[j];
      }
    }
    return {
      name: symbol,
      symbol: symbol,
      address:      '0x0000000000000000000000000000000000000000',
      addressOnEth: '0x0000000000000000000000000000000000000000',
      decimals: 18,
      logoURI: 'https://storageapi2.fleek.co/chwizdo-team-bucket/token image/ethereum-eth-logo.svg'
    };
  }

  const onLogInChanged = (account) => {
    if (!account)
    setWalletConnected(false);
    else
    setWalletConnected(true);
  };
  
  const getDateYDM = (date) => {
    return date.getFullYear(date)  + "-" + ("0"+(date.getMonth(date)+1)).slice(-2) + "-" + ("0" + date.getDate(date)).slice(-2)
  }
  const getDHM = (sec) => {
    if(sec<0) return '00d:00h:00m';
    var diff = sec;
    var days = 0, hrs = 0, min = 0, leftSec = 0;
    diff = Math.floor(diff);
    days = Math.floor(diff/(24*60*60));
    leftSec = diff - days * 24*60*60;
    hrs = Math.floor(leftSec/(60*60));
    leftSec = leftSec - hrs * 60*60;
    min = Math.floor(leftSec/(60));
    return days.toString() + 'd:' + hrs.toString() + 'h:' + min.toString() +'m';

  }

  const getPools = async (library, account, chainId) => {
    setIsLoadingPool(true);
    const block = await library.getBlockNumber();
    var pools;
    try {
      pools = await newGetAllPools(library, account, chainId);
    } catch(e) {
      console.log("getPools error: ",account,chainId,library,pools);
      return;
    }
    // const pools = await newGetAllPools(library, account, chainId);
    const newFarmsContents = [];
    let ismyfarm = false;
    pools&&pools.forEach((pool,idx) => {
      const newFarmsContent = {
        index: idx,
        poolId: pool.poolId,
        lpTokens: pool.lpTokenAddress,
        token1: pool.token0Symbol,
        token1Logo: getLogoURIWithSymbol(pool.token0Symbol),
        token2: pool.token1Symbol,
        token2Logo: getLogoURIWithSymbol(pool.token1Symbol),
        pendingReward: pool.rewardTokensSymbols.map((token, index) => ({
          token,
          amount: pool.rewardTokensAmount[index] == 0?0 : pool.rewardTokensAmount[index],
        })),
        totalApr: pool.apr.toFixed(2),
        tvl: pool.tvl,
        hasUserPosition: pool.hasUserPosition,
        hidden: true,
        stakeData: pool.stakeData,
        poolLpScore: pool.lpScore,
        poolLpBalance: pool.lpBalance,
        endsIn: getDHM((pool.endBlock - block) * BLOCK_TIME()),
        status: pool.endBlock - block > 0,
        ratio: pool.ratio,
        endAfter: (pool.endBlock - block) * BLOCK_TIME(),
        token1Ratio: pool.token1Ratio,
        token2Ratio: pool.token2Ratio,
        poolRewardPerYear: pool.poolRewardPerYear, // usd price
        tokensRewardPerBlock: pool.tokensRewardPerBlock
      };
      if(newFarmsContent.poolId == 0) {
        // const total = rewards[j].reduce((total, currentAmount) => total.add(parseInt(currentAmount)));
        // if(newFarmsContent.stakeData){
        //   const myStakeAcy = newFarmsContent.stakeData.reduce((total, currentAmount) => total + parseFloat(currentAmount.lpAmount), 0);
        //   setStakeACY({
        //     myAcy: myStakeAcy,
        //     totalAcy: newFarmsContent.poolLpBalance
        //   });
        // } else {
        //   setStakeACY({
        //     myAcy: 0,
        //     totalAcy: newFarmsContent.poolLpBalance
        //   });
        // }
      }
      //if user has farm, direct to myfarm
      if(newFarmsContent.hasUserPosition && account) {
        setIsMyFarms(true);
        ismyfarm = true;
      }
      newFarmsContents.push(newFarmsContent);
    });
    
      if(account != "0x0000000000000000000000000000000000000000") {
          console.log("TEST newFarmsContents 0:",account,farmsContent,walletConnected)
          setFarmsContent(newFarmsContents);
          console.log("TEST newFarmsContents 1:",newFarmsContents);
      } else {
          console.log("TEST newFarmsContents 2:",account,farmsContent,walletConnected)
          setNotLogginFarmContent(newFarmsContents);
        
        console.log("TEST newFarmsContents 2:",newFarmsContents);
      }
    setIsLoadingPool(false);
    console.log("end getPools");
  };
  
  useEffect(
    () => {
       console.log("HERE TEST:",account);
      if(!account){
        connectWallet();
      }
      setIsMyFarms(false);
      if (account) {
        setWalletConnected(true);
        const provider = new JsonRpcProvider(RPC_URL(), chainId);
        console.log("start getPools",library,chainId);
        getPools(provider, account, chainId);

      } else {
        const provider = new JsonRpcProvider(RPC_URL(), chainId);
        const account = "0x0000000000000000000000000000000000000000";
        setWalletConnected(false);
        getPools(provider, account, chainId);

      }
    },
    [account, chainId]
  );



  const onAllToggleButtonClick = () => {
    setSelectedTable(0);
    setTableTitle('All Farms');
    setTableSubtitle('Stake your LP tokens and earn token rewards');
    setRowNumber(INITIAL_ROW_NUMBER);
    setHideDao(true);
    setIsMyFarms(false);
  };

  const onAcyToggleButtonClick = () => {
    setSelectedTable(1);
    setTableTitle('ACY Farms');
    setTableSubtitle('Stake your LP tokens and earn ACY token rewards');
    setRowNumber(INITIAL_ROW_NUMBER);
    setHideDao(true);
  };

  const onDaoToggleButtonClick = () => {
    setSelectedTable(3);
    setHideDao(false);
    setTableTitle('DAO Farms');
    setTableSubtitle('Stake your ACY tokens and earn ACY token rewards');
  };

  const onPremierToggleButtonClick = () => {
    setSelectedTable(2);
    setTableTitle('Premier Farms');
    setTableSubtitle('Stake your LP tokens and earn project/mainstream token rewards');
    setRowNumber(INITIAL_ROW_NUMBER);
    setHideDao(true);
  };

  const onMyFarmsButtonClick = () => {
    setSelectedTable(4);
  };

  useEffect(
    () => {
      if (selectedTable === 4) {
        const currentTableData = SampleStakeHistoryData.filter(tableData => {
          const [token1, token2] = tableData.tokens.split('-');
          
          if (
            token1.toLowerCase().includes(searchInput.toLowerCase()) ||
            token2.toLowerCase().includes(searchInput.toLowerCase())
          )
            return true;
        });
        setDaoDataSource(currentTableData);
      } else {
        const currentTableRowCopy = currentTableRow.filter(
          tableData =>{
            
            if( tableData.token1.toLowerCase().includes(searchInput.toLowerCase()) ||
            tableData.token2.toLowerCase().includes(searchInput.toLowerCase())
            ) {
              return true;
            }
          }
        );
        if (isMyFarms){
          setTableTitle('My Farms');
          // setTableRow(currentTableRowCopy.filter(tableData => tableData.hasUserPosition));
          // setTableRow(currentTableRowCopy.filter(tableData => tableData.hasUserPosition));
          console.log('My Farms');
        }
        else if (selectedTable === 0){
          setTableTitle('All Farms');
          console.log('All Farms');
        } 
        else if (selectedTable === 1){
          setTableTitle('Standard Farms');
          console.log('Standard Farms');
        } 
        else if (selectedTable === 2){
          setTableTitle('Premier Farms');
          console.log('Premier Farms');
        } 
        else{
          setTableTitle('DAO Farms'); 
          console.log('DAO Farms');
        }
      }
    },
    [searchInput, selectedTable, isMyFarms]
  );


  return (
    <PageHeaderWrapper>
      { isLoadingPool? (
        <div>
          <PageLoading/>
          {/* Farm is not available not! */}
        </div>
      ) : (
      <div className={styles.farmsContainer}>
        <div className={styles.tableControlButtonContainer}>
          <ToggleButtonGroup
            selectedTable={selectedTable}
            onAllToggleButtonClick={onAllToggleButtonClick}
            onAcyToggleButtonClick={onAcyToggleButtonClick}
            onPremierToggleButtonClick={onPremierToggleButtonClick}
            onDaoToggleButtonClick={onDaoToggleButtonClick}
            onMyFarmsToggleButtonClick={onMyFarmsButtonClick}
            isMyFarms={isMyFarms}
          />
          <TableControl
            searchInput={searchInput}
            setSearchInput={setSearchInput}
            isMyFarms={isMyFarms}
            setIsMyFarms={setIsMyFarms}
            walletConnected={walletConnected}
            activeEnded={activeEnded}
            setActiveEnded={setActiveEnded}
          />
        </div>
        {selectedTable !== 4 && (
          <FarmsTable
            tableRow={walletConnected?farmsContent:notLogginFarmContent}
            tableTitle={tableTitle}
            tableSubtitle={tableSubtitle}
            rowNumber={rowNumber}
            setRowNumber={setRowNumber}
            hideDao={hideDao}
            selectedTable={selectedTable}
            tokenFilter={tokenFilter}
            setTokenFilter={setTokenFilter}
            walletConnected={walletConnected}
            connectWallet={connectWallet}
            account={account}
            library={library}
            chainId={chainId}
            isMyFarms={isMyFarms}
            harvestAcy={harvestAcy}
            balanceAcy={balanceAcy}
            searchInput={searchInput}
            selectedTable={selectedTable}
            isLoading={isLoadingPool || isLoadingBalance || isLoadingHarvest}
            activeEnded={activeEnded}
            setWalletConnected={setWalletConnected}
            // refreshPool={refreshPool}
          />
        )}
        {selectedTable === 4 && <DaoTable dataSource={daoDataSource} />}
      </div>
      )}
    </PageHeaderWrapper>
  );
}
Example #7
Source File: FarmsTableRow.js    From acy-dex-interface with MIT License 4 votes vote down vote up
FarmsTableRow = props => {
  const {
    index,
    lpTokens,
    rowClickHandler,
    walletConnected,
    connectWallet,
    hideArrow = false,
    chainId,
    account,
    library,
    isMyFarms,
    dispatch,
    content,
    poolId,
    stakedTokenAddr,
    token1,
    token1Logo,
    token2,
    token2Logo,
    totalApr,
    tvl,
    pendingReward,
    stakeData,
    hasUserPosition,
    searchInput,
    selectedTable,
    tokenFilter,
    dao,
    isLoading,
    activeEnded,
    setWalletConnected
  } = props;

  const [poolInfo, setPoolInfo] = useState(content);
  const [hidden, setHidden] = useState(true);

  const [balance, setBalance] = useState(12345);
  const [isHarvestDisabled, setIsHarvestDisabled] = useState(false);
  const [remainingDays, setRemainingDays] = useState(120)
  const [date, setDate] = useState("10/12/2021")
  const [isModalVisible, setIsModalVisible] = useState(false);
  const hideModal = () => setIsModalVisible(false);
  const showModal = () => setIsModalVisible(true);

  const [withdrawModal,setWithdrawModal] = useState(false);
  const hideWithdrawModal = () => setWithdrawModal(false);
  const showWithdrawModal = () => setWithdrawModal(true);
  const [selectedRowData, setSelectedRowData] = useState(null);

  const [harvestModal,setHarvestModal] = useState(false);
  const [harvestButtonText, setHarvestButtonText] = useState('Harvest');
  const [harvestButtonStatus,setHarvestButtonStatus] = useState(true);
  const hideHarvestModal = () => setHarvestModal(false);
  const showHarvestModal = () => setHarvestModal(true);

  const [showAddLiquidity,setShowAddLiquidity] = useState(false);

  const [errorMessages,setErrorMessages] = useState('');
  const [loggedIn, setLoggedIn] = useState(false);

  const [withdrawButtonText,setWithdrawButtonText] = useState('Withdraw');
  const [withdrawButtonStatus,setWithdrawButtonStatus] = useState(true);
  const [percent,setPercent] = useState(50);
  const [withdrawAmount, setWithdrawAmount] = useState(0);
  

  const ACY_LOGO = "https://acy.finance/static/media/logo.78c0179c.svg";

  


  //function to get logo URI
  function getLogoURIWithSymbol(symbol) {
    const supportedTokens = TOKENLIST();
    for (let j = 0; j < supportedTokens.length; j++) {
      if (symbol === supportedTokens[j].symbol) {
        return supportedTokens[j].logoURI;
      }
    }
    return null;
  }
  useEffect(
    () => {
      setPoolInfo(content);
    },
    [isLoading]
  );
  

  useEffect(
    () => {
      
      if (!poolInfo.lpTokens || !chainId || !account || !library) return;
      async function getFarmTokenUserBalance() {
        const bal = await getUserTokenBalanceWithAddress(
          poolInfo.lpTokens,
          chainId,
          account,
          library
        );
        setBalance(bal);
      }
      getFarmTokenUserBalance();
    },
    [poolInfo,isModalVisible]
  );
  useEffect(
    () => {
      setErrorMessages('');
      setWithdrawButtonText('Withdraw');
      setHarvestButtonStatus(true);
    },[withdrawModal]
  );
  useEffect(
    () => {
      setErrorMessages('');
      setHarvestButtonText('Harvest');
      setHarvestButtonStatus(true);
    },[harvestModal]
  );

  let history = useHistory();
  const getDHM = (sec) => {
    if(sec<0) return '00d:00h:00m';
    var diff = sec;
    var days = 0, hrs = 0, min = 0, leftSec = 0;
    diff = Math.floor(diff);
    days = Math.floor(diff/(24*60*60));
    leftSec = diff - days * 24*60*60;
    hrs = Math.floor(leftSec/(60*60));
    leftSec = leftSec - hrs * 60*60;
    min = Math.floor(leftSec/(60));
    return days.toString() + 'd:' + hrs.toString() + 'h:' + min.toString() +'m';

  }

  const refreshPoolInfo = async () => {
    const provider = new JsonRpcProvider(RPC_URL(), CHAINID());
    const pool = await newGetPool(poolInfo.poolId, provider, account, chainId);
    const block = await provider.getBlockNumber();
    const newFarmsContent = {
      index: pool.poolId,
      poolId: pool.poolId,
      lpTokens: pool.lpTokenAddress,
      token1: pool.token0Symbol,
      token1Logo: getLogoURIWithSymbol(pool.token0Symbol),
      token2: pool.token1Symbol,
      token2Logo: getLogoURIWithSymbol(pool.token1Symbol),
      pendingReward: pool.rewardTokensSymbols.map((token, index) => ({
        token,
        amount: pool.rewardTokensAmount[index] == 0?0 : pool.rewardTokensAmount[index],
      })),
      totalApr: pool.apr.toFixed(2),
      tvl: pool.tvl,
      hasUserPosition: pool.hasUserPosition,
      hidden: true,
      stakeData: pool.stakeData,
      poolLpScore: pool.lpScore,
      poolLpBalance: pool.lpBalance,
      endsIn: getDHM((pool.endBlock - block) * BLOCK_TIME()),
      status: pool.endBlock - block > 0,
      ratio: pool.ratio,
      endAfter: (pool.endBlock - block) * BLOCK_TIME(),
      token1Ratio: pool.token1Ratio,
      token2Ratio: pool.token2Ratio,
      poolRewardPerYear: pool.poolRewardPerYear,
      tokensRewardPerBlock: pool.tokensRewardPerBlock
    };
    setPoolInfo(newFarmsContent);
  };



  const redirectLiquidity = () => {
    history.push({
      pathname: '/liquidity',
      // search: '?update=true',  // query string
      state: {  // location state
        token1 : token1,
        token2 : token2,
      },
    });
  };

  const withdrawClicked = () => {
    if(false) {
      
      setErrorMessages("- You can't withdraw now");
    } else {
      setWithdrawButtonStatus(false);
      setWithdrawButtonText(<>Processing <Icon type="loading" /></>);
      withdraw(poolId, selectedRowData.positionId, (selectedRowData.lpAmount * percent / 100).toString(), setWithdrawButtonText, setWithdrawButtonStatus, withdrawCallback, library, account);
    }
  };

  const formatString = (value) => {
    let formattedStr;
    if (value >= 1000000000) {
      formattedStr = `$ ${(value / 1000000000).toFixed(2)}b`;
    }else if (value >= 1000000) {
      formattedStr = `$ ${(value / 1000000).toFixed(2)}m`;
    } else if (value >= 1000) {
      formattedStr = `$ ${(value / 1000).toFixed(2)}k`;
    } else {
      formattedStr = `$ ${(value).toFixed(2)}`;
    }
    return formattedStr;
  }

  const harvestCallback = status => {
    // const {
    //   transaction: { transactions },
    // } = props;
    // // 检查是否已经包含此交易
    // const transLength = transactions.filter(item => item.hash == status.hash).length;
    // if (transLength == 0) {
    //   dispatch({
    //     type: 'transaction/addTransaction',
    //     payload: {
    //       transactions: [...transactions, status.hash],
    //     },
    //   });
    // }
    const sti = async (hash) => {
      library.getTransactionReceipt(hash).then(async receipt => {
        // receipt is not null when transaction is done
        if (!receipt) 
          setTimeout(sti(hash), 500);
        else {
          
          // const newData = transactions.filter(item => item.hash != hash);

          // props.onGetReceipt(receipt.transactionHash, library, account);

          // dispatch({
          //   type: 'transaction/addTransaction',
          //   payload: {
          //     transactions: newData
          //   },
          // });
          // await axios.get(
          //   // fetch valid pool list from remote
          //   `${API_URL}/farm/updatePool?poolId=${poolInfo.poolId}`
          //   //change to to production
          //   //`http://api.acy.finance/api/updatePool?poolId=${poolId}`
          // ).then( async (res) => {
            
          // }).catch(e => console.log("error: ", e));
          // set button to done and disabled on default
          await refreshPoolInfo();
          setHarvestButtonText("Done");
          hideHarvestModal();
          
        }
      });
    }
    sti(status.hash);
  }

  const withdrawCallback = status => {

    // const {
    //   transaction: { transactions },
    // } = props;
    // // 检查是否已经包含此交易
    // const transLength = transactions.filter(item => item.hash == status.hash).length;
    // if (transLength == 0) {
    //   dispatch({
    //     type: 'transaction/addTransaction',
    //     payload: {
    //       transactions: [...transactions, status.hash],
    //     },
    //   });
    // }
    const sti = async (hash) => {
      library.getTransactionReceipt(hash).then(async receipt => {
        // console.log(`receiptreceipt for ${hash}: `, receipt);
        // receipt is not null when transaction is done
        if (!receipt) 
          setTimeout(sti(hash), 500);
        else {
          
          // const newData = transactions.filter(item => item.hash != hash);

          // props.onGetReceipt(receipt.transactionHash, library, account);

          // dispatch({
          //   type: 'transaction/addTransaction',
          //   payload: {
          //     transactions: newData
          //   },
          // });
          // await refreshPoolInfo();
          // await axios.get(
          //   // fetch valid pool list from remote
          //   `${API_URL}/farm/updatePool?poolId=${poolInfo.poolId}`
          //   //change to to production
          //   //`http://api.acy.finance/api/updatePool?poolId=${poolId}`
          // ).then(async (res) => {
          //   await refreshPoolInfo();
          //   setWithdrawButtonText("Done");
          //   hideWithdrawModal();
          // }).catch(e => console.log("error: ", e));
          // set button to done and disabled on default
          await refreshPoolInfo();
          setWithdrawButtonText("Done");
          hideWithdrawModal();
          
        }
      });
    }
    sti(status.hash);
  };
  const searchFilter = () => {
    if(token1.toLowerCase().includes(searchInput.toLowerCase()) || token2.toLowerCase().includes(searchInput.toLowerCase())) {
      return true;
    } else {
      return false;
    }
  };

  const tableFilter = () => {
    if(dao) {
      return true;
    }
    if(selectedTable === 0) {
      return true;
    } else if(selectedTable === 1) {
      return (poolInfo.pendingReward.length === 1 && poolInfo.pendingReward[0].token) === "ACY" && !(poolInfo.token1 && !poolInfo.token2);
    } else if(selectedTable === 2) {
      const table4 = poolInfo.pendingReward.length !== 1  ||
        (poolInfo.pendingReward.length === 1 && poolInfo.pendingReward[0].token) !== "ACY"
      if(tokenFilter) {
        let isBtcEth = false;
        poolInfo.pendingReward.forEach(({ token }) => {
          if (token === 'BTC' || token === 'ETH' || token === 'USDC' || token === 'USDT') {
            isBtcEth = true;
          }
        });
        return isBtcEth && table4;
      }
      return table4;
    }
  }

  const getFilter = () =>{
    return !tableFilter() || !searchFilter() || !daoFilter() || activeEndedFilter();
  }

  const daoFilter = () => {
    return !dao || (poolInfo.token1 && !poolInfo.token2);
  }
  const activeEndedFilter = () => {
    return poolInfo.status != activeEnded;
  }

  

  return ( poolInfo && (!isMyFarms || poolInfo.hasUserPosition) && (
    <div className={styles.tableBodyRowContainer} hidden={getFilter()}>
      {/* Table Content */}
      <div className={styles.tableBodyRowContentContainer} 
        onClick={()=> {
          // if(poolInfo.status)
            setHidden(prevState => !prevState)
          }
        }
        >
        {/* Token Title Row */}
        <div className={styles.tableBodyTitleColContainer}>
          {poolInfo.token1Logo && (
            <div className={styles.token1LogoContainer}>
              <img src={poolInfo.token1Logo} alt={poolInfo.token1} />
            </div>
          )}
          {/* conditionally hide and show token 2 logo. */}
          {/* if token 2 is undefined or null, hide token 2 logo. */}
          {poolInfo.token2Logo && (
            <div className={styles.token2LogoContainer}>
              <img src={poolInfo.token2Logo} alt={poolInfo.token2} />
            </div>
          )}

          {/* conditionally hide and show token 2 symbol */}
          {/* only display token 1 symbol if token 2 is undefined or null. */}
          <div className={styles.tokenTitleContainer}>
            {poolInfo.token1 && poolInfo.token2 && `${poolInfo.token1}-${poolInfo.token2}`}
            {poolInfo.token1 && !poolInfo.token2 && `${poolInfo.token1}`}
            {poolInfo.token2 && !poolInfo.token1 && `${poolInfo.token2}`}
            {!isMobile ? poolInfo.token1 && poolInfo.token2 && <span style={{ opacity: '0.5' }}> LP</span> : ''}
          </div>
        </div>

        {/* Pending Reward Column */}
        <div className={styles.tableBodyRewardColContainer}>
          <div className={styles.pendingRewardTitleContainer}>
            {(isMyFarms && !isMobile ) ? 'Accumulated Reward' : ''}
            {(!isMyFarms && !isMobile ) ? 'Accumulated Reward' : ''}
            {(isMobile) ? 'Reward' : ''}
            {isMobile}
          </div>
          {poolInfo.pendingReward && poolInfo.pendingReward.map((reward,idx) => (
            <div className={styles.pendingReward1ContentContainer}>
              {`${reward.amount.toFixed(2)} ${reward.token}`}
            </div>
          ))}
        </div>

        {/* Total APR Column */}
        <div className={styles.tableBodyAprColContainer}>
          <div className={styles.totalAprTitleContainer}>APR</div>
          <div className={styles.totalAprContentContainer}>{totalApr}%</div>
        </div>

        {/* TVL Column */}
        {!isMobile && (
          <div className={styles.tableBodyTvlColContainer}>
            <div className={styles.tvlTitleContainer}>TVL</div>
            <div className={styles.tvlContentContainer}>{formatString(poolInfo.tvl)}</div>
          </div>
        )}
        {!isMobile && (
          <div className={styles.tableBodyTvlColContainer}>
            <div className={styles.tvlTitleContainer}>End</div>
            <div className={styles.tvlContentContainer}>{poolInfo.endsIn}</div>
          </div>
        )}

        {/* Arrow Icon Column */}
        {!hideArrow && !dao && (
          <div className={styles.tableBodyArrowColContainer}>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              className={styles.arrowIcon}
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
            </svg>
          </div>
        )}
      </div>

      {/* Table Drawer */}
      {!isMyFarms && (
        <div className={styles.tableBodyDrawerContainer} hidden={hidden && !dao}>
        {/* Staking Propotion */}
        {!isMyFarms && (
          <div className={styles.index0tableBodyDrawerFarmContainer}>
            <div className={styles.tableBodyDrawerStakingPropotionTitle}>
              {/* *20% */}
            </div>
            {/* <div className={styles.tableBodyDrawerStakingPropotionEquation}> {token1}-{token2} LP </div> */}
          </div>
        )}
        {/* Add Liquidity */}
        {!isMyFarms && poolInfo.token1 && !poolInfo.token2 ?(
          <div className={styles.tableBodyDrawerAddLiquidityContainer}>
            <div className={styles.tableBodyDrawerAddLiquidityTitle}>Buy ACY</div>
              <button
                type="button"
                className={styles.tableBodyDrawerAddLiquidityButton}
                onClick={()=> setShowAddLiquidity(true)}
              >
                Buy
              </button>
          </div>
        ) : (
          <div className={styles.tableBodyDrawerAddLiquidityContainer}>
            <div className={styles.tableBodyDrawerAddLiquidityTitle}>Add Liquidity</div>
              <button
                type="button"
                className={styles.tableBodyDrawerAddLiquidityButton}
                onClick={()=> setShowAddLiquidity(true)}
              >
                Add
              </button>
          </div>
        )
        }
        {/* Farm Column */}
        <div className={styles.tableBodyDrawerFarmContainer}>
          <div className={styles.tableBodyDrawerWalletTitle}>Start Farming</div>
            <div>
              {walletConnected ? (
                <button
                  type="button"
                  className={styles.tableBodyDrawerWalletButton}
                  onClick={showModal}
                >
                  Stake LP
                </button>
              ) : (
                <button
                  type="button"
                  className={styles.tableBodyDrawerWalletButton}
                  onClick={connectWallet}
                >
                  Connect Wallet
                </button>
              )}
            </div>
          </div>
        </div>
      )}
      { poolInfo.stakeData && poolInfo.stakeData.map((data,id) => {
        return (
        <div hidden={hidden||!isMyFarms}>
          {/* Farm Column */}   
          <StakeRow 
            data={data}
            library={library}
            account={account}
            poolId={poolId}
            token1={poolInfo.token1}
            token1Logo={poolInfo.token1Logo}
            token2={poolInfo.token2}
            token2Logo={poolInfo.token2Logo}
            refreshPoolInfo={refreshPoolInfo}
            ratio={poolInfo.ratio}
            token1Ratio={poolInfo.token1Ratio}
            token2Ratio={poolInfo.token2Ratio}
          >
              { (id == Math.ceil(poolInfo.stakeData.length/2) - 1 && !isMobile) || 
              (id == 0 && isMobile) ?  (
            <div className={styles.tableBodyDrawerFarmContainer}>
              <div>
                <div className={styles.tableBodyDrawerWalletTitle}>Start Farming</div>
                <div>
                  {walletConnected ? (
                    <button
                      type="button"
                      className={styles.tableBodyDrawerWalletButton}
                      onClick={showModal}
                    >
                      Stake LP
                    </button>
                      ) : (
                    <button
                      type="button"
                      className={styles.tableBodyDrawerWalletButton}
                      onClick={connectWallet}
                    >
                      Connect Wallet
                    </button>
                  )}
                </div>
              </div>
            </div>
            ) : (
              <div className={styles.index0tableBodyDrawerFarmContainer}>
                {/* lp Amount {stakeData[id].lpAmount} */}
              </div>
            )}      
          </StakeRow>
        </div>
        );
      })}
      
      <AcyModal
        visible={showAddLiquidity}
        onCancel={()=> setShowAddLiquidity(false)}
        width={400}
        bodyStyle={{
          padding: '0px',
          margin: '0px',
          background: '#FFFFFF',
          borderRadius: '1.5rem',
        }}
      >
        <div>{ poolInfo.token1 && !poolInfo.token2 ? (
          <AcyCard style={{ backgroundColor: '#0e0304', padding: '10px' }}>
            <div className={styles.trade}>
              <SwapComponent
                onSelectToken0={token => {
                  // setActiveToken0(token);
                }}
                onSelectToken1={token => {
                  // setActiveToken1(token);

                }}
                onGetReceipt={null}
                token={{
                  token0: TOKENLIST().find(token => token.symbol == "USDT"),
                  token1: TOKENLIST().find(token => token.symbol == poolInfo.token1)
                }}
                isLockedToken1={true}
              />
            </div>
         </AcyCard>
        ) : (
          <AddLiquidityComponent 
            onLoggedIn={()=>setLoggedIn(true)} 
            isFarm={true}
            token={{
              token1: poolInfo.token1,
              token2: poolInfo.token2
            }}
            onLogInChanged={setWalletConnected}
          />
        )}
        </div>
      </AcyModal>
      
      <StakeModal
        onCancel={hideModal}
        isModalVisible={isModalVisible}
        token1={poolInfo.token1}
        token2={poolInfo.token2}
        balance={balance}
        poolId={poolInfo.poolId}
        stakedTokenAddr={poolInfo.lpTokens}
        refreshPoolInfo={refreshPoolInfo}
        account={account}
        library={library}
        chainId={chainId}
        poolLpScore={poolInfo.poolLpScore}
        endAfter={poolInfo.endAfter}
        ratio={poolInfo.ratio}
        token1Logo={poolInfo.token1Logo}
        token2Logo={poolInfo.token2Logo}
        token1Ratio={poolInfo.token1Ratio}
        token2Ratio={poolInfo.token2Ratio}
        poolRewardPerYear={poolInfo.poolRewardPerYear}
        tokensRewardPerBlock={poolInfo.tokensRewardPerBlock}
      />
    </div>
  )
    
  );
}
Example #8
Source File: LaunchpadProject.js    From acy-dex-interface with MIT License 4 votes vote down vote up
LaunchpadProject = () => {
  // STATES
  const { account, chainId, library, activate, active } = useWeb3React();
  const { projectId } = useParams();
  const [receivedData, setReceivedData] = useState({});
  const [mainCoinLogoURI, setMainCoinLogoURI] = useState(null);
  const [poolID, setPoolID] = useState(null);
  const [poolBaseData, setPoolBaseData] = useState(null);
  const [poolDistributionDate, setDistributionDate] = useState([]);
  const [poolDistributionStage, setpoolDistributionStage] = useState([]);
  const [poolStatus, setPoolStatus] = useState(0);
  const [poolTokenDecimals, setPoolTokenDecimals] = useState(0);
  const [poolMainCoinDecimals, setPoolMainCoinDecimals] = useState(0); // Gary: decimal initialize to 0
  const [poolMainCoinAddress, setPoolMainCoinAddress] = useState(""); // e.g., USDT
  const [poolTokenAddress, setPoolTokenAddress] = useState("");
  const [poolMainCoinLogoURL, setPoolMainCoinLogoURL] = useState(null);
  const [poolMainCoinName, setPoolMainCoinName] = useState(null);
  const [compareAlloDate, setCompareAlloDate] = useState(false);
  const [comparesaleDate, setComparesaleDate] = useState(false);
  const [comparevestDate, setComparevestDate] = useState(false);
  // const [investorNum,setinvestorNum] = useState(0);
  // const [isInvesting, setIsInvesting] = useState(false);

  // CONSTANTS

  // FUNCTIONS

  const convertUnixTime = unixTime => {
    const data = new Date((Number(unixTime)) * 1000)
    const res = data.toLocaleString()
    return res
  }

  const connectWalletByLocalStorage = useConnectWallet();
  useEffect(() => {
    if (!account) {
      connectWalletByLocalStorage();
    }
  }, [account]);

  // contract function
  const getPoolData = async (lib, acc) => {

    const poolContract = getContract(LAUNCHPAD_ADDRESS(), POOLABI, lib, acc);
    const pool = []
    const distributionRes = []
    const distributionStage = []

    // 合约函数调用
    const baseData = await poolContract.GetPoolBaseData(poolID)
    const distributionData = await poolContract.GetPoolDistributionData(poolID)
    const status = await poolContract.GetPoolStatus(poolID)

    console.log('Base Data', baseData);
    console.log('Pool Status', status);
    console.log('Distribution Data', distributionData);

    // getpoolbasedata 数据解析
    const token2Address = baseData[1]
    const tokenList = TOKEN_LIST()
    const token2Info = tokenList.find(item => item.address == token2Address)

    const token1contract = getContract(baseData[0], ERC20ABI, lib, acc)
    const token2contract = getContract(token2Address, ERC20ABI, lib, acc)

    const token1decimal = await token1contract.decimals()
    const token2decimal = await token2contract.decimals()
    // 不解析时间戳
    const res1 = BigNumber.from(baseData[2]).toBigInt().toString().slice(0, -(token1decimal)) // 获取销售的token的总数
    const res2 = BigNumber.from(baseData[3]).toBigInt().toString().slice(0, -(token1decimal)) // 已销售的token的数量
    const res3 = BigNumber.from(baseData[4]).toBigInt()
    const res4 = BigNumber.from(baseData[5]).toBigInt()

    console.log('End time', res4);

    // 获取当前阶段
    const d = Math.round(new Date().getTime() / 1000)
    if (d > res3) setComparesaleDate(true)
    if (d > res4) setComparevestDate(true)
    const saleStartDate = convertUnixTime(res3)
    const saleEndDate = convertUnixTime(res4)
    // 存放数据
    pool.push(res1, res2, saleStartDate, saleEndDate)
    // getpooldistributiondata 数据解析以及存放
    distributionData[1].map(uTime => distributionRes.push(convertUnixTime(uTime)))
    distributionData[2].map(vestingRate => distributionStage.push(BigNumber.from(vestingRate).toBigInt().toString()))

    // 判断当前是否是vesting阶段
    const curPoolStatus = Number(BigNumber.from(status).toBigInt())

    // set数据
    setPoolBaseData(pool)
    setPoolStatus(curPoolStatus)
    setPoolStatus(Number(BigNumber.from(status).toBigInt()))
    setPoolMainCoinAddress(token2Address)
    setPoolTokenAddress(baseData[0])
    setPoolTokenDecimals(token1decimal)
    setPoolMainCoinDecimals(token2decimal)
  }

  const updatePoolData = async () => {
    // project must have poolID
    if (poolID === null) return;

    const now_moment_utc = moment.utc();
    const end_moment_utc = moment.utc(receivedData.saleEnd);
    const start_moment_utc = moment.utc(receivedData.saleStart);
    if (now_moment_utc > end_moment_utc || now_moment_utc < start_moment_utc) return;

    try {
      if (account && library) {
        await getPoolData(library, account);
      } else {
        const provider = new JsonRpcProvider(LAUNCH_RPC_URL(), CHAINID());  // different RPC for mainnet
        const accnt = "0x0000000000000000000000000000000000000000";
        await getPoolData(provider, accnt);
      };
    } catch (error) {
      console.log('Invalid Pool ID.')
    }

  }

  // HOOKS
  // Retrieve project data from db
  useEffect(() => {
    getProjectInfo(API_URL(), projectId)
      .then(res => {
        if (res) {
          // extract data from string
          console.log("fecthing project info ------------111", res.contextData)
          const contextData = JSON.parse(res.contextData);

          res['tokenLabels'] = contextData['tokenLabels'];
          res['projectDescription'] = contextData['projectDescription'];
          res['alreadySale'] = contextData['alreadySale'];
          res['salePercentage'] = contextData['salePercentage'];
          res['posterUrl'] = contextData['posterUrl'];
          res['bulletin'] = contextData['bulletin'];
          res['tokenLogoUrl'] = res.basicInfo.projectTokenUrl;
          res['minInvest'] = res.allocationInfo.parameters.minInvest;

          res['regStart'] = res.scheduleInfo.regStart;
          res['regEnd'] = res.scheduleInfo.regEnd;
          res['saleStart'] = res.scheduleInfo.saleStart;
          res['saleEnd'] = res.scheduleInfo.saleEnd;

          if (res.scheduleInfo.distributionData) {
            const distributionData = res.scheduleInfo.distributionData;
            const distributionRes = [];
            const distributionStage = [];
            distributionData[2].map(vestingRate => distributionStage.push(BigNumber.from(vestingRate).toBigInt().toString()))
            setDistributionDate([...distributionData[1]]);
            setpoolDistributionStage(distributionStage);
          }

          res['tokenPrice'] = res.saleInfo.tokenPrice;
          res['totalSale'] = res.saleInfo.totalSale;
          res['totalRaise'] = res.saleInfo.totalRaise;
          res['distributionType'] = res.basicInfo.distributionType || "contract";
          res['distributionLink'] = res.basicInfo.distributionLink || "";
          res['projectName'] = res.basicInfo.projectName;
          res['projectToken'] = res.basicInfo.projectToken;
          res['mainCoin'] = res.basicInfo.mainCoin;
          res['actualChain'] = res.basicInfo.actualChain;

          // get state to hide graph and table
          const curT = new Date()
          if (curT < res.scheduleInfo.saleStart) setCompareAlloDate(true)
          const tokenList = ConstantLoader()['tokenList'];
          console.log(tokenList);
          const mainCoinInfo = tokenList.find(item => item.symbol == res.basicInfo.mainCoin)
          // const mainCoinInfo = TOKEN_LIST().find(item => item.symbol == res.basicInfo.mainCoin)
          setMainCoinLogoURI(mainCoinInfo.logoURI);
          setPoolID(res.basicInfo.poolID);

          console.log('res', res);
          setReceivedData(res);
        } else {
          console.log('redirect to list page');
          // history.push('/launchpad');
        }
      })
      .catch(e => {
        console.log("Project Detail check errrrrrrrrrrr", e);
        // console.error(e);
        // history.push('/launchpad');
      });

  }, [library, account]);

  // fetching data from Smart Contract
  useEffect(() => {
    updatePoolData();
  }, [library, account, poolID])

  // COMPONENTS
  return (
    <div>
      {!receivedData.posterUrl ? (
        <div>
          <PageLoading />
        </div>
      ) : (
        <div className="mainContainer">
          <Timer callBack={updatePoolData} ms={30000} />
          <TokenBanner posterUrl={receivedData.posterUrl} />
          <TokenLogoLabel
            projectName={receivedData.projectName}
            tokenLogo={receivedData.tokenLogoUrl}
            receivedData={receivedData}
          />
          <CardArea
            poolBaseData={poolBaseData}
            receivedData={receivedData}
            account={account}
            library={library}
            mainCoinLogoURI={mainCoinLogoURI}
            poolDistributionStage={poolDistributionStage}
            poolDistributionDate={poolDistributionDate}
            comparesaleDate={comparesaleDate}
            comparevestDate={comparevestDate}
            poolID={poolID}
            poolStatus={poolStatus}
            poolMainCoinDecimals={poolMainCoinDecimals}
            poolMainCoinAddress={poolMainCoinAddress}
            poolTokenAddress={poolTokenAddress}
            poolTokenDecimals={poolTokenDecimals}
          />
        </div>
      )}
    </div>
  );
}