import { BigNumber , BigNumberish } from '@ethersproject/bignumber' ; import { getAddress } from '@ethersproject/address' ; import { Multicaller } from '../../utils' ; import { formatUnits } from '@ethersproject/units' ; export const author = 'blockzerolabs' ; export const version = '0.1.0' ; const abi = [ 'function totalSupply() external view returns (uint256)' , 'function exists(uint256) external view returns (bool)' , 'function ownerOf(uint256) external view returns (address)' , 'function balanceOf(uint256) external view returns (uint256)' ] ; export async function strategy ( space , network , provider , addresses , options , snapshot ) { const blockTag = typeof snapshot === 'number' ? snapshot : 'latest' ; const totalSupply = options . totalSupply ; const nftExistsMulti = new Multicaller ( network , provider , abi , { blockTag } ) ; for ( let _nftId = 0 ; _nftId < totalSupply ; _nftId ++ ) { nftExistsMulti . call ( _nftId , options . _nftTokenAddress , 'exists' , [ _nftId ] ) ; } const nftExists = await nftExistsMulti . execute ( ) ; const nftOwnersMulti = new Multicaller ( network , provider , abi , { blockTag } ) ; for ( let _nftId = 0 ; _nftId < totalSupply ; _nftId ++ ) { if ( nftExists [ _nftId ] ) { nftOwnersMulti . call ( _nftId , options . _nftTokenAddress , 'ownerOf' , [ _nftId ] ) ; } } const nftOwners = await nftOwnersMulti . execute ( ) ; const vaultBalanceMulti = new Multicaller ( network , provider , abi , { blockTag } ) ; for ( let _nftId = 0 ; _nftId < totalSupply ; _nftId ++ ) { if ( nftExists [ _nftId ] ) { vaultBalanceMulti . call ( _nftId , options . _vaultAddress , 'balanceOf' , [ _nftId ] ) ; } } const vaultBalance = await vaultBalanceMulti . execute ( ) ; const balances = { } ; addresses . forEach ( ( address ) => { let totalBalance = BigNumber . from ( 0 ) ; for ( let _nftId = 0 ; _nftId < totalSupply ; _nftId ++ ) { if ( nftExists [ _nftId ] ) { if ( nftOwners [ _nftId ] == getAddress ( address ) ) { totalBalance = totalBalance . add ( vaultBalance [ _nftId ] ) ; } } } balances [ address ] = parseFloat ( formatUnits ( totalBalance , options . decimals ) ) ; } ) ; return balances ; }