Skip to content

Commit

Permalink
fix: fill last tick, chore fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
damnnou committed Apr 23, 2024
1 parent 5590633 commit 15b9890
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 133 deletions.
80 changes: 27 additions & 53 deletions src/components/common/Table/poolsColumns.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ColumnDef } from '@tanstack/react-table';
import { HeaderItem } from './common';
import { Address } from 'wagmi';
import CurrencyLogo from '../CurrencyLogo';
import { TokenFieldsFragment } from '@/graphql/generated/graphql';
import { DynamicFeePluginIcon } from '../PluginIcons';
import { formatUSD } from '@/utils/common/formatUSD';
import { usePoolPlugins } from '@/hooks/pools/usePoolPlugins';
import { Skeleton } from '@/components/ui/skeleton';
import { FarmingPluginIcon } from '../PluginIcons';
import { useCurrency } from '@/hooks/common/useCurrency';
import { ColumnDef } from "@tanstack/react-table";
import { HeaderItem } from "./common";
import { Address } from "wagmi";
import CurrencyLogo from "../CurrencyLogo";
import { TokenFieldsFragment } from "@/graphql/generated/graphql";
import { DynamicFeePluginIcon } from "../PluginIcons";
import { formatUSD } from "@/utils/common/formatUSD";
import { usePoolPlugins } from "@/hooks/pools/usePoolPlugins";
import { Skeleton } from "@/components/ui/skeleton";
import { FarmingPluginIcon } from "../PluginIcons";
import { useCurrency } from "@/hooks/common/useCurrency";

interface Pair {
token0: TokenFieldsFragment;
Expand All @@ -23,6 +23,8 @@ interface Pool {
volume24USD: number;
maxApr: number;
avgApr: number;
isMyPool: boolean;
hasActiveFarming: boolean;
}

const PoolPair = ({ pair, fee }: Pool) => {
Expand All @@ -36,11 +38,7 @@ const PoolPair = ({ pair, fee }: Pool) => {
<div className="flex items-center gap-4 ml-2">
<div className="flex">
<CurrencyLogo currency={currencyA} size={30} />
<CurrencyLogo
currency={currencyB}
size={30}
className="-ml-2"
/>
<CurrencyLogo currency={currencyB} size={30} className="-ml-2" />
</div>

{currencyA && currencyB ? (
Expand All @@ -67,76 +65,52 @@ const Plugins = ({ poolId }: { poolId: Address }) => {

export const poolsColumns: ColumnDef<Pool>[] = [
{
accessorKey: 'pair',
accessorKey: "pair",
header: () => <HeaderItem className="ml-2">Pool</HeaderItem>,
cell: ({ row }) => <PoolPair {...row.original} />,
filterFn: (v, _, value) =>
[
v.original.pair.token0.symbol,
v.original.pair.token1.symbol,
v.original.pair.token0.name,
v.original.pair.token1.name,
]
.join(' ')
[v.original.pair.token0.symbol, v.original.pair.token1.symbol, v.original.pair.token0.name, v.original.pair.token1.name]
.join(" ")
.toLowerCase()
.includes(value),
},
{
accessorKey: 'plugins',
accessorKey: "plugins",
header: () => <HeaderItem>Plugins</HeaderItem>,
cell: ({ row }) => <Plugins poolId={row.original.id} />,
filterFn: (v, _, value: boolean) => v.original.hasActiveFarming === value,
},
{
accessorKey: 'tvlUSD',
accessorKey: "tvlUSD",
header: ({ column }) => (
<HeaderItem
sort={() =>
column.toggleSorting(column.getIsSorted() === 'asc')
}
isAsc={column.getIsSorted() === 'asc'}
>
<HeaderItem sort={() => column.toggleSorting(column.getIsSorted() === "asc")} isAsc={column.getIsSorted() === "asc"}>
TVL
</HeaderItem>
),
cell: ({ getValue }) => formatUSD.format(getValue() as number),
},
{
accessorKey: 'volume24USD',
accessorKey: "volume24USD",
header: ({ column }) => (
<HeaderItem
sort={() =>
column.toggleSorting(column.getIsSorted() === 'asc')
}
isAsc={column.getIsSorted() === 'asc'}
>
<HeaderItem sort={() => column.toggleSorting(column.getIsSorted() === "asc")} isAsc={column.getIsSorted() === "asc"}>
Volume 24H
</HeaderItem>
),
cell: ({ getValue }) => formatUSD.format(getValue() as number),
},
{
accessorKey: 'maxApr',
accessorKey: "maxApr",
header: ({ column }) => (
<HeaderItem
sort={() =>
column.toggleSorting(column.getIsSorted() === 'asc')
}
isAsc={column.getIsSorted() === 'asc'}
>
<HeaderItem sort={() => column.toggleSorting(column.getIsSorted() === "asc")} isAsc={column.getIsSorted() === "asc"}>
Max. APR
</HeaderItem>
),
cell: ({ getValue }) => `${getValue()} %`,
},
{
accessorKey: 'avgApr',
accessorKey: "avgApr",
header: ({ column }) => (
<HeaderItem
sort={() =>
column.toggleSorting(column.getIsSorted() === 'asc')
}
isAsc={column.getIsSorted() === 'asc'}
>
<HeaderItem sort={() => column.toggleSorting(column.getIsSorted() === "asc")} isAsc={column.getIsSorted() === "asc"}>
Avg. APR
</HeaderItem>
),
Expand Down
12 changes: 7 additions & 5 deletions src/components/create-position/LiquidityChart/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface CustomBarProps {
percent: number | undefined;
isCurrent: boolean;
isAfterSwapTick: boolean;
isFocused: boolean;
}

interface CustomTooltipProps {
Expand Down Expand Up @@ -41,19 +42,20 @@ const CustomBar = ({
fill,
percent,
isCurrent,
isAfterSwapTick
isAfterSwapTick,
isFocused,
}: CustomBarProps) => {
return (
<g className='group'>
<g>
<defs>
<linearGradient id='colorUv' x1='0' y1='0' x2='0' y2='100%'>
<stop offset='0' stopColor='#2797ff' />
<stop offset='1' stopColor='rgba(35, 133, 222, 0.05)' />
</linearGradient>
</defs>
{percent && <text x={x + 10} y={y - 10} fill="white" fontSize={'14px'} fontWeight={600} textAnchor="middle">{`${percent.toFixed(0)}%`}</text>}
{isCurrent && <text className='group-hover:flex hidden' x={x + 10} y={y - 10} fill="white" fontSize={'14px'} fontWeight={600} textAnchor="middle">Current Price</text>}
{isAfterSwapTick && !isCurrent && <text className='group-hover:flex hidden' x={x + 10} y={y - 10} fill="white" fontSize={'14px'} fontWeight={600} textAnchor="middle">After Swap</text>}
{isCurrent && isFocused && <text x={x + 10} y={y - 10} fill="white" fontSize={'14px'} fontWeight={600} textAnchor="middle">Current Price</text>}
{isAfterSwapTick && !isCurrent && isFocused && <text x={x + 10} y={y - 10} fill="white" fontSize={'14px'} fontWeight={600} textAnchor="middle">After Swap</text>}
<rect x={x} y={y} fill={fill} width={width} height={height} rx="4" />
</g>
)
Expand Down Expand Up @@ -145,7 +147,7 @@ export function Chart({ formattedData, currencyA, currencyB, leftPrice, rightPri
percent = (props.payload.index < currentPriceRealIndex ? -1 : 1) * ((Math.max(props.payload.index, currentPriceRealIndex) - Math.min(props.payload.index, currentPriceRealIndex)) / currentPriceRealIndex) * 100
}

return <CustomBar key={props.index} height={props.height} width={props.width} x={props.x} y={props.y} fill={props.fill} percent={percent} isCurrent={props.isCurrent} isAfterSwapTick={props.isAfterSwapTick} />
return <CustomBar isFocused={Boolean(props.index === focusBar)} key={props.index} height={props.height} width={props.width} x={props.x} y={props.y} fill={props.fill} percent={percent} isCurrent={props.isCurrent} isAfterSwapTick={props.isAfterSwapTick} />
}}
>
{formattedData?.map((entry: any, index: number) => {
Expand Down
107 changes: 46 additions & 61 deletions src/components/pools/PoolsList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,66 @@
import { poolsColumns } from '@/components/common/Table/poolsColumns';
import {
usePoolsListQuery,
usePoolsVolumeDataQuery,
} from '@/graphql/generated/graphql';
import { useMemo } from 'react';
import { Address } from 'viem';
import { POOL_AVG_APR_API, POOL_MAX_APR_API, fetcher } from '@/constants/api';
import useSWR from 'swr';
import PoolsTable from '@/components/common/Table/poolsTable';
import { poolsColumns } from "@/components/common/Table/poolsColumns";
import { usePoolsListQuery, usePoolsVolumeDataQuery } from "@/graphql/generated/graphql";
import { useMemo } from "react";
import { Address } from "viem";
import { POOL_AVG_APR_API, POOL_MAX_APR_API, fetcher } from "@/constants/api";
import useSWR from "swr";
import PoolsTable from "@/components/common/Table/poolsTable";
import { usePositions } from "@/hooks/positions/usePositions";
import { usePoolsStore } from "@/state/poolsStore";

const PoolsList = () => {
const { data: pools, loading: isPoolsListLoading } = usePoolsListQuery();

const { data: poolsVolume, loading: isPoolsVolumeLoading } =
usePoolsVolumeDataQuery();
const { data: poolsVolume, loading: isPoolsVolumeLoading } = usePoolsVolumeDataQuery();

const { data: poolsMaxApr, isLoading: isPoolsMaxAprLoading } = useSWR(
POOL_MAX_APR_API,
fetcher
);
const { data: poolsAvgApr, isLoading: isPoolsAvgAprLoading } = useSWR(
POOL_AVG_APR_API,
fetcher
);
const { data: poolsMaxApr, isLoading: isPoolsMaxAprLoading } = useSWR(POOL_MAX_APR_API, fetcher);
const { data: poolsAvgApr, isLoading: isPoolsAvgAprLoading } = useSWR(POOL_AVG_APR_API, fetcher);

const { positions, loading: isPositionsLoading } = usePositions();

const isLoading =
isPoolsListLoading ||
isPoolsVolumeLoading ||
isPoolsMaxAprLoading ||
isPoolsAvgAprLoading;
const isLoading = isPoolsListLoading || isPoolsVolumeLoading || isPoolsMaxAprLoading || isPoolsAvgAprLoading || isPositionsLoading;

const { pluginsForPools } = usePoolsStore();

const formattedPools = useMemo(() => {
if (
!pools?.pools ||
!poolsMaxApr ||
!poolsAvgApr ||
!poolsVolume?.poolDayDatas
)
return [];
if (!pools?.pools || !poolsMaxApr || !poolsAvgApr || !poolsVolume?.poolDayDatas || !positions) return [];

return pools.pools.map(({ id, token0, token1, fee, totalValueLockedUSD }) => {
const currentPool = poolsVolume.poolDayDatas.find((currPool) => currPool.pool.id === id);
const lastDate = currentPool ? currentPool.date * 1000 : 0;
const currentDate = new Date().getTime();

const timeDifference = currentDate - lastDate;
const msIn24Hours = 24 * 60 * 60 * 1000;

return pools.pools.map(
({ id, token0, token1, fee, totalValueLockedUSD }) => {
const currentPool = poolsVolume.poolDayDatas.find(
(currPool) => currPool.pool.id === id
);
const lastDate = currentPool ? currentPool.date * 1000 : 0;
const currentDate = new Date().getTime();
const openPositions = positions.filter((position) => position.pool.toLowerCase() === id.toLowerCase());

const timeDifference = currentDate - lastDate;
const msIn24Hours = 24 * 60 * 60 * 1000;
const hasActiveFarming = pluginsForPools[id as Address]?.farmingPlugin;

return {
id: id as Address,
pair: {
token0,
token1,
},
fee: Number(fee) / 10_000,
tvlUSD: Number(totalValueLockedUSD),
volume24USD:
timeDifference <= msIn24Hours && currentPool
? currentPool.volumeUSD
: 0,
maxApr: poolsMaxApr[id] ? poolsMaxApr[id].toFixed(2) : 0,
avgApr: poolsAvgApr[id] ? poolsAvgApr[id].toFixed(2) : 0,
};
}
);
}, [pools, poolsMaxApr, poolsAvgApr, poolsVolume]);
return {
id: id as Address,
pair: {
token0,
token1,
},
fee: Number(fee) / 10_000,
tvlUSD: Number(totalValueLockedUSD),
volume24USD: timeDifference <= msIn24Hours && currentPool ? currentPool.volumeUSD : 0,
maxApr: poolsMaxApr[id] ? poolsMaxApr[id].toFixed(2) : 0,
avgApr: poolsAvgApr[id] ? poolsAvgApr[id].toFixed(2) : 0,
isMyPool: openPositions?.length > 0,
hasActiveFarming,
};
});
}, [pools, poolsMaxApr, poolsAvgApr, poolsVolume, positions]);

return (
<div className="flex flex-col gap-4">
<PoolsTable
columns={poolsColumns}
data={formattedPools}
defaultSortingID={'tvlUSD'}
link={'pool'}
defaultSortingID={"tvlUSD"}
link={"pool"}
showPagination={true}
loading={isLoading}
/>
Expand Down
17 changes: 8 additions & 9 deletions src/components/swap/TicksChart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,14 @@ const TicksChart = ({ currencyA, currencyB, zoom = 50 }: TicksChartProps) => {

const slicedData = processedData.slice(middle - chunkLength, middle + chunkLength);

if (slicedData[slicedData.length - 1].isAfterSwapRange) {
slicedData.map((t: any) => (t.isAfterSwapTick = false));
slicedData[slicedData.length - 1].isAfterSwapTick = true;
}

if (slicedData[0].isAfterSwapRange) {
slicedData.map((t: any) => (t.isAfterSwapTick = false));
slicedData[0].isAfterSwapTick = true;
}
slicedData.forEach((t: any) => (t.isAfterSwapTick = false));

const firstTick = slicedData.find((t: any) => t.isAfterSwapRange && !t.isReversed);
const lastTick = [...slicedData].reverse().find((t: any) => t.isAfterSwapRange && t.isReversed);

if (firstTick) firstTick.isAfterSwapTick = true;

if (lastTick) lastTick.isAfterSwapTick = true;

return slicedData.reverse();
}, [processedData, zoom, tick]);
Expand Down
4 changes: 4 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@
}
::-webkit-scrollbar-thumb:active{
background: rgba(255, 255, 255, .8);
}

.recharts-surface {
overflow: visible;
}
7 changes: 2 additions & 5 deletions src/utils/swap/processTicks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ export async function processTicks(
const active = currentTick <= tick && tick < nextTick;

const afterSwapRange =
tickAfterSwap &&
((tickAfterSwap >= currentTick && currentTick >= tick) || (tickAfterSwap <= currentTick && currentTick <= tick));

const afterSwapTick = tickAfterSwap && tickAfterSwap >= currentTick && tickAfterSwap < nextTick;
tickAfterSwap && ((tickAfterSwap >= currentTick && currentTick >= tick) || (tickAfterSwap <= nextTick && nextTick <= tick));

const sqrtPriceX96 = TickMath.getSqrtRatioAtTick(currentTick);
const mockTicks = [
Expand Down Expand Up @@ -68,7 +65,7 @@ export async function processTicks(
index: i,
isCurrent: active,
isAfterSwapRange: afterSwapRange,
isAfterSwapTick: afterSwapTick,
isAfterSwapTick: null,
isReversed,
activeLiquidity: parseFloat(t.liquidityActive.toString()),
price0: parseFloat(t.price0),
Expand Down

0 comments on commit 15b9890

Please sign in to comment.