Skip to content

Commit

Permalink
Show the correct number of days when pool is younger than rate period (
Browse files Browse the repository at this point in the history
…#1481)

* Add ratePeriodDays to useLpApy and useVaultRate hooks

* Update PoolRow to display the ratePeriodDays

* Update other places we display rate period
  • Loading branch information
DannyDelott authored Sep 11, 2024
1 parent b0fec7a commit 34509b9
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 33 deletions.
96 changes: 71 additions & 25 deletions apps/hyperdrive-trading/src/hyperdrive/getYieldSourceRate.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,86 @@
import { Block, ReadHyperdrive } from "@delvtech/hyperdrive-viem";
import { AppConfig, findHyperdriveConfig } from "@hyperdrive/appconfig";
import {
AppConfig,
findHyperdriveConfig,
HyperdriveConfig,
} from "@hyperdrive/appconfig";
import { convertMillisecondsToDays } from "src/base/convertMillisecondsToDays";
import { isForkChain } from "src/chains/isForkChain";

export async function getYieldSourceRate(
readHyperdrive: ReadHyperdrive,
appConfig: AppConfig,
): Promise<bigint> {
): Promise<{ rate: bigint; ratePeriodDays: number }> {
const hyperdriveChainId = await readHyperdrive.network.getChainId();
const hyperdrive = findHyperdriveConfig({
hyperdriveChainId,
hyperdriveAddress: readHyperdrive.address,
hyperdrives: appConfig.hyperdrives,
});

const numBlocksForHistoricalRate = getNumBlocksForHistoricalRate({
appConfig,
hyperdrive,
});

const currentBlock = (await readHyperdrive.network.getBlock()) as Block;
const initializationBlock = hyperdrive.initializationBlock;

const isPoolYoungerThanOneRatePeriod =
initializationBlock >
currentBlock.blockNumber! - numBlocksForHistoricalRate;

// If we don't have enough blocks to go back 1 full historical period, then
// grab the all-time rate instead.
if (isPoolYoungerThanOneRatePeriod) {
const blocksSinceInitialization =
currentBlock.blockNumber! - initializationBlock;

const daysSinceInitialization = convertMillisecondsToDays(
Date.now() - Number(hyperdrive.initializationTimestamp * 1000n),
);

return {
rate: await readHyperdrive.getYieldSourceRate({
blockRange: blocksSinceInitialization,
}),
ratePeriodDays: daysSinceInitialization,
};
}

const rate = await readHyperdrive.getYieldSourceRate({
blockRange: numBlocksForHistoricalRate,
});

return {
rate,
ratePeriodDays:
appConfig.yieldSources[hyperdrive.yieldSource].historicalRatePeriod,
};
}

function getNumBlocksForHistoricalRate({
appConfig,
hyperdrive,
}: {
appConfig: AppConfig;
hyperdrive: HyperdriveConfig;
}) {
const blocksPerDay = appConfig.chains[hyperdrive.chainId].dailyAverageBlocks;
const historicalRatePeriod =
appConfig.yieldSources[hyperdrive.yieldSource].historicalRatePeriod;

const numBlocksForHistoricalRate = isForkChain(hyperdrive.chainId)
? 1000n // roughly 3 hours for cloudchain
: appConfig.chains[hyperdrive.chainId].dailyAverageBlocks *
BigInt(
appConfig.yieldSources[hyperdrive.yieldSource].historicalRatePeriod,
);

return (
readHyperdrive
.getYieldSourceRate({
blockRange: numBlocksForHistoricalRate,
})
// If the 24 hour rate doesn't exist, assume the pool was initialized less
// than 24 hours ago and try to get the all-time rate
.catch(async () => {
const currentBlock = (await readHyperdrive.network.getBlock()) as Block;
const initializationBlock = hyperdrive.initializationBlock;
const blocksSinceInitialization =
currentBlock.blockNumber! - initializationBlock;

return readHyperdrive.getYieldSourceRate({
blockRange: blocksSinceInitialization,
});
})
);
: blocksPerDay * BigInt(historicalRatePeriod);

return numBlocksForHistoricalRate;
}

function getDaysSinceInitialization({
hyperdrive,
}: {
hyperdrive: HyperdriveConfig;
}): number {
return Number(hyperdrive.initializationTimestamp * 1000n) - Date.now();
}
24 changes: 23 additions & 1 deletion apps/hyperdrive-trading/src/ui/hyperdrive/hooks/useLpApy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Block } from "@delvtech/hyperdrive-viem";
import { findHyperdriveConfig } from "@hyperdrive/appconfig";
import { useQuery } from "@tanstack/react-query";
import { convertMillisecondsToDays } from "src/base/convertMillisecondsToDays";
import { formatRate } from "src/base/formatRate";
import { makeQueryKey } from "src/base/makeQueryKey";
import { isForkChain } from "src/chains/isForkChain";
Expand All @@ -16,7 +18,9 @@ export function useLpApy({
hyperdriveAddress: Address;
chainId: number;
}): {
lpApy: { lpApy: bigint; formatted: string } | undefined;
lpApy:
| { lpApy: bigint; formatted: string; ratePeriodDays: number }
| undefined;
lpApyStatus: "error" | "success" | "loading";
} {
const { poolInfo: currentPoolInfo } = usePoolInfo({
Expand Down Expand Up @@ -58,8 +62,26 @@ export function useLpApy({
blockNumber - numBlocksForHistoricalRate,
});

// Figure out if the pool is younger than 1 rate period
const currentBlock =
(await readHyperdrive.network.getBlock()) as Block;
const isPoolYoungerThanOneRatePeriod =
hyperdrive.initializationBlock >
currentBlock.blockNumber! - numBlocksForHistoricalRate;

// If we don't have enough blocks to go back 1 full historical period, then
// grab the all-time rate instead.
let ratePeriodDays =
appConfig.yieldSources[hyperdrive.yieldSource].historicalRatePeriod;
if (isPoolYoungerThanOneRatePeriod) {
ratePeriodDays = convertMillisecondsToDays(
Date.now() - Number(hyperdrive.initializationTimestamp * 1000n),
);
}

return {
lpApy,
ratePeriodDays,
formatted: formatRate(lpApy),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function VariableRateStat({

return (
<Stat
label={`Variable APY (${yieldSource.historicalRatePeriod}d)`}
label={`Variable APY (${vaultRate?.ratePeriodDays}d)`}
description={`The yield rate earned on deposits into ${yieldSource.shortName} in the last ${yieldSource.historicalRatePeriod} days.`}
tooltipPosition="bottom"
value={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function YieldStats({
</Animated>
<Animated isActive={position === "lp"}>
<Stat
label={`LP APY (${yieldSource.historicalRatePeriod}d)`}
label={lpApy ? `LP APY (${lpApy.ratePeriodDays}d)` : "LP APY"}
value={
<RewardsTooltip
chainId={hyperdrive.chainId}
Expand Down
2 changes: 1 addition & 1 deletion apps/hyperdrive-trading/src/ui/markets/PoolRow/PoolRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ export function PoolRow({
}
/>
<PoolStat
label={`LP APY (${yieldSources[hyperdrive.yieldSource].historicalRatePeriod}d)`}
label={lpApy ? `LP APY (${lpApy.ratePeriodDays}d)` : "LP APY"}
isLoading={lpApyStatus === "loading"}
isNew={isLpApyNew}
value={
Expand Down
14 changes: 10 additions & 4 deletions apps/hyperdrive-trading/src/ui/vaults/useYieldSourceRate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export function useYieldSourceRate({
chainId: number;
hyperdriveAddress: Address | undefined;
}): {
vaultRate: { vaultRate: bigint; formatted: string } | undefined;
vaultRate:
| { vaultRate: bigint; formatted: string; ratePeriodDays: number }
| undefined;
vaultRateStatus: "error" | "success" | "loading";
} {
const readHyperdrive = useReadHyperdrive({
Expand All @@ -22,22 +24,26 @@ export function useYieldSourceRate({
});
const appConfig = useAppConfig();
const queryEnabled = !!hyperdriveAddress && !!readHyperdrive;
const { data: vaultRate, status: vaultRateStatus } = useQuery({
const { data, status: vaultRateStatus } = useQuery({
enabled: queryEnabled,
queryKey: makeQueryKey("vaultRate", {
chainId,
hyperdriveAddress,
}),
queryFn: queryEnabled
? async () => {
const rate = await getYieldSourceRate(readHyperdrive, appConfig);
const { rate, ratePeriodDays } = await getYieldSourceRate(
readHyperdrive,
appConfig,
);
return {
vaultRate: rate,
formatted: formatRate(rate),
ratePeriodDays,
};
}
: undefined,
});

return { vaultRate, vaultRateStatus };
return { vaultRate: data, vaultRateStatus };
}

0 comments on commit 34509b9

Please sign in to comment.