Skip to content

Commit

Permalink
fix volume/reserve/fees display when usd value is unavailable
Browse files Browse the repository at this point in the history
  • Loading branch information
alecananian committed Jun 28, 2024
1 parent 57e4198 commit 8a1768e
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 35 deletions.
2 changes: 1 addition & 1 deletion app/components/SearchPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ const SearchPopup = ({ onClose }: SearchProps) => {
<p className="text-md text-night-600">Volume(24h)</p>
</div>
<div className="flex w-1/3 justify-end">
<p className="text-md text-night-600">APR</p>
<p className="text-md text-night-600">APY</p>
</div>
<div className="flex w-1/3 justify-end">
<p className="text-md text-night-600">TVL</p>
Expand Down
7 changes: 7 additions & 0 deletions app/graphql/pair.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,21 @@ export const PAIR_FRAGMENT = gql`
reserveUSD
totalSupply
txCount
volume0
volume1
volumeUSD
lpFee
protocolFee
royaltiesFee
royaltiesBeneficiary
totalFee
dayData(first: 7, orderBy: date, orderDirection: desc) {
date
reserve0
reserve1
reserveUSD
volume0
volume1
volumeUSD
txCount
}
Expand Down
42 changes: 23 additions & 19 deletions app/lib/pools.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ import type {
TroveTokenMapping,
} from "~/types";

const getPoolAPY = (volume1w: number, reserveUSD: number) => {
if (reserveUSD === 0) {
return 0;
}

const apr = ((volume1w / 7) * 365 * 0.0025) / reserveUSD;
return ((1 + apr / 100 / 3650) ** 3650 - 1) * 100;
};

export const createPoolFromPair = (
pair: Pair,
collectionMapping: TroveCollectionMapping,
Expand All @@ -38,12 +29,12 @@ export const createPoolFromPair = (
parseUnits(pair.reserve1 as NumberString, Number(pair.token1.decimals))
).toString(),
};

const reserveUSD = Number(pair.reserveUSD);
const volume24h = Number(pair.dayData[0]?.volumeUSD ?? 0);
const volume1w = pair.dayData.reduce(
(total, { volumeUSD }) => total + Number(volumeUSD),
0
);
const dayTime = Math.floor(Date.now() / 1000) - 60 * 60 * 24;
const dayData = pair.dayData.find(({ date }) => Number(date) >= dayTime);
const weekTime = Math.floor(Date.now() / 1000) - 60 * 60 * 24 * 7;
const weekData = pair.dayData.filter(({ date }) => Number(date) >= weekTime);
return {
...pair,
name: `${token0.symbol} / ${token1.symbol}`,
Expand All @@ -52,11 +43,24 @@ export const createPoolFromPair = (
hasNFT: token0.isNFT || token1.isNFT,
isNFTNFT: token0.isNFT && token1.isNFT,
reserveUSD,
volume24h,
volume1w,
apy: getPoolAPY(volume1w, reserveUSD),
feesUSD: Number(pair.volumeUSD) * Number(pair.lpFee),
fees24h: volume24h * Number(pair.lpFee),
volume0: Number(pair.volume0),
volume1: Number(pair.volume1),
volumeUSD: Number(pair.volumeUSD),
volume24h0: Number(dayData?.volume0 ?? 0),
volume24h1: Number(dayData?.volume1 ?? 0),
volume24hUSD: Number(dayData?.volumeUSD ?? 0),
volume1w0: weekData.reduce(
(total, { volume0 }) => total + Number(volume0),
0
),
volume1w1: weekData.reduce(
(total, { volume1 }) => total + Number(volume1),
0
),
volume1wUSD: weekData.reduce(
(total, { volumeUSD }) => total + Number(volumeUSD),
0
),
};
};

Expand Down
77 changes: 74 additions & 3 deletions app/lib/pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {
} from "@sushiswap/tines";
import { parseUnits } from "viem";

import { formatAmount, formatTokenAmount, formatUSD } from "./currency";
import type { Pool } from "./pools.server";
import { tokenToRToken } from "./tokens";
import type { AddressString, NumberString, PoolToken } from "~/types";
import type { AddressString, PoolToken } from "~/types";

export const quote = (amountA: bigint, reserveA: bigint, reserveB: bigint) =>
reserveA > 0 ? (amountA * reserveB) / reserveA : 0n;
Expand Down Expand Up @@ -51,8 +52,8 @@ export const createSwapRoute = (
tokenToRToken(token0),
tokenToRToken(token1),
Number(totalFee ?? 0),
parseUnits(reserve0 as NumberString, token0.decimals),
parseUnits(reserve1 as NumberString, token0.decimals)
parseUnits(reserve0.toString(), token0.decimals),
parseUnits(reserve1.toString(), token0.decimals)
);
}
);
Expand Down Expand Up @@ -80,3 +81,73 @@ export const createSwapRoute = (

return findMultiRouteExactIn(rTokenIn, rTokenOut, amount, rPools, networks);
};

export const getPoolAPY = (pool: Pool) => {
const volume1w = pool.volume1wUSD
? pool.volume1wUSD
: pool.isNFTNFT || !pool.token0.isNFT
? pool.volume1w0
: pool.volume1w1;
const reserve = pool.reserveUSD
? pool.reserveUSD
: pool.isNFTNFT || !pool.token0.isNFT
? Number(pool.token0.reserve)
: Number(pool.token1.reserve);

if (reserve === 0) {
return 0;
}

const apr = ((volume1w / 7) * 365 * 0.0025) / reserve;
return ((1 + apr / 100 / 3650) ** 3650 - 1) * 100;
};

export const getPoolVolume24hDisplay = (pool: Pool) => {
if (!pool.volume24hUSD) {
if (pool.isNFTNFT || !pool.token0.isNFT) {
return `${formatAmount(pool.volume24h0)} ${pool.token0.symbol}`;
}

return `${formatAmount(pool.volume24h1)} ${pool.token1.symbol}`;
}

return formatUSD(pool.volume24hUSD);
};

export const getPoolReserveDisplay = (pool: Pool) => {
if (!pool.reserveUSD) {
if (pool.isNFTNFT || !pool.token0.isNFT) {
return `${formatTokenAmount(BigInt(pool.token0.reserve))} ${pool.token0.symbol}`;
}

return `${formatTokenAmount(BigInt(pool.token1.reserve))} ${pool.token1.symbol}`;
}

return formatUSD(pool.reserveUSD);
};

export const getPoolFeesDisplay = (pool: Pool) => {
const fee = Number(pool.lpFee);
if (!pool.volumeUSD) {
if (pool.isNFTNFT || !pool.token0.isNFT) {
return `${formatAmount(pool.volume0 * fee)} ${pool.token0.symbol}`;
}

return `${formatAmount(pool.volume0 * fee)}`;
}

return formatUSD(pool.volumeUSD * fee);
};

export const getPoolFees24hDisplay = (pool: Pool) => {
const fee = Number(pool.lpFee);
if (!pool.volume24hUSD) {
if (pool.isNFTNFT || !pool.token0.isNFT) {
return `${formatAmount(pool.volume24h0 * fee)} ${pool.token0.symbol}`;
}

return `${formatAmount(pool.volume24h1 * fee)}`;
}

return formatUSD(pool.volume24hUSD * fee);
};
15 changes: 10 additions & 5 deletions app/routes/pools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ import { Tabs } from "~/components/Tabs";
import { PoolImage } from "~/components/pools/PoolImage";
import { Button } from "~/components/ui/Button";
import { useAccount } from "~/contexts/account";
import { formatUSD } from "~/lib/currency";
import { formatPercent } from "~/lib/number";
import {
getPoolAPY,
getPoolFeesDisplay,
getPoolReserveDisplay,
getPoolVolume24hDisplay,
} from "~/lib/pools";
import type { Pool } from "~/lib/pools.server";
import { generateTitle, getSocialMetas, getUrl } from "~/lib/seo";
import type { RootLoader } from "~/root";
Expand Down Expand Up @@ -101,16 +106,16 @@ const PoolsTable = ({ pools }: { pools: Pool[] }) => {
</Link>
</td>
<td className="hidden px-4 py-4 text-right sm:table-cell sm:px-5">
{formatUSD(pool.volume24h)}
{getPoolVolume24hDisplay(pool)}
</td>
<td className="hidden px-4 py-4 text-right sm:table-cell sm:px-5">
{formatPercent(pool.apy)}
{formatPercent(getPoolAPY(pool))}
</td>
<td className="px-4 py-4 text-right sm:px-5">
{formatUSD(pool.reserveUSD)}
{getPoolReserveDisplay(pool)}
</td>
<td className="hidden px-4 py-4 text-right sm:table-cell sm:px-5">
{formatUSD(pool.feesUSD)}
{getPoolFeesDisplay(pool)}
</td>
</tr>
))}
Expand Down
13 changes: 9 additions & 4 deletions app/routes/pools_.$id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ import { truncateEthAddress } from "~/lib/address";
import { sumArray } from "~/lib/array";
import { formatAmount, formatTokenAmount, formatUSD } from "~/lib/currency";
import { bigIntToNumber, formatNumber, formatPercent } from "~/lib/number";
import {
getPoolAPY,
getPoolFees24hDisplay,
getPoolVolume24hDisplay,
} from "~/lib/pools";
import type { Pool } from "~/lib/pools.server";
import { generateTitle, getSocialMetas, getUrl } from "~/lib/seo";
import { cn } from "~/lib/utils";
Expand Down Expand Up @@ -388,19 +393,19 @@ export default function PoolDetailsPage() {
<div className="flex w-full flex-col gap-0.5 rounded-lg bg-night-1100 px-4 py-3">
<p className="text-night-500">Volume (24h)</p>
<p className="font-medium text-night-100">
{formatUSD(pool.volume24h)}
{getPoolVolume24hDisplay(pool)}
</p>
</div>
<div className="flex w-full flex-col gap-0.5 rounded-lg bg-night-1100 px-4 py-3">
<p className="text-night-500">APR</p>
<p className="text-night-500">APY</p>
<p className="font-medium text-night-100">
{formatPercent(pool.apy)}
{formatPercent(getPoolAPY(pool))}
</p>
</div>
<div className="flex w-full flex-col gap-0.5 rounded-lg bg-night-1100 px-4 py-3">
<p className="text-night-500">Fees (24h)</p>
<p className="font-medium text-night-100">
{formatUSD(pool.fees24h)}
{getPoolFees24hDisplay(pool)}
</p>
</div>
</div>
Expand Down
7 changes: 4 additions & 3 deletions app/routes/pools_.$id[.]png.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { MagicSwapLogoFull } from "@treasure-project/branding";
import invariant from "tiny-invariant";

import { fetchPool } from "~/api/pools.server";
import { formatAmount, formatTokenAmount, formatUSD } from "~/lib/currency";
import { formatAmount, formatTokenAmount } from "~/lib/currency";
import { bigIntToNumber, formatPercent } from "~/lib/number";
import {
NIGHT_100,
NIGHT_400,
TokenDisplay,
generateOgImage,
} from "~/lib/og.server";
import { getPoolAPY, getPoolReserveDisplay } from "~/lib/pools";

const PILL_BG = "rgba(64, 70, 82, 0.6)";

Expand Down Expand Up @@ -89,7 +90,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
color: NIGHT_100,
}}
>
{formatUSD(pool?.reserveUSD || 0)}
{pool ? getPoolReserveDisplay(pool) : 0}
</div>
<div
style={{
Expand All @@ -107,7 +108,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
color: NIGHT_100,
}}
>
{formatPercent(pool?.apy || 0)}
{formatPercent(pool ? getPoolAPY(pool) : 0)}
</div>
<div
style={{
Expand Down

0 comments on commit 8a1768e

Please sign in to comment.