diff --git a/projects/ui/src/components/App/index.tsx b/projects/ui/src/components/App/index.tsx
index 9d95c520f..4955c7bef 100644
--- a/projects/ui/src/components/App/index.tsx
+++ b/projects/ui/src/components/App/index.tsx
@@ -266,7 +266,7 @@ function Arbitrum() {
}
export default function App() {
- const { isArbitrum, isDev: isTestnet } = useChainState();
+ const { isArbitrum, isTestnet } = useChainState();
if (!isArbitrum || (isArbitrum && !isTestnet)) {
return ;
diff --git a/projects/ui/src/components/Balances/SiloBalancesHistory.tsx b/projects/ui/src/components/Balances/SiloBalancesHistory.tsx
index 4ad540f9a..2e00fc459 100644
--- a/projects/ui/src/components/Balances/SiloBalancesHistory.tsx
+++ b/projects/ui/src/components/Balances/SiloBalancesHistory.tsx
@@ -11,7 +11,7 @@ import {
SeasonRange,
} from '~/hooks/beanstalk/useSeasonsQuery';
import useFarmerSiloHistory from '~/hooks/farmer/useFarmerSiloHistory';
-import { L1_SILO_WHITELIST } from '~/constants/tokens';
+import { useWhitelistedTokens } from '~/hooks/beanstalk/useTokens';
import MockPlot from '../Silo/MockPlot';
import BlurComponent from '../Common/ZeroState/BlurComponent';
import WalletButton from '../Common/Connection/WalletButton';
@@ -21,6 +21,7 @@ const SiloBalancesHistory: React.FC<{}> = () => {
const account = useAccount();
const timeTabParams = useTimeTabState();
const { data, loading } = useFarmerSiloHistory(account, true, false);
+ const { whitelist } = useWhitelistedTokens();
const formatValue = (value: number) =>
`$${value?.toLocaleString('en-US', { maximumFractionDigits: 2 })}`;
@@ -48,7 +49,7 @@ const SiloBalancesHistory: React.FC<{}> = () => {
const queryData: QueryData = {
data: filteredSeries as BaseDataPoint[][],
loading: loading,
- keys: L1_SILO_WHITELIST.map((t) => t.address),
+ keys: whitelist.map((t) => t.address),
error: undefined,
};
diff --git a/projects/ui/src/components/Common/Charts/ChartPropProvider.tsx b/projects/ui/src/components/Common/Charts/ChartPropProvider.tsx
index 626640ba3..931aec4cf 100644
--- a/projects/ui/src/components/Common/Charts/ChartPropProvider.tsx
+++ b/projects/ui/src/components/Common/Charts/ChartPropProvider.tsx
@@ -32,13 +32,15 @@ export type BaseDataPoint = {
[key: string]: number;
};
+type BaseChartMultiStyle = {
+ stroke: string; // stroke color
+ fillPrimary: string; // gradient 'to' color
+ fillSecondary?: string; // gradient 'from' color
+ strokeWidth?: number;
+};
+
export type ChartMultiStyles = {
- [key: string]: {
- stroke: string; // stroke color
- fillPrimary: string; // gradient 'to' color
- fillSecondary?: string; // gradient 'from' color
- strokeWidth?: number;
- };
+ [key: string]: BaseChartMultiStyle;
};
type ChartStyleConfig = {
@@ -75,8 +77,8 @@ type Scales = {
};
export type Scale = {
- xScale: ReturnType;
- yScale: ReturnType;
+ xScale: ReturnType<(typeof SCALES)[keyof typeof SCALES]>;
+ yScale: ReturnType<(typeof SCALES)[keyof typeof SCALES]>;
};
type ChartAccessorProps = {
@@ -120,6 +122,7 @@ type UtilProps = {
};
export type DataRegion = { yTop: number; yBottom: number };
+// eslint-disable-next-line react/no-unused-prop-types
export type BaseGraphProps = { width: number; height: number };
export type ProviderChartProps = {
@@ -142,7 +145,7 @@ export type BaseChartProps = {
isTWAP?: boolean;
useCustomTokenList?: ERC20Token[];
useCustomTooltipNames?: { [key: string]: string };
- tokenPerSeasonFilter?: { [key: string]: { from: number, to: number } };
+ tokenPerSeasonFilter?: { [key: string]: { from: number; to: number } };
horizontalLineNumber?: number;
stylesConfig?: ChartMultiStyles;
stackedArea?: boolean;
@@ -184,33 +187,47 @@ const chartPadding = {
};
const chartColors = BeanstalkPalette.theme.spring.chart;
-const defaultChartStyles: ChartMultiStyles = {
- 0: {
- stroke: BeanstalkPalette.theme.spring.beanstalkGreen,
- fillPrimary: chartColors.primaryLight,
- strokeWidth: 2,
- },
- 1: {
- stroke: chartColors.purple,
- fillPrimary: chartColors.purpleLight,
- strokeWidth: 2,
- },
- 2: {
- stroke: chartColors.green,
- fillPrimary: chartColors.greenLight,
- strokeWidth: 2,
- },
- 3: {
- stroke: chartColors.yellow,
- fillPrimary: chartColors.yellowLight,
- strokeWidth: 2,
- },
- 4: {
- stroke: chartColors.blue,
- fillPrimary: chartColors.blueLight,
- strokeWidth: 2,
- },
+
+const chartStylePrimary: BaseChartMultiStyle = {
+ stroke: BeanstalkPalette.theme.spring.beanstalkGreen,
+ fillPrimary: chartColors.primaryLight,
+ strokeWidth: 2,
+};
+const chartStylePurple: BaseChartMultiStyle = {
+ stroke: chartColors.purple,
+ fillPrimary: chartColors.purpleLight,
+ strokeWidth: 2,
+};
+const chartStyleGreen: BaseChartMultiStyle = {
+ stroke: chartColors.green,
+ fillPrimary: chartColors.greenLight,
+ strokeWidth: 2,
};
+const chartStyleYellow: BaseChartMultiStyle = {
+ stroke: chartColors.yellow,
+ fillPrimary: chartColors.yellowLight,
+ strokeWidth: 2,
+};
+const chartStyleBlue: BaseChartMultiStyle = {
+ stroke: chartColors.blue,
+ fillPrimary: chartColors.blueLight,
+ strokeWidth: 2,
+};
+
+const chartStyleArr = [
+ chartStylePrimary,
+ chartStylePurple,
+ chartStyleGreen,
+ chartStyleYellow,
+ chartStyleBlue,
+];
+
+const defaultChartStyles: ChartMultiStyles = Object.fromEntries(
+ [...chartStyleArr, ...chartStyleArr].map((chartStyle, i) => [
+ i.toString(),
+ chartStyle,
+ ])
+);
/**
* get chart styles for given key
diff --git a/projects/ui/src/hooks/beanstalk/useTokens.ts b/projects/ui/src/hooks/beanstalk/useTokens.ts
index f78b63022..b9b53a6b8 100644
--- a/projects/ui/src/hooks/beanstalk/useTokens.ts
+++ b/projects/ui/src/hooks/beanstalk/useTokens.ts
@@ -6,12 +6,14 @@ import LegacyToken, {
NativeToken as LegacyNativeToken,
} from '~/classes/Token';
import { ChainConstant, SupportedChainId, TokenMap } from '~/constants';
+import * as ADDRESSES from '~/constants/addresses';
import useSdk from '~/hooks/sdk';
import { useAppSelector } from '~/state';
import { BeanPools } from '~/state/bean/pools';
import * as LegacyTokens from '~/constants/tokens';
import { getTokenIndex, isSdkToken } from '~/util';
-import useChainState from '../chain/useChainState';
+import useChainState from '~/hooks/chain/useChainState';
+import { useResolvedChainId } from '../chain/useChainId';
// -------------------------
// Token Instances
@@ -89,7 +91,8 @@ export const useTokens = (): {
const erc20TokenMap = Object.values(balanceTokens).reduce<
TokenMap
>((acc, token) => {
- if (token.equals(tokens.ETH)) return acc;
+ const tokenIndex = getTokenIndex(token);
+ if (tokenIndex === 'eth') return acc;
acc[getTokenIndex(token)] = token as ERC20Token;
return acc;
}, {});
@@ -144,6 +147,31 @@ export const useUnripeTokens = () => {
}, [sdk]);
};
+export const useGetUnripeTokenWithAddress = () => {
+ const urTokens = useUnripeTokens();
+
+ const getUnripeSdkToken = useCallback(
+ (_address: string) => {
+ const address = _address.toLowerCase();
+
+ if (Object.values(ADDRESSES.UNRIPE_BEAN_ADDRESSES).includes(address)) {
+ return urTokens.UNRIPE_BEAN;
+ }
+
+ if (
+ Object.values(ADDRESSES.UNRIPE_BEAN_WSTETH_ADDRESSES).includes(address)
+ ) {
+ return urTokens.UNRIPE_BEAN_WSTETH;
+ }
+ },
+ [urTokens]
+ );
+
+ return {
+ getUnripeSdkToken,
+ };
+};
+
/**
* @param sortByLiquidity - If true, sort Well LP tokens by liquidity (highest to lowest)
*/
@@ -245,37 +273,40 @@ function getWhitelistSorted(
});
}
-const i = SupportedChainId.ARBITRUM_MAINNET;
+const cARB = SupportedChainId.ARBITRUM_MAINNET;
+const cETH = SupportedChainId.ETH_MAINNET;
const oldTokenMap: Record | LegacyToken> = {
- [LegacyTokens.ETH[i].symbol]: LegacyTokens.ETH,
- [LegacyTokens.BEAN[i].symbol]: LegacyTokens.BEAN,
- [LegacyTokens.UNRIPE_BEAN[i].symbol]: LegacyTokens.UNRIPE_BEAN,
- [LegacyTokens.UNRIPE_BEAN_WSTETH[i].symbol]: LegacyTokens.UNRIPE_BEAN_WSTETH,
- [LegacyTokens.WETH[i].symbol]: LegacyTokens.WETH,
- [LegacyTokens.DAI[i].symbol]: LegacyTokens.DAI,
- [LegacyTokens.USDC[i].symbol]: LegacyTokens.USDC,
- [LegacyTokens.USDT[i].symbol]: LegacyTokens.USDT,
- [LegacyTokens.WSTETH[i].symbol]: LegacyTokens.WSTETH,
- [LegacyTokens.WEETH[i].symbol]: LegacyTokens.WEETH,
- [LegacyTokens.WBTC[i].symbol]: LegacyTokens.WBTC,
- [LegacyTokens.BEAN_ETH_WELL_LP[i].symbol]: LegacyTokens.BEAN_ETH_WELL_LP,
- [LegacyTokens.BEAN_WSTETH_WELL_LP[i].symbol]:
+ [LegacyTokens.ETH[cARB].symbol]: LegacyTokens.ETH,
+ [LegacyTokens.BEAN[cARB].symbol]: LegacyTokens.BEAN,
+ [LegacyTokens.UNRIPE_BEAN[cARB].symbol]: LegacyTokens.UNRIPE_BEAN,
+ [LegacyTokens.UNRIPE_BEAN_WSTETH[cARB].symbol]:
+ LegacyTokens.UNRIPE_BEAN_WSTETH,
+ [LegacyTokens.WETH[cARB].symbol]: LegacyTokens.WETH,
+ [LegacyTokens.DAI[cARB].symbol]: LegacyTokens.DAI,
+ [LegacyTokens.USDC[cARB].symbol]: LegacyTokens.USDC,
+ [LegacyTokens.USDT[cARB].symbol]: LegacyTokens.USDT,
+ [LegacyTokens.WSTETH[cARB].symbol]: LegacyTokens.WSTETH,
+ [LegacyTokens.WEETH[cARB].symbol]: LegacyTokens.WEETH,
+ [LegacyTokens.WBTC[cARB].symbol]: LegacyTokens.WBTC,
+ [LegacyTokens.BEAN_ETH_WELL_LP[cARB].symbol]: LegacyTokens.BEAN_ETH_WELL_LP,
+ [LegacyTokens.BEAN_WSTETH_WELL_LP[cARB].symbol]:
LegacyTokens.BEAN_WSTETH_WELL_LP,
- [LegacyTokens.BEAN_WEETH_WELL_LP[i].symbol]: LegacyTokens.BEAN_WEETH_WELL_LP,
- [LegacyTokens.BEAN_WBTC_WELL_LP[i].symbol]: LegacyTokens.BEAN_WBTC_WELL_LP,
- [LegacyTokens.BEAN_USDC_WELL_LP[i].symbol]: LegacyTokens.BEAN_USDC_WELL_LP,
- [LegacyTokens.BEAN_USDT_WELL_LP[i].symbol]: LegacyTokens.BEAN_USDT_WELL_LP,
+ [LegacyTokens.BEAN_WEETH_WELL_LP[cARB].symbol]:
+ LegacyTokens.BEAN_WEETH_WELL_LP,
+ [LegacyTokens.BEAN_WBTC_WELL_LP[cARB].symbol]: LegacyTokens.BEAN_WBTC_WELL_LP,
+ [LegacyTokens.BEAN_USDC_WELL_LP[cARB].symbol]: LegacyTokens.BEAN_USDC_WELL_LP,
+ [LegacyTokens.BEAN_USDT_WELL_LP[cARB].symbol]: LegacyTokens.BEAN_USDT_WELL_LP,
[LegacyTokens.STALK.symbol]: LegacyTokens.STALK,
[LegacyTokens.SEEDS.symbol]: LegacyTokens.SEEDS,
[LegacyTokens.PODS.symbol]: LegacyTokens.PODS,
[LegacyTokens.SPROUTS.symbol]: LegacyTokens.SPROUTS,
[LegacyTokens.RINSABLE_SPROUTS.symbol]: LegacyTokens.RINSABLE_SPROUTS,
- [LegacyTokens.BEAN_CRV3_LP[1].symbol]: LegacyTokens.BEAN_CRV3_LP,
- [LegacyTokens.CRV3[1].symbol]: LegacyTokens.CRV3,
- [LegacyTokens.BEAN_ETH_UNIV2_LP[1].symbol]: LegacyTokens.BEAN_ETH_UNIV2_LP,
- [LegacyTokens.BEAN_LUSD_LP[1].symbol]: LegacyTokens.BEAN_LUSD_LP,
- [LegacyTokens.LUSD[1].symbol]: LegacyTokens.LUSD,
+ [LegacyTokens.BEAN_CRV3_LP[cETH].symbol]: LegacyTokens.BEAN_CRV3_LP,
+ [LegacyTokens.CRV3[cETH].symbol]: LegacyTokens.CRV3,
+ [LegacyTokens.BEAN_ETH_UNIV2_LP[cETH].symbol]: LegacyTokens.BEAN_ETH_UNIV2_LP,
+ [LegacyTokens.BEAN_LUSD_LP[cETH].symbol]: LegacyTokens.BEAN_LUSD_LP,
+ [LegacyTokens.LUSD[cETH].symbol]: LegacyTokens.LUSD,
} as const;
export const useGetLegacyToken = () => {
@@ -294,3 +325,76 @@ export const useGetLegacyToken = () => {
return getLegacyToken;
};
+
+const makeEntry = (
+ a: ChainConstant,
+ t: ChainConstant
+) => ({
+ ...(a[cARB] && t[cARB] ? { [a[cARB]]: t } : {}),
+ ...(a[cETH] && t[cETH] ? { [a[cETH]]: t } : {}),
+});
+
+const A = ADDRESSES;
+const L = LegacyTokens;
+
+const ADDRESS_TO_CHAIN_CONSTANT: Record> = {
+ // BEAN
+ ...makeEntry(A.BEAN_ADDRESSES, L.BEAN),
+
+ // UNRIPE
+
+ ...makeEntry(A.UNRIPE_BEAN_ADDRESSES, L.UNRIPE_BEAN),
+ ...makeEntry(A.UNRIPE_BEAN_WSTETH_ADDRESSES, L.UNRIPE_BEAN_WSTETH),
+
+ // ERC20
+ ...makeEntry(A.WETH_ADDRESSES, L.WETH),
+ ...makeEntry(A.WSTETH_ADDRESSES, L.WSTETH),
+ ...makeEntry(A.WEETH_ADDRESSES, L.WEETH),
+ ...makeEntry(A.WBTC_ADDRESSES, L.WBTC),
+ ...makeEntry(A.DAI_ADDRESSES, L.DAI),
+ ...makeEntry(A.USDC_ADDRESSES, L.USDC),
+ ...makeEntry(A.USDT_ADDRESSES, L.USDT),
+ ...makeEntry(A.ARB_ADDRESSES, L.ARB),
+
+ // LP
+ ...makeEntry(A.BEAN_ETH_WELL_ADDRESSES, L.BEAN_ETH_WELL_LP),
+ ...makeEntry(A.BEAN_WSTETH_ADDRESSS, L.BEAN_WSTETH_WELL_LP),
+ ...makeEntry(A.BEANWEETH_WELL_ADDRESSES, L.BEAN_WEETH_WELL_LP),
+ ...makeEntry(A.BEANWBTC_WELL_ADDRESSES, L.BEAN_WBTC_WELL_LP),
+ ...makeEntry(A.BEANUSDC_WELL_ADDRESSES, L.BEAN_USDC_WELL_LP),
+ ...makeEntry(A.BEANUSDT_WELL_ADDRESSES, L.BEAN_USDT_WELL_LP),
+
+ // Deprecated
+ // ...makeEntry(A.CRV3_ADDRESSES, L.CRV3),
+ // ...makeEntry(A.BEAN_CRV3_ADDRESSES, L.BEAN_CRV3_LP),
+ // ...makeEntry(A.BEAN_LUSD_ADDRESSES, L.BEAN_LUSD_LP),
+ // ...makeEntry(A.LUSD_ADDRESSES, L.LUSD),
+ // ...makeEntry(A.BEAN_ETH_UNIV2_LP_ADDRESSES, L.BEAN_ETH_UNIV2_LP),
+} as const;
+
+/**
+ *
+ * @returns a function that takes an address (chain agnostic) and returns the sdk token instance
+ * for the chain the user is currently on
+ *
+ */
+export const useGetNormaliseChainToken = () => {
+ const { erc20TokenMap } = useTokens();
+ const chainId = useResolvedChainId();
+
+ /**
+ * returns the sdk token instance for the chain the user is currently on if available
+ */
+ const getToken = useCallback(
+ (_address: string) => {
+ const token = ADDRESS_TO_CHAIN_CONSTANT[_address.toLowerCase()];
+
+ return token?.[chainId]
+ ? erc20TokenMap[getTokenIndex(token[chainId])]
+ : undefined;
+ },
+ [erc20TokenMap, chainId]
+ );
+
+ return getToken;
+};
\ No newline at end of file
diff --git a/projects/ui/src/hooks/chain/useChainId.ts b/projects/ui/src/hooks/chain/useChainId.ts
index 2695738f9..8d8fd6fe4 100644
--- a/projects/ui/src/hooks/chain/useChainId.ts
+++ b/projects/ui/src/hooks/chain/useChainId.ts
@@ -1,3 +1,4 @@
+import { ChainResolver } from '@beanstalk/sdk-core';
import { useMemo } from 'react';
import { useAccount } from 'wagmi';
import { SupportedChainId } from '~/constants';
@@ -17,3 +18,9 @@ export default function useChainId() {
const { chain } = useAccount();
return useMemo(() => chain?.id || defaultChainId, [chain?.id]);
}
+
+export function useResolvedChainId() {
+ const chainId = useChainId();
+
+ return ChainResolver.resolveToMainnetChainId(chainId);
+}
diff --git a/projects/ui/src/hooks/farmer/useFarmerBalancesBreakdown.ts b/projects/ui/src/hooks/farmer/useFarmerBalancesBreakdown.ts
index cf743d95a..cb1b3e7dc 100644
--- a/projects/ui/src/hooks/farmer/useFarmerBalancesBreakdown.ts
+++ b/projects/ui/src/hooks/farmer/useFarmerBalancesBreakdown.ts
@@ -184,7 +184,10 @@ export function useFarmerBalancesL1Breakdown() {
addresses.forEach((address) => {
const token = whitelist[address];
const siloBalance = siloBalances[address];
- const tokenBalance = tokenBalances[address] || ZERO_BN;
+ const tokenBalance = tokenBalances[address] || {
+ internal: ZERO_BN,
+ external: ZERO_BN,
+ };
// Ensure we've loaded a Silo Balance for this token.
if (siloBalance) {
@@ -222,6 +225,8 @@ export function useFarmerBalancesL1Breakdown() {
}
});
+ console.log('useFarmersBalancesL1Breakdown', prev);
+
return prev;
}, [whitelist, addresses, siloBalances, tokenBalances, getUSD]);
}
diff --git a/projects/ui/src/hooks/farmer/useFarmerSiloHistory.ts b/projects/ui/src/hooks/farmer/useFarmerSiloHistory.ts
index 3c9d84000..614b6d120 100644
--- a/projects/ui/src/hooks/farmer/useFarmerSiloHistory.ts
+++ b/projects/ui/src/hooks/farmer/useFarmerSiloHistory.ts
@@ -10,14 +10,14 @@ import useSeasonsQuery, {
} from '~/hooks/beanstalk/useSeasonsQuery';
import useInterpolateDeposits from '~/hooks/farmer/useInterpolateDeposits';
import useInterpolateStalk from '~/hooks/farmer/useInterpolateStalk';
-import { useFarmerBalancesL1Breakdown } from './useFarmerBalancesBreakdown';
+import useFarmerBalancesBreakdown from './useFarmerBalancesBreakdown';
const useFarmerSiloHistory = (
account: string | undefined,
itemizeByToken: boolean = false,
includeStalk: boolean = false
) => {
- const breakdown = useFarmerBalancesL1Breakdown(); // TODO: Fix me
+ const breakdown = useFarmerBalancesBreakdown();
/// Data
const siloRewardsQuery = useFarmerSiloRewardsQuery({
diff --git a/projects/ui/src/hooks/farmer/useInterpolateDeposits.ts b/projects/ui/src/hooks/farmer/useInterpolateDeposits.ts
index 2527ab3e4..da0f42b5b 100644
--- a/projects/ui/src/hooks/farmer/useInterpolateDeposits.ts
+++ b/projects/ui/src/hooks/farmer/useInterpolateDeposits.ts
@@ -9,9 +9,13 @@ import {
interpolateFarmerDepositedValue,
SnapshotBeanstalk,
} from '~/util/Interpolate';
-import { SupportedChainId, ZERO_BN } from '~/constants';
-import { UNRIPE_BEAN_WSTETH } from '~/constants/tokens';
+import { ZERO_BN } from '~/constants';
import useUnripeUnderlyingMap from '../beanstalk/useUnripeUnderlying';
+import {
+ useGetNormaliseChainToken,
+ useUnripeTokens,
+ useWhitelistedTokens,
+} from '../beanstalk/useTokens';
const useInterpolateDeposits = (
siloAssetsQuery: ReturnType,
@@ -20,12 +24,11 @@ const useInterpolateDeposits = (
) => {
const unripe = useAppSelector((state) => state._bean.unripe);
const beanPools = useAppSelector((state) => state._bean.pools);
+ const { UNRIPE_BEAN_WSTETH: urBeanLP } = useUnripeTokens();
+ const normalizeToken = useGetNormaliseChainToken();
+ const { whitelist } = useWhitelistedTokens();
const underlyingMap = useUnripeUnderlyingMap();
- // const sdk = useSdk();
- // BS3TODO: fix me
- const urBeanLP = UNRIPE_BEAN_WSTETH[SupportedChainId.ETH_MAINNET];
-
return useMemo(() => {
if (
priceQuery.loading ||
@@ -40,15 +43,14 @@ const useInterpolateDeposits = (
// sorted by Season and normalized based on chop rate.
const snapshots = siloAssetsQuery.data.farmer.silo.assets
.reduce((prev, asset) => {
- const tokenAddress = asset.token.toLowerCase();
+ const tokenAddress = normalizeToken(asset.token)?.address;
+ if (!tokenAddress) return prev;
prev.push(
...asset.hourlySnapshots.map((snapshot) => {
let hourlyDepositedBDV;
if (tokenAddress in unripe) {
- if (
- tokenAddress.toLowerCase() === urBeanLP.address.toLowerCase()
- ) {
+ if (tokenAddress === urBeanLP.address) {
// formula: penalty = amount of BEANwstETH per 1 urBEANwstETH.
// bdv of urBEANwstETH = amount * penalty * BDV of 1 BEANwstETH
const underlying = underlyingMap[tokenAddress];
@@ -89,9 +91,15 @@ const useInterpolateDeposits = (
return interpolateFarmerDepositedValue(
snapshots,
priceQuery.data.seasons,
- itemizeByToken
+ itemizeByToken,
+ 24,
+ whitelist,
+ normalizeToken,
+
);
}, [
+ normalizeToken,
+ whitelist,
priceQuery.loading,
priceQuery.data?.seasons,
siloAssetsQuery.data?.farmer?.silo?.assets,
diff --git a/projects/ui/src/hooks/farmer/useInterpolateStalk.ts b/projects/ui/src/hooks/farmer/useInterpolateStalk.ts
index b80dd8f26..f802df98b 100644
--- a/projects/ui/src/hooks/farmer/useInterpolateStalk.ts
+++ b/projects/ui/src/hooks/farmer/useInterpolateStalk.ts
@@ -1,10 +1,9 @@
import { useMemo } from 'react';
-import { useSelector } from 'react-redux';
import { useFarmerSiloRewardsQuery, useWhitelistTokenRewardsQuery } from '~/generated/graphql';
import useSeason from '~/hooks/beanstalk/useSeason';
-import { AppState } from '~/state';
+import { useAppSelector } from '~/state';
import { interpolateFarmerStalk } from '~/util/Interpolate';
-import useSdk from '../sdk';
+import { useWhitelistedTokens } from '../beanstalk/useTokens';
const useInterpolateStalk = (
siloRewardsQuery: ReturnType,
@@ -12,21 +11,18 @@ const useInterpolateStalk = (
skip: boolean = false
) => {
const season = useSeason();
- const sdk = useSdk();
+ const { whitelist } = useWhitelistedTokens();
// Balances
- const balances = useSelector<
- AppState,
- AppState['_farmer']['silo']['balances']
- >((state) => state._farmer.silo.balances);
+ const balances = useAppSelector((state) => state._farmer.silo.balances);
return useMemo(() => {
if (skip || !season.gt(0) || !siloRewardsQuery.data?.snapshots?.length || !whitelistQuery.data?.snapshots?.length)
return [[], []];
const siloSnapshots = siloRewardsQuery.data.snapshots;
const whitelistSnapshots = whitelistQuery.data.snapshots;
- return interpolateFarmerStalk(siloSnapshots, whitelistSnapshots, season, undefined, balances, sdk);
- }, [skip, siloRewardsQuery.data?.snapshots, whitelistQuery.data?.snapshots, season, balances, sdk]);
+ return interpolateFarmerStalk(siloSnapshots, whitelistSnapshots, season, undefined, balances, whitelist);
+ }, [skip, siloRewardsQuery.data?.snapshots, whitelistQuery.data?.snapshots, season, balances, whitelist]);
};
export default useInterpolateStalk;
diff --git a/projects/ui/src/util/Interpolate.ts b/projects/ui/src/util/Interpolate.ts
index 132e9d1e9..55e62bad4 100644
--- a/projects/ui/src/util/Interpolate.ts
+++ b/projects/ui/src/util/Interpolate.ts
@@ -1,7 +1,7 @@
import BigNumber from 'bignumber.js';
import { DateTime } from 'luxon';
import { TokenMap, ZERO_BN } from '~/constants';
-import { BEAN, SEEDS, SILO_WHITELIST, STALK } from '~/constants/tokens';
+import { BEAN, SEEDS, STALK } from '~/constants/tokens';
import {
FarmerSiloRewardsQuery,
SeasonalInstantPriceQuery,
@@ -15,7 +15,8 @@ import {
} from '~/util';
import { BaseDataPoint } from '~/components/Common/Charts/ChartPropProvider';
import { FarmerSiloTokenBalance } from '~/state/farmer/silo';
-import { BeanstalkSDK } from '@beanstalk/sdk';
+import { Token } from '@beanstalk/sdk';
+import { useWhitelistedTokens } from '~/hooks/beanstalk/useTokens';
export type Snapshot = {
id: string;
@@ -40,7 +41,8 @@ export type SnapshotBeanstalk = {
export const addBufferSeasons = (
points: BaseDataPoint[],
num: number = 24,
- itemizeByToken: boolean = false
+ whitelist: ReturnType['whitelist'],
+ itemizeByToken: boolean = false,
) => {
if (points.length === 0) return [];
const d = DateTime.fromJSDate(points[0].date);
@@ -58,8 +60,8 @@ export const addBufferSeasons = (
value: 0,
// FIXME: have the chart default to zero if a key isn't provided?
...(itemizeByToken
- ? SILO_WHITELIST.reduce>((prev, curr) => {
- prev[curr[1].address] = 0;
+ ? whitelist.reduce>((prev, curr) => {
+ prev[curr.address] = 0;
return prev;
}, {})
: undefined),
@@ -80,11 +82,10 @@ export const interpolateFarmerStalk = (
season: BigNumber,
bufferSeasons: number = 24,
farmerSiloBalances: TokenMap,
- sdk: BeanstalkSDK
+ whitelist: ReturnType['whitelist']
) => {
// Sequence
let j = 0;
- const siloWhitelist = sdk.tokens.siloWhitelist;
const minSeason = snapshots[j].season;
const maxSeason = season.toNumber(); // current season
let currStalk: BigNumber = ZERO_BN;
@@ -94,7 +95,7 @@ export const interpolateFarmerStalk = (
secondsToDate(snapshots[j].createdAt)
);
let nextSeason: number | undefined = minSeason;
-
+
// Add buffer points before the first snapshot
const stalk: BaseDataPoint[] = [];
const seeds: BaseDataPoint[] = [];
@@ -102,21 +103,27 @@ export const interpolateFarmerStalk = (
function getSeedsPerBdv(_season: number) {
let _output: BigNumber = ZERO_BN;
- siloWhitelist.forEach((token) => {
+ whitelist.forEach((token) => {
if (farmerSiloBalances[token.address]) {
const deposits = farmerSiloBalances[token.address].deposited;
- const index = whitelistSnapshots.findLastIndex((snapshot) => snapshot.season <= _season && snapshot.token.id === token.address.toLowerCase());
+ const index = whitelistSnapshots.findLastIndex(
+ (snapshot) =>
+ snapshot.season <= _season &&
+ snapshot.token.id === token.address.toLowerCase()
+ );
if (index >= 0) {
- const seedsPerBdv = BigNumber(whitelistSnapshots[index].stalkEarnedPerSeason).div(1_000_000);
- _output = (seedsPerBdv).multipliedBy(deposits.bdv).plus(_output);
- };
- };
+ const seedsPerBdv = BigNumber(
+ whitelistSnapshots[index].stalkEarnedPerSeason
+ ).div(1_000_000);
+ _output = seedsPerBdv.multipliedBy(deposits.bdv).plus(_output);
+ }
+ }
});
return _output;
- };
+ }
let lastSeedsSnapshot: BigNumber = ZERO_BN;
- const lastSnapshotSeason = snapshots[snapshots.length - 1].season;
+ const lastSnapshotSeason = snapshots[snapshots.length - 1].season;
for (let s = minSeason; s <= maxSeason; s += 1) {
if (s === nextSeason) {
// Reached a data point for which we have a snapshot.
@@ -135,13 +142,13 @@ export const interpolateFarmerStalk = (
currSeeds = lastSeedsSnapshot;
} else {
currSeeds = getSeedsPerBdv(s);
- };
+ }
// Estimate actual amount of stalk / grown stalk using seeds
// Each Seed grows 1/10,000 Stalk per Season
- currGrownStalk = currGrownStalk.plus((currSeeds).multipliedBy(1 / 10_000));
+ currGrownStalk = currGrownStalk.plus(currSeeds.multipliedBy(1 / 10_000));
currTimestamp = currTimestamp.plus({ hours: 1 });
- };
+ }
stalk.push({
season: s,
date: currTimestamp.toJSDate(),
@@ -160,9 +167,9 @@ export const interpolateFarmerStalk = (
}
return [
- addBufferSeasons(stalk, bufferSeasons, false),
- addBufferSeasons(seeds, bufferSeasons, false),
- addBufferSeasons(grownStalk, bufferSeasons, false),
+ addBufferSeasons(stalk, bufferSeasons, whitelist, false),
+ addBufferSeasons(seeds, bufferSeasons, whitelist, false),
+ addBufferSeasons(grownStalk, bufferSeasons, whitelist, false),
] as const;
};
@@ -175,10 +182,12 @@ export const interpolateFarmerDepositedValue = (
snapshots: SnapshotBeanstalk[], // oldest season first
_prices: SeasonalInstantPriceQuery['seasons'], // most recent season first
itemizeByToken: boolean = true,
- bufferSeasons: number = 24
+ bufferSeasons: number = 24,
+ whitelist: ReturnType['whitelist'],
+ normaliseChainToken: (token: string) => Token | undefined
) => {
const prices = Array.from(_prices).reverse(); // FIXME: inefficient
- if (prices.length === 0) return [];
+ if (!prices.length || !snapshots.length) return [];
// Sequence
let j = 0;
@@ -189,8 +198,8 @@ export const interpolateFarmerDepositedValue = (
// null if we don't need to itemize by token
const currBDVByToken = itemizeByToken
- ? SILO_WHITELIST.reduce<{ [address: string]: BigNumber }>((prev, curr) => {
- prev[curr[1].address] = ZERO_BN;
+ ? whitelist.reduce<{ [address: string]: BigNumber }>((prev, curr) => {
+ prev[curr.address] = ZERO_BN;
return prev;
}, {})
: null;
@@ -237,7 +246,11 @@ export const interpolateFarmerDepositedValue = (
thisBDV = thisBDV.plus(thisSnapshotBDV);
if (currBDVByToken) {
- const tokenAddr = snapshots[j]?.id.split('-')[1].toLowerCase();
+ const snapshotTokenAddress = snapshots[j]?.id
+ .split('-')[1]
+ .toLowerCase();
+ const tokenAddr = normaliseChainToken(snapshotTokenAddress)?.address;
+
if (tokenAddr && currBDVByToken[tokenAddr]) {
currBDVByToken[tokenAddr] =
currBDVByToken[tokenAddr].plus(thisSnapshotBDV);
@@ -252,8 +265,8 @@ export const interpolateFarmerDepositedValue = (
date: thisTimestamp.toJSDate(),
value: thisBDV.multipliedBy(thisPriceBN).toNumber(),
...(currBDVByToken
- ? SILO_WHITELIST.reduce>((prev, token) => {
- const addr = token[1].address;
+ ? whitelist.reduce>((prev, token) => {
+ const addr = token.address;
prev[addr] = currBDVByToken[addr]
.multipliedBy(thisPriceBN)
.toNumber();
@@ -265,5 +278,5 @@ export const interpolateFarmerDepositedValue = (
currBDV = thisBDV;
}
- return addBufferSeasons(points, bufferSeasons, Boolean(currBDVByToken));
+ return addBufferSeasons(points, bufferSeasons, whitelist, Boolean(currBDVByToken));
};