Skip to content

Commit 3bbab83

Browse files
Created getWalletNFTBalances and getWalletNFTAllowances functions and… (#1357)
* Created getWalletNFTBalances and getWalletNFTAllowances functions and related tests * Broke down getWalletNFTBalances and getWalletNFTAllowances into token type specific functions * Removed unused error * updated erc721 and erc1155 function names
1 parent 5a537e5 commit 3bbab83

File tree

2 files changed

+425
-0
lines changed

2 files changed

+425
-0
lines changed

source/batch-call/contracts/BatchCall.sol

+165
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ pragma solidity 0.8.23;
33

44
import { ERC20 } from "solady/src/tokens/ERC20.sol";
55
import "@openzeppelin/contracts/utils/Address.sol";
6+
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
7+
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
68
import "@airswap/swap/contracts/interfaces/ISwap.sol";
79
import "@airswap/swap-erc20/contracts/interfaces/ISwapERC20.sol";
810
import "@airswap/registry/contracts/interfaces/IRegistry.sol";
@@ -311,4 +313,167 @@ contract BatchCall {
311313
}
312314
return tokensSupported;
313315
}
316+
317+
/**
318+
* @notice Batch check ERC721 balances for multiple NFTs
319+
* @param userAddress address The user to check balances for
320+
* @param contractAddresses address[] Array of ERC721 contract addresses
321+
* @param tokenIds uint256[] Array of token IDs
322+
* @return uint256[] Array of balances (1 or 0) corresponding to each NFT
323+
*/
324+
function walletBalancesERC721(
325+
address userAddress,
326+
address[] calldata contractAddresses,
327+
uint256[] calldata tokenIds
328+
) external view returns (uint256[] memory) {
329+
if (
330+
contractAddresses.length == 0 ||
331+
contractAddresses.length != tokenIds.length
332+
) revert ArgumentInvalid();
333+
334+
uint256[] memory balances = new uint256[](contractAddresses.length);
335+
336+
for (uint256 i; i < contractAddresses.length; ) {
337+
if (contractAddresses[i].isContract()) {
338+
IERC721 nft = IERC721(contractAddresses[i]);
339+
try nft.ownerOf(tokenIds[i]) returns (address owner) {
340+
balances[i] = owner == userAddress ? 1 : 0;
341+
} catch {
342+
balances[i] = 0;
343+
}
344+
} else {
345+
balances[i] = 0;
346+
}
347+
unchecked {
348+
++i;
349+
}
350+
}
351+
352+
return balances;
353+
}
354+
355+
/**
356+
* @notice Batch check ERC1155 balances for multiple NFTs
357+
* @param userAddress address The user to check balances for
358+
* @param contractAddresses address[] Array of ERC1155 contract addresses
359+
* @param tokenIds uint256[] Array of token IDs
360+
* @return uint256[] Array of balances corresponding to each NFT
361+
*/
362+
function walletBalancesERC1155(
363+
address userAddress,
364+
address[] calldata contractAddresses,
365+
uint256[] calldata tokenIds
366+
) external view returns (uint256[] memory) {
367+
if (
368+
contractAddresses.length == 0 ||
369+
contractAddresses.length != tokenIds.length
370+
) revert ArgumentInvalid();
371+
372+
uint256[] memory balances = new uint256[](contractAddresses.length);
373+
374+
for (uint256 i; i < contractAddresses.length; ) {
375+
if (contractAddresses[i].isContract()) {
376+
IERC1155 nft = IERC1155(contractAddresses[i]);
377+
try nft.balanceOf(userAddress, tokenIds[i]) returns (uint256 balance) {
378+
balances[i] = balance;
379+
} catch {
380+
balances[i] = 0;
381+
}
382+
} else {
383+
balances[i] = 0;
384+
}
385+
unchecked {
386+
++i;
387+
}
388+
}
389+
390+
return balances;
391+
}
392+
393+
/**
394+
* @notice Batch check ERC721 allowances for multiple NFTs
395+
* @param userAddress address The user who granted the approval
396+
* @param operatorAddress address The operator to check approval for
397+
* @param contractAddresses address[] Array of ERC721 contract addresses
398+
* @param tokenIds uint256[] Array of token IDs
399+
* @return bool[] Array of allowance states corresponding to each NFT
400+
*/
401+
function walletAllowancesERC721(
402+
address userAddress,
403+
address operatorAddress,
404+
address[] calldata contractAddresses,
405+
uint256[] calldata tokenIds
406+
) external view returns (bool[] memory) {
407+
if (
408+
contractAddresses.length == 0 ||
409+
contractAddresses.length != tokenIds.length
410+
) revert ArgumentInvalid();
411+
412+
bool[] memory allowances = new bool[](contractAddresses.length);
413+
414+
for (uint256 i; i < contractAddresses.length; ) {
415+
if (contractAddresses[i].isContract()) {
416+
IERC721 nft = IERC721(contractAddresses[i]);
417+
try nft.isApprovedForAll(userAddress, operatorAddress) returns (
418+
bool isApproved
419+
) {
420+
if (isApproved) {
421+
allowances[i] = true;
422+
} else {
423+
try nft.getApproved(tokenIds[i]) returns (address approved) {
424+
allowances[i] = approved == operatorAddress;
425+
} catch {
426+
allowances[i] = false;
427+
}
428+
}
429+
} catch {
430+
allowances[i] = false;
431+
}
432+
} else {
433+
allowances[i] = false;
434+
}
435+
unchecked {
436+
++i;
437+
}
438+
}
439+
440+
return allowances;
441+
}
442+
443+
/**
444+
* @notice Batch check ERC1155 allowances for multiple NFTs
445+
* @param userAddress address The user who granted the approval
446+
* @param operatorAddress address The operator to check approval for
447+
* @param contractAddresses address[] Array of ERC1155 contract addresses
448+
* @return bool[] Array of allowance states corresponding to each NFT
449+
*/
450+
function walletAllowancesERC1155(
451+
address userAddress,
452+
address operatorAddress,
453+
address[] calldata contractAddresses
454+
) external view returns (bool[] memory) {
455+
if (contractAddresses.length == 0) revert ArgumentInvalid();
456+
457+
bool[] memory allowances = new bool[](contractAddresses.length);
458+
459+
for (uint256 i; i < contractAddresses.length; ) {
460+
if (contractAddresses[i].isContract()) {
461+
IERC1155 nft = IERC1155(contractAddresses[i]);
462+
try nft.isApprovedForAll(userAddress, operatorAddress) returns (
463+
bool approved
464+
) {
465+
allowances[i] = approved;
466+
} catch {
467+
allowances[i] = false;
468+
}
469+
} else {
470+
allowances[i] = false;
471+
}
472+
unchecked {
473+
++i;
474+
}
475+
}
476+
477+
return allowances;
478+
}
314479
}

0 commit comments

Comments
 (0)