From 05d10d5ad5b084a4eaff20a9f6784a9eca00daf4 Mon Sep 17 00:00:00 2001 From: Francisco Tobar Date: Tue, 5 Nov 2024 20:38:08 -0600 Subject: [PATCH] feat(cr_v2): all time rewards --- src/app/collective-rewards/actions.ts | 14 ++- .../rewards/AllTimeRewards.tsx | 87 +++++++++++++++++++ .../rewards/ClaimableRewards.tsx | 10 +-- .../rewards/LastCycleRewards.tsx | 7 +- .../collective-rewards/rewards/MyRewards.tsx | 3 +- .../collective-rewards/rewards/hooks/index.ts | 1 + .../hooks/useGetBuilderRewardsClaimedLogs.ts | 41 +++++++++ src/app/collective-rewards/rewards/index.ts | 1 + src/lib/endpoints.ts | 3 + 9 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 src/app/collective-rewards/rewards/AllTimeRewards.tsx create mode 100644 src/app/collective-rewards/rewards/hooks/useGetBuilderRewardsClaimedLogs.ts diff --git a/src/app/collective-rewards/actions.ts b/src/app/collective-rewards/actions.ts index 67e0bb3c..687af3de 100644 --- a/src/app/collective-rewards/actions.ts +++ b/src/app/collective-rewards/actions.ts @@ -1,7 +1,11 @@ import { Address } from 'viem' import { SimplifiedRewardDistributorAddress } from '@/lib/contracts' import { axiosInstance } from '@/lib/utils' -import { fetchNotifyRewardLogsByAddress, fetchRewardDistributedLogsByAddress } from '@/lib/endpoints' +import { + fetchBuilderRewardsClaimedLogsByAddress, + fetchNotifyRewardLogsByAddress, + fetchRewardDistributedLogsByAddress, +} from '@/lib/endpoints' export const fetchRewardDistributedLogs = (fromBlock = 0) => { return axiosInstance.get( @@ -21,3 +25,11 @@ export const fetchNotifyRewardLogs = (gaugeAddress: Address, fromBlock = 0) => { .replace('{{fromBlock}}', fromBlock.toString()), ) } + +export const fetchBuilderRewardsClaimed = (gaugeAddress: Address, fromBlock = 0) => { + return axiosInstance.get( + fetchBuilderRewardsClaimedLogsByAddress + .replace('{{address}}', gaugeAddress) + .replace('{{fromBlock}}', fromBlock.toString()), + ) +} diff --git a/src/app/collective-rewards/rewards/AllTimeRewards.tsx b/src/app/collective-rewards/rewards/AllTimeRewards.tsx new file mode 100644 index 00000000..c26c18da --- /dev/null +++ b/src/app/collective-rewards/rewards/AllTimeRewards.tsx @@ -0,0 +1,87 @@ +import { + formatMetrics, + MetricsCard, + MetricsCardTitle, + MetricsCardWithSpinner, + TokenMetricsCardRow, + useGetBuilderRewards, + useGetBuilderRewardsClaimedLogs, +} from '@/app/collective-rewards/rewards' +import { useHandleErrors } from '@/app/collective-rewards/utils' +import { formatBalanceToHuman } from '@/app/user/Balances/balanceUtils' +import { withSpinner } from '@/components/LoadingSpinner/withLoadingSpinner' +import { usePricesContext } from '@/shared/context/PricesContext' +import { FC } from 'react' +import { Address } from 'viem' + +type Token = { + symbol: string + address: Address +} + +type TokenRewardsMetricsProps = { + gauge: Address + currency?: string + token: { + symbol: string + address: Address + } +} + +const TokenRewardsMetrics: FC = ({ + gauge, + token: { symbol, address }, + currency = 'USD', +}) => { + const { + data: rewardsPerToken, + isLoading: logsLoading, + error: rewardsError, + } = useGetBuilderRewardsClaimedLogs(gauge) + const { + data: claimableRewards, + isLoading: claimableRewardsLoading, + error: claimableRewardsError, + } = useGetBuilderRewards(address, gauge) + + const error = rewardsError ?? claimableRewardsError + useHandleErrors({ error, title: 'Error loading all time rewards' }) + + const { prices } = usePricesContext() + + const totalClaimedRewards = + rewardsPerToken[address]?.reduce((acc, event) => { + const amount = event.args.amount_ ?? 0n + return acc + amount + }, 0n) ?? 0n + + const totalRewards = totalClaimedRewards + (claimableRewards ?? 0n) + const totalRewardsInHuman = Number(formatBalanceToHuman(totalRewards)) + const price = prices[symbol]?.price ?? 0 + + const { amount, fiatAmount } = formatMetrics(totalRewardsInHuman, price, symbol, currency) + + return withSpinner(TokenMetricsCardRow)({ + amount, + fiatAmount, + isLoading: logsLoading || claimableRewardsLoading, + }) +} + +type AllTimeRewardsProps = { + gauge: Address + currency?: string + data: { + [token: string]: Token + } +} + +export const AllTimeRewards: FC = ({ data: { rif, rbtc }, ...rest }) => { + return ( + + + + + + ) +} diff --git a/src/app/collective-rewards/rewards/ClaimableRewards.tsx b/src/app/collective-rewards/rewards/ClaimableRewards.tsx index 14dec5a6..260bc0be 100644 --- a/src/app/collective-rewards/rewards/ClaimableRewards.tsx +++ b/src/app/collective-rewards/rewards/ClaimableRewards.tsx @@ -52,14 +52,14 @@ type Token = { address: Address } -type RewardsTokenMetricsProps = { +type TokenRewardsMetricsProps = { builder: Address gauge: Address token: Token currency?: string } -const RewardsTokenMetrics: FC = ({ +const TokenRewardsMetrics: FC = ({ builder, gauge, token: { address, symbol }, @@ -106,12 +106,12 @@ type ClaimableRewardsProps = { } } -export const ClaimableRewards: FC = ({ data, ...rest }) => { +export const ClaimableRewards: FC = ({ data: { rif, rbtc }, ...rest }) => { return ( - - + + ) } diff --git a/src/app/collective-rewards/rewards/LastCycleRewards.tsx b/src/app/collective-rewards/rewards/LastCycleRewards.tsx index 0825d15d..8cc4eebd 100644 --- a/src/app/collective-rewards/rewards/LastCycleRewards.tsx +++ b/src/app/collective-rewards/rewards/LastCycleRewards.tsx @@ -4,7 +4,6 @@ import { getLastCycleRewards, MetricsCard, MetricsCardTitle, - MetricsCardWithSpinner, TokenMetricsCardRow, useGetNotifyRewardLogs, } from '@/app/collective-rewards/rewards' @@ -12,10 +11,10 @@ import { useHandleErrors } from '@/app/collective-rewards/utils' import { formatBalanceToHuman } from '@/app/user/Balances/balanceUtils' import { withSpinner } from '@/components/LoadingSpinner/withLoadingSpinner' import { usePricesContext } from '@/shared/context/PricesContext' -import { FC, useEffect, useState } from 'react' +import { FC } from 'react' import { Address } from 'viem' -type TokenRewardsProps = { +type TokenRewardsMetricsProps = { gauge: Address currency?: string token: { @@ -24,7 +23,7 @@ type TokenRewardsProps = { } } -const TokenRewardsMetrics: FC = ({ +const TokenRewardsMetrics: FC = ({ gauge, token: { symbol, address }, currency = 'USD', diff --git a/src/app/collective-rewards/rewards/MyRewards.tsx b/src/app/collective-rewards/rewards/MyRewards.tsx index e530fa27..4897ae78 100644 --- a/src/app/collective-rewards/rewards/MyRewards.tsx +++ b/src/app/collective-rewards/rewards/MyRewards.tsx @@ -7,6 +7,7 @@ import { useClaimStateReporting, LastCycleRewards, ClaimableRewards, + AllTimeRewards, } from '@/app/collective-rewards/rewards' import { CycleContextProvider } from '@/app/collective-rewards/metrics' import { PricesContextProvider } from '@/shared/context/PricesContext' @@ -48,7 +49,7 @@ export const Rewards: FC<{ builder: Address; gauge: Address }> = ({ builder, gau
Estimated Rewards
-
All time rewards
+
All time share
+> + +export type BuilderClaimedRewardsPerToken = Record + +export const useGetBuilderRewardsClaimedLogs = (gauge: Address) => { + const { data, error, isLoading } = useQuery({ + queryFn: async () => { + const { data } = await fetchBuilderRewardsClaimed(gauge) + + const events = parseEventLogs({ + abi: GaugeAbi, + logs: data, + eventName: 'BuilderRewardsClaimed', + }) + + return events.reduce((acc, log) => { + const rewardToken = getAddress(log.args.rewardToken_) + acc[rewardToken] = [...(acc[rewardToken] || []), log] + + return acc + }, {}) + }, + queryKey: ['builderRewardsClaimedLogs', gauge], + refetchInterval: AVERAGE_BLOCKTIME, + initialData: {}, + }) + + return { + data, + error, + isLoading, + } +} diff --git a/src/app/collective-rewards/rewards/index.ts b/src/app/collective-rewards/rewards/index.ts index 752b7b97..a556b0c7 100644 --- a/src/app/collective-rewards/rewards/index.ts +++ b/src/app/collective-rewards/rewards/index.ts @@ -4,3 +4,4 @@ export * from './utils' export * from './MyRewards' export * from './LastCycleRewards' export * from './ClaimableRewards' +export * from './AllTimeRewards' diff --git a/src/lib/endpoints.ts b/src/lib/endpoints.ts index faae7ed0..b96bd4c0 100644 --- a/src/lib/endpoints.ts +++ b/src/lib/endpoints.ts @@ -28,3 +28,6 @@ export const fetchRewardDistributedLogsByAddress = `/address/{{address}}/eventsB const NOTIFY_REWARD_EVENT = '0x3c0f5c48b0ffa2c570c1a0f4fbf7b0f8982213afff9eb42cd258ead865cf3c9d' export const fetchNotifyRewardLogsByAddress = `/address/{{address}}/eventsByTopic0?topic0=${NOTIFY_REWARD_EVENT}&chainId=${CHAIN_ID}&fromBlock={{fromBlock}}` + +const BUILDER_REWARDS_CLAIMED_EVENT = 'c309438e69ba53ef6afef64839bd1ab1acc4a9a8fd28c8e0356075ca66f72c1b' +export const fetchBuilderRewardsClaimedLogsByAddress = `/address/{{address}}/eventsByTopic0?topic0=${BUILDER_REWARDS_CLAIMED_EVENT}&chainId=${CHAIN_ID}&fromBlock={{fromBlock}}`