22pragma solidity ^ 0.8.0 ;
33
44import "./interface/ITokenBundle.sol " ;
5+ import "../lib/CurrencyTransferLib.sol " ;
6+
7+ interface IERC165 {
8+ function supportsInterface (bytes4 interfaceId ) external view returns (bool );
9+ }
510
611abstract contract TokenBundle is ITokenBundle {
712 /// @dev Mapping from bundle UID => bundle info.
@@ -30,6 +35,7 @@ abstract contract TokenBundle is ITokenBundle {
3035 require (bundle[_bundleId].count == 0 , "TokenBundle: existent at bundleId " );
3136
3237 for (uint256 i = 0 ; i < targetCount; i += 1 ) {
38+ _checkTokenType (_tokensToBind[i]);
3339 bundle[_bundleId].tokens[i] = _tokensToBind[i];
3440 }
3541
@@ -46,6 +52,7 @@ abstract contract TokenBundle is ITokenBundle {
4652
4753 for (uint256 i = 0 ; i < check; i += 1 ) {
4854 if (i < targetCount) {
55+ _checkTokenType (_tokensToBind[i]);
4956 bundle[_bundleId].tokens[i] = _tokensToBind[i];
5057 } else if (i < currentCount) {
5158 delete bundle[_bundleId].tokens[i];
@@ -57,6 +64,7 @@ abstract contract TokenBundle is ITokenBundle {
5764
5865 /// @dev Lets the calling contract add a token to a bundle for a unique bundle id and index.
5966 function _addTokenInBundle (Token memory _tokenToBind , uint256 _bundleId ) internal {
67+ _checkTokenType (_tokenToBind);
6068 uint256 id = bundle[_bundleId].count;
6169
6270 bundle[_bundleId].tokens[id] = _tokenToBind;
@@ -70,9 +78,38 @@ abstract contract TokenBundle is ITokenBundle {
7078 uint256 _index
7179 ) internal {
7280 require (_index < bundle[_bundleId].count, "TokenBundle: index DNE. " );
81+ _checkTokenType (_tokenToBind);
7382 bundle[_bundleId].tokens[_index] = _tokenToBind;
7483 }
7584
85+ /// @dev Checks if the type of asset-contract is same as the TokenType specified.
86+ function _checkTokenType (Token memory _token ) internal view {
87+ if (_token.tokenType == TokenType.ERC721 ) {
88+ try IERC165 (_token.assetContract).supportsInterface (0x80ac58cd ) returns (bool supported721 ) {
89+ require (supported721, "Asset doesn't match TokenType " );
90+ } catch {
91+ revert ("Asset doesn't match TokenType " );
92+ }
93+ } else if (_token.tokenType == TokenType.ERC1155 ) {
94+ try IERC165 (_token.assetContract).supportsInterface (0xd9b67a26 ) returns (bool supported1155 ) {
95+ require (supported1155, "Asset doesn't match TokenType " );
96+ } catch {
97+ revert ("Asset doesn't match TokenType " );
98+ }
99+ } else if (_token.tokenType == TokenType.ERC20 ) {
100+ if (_token.assetContract != CurrencyTransferLib.NATIVE_TOKEN) {
101+ // 0x36372b07
102+ try IERC165 (_token.assetContract).supportsInterface (0x80ac58cd ) returns (bool supported721 ) {
103+ require (! supported721, "Asset doesn't match TokenType " );
104+
105+ try IERC165 (_token.assetContract).supportsInterface (0xd9b67a26 ) returns (bool supported1155 ) {
106+ require (! supported1155, "Asset doesn't match TokenType " );
107+ } catch Error (string memory ) {} catch {}
108+ } catch Error (string memory ) {} catch {}
109+ }
110+ }
111+ }
112+
76113 /// @dev Lets the calling contract set/update the uri of a particular bundle.
77114 function _setUriOfBundle (string calldata _uri , uint256 _bundleId ) internal {
78115 bundle[_bundleId].uri = _uri;
0 commit comments