mango-ui-v3/components/account-page/AccountOverview.tsx

654 lines
24 KiB
TypeScript
Raw Normal View History

2021-08-05 07:07:29 -07:00
import { useEffect, useCallback, useMemo, useState } from 'react'
2021-07-25 06:54:25 -07:00
import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
import styled from '@emotion/styled'
2021-07-29 06:19:32 -07:00
import { Menu } from '@headlessui/react'
2021-08-01 05:48:15 -07:00
import Link from 'next/link'
2021-07-29 06:19:32 -07:00
import {
2021-08-01 05:48:15 -07:00
ChartBarIcon,
2021-07-29 06:19:32 -07:00
CurrencyDollarIcon,
2021-08-01 05:48:15 -07:00
ExclamationIcon,
2021-07-29 06:19:32 -07:00
DotsHorizontalIcon,
2021-08-05 07:07:29 -07:00
GiftIcon,
2021-07-29 06:19:32 -07:00
HeartIcon,
XIcon,
} from '@heroicons/react/outline'
2021-08-05 07:07:29 -07:00
import { ArrowSmDownIcon, ArrowSmUpIcon } from '@heroicons/react/solid'
import {
getTokenBySymbol,
nativeToUi,
ZERO_BN,
I80F48,
} from '@blockworks-foundation/mango-client'
import useMangoStore, {
mangoClient,
MNGO_INDEX,
} from '../../stores/useMangoStore'
2021-07-25 06:54:25 -07:00
import { useBalances } from '../../hooks/useBalances'
2021-07-29 06:19:32 -07:00
import { useSortableData } from '../../hooks/useSortableData'
2021-08-02 05:44:58 -07:00
import useLocalStorageState from '../../hooks/useLocalStorageState'
2021-08-01 05:48:15 -07:00
import { sleep, usdFormatter, tokenPrecision } from '../../utils'
import { notify } from '../../utils/notifications'
import { Market } from '@project-serum/serum'
2021-07-25 06:54:25 -07:00
import SideBadge from '../SideBadge'
2021-07-29 06:19:32 -07:00
import Button, { LinkButton } from '../Button'
import Switch from '../Switch'
import PositionsTable from '../PositionsTable'
2021-08-01 05:48:15 -07:00
import DepositModal from '../DepositModal'
import WithdrawModal from '../WithdrawModal'
2021-07-25 06:54:25 -07:00
const StyledAccountValue = styled.div`
font-size: 1.8rem;
line-height: 1.2;
`
export default function AccountOverview() {
2021-07-29 06:19:32 -07:00
const [spotPortfolio, setSpotPortfolio] = useState([])
2021-08-01 05:48:15 -07:00
const [unsettled, setUnsettled] = useState([])
2021-07-29 06:19:32 -07:00
const [filteredSpotPortfolio, setFilteredSpotPortfolio] = useState([])
2021-08-02 05:44:58 -07:00
const [showZeroBalances, setShowZeroBalances] = useLocalStorageState(
'showZeroAccountBalances',
false
)
2021-08-01 05:48:15 -07:00
const [showDepositModal, setShowDepositModal] = useState(false)
const [showWithdrawModal, setShowWithdrawModal] = useState(false)
const [actionSymbol, setActionSymbol] = useState('')
2021-07-25 06:54:25 -07:00
const balances = useBalances()
2021-08-01 05:48:15 -07:00
const actions = useMangoStore((s) => s.actions)
2021-07-25 06:54:25 -07:00
const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config)
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
2021-07-29 06:19:32 -07:00
const { items, requestSort, sortConfig } = useSortableData(
filteredSpotPortfolio
)
2021-07-25 06:54:25 -07:00
2021-07-29 06:19:32 -07:00
useEffect(() => {
const spotPortfolio = []
2021-08-01 05:48:15 -07:00
const unsettled = []
2021-07-25 06:54:25 -07:00
balances.forEach((b) => {
const token = getTokenBySymbol(groupConfig, b.symbol)
const tokenIndex = mangoGroup.getTokenIndex(token.mintKey)
2021-08-01 05:48:15 -07:00
if (+b.marginDeposits > 0 || b.orders > 0) {
2021-07-29 06:19:32 -07:00
spotPortfolio.push({
2021-07-25 06:54:25 -07:00
market: b.symbol,
balance: +b.marginDeposits + b.orders + b.unsettled,
2021-07-29 06:19:32 -07:00
borrowRate: mangoGroup
.getBorrowRate(tokenIndex)
.mul(I80F48.fromNumber(100)),
depositRate: mangoGroup
.getDepositRate(tokenIndex)
.mul(I80F48.fromNumber(100)),
price: mangoGroup.getPrice(tokenIndex, mangoCache).toNumber(),
2021-07-25 06:54:25 -07:00
symbol: b.symbol,
value:
(+b.marginDeposits + b.orders + b.unsettled) *
mangoGroup.getPrice(tokenIndex, mangoCache).toNumber(),
2021-07-29 06:19:32 -07:00
type: 'Deposit',
2021-07-25 06:54:25 -07:00
})
2021-07-29 06:19:32 -07:00
} else if (+b.borrows > 0) {
spotPortfolio.push({
2021-07-25 06:54:25 -07:00
market: b.symbol,
balance: +b.borrows,
2021-07-29 06:19:32 -07:00
borrowRate: mangoGroup
.getBorrowRate(tokenIndex)
.mul(I80F48.fromNumber(100)),
depositRate: mangoGroup
.getDepositRate(tokenIndex)
.mul(I80F48.fromNumber(100)),
price: mangoGroup.getPrice(tokenIndex, mangoCache).toNumber(),
symbol: b.symbol,
2021-07-25 06:54:25 -07:00
value: b.borrows.mul(mangoGroup.getPrice(tokenIndex, mangoCache)),
2021-07-29 06:19:32 -07:00
type: 'Borrow',
})
} else {
spotPortfolio.push({
market: b.symbol,
balance: 0,
borrowRate: mangoGroup
.getBorrowRate(tokenIndex)
.mul(I80F48.fromNumber(100)),
depositRate: mangoGroup
.getDepositRate(tokenIndex)
.mul(I80F48.fromNumber(100)),
price: mangoGroup.getPrice(tokenIndex, mangoCache).toNumber(),
symbol: b.symbol,
value: 0,
type: '',
2021-07-25 06:54:25 -07:00
})
}
2021-08-01 05:48:15 -07:00
if (b.unsettled > 0) {
unsettled.push({
market: b.symbol,
balance: b.unsettled,
symbol: b.symbol,
value:
b.unsettled *
mangoGroup.getPrice(tokenIndex, mangoCache).toNumber(),
})
}
2021-07-25 06:54:25 -07:00
})
2021-07-29 06:19:32 -07:00
setSpotPortfolio(spotPortfolio.sort((a, b) => b.value - a.value))
setFilteredSpotPortfolio(
2021-08-02 05:44:58 -07:00
!showZeroBalances
? spotPortfolio
.filter((pos) => pos.balance > 0)
.sort((a, b) => b.value - a.value)
: spotPortfolio.sort((a, b) => b.value - a.value)
2021-07-29 06:19:32 -07:00
)
2021-08-02 05:44:58 -07:00
2021-08-01 05:48:15 -07:00
setUnsettled(unsettled)
2021-08-02 05:44:58 -07:00
}, [mangoAccount])
2021-07-29 06:19:32 -07:00
2021-08-05 07:07:29 -07:00
const maintHealthRatio = useMemo(() => {
return mangoAccount
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Maint')
: 100
}, [mangoAccount, mangoGroup, mangoCache])
const initHealthRatio = useMemo(() => {
return mangoAccount
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Init')
: 100
}, [mangoAccount, mangoGroup, mangoCache])
const mngoAccrued = useMemo(() => {
return mangoAccount
? mangoAccount.perpAccounts.reduce((acc, perpAcct) => {
return perpAcct.mngoAccrued.add(acc)
}, ZERO_BN)
: ZERO_BN
}, [mangoAccount])
2021-07-29 06:19:32 -07:00
const handleShowZeroBalances = (checked) => {
if (checked) {
setFilteredSpotPortfolio(spotPortfolio)
} else {
setFilteredSpotPortfolio(spotPortfolio.filter((pos) => pos.balance > 0))
}
setShowZeroBalances(checked)
}
2021-07-25 06:54:25 -07:00
2021-08-01 05:48:15 -07:00
async function handleSettleAll() {
const mangoAccount = useMangoStore.getState().selectedMangoAccount.current
const mangoGroup = useMangoStore.getState().selectedMangoGroup.current
const markets = useMangoStore.getState().selectedMangoGroup.markets
const wallet = useMangoStore.getState().wallet.current
try {
const spotMarkets = Object.values(markets).filter(
(mkt) => mkt instanceof Market
) as Market[]
await mangoClient.settleAll(mangoGroup, mangoAccount, spotMarkets, wallet)
notify({ title: 'Successfully settled funds' })
await sleep(250)
actions.fetchMangoAccounts()
} catch (e) {
console.warn('Error settling all:', e)
if (e.message === 'No unsettled funds') {
notify({
title: 'There are no unsettled funds',
type: 'error',
})
} else {
notify({
title: 'Error settling funds',
description: e.message,
txid: e.txid,
type: 'error',
})
}
}
}
2021-08-05 07:07:29 -07:00
const handleRedeemMngo = async () => {
const wallet = useMangoStore.getState().wallet.current
const mngoNodeBank =
mangoGroup.rootBankAccounts[MNGO_INDEX].nodeBankAccounts[0]
try {
const txid = await mangoClient.redeemAllMngo(
mangoGroup,
mangoAccount,
wallet,
mangoGroup.tokens[MNGO_INDEX].rootBank,
mngoNodeBank.publicKey,
mngoNodeBank.vault
)
actions.fetchMangoAccounts()
notify({
title: 'Successfully redeemed MNGO',
description: '',
txid,
})
} catch (e) {
notify({
title: 'Error redeeming MNGO',
description: e.message,
txid: e.txid,
type: 'error',
})
}
}
2021-08-01 05:48:15 -07:00
const handleOpenDepositModal = useCallback((symbol) => {
setActionSymbol(symbol)
setShowDepositModal(true)
}, [])
const handleOpenWithdrawModal = useCallback((symbol) => {
setActionSymbol(symbol)
setShowWithdrawModal(true)
}, [])
2021-07-25 06:54:25 -07:00
return mangoAccount ? (
<>
2021-08-05 07:07:29 -07:00
<div className="grid grid-flow-col grid-cols-1 grid-rows-4 md:grid-cols-4 md:grid-rows-1 gap-4 pb-8">
2021-08-01 05:48:15 -07:00
<div className="border border-th-bkg-4 p-4 rounded-lg">
<div className="pb-2 text-th-fgd-3">Account Value</div>
2021-08-05 07:07:29 -07:00
<div className="flex items-center pb-3">
2021-08-01 05:48:15 -07:00
<CurrencyDollarIcon className="flex-shrink-0 h-7 w-7 mr-1.5 text-th-primary" />
<StyledAccountValue className="font-bold text-th-fgd-1">
{usdFormatter.format(
+mangoAccount.computeValue(mangoGroup, mangoCache).toFixed(2)
)}
</StyledAccountValue>
</div>
</div>
<div className="border border-th-bkg-4 p-4 rounded-lg">
<div className="pb-2 text-th-fgd-3">PNL</div>
2021-08-05 07:07:29 -07:00
<div className="flex items-center pb-3">
2021-08-01 05:48:15 -07:00
<ChartBarIcon className="flex-shrink-0 h-7 w-7 mr-1.5 text-th-primary" />
<StyledAccountValue className="font-bold text-th-fgd-1">
{usdFormatter.format(
+mangoAccount.computeValue(mangoGroup, mangoCache).toFixed(2)
)}
</StyledAccountValue>
</div>
2021-07-25 06:54:25 -07:00
</div>
2021-07-29 06:19:32 -07:00
<div className="border border-th-bkg-4 p-4 rounded-lg">
2021-08-05 07:07:29 -07:00
<div className="pb-2 text-th-fgd-3">Health Ratio</div>
<div className="flex items-center pb-4">
<HeartIcon className="flex-shrink-0 h-7 w-7 mr-1.5 text-th-primary" />
<StyledAccountValue className="font-bold text-th-fgd-1">
{maintHealthRatio.toFixed(2)}%
</StyledAccountValue>
2021-07-25 06:54:25 -07:00
</div>
2021-08-05 07:07:29 -07:00
<div className="h-1.5 flex rounded bg-th-bkg-3">
<div
style={{
width: `${maintHealthRatio}%`,
}}
className={`flex rounded ${
maintHealthRatio > 30
? 'bg-th-green'
: initHealthRatio > 0
? 'bg-th-orange'
: 'bg-th-red'
}`}
></div>
2021-07-25 06:54:25 -07:00
</div>
</div>
2021-07-29 06:19:32 -07:00
<div className="border border-th-bkg-4 p-4 rounded-lg">
2021-08-05 07:07:29 -07:00
<div className="pb-2 text-th-fgd-3">MNGO Rewards</div>
<div className="flex items-center pb-2">
<GiftIcon className="flex-shrink-0 h-7 w-7 mr-1.5 text-th-primary" />
<StyledAccountValue className="font-bold text-th-fgd-1">
{mangoGroup
? nativeToUi(
mngoAccrued.toNumber(),
mangoGroup.tokens[MNGO_INDEX].decimals
)
: 0}
</StyledAccountValue>
2021-07-25 06:54:25 -07:00
</div>
2021-08-05 07:07:29 -07:00
<LinkButton
onClick={handleRedeemMngo}
disabled={mngoAccrued.eq(ZERO_BN)}
className="text-th-primary text-xs"
>
Claim Reward
</LinkButton>
2021-07-25 06:54:25 -07:00
</div>
</div>
2021-08-01 05:48:15 -07:00
{unsettled.length > 0 ? (
2021-08-05 07:07:29 -07:00
<div className="border border-th-bkg-3 rounded-lg mb-8 p-6">
2021-08-01 05:48:15 -07:00
<div className="flex items-center justify-between pb-4">
<div className="flex items-center text-lg">
<ExclamationIcon className="h-5 mr-1.5 mt-0.5 text-th-primary w-5" />
Unsettled Balances
</div>
<Button
className="text-xs pt-0 pb-0 h-8 pl-3 pr-3"
onClick={handleSettleAll}
>
Settle All
</Button>
</div>
{unsettled.map((a) => (
<div
className="border-b border-th-bkg-4 flex items-center justify-between py-4 last:border-b-0 last:pb-0"
key={a.symbol}
>
<div className="flex items-center">
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${a.symbol.toLowerCase()}.svg`}
className={`mr-2.5`}
/>
<div>{a.symbol}</div>
</div>
{a.balance.toFixed(tokenPrecision[a.symbol])}
</div>
))}
</div>
) : null}
2021-07-29 06:19:32 -07:00
<div className="pb-8">
<div className="pb-4 text-th-fgd-1 text-lg">Perp Positions</div>
<PositionsTable />
</div>
2021-08-05 07:07:29 -07:00
<div className="pb-4 text-th-fgd-1 text-lg">Assets & Liabilities</div>
<div className="grid grid-flow-col grid-cols-1 grid-rows-2 md:grid-cols-2 md:grid-rows-1 gap-4 pb-4">
<div className="border border-th-bkg-4 p-4 rounded-lg">
<div className="pb-0.5 text-xs text-th-fgd-3">Total Assets Value</div>
<div className="flex items-center">
<div className="text-lg text-th-fgd-1">
{usdFormatter.format(
+mangoAccount.getAssetsVal(mangoGroup, mangoCache)
)}
</div>
</div>
</div>
<div className="border border-th-bkg-4 p-4 rounded-lg">
<div className="pb-0.5 text-xs text-th-fgd-3">
Total Liabilities Value
</div>
<div className="flex items-center">
<div className="text-lg text-th-fgd-1">
{usdFormatter.format(
+mangoAccount.getLiabsVal(mangoGroup, mangoCache)
)}
</div>
</div>
</div>
</div>
<div className="flex justify-end pb-4">
2021-08-02 05:44:58 -07:00
<Switch
checked={showZeroBalances}
className="text-xs"
onChange={handleShowZeroBalances}
>
Show zero balances
</Switch>
</div>
{filteredSpotPortfolio.length > 0 ? (
<Table className="min-w-full divide-y divide-th-bkg-2">
<Thead>
<Tr className="text-th-fgd-3 text-xs">
<Th scope="col" className={`px-6 py-2 text-left`}>
<LinkButton
className="flex font-normal items-center no-underline"
onClick={() => requestSort('market')}
>
Asset
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'market'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
<Th scope="col" className={`px-6 py-2 text-left`}>
<LinkButton
className="flex font-normal items-center no-underline"
onClick={() => requestSort('type')}
>
Type
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'type'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
<Th scope="col" className={`px-6 py-2 text-left`}>
<LinkButton
className="flex font-normal items-center no-underline"
onClick={() => requestSort('balance')}
>
Balance
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'balance'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
<Th scope="col" className={`px-6 py-2 text-left`}>
<LinkButton
className="flex font-normal items-center no-underline"
onClick={() => requestSort('price')}
>
Price
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'price'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
<Th scope="col" className="px-6 py-2 text-left">
<LinkButton
className="flex font-normal items-center no-underline"
onClick={() => requestSort('value')}
>
Value
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'value'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
<Th scope="col" className="px-6 py-2 text-left">
<LinkButton
className="flex font-normal items-center no-underline"
onClick={() => requestSort('depositRate')}
>
Deposit Rate
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'depositRate'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
<Th scope="col" className="px-6 py-2 text-left">
<LinkButton
className="flex font-normal items-center no-underline"
onClick={() => requestSort('borrowRate')}
>
Borrow Rate
<ArrowSmDownIcon
className={`default-transition flex-shrink-0 h-4 w-4 ml-1 ${
sortConfig?.key === 'borrowRate'
? sortConfig.direction === 'ascending'
? 'transform rotate-180'
: 'transform rotate-360'
: null
}`}
/>
</LinkButton>
</Th>
</Tr>
</Thead>
<Tbody>
{items.map((pos, i) => (
<Tr
key={i}
className={`border-b border-th-bkg-3
2021-07-25 06:54:25 -07:00
${i % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
`}
2021-08-02 05:44:58 -07:00
>
<Td
className={`px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1`}
2021-07-25 06:54:25 -07:00
>
2021-08-02 05:44:58 -07:00
<div className="flex items-center">
<img
alt=""
width="20"
height="20"
src={`/assets/icons/${pos.symbol.toLowerCase()}.svg`}
className={`mr-2.5`}
/>
<div>{pos.market}</div>
</div>
</Td>
<Td
className={`px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1`}
>
{pos.type === 'Long' || pos.type === 'Short' ? (
<SideBadge side={pos.type} />
) : (
pos.type
)}
</Td>
<Td
className={`px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1`}
>
{pos.balance > 0
? pos.balance.toFixed(tokenPrecision[pos.symbol])
: 0}
</Td>
<Td
className={`px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1`}
>
{usdFormatter.format(pos.price)}
</Td>
<Td
className={`px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1`}
>
{usdFormatter.format(pos.value)}
</Td>
<Td
className={`px-6 py-2 whitespace-nowrap text-sm text-th-green`}
>
{pos.depositRate.toFixed(2)}%
</Td>
<Td
className={`px-6 py-2 whitespace-nowrap text-sm text-th-red`}
>
{pos.borrowRate.toFixed(2)}%
</Td>
<Td className={`px-6 py-2 flex justify-end`}>
<Menu>
{({ open }) => (
<div className="relative h-full">
<Menu.Button className="bg-th-bkg-4 flex items-center justify-center rounded-full w-8 h-8 text-th-fgd-1 focus:outline-none hover:text-th-primary">
{open ? (
<XIcon className="h-5 w-5" />
) : (
<DotsHorizontalIcon className="h-5 w-5" />
)}
</Menu.Button>
<Menu.Items className="bg-th-bkg-1 mt-2 p-1 absolute right-0 bottom-10 shadow-lg outline-none rounded-md w-32 z-20">
<div className="border-b border-th-bkg-3 flex items-center p-2 text-th-fgd-3 text-xs">
<img
alt=""
width="12"
height="12"
src={`/assets/icons/${pos.symbol.toLowerCase()}.svg`}
className={`mr-1.5`}
/>
{pos.symbol}
</div>
{pos.symbol !== 'USDC' ? (
2021-07-29 06:19:32 -07:00
<Menu.Item>
2021-08-02 05:44:58 -07:00
<Link
href={`/spot/${pos.symbol}`}
key={pos.symbol}
2021-07-29 06:19:32 -07:00
>
2021-08-02 05:44:58 -07:00
<a className="block font-normal p-2 rounded-none text-th-fgd-1 w-full hover:bg-th-bkg-2 hover:cursor-pointer hover:text-th-fgd-1 focus:outline-none">
<div className="text-left">Trade</div>
</a>
</Link>
2021-07-29 06:19:32 -07:00
</Menu.Item>
2021-08-02 05:44:58 -07:00
) : null}
<Menu.Item>
<button
className="font-normal rounded-none w-full p-2 hover:bg-th-bkg-2 hover:cursor-pointer focus:outline-none"
onClick={() => handleOpenDepositModal(pos.symbol)}
>
<div className="text-left">Deposit</div>
</button>
</Menu.Item>
<Menu.Item>
<button
className="font-normal rounded-none w-full p-2 hover:bg-th-bkg-2 hover:cursor-pointer focus:outline-none"
onClick={() =>
handleOpenWithdrawModal(pos.symbol)
}
>
<div className="text-left">Withdraw</div>
</button>
</Menu.Item>
</Menu.Items>
</div>
)}
</Menu>
</Td>
</Tr>
))}
</Tbody>
</Table>
) : (
<div
className={`w-full text-center py-6 bg-th-bkg-1 text-th-fgd-3 rounded-md`}
>
No assets
</div>
)}
2021-08-01 05:48:15 -07:00
{showDepositModal && (
<DepositModal
isOpen={showDepositModal}
onClose={() => setShowDepositModal(false)}
tokenSymbol={actionSymbol}
/>
)}
{showWithdrawModal && (
<WithdrawModal
isOpen={showWithdrawModal}
onClose={() => setShowWithdrawModal(false)}
tokenSymbol={actionSymbol}
/>
)}
2021-07-25 06:54:25 -07:00
</>
) : null
}