import { formatUnits } from '@ethersproject/units' ; import { BigNumber } from '@ethersproject/bignumber' ; import { multicall } from '../../utils' ; const BIG18 = BigNumber . from ( '1000000000000000000' ) ; export const author = 'FraxFinance' ; export const version = '0.0.2' ; const DECIMALS = 18 ; const abi = [ { constant : true , inputs : [ { internalType : 'address' , name : 'account' , type : 'address' } ] , name : 'balanceOf' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , payable : false , stateMutability : 'view' , type : 'function' } , { inputs : [ { internalType : 'address' , name : 'account' , type : 'address' } ] , name : 'boostedBalanceOf' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , stateMutability : 'view' , type : 'function' } , { constant : true , inputs : [ ] , name : 'totalSupply' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , payable : false , stateMutability : 'view' , type : 'function' } , { inputs : [ ] , name : 'getReserves' , outputs : [ { internalType : 'uint112' , name : '_reserve0' , type : 'uint112' } , { internalType : 'uint112' , name : '_reserve1' , type : 'uint112' } , { internalType : 'uint32' , name : '_blockTimestampLast' , type : 'uint32' } ] , stateMutability : 'view' , type : 'function' , constant : true } , { inputs : [ ] , name : 'token0' , outputs : [ { internalType : 'address' , name : '' , type : 'address' } ] , stateMutability : 'view' , type : 'function' } ] ; const chunk = ( arr , size ) => Array . from ( { length : Math . ceil ( arr . length / size ) } , ( v , i ) => arr . slice ( i * size , i * size + size ) ) ; export async function strategy ( space , network , provider , addresses , options , snapshot ) { const blockTag = typeof snapshot === 'number' ? snapshot : 'latest' ; const fxsQuery = addresses . map ( ( address ) => [ options . FXS , 'balanceOf' , [ address ] ] ) ; const vefxsQuery = addresses . map ( ( address ) => [ options . VEFXS , 'balanceOf' , [ address ] ] ) ; const freeUniLPFraxFxsQuery = addresses . map ( ( address ) => [ options . UNI_LP_FRAX_FXS , 'balanceOf' , [ address ] ] ) ; const farmingUniLPFraxFxsQuery = addresses . map ( ( address ) => [ options . FARMING_UNI_LP_FRAX_FXS , 'boostedBalanceOf' , [ address ] ] ) ; const response = await multicall ( network , provider , abi , [ [ options . UNI_LP_FRAX_FXS , 'token0' ] , [ options . UNI_LP_FRAX_FXS , 'getReserves' ] , [ options . UNI_LP_FRAX_FXS , 'totalSupply' ] , ... fxsQuery , ... vefxsQuery , ... freeUniLPFraxFxsQuery , ... farmingUniLPFraxFxsQuery ] , { blockTag } ) ; const uniLPFraxFxs_token0 = response [ 0 ] ; const uniLPFraxFxs_getReserves = response [ 1 ] ; const uniLPFraxFxs_totalSupply = response [ 2 ] ; let uni_FraxFxs_reservesFXS_E0 ; if ( uniLPFraxFxs_token0 [ 0 ] == options . FXS ) uni_FraxFxs_reservesFXS_E0 = uniLPFraxFxs_getReserves [ 0 ] ; else uni_FraxFxs_reservesFXS_E0 = uniLPFraxFxs_getReserves [ 1 ] ; const uni_FraxFxs_totalSupply_E0 = uniLPFraxFxs_totalSupply [ 0 ] ; const uniLPFraxFxs_fxs_per_LP_E18 = uni_FraxFxs_reservesFXS_E0 . mul ( BIG18 ) . div ( uni_FraxFxs_totalSupply_E0 ) ; const responseClean = response . slice ( 3 , response . length ) ; const chunks = chunk ( responseClean , addresses . length ) ; const fxsBalances = chunks [ 0 ] ; const vefxsBalances = chunks [ 1 ] ; const freeUniFraxFxsBalances = chunks [ 2 ] ; const farmUniFraxFxsBalances = chunks [ 3 ] ; return Object . fromEntries ( Array ( addresses . length ) . fill ( 'x' ) . map ( ( _ , i ) => { const free_fxs = fxsBalances [ i ] [ 0 ] ; const vefxs = vefxsBalances [ i ] [ 0 ] ; const free_uni_frax_fxs = freeUniFraxFxsBalances [ i ] [ 0 ] ; const farm_uni_frax_fxs = farmUniFraxFxsBalances [ i ] [ 0 ] ; return [ addresses [ i ] , parseFloat ( formatUnits ( free_fxs . add ( vefxs ) . add ( free_uni_frax_fxs . mul ( uniLPFraxFxs_fxs_per_LP_E18 ) . div ( BIG18 ) ) . add ( farm_uni_frax_fxs . mul ( uniLPFraxFxs_fxs_per_LP_E18 ) . div ( BIG18 ) ) . toString ( ) , DECIMALS ) ) ] ; } ) ) ; }