import { Contract , ethers } from "ethers" ; import { useEffect , useState } from "react" ; import { Connection } from "../Connection" ; import { Prices } from "../Prices" ; import { Contracts } from "../Contracts" ; import { Jar } from "./useFetchJars" ; import { Pool } from "../Contracts/Pool" ; import { Gauge } from "../Contracts/Gauge" ; import { CurveGauge } from "../Contracts/CurveGauge" ; import { NETWORK_NAMES } from "containers/config" ; import { Contract as MulticallContract } from "ethers-multicall" ; export interface JarApy { [ k ] : number ; } export interface JarWithAPY extends Jar { totalAPY : number ; APYs : Array < JarApy > ; } type Input = Array < Jar > | null ; type Output = { APYs : Array < { [ key ] : number ; } > ; } ; const getCompoundingAPY = ( apr ) => { return 100 * ( Math . pow ( 1 + apr / 365 , 365 ) - 1 ) ; } ; export const useCurveCrvAPY = ( jars , underlyingPrice , gauge , pool ) : Output => { const { prices } = Prices . useContainer ( ) ; const { gaugeController } = Contracts . useContainer ( ) ; const { multicallProvider , chainName } = Connection . useContainer ( ) ; const [ CRVAPY , setCRVAPY ] = useState < number | null > ( null ) ; const getCRVAPY = async ( ) => { if ( gaugeController && gauge && pool && underlyingPrice && prices ?. crv && multicallProvider ) { const mcGauge = new MulticallContract ( gauge . address , gauge . interface . fragments ) ; const mcPool = new MulticallContract ( pool . address , pool . interface . fragments ) ; const weight = await gaugeController [ "gauge_relative_weight(address)" ] ( gauge . address ) . then ( ( x ) => parseFloat ( ethers . utils . formatUnits ( x ) ) ) ; const [ workingSupply , gaugeRate , virtualPrice ] = ( await multicallProvider . all ( [ mcGauge . working_supply ( ) , mcGauge . inflation_rate ( ) , mcPool . get_virtual_price ( ) , ] ) ) . map ( ( x ) => parseFloat ( ethers . utils . formatUnits ( x ) ) ) ; const rate = ( ( ( gaugeRate * weight * 31536000 ) / workingSupply ) * 0.4 ) / ( virtualPrice * underlyingPrice ) ; const crvApy = rate * prices ?. crv * 100 ; setCRVAPY ( crvApy * 0.725 ) ; } } ; useEffect ( ( ) => { if ( chainName === NETWORK_NAMES . ETH ) getCRVAPY ( ) ; } , [ jars , prices ] ) ; return { APYs : [ { crv : getCompoundingAPY ( ( CRVAPY || 0 ) / 100 ) , apr : CRVAPY || 0 } ] , } ; } ;