From 2367e441d52d31ebe5b42cfd2e4d49512593c8cb Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:29:48 +0000 Subject: [PATCH 1/6] fix: update bonus pods from 10% to 5% in sow order form Fixes #404 Co-authored-by: fr1jo --- src/components/Tractor/form/SowOrderV0Fields.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Tractor/form/SowOrderV0Fields.tsx b/src/components/Tractor/form/SowOrderV0Fields.tsx index 0d6e7d64..b210b0fb 100644 --- a/src/components/Tractor/form/SowOrderV0Fields.tsx +++ b/src/components/Tractor/form/SowOrderV0Fields.tsx @@ -496,7 +496,7 @@ SowOrderV0Fields.MorningAuction = function MorningAuction() { // TODO: ADD REFERRAL CODE VALIDATOR! -const BONUS_MULTIPLIER = 0.1; +const BONUS_MULTIPLIER = 0.05; SowOrderV0Fields.PodDisplay = function PodDisplay({ onOpenReferralPopover, From 2c18f541332703f97af423b13f484b1f9a5ec58c Mon Sep 17 00:00:00 2001 From: feyyazcigim Date: Wed, 4 Feb 2026 04:22:25 +0300 Subject: [PATCH 2/6] feat: implement dashboard for legacy beanstalk holder obligations --- src/ProtectedLayout.tsx | 9 + src/components/BeanstalkStatField.tsx | 64 ++++ src/components/nav/nav/Navbar.tsx | 1 + src/components/nav/nav/Navi.desktop.tsx | 3 + src/components/nav/nav/Navi.mobile.tsx | 3 + src/components/ui/Button.tsx | 3 +- src/constants/meta.ts | 6 + src/pages/Beanstalk.tsx | 53 +++ .../components/BeanstalkFertilizerSection.tsx | 39 +++ .../components/BeanstalkGlobalCard.tsx | 66 ++++ .../components/BeanstalkObligationsCard.tsx | 47 +++ .../components/BeanstalkPodsSection.tsx | 53 +++ .../components/BeanstalkSiloSection.tsx | 39 +++ src/state/useBeanstalkGlobalStats.ts | 153 +++++++++ src/state/useFarmerBeanstalkRepayment.ts | 313 ++++++++++++++++++ 15 files changed, 851 insertions(+), 1 deletion(-) create mode 100644 src/components/BeanstalkStatField.tsx create mode 100644 src/pages/Beanstalk.tsx create mode 100644 src/pages/beanstalk/components/BeanstalkFertilizerSection.tsx create mode 100644 src/pages/beanstalk/components/BeanstalkGlobalCard.tsx create mode 100644 src/pages/beanstalk/components/BeanstalkObligationsCard.tsx create mode 100644 src/pages/beanstalk/components/BeanstalkPodsSection.tsx create mode 100644 src/pages/beanstalk/components/BeanstalkSiloSection.tsx create mode 100644 src/state/useBeanstalkGlobalStats.ts create mode 100644 src/state/useFarmerBeanstalkRepayment.ts diff --git a/src/ProtectedLayout.tsx b/src/ProtectedLayout.tsx index 630ae118..ff817024 100644 --- a/src/ProtectedLayout.tsx +++ b/src/ProtectedLayout.tsx @@ -2,6 +2,7 @@ import { isDev } from "@/utils/utils"; import { Navigate, Route, Routes } from "react-router-dom"; import DevPage from "./components/DevPage"; import PageMetaWrapper from "./components/PageMetaWrapper"; +import Beanstalk from "./pages/Beanstalk"; import Collection from "./pages/Collection"; import Error404 from "./pages/Error404"; import Explorer from "./pages/Explorer"; @@ -69,6 +70,14 @@ export default function ProtectedLayout() { } /> + + + + } + /> void; + disabled?: boolean; +} + +interface BeanstalkStatFieldProps { + title: string; + value: ReactNode; + isLoading?: boolean; + disabled?: boolean; + actions?: BeanstalkStatFieldAction[]; + children?: ReactNode; +} + +/** + * Reusable stat field component with title, value, and optional action buttons + * Used in Beanstalk obligations and global stats cards + */ +const BeanstalkStatField: React.FC = ({ + title, + value, + isLoading = false, + disabled = false, + actions, + children, +}) => { + return ( +
+
+
{title}
+ {actions && actions.length > 0 && ( +
+ {actions.map((action) => ( + + ))} +
+ )} +
+ {children ? ( + children + ) : ( + +
{disabled ? N/A : value}
+
+ )} +
+ ); +}; + +export default BeanstalkStatField; diff --git a/src/components/nav/nav/Navbar.tsx b/src/components/nav/nav/Navbar.tsx index 39d9c9a8..aa4729fb 100644 --- a/src/components/nav/nav/Navbar.tsx +++ b/src/components/nav/nav/Navbar.tsx @@ -332,6 +332,7 @@ export const navLinks = { field: "/field", swap: "/swap", referral: "/referral", + beanstalk: "/beanstalk", sPinto: "/sPinto", collection: "/collection", podmarket: "/market/pods", diff --git a/src/components/nav/nav/Navi.desktop.tsx b/src/components/nav/nav/Navi.desktop.tsx index da6f6eec..4a6072f8 100644 --- a/src/components/nav/nav/Navi.desktop.tsx +++ b/src/components/nav/nav/Navi.desktop.tsx @@ -110,6 +110,9 @@ const AppNavi = () => { Referral + + Beanstalk + sPinto diff --git a/src/components/nav/nav/Navi.mobile.tsx b/src/components/nav/nav/Navi.mobile.tsx index 7581cce5..c57cad24 100644 --- a/src/components/nav/nav/Navi.mobile.tsx +++ b/src/components/nav/nav/Navi.mobile.tsx @@ -175,6 +175,9 @@ function MobileNavContent({ learnOpen, setLearnOpen, unmount, close }: IMobileNa > Referral + + Beanstalk + = { description: "Share Pinto and earn rewards through referrals.", url: "https://pinto.money/referral", }, + beanstalk: { + title: "Beanstalk Obligations | Pinto", + description: "View your legacy Beanstalk holder obligations including Silo Payback, Pods, and Fertilizer.", + url: "https://pinto.money/beanstalk", + }, }; export default PINTO_META; diff --git a/src/pages/Beanstalk.tsx b/src/pages/Beanstalk.tsx new file mode 100644 index 00000000..d05cc05a --- /dev/null +++ b/src/pages/Beanstalk.tsx @@ -0,0 +1,53 @@ +import ReadMoreAccordion from "@/components/ReadMoreAccordion"; +import { Card } from "@/components/ui/Card"; +import PageContainer from "@/components/ui/PageContainer"; +import { Separator } from "@/components/ui/Separator"; +import BeanstalkGlobalCard from "./beanstalk/components/BeanstalkGlobalCard"; +import BeanstalkObligationsCard from "./beanstalk/components/BeanstalkObligationsCard"; + +const Beanstalk = () => { + return ( + +
+
+ {/* Hero Section */} +
+
Beanstalk Obligations
+
+ Beanstalk Debt issued by Pinto. + + Beanstalk participants at the time of Pinto launch were issued assets based on their holdings. When + Pinto exceeds 1 Billion in supply, 3% of mints go towards these between Beanstalk Silo Tokens, Pods, and + Fertilizer.{" "} + + Learn more + + +
+
+ + + {/* Main Cards - Two Column Layout */} +
+ {/* Left Panel - Obligations Card */} + + + + + {/* Right Panel - Global Stats Card */} + + + +
+
+
+
+ ); +}; + +export default Beanstalk; diff --git a/src/pages/beanstalk/components/BeanstalkFertilizerSection.tsx b/src/pages/beanstalk/components/BeanstalkFertilizerSection.tsx new file mode 100644 index 00000000..6ab7e299 --- /dev/null +++ b/src/pages/beanstalk/components/BeanstalkFertilizerSection.tsx @@ -0,0 +1,39 @@ +import { TokenValue } from "@/classes/TokenValue"; +import BeanstalkStatField from "@/components/BeanstalkStatField"; +import { formatter } from "@/utils/format"; + +interface BeanstalkFertilizerSectionProps { + balance: TokenValue; + isLoading: boolean; + disabled?: boolean; + onRinse?: () => void; + onSend?: () => void; +} + +/** + * Section component displaying fertilizer balance + */ +const BeanstalkFertilizerSection: React.FC = ({ + balance, + isLoading, + disabled = false, + onRinse, + onSend, +}) => { + const hasBalance = !balance.isZero; + + return ( + + ); +}; + +export default BeanstalkFertilizerSection; diff --git a/src/pages/beanstalk/components/BeanstalkGlobalCard.tsx b/src/pages/beanstalk/components/BeanstalkGlobalCard.tsx new file mode 100644 index 00000000..30e791a8 --- /dev/null +++ b/src/pages/beanstalk/components/BeanstalkGlobalCard.tsx @@ -0,0 +1,66 @@ +import BeanstalkStatField from "@/components/BeanstalkStatField"; +import { Button } from "@/components/ui/Button"; +import { useBeanstalkGlobalStats } from "@/state/useBeanstalkGlobalStats"; +import { formatter } from "@/utils/format"; + +/** + * Component displaying global Beanstalk repayment statistics + * Shows total urBDV distributed, total pods in repayment field, + * total unfertilized sprouts, and total Pinto paid out + * Shows N/A values when data cannot be loaded + */ +const BeanstalkGlobalCard: React.FC = () => { + const { + totalUrBdvDistributed, + totalPodsInRepaymentField, + totalUnfertilizedSprouts, + totalPintoPaidOut, + isLoading, + isError, + refetch, + } = useBeanstalkGlobalStats(); + + const formatValue = (value: typeof totalUrBdvDistributed) => { + return formatter.number(value, { minDecimals: 2, maxDecimals: 2 }); + }; + + return ( +
+ {isError && ( +
+ +
+ )} +
+ + + + +
+
+ ); +}; + +export default BeanstalkGlobalCard; diff --git a/src/pages/beanstalk/components/BeanstalkObligationsCard.tsx b/src/pages/beanstalk/components/BeanstalkObligationsCard.tsx new file mode 100644 index 00000000..2bc0ad65 --- /dev/null +++ b/src/pages/beanstalk/components/BeanstalkObligationsCard.tsx @@ -0,0 +1,47 @@ +import { Button } from "@/components/ui/Button"; +import { useFarmerBeanstalkRepayment } from "@/state/useFarmerBeanstalkRepayment"; +import { useAccount } from "wagmi"; +import BeanstalkFertilizerSection from "./BeanstalkFertilizerSection"; +import BeanstalkPodsSection from "./BeanstalkPodsSection"; +import BeanstalkSiloSection from "./BeanstalkSiloSection"; + +/** + * Container component for displaying user's Beanstalk obligations + * Shows Silo Payback (urBDV), Pods from repayment field, and Fertilizer data + * Shows N/A values when wallet is not connected or data cannot be loaded + */ +const BeanstalkObligationsCard: React.FC = () => { + const account = useAccount(); + const { silo, pods, fertilizer, isLoading, isError, refetch } = useFarmerBeanstalkRepayment(); + + const isConnected = !!account.address; + const showDisabled = !isConnected || isError; + + return ( +
+ {isConnected && isError && ( +
+ +
+ )} +
+ + + +
+
+ ); +}; + +export default BeanstalkObligationsCard; diff --git a/src/pages/beanstalk/components/BeanstalkPodsSection.tsx b/src/pages/beanstalk/components/BeanstalkPodsSection.tsx new file mode 100644 index 00000000..e26a2f5d --- /dev/null +++ b/src/pages/beanstalk/components/BeanstalkPodsSection.tsx @@ -0,0 +1,53 @@ +import { TokenValue } from "@/classes/TokenValue"; +import BeanstalkStatField from "@/components/BeanstalkStatField"; +import PodLineGraph from "@/components/PodLineGraph"; +import TextSkeleton from "@/components/TextSkeleton"; +import { Plot } from "@/utils/types"; + +interface BeanstalkPodsSectionProps { + plots: Plot[]; + totalPods: TokenValue; + isLoading: boolean; + disabled?: boolean; + onHarvest?: () => void; + onSend?: () => void; +} + +/** + * Section component displaying pods from the repayment field (fieldId=1) + * Shows PodLineGraph visualization + */ +const BeanstalkPodsSection: React.FC = ({ + plots, + totalPods, + isLoading, + disabled = false, + onHarvest, + onSend, +}) => { + const hasPlots = plots.length > 0; + const hasPods = !totalPods.isZero; + const showDisabledGraph = disabled || !hasPlots; + + return ( + + {isLoading ? ( + + ) : ( +
+ +
+ )} +
+ ); +}; + +export default BeanstalkPodsSection; diff --git a/src/pages/beanstalk/components/BeanstalkSiloSection.tsx b/src/pages/beanstalk/components/BeanstalkSiloSection.tsx new file mode 100644 index 00000000..c24ca4dd --- /dev/null +++ b/src/pages/beanstalk/components/BeanstalkSiloSection.tsx @@ -0,0 +1,39 @@ +import { TokenValue } from "@/classes/TokenValue"; +import BeanstalkStatField from "@/components/BeanstalkStatField"; +import { formatter } from "@/utils/format"; + +interface BeanstalkSiloSectionProps { + balance: TokenValue; + isLoading: boolean; + disabled?: boolean; + onClaim?: () => void; + onSend?: () => void; +} + +/** + * Section component displaying urBDV token balance for Silo Payback + */ +const BeanstalkSiloSection: React.FC = ({ + balance, + isLoading, + disabled = false, + onClaim, + onSend, +}) => { + const hasBalance = !balance.isZero; + + return ( + + ); +}; + +export default BeanstalkSiloSection; diff --git a/src/state/useBeanstalkGlobalStats.ts b/src/state/useBeanstalkGlobalStats.ts new file mode 100644 index 00000000..315d47db --- /dev/null +++ b/src/state/useBeanstalkGlobalStats.ts @@ -0,0 +1,153 @@ +import { TokenValue } from "@/classes/TokenValue"; +import { PODS } from "@/constants/internalTokens"; +import { defaultQuerySettingsMedium } from "@/constants/query"; +import { useProtocolAddress } from "@/hooks/pinto/useProtocolAddress"; +import { useCallback, useMemo } from "react"; +import { useReadContracts } from "wagmi"; + +/** + * ABI snippets for Silo Payback contract global functions + */ +const siloPaybackGlobalAbi = [ + { + inputs: [], + name: "totalUrBdvDistributed", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalPintoPaidOut", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, +] as const; + +/** + * ABI snippets for Field contract global functions + */ +const fieldGlobalAbi = [ + { + inputs: [{ internalType: "uint256", name: "fieldId", type: "uint256" }], + name: "totalPods", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, +] as const; + +/** + * ABI snippets for Barn Payback contract global functions + */ +const barnPaybackGlobalAbi = [ + { + inputs: [], + name: "totalUnfertilizedSprouts", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, +] as const; + +/** + * Interface for the global Beanstalk statistics data + */ +export interface BeanstalkGlobalStatsData { + totalUrBdvDistributed: TokenValue; + totalPodsInRepaymentField: TokenValue; + totalUnfertilizedSprouts: TokenValue; + totalPintoPaidOut: TokenValue; + isLoading: boolean; + isError: boolean; + refetch: () => Promise; +} + +// Token decimals for urBDV (same as BEAN - 6 decimals) +const URBDV_DECIMALS = 6; +// Token decimals for Pinto (6 decimals) +const PINTO_DECIMALS = 6; +// Token decimals for sprouts +const SPROUTS_DECIMALS = 6; + +/** + * Hook for fetching global Beanstalk repayment statistics + * + * This hook fetches protocol-wide statistics: + * - Total urBDV distributed across all holders + * - Total pods in the repayment field (fieldId=1) + * - Total unfertilized sprouts + * - Total Pinto paid out to holders + * + * Uses a 5-minute stale time for more frequent updates of global stats + * + * @returns BeanstalkGlobalStatsData with all global statistics + */ +export function useBeanstalkGlobalStats(): BeanstalkGlobalStatsData { + const protocolAddress = useProtocolAddress(); + + // Query for all global statistics + const globalQuery = useReadContracts({ + contracts: [ + { + address: protocolAddress, + abi: siloPaybackGlobalAbi, + functionName: "totalUrBdvDistributed", + args: [], + }, + { + address: protocolAddress, + abi: fieldGlobalAbi, + functionName: "totalPods", + args: [1n], // fieldId=1 for repayment field + }, + { + address: protocolAddress, + abi: barnPaybackGlobalAbi, + functionName: "totalUnfertilizedSprouts", + args: [], + }, + { + address: protocolAddress, + abi: siloPaybackGlobalAbi, + functionName: "totalPintoPaidOut", + args: [], + }, + ], + allowFailure: true, + query: { + ...defaultQuerySettingsMedium, // 5 minutes staleTime for global stats + }, + }); + + // Process global data + const globalData = useMemo(() => { + const totalUrBdvDistributed = globalQuery.data?.[0]?.result; + const totalPodsInRepaymentField = globalQuery.data?.[1]?.result; + const totalUnfertilizedSprouts = globalQuery.data?.[2]?.result; + const totalPintoPaidOut = globalQuery.data?.[3]?.result; + + return { + totalUrBdvDistributed: TokenValue.fromBlockchain(totalUrBdvDistributed ?? 0n, URBDV_DECIMALS), + totalPodsInRepaymentField: TokenValue.fromBlockchain(totalPodsInRepaymentField ?? 0n, PODS.decimals), + totalUnfertilizedSprouts: TokenValue.fromBlockchain(totalUnfertilizedSprouts ?? 0n, SPROUTS_DECIMALS), + totalPintoPaidOut: TokenValue.fromBlockchain(totalPintoPaidOut ?? 0n, PINTO_DECIMALS), + }; + }, [globalQuery.data]); + + // Refetch function + const refetch = useCallback(async () => { + await globalQuery.refetch(); + }, [globalQuery.refetch]); + + return useMemo( + () => ({ + ...globalData, + isLoading: globalQuery.isLoading, + isError: globalQuery.isError, + refetch, + }), + [globalData, globalQuery.isLoading, globalQuery.isError, refetch], + ); +} diff --git a/src/state/useFarmerBeanstalkRepayment.ts b/src/state/useFarmerBeanstalkRepayment.ts new file mode 100644 index 00000000..8c92ff52 --- /dev/null +++ b/src/state/useFarmerBeanstalkRepayment.ts @@ -0,0 +1,313 @@ +import { TokenValue } from "@/classes/TokenValue"; +import { ZERO_ADDRESS } from "@/constants/address"; +import { PODS } from "@/constants/internalTokens"; +import { defaultQuerySettings } from "@/constants/query"; +import { beanstalkAbi } from "@/generated/contractHooks"; +import { useProtocolAddress } from "@/hooks/pinto/useProtocolAddress"; +import { Plot } from "@/utils/types"; +import { useCallback, useMemo } from "react"; +import { toHex } from "viem"; +import { useAccount, useReadContracts } from "wagmi"; + +/** + * ABI snippets for Silo Payback contract functions + * These are the functions needed to fetch urBDV token data for legacy Beanstalk holders + */ +const siloPaybackAbi = [ + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "balanceOfUrBdv", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "earnedUrBdv", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "totalDistributedToAccount", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "totalReceivedByAccount", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, +] as const; + +/** + * ABI snippets for Barn Payback contract functions + * These are the functions needed to fetch fertilizer and sprouts data + */ +const barnPaybackAbi = [ + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "balanceOfFertilizer", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "balanceOfSprouts", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "balanceOfFertilized", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "humidity", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, +] as const; + +/** + * Interface for silo payback data + */ +interface SiloPaybackData { + balance: TokenValue; + earned: TokenValue; + totalDistributed: TokenValue; + totalReceived: TokenValue; +} + +/** + * Interface for pods data from repayment field (fieldId=1) + */ +interface PodsData { + plots: Plot[]; + totalPods: TokenValue; +} + +/** + * Interface for fertilizer data + */ +interface FertilizerData { + balance: TokenValue; + sprouts: TokenValue; + fertilized: TokenValue; + humidity: TokenValue; +} + +/** + * Interface for the complete farmer Beanstalk repayment data + */ +export interface FarmerBeanstalkRepaymentData { + silo: SiloPaybackData; + pods: PodsData; + fertilizer: FertilizerData; + isLoading: boolean; + isError: boolean; + refetch: () => Promise; +} + +// Token decimals for urBDV (same as BEAN - 6 decimals) +const URBDV_DECIMALS = 6; +// Token decimals for fertilizer amounts +const FERTILIZER_DECIMALS = 6; +// Humidity is typically represented as a percentage with 2 decimal places +const HUMIDITY_DECIMALS = 2; + +/** + * Hook for fetching farmer-specific Beanstalk repayment data + * + * This hook fetches: + * - Silo payback data (urBDV balance, earned, distributed, received) + * - Pods data from repayment field (fieldId=1) + * - Fertilizer data (balance, sprouts, fertilized, humidity) + * + * @returns FarmerBeanstalkRepaymentData with all farmer obligations data + */ +export function useFarmerBeanstalkRepayment(): FarmerBeanstalkRepaymentData { + const account = useAccount(); + const protocolAddress = useProtocolAddress(); + const farmerAddress = account.address ?? ZERO_ADDRESS; + + // Query for silo payback data + const siloQuery = useReadContracts({ + contracts: [ + { + address: protocolAddress, + abi: siloPaybackAbi, + functionName: "balanceOfUrBdv", + args: [farmerAddress], + }, + { + address: protocolAddress, + abi: siloPaybackAbi, + functionName: "earnedUrBdv", + args: [farmerAddress], + }, + { + address: protocolAddress, + abi: siloPaybackAbi, + functionName: "totalDistributedToAccount", + args: [farmerAddress], + }, + { + address: protocolAddress, + abi: siloPaybackAbi, + functionName: "totalReceivedByAccount", + args: [farmerAddress], + }, + ], + allowFailure: true, + query: { + enabled: !!account.address, + ...defaultQuerySettings, // 20 minutes staleTime + }, + }); + + // Query for pods data from repayment field (fieldId=1) + const podsQuery = useReadContracts({ + contracts: [ + { + address: protocolAddress, + abi: beanstalkAbi, + functionName: "getPlotsFromAccount", + args: [farmerAddress, 1n], // fieldId=1 for repayment field + }, + { + address: protocolAddress, + abi: beanstalkAbi, + functionName: "balanceOfPods", + args: [farmerAddress, 1n], // fieldId=1 for repayment field + }, + ], + allowFailure: true, + query: { + enabled: !!account.address, + ...defaultQuerySettings, // 20 minutes staleTime + }, + }); + + // Query for fertilizer data + const fertilizerQuery = useReadContracts({ + contracts: [ + { + address: protocolAddress, + abi: barnPaybackAbi, + functionName: "balanceOfFertilizer", + args: [farmerAddress], + }, + { + address: protocolAddress, + abi: barnPaybackAbi, + functionName: "balanceOfSprouts", + args: [farmerAddress], + }, + { + address: protocolAddress, + abi: barnPaybackAbi, + functionName: "balanceOfFertilized", + args: [farmerAddress], + }, + { + address: protocolAddress, + abi: barnPaybackAbi, + functionName: "humidity", + args: [], + }, + ], + allowFailure: true, + query: { + enabled: !!account.address, + ...defaultQuerySettings, // 20 minutes staleTime + }, + }); + + // Process silo data + const siloData = useMemo((): SiloPaybackData => { + const balance = siloQuery.data?.[0]?.result; + const earned = siloQuery.data?.[1]?.result; + const totalDistributed = siloQuery.data?.[2]?.result; + const totalReceived = siloQuery.data?.[3]?.result; + + return { + balance: TokenValue.fromBlockchain(balance ?? 0n, URBDV_DECIMALS), + earned: TokenValue.fromBlockchain(earned ?? 0n, URBDV_DECIMALS), + totalDistributed: TokenValue.fromBlockchain(totalDistributed ?? 0n, URBDV_DECIMALS), + totalReceived: TokenValue.fromBlockchain(totalReceived ?? 0n, URBDV_DECIMALS), + }; + }, [siloQuery.data]); + + // Process pods data + const podsData = useMemo((): PodsData => { + const plotsResult = podsQuery.data?.[0]?.result as readonly { index: bigint; pods: bigint }[] | undefined; + const totalPodsResult = podsQuery.data?.[1]?.result; + + const plots: Plot[] = (plotsResult ?? []).map((plotData) => { + const index = TokenValue.fromBigInt(plotData.index, PODS.decimals); + const pods = TokenValue.fromBigInt(plotData.pods, PODS.decimals); + + return { + id: index.toHuman(), + idHex: toHex(`${plotData.index}${plotData.pods}`), + index, + pods, + harvestedPods: TokenValue.ZERO, + harvestablePods: TokenValue.ZERO, + unharvestablePods: pods, + }; + }); + + return { + plots, + totalPods: TokenValue.fromBlockchain(totalPodsResult ?? 0n, PODS.decimals), + }; + }, [podsQuery.data]); + + // Process fertilizer data + const fertilizerData = useMemo((): FertilizerData => { + const balance = fertilizerQuery.data?.[0]?.result; + const sprouts = fertilizerQuery.data?.[1]?.result; + const fertilized = fertilizerQuery.data?.[2]?.result; + const humidity = fertilizerQuery.data?.[3]?.result; + + return { + balance: TokenValue.fromBlockchain(balance ?? 0n, FERTILIZER_DECIMALS), + sprouts: TokenValue.fromBlockchain(sprouts ?? 0n, FERTILIZER_DECIMALS), + fertilized: TokenValue.fromBlockchain(fertilized ?? 0n, FERTILIZER_DECIMALS), + humidity: TokenValue.fromBlockchain(humidity ?? 0n, HUMIDITY_DECIMALS), + }; + }, [fertilizerQuery.data]); + + // Refetch all queries + const refetch = useCallback(async () => { + await Promise.all([siloQuery.refetch(), podsQuery.refetch(), fertilizerQuery.refetch()]); + }, [siloQuery.refetch, podsQuery.refetch, fertilizerQuery.refetch]); + + // Combined loading and error states + const isLoading = siloQuery.isLoading || podsQuery.isLoading || fertilizerQuery.isLoading; + const isError = siloQuery.isError || podsQuery.isError || fertilizerQuery.isError; + + return useMemo( + () => ({ + silo: siloData, + pods: podsData, + fertilizer: fertilizerData, + isLoading, + isError, + refetch, + }), + [siloData, podsData, fertilizerData, isLoading, isError, refetch], + ); +} From b6d1d7578a872d766680ba3aa5641162b8f968f6 Mon Sep 17 00:00:00 2001 From: feyyazcigim Date: Wed, 4 Feb 2026 05:55:26 +0300 Subject: [PATCH 3/6] chore: remove non-existent contract calls and add subgraph TODOs --- src/state/useBeanstalkGlobalStats.ts | 97 ++++----- src/state/useFarmerBeanstalkRepayment.ts | 256 ++++++++--------------- 2 files changed, 125 insertions(+), 228 deletions(-) diff --git a/src/state/useBeanstalkGlobalStats.ts b/src/state/useBeanstalkGlobalStats.ts index 315d47db..0c825214 100644 --- a/src/state/useBeanstalkGlobalStats.ts +++ b/src/state/useBeanstalkGlobalStats.ts @@ -7,23 +7,24 @@ import { useReadContracts } from "wagmi"; /** * ABI snippets for Silo Payback contract global functions + * NOTE: These functions don't exist in the protocol yet - will be indexed from subgraph later */ -const siloPaybackGlobalAbi = [ - { - inputs: [], - name: "totalUrBdvDistributed", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "totalPintoPaidOut", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, -] as const; +// const siloPaybackGlobalAbi = [ +// { +// inputs: [], +// name: "totalUrBdvDistributed", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// { +// inputs: [], +// name: "totalPintoPaidOut", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// ] as const; /** * ABI snippets for Field contract global functions @@ -40,16 +41,17 @@ const fieldGlobalAbi = [ /** * ABI snippets for Barn Payback contract global functions + * NOTE: This function doesn't exist in the protocol yet - will be indexed from subgraph later */ -const barnPaybackGlobalAbi = [ - { - inputs: [], - name: "totalUnfertilizedSprouts", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, -] as const; +// const barnPaybackGlobalAbi = [ +// { +// inputs: [], +// name: "totalUnfertilizedSprouts", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// ] as const; /** * Interface for the global Beanstalk statistics data @@ -67,7 +69,7 @@ export interface BeanstalkGlobalStatsData { // Token decimals for urBDV (same as BEAN - 6 decimals) const URBDV_DECIMALS = 6; // Token decimals for Pinto (6 decimals) -const PINTO_DECIMALS = 6; +// const PINTO_DECIMALS = 6; // Token decimals for sprouts const SPROUTS_DECIMALS = 6; @@ -75,10 +77,10 @@ const SPROUTS_DECIMALS = 6; * Hook for fetching global Beanstalk repayment statistics * * This hook fetches protocol-wide statistics: - * - Total urBDV distributed across all holders + * - Total urBDV distributed across all holders (TODO: from subgraph) * - Total pods in the repayment field (fieldId=1) - * - Total unfertilized sprouts - * - Total Pinto paid out to holders + * - Total unfertilized sprouts (TODO: from subgraph) + * - Total Pinto paid out to holders (TODO: from subgraph) * * Uses a 5-minute stale time for more frequent updates of global stats * @@ -87,33 +89,20 @@ const SPROUTS_DECIMALS = 6; export function useBeanstalkGlobalStats(): BeanstalkGlobalStatsData { const protocolAddress = useProtocolAddress(); - // Query for all global statistics + // Query for available global statistics (only totalPods exists in protocol) const globalQuery = useReadContracts({ contracts: [ - { - address: protocolAddress, - abi: siloPaybackGlobalAbi, - functionName: "totalUrBdvDistributed", - args: [], - }, { address: protocolAddress, abi: fieldGlobalAbi, functionName: "totalPods", args: [1n], // fieldId=1 for repayment field }, - { - address: protocolAddress, - abi: barnPaybackGlobalAbi, - functionName: "totalUnfertilizedSprouts", - args: [], - }, - { - address: protocolAddress, - abi: siloPaybackGlobalAbi, - functionName: "totalPintoPaidOut", - args: [], - }, + // TODO: These functions don't exist in the protocol yet + // Will be indexed from subgraph later: + // - totalUrBdvDistributed + // - totalUnfertilizedSprouts + // - totalPintoPaidOut ], allowFailure: true, query: { @@ -123,16 +112,14 @@ export function useBeanstalkGlobalStats(): BeanstalkGlobalStatsData { // Process global data const globalData = useMemo(() => { - const totalUrBdvDistributed = globalQuery.data?.[0]?.result; - const totalPodsInRepaymentField = globalQuery.data?.[1]?.result; - const totalUnfertilizedSprouts = globalQuery.data?.[2]?.result; - const totalPintoPaidOut = globalQuery.data?.[3]?.result; + const totalPodsInRepaymentField = globalQuery.data?.[0]?.result; return { - totalUrBdvDistributed: TokenValue.fromBlockchain(totalUrBdvDistributed ?? 0n, URBDV_DECIMALS), + // TODO: These will come from subgraph later + totalUrBdvDistributed: TokenValue.fromBlockchain(0n, URBDV_DECIMALS), totalPodsInRepaymentField: TokenValue.fromBlockchain(totalPodsInRepaymentField ?? 0n, PODS.decimals), - totalUnfertilizedSprouts: TokenValue.fromBlockchain(totalUnfertilizedSprouts ?? 0n, SPROUTS_DECIMALS), - totalPintoPaidOut: TokenValue.fromBlockchain(totalPintoPaidOut ?? 0n, PINTO_DECIMALS), + totalUnfertilizedSprouts: TokenValue.fromBlockchain(0n, SPROUTS_DECIMALS), + totalPintoPaidOut: TokenValue.fromBlockchain(0n, URBDV_DECIMALS), }; }, [globalQuery.data]); diff --git a/src/state/useFarmerBeanstalkRepayment.ts b/src/state/useFarmerBeanstalkRepayment.ts index 8c92ff52..28bc670f 100644 --- a/src/state/useFarmerBeanstalkRepayment.ts +++ b/src/state/useFarmerBeanstalkRepayment.ts @@ -11,82 +11,79 @@ import { useAccount, useReadContracts } from "wagmi"; /** * ABI snippets for Silo Payback contract functions - * These are the functions needed to fetch urBDV token data for legacy Beanstalk holders + * NOTE: These functions don't exist in the protocol yet - will be indexed from subgraph later */ -const siloPaybackAbi = [ - { - inputs: [{ internalType: "address", name: "account", type: "address" }], - name: "balanceOfUrBdv", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, - { - inputs: [{ internalType: "address", name: "account", type: "address" }], - name: "earnedUrBdv", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, - { - inputs: [{ internalType: "address", name: "account", type: "address" }], - name: "totalDistributedToAccount", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, - { - inputs: [{ internalType: "address", name: "account", type: "address" }], - name: "totalReceivedByAccount", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, -] as const; +// const siloPaybackAbi = [ +// { +// inputs: [{ internalType: "address", name: "account", type: "address" }], +// name: "balanceOfUrBdv", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// { +// inputs: [{ internalType: "address", name: "account", type: "address" }], +// name: "earnedUrBdv", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// { +// inputs: [{ internalType: "address", name: "account", type: "address" }], +// name: "totalDistributedToAccount", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// { +// inputs: [{ internalType: "address", name: "account", type: "address" }], +// name: "totalReceivedByAccount", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// ] as const; /** * ABI snippets for Barn Payback contract functions - * These are the functions needed to fetch fertilizer and sprouts data + * NOTE: These functions don't exist in the protocol yet - will be indexed from subgraph later */ -const barnPaybackAbi = [ - { - inputs: [{ internalType: "address", name: "account", type: "address" }], - name: "balanceOfFertilizer", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, - { - inputs: [{ internalType: "address", name: "account", type: "address" }], - name: "balanceOfSprouts", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, - { - inputs: [{ internalType: "address", name: "account", type: "address" }], - name: "balanceOfFertilized", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "humidity", - outputs: [{ internalType: "uint256", name: "", type: "uint256" }], - stateMutability: "view", - type: "function", - }, -] as const; +// const barnPaybackAbi = [ +// { +// inputs: [{ internalType: "address", name: "account", type: "address" }], +// name: "balanceOfFertilizer", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// { +// inputs: [{ internalType: "address", name: "account", type: "address" }], +// name: "balanceOfSprouts", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// { +// inputs: [{ internalType: "address", name: "account", type: "address" }], +// name: "balanceOfFertilized", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// { +// inputs: [], +// name: "humidity", +// outputs: [{ internalType: "uint256", name: "", type: "uint256" }], +// stateMutability: "view", +// type: "function", +// }, +// ] as const; /** * Interface for silo payback data */ interface SiloPaybackData { balance: TokenValue; - earned: TokenValue; - totalDistributed: TokenValue; - totalReceived: TokenValue; } /** @@ -102,9 +99,6 @@ interface PodsData { */ interface FertilizerData { balance: TokenValue; - sprouts: TokenValue; - fertilized: TokenValue; - humidity: TokenValue; } /** @@ -123,16 +117,14 @@ export interface FarmerBeanstalkRepaymentData { const URBDV_DECIMALS = 6; // Token decimals for fertilizer amounts const FERTILIZER_DECIMALS = 6; -// Humidity is typically represented as a percentage with 2 decimal places -const HUMIDITY_DECIMALS = 2; /** * Hook for fetching farmer-specific Beanstalk repayment data * * This hook fetches: - * - Silo payback data (urBDV balance, earned, distributed, received) - * - Pods data from repayment field (fieldId=1) - * - Fertilizer data (balance, sprouts, fertilized, humidity) + * - Silo payback data (TODO: from subgraph - urBDV balance) + * - Pods data from repayment field (fieldId=1) - from on-chain + * - Fertilizer data (TODO: from subgraph) * * @returns FarmerBeanstalkRepaymentData with all farmer obligations data */ @@ -141,42 +133,8 @@ export function useFarmerBeanstalkRepayment(): FarmerBeanstalkRepaymentData { const protocolAddress = useProtocolAddress(); const farmerAddress = account.address ?? ZERO_ADDRESS; - // Query for silo payback data - const siloQuery = useReadContracts({ - contracts: [ - { - address: protocolAddress, - abi: siloPaybackAbi, - functionName: "balanceOfUrBdv", - args: [farmerAddress], - }, - { - address: protocolAddress, - abi: siloPaybackAbi, - functionName: "earnedUrBdv", - args: [farmerAddress], - }, - { - address: protocolAddress, - abi: siloPaybackAbi, - functionName: "totalDistributedToAccount", - args: [farmerAddress], - }, - { - address: protocolAddress, - abi: siloPaybackAbi, - functionName: "totalReceivedByAccount", - args: [farmerAddress], - }, - ], - allowFailure: true, - query: { - enabled: !!account.address, - ...defaultQuerySettings, // 20 minutes staleTime - }, - }); - // Query for pods data from repayment field (fieldId=1) + // These are the only functions that exist in the protocol const podsQuery = useReadContracts({ contracts: [ { @@ -194,62 +152,20 @@ export function useFarmerBeanstalkRepayment(): FarmerBeanstalkRepaymentData { ], allowFailure: true, query: { - enabled: !!account.address, - ...defaultQuerySettings, // 20 minutes staleTime - }, - }); - - // Query for fertilizer data - const fertilizerQuery = useReadContracts({ - contracts: [ - { - address: protocolAddress, - abi: barnPaybackAbi, - functionName: "balanceOfFertilizer", - args: [farmerAddress], - }, - { - address: protocolAddress, - abi: barnPaybackAbi, - functionName: "balanceOfSprouts", - args: [farmerAddress], - }, - { - address: protocolAddress, - abi: barnPaybackAbi, - functionName: "balanceOfFertilized", - args: [farmerAddress], - }, - { - address: protocolAddress, - abi: barnPaybackAbi, - functionName: "humidity", - args: [], - }, - ], - allowFailure: true, - query: { - enabled: !!account.address, + // Always fetch - will use ZERO_ADDRESS if wallet not connected ...defaultQuerySettings, // 20 minutes staleTime }, }); - // Process silo data + // TODO: Silo payback data will come from subgraph + // Functions don't exist in protocol: balanceOfUrBdv, earnedUrBdv, totalDistributedToAccount, totalReceivedByAccount const siloData = useMemo((): SiloPaybackData => { - const balance = siloQuery.data?.[0]?.result; - const earned = siloQuery.data?.[1]?.result; - const totalDistributed = siloQuery.data?.[2]?.result; - const totalReceived = siloQuery.data?.[3]?.result; - return { - balance: TokenValue.fromBlockchain(balance ?? 0n, URBDV_DECIMALS), - earned: TokenValue.fromBlockchain(earned ?? 0n, URBDV_DECIMALS), - totalDistributed: TokenValue.fromBlockchain(totalDistributed ?? 0n, URBDV_DECIMALS), - totalReceived: TokenValue.fromBlockchain(totalReceived ?? 0n, URBDV_DECIMALS), + balance: TokenValue.fromBlockchain(0n, URBDV_DECIMALS), }; - }, [siloQuery.data]); + }, []); - // Process pods data + // Process pods data - these functions exist in protocol const podsData = useMemo((): PodsData => { const plotsResult = podsQuery.data?.[0]?.result as readonly { index: bigint; pods: bigint }[] | undefined; const totalPodsResult = podsQuery.data?.[1]?.result; @@ -275,29 +191,23 @@ export function useFarmerBeanstalkRepayment(): FarmerBeanstalkRepaymentData { }; }, [podsQuery.data]); - // Process fertilizer data + // TODO: Fertilizer data will come from subgraph + // Functions don't exist in protocol: balanceOfFertilizer, balanceOfSprouts, balanceOfFertilized + // humidity() exists as getCurrentHumidity() but not needed for now const fertilizerData = useMemo((): FertilizerData => { - const balance = fertilizerQuery.data?.[0]?.result; - const sprouts = fertilizerQuery.data?.[1]?.result; - const fertilized = fertilizerQuery.data?.[2]?.result; - const humidity = fertilizerQuery.data?.[3]?.result; - return { - balance: TokenValue.fromBlockchain(balance ?? 0n, FERTILIZER_DECIMALS), - sprouts: TokenValue.fromBlockchain(sprouts ?? 0n, FERTILIZER_DECIMALS), - fertilized: TokenValue.fromBlockchain(fertilized ?? 0n, FERTILIZER_DECIMALS), - humidity: TokenValue.fromBlockchain(humidity ?? 0n, HUMIDITY_DECIMALS), + balance: TokenValue.fromBlockchain(0n, FERTILIZER_DECIMALS), }; - }, [fertilizerQuery.data]); + }, []); - // Refetch all queries + // Refetch pods query (only one that works) const refetch = useCallback(async () => { - await Promise.all([siloQuery.refetch(), podsQuery.refetch(), fertilizerQuery.refetch()]); - }, [siloQuery.refetch, podsQuery.refetch, fertilizerQuery.refetch]); + await podsQuery.refetch(); + }, [podsQuery.refetch]); - // Combined loading and error states - const isLoading = siloQuery.isLoading || podsQuery.isLoading || fertilizerQuery.isLoading; - const isError = siloQuery.isError || podsQuery.isError || fertilizerQuery.isError; + // Loading and error states only from pods query + const isLoading = podsQuery.isLoading; + const isError = podsQuery.isError; return useMemo( () => ({ From 01f94e7d5d7196d8eaaa1452f9fcc21b7f2c80fc Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 12:47:03 +0000 Subject: [PATCH 4/6] refactor: extract repayment field ID to constant Extract hardcoded field ID value (1n) to BEANSTALK_REPAYMENT_FIELD_ID constant for better code maintainability and readability. Co-authored-by: frijo Co-Authored-By: Claude Sonnet 4.5 --- src/state/useBeanstalkGlobalStats.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/state/useBeanstalkGlobalStats.ts b/src/state/useBeanstalkGlobalStats.ts index 0c825214..a29ef48e 100644 --- a/src/state/useBeanstalkGlobalStats.ts +++ b/src/state/useBeanstalkGlobalStats.ts @@ -72,6 +72,8 @@ const URBDV_DECIMALS = 6; // const PINTO_DECIMALS = 6; // Token decimals for sprouts const SPROUTS_DECIMALS = 6; +// Field ID for the Beanstalk repayment field +const BEANSTALK_REPAYMENT_FIELD_ID = 1n; /** * Hook for fetching global Beanstalk repayment statistics @@ -96,7 +98,7 @@ export function useBeanstalkGlobalStats(): BeanstalkGlobalStatsData { address: protocolAddress, abi: fieldGlobalAbi, functionName: "totalPods", - args: [1n], // fieldId=1 for repayment field + args: [BEANSTALK_REPAYMENT_FIELD_ID], }, // TODO: These functions don't exist in the protocol yet // Will be indexed from subgraph later: From 01c3a9df99f23574573297f969f5a28c37a008ac Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 13:19:21 +0000 Subject: [PATCH 5/6] refactor: replace anchor tag with Link component in Beanstalk page Co-authored-by: frijo Co-Authored-By: Claude Sonnet 4.5 --- src/pages/Beanstalk.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/Beanstalk.tsx b/src/pages/Beanstalk.tsx index d05cc05a..7fe23357 100644 --- a/src/pages/Beanstalk.tsx +++ b/src/pages/Beanstalk.tsx @@ -2,6 +2,7 @@ import ReadMoreAccordion from "@/components/ReadMoreAccordion"; import { Card } from "@/components/ui/Card"; import PageContainer from "@/components/ui/PageContainer"; import { Separator } from "@/components/ui/Separator"; +import { Link } from "react-router-dom"; import BeanstalkGlobalCard from "./beanstalk/components/BeanstalkGlobalCard"; import BeanstalkObligationsCard from "./beanstalk/components/BeanstalkObligationsCard"; @@ -19,14 +20,14 @@ const Beanstalk = () => { Beanstalk participants at the time of Pinto launch were issued assets based on their holdings. When Pinto exceeds 1 Billion in supply, 3% of mints go towards these between Beanstalk Silo Tokens, Pods, and Fertilizer.{" "} - Learn more - + From eaf5465160ed01c346888fbdab4295bf5557a2cf Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 15:41:37 +0000 Subject: [PATCH 6/6] refactor: extract urBDV and Sprouts to internal token definitions - Add URBDV and SPROUTS token definitions to internalTokens.ts - Remove hardcoded URBDV_DECIMALS and SPROUTS_DECIMALS constants - Update useBeanstalkGlobalStats to use token instances for decimals Co-authored-by: frijo --- src/constants/internalTokens.ts | 16 ++++++++++++++++ src/state/useBeanstalkGlobalStats.ts | 14 ++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/constants/internalTokens.ts b/src/constants/internalTokens.ts index 954e7e41..b9a9ceb1 100644 --- a/src/constants/internalTokens.ts +++ b/src/constants/internalTokens.ts @@ -27,3 +27,19 @@ export const PODS: InternalToken = { displayDecimals: 2, logoURI: podLogo, }; + +export const URBDV: InternalToken = { + name: "Unripe BDV", + symbol: "urBDV", + decimals: 6, + displayDecimals: 2, + logoURI: "", // TODO: Add logo if needed +}; + +export const SPROUTS: InternalToken = { + name: "Sprouts", + symbol: "SPROUTS", + decimals: 6, + displayDecimals: 2, + logoURI: "", // TODO: Add logo if needed +}; diff --git a/src/state/useBeanstalkGlobalStats.ts b/src/state/useBeanstalkGlobalStats.ts index a29ef48e..4a3518fb 100644 --- a/src/state/useBeanstalkGlobalStats.ts +++ b/src/state/useBeanstalkGlobalStats.ts @@ -1,5 +1,5 @@ import { TokenValue } from "@/classes/TokenValue"; -import { PODS } from "@/constants/internalTokens"; +import { PODS, SPROUTS, URBDV } from "@/constants/internalTokens"; import { defaultQuerySettingsMedium } from "@/constants/query"; import { useProtocolAddress } from "@/hooks/pinto/useProtocolAddress"; import { useCallback, useMemo } from "react"; @@ -66,12 +66,6 @@ export interface BeanstalkGlobalStatsData { refetch: () => Promise; } -// Token decimals for urBDV (same as BEAN - 6 decimals) -const URBDV_DECIMALS = 6; -// Token decimals for Pinto (6 decimals) -// const PINTO_DECIMALS = 6; -// Token decimals for sprouts -const SPROUTS_DECIMALS = 6; // Field ID for the Beanstalk repayment field const BEANSTALK_REPAYMENT_FIELD_ID = 1n; @@ -118,10 +112,10 @@ export function useBeanstalkGlobalStats(): BeanstalkGlobalStatsData { return { // TODO: These will come from subgraph later - totalUrBdvDistributed: TokenValue.fromBlockchain(0n, URBDV_DECIMALS), + totalUrBdvDistributed: TokenValue.fromBlockchain(0n, URBDV.decimals), totalPodsInRepaymentField: TokenValue.fromBlockchain(totalPodsInRepaymentField ?? 0n, PODS.decimals), - totalUnfertilizedSprouts: TokenValue.fromBlockchain(0n, SPROUTS_DECIMALS), - totalPintoPaidOut: TokenValue.fromBlockchain(0n, URBDV_DECIMALS), + totalUnfertilizedSprouts: TokenValue.fromBlockchain(0n, SPROUTS.decimals), + totalPintoPaidOut: TokenValue.fromBlockchain(0n, URBDV.decimals), }; }, [globalQuery.data]);