import { BigNumber , BigNumberish } from '@ethersproject/bignumber' ; import { formatUnits } from '@ethersproject/units' ; import { Multicaller } from '../../utils' ; import examplesFile from './examples.json' ; export const author = 'CoinSwap-Space' ; export const version = '0.0.1' ; export const examples = examplesFile ; const abi = [ 'function balanceOf(address account) external view returns (uint256)' ] ; const masterCSSAbi = [ 'function userInfo(uint256, address) view returns (uint256 amount, uint256 rewardDebt)' , 'function totalSupply() view returns (uint256)' , 'function balanceOf(address _owner) view returns (uint256 balance)' ] ; const communityStakeAbi = [ 'function userInfo(address) view returns (uint256 amount, uint256 rewardDebt)' ] ; const bn = ( num ) : BigNumber => { return BigNumber . from ( num . toString ( ) ) ; } ; const addUserBalance = ( userBalances , user , balance ) => { if ( userBalances [ user ] ) { return ( userBalances [ user ] = userBalances [ user ] . add ( balance ) ) ; } else { return ( userBalances [ user ] = balance ) ; } } ; export async function strategy ( space , network , provider , addresses , options , snapshot ) { const blockTag = typeof snapshot === 'number' ? snapshot : 'latest' ; const multi = new Multicaller ( network , provider , abi , { blockTag } ) ; addresses . forEach ( ( address ) => multi . call ( address , options . address , 'balanceOf' , [ address ] ) ) ; const resultToken = await multi . execute ( ) ; const multiMasterCSS = new Multicaller ( network , provider , masterCSSAbi , { blockTag } ) ; addresses . forEach ( ( address ) => multiMasterCSS . call ( address , options . masterCSS , 'userInfo' , [ '0' , address ] ) ) ; const resultMasterCSS = await multiMasterCSS . execute ( ) ; const multiCommunityStake = new Multicaller ( network , provider , communityStakeAbi , { blockTag } ) ; options . communityStake . forEach ( ( communityStakeAddress ) => { addresses . forEach ( ( address ) => multiCommunityStake . call ( communityStakeAddress + '-' + address , communityStakeAddress , 'userInfo' , [ address ] ) ) ; } ) ; const communityStakeCSS = await multiCommunityStake . execute ( ) ; const multiCssLPs = new Multicaller ( network , provider , masterCSSAbi , { blockTag } ) ; options . cssLPs . forEach ( ( cssLpAddr ) => { multiCssLPs . call ( 'balanceOf' , options . address , 'balanceOf' , [ cssLpAddr . address ] ) ; multiCssLPs . call ( 'totalSupply' , cssLpAddr . address , 'totalSupply' ) ; addresses . forEach ( ( address ) => multiCssLPs . call ( cssLpAddr . address + '-' + address , options . masterCSS , 'userInfo' , [ cssLpAddr . pid , address ] ) ) ; } ) ; const resultCssLPs = await multiCssLPs . execute ( ) ; const userBalances = [ ] ; for ( let i = 0 ; i < addresses . length - 1 ; i ++ ) { userBalances [ addresses [ i ] ] = bn ( 0 ) ; } Object . fromEntries ( Object . entries ( resultMasterCSS ) . map ( ( [ address , balance ] ) => { return addUserBalance ( userBalances , address , balance [ 0 ] ) ; } ) ) ; Object . fromEntries ( Object . entries ( resultToken ) . map ( ( [ address , balance ] ) => { return addUserBalance ( userBalances , address , balance ) ; } ) ) ; options . communityStake . forEach ( ( communityStakeAddr ) => { addresses . forEach ( ( userAddr ) => { addUserBalance ( userBalances , userAddr , communityStakeCSS [ communityStakeAddr + '-' + userAddr ] [ 0 ] ) ; } ) ; } ) ; options . cssLPs . forEach ( ( cssLPAddr ) => { addresses . forEach ( ( userAddr ) => { addUserBalance ( userBalances , userAddr , bn ( resultCssLPs [ cssLPAddr . address + '-' + userAddr ] [ 0 ] ) . mul ( bn ( resultCssLPs . balanceOf ) ) . div ( bn ( resultCssLPs . totalSupply ) ) ) ; } ) ; } ) ; return Object . fromEntries ( Object . entries ( userBalances ) . map ( ( [ address , balance ] ) => [ address , parseFloat ( formatUnits ( balance , options . decimals ) ) ] ) ) ; }