git.delta.rocks / unique-network / refs/commits / b7593be89010

difftreelog

add `collectionHelperAddress` method to `ERC721` & `ERC20` interfaces.

PraetorP2022-11-24parent: #5aafe0c.patch.diff
in: master

14 files changed

modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -30,6 +30,7 @@
 use pallet_evm_coder_substrate::{call, dispatch_to_evm};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
 use pallet_common::{CollectionHandle, erc::CollectionCall};
+use sp_core::Get;
 
 use crate::{
 	Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply,
@@ -132,6 +133,11 @@
 
 		Ok(<Allowance<T>>::get((self.id, owner, spender)).into())
 	}
+
+	/// @notice Returns collection helper contract address
+	fn collection_helper_address(&self) -> Result<address> {
+		Ok(T::ContractAddress::get())
+	}
 }
 
 #[solidity_interface(name = ERC20Mintable)]
modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -547,7 +547,7 @@
 	event Approval(address indexed owner, address indexed spender, uint256 value);
 }
 
-/// @dev the ERC-165 identifier for this interface is 0x942e8b22
+/// @dev the ERC-165 identifier for this interface is 0x8cb847c4
 contract ERC20 is Dummy, ERC165, ERC20Events {
 	/// @dev EVM selector for this function is: 0x06fdde03,
 	///  or in textual repr: name()
@@ -634,6 +634,15 @@
 		dummy;
 		return 0;
 	}
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() public view returns (address) {
+		require(false, stub_error);
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
 }
 
 contract UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -42,6 +42,7 @@
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
 use pallet_evm_coder_substrate::call;
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
+use sp_core::Get;
 
 use crate::{
 	AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,
@@ -489,6 +490,11 @@
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
+	
+	/// @notice Returns collection helper contract address 
+	fn collection_helper_address(&self) -> Result<address> {
+		Ok(T::ContractAddress::get())
+	}
 }
 
 /// @title ERC721 Token that can be irreversibly burned (destroyed).
modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -920,7 +920,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x80ac58cd
+/// @dev the ERC-165 identifier for this interface is 0x983a942b
 contract ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all NFTs assigned to an owner
 	/// @dev NFTs assigned to the zero address are considered invalid, and this
@@ -1050,6 +1050,15 @@
 		dummy;
 		return 0x0000000000000000000000000000000000000000;
 	}
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() public view returns (address) {
+		require(false, stub_error);
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
 }
 
 contract UniqueNFT is
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -38,7 +38,7 @@
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
 use pallet_evm_coder_substrate::{call, dispatch_to_evm};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
-use sp_core::H160;
+use sp_core::{H160, Get};
 use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};
 use up_data_structs::{
 	CollectionId, CollectionPropertiesVec, mapping::TokenAddressMapping, Property, PropertyKey,
@@ -482,6 +482,11 @@
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
+	
+	/// @notice Returns collection helper contract address
+	fn collection_helper_address(&self) -> Result<address> {
+		Ok(T::ContractAddress::get())
+	}
 }
 
 /// Returns amount of pieces of `token` that `owner` have
modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -919,7 +919,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x58800161
+/// @dev the ERC-165 identifier for this interface is 0x4016cd87
 contract ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all RFTs assigned to an owner
 	/// @dev RFTs assigned to the zero address are considered invalid, and this
@@ -1047,6 +1047,15 @@
 		dummy;
 		return 0x0000000000000000000000000000000000000000;
 	}
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() public view returns (address) {
+		require(false, stub_error);
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
 }
 
 contract UniqueRefungible is
modifiedtests/src/apiConsts.test.tsdiffbeforeafterboth
--- a/tests/src/apiConsts.test.ts
+++ b/tests/src/apiConsts.test.ts
@@ -117,4 +117,4 @@
 
 function checkConst<T>(constValue: any, expectedValue: T) {
   expect(constValue.toBigInt()).equal(expectedValue);
-}
+}
\ No newline at end of file
modifiedtests/src/eth/abi/fungible.jsondiffbeforeafterboth
before · tests/src/eth/abi/fungible.json
1[2  {3    "anonymous": false,4    "inputs": [5      {6        "indexed": true,7        "internalType": "address",8        "name": "owner",9        "type": "address"10      },11      {12        "indexed": true,13        "internalType": "address",14        "name": "spender",15        "type": "address"16      },17      {18        "indexed": false,19        "internalType": "uint256",20        "name": "value",21        "type": "uint256"22      }23    ],24    "name": "Approval",25    "type": "event"26  },27  {28    "anonymous": false,29    "inputs": [30      {31        "indexed": true,32        "internalType": "address",33        "name": "from",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "to",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "uint256",45        "name": "value",46        "type": "uint256"47      }48    ],49    "name": "Transfer",50    "type": "event"51  },52  {53    "inputs": [54      {55        "components": [56          { "internalType": "address", "name": "eth", "type": "address" },57          { "internalType": "uint256", "name": "sub", "type": "uint256" }58        ],59        "internalType": "struct EthCrossAccount",60        "name": "newAdmin",61        "type": "tuple"62      }63    ],64    "name": "addCollectionAdminCross",65    "outputs": [],66    "stateMutability": "nonpayable",67    "type": "function"68  },69  {70    "inputs": [71      {72        "components": [73          { "internalType": "address", "name": "eth", "type": "address" },74          { "internalType": "uint256", "name": "sub", "type": "uint256" }75        ],76        "internalType": "struct EthCrossAccount",77        "name": "user",78        "type": "tuple"79      }80    ],81    "name": "addToCollectionAllowListCross",82    "outputs": [],83    "stateMutability": "nonpayable",84    "type": "function"85  },86  {87    "inputs": [88      { "internalType": "address", "name": "owner", "type": "address" },89      { "internalType": "address", "name": "spender", "type": "address" }90    ],91    "name": "allowance",92    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],93    "stateMutability": "view",94    "type": "function"95  },96  {97    "inputs": [98      {99        "components": [100          { "internalType": "address", "name": "eth", "type": "address" },101          { "internalType": "uint256", "name": "sub", "type": "uint256" }102        ],103        "internalType": "struct EthCrossAccount",104        "name": "user",105        "type": "tuple"106      }107    ],108    "name": "allowlistedCross",109    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],110    "stateMutability": "view",111    "type": "function"112  },113  {114    "inputs": [115      { "internalType": "address", "name": "spender", "type": "address" },116      { "internalType": "uint256", "name": "amount", "type": "uint256" }117    ],118    "name": "approve",119    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],120    "stateMutability": "nonpayable",121    "type": "function"122  },123  {124    "inputs": [125      {126        "components": [127          { "internalType": "address", "name": "eth", "type": "address" },128          { "internalType": "uint256", "name": "sub", "type": "uint256" }129        ],130        "internalType": "struct EthCrossAccount",131        "name": "spender",132        "type": "tuple"133      },134      { "internalType": "uint256", "name": "amount", "type": "uint256" }135    ],136    "name": "approveCross",137    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],138    "stateMutability": "nonpayable",139    "type": "function"140  },141  {142    "inputs": [143      { "internalType": "address", "name": "owner", "type": "address" }144    ],145    "name": "balanceOf",146    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],147    "stateMutability": "view",148    "type": "function"149  },150  {151    "inputs": [152      {153        "components": [154          { "internalType": "address", "name": "eth", "type": "address" },155          { "internalType": "uint256", "name": "sub", "type": "uint256" }156        ],157        "internalType": "struct EthCrossAccount",158        "name": "from",159        "type": "tuple"160      },161      { "internalType": "uint256", "name": "amount", "type": "uint256" }162    ],163    "name": "burnFromCross",164    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],165    "stateMutability": "nonpayable",166    "type": "function"167  },168  {169    "inputs": [170      {171        "components": [172          { "internalType": "address", "name": "eth", "type": "address" },173          { "internalType": "uint256", "name": "sub", "type": "uint256" }174        ],175        "internalType": "struct EthCrossAccount",176        "name": "newOwner",177        "type": "tuple"178      }179    ],180    "name": "changeCollectionOwnerCross",181    "outputs": [],182    "stateMutability": "nonpayable",183    "type": "function"184  },185  {186    "inputs": [],187    "name": "collectionAdmins",188    "outputs": [189      {190        "components": [191          { "internalType": "address", "name": "eth", "type": "address" },192          { "internalType": "uint256", "name": "sub", "type": "uint256" }193        ],194        "internalType": "struct EthCrossAccount[]",195        "name": "",196        "type": "tuple[]"197      }198    ],199    "stateMutability": "view",200    "type": "function"201  },202  {203    "inputs": [],204    "name": "collectionOwner",205    "outputs": [206      {207        "components": [208          { "internalType": "address", "name": "eth", "type": "address" },209          { "internalType": "uint256", "name": "sub", "type": "uint256" }210        ],211        "internalType": "struct EthCrossAccount",212        "name": "",213        "type": "tuple"214      }215    ],216    "stateMutability": "view",217    "type": "function"218  },219  {220    "inputs": [221      { "internalType": "string[]", "name": "keys", "type": "string[]" }222    ],223    "name": "collectionProperties",224    "outputs": [225      {226        "components": [227          { "internalType": "string", "name": "key", "type": "string" },228          { "internalType": "bytes", "name": "value", "type": "bytes" }229        ],230        "internalType": "struct Property[]",231        "name": "",232        "type": "tuple[]"233      }234    ],235    "stateMutability": "view",236    "type": "function"237  },238  {239    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],240    "name": "collectionProperty",241    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],242    "stateMutability": "view",243    "type": "function"244  },245  {246    "inputs": [],247    "name": "collectionSponsor",248    "outputs": [249      {250        "components": [251          { "internalType": "address", "name": "field_0", "type": "address" },252          { "internalType": "uint256", "name": "field_1", "type": "uint256" }253        ],254        "internalType": "struct Tuple8",255        "name": "",256        "type": "tuple"257      }258    ],259    "stateMutability": "view",260    "type": "function"261  },262  {263    "inputs": [],264    "name": "confirmCollectionSponsorship",265    "outputs": [],266    "stateMutability": "nonpayable",267    "type": "function"268  },269  {270    "inputs": [],271    "name": "contractAddress",272    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],273    "stateMutability": "view",274    "type": "function"275  },276  {277    "inputs": [],278    "name": "decimals",279    "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],280    "stateMutability": "view",281    "type": "function"282  },283  {284    "inputs": [285      { "internalType": "string[]", "name": "keys", "type": "string[]" }286    ],287    "name": "deleteCollectionProperties",288    "outputs": [],289    "stateMutability": "nonpayable",290    "type": "function"291  },292  {293    "inputs": [],294    "name": "description",295    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],296    "stateMutability": "view",297    "type": "function"298  },299  {300    "inputs": [],301    "name": "hasCollectionPendingSponsor",302    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],303    "stateMutability": "view",304    "type": "function"305  },306  {307    "inputs": [308      {309        "components": [310          { "internalType": "address", "name": "eth", "type": "address" },311          { "internalType": "uint256", "name": "sub", "type": "uint256" }312        ],313        "internalType": "struct EthCrossAccount",314        "name": "user",315        "type": "tuple"316      }317    ],318    "name": "isOwnerOrAdminCross",319    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],320    "stateMutability": "view",321    "type": "function"322  },323  {324    "inputs": [325      { "internalType": "address", "name": "to", "type": "address" },326      { "internalType": "uint256", "name": "amount", "type": "uint256" }327    ],328    "name": "mint",329    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],330    "stateMutability": "nonpayable",331    "type": "function"332  },333  {334    "inputs": [335      {336        "components": [337          { "internalType": "address", "name": "field_0", "type": "address" },338          { "internalType": "uint256", "name": "field_1", "type": "uint256" }339        ],340        "internalType": "struct Tuple8[]",341        "name": "amounts",342        "type": "tuple[]"343      }344    ],345    "name": "mintBulk",346    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],347    "stateMutability": "nonpayable",348    "type": "function"349  },350  {351    "inputs": [],352    "name": "name",353    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],354    "stateMutability": "view",355    "type": "function"356  },357  {358    "inputs": [359      {360        "components": [361          { "internalType": "address", "name": "eth", "type": "address" },362          { "internalType": "uint256", "name": "sub", "type": "uint256" }363        ],364        "internalType": "struct EthCrossAccount",365        "name": "admin",366        "type": "tuple"367      }368    ],369    "name": "removeCollectionAdminCross",370    "outputs": [],371    "stateMutability": "nonpayable",372    "type": "function"373  },374  {375    "inputs": [],376    "name": "removeCollectionSponsor",377    "outputs": [],378    "stateMutability": "nonpayable",379    "type": "function"380  },381  {382    "inputs": [383      {384        "components": [385          { "internalType": "address", "name": "eth", "type": "address" },386          { "internalType": "uint256", "name": "sub", "type": "uint256" }387        ],388        "internalType": "struct EthCrossAccount",389        "name": "user",390        "type": "tuple"391      }392    ],393    "name": "removeFromCollectionAllowListCross",394    "outputs": [],395    "stateMutability": "nonpayable",396    "type": "function"397  },398  {399    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],400    "name": "setCollectionAccess",401    "outputs": [],402    "stateMutability": "nonpayable",403    "type": "function"404  },405  {406    "inputs": [407      { "internalType": "string", "name": "limit", "type": "string" },408      { "internalType": "uint256", "name": "value", "type": "uint256" }409    ],410    "name": "setCollectionLimit",411    "outputs": [],412    "stateMutability": "nonpayable",413    "type": "function"414  },415  {416    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],417    "name": "setCollectionMintMode",418    "outputs": [],419    "stateMutability": "nonpayable",420    "type": "function"421  },422  {423    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],424    "name": "setCollectionNesting",425    "outputs": [],426    "stateMutability": "nonpayable",427    "type": "function"428  },429  {430    "inputs": [431      { "internalType": "bool", "name": "enable", "type": "bool" },432      {433        "internalType": "address[]",434        "name": "collections",435        "type": "address[]"436      }437    ],438    "name": "setCollectionNesting",439    "outputs": [],440    "stateMutability": "nonpayable",441    "type": "function"442  },443  {444    "inputs": [445      {446        "components": [447          { "internalType": "string", "name": "key", "type": "string" },448          { "internalType": "bytes", "name": "value", "type": "bytes" }449        ],450        "internalType": "struct Property[]",451        "name": "properties",452        "type": "tuple[]"453      }454    ],455    "name": "setCollectionProperties",456    "outputs": [],457    "stateMutability": "nonpayable",458    "type": "function"459  },460  {461    "inputs": [462      {463        "components": [464          { "internalType": "address", "name": "eth", "type": "address" },465          { "internalType": "uint256", "name": "sub", "type": "uint256" }466        ],467        "internalType": "struct EthCrossAccount",468        "name": "sponsor",469        "type": "tuple"470      }471    ],472    "name": "setCollectionSponsorCross",473    "outputs": [],474    "stateMutability": "nonpayable",475    "type": "function"476  },477  {478    "inputs": [479      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }480    ],481    "name": "supportsInterface",482    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],483    "stateMutability": "view",484    "type": "function"485  },486  {487    "inputs": [],488    "name": "symbol",489    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],490    "stateMutability": "view",491    "type": "function"492  },493  {494    "inputs": [],495    "name": "totalSupply",496    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],497    "stateMutability": "view",498    "type": "function"499  },500  {501    "inputs": [502      { "internalType": "address", "name": "to", "type": "address" },503      { "internalType": "uint256", "name": "amount", "type": "uint256" }504    ],505    "name": "transfer",506    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],507    "stateMutability": "nonpayable",508    "type": "function"509  },510  {511    "inputs": [512      {513        "components": [514          { "internalType": "address", "name": "eth", "type": "address" },515          { "internalType": "uint256", "name": "sub", "type": "uint256" }516        ],517        "internalType": "struct EthCrossAccount",518        "name": "to",519        "type": "tuple"520      },521      { "internalType": "uint256", "name": "amount", "type": "uint256" }522    ],523    "name": "transferCross",524    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],525    "stateMutability": "nonpayable",526    "type": "function"527  },528  {529    "inputs": [530      { "internalType": "address", "name": "from", "type": "address" },531      { "internalType": "address", "name": "to", "type": "address" },532      { "internalType": "uint256", "name": "amount", "type": "uint256" }533    ],534    "name": "transferFrom",535    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],536    "stateMutability": "nonpayable",537    "type": "function"538  },539  {540    "inputs": [541      {542        "components": [543          { "internalType": "address", "name": "eth", "type": "address" },544          { "internalType": "uint256", "name": "sub", "type": "uint256" }545        ],546        "internalType": "struct EthCrossAccount",547        "name": "from",548        "type": "tuple"549      },550      {551        "components": [552          { "internalType": "address", "name": "eth", "type": "address" },553          { "internalType": "uint256", "name": "sub", "type": "uint256" }554        ],555        "internalType": "struct EthCrossAccount",556        "name": "to",557        "type": "tuple"558      },559      { "internalType": "uint256", "name": "amount", "type": "uint256" }560    ],561    "name": "transferFromCross",562    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],563    "stateMutability": "nonpayable",564    "type": "function"565  },566  {567    "inputs": [],568    "name": "uniqueCollectionType",569    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],570    "stateMutability": "view",571    "type": "function"572  }573]
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -231,6 +231,13 @@
   },
   {
     "inputs": [],
+    "name": "collectionHelperAddress",
+    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionOwner",
     "outputs": [
       {
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -213,6 +213,13 @@
   },
   {
     "inputs": [],
+    "name": "collectionHelperAddress",
+    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionOwner",
     "outputs": [
       {
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -354,7 +354,7 @@
 	event Approval(address indexed owner, address indexed spender, uint256 value);
 }
 
-/// @dev the ERC-165 identifier for this interface is 0x942e8b22
+/// @dev the ERC-165 identifier for this interface is 0x8cb847c4
 interface ERC20 is Dummy, ERC165, ERC20Events {
 	/// @dev EVM selector for this function is: 0x06fdde03,
 	///  or in textual repr: name()
@@ -395,6 +395,11 @@
 	/// @dev EVM selector for this function is: 0xdd62ed3e,
 	///  or in textual repr: allowance(address,address)
 	function allowance(address owner, address spender) external view returns (uint256);
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() external view returns (address);
 }
 
 interface UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -605,7 +605,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x80ac58cd
+/// @dev the ERC-165 identifier for this interface is 0x983a942b
 interface ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all NFTs assigned to an owner
 	/// @dev NFTs assigned to the zero address are considered invalid, and this
@@ -685,6 +685,11 @@
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
 	function isApprovedForAll(address owner, address operator) external view returns (address);
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() external view returns (address);
 }
 
 interface UniqueNFT is
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -604,7 +604,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x58800161
+/// @dev the ERC-165 identifier for this interface is 0x4016cd87
 interface ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all RFTs assigned to an owner
 	/// @dev RFTs assigned to the zero address are considered invalid, and this
@@ -682,6 +682,11 @@
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
 	function isApprovedForAll(address owner, address operator) external view returns (address);
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() external view returns (address);
 }
 
 interface UniqueRefungible is
addedtests/src/eth/collectionHelperAddress.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/collectionHelperAddress.test.ts
@@ -0,0 +1,57 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+import {itEth, usingEthPlaygrounds, expect} from './util';
+import {IKeyringPair} from '@polkadot/types/types';
+
+const EVM_COLLECTION_HELPERS_ADDRESS = '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f';
+
+describe('[eth]CollectionHelerpAddress test: ERC721 ', () => {
+  let donor: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (helper, privateKey) => {
+      donor = await privateKey({filename: __filename});
+    });
+  });
+
+  itEth('NFT\\RFT', async ({helper}) => {
+    const owner =  await helper.eth.createAccountWithBalance(donor);
+    
+    const {collectionAddress: nftCollectionAddress} = await helper.eth.createNFTCollection(owner, 'Sponsor', 'absolutely anything', 'ROC');
+    const nftCollection = helper.ethNativeContract.collection(nftCollectionAddress, 'nft', owner);
+    
+    const {collectionAddress: rftCollectionAddress} = await helper.eth.createRFTCollection(owner, 'Sponsor', 'absolutely anything', 'ROC');
+    const rftCollection = helper.ethNativeContract.collection(rftCollectionAddress, 'rft', owner);
+    
+    expect((await nftCollection.methods.collectionHelperAddress().call())
+      .toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS);
+    
+    expect((await rftCollection.methods.collectionHelperAddress().call())
+      .toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS);
+  });
+  
+  itEth('FT', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor);
+
+    const {collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Sponsor', 18, 'absolutely anything', 'ROC');
+    const collection = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
+    
+    expect((await collection.methods.collectionHelperAddress().call())
+      .toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS);
+  });
+ 
+});