Skip to content

Commit

Permalink
Fix bug causing incorrect Short balance to show (#212)
Browse files Browse the repository at this point in the history
  • Loading branch information
DannyDelott authored Jul 11, 2023
1 parent 6003446 commit 9bbfbd1
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { getFixedAPRQuery } from "@hyperdrive/core";
import { getCurrentFixedAPRQuery } from "@hyperdrive/core";
import { useQuery } from "@tanstack/react-query";
import { Hyperdrive } from "src/appconfig/types";
import { queryClient } from "src/network/queryClient";
import { useAppConfig } from "src/ui/appconfig/useAppConfig";
import { usePublicClient } from "wagmi";

export function useFixedAPR(hyperdrive: Hyperdrive): {
export function useCurrentFixedAPR(hyperdrive: Hyperdrive): {
fixedAPR: { apr: bigint; formatted: string } | undefined;
fixedAPRStatus: "loading" | "error" | "success";
} {
const { appConfig } = useAppConfig();
const publicClient = usePublicClient();

const { data, status } = useQuery(
getFixedAPRQuery({
getCurrentFixedAPRQuery({
hyperdriveAddress: hyperdrive.address,
hyperdriveMathAddress: appConfig?.hyperdriveMath,
publicClient: publicClient as any,
queryClient,
}),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ReactElement } from "react";
import { Hyperdrive } from "src/appconfig/types";
import { convertMillisecondsToDays } from "src/base/convertMillisecondsToDays";
import { Stat } from "src/ui/base/components/Stat";
import { useFixedAPR } from "src/ui/hyperdrive/longs/hooks/useFixedAPR";
import { useCurrentFixedAPR } from "src/ui/hyperdrive/longs/hooks/useCurrentFixedAPR";

export function MarketStats({
hyperdrive,
Expand All @@ -11,7 +11,7 @@ export function MarketStats({
}): ReactElement {
const formattedTermLength = formatTermLength(hyperdrive.termLengthMS);

const { fixedAPR } = useFixedAPR(hyperdrive);
const { fixedAPR } = useCurrentFixedAPR(hyperdrive);

return (
<div className="flex w-full flex-wrap items-center justify-start gap-16">
Expand Down
50 changes: 50 additions & 0 deletions packages/hyperdrive/src/amm/getPoolConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
PublicClient,
Address,
Transport,
Chain,
ContractFunctionResult,
} from "viem";
import { HyperdriveABI } from "src/abis/Hyperdrive";
import { QueryObserverOptions } from "@tanstack/query-core";

interface GetPoolConfigOptions {
hyperdriveAddress: Address;
publicClient: PublicClient<Transport, Chain>;
}

export async function getPoolConfig({
publicClient,
hyperdriveAddress,
}: GetPoolConfigOptions): Promise<
ContractFunctionResult<typeof HyperdriveABI, "getPoolConfig">
> {
return await publicClient.readContract({
address: hyperdriveAddress,
abi: HyperdriveABI,
functionName: "getPoolConfig",
});
}

export function getPoolConfigQuery({
hyperdriveAddress,
publicClient,
}: Partial<GetPoolConfigOptions>): QueryObserverOptions<
Awaited<ReturnType<typeof getPoolConfig>>
> {
const queryEnabled = !!hyperdriveAddress && !!publicClient;

return {
enabled: queryEnabled,
queryKey: ["@hyperdrive/core", "getPoolConfig", { hyperdriveAddress }],
queryFn: queryEnabled
? async () =>
getPoolConfig({
hyperdriveAddress,
publicClient,
})
: undefined,
// pool config is static constants, so it never needs to be refreshed
staleTime: Infinity,
};
}
48 changes: 48 additions & 0 deletions packages/hyperdrive/src/amm/getPoolInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
PublicClient,
Transport,
Chain,
Address,
ContractFunctionResult,
} from "viem";
import { HyperdriveABI } from "src/abis/Hyperdrive";
import { QueryObserverOptions } from "@tanstack/query-core";

interface GetPoolInfoOptions {
hyperdriveAddress: Address;
publicClient: PublicClient<Transport, Chain>;
}

export async function getPoolInfo({
publicClient,
hyperdriveAddress,
}: GetPoolInfoOptions): Promise<
ContractFunctionResult<typeof HyperdriveABI, "getPoolInfo">
> {
return publicClient.readContract({
address: hyperdriveAddress,
abi: HyperdriveABI,
functionName: "getPoolInfo",
});
}

export function getPoolInfoQuery({
hyperdriveAddress,
publicClient,
}: Partial<GetPoolInfoOptions>): QueryObserverOptions<
Awaited<ReturnType<typeof getPoolInfo>>
> {
const queryEnabled = !!hyperdriveAddress && !!publicClient;

return {
enabled: queryEnabled,
queryKey: ["@hyperdrive/core", "getPoolInfo", { hyperdriveAddress }],
queryFn: queryEnabled
? async () =>
getPoolInfo({
hyperdriveAddress,
publicClient,
})
: undefined,
};
}
110 changes: 76 additions & 34 deletions packages/hyperdrive/src/amm/longs/getFixedAPR.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,89 @@
import { PublicClient, Address, Transport, Chain, formatUnits } from "viem";
import { HyperdriveMathABI } from "src/abis/HyperdriveMath";
import { HyperdriveABI } from "src/abis/Hyperdrive";
import { QueryObserverOptions } from "@tanstack/query-core";
import { QueryClient, QueryObserverOptions } from "@tanstack/query-core";
import { getPoolConfigQuery } from "src/amm/getPoolConfig";
import { getPoolInfoQuery } from "src/amm/getPoolInfo";

export interface GetFixedAPROptions {
hyperdriveAddress: Address;
hyperdriveMathAddress: Address;
/**
* Comes from getPoolInfo
*/
shareReserves: bigint;
/**
* Comes from getPoolInfo
*/
bondReserves: bigint;
/**
* Comes from getPoolConfig
*/
initialSharePrice: bigint;
/**
* Comes from getPoolConfig
*/
positionDuration: bigint;
/**
* Comes from getPoolConfig
*/
timeStretch: bigint;
publicClient: PublicClient<Transport, Chain>;
}

export async function getFixedAPR({
hyperdriveAddress,
hyperdriveMathAddress,
publicClient,
shareReserves,
bondReserves,
initialSharePrice,
positionDuration,
timeStretch,
}: GetFixedAPROptions): Promise<{ apr: bigint; formatted: string }> {
// TODO: Move to own method
const poolConfig = await publicClient.readContract({
address: hyperdriveAddress,
abi: HyperdriveABI,
functionName: "getPoolConfig",
});

// TODO: Move to own method
const poolInfo = await publicClient.readContract({
address: hyperdriveAddress,
abi: HyperdriveABI,
functionName: "getPoolInfo",
});

const apr = await publicClient.readContract({
address: hyperdriveMathAddress,
abi: HyperdriveMathABI,
functionName: "calculateAPRFromReserves",
args: [
poolInfo.shareReserves,
poolInfo.bondReserves,
poolConfig.initialSharePrice,
poolConfig.positionDuration,
poolConfig.timeStretch,
shareReserves,
bondReserves,
initialSharePrice,
positionDuration,
timeStretch,
],
});

const formatted = formatAPR(apr);

return {
apr,
formatted,
};
}

function formatAPR(apr: bigint) {
// APR is stored in 18 decimals, so to avoid rounding errors, eg:
// 0.049999999999999996 * 100 = 5, we just take the first 4 characters after
// the decimal, and format those to a percent, eg: 0.0499 * 100 = 4.99.
const truncatedAPR = +formatUnits(apr, 18).slice(0, 6);
const formatted = `${(100 * truncatedAPR).toFixed(2)}`;
return formatted;
}

return {
apr,
formatted,
};
interface GetCurrentFixedAPRQueryOptions {
hyperdriveAddress: Address | undefined;
hyperdriveMathAddress: Address | undefined;
publicClient: PublicClient<Transport, Chain>;
queryClient: QueryClient;
}

/**
* TODO: Move this to its own @hyperdrive/queries package eventually.
*/
export function getFixedAPRQuery({
export function getCurrentFixedAPRQuery({
hyperdriveAddress,
hyperdriveMathAddress,
publicClient,
}: Partial<GetFixedAPROptions>): QueryObserverOptions<
queryClient,
}: GetCurrentFixedAPRQueryOptions): QueryObserverOptions<
Awaited<ReturnType<typeof getFixedAPR>>
> {
const queryEnabled =
Expand All @@ -74,12 +97,31 @@ export function getFixedAPRQuery({
{ hyperdriveAddress, hyperdriveMathAddress },
],
queryFn: queryEnabled
? async () =>
getFixedAPR({
hyperdriveAddress,
hyperdriveMathAddress,
? async () => {
const { initialSharePrice, positionDuration, timeStretch } =
await queryClient.fetchQuery(
getPoolConfigQuery({
publicClient,
hyperdriveAddress,
}),
);
const { bondReserves, shareReserves } = await queryClient.fetchQuery(
getPoolInfoQuery({
publicClient,
hyperdriveAddress,
}),
);

return getFixedAPR({
publicClient,
})
hyperdriveMathAddress,
bondReserves,
shareReserves,
initialSharePrice,
timeStretch,
positionDuration,
});
}
: undefined,
};
}
2 changes: 1 addition & 1 deletion packages/hyperdrive/src/amm/shorts/getOpenShorts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function getOpenShorts({
).filter(
(transferSingleEvent) =>
decodeAssetFromTransferSingleEventData(transferSingleEvent.eventLog.data)
.assetType === "LONG",
.assetType === "SHORT",
);
const shortsRedeemedOrSentById = mapValues(
groupBy(shortsRedeemedOrSent, (event) => event.eventData.id),
Expand Down
14 changes: 6 additions & 8 deletions packages/hyperdrive/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
/** Address lists */
// Address lists
export type { AddressesJson } from "src/addresses/types";
export { HyperdriveGoerliAddresses } from "src/addresses/goerli";

/** ABIs */
// ABIs
export { ERC20_ABI } from "src/abis/ERC20";
export { ERC20MintableABI } from "src/abis/ERC20Mintable";

export { HyperdriveMathABI } from "src/abis/HyperdriveMath";

// TODO: Contracts team to supply a single ABI for the hyperdrive pool soon.
// Use HyperdriveABI for read methods, eg: getPoolConfig
export { HyperdriveABI } from "src/abis/Hyperdrive";

// AMM
export { getPoolConfig, getPoolConfigQuery } from "src/amm/getPoolConfig";
export { getPoolInfo, getPoolInfoQuery } from "src/amm/getPoolInfo";
export { getTransferSingleEvents } from "src/amm/events/getTransferSingleEvents";

/** Longs */
// Longs
export { getOpenLongs, getOpenLongsQuery } from "src/amm/longs/getOpenLongs";
export type { GetOpenLongsOptions } from "src/amm/longs/getOpenLongs";
export {
Expand All @@ -24,7 +22,7 @@ export {
} from "src/amm/longs/getClosedLongs";
export type { GetClosedLongsOptions as GetCloseLongsOptions } from "src/amm/longs/getClosedLongs";
export type { Long, ClosedLong } from "src/amm/longs/types";
export { getFixedAPRQuery } from "src/amm/longs/getFixedAPR";
export { getCurrentFixedAPRQuery } from "src/amm/longs/getFixedAPR";

// Shorts
export {
Expand Down

2 comments on commit 9bbfbd1

@vercel
Copy link

@vercel vercel bot commented on 9bbfbd1 Jul 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

hyperdrive-fixed-borrow – ./apps/fixed-borrow

hyperdrive-fixed-borrow.vercel.app
hyperdrive-fixed-borrow-delvtech.vercel.app
hyperdrive-fixed-borrow-git-main-delvtech.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 9bbfbd1 Jul 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

hyperdrive-monorepo-hyperdrive-trading – ./apps/hyperdrive-trading

hyperdrive-monorepo-hyperdrive-trading-git-main-delvtech.vercel.app
hyperdrive-monorepo-hyperdrive-trading-delvtech.vercel.app
hyperdrive-monorepo-hyperdrive-trading.vercel.app

Please sign in to comment.