diff --git a/frontend/src/actions/dexActions.js b/frontend/src/actions/dexActions.js index fdec9981..9691fdc7 100644 --- a/frontend/src/actions/dexActions.js +++ b/frontend/src/actions/dexActions.js @@ -2,7 +2,6 @@ import BigNumber from "bignumber.js"; import { currentConnection, ETH, - etheriumNetwork, moonriverNetwork, PBR, routerAddresses, @@ -69,7 +68,7 @@ export const swapTokens = const toAddress = account; const _deadlineUnix = getUnixTime(deadline); dispatch({ - type: SHOW_LOADING, + type: SHOW_DEX_LOADING, }); dispatch({ type: START_TRANSACTION }); @@ -214,7 +213,6 @@ export const swapTokens = await swapPromise .on("receipt", async function (receipt) { - console.log("UPDATE_TRANSACTION_STATUS", receipt); dispatch({ type: UPDATE_TRANSACTION_STATUS, payload: { @@ -238,7 +236,7 @@ export const swapTokens = }); } dispatch({ - type: HIDE_LOADING, + type: HIDE_DEX_LOADING, }); }; @@ -282,7 +280,7 @@ export const addLiquidity = const _routerContract = routerContract(network); dispatch({ - type: SHOW_LOADING, + type: SHOW_DEX_LOADING, }); //input params const token0AmountDesired = token0.amount; @@ -343,7 +341,7 @@ export const addLiquidity = } dispatch({ - type: HIDE_LOADING, + type: HIDE_DEX_LOADING, }); }; @@ -354,7 +352,7 @@ export const addLiquidityEth = try { const _routerContract = routerContract(network); dispatch({ - type: SHOW_LOADING, + type: SHOW_DEX_LOADING, }); //input params const etherAmount = ethToken.amount; @@ -417,7 +415,7 @@ export const addLiquidityEth = } dispatch({ - type: HIDE_LOADING, + type: HIDE_DEX_LOADING, }); }; @@ -510,7 +508,6 @@ export const removeLiquidityEth = const tokenAmountMin = "0"; const lpTokenAmount = lpAmount; - console.log({ ethToken, erc20Token, lpAmount }); // deadline should be passed in minites in calculation const _deadlineUnix = getUnixTime(deadline); @@ -617,11 +614,39 @@ export const confirmAllowance = const _routerContract = routerContract(network); dispatch({ - type: SHOW_LOADING, + type: SHOW_DEX_LOADING, }); await _tokenContract.methods .approve(_routerContract._address, balance) - .send({ from: account }); + .send({ from: account }, function (error, transactionHash) { + if (error) { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { type: "token_approve", hash: null, status: "failed" }, + }); + } else { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { type: "token_approve", hash: transactionHash }, + }); + } + }) + .on("receipt", async function (receipt) { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { + type: "token_approve", + status: "success", + result: {}, // add result data for reciept + }, + }); + }) + .on("error", async function (error) { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { type: "token_approve", status: "failed" }, + }); + }); dispatch({ type: APPROVE_TOKEN, @@ -635,7 +660,7 @@ export const confirmAllowance = }); } dispatch({ - type: HIDE_LOADING, + type: HIDE_DEX_LOADING, }); }; @@ -693,7 +718,39 @@ export const confirmLPAllowance = await _pairContract.methods .approve(_routerContractAddress, balance) - .send({ from: account }); + .send({ from: account }, function (error, transactionHash) { + if (error) { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { + type: "lp_token_approve", + hash: null, + status: "failed", + }, + }); + } else { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { type: "lp_token_approve", hash: transactionHash }, + }); + } + }) + .on("receipt", async function (receipt) { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { + type: "lp_token_approve", + status: "success", + result: {}, // add result data + }, + }); + }) + .on("error", async function (error) { + dispatch({ + type: UPDATE_TRANSACTION_STATUS, + payload: { type: "lp_token_approve", status: "failed" }, + }); + }); dispatch({ type: APPROVE_LP_TOKENS, diff --git a/frontend/src/actions/farmActions.js b/frontend/src/actions/farmActions.js index 8469a4ed..3422b7d2 100644 --- a/frontend/src/actions/farmActions.js +++ b/frontend/src/actions/farmActions.js @@ -293,6 +293,7 @@ export const getFarmInfo = poolWeight: new BigNumber(poolInfo?.allocPoint) .div(totalAllocPoint) .toString(), + lockedLp: fromWei(poolInfo?.lpAmount), }; dispatch({ @@ -363,10 +364,11 @@ export const getLpBalanceFarm = const balObject = {}; balObject[pairAddress] = { lpBalance, - poolLpTokens: new BigNumber(fromWei(totalSupply)) + poolLpTokens: new BigNumber(fromWei(totalSupply)) // multiply this value with eth price to get correct pool total Liquidity usd value .times(lpTokenPrice) .toFixed(0) .toString(), + lpTokenPrice, // multiply this value with eth price to get correct lp price in usd }; dispatch({ diff --git a/frontend/src/components/common/SelectTokenDialog.js b/frontend/src/components/common/SelectTokenDialog.js index 741d39da..9fad9377 100644 --- a/frontend/src/components/common/SelectTokenDialog.js +++ b/frontend/src/components/common/SelectTokenDialog.js @@ -57,7 +57,7 @@ const useStyles = makeStyles((theme) => ({ }, closeIcon: { - color: "#f6f6f6", + color: theme.palette.textColors.heading, fontSize: 24, [theme.breakpoints.down("sm")]: { fontSize: 20, diff --git a/frontend/src/components/pages/AddLiquidity/AddCard.js b/frontend/src/components/pages/AddLiquidity/AddCard.js index 70d26ac4..0d89ac9a 100644 --- a/frontend/src/components/pages/AddLiquidity/AddCard.js +++ b/frontend/src/components/pages/AddLiquidity/AddCard.js @@ -1,10 +1,4 @@ -import { - Button, - Card, - CircularProgress, - IconButton, - makeStyles, -} from "@material-ui/core"; +import { Button, Card, IconButton, makeStyles } from "@material-ui/core"; import { connect } from "react-redux"; import KeyboardBackspaceIcon from "@material-ui/icons/KeyboardBackspace"; import { useCallback, useEffect, useMemo, useState } from "react"; @@ -235,6 +229,7 @@ const AddCard = (props) => { pairContractData, transaction, tokenList, + dexLoading, }, addLiquidityEth, checkAllowance, @@ -400,7 +395,6 @@ const AddCard = (props) => { }; const loadPairReserves = async () => { - // console.log('loading pair reserves after add liquidity') let _pairAddress = currentPairAddress(); if (!_pairAddress) { @@ -746,6 +740,11 @@ const AddCard = (props) => { }; const handleAction = () => { + if (dexLoading) { + setSwapDialog(true); + return; + } + if (currentTokenApprovalStatus()) { handleAddLiquidity(); } else { @@ -762,6 +761,11 @@ const AddCard = (props) => { return "Please wait..."; } else if (addStatus.disabled) { return addStatus.message; + } else if ( + ["add", "token_approve"].includes(transaction.type) && + transaction.status === "pending" + ) { + return "Pending Transaction..."; } else { return !currentTokenApprovalStatus() ? currApproveBtnText() @@ -775,13 +779,24 @@ const AddCard = (props) => { return; } - if (transaction.type === "add" && transaction.status === "success") { + if ( + ["add", "token_approve"].includes(transaction.type) && + transaction.status === "success" + ) { getAccountBalance(selectedToken0, currentNetwork); getAccountBalance(selectedToken1, currentNetwork); } if ( - (transaction.type === "add" && transaction.status === "success") || + ["add", "token_approve"].includes(transaction.type) && + transaction.status === "pending" + ) { + setSwapDialog(true); + } + + if ( + (["add", "token_approve"].includes(transaction.type) && + transaction.status === "success") || transaction.status === "failed" ) { setSwapDialog(true); @@ -790,10 +805,16 @@ const AddCard = (props) => { const handleConfirmSwapClose = (value) => { setSwapDialog(value); - if (transaction.type === "add" && transaction.status === "success") { + if ( + ["add", "token_approve"].includes(transaction.type) && + transaction.status === "success" + ) { store.dispatch({ type: START_TRANSACTION }); clearInputState(); - } else if (transaction.type === "add" && transaction.status === "failed") { + } else if ( + ["add", "token_approve"].includes(transaction.type) && + transaction.status === "failed" + ) { store.dispatch({ type: START_TRANSACTION }); } }; @@ -908,19 +929,7 @@ const AddCard = (props) => { onClick={handleAction} className={classes.addLiquidityButton} > - {!addStatus.disabled && loading ? ( - - {transaction.status === "pending" && "Transaction Pending"} - - - - ) : ( - currentButton() - )} + {currentButton()} diff --git a/frontend/src/components/pages/AddLiquidity/RemoveCard.js b/frontend/src/components/pages/AddLiquidity/RemoveCard.js index 7dc89b8c..5eefa562 100644 --- a/frontend/src/components/pages/AddLiquidity/RemoveCard.js +++ b/frontend/src/components/pages/AddLiquidity/RemoveCard.js @@ -1,4 +1,5 @@ import { + Button, Card, CircularProgress, IconButton, @@ -6,7 +7,7 @@ import { } from "@material-ui/core"; import { connect } from "react-redux"; import KeyboardBackspaceIcon from "@material-ui/icons/KeyboardBackspace"; -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import SwapSettings from "../../common/SwapSettings"; import CustomButton from "../../Buttons/CustomButton"; import ArrowDownwardIcon from "@material-ui/icons/ArrowDownward"; @@ -206,23 +207,23 @@ const useStyles = makeStyles((theme) => ({ borderRadius: "30%", }, removeBtn: { - marginTop: 30, - backgroundColor: theme.palette.primary.pbr, - color: theme.palette.primary.buttonText, - - width: "fit-content", + marginTop: 20, + backgroundColor: "rgba(224, 7, 125, 0.9)", + color: "white", + width: "95%", textTransform: "none", - fontSize: 17, + fontSize: 19, borderRadius: 20, willChange: "transform", transition: "transform 450ms ease 0s", transform: "perspective(1px) translateZ(0px)", - padding: "12px 30px 12px 30px", + padding: "10px 50px 10px 50px", "&:hover": { background: "rgba(224, 7, 125, 0.7)", }, [theme.breakpoints.down("sm")]: { - fontSize: 14, + marginTop: 5, + fontSize: 15, }, }, approveBtn: { @@ -249,7 +250,7 @@ const useStyles = makeStyles((theme) => ({ })); const RemoveCard = ({ - account: { currentNetwork, currentAccount, connected }, + account: { currentNetwork, currentAccount, connected, loading }, dex: { lpApproved, lpBalance, @@ -539,13 +540,23 @@ const RemoveCard = ({ return; } - if (transaction.type === "remove" && transaction.status === "success") { + if ( + ["remove", "lp_token_approve"].includes(transaction.type) && + transaction.status === "success" + ) { getAccountBalance(selectedToken0, currentNetwork); getAccountBalance(selectedToken1, currentNetwork); } if ( - transaction.type === "remove" && + ["remove", "lp_token_approve"].includes(transaction.type) && + transaction.status === "pending" + ) { + setSwapDialog(true); + } + + if ( + ["remove", "lp_token_approve"].includes(transaction.type) && (transaction.status === "success" || transaction.status === "failed") ) { setSwapDialog(true); @@ -554,11 +565,14 @@ const RemoveCard = ({ const handleConfirmSwapClose = (value) => { setSwapDialog(value); - if (transaction.type === "remove" && transaction.status === "success") { + if ( + ["remove", "lp_token_approve"].includes(transaction.type) && + transaction.status === "success" + ) { store.dispatch({ type: START_TRANSACTION }); handleClearState(); } else if ( - transaction.type === "remove" && + ["remove", "lp_token_approve"].includes(transaction.type) && transaction.status === "failed" ) { store.dispatch({ type: START_TRANSACTION }); @@ -569,6 +583,55 @@ const RemoveCard = ({ return (parseInt(token1.decimals) + parseInt(token2.decimals)) / 2; }; + const disableStatus = useMemo(() => { + if (!connected) { + return true; + } + + return ( + loading || + new BigNumber(currentLpBalance()).eq(0) || + new BigNumber(liquidityPercent).eq(0) + ); + }, [connected, loading, liquidityPercent, currentLpBalance()]); + + const currentButton = useMemo(() => { + if (!connected) { + return "Connect Wallet"; + } + + if (loading) { + return "Please wait..."; + } else if (new BigNumber(currentLpBalance()).eq(0)) { + return "No liquidity to remove"; + } else if ( + ["remove", "lp_token_approve"].includes(transaction.type) && + transaction.status === "pending" + ) { + return "Pending Transaction..."; + } else { + return !currentLpApproved() ? "Approve LP token" : "Remove Liquidity"; + } + }, [ + connected, + loading, + transaction, + currentLpApproved(), + currentLpBalance(), + ]); + + const handleAction = () => { + if (dexLoading) { + setSwapDialog(true); + return; + } + if (!currentLpApproved()) { + handleConfirmAllowance(); + } else { + handleRemoveLiquidity(); + } + }; + return ( <> @@ -677,7 +740,7 @@ const RemoveCard = ({
- {dexLoading ? ( + {loading ? (
@@ -716,8 +779,8 @@ const RemoveCard = ({ (new BigNumber(liquidityPercent).eq(0) && "* Choose your amount of first to remove liquidity.")}
-
- */} + {/* Remove - -
+ */} + + {/* */} diff --git a/frontend/src/components/pages/Farms/Farm.js b/frontend/src/components/pages/Farms/Farm.js index 499c87c1..becb7da2 100644 --- a/frontend/src/components/pages/Farms/Farm.js +++ b/frontend/src/components/pages/Farms/Farm.js @@ -250,6 +250,19 @@ const Farm = (props) => { return usdValue; }, [ethPrice, lpBalance, farmPoolAddress]); + const totalValueLockedUSD = useMemo(() => { + if (!ethPrice || !farmData?.lockedLp || !lpBalance) { + return "0"; + } + + const lpTokenPrice = lpBalance?.[farmPoolAddress]?.lpTokenPrice; + const lockedLpTokens = farmData?.lockedLp; + return new BigNumber(lockedLpTokens) + .times(lpTokenPrice) + .times(ethPrice?.[0]) + .toString(); + }, [ethPrice, farmData, lpBalance, farmPoolAddress]); + const parseStakedAmount = useMemo( () => farms && @@ -454,6 +467,12 @@ const Farm = (props) => {
+
Total Value Locked:
+
+ ${formattedNum(totalValueLockedUSD)} +
+
+
Total Liquidity:
${formattedNum(totalPoolLiquidityUSDValue)} diff --git a/frontend/src/components/pages/Swap/Swap.js b/frontend/src/components/pages/Swap/Swap.js index ccb9ff08..c72e15d4 100644 --- a/frontend/src/components/pages/Swap/Swap.js +++ b/frontend/src/components/pages/Swap/Swap.js @@ -211,6 +211,7 @@ const Swap = (props) => { token1Out, priceLoading, tokenList, + dexLoading, }, checkAllowance, confirmAllowance, @@ -491,6 +492,7 @@ const Swap = (props) => { disabled: true, message: "Not enough liquidity for this trade!", }); + return; } // update current price ratio based on trade amounts @@ -566,6 +568,7 @@ const Swap = (props) => { disabled: true, message: "Not enough liquidity for this trade!", }); + return; } // update current price ratio based on trade amounts @@ -717,6 +720,11 @@ const Swap = (props) => { }; const handleAction = () => { + if (dexLoading) { + setSwapDialog(true); + return; + } + if (currentTokenApprovalStatus()) { handleSwapToken(); } else { @@ -734,10 +742,10 @@ const Swap = (props) => { } else if (swapStatus.disabled) { return swapStatus.message; } else if ( - transaction.type === "swap" && + ["swap", "token_approve"].includes(transaction.type) && transaction.status === "pending" ) { - return "Pending Swap Transaction..."; + return "Pending Transaction..."; } else { return !currentTokenApprovalStatus() ? "Approve" : swapStatus.message; } @@ -749,14 +757,17 @@ const Swap = (props) => { return; } - if (transaction.type === "swap" && transaction.status === "success") { + if ( + ["swap", "token_approve"].includes(transaction.type) && + transaction.status === "success" + ) { localStorage.priceTracker = "None"; getAccountBalance(selectedToken0, currentNetwork); getAccountBalance(selectedToken1, currentNetwork); } if ( - transaction.type === "swap" && + ["swap", "token_approve"].includes(transaction.type) && (transaction.status === "success" || transaction.status === "failed") && !swapDialogOpen ) { @@ -767,10 +778,16 @@ const Swap = (props) => { const handleConfirmSwapClose = (value) => { setSwapDialog(value); - if (transaction.type === "swap" && transaction.status === "success") { + if ( + ["swap", "token_approve"].includes(transaction.type) && + transaction.status === "success" + ) { store.dispatch({ type: START_TRANSACTION }); clearInputState(); - } else if (transaction.type === "swap" && transaction.status === "failed") { + } else if ( + ["swap", "token_approve"].includes(transaction.type) && + transaction.status === "failed" + ) { store.dispatch({ type: START_TRANSACTION }); } }; diff --git a/frontend/src/constants.js b/frontend/src/constants.js index e74be839..2190a386 100644 --- a/frontend/src/constants.js +++ b/frontend/src/constants.js @@ -63,7 +63,7 @@ export const factoryAddresses = { export const farmAddresses = { ethereum: testing - ? "0x855CC2d28210F5A1074546ba71DF04EE4612843B" + ? "0x57eA8360A59468112cE669EA8bFb2169062EAF0d" : "0xBaF15D830ddeB6c11fFae8890d9c902D8dF1f3E7", }; diff --git a/frontend/src/contracts/abi/PolkaBridgeFarm.json b/frontend/src/contracts/abi/PolkaBridgeFarm.json index b660f89e..c223e816 100644 --- a/frontend/src/contracts/abi/PolkaBridgeFarm.json +++ b/frontend/src/contracts/abi/PolkaBridgeFarm.json @@ -296,6 +296,7 @@ "name": "lpToken", "type": "address" }, + { "internalType": "uint256", "name": "lpAmount", "type": "uint256" }, { "internalType": "uint256", "name": "allocPoint", "type": "uint256" }, { "internalType": "uint256",