diff --git a/package.json b/package.json
index 8114c04..fc1a469 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "ghost-dao-interface",
"private": true,
- "version": "0.7.40",
+ "version": "0.7.41",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/src/containers/Breakout/BreakoutModal.jsx b/src/containers/Breakout/BreakoutModal.jsx
index 36971f1..58d1729 100644
--- a/src/containers/Breakout/BreakoutModal.jsx
+++ b/src/containers/Breakout/BreakoutModal.jsx
@@ -20,7 +20,7 @@ import { GHOST_CONNECT } from "../../constants/ecosystem";
import { useLocalStorage } from "../../hooks/localstorage";
import { useBreakoutModal } from "../../hooks/breakoutModal";
-import { useTokenSymbol, useCirculatingSupply } from "../../hooks/tokens";
+import { useTokenSymbol } from "../../hooks/tokens";
import { useEpoch, useGatekeeperApy, useGatekeeperAddress } from "../../hooks/staking";
import { useEvmNetwork, useCurrentIndex, useUnstableProvider } from "../../hooks/ghost";
import { formatNumber, shorten } from "../../helpers";
@@ -252,8 +252,7 @@ const WelcomeView = ({
const { epoch } = useEpoch(chainId);
const { gatekeeperAddress } = useGatekeeperAddress(chainId);
- const circulatingSupply = useCirculatingSupply(chainId, "STNK");
- const gatekeepedApy = useGatekeeperApy(chainId);
+ const { gatekeepedApy, apyInner } = useGatekeeperApy(chainId);
const { isExtensionMissing } = useUnstableProvider();
@@ -262,16 +261,6 @@ const WelcomeView = ({
closeModal();
}
- const apyInner = useMemo(() => {
- let apy = Infinity;
- if (circulatingSupply._value > 0n) {
- const value = epoch.distribute.div(circulatingSupply);
- apy = 100 * (Math.pow(1 + parseFloat(value.toString()), 1095) - 1);
- if (apy === 0) apy = Infinity;
- }
- return apy;
- }, [circulatingSupply, epoch]);
-
const callDefaultFunction = useCallback(async () => {
setIsPending(true);
await defaultFunction()();
@@ -314,7 +303,7 @@ const WelcomeView = ({
- {formatNumber(apyInner * gatekeepedApy, 2)}% APY
+ {formatNumber(gatekeepedApy, 2)}% APY
{
const { symbol: csprSymbol } = useTokenSymbol(chainId, "CSPR");
const { contractAddress: ftsoAddress } = useBalance(chainId, "FTSO", EMPTY_ADDRESS);
const { liveBonds } = useLiveBonds(chainId);
-
- const circulatingSupply = useCirculatingSupply(chainId, "STNK");
- const gatekeepedApy = useGatekeeperApy(chainId);
- const { epoch } = useEpoch(chainId);
+ const { gatekeepedApy, apyInner } = useGatekeeperApy(chainId);
const maxBondDiscountTest = useMemo(() => {
const sortedGhostBonds = liveBonds.filter((bond) => !bond.isSoldOut)
@@ -83,16 +80,6 @@ const ProtocolDetails = ({ chainId, isMobileScreen, theme, }) => {
return `Up to ${formatNumber(maxDiscount, 0)}% Discount`;
}, [liveBonds]);
- const apyInner = useMemo(() => {
- let apy = Infinity;
- if (circulatingSupply._value > 0n) {
- const value = epoch.distribute.div(circulatingSupply);
- apy = 100 * (Math.pow(1 + parseFloat(value.toString()), 1095) - 1);
- if (apy === 0) apy = Infinity;
- }
- return apy;
- }, [circulatingSupply, epoch]);
-
const bridgeNumbers = useMemo(() => {
const connectedNetworks = Object.keys(GATEKEEPER_ADDRESSES).length;
const number = 1 + connectedNetworks * 3;
@@ -138,7 +125,7 @@ const ProtocolDetails = ({ chainId, isMobileScreen, theme, }) => {
theme={theme}
url={`/${networkName.toLowerCase()}/bridge`}
name={`${bridgeNumbers} Stake\u00B2`}
- sideName={`${formatNumber(apyInner * gatekeepedApy, 0)}% APY`}
+ sideName={`${formatNumber(gatekeepedApy, 0)}% APY`}
description={`Staking\u00B2 strategy further deepens long-term incentives powered by sustainable crosschain bridging revenue. ${bridgeNumbers} Stake\u00B2 your ${csprSymbol} to receive organic APY with no warm-up and no dilution.`}
/>
diff --git a/src/hooks/staking/index.js b/src/hooks/staking/index.js
index 368a314..8cea140 100644
--- a/src/hooks/staking/index.js
+++ b/src/hooks/staking/index.js
@@ -8,21 +8,18 @@ import { abi as GatekeeperAbi } from "../../abi/GhostGatekeeper.json";
import { shorten } from "../../helpers";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import { executeOnChainTransaction } from "../helpers";
+import { useCirculatingSupply } from "../tokens";
export const useGatekeeperApy = (chainId) => {
- const { data: gatekeeper, refetch } = useReadContract({
- abi: StakingAbi,
- address: STAKING_ADDRESSES[chainId],
- functionName: "gatekeeper",
- scopeKey: `gatekeeper-${chainId}`,
- chainId: chainId,
- });
+ const circulatingSupply = useCirculatingSupply(chainId, "STNK");
+ const { gatekeeperAddress } = useGatekeeperAddress(chainId);
+ const { epoch } = useEpoch(chainId);
const { data: metadata, error } = useReadContract({
abi: GatekeeperAbi,
- address: gatekeeper,
+ address: gatekeeperAddress,
functionName: "metadata",
- scopeKey: `gatekeeperMetadata-${chainId}-${gatekeeper}`,
+ scopeKey: `gatekeeperMetadata-${chainId}-${gatekeeperAddress}`,
chainId: chainId,
});
@@ -40,12 +37,25 @@ export const useGatekeeperApy = (chainId) => {
const numerator = amountIn.mul(feeIn).add(amountOut.mul(feeOut));
const denominator = amountIn.mul(stakeRatio).sub(amountOut.mul(stakeRatio));
- if (denominator?.toString() === "0") {
- return 1;
+ let apyInner = Infinity;
+ if ((circulatingSupply?._value ?? 0n) === 0n) {
+ return { gatekeepedApy: apyInner, apyInner};
}
+ const value = epoch.distribute.div(circulatingSupply);
+ apyInner = 100 * (Math.pow(1 + parseFloat(value.toString()), 1095) - 1);
+ if (apyInner === 0) apyInner = Infinity;
+
+ if (!denominator?._value || denominator._value.isZero()) {
+ return { gatekeepedApy: apyInner, apyInner };
+ }
const result = Number(numerator.div(denominator).toString());
- return Math.pow(1 + result, power);
+ const gatekeepedApy = Math.pow(1 + result, power);
+
+ return {
+ gatekeepedApy: apyInner + gatekeepedApy + (apyInner * gatekeepedApy) / 100,
+ apyInner,
+ }
}
export const useCurrentIndex = (chainId) => {