import { BigNumber } from '@ethersproject/bignumber' ; import { hexZeroPad } from '@ethersproject/bytes' ; import { formatUnits } from '@ethersproject/units' ; import { Multicaller } from '../../utils' ; export const author = 'thegostep' ; export const version = '0.1.1' ; const abi = [ 'function balanceOf(address owner) external view returns (uint256)' , 'function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256)' ] ; export async function strategy ( space , network , provider , addresses , options , snapshot ) { const blockTag = typeof snapshot === 'number' ? snapshot : 'latest' ; const callWalletToCrucibleCount = new Multicaller ( network , provider , abi , { blockTag } ) ; for ( const walletAddress of addresses ) { callWalletToCrucibleCount . call ( walletAddress , options . crucible_factory , 'balanceOf' , [ walletAddress ] ) ; } const walletToCrucibleCount = await callWalletToCrucibleCount . execute ( ) ; const callWalletToCrucibleAddresses = new Multicaller ( network , provider , abi , { blockTag } ) ; for ( const [ walletAddress , crucibleCount ] of Object . entries ( walletToCrucibleCount ) ) { for ( let index = 0 ; index < crucibleCount . toNumber ( ) ; index ++ ) { callWalletToCrucibleAddresses . call ( walletAddress . toString ( ) + '-' + index . toString ( ) , options . crucible_factory , 'tokenOfOwnerByIndex' , [ walletAddress , index ] ) ; } } const walletIDToCrucibleAddresses = await callWalletToCrucibleAddresses . execute ( ) ; const callCrucibleToLpBalance = new Multicaller ( network , provider , abi , { blockTag } ) ; for ( const [ walletID , crucibleAddress ] of Object . entries ( walletIDToCrucibleAddresses ) ) { callCrucibleToLpBalance . call ( walletID , options . erc20_address , 'balanceOf' , [ hexZeroPad ( crucibleAddress . toHexString ( ) , 20 ) ] ) ; } const walletIDToLpBalance = await callCrucibleToLpBalance . execute ( ) ; const walletToLpBalance = { } as Record < string , BigNumber > ; for ( const [ walletID , lpBalance ] of Object . entries ( walletIDToLpBalance ) ) { const address = walletID . split ( '-' ) [ 0 ] ; walletToLpBalance [ address ] = walletToLpBalance [ address ] ? walletToLpBalance [ address ] . add ( lpBalance ) : lpBalance ; } return Object . fromEntries ( Object . entries ( walletToLpBalance ) . map ( ( [ address , balance ] ) => [ address , parseFloat ( formatUnits ( balance , options . erc20_decimals ) ) ] ) ) ; }