import { useEffect , useState } from "react" ; import { BigNumber } from "ethers" ; import { Contract as MulticallContract } from "ethers-multicall" ; import { Prices } from "../Prices" ; import { MiniPickles } from "../Pickles" ; import { Contracts } from "../Contracts" ; import { Connection } from "../Connection" ; import { RawFarm } from "../Farms/useFetchFarms" ; import { NETWORK_NAMES } from "containers/config" ; import { NULL_ADDRESS } from "features/Zap/constants" ; export interface FarmWithReward extends RawFarm { totalAllocPoints : number ; picklesRewarded : { perBlock : number ; perYear : number ; } ; valueRewarded : { perBlock : number ; perYear : number ; } ; maticRewardedPerYear : number ; maticValuePerYear : number ; } interface PoolInfo { accPicklePerShare : BigNumber ; allocPoint : BigNumber ; lastRewardTime : BigNumber ; } type Input = Array < RawFarm > | null ; type Output = { farmsWithReward : Array < FarmWithReward > | null ; } ; export const useWithReward = ( rawFarms ) : Output => { const { chainName } = Connection . useContainer ( ) ; const { pickleRewarder } = Contracts . useContainer ( ) ; const { multicallProvider } = Connection . useContainer ( ) ; const { prices } = Prices . useContainer ( ) ; const { picklePerSecond , maticPerSecond } = MiniPickles . useContainer ( ) ; const [ farms , setFarms ] = useState < Array < FarmWithReward > | null > ( null ) ; let rewarderPoolInfo ; let totalRewarderAP = 0 ; let maticRewardedPerSecond = 0 ; let maticValuePerSecond = 0 ; const calculateReward = async ( ) => { if ( rawFarms && prices && pickleRewarder && multicallProvider && typeof maticPerSecond === "number" && typeof picklePerSecond === "number" ) { const hasRewarder = pickleRewarder . address != NULL_ADDRESS ; const totalAllocPoints = rawFarms . reduce ( ( acc , farm ) => acc + farm . allocPoint . toNumber ( ) , 0 ) ; if ( hasRewarder ) { const pickleRewarderMulticallContract = new MulticallContract ( pickleRewarder . address , pickleRewarder . interface . fragments ) ; rewarderPoolInfo = await multicallProvider . all < PoolInfo [ ] > ( rawFarms . map ( ( farm ) => pickleRewarderMulticallContract . poolInfo ( farm . poolIndex ) ) ) ; totalRewarderAP = rewarderPoolInfo . reduce ( ( acc , curr ) => { return acc + curr . allocPoint . toNumber ( ) ; } , 0 ) ; } const newFarms = rawFarms . map ( ( farm ) => { const fraction = farm . allocPoint . toNumber ( ) / totalAllocPoints ; const pickleRewardedPerSecond = fraction * picklePerSecond ; const valRewardedPerSecond = pickleRewardedPerSecond * prices . pickle ; if ( hasRewarder ) { const maticFraction = rewarderPoolInfo [ farm . poolIndex ] . allocPoint . toNumber ( ) / totalRewarderAP ; maticRewardedPerSecond = maticFraction * maticPerSecond ; maticValuePerSecond = maticRewardedPerSecond * ( chainName === NETWORK_NAMES . OKEX ? prices . wokt : prices . matic ) ; } return { ... farm , totalAllocPoints , picklesRewarded : { perBlock : pickleRewardedPerSecond * 2 , perYear : pickleRewardedPerSecond * 3600 * 24 * 365 , } , valueRewarded : { perBlock : valRewardedPerSecond , perYear : valRewardedPerSecond * 3600 * 24 * 365 , } , maticRewardedPerYear : maticRewardedPerSecond * 3600 * 24 * 365 , maticValuePerYear : maticValuePerSecond * 3600 * 24 * 365 , } ; } ) ; setFarms ( newFarms ) ; } } ; useEffect ( ( ) => { calculateReward ( ) ; } , [ rawFarms ?. length , picklePerSecond , maticPerSecond , prices ] ) ; return { farmsWithReward : farms } ; } ;