import { formatUnits } from '@ethersproject/units' ; import { multicall } from '../../utils' ; import { BigNumber } from '@ethersproject/bignumber' ; export const author = 'my-swarm' ; export const version = '0.1.0' ; const abi = [ { inputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } , { internalType : 'address' , name : '' , type : 'address' } ] , name : 'userInfo' , outputs : [ { internalType : 'uint256' , name : 'amount' , type : 'uint256' } , { internalType : 'uint256' , name : 'rewardDebt' , type : 'uint256' } ] , stateMutability : 'view' , type : 'function' } , { constant : true , inputs : [ ] , name : 'totalSupply' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , payable : false , stateMutability : 'view' , type : 'function' } , { constant : true , inputs : [ ] , name : 'getReserves' , outputs : [ { internalType : 'uint112' , name : '_reserve0' , type : 'uint112' } , { internalType : 'uint112' , name : '_reserve1' , type : 'uint112' } , { internalType : 'uint32' , name : '_blockTimestampLast' , type : 'uint32' } ] , payable : false , stateMutability : 'view' , type : 'function' } ] ; const getCalls = ( addresses , options ) => { const result = [ ] ; for ( const address of addresses ) { result . push ( [ options . chefAddress , 'userInfo' , [ options . pid , address ] ] ) ; if ( options . uniPairAddress != null ) { result . push ( [ options . uniPairAddress , 'totalSupply' , [ ] ] ) ; result . push ( [ options . uniPairAddress , 'getReserves' , [ ] ] ) ; } } return result ; } ; function arrayChunk < T > ( arr , chunkSize ) { const result = [ ] ; for ( let i = 0 , j = arr . length ; i < j ; i += chunkSize ) { result . push ( arr . slice ( i , i + chunkSize ) ) ; } return result ; } function processValues ( values , options ) { const poolStaked = values [ 0 ] [ 0 ] ; const weight = BigNumber . from ( options . weight || 1 ) ; const weightDecimals = BigNumber . from ( 10 ) . pow ( BigNumber . from ( options . weightDecimals || 0 ) ) ; let result ; if ( ! options . uniPairAddress ) { result = poolStaked . mul ( weight ) . div ( weightDecimals ) ; } else { const uniTotalSupply = values [ 1 ] [ 0 ] ; const uniReserve = values [ 2 ] [ options . tokenIndex || 0 ] ; const precision = BigNumber . from ( 10 ) . pow ( 18 ) ; const tokensPerLp = uniReserve . mul ( precision ) . div ( uniTotalSupply ) ; result = poolStaked . mul ( tokensPerLp ) . mul ( weight ) . div ( weightDecimals ) . div ( precision ) ; } return parseFloat ( formatUnits ( result . toString ( ) , options . decimals || 18 ) ) ; } export async function strategy ( space , network , provider , addresses , options , snapshot ) { const blockTag = typeof snapshot === 'number' ? snapshot : 'latest' ; const response = await multicall ( network , provider , abi , getCalls ( addresses , options ) , { blockTag } ) ; return Object . fromEntries ( arrayChunk ( response , options . uniPairAddress == null ? 1 : 3 ) . map ( ( value , i ) => [ addresses [ i ] , processValues ( value , options ) ] ) ) ; }