Skip to content

Commit

Permalink
feat(cr_v2): estimated rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
franciscotobar committed Nov 11, 2024
1 parent 7f0a332 commit 07da9ed
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 8 deletions.
104 changes: 104 additions & 0 deletions src/app/collective-rewards/rewards/EstimatedRewards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { useCycleContext } from '@/app/collective-rewards/metrics/context/CycleContext'
import {
formatMetrics,
getLastCycleRewards,
MetricsCardTitle,
MetricsCardWithSpinner,
TokenMetricsCardRow,
useGetNotifyRewardLogs,
useGetRewardsCoinbase,
useGetRewardsERC20,
useGetRewardShares,
useGetTotalPotentialReward,
} from '@/app/collective-rewards/rewards'
import { useHandleErrors } from '@/app/collective-rewards/utils'
import { formatBalanceToHuman } from '@/app/user/Balances/balanceUtils'
import { usePricesContext } from '@/shared/context/PricesContext'
import { FC, useEffect, useState } from 'react'
import { Address } from 'viem'

type Token = {
symbol: string
address: Address
}

type RewardsTokenMetricsProps = {
gauge: Address
currency?: string
token: {
symbol: string
address: Address
}
rewards?: bigint
setState: (state: { isLoading: boolean }) => void
}

const RewardsTokenMetrics: FC<RewardsTokenMetricsProps> = ({
gauge,
rewards = 0n,
token: { symbol, address },
currency = 'USD',
setState,
}) => {
const {
data: totalPotentialRewards,
isLoading: totalPotentialRewardsLoading,
error: totalPotentialRewardsError,
} = useGetTotalPotentialReward()
const {
data: rewardShares,
isLoading: rewardSharesLoading,
error: rewardSharesError,
} = useGetRewardShares(gauge)

const error = totalPotentialRewardsError ?? rewardSharesError
useHandleErrors([{ error: error, title: 'Error loading estimated rewards' }])

const { prices } = usePricesContext()

const estimatedRewards =
!!rewardShares && !!totalPotentialRewards ? (rewards * rewardShares) / totalPotentialRewards : 0n
const estimatedRewardsInHuman = Number(formatBalanceToHuman(estimatedRewards))
const price = prices[symbol]?.price ?? 0
const { amount, fiatAmount } = formatMetrics(estimatedRewardsInHuman, price, symbol, currency)

useEffect(() => {
setState({ isLoading: totalPotentialRewardsLoading || rewardSharesLoading })
}, [totalPotentialRewardsLoading, rewardSharesLoading, setState])

return <TokenMetricsCardRow amount={amount} fiatAmount={fiatAmount} />
}

type EstimatedRewardsProps = {
gauge: Address
currency?: string
data: {
[token: string]: Token
}
}

export const EstimatedRewards: FC<EstimatedRewardsProps> = ({ data: { rif, rbtc }, ...rest }) => {
const { data: rifRewards, isLoading: rifRewardsLoading, error: rifRewardsError } = useGetRewardsERC20()
const {
data: rbtcRewards,
isLoading: rbtcRewardsLoading,
error: rbtcRewardsError,
} = useGetRewardsCoinbase()

const error = rifRewardsError ?? rbtcRewardsError
useHandleErrors([{ error: error, title: 'Error loading estimated rewards' }])

const [{ isLoading: isLoadingRif }, setRifState] = useState({ isLoading: false })
const [{ isLoading: isLoadingRbtc }, setRbtcState] = useState({ isLoading: false })

return (
<MetricsCardWithSpinner
isLoading={isLoadingRif || isLoadingRbtc || rifRewardsLoading || rbtcRewardsLoading}
borderless
>
<MetricsCardTitle title="Estimated rewards" data-testid="EstimatedRewards" />
<RewardsTokenMetrics {...rest} token={rif} rewards={rifRewards} setState={() => setRifState} />
<RewardsTokenMetrics {...rest} token={rbtc} rewards={rbtcRewards} setState={() => setRbtcState} />
</MetricsCardWithSpinner>
)
}
7 changes: 4 additions & 3 deletions src/app/collective-rewards/rewards/MyRewards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import {
LastCycleRewards,
ClaimableRewards,
AllTimeRewards,
EstimatedRewards,
} from '@/app/collective-rewards/rewards'
import { CycleContextProvider } from '@/app/collective-rewards/metrics'
import { PricesContextProvider } from '@/shared/context/PricesContext'
import { getCoinBaseAddress } from '@/app/collective-rewards/utils'
import { getCoinbaseAddress } from '@/app/collective-rewards/utils'
import { tokenContracts } from '@/lib/contracts'
import { Popover } from '@/components/Popover'
import { Button } from '@/components/Button'
Expand All @@ -28,7 +29,7 @@ export const Rewards: FC<{ builder: Address; gauge: Address }> = ({ builder, gau
symbol: 'RIF',
},
rbtc: {
address: getCoinBaseAddress(),
address: getCoinbaseAddress(),
symbol: 'RBTC',
},
}
Expand All @@ -48,7 +49,7 @@ export const Rewards: FC<{ builder: Address; gauge: Address }> = ({ builder, gau
<PricesContextProvider>
<ClaimableRewards builder={builder} gauge={gauge} data={data} />
<LastCycleRewards gauge={gauge} data={data} />
<div>Estimated Rewards</div>
<EstimatedRewards gauge={gauge} data={data} />
<AllTimeRewards gauge={gauge} data={data} />
<div>All time share</div>
<Popover
Expand Down
21 changes: 21 additions & 0 deletions src/app/collective-rewards/rewards/hooks/getRewardShares.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { GaugeAbi } from '@/lib/abis/v2/GaugeAbi'
import { Address } from 'viem'
import { useReadContract } from 'wagmi'

export const useGetRewardShares = (gauge?: Address) => {
const { data, isLoading, error } = useReadContract({
address: gauge!,
abi: GaugeAbi,
functionName: 'rewardShares',
query: {
refetchInterval: 30_000,
enabled: !!gauge,
},
})

return {
data,
isLoading,
error,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BackersManagerAbi } from '@/lib/abis/v2/BackersManagerAbi'
import { BackersManagerAddress } from '@/lib/contracts'
import { useReadContract } from 'wagmi'

export const useGetTotalPotentialReward = () => {
const { data, isLoading, error } = useReadContract({
address: BackersManagerAddress,
abi: BackersManagerAbi,
functionName: 'totalPotentialReward',
query: {
refetchInterval: 30_000,
},
})

return {
data,
isLoading,
error,
}
}
4 changes: 4 additions & 0 deletions src/app/collective-rewards/rewards/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ export * from './useGetBuilderRewardsClaimedLogs'
export * from './useGetRewardDistributedLogs'
export * from './useGetTokenProjectedReward'
export * from './useGetNotifyRewardLogs'
export * from './getRewardShares'
export * from './getTotalPotentialRewards'
export * from './useGetRewardsCoinbase'
export * from './useGetRewardsERC20'
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query'
import { fetchRewardDistributedCached } from '@/app/collective-rewards/actions'
import { Address, isAddressEqual, parseEventLogs } from 'viem'
import { SimplifiedRewardDistributorAbi } from '@/lib/abis/SimplifiedRewardDistributorAbi'
import { resolveCollectiveRewardToken } from '@/app/collective-rewards/utils/getCoinBaseAddress'
import { resolveCollectiveRewardToken } from '@/app/collective-rewards/utils/getCoinbaseAddress'
import { AVERAGE_BLOCKTIME } from '@/lib/constants'

export const useGetRewardDistributedLogs = (rewardToken?: Address, builder?: Address) => {
Expand Down
20 changes: 20 additions & 0 deletions src/app/collective-rewards/rewards/hooks/useGetRewardsCoinbase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BackersManagerAbi } from '@/lib/abis/v2/BackersManagerAbi'
import { BackersManagerAddress } from '@/lib/contracts'
import { useReadContract } from 'wagmi'

export const useGetRewardsCoinbase = () => {
const { data, isLoading, error } = useReadContract({
address: BackersManagerAddress,
abi: BackersManagerAbi,
functionName: 'rewardsCoinbase',
query: {
refetchInterval: 30_000,
},
})

return {
data,
isLoading,
error,
}
}
20 changes: 20 additions & 0 deletions src/app/collective-rewards/rewards/hooks/useGetRewardsERC20.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BackersManagerAbi } from '@/lib/abis/v2/BackersManagerAbi'
import { BackersManagerAddress } from '@/lib/contracts'
import { useReadContract } from 'wagmi'

export const useGetRewardsERC20 = () => {
const { data, isLoading, error } = useReadContract({
address: BackersManagerAddress,
abi: BackersManagerAbi,
functionName: 'rewardsERC20',
query: {
refetchInterval: 30_000,
},
})

return {
data,
isLoading,
error,
}
}
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 './EstimatedRewards'
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getAddress, keccak256, toUtf8Bytes, ZeroAddress } from 'ethers'
import { Address } from 'viem'

export const getCoinBaseAddress = () => {
export const getCoinbaseAddress = () => {
return getAddress(keccak256(toUtf8Bytes('COINBASE_ADDRESS')).slice(26)) as Address
}

export const resolveCollectiveRewardToken = (rewardToken: Address) =>
rewardToken === ZeroAddress ? getCoinBaseAddress() : rewardToken
rewardToken === ZeroAddress ? getCoinbaseAddress() : rewardToken
2 changes: 1 addition & 1 deletion src/app/collective-rewards/utils/getLastCycleRewards.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Address, isAddressEqual, parseEventLogs } from 'viem'
import { SimplifiedRewardDistributorAbi } from '@/lib/abis/SimplifiedRewardDistributorAbi'
import { getPreviousCycle } from '@/app/collective-rewards/utils/getPreviousCycle'
import { resolveCollectiveRewardToken } from '@/app/collective-rewards/utils/getCoinBaseAddress'
import { resolveCollectiveRewardToken } from '@/app/collective-rewards/utils/getCoinbaseAddress'

type EventLog = ReturnType<
typeof parseEventLogs<typeof SimplifiedRewardDistributorAbi, true, 'RewardDistributed'>
Expand Down
2 changes: 1 addition & 1 deletion src/app/collective-rewards/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './handleErrors'
export * from './getCoinBaseAddress'
export * from './getCoinbaseAddress'

0 comments on commit 07da9ed

Please sign in to comment.