Skip to content

Commit

Permalink
feat(cr_v2): all time share
Browse files Browse the repository at this point in the history
  • Loading branch information
franciscotobar committed Nov 12, 2024
1 parent 7f0a332 commit 191cb10
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 24 deletions.
27 changes: 24 additions & 3 deletions src/app/collective-rewards/actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { Address } from 'viem'
import { SimplifiedRewardDistributorAddress } from '@/lib/contracts'
import { BackersManagerAddress, SimplifiedRewardDistributorAddress } from '@/lib/contracts'
import { axiosInstance } from '@/lib/utils'
import { fetchNotifyRewardLogsByAddress, fetchRewardDistributedLogsByAddress } from '@/lib/endpoints'
import {
fetchBuilderRewardsClaimedLogsByAddress,
fetchGaugeNotifyRewardLogsByAddress,
fetchNotifyRewardLogsByAddress,
fetchRewardDistributedLogsByAddress,
} from '@/lib/endpoints'

export const fetchRewardDistributedLogs = (fromBlock = 0) => {
return axiosInstance.get(
Expand All @@ -14,9 +19,25 @@ export const fetchRewardDistributedLogs = (fromBlock = 0) => {
export const fetchRewardDistributedCached = () =>
axiosInstance.get('/reward-distributed/api', { baseURL: '/' })

export const fetchNotifyRewardLogs = (gaugeAddress: Address, fromBlock = 0) => {
export const fetchNotifyRewardLogs = (fromBlock = 0) => {
return axiosInstance.get(
fetchNotifyRewardLogsByAddress
.replace('{{address}}', BackersManagerAddress)
.replace('{{fromBlock}}', fromBlock.toString()),
)
}

export const fetchGaugeNotifyRewardLogs = (gaugeAddress: Address, fromBlock = 0) => {
return axiosInstance.get(
fetchGaugeNotifyRewardLogsByAddress
.replace('{{address}}', gaugeAddress)
.replace('{{fromBlock}}', fromBlock.toString()),
)
}

export const fetchBuilderRewardsClaimed = (gaugeAddress: Address, fromBlock = 0) => {
return axiosInstance.get(
fetchBuilderRewardsClaimedLogsByAddress
.replace('{{address}}', gaugeAddress)
.replace('{{fromBlock}}', fromBlock.toString()),
)
Expand Down
58 changes: 58 additions & 0 deletions src/app/collective-rewards/rewards/AllTimeShare.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Address } from 'viem'
import { FC } from 'react'
import {
useGetNotifyRewardLogs,
useGetGaugeNotifyRewardLogs,
useGetBuilderRewards,
} from '@/app/collective-rewards/rewards'
import { MetricsCardWithSpinner } from '@/components/MetricsCard/MetricsCard'
import { useHandleErrors } from '@/app/collective-rewards/utils'

type AllTimeShareProps = {
gauge: Address
data: {
[token: string]: {
symbol: string
address: Address
}
}
}

export const AllTimeShare: FC<AllTimeShareProps> = ({ gauge, data: { rif } }) => {
const { data: rewardsPerToken, isLoading: logsLoading, error: rewardsError } = useGetNotifyRewardLogs()
const {
data: gaugeRewardsPerToken,
isLoading: gaugeLogsLoading,
error: gaugeRewardsError,
} = useGetGaugeNotifyRewardLogs(gauge)
const {
data: claimableRewards,
isLoading: claimableRewardsLoading,
error: claimableRewardsError,
} = useGetBuilderRewards(rif.address, gauge)

const error = rewardsError ?? gaugeRewardsError ?? claimableRewardsError

useHandleErrors([{ error, title: 'Error loading all time share' }])

let isLoading: boolean = logsLoading || gaugeLogsLoading || claimableRewardsLoading

if (!rewardsPerToken[rif.address] || !gaugeRewardsPerToken[rif.address]) {
return <MetricsCardWithSpinner title="All time share" amount="0%" isLoading={isLoading} borderless />
}

const rifRewards = rewardsPerToken[rif.address].reduce((acc, event) => {
const amount = event.args.amount_
return acc + amount
}, 0n)
const gaugeRifRewards = gaugeRewardsPerToken[rif.address].reduce((acc, event) => {
const amount = event.args.builderAmount_
return acc + amount
}, 0n)

const totalRewards = gaugeRifRewards + (claimableRewards ?? 0n)

const amount = !rifRewards ? '0%' : `${(totalRewards * 100n) / rifRewards}%`

return <MetricsCardWithSpinner title="All time share" amount={amount} isLoading={isLoading} borderless />
}
7 changes: 6 additions & 1 deletion src/app/collective-rewards/rewards/LastCycleRewards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
MetricsCardTitle,
MetricsCardWithSpinner,
TokenMetricsCardRow,
useGetGaugeNotifyRewardLogs,
useGetNotifyRewardLogs,
} from '@/app/collective-rewards/rewards'
import { useHandleErrors } from '@/app/collective-rewards/utils'
Expand All @@ -30,7 +31,11 @@ const RewardsTokenMetrics: FC<TokenRewardsProps> = ({
setState,
}) => {
const { data: cycle, isLoading: cycleLoading, error: cycleError } = useCycleContext()
const { data: rewardsPerToken, isLoading: logsLoading, error: rewardsError } = useGetNotifyRewardLogs(gauge)
const {
data: rewardsPerToken,
isLoading: logsLoading,
error: rewardsError,
} = useGetGaugeNotifyRewardLogs(gauge)

const error = cycleError ?? rewardsError
useHandleErrors([{ error: error, title: 'Error loading last cycle rewards' }])
Expand Down
3 changes: 2 additions & 1 deletion src/app/collective-rewards/rewards/MyRewards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
LastCycleRewards,
ClaimableRewards,
AllTimeRewards,
AllTimeShare,
} from '@/app/collective-rewards/rewards'
import { CycleContextProvider } from '@/app/collective-rewards/metrics'
import { PricesContextProvider } from '@/shared/context/PricesContext'
Expand Down Expand Up @@ -50,7 +51,7 @@ export const Rewards: FC<{ builder: Address; gauge: Address }> = ({ builder, gau
<LastCycleRewards gauge={gauge} data={data} />
<div>Estimated Rewards</div>
<AllTimeRewards gauge={gauge} data={data} />
<div>All time share</div>
<AllTimeShare gauge={gauge} data={data} />
<Popover
disabled={isClaimFunctionReady}
content={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export const useGetBuilderRewards = (rewardToken: Address, gauge: Address) => {
args: [rewardToken],
query: {
refetchInterval: AVERAGE_BLOCKTIME,
enabled: !!gauge,
},
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'
import { fetchNotifyRewardLogs } from '@/app/collective-rewards/actions'
import { fetchBuilderRewardsClaimed } from '@/app/collective-rewards/actions'
import { Address, getAddress, parseEventLogs } from 'viem'
import { GaugeAbi } from '@/lib/abis/v2/GaugeAbi'
import { AVERAGE_BLOCKTIME } from '@/lib/constants'
Expand All @@ -10,10 +10,10 @@ export type BuilderRewardsClaimedEventLog = ReturnType<

export type BuilderClaimedRewardsPerToken = Record<Address, BuilderRewardsClaimedEventLog>

export const useGetBuilderRewardsClaimedLogs = (gauge?: Address) => {
export const useGetBuilderRewardsClaimedLogs = (gauge: Address) => {
const { data, error, isLoading } = useQuery({
queryFn: async () => {
const { data } = await fetchNotifyRewardLogs(gauge!)
const { data } = await fetchBuilderRewardsClaimed(gauge!)

const events = parseEventLogs({
abi: GaugeAbi,
Expand All @@ -23,18 +23,14 @@ export const useGetBuilderRewardsClaimedLogs = (gauge?: Address) => {

return events.reduce<BuilderClaimedRewardsPerToken>((acc, log) => {
const rewardToken = getAddress(log.args.rewardToken_)
const existingRewardToken = acc[rewardToken] || []
existingRewardToken.push(log)

acc[rewardToken] = existingRewardToken
acc[rewardToken] = [...(acc[rewardToken] || []), log]

return acc
}, {})
},
queryKey: ['builderRewardsClaimedLogs'],
refetchInterval: AVERAGE_BLOCKTIME,
initialData: {},
enabled: !!gauge,
})

return {
Expand Down
49 changes: 43 additions & 6 deletions src/app/collective-rewards/rewards/hooks/useGetNotifyRewardLogs.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,69 @@
import { useQuery } from '@tanstack/react-query'
import { fetchNotifyRewardLogs } from '@/app/collective-rewards/actions'
import { fetchGaugeNotifyRewardLogs, fetchNotifyRewardLogs } from '@/app/collective-rewards/actions'
import { Address, getAddress, parseEventLogs } from 'viem'
import { GaugeAbi } from '@/lib/abis/v2/GaugeAbi'
import { BackersManagerAbi } from '@/lib/abis/v2/BackersManagerAbi'
import { BackersManagerAddress } from '@/lib/contracts'
import { AVERAGE_BLOCKTIME } from '@/lib/constants'

export type NotifyRewardEventLog = ReturnType<typeof parseEventLogs<typeof GaugeAbi, true, 'NotifyReward'>>
export type NotifyRewardEventLog = ReturnType<
typeof parseEventLogs<typeof BackersManagerAbi, true, 'NotifyReward'>
>

export type NotifyRewardsPerToken = Record<Address, NotifyRewardEventLog>

export const useGetNotifyRewardLogs = (gauge: Address) => {
export const useGetNotifyRewardLogs = () => {
const { data, error, isLoading } = useQuery({
queryFn: async () => {
const { data } = await fetchNotifyRewardLogs(gauge)
const { data } = await fetchNotifyRewardLogs()

const events = parseEventLogs({
abi: GaugeAbi,
abi: BackersManagerAbi,
logs: data,
eventName: 'NotifyReward',
})

return events.reduce<NotifyRewardsPerToken>((acc, log) => {
const rewardToken = getAddress(log.args.rewardToken_)
acc[rewardToken] = [...(acc[rewardToken] || []), log]
return acc
}, {})
},
queryKey: ['notifyRewardLogs', BackersManagerAddress],
refetchInterval: AVERAGE_BLOCKTIME,
initialData: {},
})

return {
data,
error,
isLoading,
}
}

export type GaugeNotifyRewardEventLog = ReturnType<
typeof parseEventLogs<typeof GaugeAbi, true, 'NotifyReward'>
>
export type GaugeNotifyRewardsPerToken = Record<Address, GaugeNotifyRewardEventLog>

export const useGetGaugeNotifyRewardLogs = (gauge: Address) => {
const { data, error, isLoading } = useQuery({
queryFn: async () => {
const { data } = await fetchGaugeNotifyRewardLogs(gauge)

const events = parseEventLogs({
abi: GaugeAbi,
logs: data,
eventName: 'NotifyReward',
})

return events.reduce<GaugeNotifyRewardsPerToken>((acc, log) => {
const rewardToken = getAddress(log.args.rewardToken_)
acc[rewardToken] = [...(acc[rewardToken] || []), log]
return acc
}, {})
},
queryKey: ['notifyRewardLogs'],
queryKey: ['notifyRewardLogs', gauge],
refetchInterval: AVERAGE_BLOCKTIME,
initialData: {},
})
Expand Down
1 change: 1 addition & 0 deletions src/app/collective-rewards/rewards/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './MyRewards'
export * from './LastCycleRewards'
export * from './ClaimableRewards'
export * from './AllTimeRewards'
export * from './AllTimeShare'
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { NotifyRewardEventLog } from '@/app/collective-rewards/rewards'
import { GaugeNotifyRewardEventLog } from '@/app/collective-rewards/rewards'
import { Cycle } from '@/app/collective-rewards/metrics/context/CycleContext'

type Log = NotifyRewardEventLog[number]
type Log = GaugeNotifyRewardEventLog[number]
type CycleRewards = {
builderAmount: bigint
backersAmount: bigint
}

export const getLastCycleRewards = (cycle: Cycle, notifyRewardLogs?: NotifyRewardEventLog) => {
export const getLastCycleRewards = (cycle: Cycle, notifyRewardLogs?: GaugeNotifyRewardEventLog) => {
const { cycleDuration, endDistributionWindow, cycleStart } = cycle
const distributionWindow = endDistributionWindow.diff(cycleStart)
const lastCycleStart = cycleStart.minus({ millisecond: +cycleDuration })
Expand Down
8 changes: 7 additions & 1 deletion src/lib/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,11 @@ export const getNftHolders = `/nfts/{{address}}/holders?chainId=${CHAIN_ID}`
const REWARD_DISTRIBUTED_EVENT = '0x57ea5c7c295b52ef3b06c69661d59c8a6d9c602ac5355cfe5e54e303c139f270'
export const fetchRewardDistributedLogsByAddress = `/address/{{address}}/eventsByTopic0?topic0=${REWARD_DISTRIBUTED_EVENT}&chainId=${CHAIN_ID}&fromBlock={{fromBlock}}`

const NOTIFY_REWARD_EVENT = '0x3c0f5c48b0ffa2c570c1a0f4fbf7b0f8982213afff9eb42cd258ead865cf3c9d'
const NOTIFY_REWARD_EVENT = 'f70d5c697de7ea828df48e5c4573cb2194c659f1901f70110c52b066dcf50826'
export const fetchNotifyRewardLogsByAddress = `/address/{{address}}/eventsByTopic0?topic0=${NOTIFY_REWARD_EVENT}&chainId=${CHAIN_ID}&fromBlock={{fromBlock}}`

const GAUGE_NOTIFY_REWARD_EVENT = '0x3c0f5c48b0ffa2c570c1a0f4fbf7b0f8982213afff9eb42cd258ead865cf3c9d'
export const fetchGaugeNotifyRewardLogsByAddress = `/address/{{address}}/eventsByTopic0?topic0=${GAUGE_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}}`

0 comments on commit 191cb10

Please sign in to comment.