From f2e7db02604ac74b7150beef770ac6f10f69652a Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 6 Apr 2022 09:47:41 +0100 Subject: [PATCH] Pool components UI refactor (#1295) * reorder UI * refactor with new PoolSection component * move all the things * layout tweaks * fix pool data without wallet * fix undefined user pool share * fix max remove calculation * make conversion use our decimals definition --- .../Token/index.module.css} | 16 +- src/components/@shared/Token/index.tsx | 40 +++++ .../AssetActionHistoryTable.module.css | 5 +- .../Pool/{ => Actions}/Header.module.css | 0 .../Pool/{ => Actions}/Header.tsx | 0 .../index.module.css} | 0 .../Pool/{Actions.tsx => Actions/index.tsx} | 2 +- .../Asset/AssetActions/Pool/Add/FormAdd.tsx | 41 ++--- .../Asset/AssetActions/Pool/Add/Output.tsx | 50 +----- .../Asset/AssetActions/Pool/Add/index.tsx | 58 +++--- .../AssetActions/Pool/Graph/Nav.module.css | 6 +- .../AssetActions/Pool/Graph/index.module.css | 14 +- .../Asset/AssetActions/Pool/Graph/index.tsx | 13 +- .../Asset/AssetActions/Pool/Remove/_utils.ts | 19 ++ .../Asset/AssetActions/Pool/Remove/index.tsx | 91 +++++----- .../Pool/Section/Title.module.css | 13 ++ .../Asset/AssetActions/Pool/Section/Title.tsx | 26 +++ .../Pool/Section/index.module.css | 39 ++++ .../Asset/AssetActions/Pool/Section/index.tsx | 39 ++++ .../Pool/Sections/Update.module.css | 32 ++++ .../AssetActions/Pool/Sections/Update.tsx | 17 ++ .../Pool/Sections/index.module.css | 20 +++ .../AssetActions/Pool/Sections/index.tsx | 130 ++++++++++++++ .../Asset/AssetActions/Pool/Token.tsx | 27 --- .../AssetActions/Pool/TokenList.module.css | 43 ----- .../Asset/AssetActions/Pool/TokenList.tsx | 51 ------ .../Asset/AssetActions/Pool/index.module.css | 75 -------- .../Asset/AssetActions/Pool/index.tsx | 170 +----------------- .../Asset/AssetActions/Trade/Output.tsx | 2 +- .../Profile/History/PoolShares/Liquidity.tsx | 2 +- 30 files changed, 503 insertions(+), 538 deletions(-) rename src/components/{Asset/AssetActions/Pool/Token.module.css => @shared/Token/index.module.css} (67%) create mode 100644 src/components/@shared/Token/index.tsx rename src/components/Asset/AssetActions/Pool/{ => Actions}/Header.module.css (100%) rename src/components/Asset/AssetActions/Pool/{ => Actions}/Header.tsx (100%) rename src/components/Asset/AssetActions/Pool/{Actions.module.css => Actions/index.module.css} (100%) rename src/components/Asset/AssetActions/Pool/{Actions.tsx => Actions/index.tsx} (98%) create mode 100644 src/components/Asset/AssetActions/Pool/Remove/_utils.ts create mode 100644 src/components/Asset/AssetActions/Pool/Section/Title.module.css create mode 100644 src/components/Asset/AssetActions/Pool/Section/Title.tsx create mode 100644 src/components/Asset/AssetActions/Pool/Section/index.module.css create mode 100644 src/components/Asset/AssetActions/Pool/Section/index.tsx create mode 100644 src/components/Asset/AssetActions/Pool/Sections/Update.module.css create mode 100644 src/components/Asset/AssetActions/Pool/Sections/Update.tsx create mode 100644 src/components/Asset/AssetActions/Pool/Sections/index.module.css create mode 100644 src/components/Asset/AssetActions/Pool/Sections/index.tsx delete mode 100644 src/components/Asset/AssetActions/Pool/Token.tsx delete mode 100644 src/components/Asset/AssetActions/Pool/TokenList.module.css delete mode 100644 src/components/Asset/AssetActions/Pool/TokenList.tsx delete mode 100644 src/components/Asset/AssetActions/Pool/index.module.css diff --git a/src/components/Asset/AssetActions/Pool/Token.module.css b/src/components/@shared/Token/index.module.css similarity index 67% rename from src/components/Asset/AssetActions/Pool/Token.module.css rename to src/components/@shared/Token/index.module.css index 29323a4e7..d8526518f 100644 --- a/src/components/Asset/AssetActions/Pool/Token.module.css +++ b/src/components/@shared/Token/index.module.css @@ -1,6 +1,5 @@ .token { font-weight: var(--font-weight-bold); - margin-bottom: calc(var(--spacer) / 4); white-space: nowrap; } @@ -26,6 +25,21 @@ height: var(--font-size-base); } +.conversion { + composes: token; + margin-bottom: 0; + font-weight: var(--font-weight-base) !important; + font-size: var(--font-size-small); + padding-left: var(--font-size-base); + padding-top: calc(var(--spacer) / 10); +} + +.conversion strong { + font-size: var(--font-size-base); + color: var(--font-color-heading); + line-height: 1; +} + /* Data Token Icon Style */ .icon:not([class*='OCEAN']) path { fill: var(--brand-violet); diff --git a/src/components/@shared/Token/index.tsx b/src/components/@shared/Token/index.tsx new file mode 100644 index 000000000..47576acdc --- /dev/null +++ b/src/components/@shared/Token/index.tsx @@ -0,0 +1,40 @@ +import React, { ReactElement } from 'react' +import styles from './index.module.css' +import PriceUnit from '@shared/Price/PriceUnit' +import Logo from '@shared/atoms/Logo' +import Decimal from 'decimal.js' +import Conversion from '@shared/Price/Conversion' +import { MAX_DECIMALS } from '@utils/constants' + +export default function Token({ + symbol, + balance, + conversion, + noIcon, + size +}: { + symbol: string + balance: string + conversion?: Decimal + noIcon?: boolean + size?: 'small' | 'mini' +}): ReactElement { + return ( + <> +
+
+ +
+ +
+ {conversion?.greaterThan(0) && ( + + )} + + ) +} diff --git a/src/components/Asset/AssetActions/AssetActionHistoryTable.module.css b/src/components/Asset/AssetActions/AssetActionHistoryTable.module.css index 63be54ad2..a46132d31 100644 --- a/src/components/Asset/AssetActions/AssetActionHistoryTable.module.css +++ b/src/components/Asset/AssetActions/AssetActionHistoryTable.module.css @@ -1,6 +1,5 @@ .actions { - composes: container from './Pool/index.module.css'; - border-top: 1px solid var(--border-color); + composes: section from './Pool/Section/index.module.css'; margin-top: calc(var(--spacer) / 1.5); padding: calc(var(--spacer) / 1.5); background: var(--background-highlight); @@ -12,7 +11,7 @@ } .title { - composes: title from './Pool/index.module.css'; + composes: title from './Pool/Section/Title.module.css'; margin-bottom: 0; display: flex; align-items: center; diff --git a/src/components/Asset/AssetActions/Pool/Header.module.css b/src/components/Asset/AssetActions/Pool/Actions/Header.module.css similarity index 100% rename from src/components/Asset/AssetActions/Pool/Header.module.css rename to src/components/Asset/AssetActions/Pool/Actions/Header.module.css diff --git a/src/components/Asset/AssetActions/Pool/Header.tsx b/src/components/Asset/AssetActions/Pool/Actions/Header.tsx similarity index 100% rename from src/components/Asset/AssetActions/Pool/Header.tsx rename to src/components/Asset/AssetActions/Pool/Actions/Header.tsx diff --git a/src/components/Asset/AssetActions/Pool/Actions.module.css b/src/components/Asset/AssetActions/Pool/Actions/index.module.css similarity index 100% rename from src/components/Asset/AssetActions/Pool/Actions.module.css rename to src/components/Asset/AssetActions/Pool/Actions/index.module.css diff --git a/src/components/Asset/AssetActions/Pool/Actions.tsx b/src/components/Asset/AssetActions/Pool/Actions/index.tsx similarity index 98% rename from src/components/Asset/AssetActions/Pool/Actions.tsx rename to src/components/Asset/AssetActions/Pool/Actions/index.tsx index 5650c1e0d..a653d4d10 100644 --- a/src/components/Asset/AssetActions/Pool/Actions.tsx +++ b/src/components/Asset/AssetActions/Pool/Actions/index.tsx @@ -1,7 +1,7 @@ import React, { ReactElement, useState } from 'react' import Loader from '@shared/atoms/Loader' import Button from '@shared/atoms/Button' -import styles from './Actions.module.css' +import styles from './index.module.css' import ExplorerLink from '@shared/ExplorerLink' import SuccessConfetti from '@shared/SuccessConfetti' import { useWeb3 } from '@context/Web3' diff --git a/src/components/Asset/AssetActions/Pool/Add/FormAdd.tsx b/src/components/Asset/AssetActions/Pool/Add/FormAdd.tsx index 735adbc47..0dda5bec4 100644 --- a/src/components/Asset/AssetActions/Pool/Add/FormAdd.tsx +++ b/src/components/Asset/AssetActions/Pool/Add/FormAdd.tsx @@ -14,29 +14,21 @@ import { useWeb3 } from '@context/Web3' import { isValidNumber } from '@utils/numbers' import Decimal from 'decimal.js' import { useAsset } from '@context/Asset' -import { LoggerInstance, Pool } from '@oceanprotocol/lib' +import { Pool } from '@oceanprotocol/lib' +import { usePool } from '@context/Pool' export default function FormAdd({ - tokenInAddress, - tokenInSymbol, amountMax, - totalPoolTokens, - totalBalance, - poolAddress, setNewPoolTokens, setNewPoolShare }: { - tokenInAddress: string - tokenInSymbol: string amountMax: string - totalPoolTokens: string - totalBalance: PoolBalance - poolAddress: string setNewPoolTokens: (value: string) => void setNewPoolShare: (value: string) => void }): ReactElement { const { balance, web3 } = useWeb3() const { isAssetNetwork } = useAsset() + const { poolData, poolInfo } = usePool() // Connect with form const { @@ -47,9 +39,9 @@ export default function FormAdd({ useEffect(() => { async function calculatePoolShares() { - if (!web3) return + if (!web3 || !poolData?.id || !poolInfo?.totalPoolTokens) return - if (!values.amount || !tokenInAddress) { + if (!values.amount || !poolInfo?.baseTokenAddress) { setNewPoolTokens('0') setNewPoolShare('0') return @@ -59,31 +51,32 @@ export default function FormAdd({ const poolInstance = new Pool(web3) const poolTokens = await poolInstance.calcPoolOutGivenSingleIn( - poolAddress, - tokenInAddress, + poolData.id, + poolInfo.baseTokenAddress, values.amount ) setNewPoolTokens(poolTokens) const newPoolShareDecimal = - isValidNumber(poolTokens) && isValidNumber(totalPoolTokens) + isValidNumber(poolTokens) && isValidNumber(poolInfo.totalPoolTokens) ? new Decimal(poolTokens) .dividedBy( - new Decimal(totalPoolTokens).plus(new Decimal(poolTokens)) + new Decimal(poolInfo.totalPoolTokens).plus( + new Decimal(poolTokens) + ) ) .mul(100) .toString() : '0' - totalBalance && setNewPoolShare(newPoolShareDecimal) + setNewPoolShare(newPoolShareDecimal) } calculatePoolShares() }, [ - tokenInAddress, + poolInfo?.baseTokenAddress, web3, values.amount, - totalBalance, - totalPoolTokens, + poolInfo?.totalPoolTokens, amountMax, - poolAddress, + poolData?.id, setNewPoolTokens, setNewPoolShare ]) @@ -93,7 +86,7 @@ export default function FormAdd({ @@ -111,7 +104,7 @@ export default function FormAdd({ min="0" value={values.amount} step="any" - prefix={tokenInSymbol} + prefix={poolInfo?.baseTokenSymbol} placeholder="0" field={field} form={form} diff --git a/src/components/Asset/AssetActions/Pool/Add/Output.tsx b/src/components/Asset/AssetActions/Pool/Add/Output.tsx index e02b39902..26fc0f710 100644 --- a/src/components/Asset/AssetActions/Pool/Add/Output.tsx +++ b/src/components/Asset/AssetActions/Pool/Add/Output.tsx @@ -1,60 +1,24 @@ -import { FormikContextType, useFormikContext } from 'formik' -import React, { ReactElement, useEffect, useState } from 'react' -import { FormAddLiquidity } from '.' +import React, { ReactElement } from 'react' import FormHelp from '@shared/FormInput/Help' -import Token from '../Token' +import Token from '../../../../@shared/Token' import styles from './Output.module.css' -import Decimal from 'decimal.js' import content from '../../../../../../content/price.json' +import { usePool } from '@context/Pool' export default function Output({ newPoolTokens, - newPoolShare, - swapFee, - datatokenSymbol, - totalPoolTokens, - totalBalance + newPoolShare }: { newPoolTokens: string newPoolShare: string - swapFee: string - datatokenSymbol: string - totalPoolTokens: string - totalBalance: PoolBalance }): ReactElement { - const { help, titleIn, titleOut } = content.pool.add.output - - // Connect with form - const { values }: FormikContextType = useFormikContext() - - const [poolOcean, setPoolOcean] = useState('0') - const [poolDatatoken, setPoolDatatoken] = useState('0') - - useEffect(() => { - if (!values.amount || !totalBalance || !totalPoolTokens || !newPoolTokens) - return - const newPoolSupply = new Decimal(totalPoolTokens).plus(newPoolTokens) - const ratio = new Decimal(newPoolTokens).div(newPoolSupply) - const newOceanReserve = new Decimal(totalBalance.baseToken).plus( - values.amount - ) - const newDtReserve = new Decimal(totalBalance.datatoken) - const poolOcean = newOceanReserve.mul(ratio).toString() - const poolDatatoken = newDtReserve.mul(ratio).toString() - setPoolOcean(poolOcean) - setPoolDatatoken(poolDatatoken) - }, [ - values.amount, - totalBalance, - totalPoolTokens, - newPoolShare, - newPoolTokens - ]) + const { help, titleIn } = content.pool.add.output + const { poolInfo } = usePool() return ( <> - {help.replace('SWAPFEE', swapFee)} + {help.replace('SWAPFEE', poolInfo?.liquidityProviderSwapFee)}

{titleIn}

diff --git a/src/components/Asset/AssetActions/Pool/Add/index.tsx b/src/components/Asset/AssetActions/Pool/Add/index.tsx index d70fee089..8e2ef6c78 100644 --- a/src/components/Asset/AssetActions/Pool/Add/index.tsx +++ b/src/components/Asset/AssetActions/Pool/Add/index.tsx @@ -1,5 +1,5 @@ import React, { ReactElement, useState, useEffect } from 'react' -import Header from '../Header' +import Header from '../Actions/Header' import { toast } from 'react-toastify' import Actions from '../Actions' import * as Yup from 'yup' @@ -25,28 +25,15 @@ const initialValues: FormAddLiquidity = { } export default function Add({ - setShowAdd, - poolAddress, - totalPoolTokens, - totalBalance, - swapFee, - datatokenSymbol, - tokenInSymbol, - tokenInAddress + setShowAdd }: { setShowAdd: (show: boolean) => void - poolAddress: string - totalPoolTokens: string - totalBalance: PoolBalance - swapFee: string - datatokenSymbol: string - tokenInSymbol: string - tokenInAddress: string }): ReactElement { const { accountId, balance, web3 } = useWeb3() const { isAssetNetwork } = useAsset() - const { fetchAllData } = usePool() + const { poolData, poolInfo, fetchAllData } = usePool() const { debug } = useUserPreferences() + const [txId, setTxId] = useState() const [amountMax, setAmountMax] = useState() const [newPoolTokens, setNewPoolTokens] = useState('0') @@ -67,15 +54,22 @@ export default function Add({ // Get maximum amount for OCEAN useEffect(() => { - if (!web3 || !accountId || !isAssetNetwork || !poolAddress) return + if ( + !web3 || + !accountId || + !isAssetNetwork || + !poolData?.id || + !poolInfo?.baseTokenAddress + ) + return async function getMaximum() { try { const poolInstance = new Pool(web3) const poolReserve = await poolInstance.getReserve( - poolAddress, - tokenInAddress + poolData.id, + poolInfo.baseTokenAddress ) const amountMaxPool = calcMaxExactIn(poolReserve) @@ -93,8 +87,8 @@ export default function Add({ web3, accountId, isAssetNetwork, - poolAddress, - tokenInAddress, + poolData?.id, + poolInfo?.baseTokenAddress, balance?.ocean ]) @@ -106,7 +100,7 @@ export default function Add({ try { const result = await poolInstance.joinswapExternAmountIn( accountId, - poolAddress, + poolData?.id, amount, minPoolAmountOut ) @@ -141,12 +135,7 @@ export default function Add({
{isWarningAccepted ? ( @@ -166,14 +155,7 @@ export default function Add({ )}
- + diff --git a/src/components/Asset/AssetActions/Pool/Graph/Nav.module.css b/src/components/Asset/AssetActions/Pool/Graph/Nav.module.css index 27741c4be..085ef452b 100644 --- a/src/components/Asset/AssetActions/Pool/Graph/Nav.module.css +++ b/src/components/Asset/AssetActions/Pool/Graph/Nav.module.css @@ -1,9 +1,11 @@ .type { - position: absolute; - bottom: -10px; + position: relative; z-index: 1; + width: 100%; text-align: center; padding: 5px var(--spacer); + border-top: 1px solid var(--border-color); + border-bottom: 1px solid var(--border-color); } .button, diff --git a/src/components/Asset/AssetActions/Pool/Graph/index.module.css b/src/components/Asset/AssetActions/Pool/Graph/index.module.css index 3a696bfcb..ccfc416fb 100644 --- a/src/components/Asset/AssetActions/Pool/Graph/index.module.css +++ b/src/components/Asset/AssetActions/Pool/Graph/index.module.css @@ -1,19 +1,17 @@ .graphWrap { + composes: container from '../Section/index.module.css'; + + padding: 0; + grid-column: full; min-height: 120px; display: flex; align-items: center; justify-content: center; - margin: calc(var(--spacer) / 6) -1.35rem calc(var(--spacer) / 1.5) -1.35rem; + flex-direction: column; + margin-bottom: calc(var(--spacer) / 2); position: relative; } -@media (min-width: 40rem) { - .graphWrap { - margin-left: -2rem; - margin-right: -2rem; - } -} - .graphWrap canvas { position: relative; z-index: 0; diff --git a/src/components/Asset/AssetActions/Pool/Graph/index.tsx b/src/components/Asset/AssetActions/Pool/Graph/index.tsx index f799edc45..b8d711282 100644 --- a/src/components/Asset/AssetActions/Pool/Graph/index.tsx +++ b/src/components/Asset/AssetActions/Pool/Graph/index.tsx @@ -11,17 +11,14 @@ import Decimal from 'decimal.js' import { lineStyle, GraphType } from './_constants' import Nav from './Nav' import { getOptions } from './_utils' -import { PoolData_poolSnapshots as PoolDataPoolSnapshots } from 'src/@types/subgraph/PoolData' import { usePrices } from '@context/Prices' import { MAX_DECIMALS } from '@utils/constants' +import { usePool } from '@context/Pool' -export default function Graph({ - poolSnapshots -}: { - poolSnapshots: PoolDataPoolSnapshots[] -}): ReactElement { +export default function Graph(): ReactElement { const { locale, currency } = useUserPreferences() const { prices } = usePrices() + const { poolSnapshots } = usePool() const darkMode = useDarkMode(false, darkModeConfig) const [options, setOptions] = useState>() @@ -104,13 +101,13 @@ export default function Graph({ ) : ( <> -
diff --git a/src/components/Asset/AssetActions/Pool/Remove/_utils.ts b/src/components/Asset/AssetActions/Pool/Remove/_utils.ts new file mode 100644 index 000000000..e1ffd0505 --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Remove/_utils.ts @@ -0,0 +1,19 @@ +import { calcMaxExactOut } from '@oceanprotocol/lib' +import Decimal from 'decimal.js' + +export async function getMax(poolTokens: string, totalPoolTokens: string) { + const poolTokensAmount = !poolTokens || poolTokens === '0' ? '1' : poolTokens + const maxTokensToRemoveFromPool = calcMaxExactOut(totalPoolTokens) + const poolTokensDecimal = new Decimal(poolTokensAmount) + const maxTokensToRemoveForUser = maxTokensToRemoveFromPool.greaterThan( + poolTokensDecimal + ) + ? poolTokensDecimal + : maxTokensToRemoveFromPool + + const maxPercent = new Decimal(100) + .mul(maxTokensToRemoveForUser) + .div(poolTokensDecimal) + + return maxPercent.toDecimalPlaces(0, Decimal.ROUND_DOWN).toString() +} diff --git a/src/components/Asset/AssetActions/Pool/Remove/index.tsx b/src/components/Asset/AssetActions/Pool/Remove/index.tsx index 538c1c858..b3cc7cf7b 100644 --- a/src/components/Asset/AssetActions/Pool/Remove/index.tsx +++ b/src/components/Asset/AssetActions/Pool/Remove/index.tsx @@ -6,11 +6,11 @@ import React, { useRef } from 'react' import styles from './index.module.css' -import Header from '../Header' +import Header from '../Actions/Header' import { toast } from 'react-toastify' import Actions from '../Actions' -import { LoggerInstance, Pool, calcMaxExactOut } from '@oceanprotocol/lib' -import Token from '../Token' +import { LoggerInstance, Pool } from '@oceanprotocol/lib' +import Token from '../../../../@shared/Token' import FormHelp from '@shared/FormInput/Help' import Button from '@shared/atoms/Button' import debounce from 'lodash.debounce' @@ -21,27 +21,18 @@ import Decimal from 'decimal.js' import { useAsset } from '@context/Asset' import content from '../../../../../../content/price.json' import { usePool } from '@context/Pool' +import { getMax } from './_utils' const slippagePresets = ['5', '10', '15', '25', '50'] export default function Remove({ - setShowRemove, - poolAddress, - poolTokens, - totalPoolTokens, - tokenOutAddress, - tokenOutSymbol + setShowRemove }: { setShowRemove: (show: boolean) => void - poolAddress: string - poolTokens: string - totalPoolTokens: string - tokenOutAddress: string - tokenOutSymbol: string }): ReactElement { const { accountId, web3 } = useWeb3() const { isAssetNetwork } = useAsset() - const { fetchAllData } = usePool() + const { poolData, poolInfo, poolInfoUser, fetchAllData } = usePool() const [amountPercent, setAmountPercent] = useState('0') const [amountMaxPercent, setAmountMaxPercent] = useState('100') @@ -62,7 +53,7 @@ export default function Remove({ try { const result = await poolInstance.exitswapPoolAmountIn( accountId, - poolAddress, + poolData?.id, amountPoolShares, minOceanAmount ) @@ -81,35 +72,23 @@ export default function Remove({ } } + // + // Calculate and set maximum shares user is able to remove + // useEffect(() => { - if (!accountId || !poolTokens) return + if (!accountId || !poolInfoUser?.poolShares || !poolInfo?.totalPoolTokens) + return - async function getMax() { - const poolTokensAmount = - !poolTokens || poolTokens === '0' ? '1' : poolTokens - const maxTokensToRemoveFromPool = calcMaxExactOut(totalPoolTokens) - const poolTokensDecimal = new Decimal(poolTokensAmount) - const maxTokensToRemoveForUser = maxTokensToRemoveFromPool.greaterThan( - poolTokensDecimal - ) - ? poolTokensDecimal - : maxTokensToRemoveFromPool - - const maxPercent = new Decimal(100) - .mul(maxTokensToRemoveForUser) - .div(poolTokensDecimal) - setAmountMaxPercent( - maxPercent.toDecimalPlaces(0, Decimal.ROUND_DOWN).toString() - ) - } - getMax() - }, [accountId, poolAddress, poolTokens, totalPoolTokens]) + getMax(poolInfoUser.poolShares, poolInfo.totalPoolTokens).then((max) => + setAmountMaxPercent(max) + ) + }, [accountId, poolInfoUser?.poolShares, poolInfo?.totalPoolTokens]) const getValues = useRef( debounce(async (newAmountPoolShares) => { const newAmountOcean = await poolInstance.calcSingleOutGivenPoolIn( - poolAddress, - tokenOutAddress, + poolData?.id, + poolInfo?.baseTokenAddress, newAmountPoolShares ) @@ -119,9 +98,21 @@ export default function Remove({ // Check and set outputs when amountPoolShares changes useEffect(() => { - if (!accountId || !poolTokens) return + if ( + !accountId || + !poolInfoUser?.poolShares || + !poolInfo?.totalPoolTokens || + !poolData?.id + ) + return getValues.current(amountPoolShares) - }, [amountPoolShares, accountId, poolTokens, poolAddress, totalPoolTokens]) + }, [ + amountPoolShares, + accountId, + poolInfoUser?.poolShares, + poolData?.id, + poolInfo?.totalPoolTokens + ]) useEffect(() => { if (!amountOcean || amountPercent === '0') { @@ -135,16 +126,16 @@ export default function Remove({ .toString() setMinOceanAmount(minOceanAmount.slice(0, 18)) - }, [slippage, amountOcean]) + }, [slippage, amountOcean, amountPercent]) // Set amountPoolShares based on set slider value function handleAmountPercentChange(e: ChangeEvent) { setAmountPercent(e.target.value) - if (!poolTokens) return + if (!poolInfoUser?.poolShares) return const amountPoolShares = new Decimal(e.target.value) .dividedBy(100) - .mul(new Decimal(poolTokens)) + .mul(new Decimal(poolInfoUser.poolShares)) .toString() setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`) @@ -156,7 +147,7 @@ export default function Remove({ const amountPoolShares = new Decimal(amountMaxPercent) .dividedBy(100) - .mul(new Decimal(poolTokens)) + .mul(new Decimal(poolInfoUser?.poolShares)) .toString() setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`) @@ -177,7 +168,7 @@ export default function Remove({ />
- +

{amountPercent}%

@@ -206,7 +197,7 @@ export default function Remove({

{content.pool.remove.output.titleOut} minimum

- +
{/*

{content.pool.remove.output.titleIn}

@@ -237,11 +228,11 @@ export default function Remove({ !isAssetNetwork || amountPercent === '0' || amountOcean === '0' || - poolTokens === '0' + poolInfo?.totalPoolTokens === '0' } txId={txId} - tokenAddress={tokenOutAddress} - tokenSymbol={tokenOutSymbol} + tokenAddress={poolInfo?.baseTokenAddress} + tokenSymbol={poolInfo?.baseTokenSymbol} />
) diff --git a/src/components/Asset/AssetActions/Pool/Section/Title.module.css b/src/components/Asset/AssetActions/Pool/Section/Title.module.css new file mode 100644 index 000000000..a376e0183 --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Section/Title.module.css @@ -0,0 +1,13 @@ +.title { + font-size: var(--font-size-base); + margin-bottom: calc(var(--spacer) / 3); + color: var(--color-secondary); +} + +.titlePostfix { + font-size: var(--font-size-mini); + font-family: var(--font-family-base); + font-weight: var(--font-weight-base); + display: inline-block; + margin-left: 0.3rem; +} diff --git a/src/components/Asset/AssetActions/Pool/Section/Title.tsx b/src/components/Asset/AssetActions/Pool/Section/Title.tsx new file mode 100644 index 000000000..67ddbe713 --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Section/Title.tsx @@ -0,0 +1,26 @@ +import Tooltip from '@shared/atoms/Tooltip' +import React from 'react' +import styles from './Title.module.css' + +export default function Title({ + title, + tooltip, + titlePostfix, + titlePostfixTitle +}: { + title: string + tooltip?: string + titlePostfix?: string + titlePostfixTitle?: string +}) { + return ( +

+ {title} {tooltip && }{' '} + {titlePostfix && ( + + {titlePostfix} + + )} +

+ ) +} diff --git a/src/components/Asset/AssetActions/Pool/Section/index.module.css b/src/components/Asset/AssetActions/Pool/Section/index.module.css new file mode 100644 index 000000000..1bca7a276 --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Section/index.module.css @@ -0,0 +1,39 @@ +.container { + margin-left: calc(-1 * var(--spacer) / 1.5); + margin-right: calc(-1 * var(--spacer) / 1.5); + padding: calc(var(--spacer) / 1.5) calc(var(--spacer) / 1.5) + calc(var(--spacer) / 2) calc(var(--spacer) / 1.5); +} + +@media (min-width: 40rem) { + .container { + padding-left: var(--spacer); + padding-right: var(--spacer); + margin-left: calc(-1 * var(--spacer)); + margin-right: calc(-1 * var(--spacer)); + } +} + +.section { + composes: container; + + border-top: 1px solid var(--border-color); + position: relative; +} + +.section.highlight { + background: var(--background-highlight); +} + +.section:first-child { + padding-top: 0; + border-top: 0; +} + +.grid { + display: grid; + gap: calc(var(--spacer) / 2); + grid-template-columns: + [full-start] minmax(13rem, 1fr) [break] minmax(7rem, 1fr) + [full-end]; +} diff --git a/src/components/Asset/AssetActions/Pool/Section/index.tsx b/src/components/Asset/AssetActions/Pool/Section/index.tsx new file mode 100644 index 000000000..dac852fb8 --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Section/index.tsx @@ -0,0 +1,39 @@ +import React, { ReactElement, ReactNode } from 'react' +import styles from './index.module.css' +import Title from './Title' + +export default function PoolSection({ + title, + tooltip, + titlePostfix, + titlePostfixTitle, + children, + highlight, + className +}: { + title?: string + children: ReactNode + tooltip?: string + titlePostfix?: string + titlePostfixTitle?: string + highlight?: boolean + className?: string +}): ReactElement { + return ( +
+ {title && ( + + )} + <div className={styles.grid}>{children}</div> + </div> + ) +} diff --git a/src/components/Asset/AssetActions/Pool/Sections/Update.module.css b/src/components/Asset/AssetActions/Pool/Sections/Update.module.css new file mode 100644 index 000000000..c45589126 --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Sections/Update.module.css @@ -0,0 +1,32 @@ +.update { + font-size: var(--font-size-mini); + color: var(--color-secondary); + text-align: center; + padding-top: calc(var(--spacer) / 4); + padding-bottom: calc(var(--spacer) / 3); +} + +/* .update:before { + content: ''; + width: 6px; + height: 6px; + border-radius: 50%; + display: inline-block; + border: 1px solid var(--brand-alert-green); + margin-right: 0.2rem; + margin-top: -0.1rem; + vertical-align: middle; + animation: pulse 2s ease-in-out infinite; + } + + @keyframes pulse { + 0% { + background: transparent; + } + 50% { + background: var(--brand-alert-green); + } + 100% { + background: transparent; + } + } */ diff --git a/src/components/Asset/AssetActions/Pool/Sections/Update.tsx b/src/components/Asset/AssetActions/Pool/Sections/Update.tsx new file mode 100644 index 000000000..1cd3bfb8a --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Sections/Update.tsx @@ -0,0 +1,17 @@ +import { usePool } from '@context/Pool' +import Button from '@shared/atoms/Button' +import React from 'react' +import styles from './Update.module.css' + +export default function Update() { + const { fetchAllData } = usePool() + + return ( + <div className={styles.update}> + <Button style="text" size="small" onClick={() => fetchAllData()}> + Refresh Data + </Button> + {/* Fetching every {refreshInterval / 1000} sec. */} + </div> + ) +} diff --git a/src/components/Asset/AssetActions/Pool/Sections/index.module.css b/src/components/Asset/AssetActions/Pool/Sections/index.module.css new file mode 100644 index 000000000..4dd63dc04 --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Sections/index.module.css @@ -0,0 +1,20 @@ +.dataToken { + font-size: var(--font-size-large); + text-align: center; +} + +.dataToken > div { + display: block; +} + +.dataTokenLinks { + display: flex; + justify-content: center; + font-size: var(--font-size-small); + margin-top: calc(var(--spacer) / 4); +} + +.dataTokenLinks a { + margin-left: calc(var(--spacer) / 3); + margin-right: calc(var(--spacer) / 3); +} diff --git a/src/components/Asset/AssetActions/Pool/Sections/index.tsx b/src/components/Asset/AssetActions/Pool/Sections/index.tsx new file mode 100644 index 000000000..858ef6bfd --- /dev/null +++ b/src/components/Asset/AssetActions/Pool/Sections/index.tsx @@ -0,0 +1,130 @@ +import { useAsset } from '@context/Asset' +import { usePool } from '@context/Pool' +import Tooltip from '@shared/atoms/Tooltip' +import ExplorerLink from '@shared/ExplorerLink' +import PriceUnit from '@shared/Price/PriceUnit' +import React from 'react' +import Graph from '../Graph' +import PoolSection from '../Section' +import Token from '../../../../@shared/Token' +import content from '../../../../../../content/price.json' +import styles from './index.module.css' +import Update from './Update' + +export default function PoolSections() { + const { asset } = useAsset() + const { poolData, poolInfo, poolInfoUser, poolInfoOwner } = usePool() + + return ( + <> + <PoolSection className={styles.dataToken}> + <PriceUnit price="1" symbol={poolInfo?.datatokenSymbol} size="large" />{' '} + ={' '} + <PriceUnit + price={`${poolData?.spotPrice}`} + symbol={poolInfo?.baseTokenSymbol} + size="large" + /> + <Tooltip content={content.pool.tooltips.price} /> + <div className={styles.dataTokenLinks}> + <ExplorerLink + networkId={asset?.chainId} + path={`address/${asset?.accessDetails?.addressOrId}`} + > + Pool + </ExplorerLink> + <ExplorerLink + networkId={asset?.chainId} + path={ + asset?.chainId === 2021000 || asset?.chainId === 1287 + ? `tokens/${asset?.services[0].datatokenAddress}` + : `token/${asset?.services[0].datatokenAddress}` + } + > + Datatoken + </ExplorerLink> + </div> + </PoolSection> + + <PoolSection + title="Your Value Locked" + titlePostfix={ + poolInfoUser?.poolShare && `${poolInfoUser?.poolShare}% of pool` + } + tooltip={content.pool.tooltips.liquidity.replace( + 'SWAPFEE', + poolInfo?.liquidityProviderSwapFee + )} + highlight + > + <Token + symbol={poolInfo?.baseTokenSymbol} + balance={poolInfoUser?.liquidity.toString()} + conversion={poolInfoUser?.liquidity} + /> + </PoolSection> + + <PoolSection + title="Owner Value Locked" + titlePostfix={`${poolInfoOwner?.poolShare}% of pool`} + > + <Token + symbol={poolInfo?.baseTokenSymbol} + balance={poolInfoOwner?.liquidity.toString()} + conversion={poolInfoOwner?.liquidity} + /> + </PoolSection> + + <PoolSection title="Total Value Locked"> + <Token + symbol={poolInfo?.baseTokenSymbol} + balance={poolInfo?.totalLiquidityInOcean.toString()} + conversion={poolInfo?.totalLiquidityInOcean} + /> + </PoolSection> + + <PoolSection + title="Pool Statistics" + titlePostfix={ + poolInfo?.weightDt && + `${poolInfo?.weightBaseToken}/${poolInfo?.weightDt}` + } + titlePostfixTitle={`Weight of ${poolInfo?.weightBaseToken}% ${poolInfo?.baseTokenSymbol} & ${poolInfo?.weightDt}% ${poolInfo?.datatokenSymbol}`} + > + <Graph /> + + <Token + symbol={poolInfo?.baseTokenSymbol} + balance={`${poolData?.baseTokenLiquidity}`} + size="mini" + /> + <Token + symbol={poolInfo?.datatokenSymbol} + balance={`${poolData?.datatokenLiquidity}`} + size="mini" + /> + + <Token + symbol="% pool fee" + balance={poolInfo?.liquidityProviderSwapFee} + noIcon + size="mini" + /> + <Token + symbol="% market fee" + balance={poolInfo?.publishMarketSwapFee} + noIcon + size="mini" + /> + <Token + symbol="% OPF fee" + balance={poolInfo?.opcFee} + noIcon + size="mini" + /> + </PoolSection> + + <Update /> + </> + ) +} diff --git a/src/components/Asset/AssetActions/Pool/Token.tsx b/src/components/Asset/AssetActions/Pool/Token.tsx deleted file mode 100644 index bc532a16a..000000000 --- a/src/components/Asset/AssetActions/Pool/Token.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { ReactElement } from 'react' -import styles from './Token.module.css' -import PriceUnit from '@shared/Price/PriceUnit' -import Logo from '@shared/atoms/Logo' - -export default function Token({ - symbol, - balance, - noIcon, - size -}: { - symbol: string - balance: string - noIcon?: boolean - size?: 'small' | 'mini' -}): ReactElement { - return ( - <div className={`${styles.token} ${size ? styles[size] : ''}`}> - <figure - className={`${styles.icon} ${symbol} ${noIcon ? styles.noIcon : ''}`} - > - <Logo noWordmark /> - </figure> - <PriceUnit price={balance} symbol={symbol} size={size} /> - </div> - ) -} diff --git a/src/components/Asset/AssetActions/Pool/TokenList.module.css b/src/components/Asset/AssetActions/Pool/TokenList.module.css deleted file mode 100644 index eadee0548..000000000 --- a/src/components/Asset/AssetActions/Pool/TokenList.module.css +++ /dev/null @@ -1,43 +0,0 @@ -.tokenlist { - margin-left: -2rem; - margin-right: -2rem; - padding: calc(var(--spacer) / 1.5) calc(var(--spacer) / 1.5) - calc(var(--spacer) / 2) calc(var(--spacer) / 1.5); - border-top: 1px solid var(--border-color); - position: relative; -} - -@media (min-width: 40rem) { - .tokenlist { - padding-left: var(--spacer); - padding-right: var(--spacer); - } -} - -.tokenlist.highlight { - background: var(--background-highlight); -} - -.tokens { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); -} - -.title { - composes: title from './index.module.css'; -} - -.totalLiquidity { - composes: token from './Token.module.css'; - margin-bottom: 0; - font-weight: var(--font-weight-base) !important; - font-size: var(--font-size-small); - padding-left: var(--font-size-base); - padding-top: calc(var(--spacer) / 10); -} - -.totalLiquidity strong { - font-size: var(--font-size-base); - color: var(--font-color-heading); - line-height: 1; -} diff --git a/src/components/Asset/AssetActions/Pool/TokenList.tsx b/src/components/Asset/AssetActions/Pool/TokenList.tsx deleted file mode 100644 index 53e45fdef..000000000 --- a/src/components/Asset/AssetActions/Pool/TokenList.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import Conversion from '@shared/Price/Conversion' -import React, { ReactElement, ReactNode } from 'react' -import Token from './Token' -import styles from './TokenList.module.css' -import Decimal from 'decimal.js' - -export default function TokenList({ - title, - children, - baseTokenValue, - baseTokenSymbol, - datatokenValue, - datatokenSymbol, - conversion, - highlight, - size = 'small' -}: { - title?: string | ReactNode - children?: ReactNode - baseTokenValue: string - baseTokenSymbol: string - datatokenValue?: string - datatokenSymbol?: string - conversion?: Decimal - highlight?: boolean - size?: 'small' | 'mini' -}): ReactElement { - return ( - <div className={`${styles.tokenlist} ${highlight ? styles.highlight : ''}`}> - {title && <h3 className={styles.title}>{title}</h3>} - <div className={styles.tokens}> - <Token symbol={baseTokenSymbol} balance={baseTokenValue} size={size} /> - - {conversion?.greaterThan(0) && ( - <Conversion - price={conversion.toString()} - className={styles.totalLiquidity} - /> - )} - {datatokenValue && ( - <Token - symbol={datatokenSymbol} - balance={datatokenValue} - size={size} - /> - )} - {children} - </div> - </div> - ) -} diff --git a/src/components/Asset/AssetActions/Pool/index.module.css b/src/components/Asset/AssetActions/Pool/index.module.css deleted file mode 100644 index a1e8b02ca..000000000 --- a/src/components/Asset/AssetActions/Pool/index.module.css +++ /dev/null @@ -1,75 +0,0 @@ -.container { - margin-left: -2rem; - margin-right: -2rem; - padding-left: calc(var(--spacer) / 1.5); - padding-right: calc(var(--spacer) / 1.5); -} - -.dataToken { - composes: container; - padding-bottom: calc(var(--spacer) / 1.5); - font-size: var(--font-size-large); - text-align: center; - position: relative; -} - -.dataTokenLinks { - display: flex; - justify-content: center; - font-size: var(--font-size-small); - margin-top: calc(var(--spacer) / 4); -} - -.dataTokenLinks a { - margin-left: calc(var(--spacer) / 3); - margin-right: calc(var(--spacer) / 3); -} - -.title { - font-size: var(--font-size-base); - margin-bottom: calc(var(--spacer) / 3); - color: var(--color-secondary); -} - -.titleInfo { - font-size: var(--font-size-mini); - font-family: var(--font-family-base); - font-weight: var(--font-weight-base); - display: inline-block; - margin-left: 0.3rem; -} - -.update { - composes: container; - font-size: var(--font-size-mini); - color: var(--color-secondary); - text-align: center; - border-top: 1px solid var(--border-color); - padding-top: calc(var(--spacer) / 4); - padding-bottom: calc(var(--spacer) / 4); -} - -/* .update:before { - content: ''; - width: 6px; - height: 6px; - border-radius: 50%; - display: inline-block; - border: 1px solid var(--brand-alert-green); - margin-right: 0.2rem; - margin-top: -0.1rem; - vertical-align: middle; - animation: pulse 2s ease-in-out infinite; -} - -@keyframes pulse { - 0% { - background: transparent; - } - 50% { - background: var(--brand-alert-green); - } - 100% { - background: transparent; - } -} */ diff --git a/src/components/Asset/AssetActions/Pool/index.tsx b/src/components/Asset/AssetActions/Pool/index.tsx index 2b9a94bfe..cdabf6838 100644 --- a/src/components/Asset/AssetActions/Pool/index.tsx +++ b/src/components/Asset/AssetActions/Pool/index.tsx @@ -1,37 +1,20 @@ import React, { ReactElement, useState } from 'react' -import styles from './index.module.css' -import stylesActions from './Actions.module.css' -import PriceUnit from '@shared/Price/PriceUnit' +import stylesActions from './Actions/index.module.css' import Button from '@shared/atoms/Button' import Add from './Add' import Remove from './Remove' -import Tooltip from '@shared/atoms/Tooltip' -import ExplorerLink from '@shared/ExplorerLink' -import TokenList from './TokenList' import AssetActionHistoryTable from '../AssetActionHistoryTable' -import Graph from './Graph' import { useAsset } from '@context/Asset' import { useWeb3 } from '@context/Web3' import PoolTransactions from '@shared/PoolTransactions' -import Decimal from 'decimal.js' -import content from '../../../../../content/price.json' + import { usePool } from '@context/Pool' -import Token from './Token' +import PoolSections from './Sections' export default function Pool(): ReactElement { - const { accountId } = useWeb3() const { isInPurgatory, asset, isAssetNetwork } = useAsset() - const { - poolData, - poolInfo, - poolInfoUser, - poolInfoOwner, - poolSnapshots, - hasUserAddedLiquidity, - isRemoveDisabled, - fetchAllData - // refreshInterval - } = usePool() + const { hasUserAddedLiquidity, isRemoveDisabled } = usePool() + const { accountId } = useWeb3() const [showAdd, setShowAdd] = useState(false) const [showRemove, setShowRemove] = useState(false) @@ -39,150 +22,13 @@ export default function Pool(): ReactElement { return ( <> {showAdd ? ( - <Add - setShowAdd={setShowAdd} - poolAddress={asset?.accessDetails?.addressOrId} - totalPoolTokens={poolInfo?.totalPoolTokens} - totalBalance={{ - baseToken: new Decimal(poolData?.baseTokenLiquidity).toString(), - datatoken: new Decimal(poolData?.datatokenLiquidity).toString() - }} - swapFee={poolInfo?.liquidityProviderSwapFee} - datatokenSymbol={poolInfo?.datatokenSymbol} - tokenInAddress={poolInfo?.baseTokenAddress} - tokenInSymbol={poolInfo?.baseTokenSymbol} - /> + <Add setShowAdd={setShowAdd} /> ) : showRemove ? ( - <Remove - setShowRemove={setShowRemove} - poolAddress={asset?.accessDetails?.addressOrId} - poolTokens={poolInfoUser?.poolShares} - totalPoolTokens={poolInfo?.totalPoolTokens} - tokenOutAddress={poolInfo?.baseTokenAddress} - tokenOutSymbol={poolInfo?.baseTokenSymbol} - /> + <Remove setShowRemove={setShowRemove} /> ) : ( <> - <div className={styles.dataToken}> - <PriceUnit - price="1" - symbol={poolInfo?.datatokenSymbol} - size="large" - />{' '} - ={' '} - <PriceUnit - price={`${poolData?.spotPrice}`} - symbol={poolInfo?.baseTokenSymbol} - size="large" - /> - <Tooltip content={content.pool.tooltips.price} /> - <div className={styles.dataTokenLinks}> - <ExplorerLink - networkId={asset?.chainId} - path={`address/${asset?.accessDetails?.addressOrId}`} - > - Pool - </ExplorerLink> - <ExplorerLink - networkId={asset?.chainId} - path={ - asset?.chainId === 2021000 || asset?.chainId === 1287 - ? `tokens/${asset?.services[0].datatokenAddress}` - : `token/${asset?.services[0].datatokenAddress}` - } - > - Datatoken - </ExplorerLink> - </div> - </div> - <TokenList - title={ - <> - Your Value Locked - <Tooltip - content={content.pool.tooltips.liquidity.replace( - 'SWAPFEE', - poolInfo?.liquidityProviderSwapFee - )} - /> - {poolInfoUser?.poolShare && ( - <span className={styles.titleInfo}> - {poolInfoUser?.poolShare}% of pool - </span> - )} - </> - } - baseTokenValue={poolInfoUser?.liquidity.toString()} - baseTokenSymbol={poolInfo?.baseTokenSymbol} - conversion={poolInfoUser?.liquidity} - highlight - /> - <TokenList - title={ - <> - Owner Value Locked - <span className={styles.titleInfo}> - {poolInfoOwner?.poolShare}% of pool - </span> - </> - } - baseTokenValue={poolInfoOwner?.liquidity.toString()} - baseTokenSymbol={poolInfo?.baseTokenSymbol} - conversion={poolInfoOwner?.liquidity} - /> - <TokenList - title={ - <> - Pool Statistics - {poolInfo?.weightDt && ( - <span - className={styles.titleInfo} - title={`Weight of ${poolInfo?.weightBaseToken}% ${poolInfo?.baseTokenSymbol} & ${poolInfo?.weightDt}% ${poolInfo?.datatokenSymbol}`} - > - {poolInfo?.weightBaseToken}/{poolInfo?.weightDt} - </span> - )} - <Graph poolSnapshots={poolSnapshots} /> - </> - } - baseTokenValue={`${poolInfo?.totalLiquidityInOcean}`} - baseTokenSymbol={poolInfo?.baseTokenSymbol} - conversion={poolInfo?.totalLiquidityInOcean} - /> + <PoolSections /> - <TokenList - size="mini" - baseTokenValue={`${poolData?.baseTokenLiquidity}`} - baseTokenSymbol={poolInfo?.baseTokenSymbol} - datatokenValue={`${poolData?.datatokenLiquidity}`} - datatokenSymbol={poolInfo?.datatokenSymbol} - > - <Token - symbol="% pool fee" - balance={poolInfo?.liquidityProviderSwapFee} - noIcon - size="mini" - /> - <Token - symbol="% market fee" - balance={poolInfo?.publishMarketSwapFee} - noIcon - size="mini" - /> - <Token - symbol="% OPF fee" - balance={poolInfo?.opcFee} - noIcon - size="mini" - /> - </TokenList> - - <div className={styles.update}> - <Button style="text" size="small" onClick={() => fetchAllData()}> - Refresh Data - </Button> - {/* Fetching every {refreshInterval / 1000} sec. */} - </div> <div className={stylesActions.actions}> <Button style="primary" diff --git a/src/components/Asset/AssetActions/Trade/Output.tsx b/src/components/Asset/AssetActions/Trade/Output.tsx index 9f36c2412..c80c0a104 100644 --- a/src/components/Asset/AssetActions/Trade/Output.tsx +++ b/src/components/Asset/AssetActions/Trade/Output.tsx @@ -1,7 +1,7 @@ import { FormikContextType, useFormikContext } from 'formik' import React, { ReactElement, useEffect, useState } from 'react' import { useAsset } from '@context/Asset' -import Token from '../Pool/Token' +import Token from '../../../@shared/Token' import styles from './Output.module.css' import Decimal from 'decimal.js' diff --git a/src/components/Profile/History/PoolShares/Liquidity.tsx b/src/components/Profile/History/PoolShares/Liquidity.tsx index 8dd4ffad2..3984fe758 100644 --- a/src/components/Profile/History/PoolShares/Liquidity.tsx +++ b/src/components/Profile/History/PoolShares/Liquidity.tsx @@ -1,7 +1,7 @@ import React from 'react' import Conversion from '@shared/Price/Conversion' import styles from './Liquidity.module.css' -import Token from '../../../Asset/AssetActions/Pool/Token' +import Token from '../../../@shared/Token' import { isValidNumber } from '@utils/numbers' import Decimal from 'decimal.js' import { AssetPoolShare } from './index'