Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/staking-app-release-batch' int…
Browse files Browse the repository at this point in the history
…o feat/add-pythnet-client
  • Loading branch information
cprussin committed Oct 8, 2024
2 parents 498a251 + 1a37585 commit 7d59721
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 12 deletions.
7 changes: 5 additions & 2 deletions apps/staking/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ type Data = {
poolUtilizationDelta: bigint;
numFeeds: number;
qualityRanking: number;
apyHistory: { date: Date; apy: number }[];
delegationFee: bigint;
apyHistory: { date: Date; apy: number; selfApy: number }[];
positions?:
| {
warmup?: bigint | undefined;
Expand Down Expand Up @@ -254,9 +255,10 @@ const loadPublisherData = async (
(ranking) => ranking.publisher === publisherPubkeyString,
);
const numberOfSymbols = publisherNumberOfSymbols[publisherPubkeyString];
const apyHistory = publisher.apyHistory.map(({ epoch, apy }) => ({
const apyHistory = publisher.apyHistory.map(({ epoch, apy, selfApy }) => ({
date: epochToDate(epoch + 1n),
apy,
selfApy,
}));

return {
Expand All @@ -271,6 +273,7 @@ const loadPublisherData = async (
selfStake: publisher.selfDelegation,
selfStakeDelta: publisher.selfDelegationDelta,
stakeAccount: publisher.stakeAccount ?? undefined,
delegationFee: publisher.delegationFee,
};
});
};
Expand Down
11 changes: 8 additions & 3 deletions apps/staking/src/components/OracleIntegrityStaking/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1044,13 +1044,15 @@ const compareApy = (
poolCapacity: b.poolCapacity,
poolUtilization: b.poolUtilization + b.poolUtilizationDelta,
yieldRate,
delegationFee: b.delegationFee,
}) -
calculateApy({
isSelf: false,
selfStake: a.selfStake + a.selfStakeDelta,
poolCapacity: a.poolCapacity,
poolUtilization: a.poolUtilization + a.poolUtilizationDelta,
yieldRate,
delegationFee: a.delegationFee,
}));

const comparePoolCapacity = (
Expand Down Expand Up @@ -1174,7 +1176,8 @@ type PublisherProps = {
poolUtilizationDelta: bigint;
numFeeds: number;
qualityRanking: number;
apyHistory: { date: Date; apy: number }[];
delegationFee: bigint;
apyHistory: { date: Date; apy: number; selfApy: number }[];
positions?:
| {
warmup?: bigint | undefined;
Expand Down Expand Up @@ -1235,6 +1238,7 @@ const Publisher = ({
poolUtilization:
publisher.poolUtilization + publisher.poolUtilizationDelta,
yieldRate,
delegationFee: publisher.delegationFee,
}).toFixed(2),
[
isSelf,
Expand Down Expand Up @@ -1373,9 +1377,9 @@ const Publisher = ({
<PublisherTableCell>
<div className="mx-auto h-14 w-28">
<SparkChart
data={publisher.apyHistory.map(({ date, apy }) => ({
data={publisher.apyHistory.map(({ date, apy, selfApy }) => ({
date,
value: apy,
value: isSelf ? selfApy : apy,
}))}
/>
</div>
Expand Down Expand Up @@ -1662,6 +1666,7 @@ const NewApy = ({
calculateApy({
poolCapacity: publisher.poolCapacity,
yieldRate,
delegationFee: publisher.delegationFee,
...(isSelf
? {
isSelf: true,
Expand Down
1 change: 1 addition & 0 deletions governance/pyth_staking_sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export type PublisherData = {
totalDelegationDelta: bigint;
selfDelegation: bigint;
selfDelegationDelta: bigint;
delegationFee: bigint;
apyHistory: { epoch: bigint; apy: number; selfApy: number }[];
}[];

Expand Down
19 changes: 17 additions & 2 deletions governance/pyth_staking_sdk/src/utils/apy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@ export const convertEpochYieldToApy = (epochYield: bigint) => {
return (Number(epochYield) * 52 * 100) / FRACTION_PRECISION;
};

export const computeDelegatorRewardPercentage = (delegationFee: bigint) => {
return 1 - Number(delegationFee) / FRACTION_PRECISION;
};

export const calculateApy = (
options: {
selfStake: bigint;
poolCapacity: bigint;
yieldRate: bigint;
delegationFee: bigint;
} & ({ isSelf: true } | { isSelf: false; poolUtilization: bigint }),
) => {
const { selfStake, poolCapacity, yieldRate, isSelf } = options;
const eligibleSelfStake = selfStake > poolCapacity ? poolCapacity : selfStake;

if (poolCapacity === 0n) {
return 0;
}

const apyPercentage = convertEpochYieldToApy(yieldRate);

if (isSelf) {
Expand All @@ -24,6 +33,9 @@ export const calculateApy = (
}

const { poolUtilization } = options;
const delegatorPercentage = computeDelegatorRewardPercentage(
options.delegationFee,
);

const delegatorPoolUtilization = poolUtilization - selfStake;
const delegatorPoolCapacity = poolCapacity - eligibleSelfStake;
Expand All @@ -33,10 +45,13 @@ export const calculateApy = (
: delegatorPoolUtilization;

if (poolUtilization === selfStake) {
return apyPercentage;
return (
(selfStake >= poolCapacity ? 0 : apyPercentage) * delegatorPercentage
);
}

return (
(apyPercentage * Number(eligibleStake)) / Number(delegatorPoolUtilization)
(apyPercentage * delegatorPercentage * Number(eligibleStake)) /
Number(delegatorPoolUtilization)
);
};
18 changes: 13 additions & 5 deletions governance/pyth_staking_sdk/src/utils/pool.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { PublicKey } from "@solana/web3.js";

import { convertEpochYieldToApy } from "./apy";
import {
computeDelegatorRewardPercentage,
convertEpochYieldToApy,
} from "./apy";
import { FRACTION_PRECISION_N } from "../constants";
import type { PoolDataAccount, PublisherData } from "../types";

Expand All @@ -24,14 +27,19 @@ export const extractPublisherData = (
(poolData.selfDelState[index]?.deltaDelegation ?? 0n),
selfDelegation: poolData.selfDelState[index]?.totalDelegation ?? 0n,
selfDelegationDelta: poolData.selfDelState[index]?.deltaDelegation ?? 0n,
delegationFee: poolData.delegationFees[index] ?? 0n,
apyHistory: poolData.events
.filter((event) => event.epoch > 0n)
.map((event) => ({
epoch: event.epoch,
apy: convertEpochYieldToApy(
(event.y * (event.eventData[index]?.otherRewardRatio ?? 0n)) /
FRACTION_PRECISION_N,
),
apy:
convertEpochYieldToApy(
(event.y * (event.eventData[index]?.otherRewardRatio ?? 0n)) /
FRACTION_PRECISION_N,
) *
computeDelegatorRewardPercentage(
poolData.delegationFees[index] ?? 0n,
),
selfApy: convertEpochYieldToApy(
(event.y * (event.eventData[index]?.selfRewardRatio ?? 0n)) /
FRACTION_PRECISION_N,
Expand Down

0 comments on commit 7d59721

Please sign in to comment.