Merge pull request #83 from blockworks-foundation/swap-reduce-only

handle swap reduce only
This commit is contained in:
tylersssss 2023-02-10 11:34:15 -05:00 committed by GitHub
commit 6ec8f9d262
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 265 additions and 183 deletions

View File

@ -4,11 +4,13 @@ import FormatNumericValue from './FormatNumericValue'
const Change = ({
change,
decimals,
prefix,
size,
suffix,
}: {
change: number | typeof NaN
decimals?: number
prefix?: string
size?: 'small'
suffix?: string
@ -44,7 +46,7 @@ const Change = ({
{prefix ? prefix : ''}
<FormatNumericValue
value={isNaN(change) ? '0.00' : Math.abs(change)}
decimals={2}
decimals={decimals ? decimals : 2}
/>
{suffix ? suffix : ''}
</p>

View File

@ -45,6 +45,7 @@ interface DetailedAreaChartProps {
tickFormat?: (x: number) => string
title?: string
xKey: string
yDecimals?: number
yKey: string
}
@ -72,6 +73,7 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
tickFormat,
title,
xKey,
yDecimals,
yKey,
}) => {
const { t } = useTranslation('common')
@ -92,22 +94,43 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
setMouseData(null)
}
const calculateChartChange = () => {
if (data.length) {
if (mouseData) {
const index = data.findIndex((d: any) => d[xKey] === mouseData[xKey])
const change = index >= 0 ? data[index][yKey] - data[0][yKey] : 0
return isNaN(change) ? 0 : change
} else return data[data.length - 1][yKey] - data[0][yKey]
}
return 0
}
const flipGradientCoords = useMemo(() => {
if (!data.length) return
return data[0][yKey] <= 0 && data[data.length - 1][yKey] <= 0
}, [data])
const filteredData = useMemo(() => {
if (!data.length) return []
if (daysToShow !== '30') {
const seconds = Number(daysToShow) * 86400
const filtered = data.filter((d: any) => {
const dataTime = new Date(d[xKey]).getTime() / 1000
const now = new Date().getTime() / 1000
const limit = now - seconds
return dataTime >= limit
})
return filtered
}
return data
}, [data, daysToShow])
const calculateChartChange = () => {
if (filteredData.length) {
if (mouseData) {
const index = filteredData.findIndex(
(d: any) => d[xKey] === mouseData[xKey]
)
const change =
index >= 0 ? filteredData[index][yKey] - filteredData[0][yKey] : 0
return isNaN(change) ? 0 : change
} else
return (
filteredData[filteredData.length - 1][yKey] - filteredData[0][yKey]
)
}
return 0
}
return (
<FadeInFadeOut show={true}>
<ContentBox hideBorder hidePadding>
@ -119,7 +142,7 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
} w-full rounded-lg bg-th-bkg-2`}
/>
</SheenLoader>
) : data.length ? (
) : filteredData.length ? (
<div className="relative">
<div className="flex items-start justify-between">
<div className="flex flex-col md:flex-row md:items-start md:space-x-6">
@ -157,7 +180,8 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
numbers={`${
mouseData[yKey] < 0 ? '-' : ''
}${prefix}${formatNumericValue(
Math.abs(mouseData[yKey])
Math.abs(mouseData[yKey]),
yDecimals
)}${suffix}`}
/>
) : (
@ -166,6 +190,7 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
{prefix}
<FormatNumericValue
value={Math.abs(mouseData[yKey])}
decimals={yDecimals}
/>
{suffix}
</span>
@ -174,6 +199,7 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
<span className="ml-3">
<Change
change={calculateChartChange()}
decimals={yDecimals}
prefix={prefix}
suffix={suffix}
/>
@ -203,17 +229,25 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
width={small ? 17 : 30}
play
numbers={`${
data[data.length - 1][yKey] < 0 ? '-' : ''
filteredData[filteredData.length - 1][yKey] < 0
? '-'
: ''
}${prefix}${formatNumericValue(
Math.abs(data[data.length - 1][yKey])
Math.abs(
filteredData[filteredData.length - 1][yKey]
),
yDecimals
)}${suffix}`}
/>
) : (
<span>
{data[data.length - 1][yKey] < 0 ? '-' : ''}
{filteredData[filteredData.length - 1][yKey] < 0
? '-'
: ''}
{prefix}
<FormatNumericValue
value={Math.abs(data[data.length - 1][yKey])}
decimals={yDecimals}
/>
{suffix}
</span>
@ -222,6 +256,7 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
<span className="ml-3">
<Change
change={calculateChartChange()}
decimals={yDecimals}
prefix={prefix}
suffix={suffix}
/>
@ -233,9 +268,9 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
small ? 'text-xs' : 'text-sm'
} text-th-fgd-4`}
>
{dayjs(data[data.length - 1][xKey]).format(
'DD MMM YY, h:mma'
)}
{dayjs(
filteredData[filteredData.length - 1][xKey]
).format('DD MMM YY, h:mma')}
</p>
</div>
)}
@ -258,7 +293,7 @@ const DetailedAreaChart: FunctionComponent<DetailedAreaChartProps> = ({
<div className="-mx-6 mt-6 h-full">
<ResponsiveContainer width="100%" height="100%">
<AreaChart
data={data}
data={filteredData}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>

View File

@ -68,42 +68,12 @@ const MangoPerpStatsCharts = () => {
return values.reverse()
}, [perpStats])
const filteredOiValues = useMemo(() => {
if (!totalOpenInterestValues.length) return []
if (oiDaysToShow !== '30') {
const seconds = Number(oiDaysToShow) * 86400
const data = totalOpenInterestValues.filter((d: OiValueItem) => {
const dataTime = new Date(d.date).getTime() / 1000
const now = new Date().getTime() / 1000
const limit = now - seconds
return dataTime >= limit
})
return data
}
return totalOpenInterestValues
}, [totalOpenInterestValues, oiDaysToShow])
const filteredFeesValues = useMemo(() => {
if (!totalFeeValues.length) return []
if (feesDaysToShow !== '30') {
const seconds = Number(feesDaysToShow) * 86400
const data = totalFeeValues.filter((d: FeeValueItem) => {
const dataTime = new Date(d.date).getTime() / 1000
const now = new Date().getTime() / 1000
const limit = now - seconds
return dataTime >= limit
})
return data
}
return totalFeeValues
}, [totalFeeValues, feesDaysToShow])
return (
<>
{totalFeeValues.length ? (
{totalOpenInterestValues.length ? (
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<DetailedAreaChart
data={filteredOiValues}
data={totalOpenInterestValues}
daysToShow={oiDaysToShow}
setDaysToShow={setOiDaysToShow}
heightClass="h-64"
@ -117,10 +87,10 @@ const MangoPerpStatsCharts = () => {
/>
</div>
) : null}
{totalOpenInterestValues.length ? (
{totalFeeValues.length ? (
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<DetailedAreaChart
data={filteredFeesValues}
data={totalFeeValues}
daysToShow={feesDaysToShow}
setDaysToShow={setFeesDaysToShow}
heightClass="h-64"

View File

@ -1,33 +1,58 @@
import { IconButton } from '@components/shared/Button'
import SheenLoader from '@components/shared/SheenLoader'
import { ChevronLeftIcon } from '@heroicons/react/20/solid'
import mangoStore from '@store/mangoStore'
import dayjs from 'dayjs'
import { useTranslation } from 'next-i18next'
import dynamic from 'next/dynamic'
import { useMemo } from 'react'
import { useMemo, useState } from 'react'
import { formatYAxis } from 'utils/formatting'
import { formatNumericValue } from 'utils/numbers'
import { usePerpFundingRate } from '@components/trade/PerpFundingRate'
const DetailedAreaChart = dynamic(
() => import('@components/shared/DetailedAreaChart'),
{ ssr: false }
)
const PerpMarketDetails = ({
perpMarket,
perpMarketName,
setShowPerpDetails,
}: {
perpMarket: string
perpMarketName: string
setShowPerpDetails: (x: string) => void
}) => {
const { t } = useTranslation(['common', 'trade'])
const perpMarkets = mangoStore((s) => s.perpMarkets)
const perpStats = mangoStore((s) => s.perpStats.data)
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
const [priceDaysToShow, setPriceDaysToShow] = useState('30')
const [oiDaysToShow, setOiDaysToShow] = useState('30')
const [hourlyFundingeDaysToShow, setHourlyFundingDaysToShow] = useState('30')
const [instantFundingDaysToShow, setInstantFundingDaysToShow] = useState('30')
const rate = usePerpFundingRate()
const marketStats = useMemo(() => {
if (!perpStats) return []
return perpStats.filter((stat) => stat.perp_market === perpMarket).reverse()
const perpMarket = useMemo(() => {
return perpMarkets.find((m) => (m.name = perpMarketName))
}, [perpMarkets, perpMarketName])
const [marketStats, lastStat] = useMemo(() => {
if (!perpStats) return [[], undefined]
const stats = perpStats
.filter((stat) => stat.perp_market === perpMarketName)
.reverse()
return [stats, stats[stats.length - 1]]
}, [perpStats])
const fundingRate = useMemo(() => {
if (!lastStat) return 0
if (rate?.isSuccess) {
const marketRate = rate?.data?.find(
(r) => r.market_index === perpMarket?.perpMarketIndex
)
return marketRate?.funding_rate_hourly
}
return lastStat.instantaneous_funding_rate
}, [rate, lastStat])
return (
<div className="grid grid-cols-2">
<div className="col-span-2 flex items-center border-b border-th-bkg-3 px-6 py-3">
@ -38,38 +63,24 @@ const PerpMarketDetails = ({
>
<ChevronLeftIcon className="h-5 w-5" />
</IconButton>
<h2 className="text-lg">{`${perpMarket} ${t('stats')}`}</h2>
<h2 className="text-lg">{`${perpMarketName} ${t('stats')}`}</h2>
</div>
{loadingPerpStats ? (
<>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<SheenLoader className="flex flex-1">
<div className="h-96 w-full rounded-lg bg-th-bkg-2" />
</SheenLoader>
</div>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<SheenLoader className="flex flex-1">
<div className="h-96 w-full rounded-lg bg-th-bkg-2" />
</SheenLoader>
</div>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<SheenLoader className="flex flex-1">
<div className="h-96 w-full rounded-lg bg-th-bkg-2" />
</SheenLoader>
</div>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<SheenLoader className="flex flex-1">
<div className="h-96 w-full rounded-lg bg-th-bkg-2" />
</SheenLoader>
</div>
</>
) : marketStats.length ? (
{marketStats.length && lastStat ? (
<>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<DetailedAreaChart
data={marketStats}
daysToShow={'999'}
data={marketStats.concat([
{
...lastStat,
date_hour: dayjs().toISOString(),
price: perpMarket?._uiPrice || lastStat.price,
},
])}
daysToShow={priceDaysToShow}
setDaysToShow={setPriceDaysToShow}
heightClass="h-64"
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
prefix="$"
tickFormat={(x) => formatYAxis(x)}
title={t('price')}
@ -79,10 +90,21 @@ const PerpMarketDetails = ({
</div>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<DetailedAreaChart
data={marketStats}
daysToShow={'999'}
data={marketStats.concat([
{
...lastStat,
date_hour: dayjs().toISOString(),
open_interest:
perpMarket?.baseLotsToUi(perpMarket.openInterest) ||
lastStat.open_interest,
},
])}
daysToShow={oiDaysToShow}
setDaysToShow={setOiDaysToShow}
heightClass="h-64"
tickFormat={(x) => Math.floor(x).toString()}
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
tickFormat={(x) => formatYAxis(x)}
title={t('trade:open-interest')}
xKey="date_hour"
yKey={'open_interest'}
@ -91,25 +113,39 @@ const PerpMarketDetails = ({
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<DetailedAreaChart
data={marketStats}
daysToShow={'999'}
daysToShow={hourlyFundingeDaysToShow}
setDaysToShow={setHourlyFundingDaysToShow}
heightClass="h-64"
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
suffix="%"
tickFormat={(x) => formatNumericValue(x, 4)}
title={t('trade:hourly-funding')}
xKey="date_hour"
yKey={'funding_rate_hourly'}
yDecimals={5}
/>
</div>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<DetailedAreaChart
data={marketStats}
daysToShow={'999'}
data={marketStats.concat([
{
...lastStat,
date_hour: dayjs().toISOString(),
instantaneous_funding_rate: fundingRate,
},
])}
daysToShow={instantFundingDaysToShow}
setDaysToShow={setInstantFundingDaysToShow}
heightClass="h-64"
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
suffix="%"
tickFormat={(x) => formatNumericValue(x, 4)}
title={t('trade:instantaneous-funding')}
xKey="date_hour"
yKey={'instantaneous_funding_rate'}
yDecimals={5}
/>
</div>
</>

View File

@ -87,7 +87,7 @@ const PerpMarketsTable = ({
: 0
let fundingRate
if (rate.isSuccess && market instanceof PerpMarket) {
if (rate.isSuccess) {
const marketRate = rate?.data?.find(
(r) => r.market_index === market.perpMarketIndex
)
@ -198,6 +198,7 @@ const PerpMarketsTable = ({
<MobilePerpMarketItem
key={market.publicKey.toString()}
market={market}
setShowPerpDetails={setShowPerpDetails}
/>
)
})}
@ -209,7 +210,13 @@ const PerpMarketsTable = ({
export default PerpMarketsTable
const MobilePerpMarketItem = ({ market }: { market: PerpMarket }) => {
const MobilePerpMarketItem = ({
market,
setShowPerpDetails,
}: {
market: PerpMarket
setShowPerpDetails: (x: string) => void
}) => {
const { t } = useTranslation('common')
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
const perpStats = mangoStore((s) => s.perpStats.data)
@ -252,10 +259,9 @@ const MobilePerpMarketItem = ({ market }: { market: PerpMarket }) => {
<Change change={change} suffix="%" />
</div>
</div>
</div>
{!loadingPerpStats ? (
marketStats.length ? (
<div className="h-10 w-24">
<div className="ml-4 h-10 w-24">
<SimpleAreaChart
color={change >= 0 ? COLORS.UP[theme] : COLORS.DOWN[theme]}
data={marketStats}
@ -271,6 +277,13 @@ const MobilePerpMarketItem = ({ market }: { market: PerpMarket }) => {
<div className="h-10 w-[104px] animate-pulse rounded bg-th-bkg-3" />
)}
</div>
<IconButton
onClick={() => setShowPerpDetails(market.name)}
size="medium"
>
<ChevronRightIcon className="h-5 w-5" />
</IconButton>
</div>
</div>
)
}

View File

@ -8,7 +8,7 @@ const PerpStats = () => {
<PerpMarketsTable setShowPerpDetails={setShowPerpDetails} />
) : (
<PerpMarketDetails
perpMarket={showPerpDetails}
perpMarketName={showPerpDetails}
setShowPerpDetails={setShowPerpDetails}
/>
)

View File

@ -48,36 +48,6 @@ const TotalDepositBorrowCharts = () => {
return values.reverse()
}, [tokenStats])
const filteredBorrowValues = useMemo(() => {
if (!totalDepositBorrowValues) return []
if (borrowDaysToShow !== '30') {
const seconds = Number(borrowDaysToShow) * 86400
const data = totalDepositBorrowValues.filter((d) => {
const dataTime = new Date(d.date).getTime() / 1000
const now = new Date().getTime() / 1000
const limit = now - seconds
return dataTime >= limit
})
return data
}
return totalDepositBorrowValues
}, [totalDepositBorrowValues, borrowDaysToShow])
const filteredDepositValues = useMemo(() => {
if (!totalDepositBorrowValues) return []
if (depositDaysToShow !== '30') {
const seconds = Number(depositDaysToShow) * 86400
const data = totalDepositBorrowValues.filter((d) => {
const dataTime = new Date(d.date).getTime() / 1000
const now = new Date().getTime() / 1000
const limit = now - seconds
return dataTime >= limit
})
return data
}
return totalDepositBorrowValues
}, [totalDepositBorrowValues, depositDaysToShow])
const [currentTotalDepositValue, currentTotalBorrowValue] = useMemo(() => {
if (banks.length) {
return [
@ -92,7 +62,7 @@ const TotalDepositBorrowCharts = () => {
<>
<div className="col-span-2 h-96 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<DetailedAreaChart
data={filteredDepositValues.concat([
data={totalDepositBorrowValues.concat([
{
date: dayjs().toISOString(),
depositValue: Math.floor(currentTotalDepositValue),
@ -113,7 +83,7 @@ const TotalDepositBorrowCharts = () => {
</div>
<div className="col-span-2 h-96 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<DetailedAreaChart
data={filteredBorrowValues.concat([
data={totalDepositBorrowValues.concat([
{
date: dayjs().toISOString(),
borrowValue: Math.floor(currentTotalBorrowValue),

View File

@ -63,7 +63,7 @@ const SwapForm = () => {
//initial state is undefined null is returned on error
const [selectedRoute, setSelectedRoute] = useState<RouteInfo | null>()
const [animateSwitchArrow, setAnimateSwitchArrow] = useState(0)
const [showTokenSelect, setShowTokenSelect] = useState('')
const [showTokenSelect, setShowTokenSelect] = useState(undefined)
const [showSettings, setShowSettings] = useState(false)
const [showConfirm, setShowConfirm] = useState(false)
const { group } = useMangoGroup()
@ -193,7 +193,7 @@ const SwapForm = () => {
s.swap.inputBank = bank
})
}
setShowTokenSelect('')
setShowTokenSelect(undefined)
}, [])
const handleTokenOutSelect = useCallback((mintAddress: string) => {
@ -204,7 +204,7 @@ const SwapForm = () => {
s.swap.outputBank = bank
})
}
setShowTokenSelect('')
setShowTokenSelect(undefined)
}, [])
const handleSwitchTokens = useCallback(() => {
@ -299,7 +299,7 @@ const SwapForm = () => {
show={!!showTokenSelect}
>
<SwapFormTokenList
onClose={() => setShowTokenSelect('')}
onClose={() => setShowTokenSelect(undefined)}
onTokenSelect={
showTokenSelect === 'input'
? handleTokenInSelect
@ -451,6 +451,26 @@ const SwapForm = () => {
{group && inputBank ? (
<TokenVaultWarnings bank={inputBank} type="swap" />
) : null}
{inputBank && inputBank.reduceOnly ? (
<div className="pb-4">
<InlineNotification
type="warning"
desc={t('swap:input-reduce-only-warning', {
symbol: inputBank.name,
})}
/>
</div>
) : null}
{outputBank && outputBank.reduceOnly ? (
<div className="pb-4">
<InlineNotification
type="warning"
desc={t('swap:output-reduce-only-warning', {
symbol: outputBank.name,
})}
/>
</div>
) : null}
<div className="space-y-2">
<div id="swap-step-four">
<HealthImpact maintProjectedHealth={maintProjectedHealth} />

View File

@ -47,10 +47,17 @@ const TokenItem = ({
token: Token
onSubmit: (x: string) => void
useMargin: boolean
type: string
type: 'input' | 'output' | undefined
}) => {
const { t } = useTranslation('trade')
const { address, symbol, logoURI, name } = token
const bank = useMemo(() => {
const group = mangoStore.getState().group
if (!group) return
return group.getFirstBankByMint(new PublicKey(address))
}, [address])
return (
<div>
<button
@ -64,10 +71,18 @@ const TokenItem = ({
<img src={logoURI} width="24" height="24" alt={symbol} />
</picture>
<div className="ml-2.5">
<div className="text-left text-th-fgd-2">{symbol || 'unknown'}</div>
<div className="text-left text-xs text-th-fgd-4">
<p className="text-left text-th-fgd-2">
{symbol || 'unknown'}
{bank?.reduceOnly ? (
<span className="ml-1.5 text-xxs text-th-warning">
{t('reduce-only')}
</span>
) : null}
</p>
<p className="text-left text-xs text-th-fgd-4">
{name || 'unknown'}
</div>
</p>
</div>
</div>
{type === 'input' &&
@ -103,7 +118,7 @@ const SwapFormTokenList = ({
}: {
onClose: () => void
onTokenSelect: (x: string) => void
type: string
type: 'input' | 'output' | undefined
useMargin: boolean
}) => {
const { t } = useTranslation(['common', 'swap'])

View File

@ -49,7 +49,13 @@ export const getTokenInMax = (
mangoAccount.getTokenBalanceUi(inputBank)
)
const maxAmountWithoutMargin = inputTokenBalance.gt(0)
const outputTokenBalance = new Decimal(
mangoAccount.getTokenBalanceUi(outputBank)
)
const maxAmountWithoutMargin =
(inputTokenBalance.gt(0) && !outputBank.reduceOnly) ||
(outputBank.reduceOnly && outputTokenBalance.lt(0))
? inputTokenBalance
: new Decimal(0)
@ -60,7 +66,10 @@ export const getTokenInMax = (
)
const maxUiAmountWithBorrow =
rawMaxUiAmountWithBorrow > 0
outputBank.reduceOnly &&
(outputTokenBalance.gt(0) || outputTokenBalance.eq(0))
? new Decimal(0)
: rawMaxUiAmountWithBorrow > 0
? floorToDecimal(rawMaxUiAmountWithBorrow, inputBank.mintDecimals)
: new Decimal(0)
@ -83,10 +92,9 @@ export const getTokenInMax = (
maxUiAmountWithBorrow
)
const maxAmountWithBorrow = Decimal.min(
maxUiAmountWithBorrow,
inputBankVaultBalance
)
const maxAmountWithBorrow = inputBank.reduceOnly
? Decimal.min(maxAmountWithoutMargin, inputBankVaultBalance)
: Decimal.min(maxUiAmountWithBorrow, inputBankVaultBalance)
return {
amount: maxAmount,

View File

@ -46,20 +46,20 @@ const ChartTabs = ({ token }: { token: string }) => {
}, [])
}, [tokenStats])
const filterStats = (daysToShow: string) => {
if (!statsHistory.length) return []
if (daysToShow !== '30') {
const seconds = Number(daysToShow) * 86400
const data = statsHistory.filter((d) => {
const dataTime = new Date(d.date_hour).getTime() / 1000
const now = new Date().getTime() / 1000
const limit = now - seconds
return dataTime >= limit
})
return data
}
return statsHistory
}
// const filterStats = (daysToShow: string) => {
// if (!statsHistory.length) return []
// if (daysToShow !== '30') {
// const seconds = Number(daysToShow) * 86400
// const data = statsHistory.filter((d) => {
// const dataTime = new Date(d.date_hour).getTime() / 1000
// const now = new Date().getTime() / 1000
// const limit = now - seconds
// return dataTime >= limit
// })
// return data
// }
// return statsHistory
// }
return (
<div className="grid grid-cols-1 md:grid-cols-2">
@ -77,7 +77,7 @@ const ChartTabs = ({ token }: { token: string }) => {
<div className="h-96 border-t border-th-bkg-3 px-6 py-6">
{activeDepositsTab === 'token:deposits' ? (
<DetailedAreaChart
data={filterStats(depositDaysToShow)}
data={statsHistory}
daysToShow={depositDaysToShow}
setDaysToShow={setDepositDaysToShow}
heightClass="h-64"
@ -92,7 +92,7 @@ const ChartTabs = ({ token }: { token: string }) => {
/>
) : (
<DetailedAreaChart
data={filterStats(depositRateDaysToShow)}
data={statsHistory}
daysToShow={depositRateDaysToShow}
setDaysToShow={setDepositRateDaysToShow}
heightClass="h-64"
@ -125,7 +125,7 @@ const ChartTabs = ({ token }: { token: string }) => {
<div className="h-96 border-t border-th-bkg-3 px-6 py-6">
{activeBorrowsTab === 'token:borrows' ? (
<DetailedAreaChart
data={filterStats(borrowDaysToShow)}
data={statsHistory}
daysToShow={borrowDaysToShow}
setDaysToShow={setBorrowDaysToShow}
heightClass="h-64"
@ -140,7 +140,7 @@ const ChartTabs = ({ token }: { token: string }) => {
/>
) : (
<DetailedAreaChart
data={filterStats(borrowRateDaysToShow)}
data={statsHistory}
daysToShow={borrowRateDaysToShow}
setDaysToShow={setBorrowRateDaysToShow}
heightClass="h-64"

View File

@ -561,7 +561,7 @@ const AdvancedTradeForm = () => {
checked={tradeForm.reduceOnly}
onChange={(e) => handleReduceOnlyChange(e.target.checked)}
>
Reduce Only
{t('trade:reduce-only')}
</Checkbox>
</div>
</Tooltip>

View File

@ -5,12 +5,14 @@
"fees-paid-to": "Fees Paid to {{route}}",
"health-impact": "Health Impact",
"hide-fees": "Hide Fees",
"input-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap your balance to another token",
"insufficient-balance": "Insufficient {{symbol}} Balance",
"insufficient-collateral": "Insufficient Collateral",
"max-slippage": "Max Slippage",
"maximum-cost": "Maximum Cost",
"minimum-received": "Minimum Received",
"no-history": "No swap history",
"output-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap to close borrows only",
"paid": "Paid",
"pay": "You Pay",
"preset": "Preset",

View File

@ -38,6 +38,7 @@
"post": "Post",
"price-expect": "The price you receive may be worse than you expect and full execution is not guaranteed. Max slippage is 2.5% for your safety. The part of your position with slippage beyond 2.5% will not be closed.",
"quote": "Quote",
"reduce-only": "Reduce Only",
"sells": "Sells",
"settle-funds": "Settle Funds",
"settle-funds-error": "Failed to settle funds",

View File

@ -5,12 +5,14 @@
"fees-paid-to": "Fees Paid to {{route}}",
"health-impact": "Health Impact",
"hide-fees": "Hide Fees",
"input-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap your balance to another token",
"insufficient-balance": "Insufficient {{symbol}} Balance",
"insufficient-collateral": "Insufficient Collateral",
"max-slippage": "Max Slippage",
"maximum-cost": "Maximum Cost",
"minimum-received": "Minimum Received",
"no-history": "No swap history",
"output-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap to close borrows only",
"paid": "Paid",
"pay": "You Pay",
"preset": "Preset",

View File

@ -38,6 +38,7 @@
"post": "Post",
"price-expect": "The price you receive may be worse than you expect and full execution is not guaranteed. Max slippage is 2.5% for your safety. The part of your position with slippage beyond 2.5% will not be closed.",
"quote": "Quote",
"reduce-only": "Reduce Only",
"sells": "Sells",
"settle-funds": "Settle Funds",
"settle-funds-error": "Failed to settle funds",

View File

@ -5,12 +5,14 @@
"fees-paid-to": "Fees Paid to {{route}}",
"health-impact": "Health Impact",
"hide-fees": "Hide Fees",
"input-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap your balance to another token",
"insufficient-balance": "Insufficient {{symbol}} Balance",
"insufficient-collateral": "Insufficient Collateral",
"max-slippage": "Max Slippage",
"maximum-cost": "Maximum Cost",
"minimum-received": "Minimum Received",
"no-history": "No swap history",
"output-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap to close borrows only",
"paid": "Paid",
"pay": "You Pay",
"preset": "Preset",

View File

@ -38,6 +38,7 @@
"post": "Post",
"price-expect": "The price you receive may be worse than you expect and full execution is not guaranteed. Max slippage is 2.5% for your safety. The part of your position with slippage beyond 2.5% will not be closed.",
"quote": "Quote",
"reduce-only": "Reduce Only",
"sells": "Sells",
"settle-funds": "Settle Funds",
"settle-funds-error": "Failed to settle funds",

View File

@ -5,12 +5,14 @@
"fees-paid-to": "Fees Paid to {{route}}",
"health-impact": "Health Impact",
"hide-fees": "Hide Fees",
"input-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap your balance to another token",
"insufficient-balance": "Insufficient {{symbol}} Balance",
"insufficient-collateral": "Insufficient Collateral",
"max-slippage": "Max Slippage",
"maximum-cost": "Maximum Cost",
"minimum-received": "Minimum Received",
"no-history": "No swap history",
"output-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap to close borrows only",
"paid": "Paid",
"pay": "You Pay",
"preset": "Preset",

View File

@ -5,12 +5,14 @@
"fees-paid-to": "Fees Paid to {{route}}",
"health-impact": "Health Impact",
"hide-fees": "Hide Fees",
"input-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap your balance to another token",
"insufficient-balance": "Insufficient {{symbol}} Balance",
"insufficient-collateral": "Insufficient Collateral",
"max-slippage": "Max Slippage",
"maximum-cost": "Maximum Cost",
"minimum-received": "Minimum Received",
"no-history": "No swap history",
"output-reduce-only-warning": "{{symbol}} is in reduce only mode. You can swap to close borrows only",
"paid": "Paid",
"pay": "You Pay",
"preset": "Preset",