import { multicall } from '../../utils' ; import { formatUnits } from '@ethersproject/units' ; import { BigNumber } from '@ethersproject/bignumber' ; export const author = 'tempofeng' ; export const version = '0.1.0' ; const contractAbi = [ { constant : true , inputs : [ { internalType : 'address' , name : 'account' , type : 'address' } ] , name : 'balanceOf' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , payable : false , stateMutability : 'view' , type : 'function' } , { constant : true , inputs : [ { internalType : 'address' , name : 'account' , type : 'address' } ] , name : 'earned' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , payable : false , stateMutability : 'view' , type : 'function' } , { constant : true , inputs : [ { internalType : 'address' , name : 'account' , type : 'address' } ] , name : 'getBalance' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , payable : false , stateMutability : 'view' , type : 'function' } , { constant : true , inputs : [ ] , name : 'totalSupply' , outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] , payable : false , stateMutability : 'view' , type : 'function' } ] ; function bn ( num ) { return BigNumber . from ( num . toString ( ) ) ; } export async function strategy ( _space , network , provider , addresses , options , snapshot ) { const blockTag = typeof snapshot === 'number' ? snapshot : 'latest' ; let res = await multicall ( network , provider , contractAbi , [ [ options . bpoolAddress , 'totalSupply' , [ ] ] , [ options . bpoolAddress , 'getBalance' , [ options . tokenAddress ] ] , ... addresses . map ( ( address ) => [ options . unipoolAddress , 'balanceOf' , [ address ] ] ) , ... addresses . map ( ( address ) => [ options . unipoolAddress , 'earned' , [ address ] ] ) ] , { blockTag } ) ; const totalBPTsInBPool = bn ( res [ 0 ] ) ; const totalTokensInBPool = bn ( res [ 1 ] ) ; const tokensPerBPT = totalTokensInBPool . div ( totalBPTsInBPool ) ; res = res . slice ( 2 ) ; const userTokensFromBPTList = res . slice ( 0 , addresses . length ) . map ( ( num ) => { const userBPTs = bn ( num ) ; return userBPTs . mul ( tokensPerBPT ) ; } ) ; const userEarnedTokensList = res . slice ( addresses . length ) . map ( ( num ) => { return bn ( num ) ; } ) ; const sumList = userTokensFromBPTList . map ( ( userTokensFromBPT , i ) => { return userTokensFromBPT . add ( userEarnedTokensList [ i ] ) ; } ) ; return Object . fromEntries ( sumList . map ( ( sum , i ) => { const parsedSum = parseFloat ( formatUnits ( sum , options . decimal ) ) ; return [ addresses [ i ] , parsedSum ] ; } ) ) ; }