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

difftreelog

feat add allowanceCross method

Trubnikov Sergey2023-02-01parent: #0ba1adb.patch.diff
in: master

22 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6360,7 +6360,7 @@
 
 [[package]]
 name = "pallet-fungible"
-version = "0.1.9"
+version = "0.1.10"
 dependencies = [
  "evm-coder",
  "frame-benchmarking",
@@ -6773,7 +6773,7 @@
 
 [[package]]
 name = "pallet-refungible"
-version = "0.2.12"
+version = "0.2.13"
 dependencies = [
  "evm-coder",
  "frame-benchmarking",
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/CHANGELOG.mddiffbeforeafterboth
--- a/pallets/fungible/CHANGELOG.md
+++ b/pallets/fungible/CHANGELOG.md
@@ -4,6 +4,12 @@
 
 <!-- bureaucrate goes here -->
 
+## [0.1.10] - 2023-02-01
+
+### Added
+
+- The functions `allowanceCross` to `ERC20UniqueExtensions` interface.
+
 ## [0.1.9] - 2022-12-01
 
 ### Added
modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/fungible/Cargo.toml
+++ b/pallets/fungible/Cargo.toml
@@ -2,7 +2,7 @@
 edition = "2021"
 license = "GPLv3"
 name = "pallet-fungible"
-version = "0.1.9"
+version = "0.1.10"
 
 [dependencies]
 # Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -161,6 +161,21 @@
 where
 	T::AccountId: From<[u8; 32]>,
 {
+	/// @dev Function to check the amount of tokens that an owner allowed to a spender.
+	/// @param owner crossAddress The address which owns the funds.
+	/// @param spender crossAddress The address which will spend the funds.
+	/// @return A uint256 specifying the amount of tokens still available for the spender.
+	fn allowance_cross(
+		&self,
+		owner: pallet_common::eth::CrossAddress,
+		spender: pallet_common::eth::CrossAddress,
+	) -> Result<U256> {
+		let owner = owner.into_sub_cross_account::<T>()?;
+		let spender = spender.into_sub_cross_account::<T>()?;
+
+		Ok(<Allowance<T>>::get((self.id, owner, spender)).into())
+	}
+
 	/// @notice A description for the collection.
 	fn description(&self) -> Result<String> {
 		Ok(decode_utf16(self.description.iter().copied())
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -511,8 +511,22 @@
 	bytes value;
 }
 
-/// @dev the ERC-165 identifier for this interface is 0x65789571
+/// @dev the ERC-165 identifier for this interface is 0x85d7dea6
 contract ERC20UniqueExtensions is Dummy, ERC165 {
+	/// @dev Function to check the amount of tokens that an owner allowed to a spender.
+	/// @param owner crossAddress The address which owns the funds.
+	/// @param spender crossAddress The address which will spend the funds.
+	/// @return A uint256 specifying the amount of tokens still available for the spender.
+	/// @dev EVM selector for this function is: 0xe0af4bd7,
+	///  or in textual repr: allowanceCross((address,uint256),(address,uint256))
+	function allowanceCross(CrossAddress memory owner, CrossAddress memory spender) public view returns (uint256) {
+		require(false, stub_error);
+		owner;
+		spender;
+		dummy;
+		return 0;
+	}
+
 	/// @notice A description for the collection.
 	/// @dev EVM selector for this function is: 0x7284e416,
 	///  or in textual repr: description()
@@ -576,7 +590,7 @@
 	/// @param amounts array of pairs of account address and amount
 	/// @dev EVM selector for this function is: 0x1acf2d55,
 	///  or in textual repr: mintBulk((address,uint256)[])
-	function mintBulk(Tuple9[] memory amounts) public returns (bool) {
+	function mintBulk(Tuple11[] memory amounts) public returns (bool) {
 		require(false, stub_error);
 		amounts;
 		dummy = 0;
@@ -619,7 +633,7 @@
 }
 
 /// @dev anonymous struct
-struct Tuple9 {
+struct Tuple11 {
 	address field_0;
 	uint256 field_1;
 }
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/CHANGELOG.mddiffbeforeafterboth
--- a/pallets/refungible/CHANGELOG.md
+++ b/pallets/refungible/CHANGELOG.md
@@ -4,6 +4,12 @@
 
 <!-- bureaucrate goes here -->
 
+## [0.2.13] - 2023-02-01
+
+### Added
+
+- The functions `allowanceCross` to `ERC20UniqueExtensions` interface.
+
 ## [0.2.12] - 2023-01-20
 
 ### Fixed
modifiedpallets/refungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/refungible/Cargo.toml
+++ b/pallets/refungible/Cargo.toml
@@ -2,7 +2,7 @@
 edition = "2021"
 license = "GPLv3"
 name = "pallet-refungible"
-version = "0.2.12"
+version = "0.2.13"
 
 [dependencies]
 # Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
modifiedpallets/refungible/src/erc_token.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -203,6 +203,21 @@
 where
 	T::AccountId: From<[u8; 32]>,
 {
+	/// @dev Function to check the amount of tokens that an owner allowed to a spender.
+	/// @param owner crossAddress The address which owns the funds.
+	/// @param spender crossAddress The address which will spend the funds.
+	/// @return A uint256 specifying the amount of tokens still available for the spender.
+	fn allowance_cross(
+		&self,
+		owner: pallet_common::eth::CrossAddress,
+		spender: pallet_common::eth::CrossAddress,
+	) -> Result<U256> {
+		let owner = owner.into_sub_cross_account::<T>()?;
+		let spender = spender.into_sub_cross_account::<T>()?;
+
+		Ok(<Allowance<T>>::get((self.id, self.1, owner, spender)).into())
+	}
+
 	/// @dev Function that burns an amount of the token of a given account,
 	/// deducting from the sender's allowance for said account.
 	/// @param from The account whose tokens will be burnt.
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
@@ -36,8 +36,22 @@
 	}
 }
 
-/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b
+/// @dev the ERC-165 identifier for this interface is 0x01d536fc
 contract ERC20UniqueExtensions is Dummy, ERC165 {
+	/// @dev Function to check the amount of tokens that an owner allowed to a spender.
+	/// @param owner crossAddress The address which owns the funds.
+	/// @param spender crossAddress The address which will spend the funds.
+	/// @return A uint256 specifying the amount of tokens still available for the spender.
+	/// @dev EVM selector for this function is: 0xe0af4bd7,
+	///  or in textual repr: allowanceCross((address,uint256),(address,uint256))
+	function allowanceCross(CrossAddress memory owner, CrossAddress memory spender) public view returns (uint256) {
+		require(false, stub_error);
+		owner;
+		spender;
+		dummy;
+		return 0;
+	}
+
 	// /// @dev Function that burns an amount of the token of a given account,
 	// /// deducting from the sender's allowance for said account.
 	// /// @param from The account whose tokens will be burnt.
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedruntime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth
--- a/runtime/common/ethereum/sponsoring/refungible.rs
+++ b/runtime/common/ethereum/sponsoring/refungible.rs
@@ -341,7 +341,9 @@
 			ERC165Call(_, _) => None,
 
 			// Not sponsored
-			BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => None,
+			AllowanceCross { .. } | BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => {
+				None
+			}
 
 			TransferCross { .. } | TransferFromCross { .. } => {
 				let RefungibleTokenHandle(handle, token_id) = token;
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 CrossAddress",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 CrossAddress",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 CrossAddress",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 CrossAddress",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 CrossAddress",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 CrossAddress",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 CrossAddress[]",195        "name": "",196        "type": "tuple[]"197      }198    ],199    "stateMutability": "view",200    "type": "function"201  },202  {203    "inputs": [],204    "name": "collectionHelperAddress",205    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],206    "stateMutability": "view",207    "type": "function"208  },209  {210    "inputs": [],211    "name": "collectionLimits",212    "outputs": [213      {214        "components": [215          {216            "internalType": "enum CollectionLimitField",217            "name": "field",218            "type": "uint8"219          },220          {221            "components": [222              { "internalType": "bool", "name": "status", "type": "bool" },223              { "internalType": "uint256", "name": "value", "type": "uint256" }224            ],225            "internalType": "struct OptionUint256",226            "name": "value",227            "type": "tuple"228          }229        ],230        "internalType": "struct CollectionLimit[]",231        "name": "",232        "type": "tuple[]"233      }234    ],235    "stateMutability": "view",236    "type": "function"237  },238  {239    "inputs": [],240    "name": "collectionNestingPermissions",241    "outputs": [242      {243        "components": [244          {245            "internalType": "enum CollectionPermissionField",246            "name": "field",247            "type": "uint8"248          },249          { "internalType": "bool", "name": "value", "type": "bool" }250        ],251        "internalType": "struct CollectionNestingPermission[]",252        "name": "",253        "type": "tuple[]"254      }255    ],256    "stateMutability": "view",257    "type": "function"258  },259  {260    "inputs": [],261    "name": "collectionNestingRestrictedCollectionIds",262    "outputs": [263      {264        "components": [265          { "internalType": "bool", "name": "token_owner", "type": "bool" },266          { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }267        ],268        "internalType": "struct CollectionNesting",269        "name": "",270        "type": "tuple"271      }272    ],273    "stateMutability": "view",274    "type": "function"275  },276  {277    "inputs": [],278    "name": "collectionOwner",279    "outputs": [280      {281        "components": [282          { "internalType": "address", "name": "eth", "type": "address" },283          { "internalType": "uint256", "name": "sub", "type": "uint256" }284        ],285        "internalType": "struct CrossAddress",286        "name": "",287        "type": "tuple"288      }289    ],290    "stateMutability": "view",291    "type": "function"292  },293  {294    "inputs": [295      { "internalType": "string[]", "name": "keys", "type": "string[]" }296    ],297    "name": "collectionProperties",298    "outputs": [299      {300        "components": [301          { "internalType": "string", "name": "key", "type": "string" },302          { "internalType": "bytes", "name": "value", "type": "bytes" }303        ],304        "internalType": "struct Property[]",305        "name": "",306        "type": "tuple[]"307      }308    ],309    "stateMutability": "view",310    "type": "function"311  },312  {313    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],314    "name": "collectionProperty",315    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],316    "stateMutability": "view",317    "type": "function"318  },319  {320    "inputs": [],321    "name": "collectionSponsor",322    "outputs": [323      {324        "components": [325          { "internalType": "address", "name": "eth", "type": "address" },326          { "internalType": "uint256", "name": "sub", "type": "uint256" }327        ],328        "internalType": "struct CrossAddress",329        "name": "",330        "type": "tuple"331      }332    ],333    "stateMutability": "view",334    "type": "function"335  },336  {337    "inputs": [],338    "name": "confirmCollectionSponsorship",339    "outputs": [],340    "stateMutability": "nonpayable",341    "type": "function"342  },343  {344    "inputs": [],345    "name": "contractAddress",346    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],347    "stateMutability": "view",348    "type": "function"349  },350  {351    "inputs": [],352    "name": "decimals",353    "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],354    "stateMutability": "view",355    "type": "function"356  },357  {358    "inputs": [359      { "internalType": "string[]", "name": "keys", "type": "string[]" }360    ],361    "name": "deleteCollectionProperties",362    "outputs": [],363    "stateMutability": "nonpayable",364    "type": "function"365  },366  {367    "inputs": [],368    "name": "description",369    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],370    "stateMutability": "view",371    "type": "function"372  },373  {374    "inputs": [],375    "name": "hasCollectionPendingSponsor",376    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],377    "stateMutability": "view",378    "type": "function"379  },380  {381    "inputs": [382      {383        "components": [384          { "internalType": "address", "name": "eth", "type": "address" },385          { "internalType": "uint256", "name": "sub", "type": "uint256" }386        ],387        "internalType": "struct CrossAddress",388        "name": "user",389        "type": "tuple"390      }391    ],392    "name": "isOwnerOrAdminCross",393    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],394    "stateMutability": "view",395    "type": "function"396  },397  {398    "inputs": [399      { "internalType": "address", "name": "to", "type": "address" },400      { "internalType": "uint256", "name": "amount", "type": "uint256" }401    ],402    "name": "mint",403    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],404    "stateMutability": "nonpayable",405    "type": "function"406  },407  {408    "inputs": [409      {410        "components": [411          { "internalType": "address", "name": "field_0", "type": "address" },412          { "internalType": "uint256", "name": "field_1", "type": "uint256" }413        ],414        "internalType": "struct Tuple9[]",415        "name": "amounts",416        "type": "tuple[]"417      }418    ],419    "name": "mintBulk",420    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],421    "stateMutability": "nonpayable",422    "type": "function"423  },424  {425    "inputs": [426      {427        "components": [428          { "internalType": "address", "name": "eth", "type": "address" },429          { "internalType": "uint256", "name": "sub", "type": "uint256" }430        ],431        "internalType": "struct CrossAddress",432        "name": "to",433        "type": "tuple"434      },435      { "internalType": "uint256", "name": "amount", "type": "uint256" }436    ],437    "name": "mintCross",438    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],439    "stateMutability": "nonpayable",440    "type": "function"441  },442  {443    "inputs": [],444    "name": "name",445    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],446    "stateMutability": "view",447    "type": "function"448  },449  {450    "inputs": [451      {452        "components": [453          { "internalType": "address", "name": "eth", "type": "address" },454          { "internalType": "uint256", "name": "sub", "type": "uint256" }455        ],456        "internalType": "struct CrossAddress",457        "name": "admin",458        "type": "tuple"459      }460    ],461    "name": "removeCollectionAdminCross",462    "outputs": [],463    "stateMutability": "nonpayable",464    "type": "function"465  },466  {467    "inputs": [],468    "name": "removeCollectionSponsor",469    "outputs": [],470    "stateMutability": "nonpayable",471    "type": "function"472  },473  {474    "inputs": [475      {476        "components": [477          { "internalType": "address", "name": "eth", "type": "address" },478          { "internalType": "uint256", "name": "sub", "type": "uint256" }479        ],480        "internalType": "struct CrossAddress",481        "name": "user",482        "type": "tuple"483      }484    ],485    "name": "removeFromCollectionAllowListCross",486    "outputs": [],487    "stateMutability": "nonpayable",488    "type": "function"489  },490  {491    "inputs": [492      { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" }493    ],494    "name": "setCollectionAccess",495    "outputs": [],496    "stateMutability": "nonpayable",497    "type": "function"498  },499  {500    "inputs": [501      {502        "components": [503          {504            "internalType": "enum CollectionLimitField",505            "name": "field",506            "type": "uint8"507          },508          {509            "components": [510              { "internalType": "bool", "name": "status", "type": "bool" },511              { "internalType": "uint256", "name": "value", "type": "uint256" }512            ],513            "internalType": "struct OptionUint256",514            "name": "value",515            "type": "tuple"516          }517        ],518        "internalType": "struct CollectionLimit",519        "name": "limit",520        "type": "tuple"521      }522    ],523    "name": "setCollectionLimit",524    "outputs": [],525    "stateMutability": "nonpayable",526    "type": "function"527  },528  {529    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],530    "name": "setCollectionMintMode",531    "outputs": [],532    "stateMutability": "nonpayable",533    "type": "function"534  },535  {536    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],537    "name": "setCollectionNesting",538    "outputs": [],539    "stateMutability": "nonpayable",540    "type": "function"541  },542  {543    "inputs": [544      { "internalType": "bool", "name": "enable", "type": "bool" },545      {546        "internalType": "address[]",547        "name": "collections",548        "type": "address[]"549      }550    ],551    "name": "setCollectionNesting",552    "outputs": [],553    "stateMutability": "nonpayable",554    "type": "function"555  },556  {557    "inputs": [558      {559        "components": [560          { "internalType": "string", "name": "key", "type": "string" },561          { "internalType": "bytes", "name": "value", "type": "bytes" }562        ],563        "internalType": "struct Property[]",564        "name": "properties",565        "type": "tuple[]"566      }567    ],568    "name": "setCollectionProperties",569    "outputs": [],570    "stateMutability": "nonpayable",571    "type": "function"572  },573  {574    "inputs": [575      {576        "components": [577          { "internalType": "address", "name": "eth", "type": "address" },578          { "internalType": "uint256", "name": "sub", "type": "uint256" }579        ],580        "internalType": "struct CrossAddress",581        "name": "sponsor",582        "type": "tuple"583      }584    ],585    "name": "setCollectionSponsorCross",586    "outputs": [],587    "stateMutability": "nonpayable",588    "type": "function"589  },590  {591    "inputs": [592      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }593    ],594    "name": "supportsInterface",595    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],596    "stateMutability": "view",597    "type": "function"598  },599  {600    "inputs": [],601    "name": "symbol",602    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],603    "stateMutability": "view",604    "type": "function"605  },606  {607    "inputs": [],608    "name": "totalSupply",609    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],610    "stateMutability": "view",611    "type": "function"612  },613  {614    "inputs": [615      { "internalType": "address", "name": "to", "type": "address" },616      { "internalType": "uint256", "name": "amount", "type": "uint256" }617    ],618    "name": "transfer",619    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],620    "stateMutability": "nonpayable",621    "type": "function"622  },623  {624    "inputs": [625      {626        "components": [627          { "internalType": "address", "name": "eth", "type": "address" },628          { "internalType": "uint256", "name": "sub", "type": "uint256" }629        ],630        "internalType": "struct CrossAddress",631        "name": "to",632        "type": "tuple"633      },634      { "internalType": "uint256", "name": "amount", "type": "uint256" }635    ],636    "name": "transferCross",637    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],638    "stateMutability": "nonpayable",639    "type": "function"640  },641  {642    "inputs": [643      { "internalType": "address", "name": "from", "type": "address" },644      { "internalType": "address", "name": "to", "type": "address" },645      { "internalType": "uint256", "name": "amount", "type": "uint256" }646    ],647    "name": "transferFrom",648    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],649    "stateMutability": "nonpayable",650    "type": "function"651  },652  {653    "inputs": [654      {655        "components": [656          { "internalType": "address", "name": "eth", "type": "address" },657          { "internalType": "uint256", "name": "sub", "type": "uint256" }658        ],659        "internalType": "struct CrossAddress",660        "name": "from",661        "type": "tuple"662      },663      {664        "components": [665          { "internalType": "address", "name": "eth", "type": "address" },666          { "internalType": "uint256", "name": "sub", "type": "uint256" }667        ],668        "internalType": "struct CrossAddress",669        "name": "to",670        "type": "tuple"671      },672      { "internalType": "uint256", "name": "amount", "type": "uint256" }673    ],674    "name": "transferFromCross",675    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],676    "stateMutability": "nonpayable",677    "type": "function"678  },679  {680    "inputs": [],681    "name": "uniqueCollectionType",682    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],683    "stateMutability": "view",684    "type": "function"685  }686]
after · 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 CrossAddress",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 CrossAddress",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 CrossAddress",104        "name": "owner",105        "type": "tuple"106      },107      {108        "components": [109          { "internalType": "address", "name": "eth", "type": "address" },110          { "internalType": "uint256", "name": "sub", "type": "uint256" }111        ],112        "internalType": "struct CrossAddress",113        "name": "spender",114        "type": "tuple"115      }116    ],117    "name": "allowanceCross",118    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],119    "stateMutability": "view",120    "type": "function"121  },122  {123    "inputs": [124      {125        "components": [126          { "internalType": "address", "name": "eth", "type": "address" },127          { "internalType": "uint256", "name": "sub", "type": "uint256" }128        ],129        "internalType": "struct CrossAddress",130        "name": "user",131        "type": "tuple"132      }133    ],134    "name": "allowlistedCross",135    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],136    "stateMutability": "view",137    "type": "function"138  },139  {140    "inputs": [141      { "internalType": "address", "name": "spender", "type": "address" },142      { "internalType": "uint256", "name": "amount", "type": "uint256" }143    ],144    "name": "approve",145    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],146    "stateMutability": "nonpayable",147    "type": "function"148  },149  {150    "inputs": [151      {152        "components": [153          { "internalType": "address", "name": "eth", "type": "address" },154          { "internalType": "uint256", "name": "sub", "type": "uint256" }155        ],156        "internalType": "struct CrossAddress",157        "name": "spender",158        "type": "tuple"159      },160      { "internalType": "uint256", "name": "amount", "type": "uint256" }161    ],162    "name": "approveCross",163    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],164    "stateMutability": "nonpayable",165    "type": "function"166  },167  {168    "inputs": [169      { "internalType": "address", "name": "owner", "type": "address" }170    ],171    "name": "balanceOf",172    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],173    "stateMutability": "view",174    "type": "function"175  },176  {177    "inputs": [178      {179        "components": [180          { "internalType": "address", "name": "eth", "type": "address" },181          { "internalType": "uint256", "name": "sub", "type": "uint256" }182        ],183        "internalType": "struct CrossAddress",184        "name": "from",185        "type": "tuple"186      },187      { "internalType": "uint256", "name": "amount", "type": "uint256" }188    ],189    "name": "burnFromCross",190    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],191    "stateMutability": "nonpayable",192    "type": "function"193  },194  {195    "inputs": [196      {197        "components": [198          { "internalType": "address", "name": "eth", "type": "address" },199          { "internalType": "uint256", "name": "sub", "type": "uint256" }200        ],201        "internalType": "struct CrossAddress",202        "name": "newOwner",203        "type": "tuple"204      }205    ],206    "name": "changeCollectionOwnerCross",207    "outputs": [],208    "stateMutability": "nonpayable",209    "type": "function"210  },211  {212    "inputs": [],213    "name": "collectionAdmins",214    "outputs": [215      {216        "components": [217          { "internalType": "address", "name": "eth", "type": "address" },218          { "internalType": "uint256", "name": "sub", "type": "uint256" }219        ],220        "internalType": "struct CrossAddress[]",221        "name": "",222        "type": "tuple[]"223      }224    ],225    "stateMutability": "view",226    "type": "function"227  },228  {229    "inputs": [],230    "name": "collectionHelperAddress",231    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],232    "stateMutability": "view",233    "type": "function"234  },235  {236    "inputs": [],237    "name": "collectionLimits",238    "outputs": [239      {240        "components": [241          {242            "internalType": "enum CollectionLimitField",243            "name": "field",244            "type": "uint8"245          },246          {247            "components": [248              { "internalType": "bool", "name": "status", "type": "bool" },249              { "internalType": "uint256", "name": "value", "type": "uint256" }250            ],251            "internalType": "struct OptionUint256",252            "name": "value",253            "type": "tuple"254          }255        ],256        "internalType": "struct CollectionLimit[]",257        "name": "",258        "type": "tuple[]"259      }260    ],261    "stateMutability": "view",262    "type": "function"263  },264  {265    "inputs": [],266    "name": "collectionNestingPermissions",267    "outputs": [268      {269        "components": [270          {271            "internalType": "enum CollectionPermissionField",272            "name": "field",273            "type": "uint8"274          },275          { "internalType": "bool", "name": "value", "type": "bool" }276        ],277        "internalType": "struct CollectionNestingPermission[]",278        "name": "",279        "type": "tuple[]"280      }281    ],282    "stateMutability": "view",283    "type": "function"284  },285  {286    "inputs": [],287    "name": "collectionNestingRestrictedCollectionIds",288    "outputs": [289      {290        "components": [291          { "internalType": "bool", "name": "token_owner", "type": "bool" },292          { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }293        ],294        "internalType": "struct CollectionNesting",295        "name": "",296        "type": "tuple"297      }298    ],299    "stateMutability": "view",300    "type": "function"301  },302  {303    "inputs": [],304    "name": "collectionOwner",305    "outputs": [306      {307        "components": [308          { "internalType": "address", "name": "eth", "type": "address" },309          { "internalType": "uint256", "name": "sub", "type": "uint256" }310        ],311        "internalType": "struct CrossAddress",312        "name": "",313        "type": "tuple"314      }315    ],316    "stateMutability": "view",317    "type": "function"318  },319  {320    "inputs": [321      { "internalType": "string[]", "name": "keys", "type": "string[]" }322    ],323    "name": "collectionProperties",324    "outputs": [325      {326        "components": [327          { "internalType": "string", "name": "key", "type": "string" },328          { "internalType": "bytes", "name": "value", "type": "bytes" }329        ],330        "internalType": "struct Property[]",331        "name": "",332        "type": "tuple[]"333      }334    ],335    "stateMutability": "view",336    "type": "function"337  },338  {339    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],340    "name": "collectionProperty",341    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],342    "stateMutability": "view",343    "type": "function"344  },345  {346    "inputs": [],347    "name": "collectionSponsor",348    "outputs": [349      {350        "components": [351          { "internalType": "address", "name": "eth", "type": "address" },352          { "internalType": "uint256", "name": "sub", "type": "uint256" }353        ],354        "internalType": "struct CrossAddress",355        "name": "",356        "type": "tuple"357      }358    ],359    "stateMutability": "view",360    "type": "function"361  },362  {363    "inputs": [],364    "name": "confirmCollectionSponsorship",365    "outputs": [],366    "stateMutability": "nonpayable",367    "type": "function"368  },369  {370    "inputs": [],371    "name": "contractAddress",372    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],373    "stateMutability": "view",374    "type": "function"375  },376  {377    "inputs": [],378    "name": "decimals",379    "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],380    "stateMutability": "view",381    "type": "function"382  },383  {384    "inputs": [385      { "internalType": "string[]", "name": "keys", "type": "string[]" }386    ],387    "name": "deleteCollectionProperties",388    "outputs": [],389    "stateMutability": "nonpayable",390    "type": "function"391  },392  {393    "inputs": [],394    "name": "description",395    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],396    "stateMutability": "view",397    "type": "function"398  },399  {400    "inputs": [],401    "name": "hasCollectionPendingSponsor",402    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],403    "stateMutability": "view",404    "type": "function"405  },406  {407    "inputs": [408      {409        "components": [410          { "internalType": "address", "name": "eth", "type": "address" },411          { "internalType": "uint256", "name": "sub", "type": "uint256" }412        ],413        "internalType": "struct CrossAddress",414        "name": "user",415        "type": "tuple"416      }417    ],418    "name": "isOwnerOrAdminCross",419    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],420    "stateMutability": "view",421    "type": "function"422  },423  {424    "inputs": [425      { "internalType": "address", "name": "to", "type": "address" },426      { "internalType": "uint256", "name": "amount", "type": "uint256" }427    ],428    "name": "mint",429    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],430    "stateMutability": "nonpayable",431    "type": "function"432  },433  {434    "inputs": [435      {436        "components": [437          { "internalType": "address", "name": "field_0", "type": "address" },438          { "internalType": "uint256", "name": "field_1", "type": "uint256" }439        ],440        "internalType": "struct Tuple11[]",441        "name": "amounts",442        "type": "tuple[]"443      }444    ],445    "name": "mintBulk",446    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],447    "stateMutability": "nonpayable",448    "type": "function"449  },450  {451    "inputs": [452      {453        "components": [454          { "internalType": "address", "name": "eth", "type": "address" },455          { "internalType": "uint256", "name": "sub", "type": "uint256" }456        ],457        "internalType": "struct CrossAddress",458        "name": "to",459        "type": "tuple"460      },461      { "internalType": "uint256", "name": "amount", "type": "uint256" }462    ],463    "name": "mintCross",464    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],465    "stateMutability": "nonpayable",466    "type": "function"467  },468  {469    "inputs": [],470    "name": "name",471    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],472    "stateMutability": "view",473    "type": "function"474  },475  {476    "inputs": [477      {478        "components": [479          { "internalType": "address", "name": "eth", "type": "address" },480          { "internalType": "uint256", "name": "sub", "type": "uint256" }481        ],482        "internalType": "struct CrossAddress",483        "name": "admin",484        "type": "tuple"485      }486    ],487    "name": "removeCollectionAdminCross",488    "outputs": [],489    "stateMutability": "nonpayable",490    "type": "function"491  },492  {493    "inputs": [],494    "name": "removeCollectionSponsor",495    "outputs": [],496    "stateMutability": "nonpayable",497    "type": "function"498  },499  {500    "inputs": [501      {502        "components": [503          { "internalType": "address", "name": "eth", "type": "address" },504          { "internalType": "uint256", "name": "sub", "type": "uint256" }505        ],506        "internalType": "struct CrossAddress",507        "name": "user",508        "type": "tuple"509      }510    ],511    "name": "removeFromCollectionAllowListCross",512    "outputs": [],513    "stateMutability": "nonpayable",514    "type": "function"515  },516  {517    "inputs": [518      { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" }519    ],520    "name": "setCollectionAccess",521    "outputs": [],522    "stateMutability": "nonpayable",523    "type": "function"524  },525  {526    "inputs": [527      {528        "components": [529          {530            "internalType": "enum CollectionLimitField",531            "name": "field",532            "type": "uint8"533          },534          {535            "components": [536              { "internalType": "bool", "name": "status", "type": "bool" },537              { "internalType": "uint256", "name": "value", "type": "uint256" }538            ],539            "internalType": "struct OptionUint256",540            "name": "value",541            "type": "tuple"542          }543        ],544        "internalType": "struct CollectionLimit",545        "name": "limit",546        "type": "tuple"547      }548    ],549    "name": "setCollectionLimit",550    "outputs": [],551    "stateMutability": "nonpayable",552    "type": "function"553  },554  {555    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],556    "name": "setCollectionMintMode",557    "outputs": [],558    "stateMutability": "nonpayable",559    "type": "function"560  },561  {562    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],563    "name": "setCollectionNesting",564    "outputs": [],565    "stateMutability": "nonpayable",566    "type": "function"567  },568  {569    "inputs": [570      { "internalType": "bool", "name": "enable", "type": "bool" },571      {572        "internalType": "address[]",573        "name": "collections",574        "type": "address[]"575      }576    ],577    "name": "setCollectionNesting",578    "outputs": [],579    "stateMutability": "nonpayable",580    "type": "function"581  },582  {583    "inputs": [584      {585        "components": [586          { "internalType": "string", "name": "key", "type": "string" },587          { "internalType": "bytes", "name": "value", "type": "bytes" }588        ],589        "internalType": "struct Property[]",590        "name": "properties",591        "type": "tuple[]"592      }593    ],594    "name": "setCollectionProperties",595    "outputs": [],596    "stateMutability": "nonpayable",597    "type": "function"598  },599  {600    "inputs": [601      {602        "components": [603          { "internalType": "address", "name": "eth", "type": "address" },604          { "internalType": "uint256", "name": "sub", "type": "uint256" }605        ],606        "internalType": "struct CrossAddress",607        "name": "sponsor",608        "type": "tuple"609      }610    ],611    "name": "setCollectionSponsorCross",612    "outputs": [],613    "stateMutability": "nonpayable",614    "type": "function"615  },616  {617    "inputs": [618      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }619    ],620    "name": "supportsInterface",621    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],622    "stateMutability": "view",623    "type": "function"624  },625  {626    "inputs": [],627    "name": "symbol",628    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],629    "stateMutability": "view",630    "type": "function"631  },632  {633    "inputs": [],634    "name": "totalSupply",635    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],636    "stateMutability": "view",637    "type": "function"638  },639  {640    "inputs": [641      { "internalType": "address", "name": "to", "type": "address" },642      { "internalType": "uint256", "name": "amount", "type": "uint256" }643    ],644    "name": "transfer",645    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],646    "stateMutability": "nonpayable",647    "type": "function"648  },649  {650    "inputs": [651      {652        "components": [653          { "internalType": "address", "name": "eth", "type": "address" },654          { "internalType": "uint256", "name": "sub", "type": "uint256" }655        ],656        "internalType": "struct CrossAddress",657        "name": "to",658        "type": "tuple"659      },660      { "internalType": "uint256", "name": "amount", "type": "uint256" }661    ],662    "name": "transferCross",663    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],664    "stateMutability": "nonpayable",665    "type": "function"666  },667  {668    "inputs": [669      { "internalType": "address", "name": "from", "type": "address" },670      { "internalType": "address", "name": "to", "type": "address" },671      { "internalType": "uint256", "name": "amount", "type": "uint256" }672    ],673    "name": "transferFrom",674    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],675    "stateMutability": "nonpayable",676    "type": "function"677  },678  {679    "inputs": [680      {681        "components": [682          { "internalType": "address", "name": "eth", "type": "address" },683          { "internalType": "uint256", "name": "sub", "type": "uint256" }684        ],685        "internalType": "struct CrossAddress",686        "name": "from",687        "type": "tuple"688      },689      {690        "components": [691          { "internalType": "address", "name": "eth", "type": "address" },692          { "internalType": "uint256", "name": "sub", "type": "uint256" }693        ],694        "internalType": "struct CrossAddress",695        "name": "to",696        "type": "tuple"697      },698      { "internalType": "uint256", "name": "amount", "type": "uint256" }699    ],700    "name": "transferFromCross",701    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],702    "stateMutability": "nonpayable",703    "type": "function"704  },705  {706    "inputs": [],707    "name": "uniqueCollectionType",708    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],709    "stateMutability": "view",710    "type": "function"711  }712]
modifiedtests/src/eth/abi/reFungibleToken.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungibleToken.json
+++ b/tests/src/eth/abi/reFungibleToken.json
@@ -61,6 +61,32 @@
   },
   {
     "inputs": [
+      {
+        "components": [
+          { "internalType": "address", "name": "eth", "type": "address" },
+          { "internalType": "uint256", "name": "sub", "type": "uint256" }
+        ],
+        "internalType": "struct CrossAddress",
+        "name": "owner",
+        "type": "tuple"
+      },
+      {
+        "components": [
+          { "internalType": "address", "name": "eth", "type": "address" },
+          { "internalType": "uint256", "name": "sub", "type": "uint256" }
+        ],
+        "internalType": "struct CrossAddress",
+        "name": "spender",
+        "type": "tuple"
+      }
+    ],
+    "name": "allowanceCross",
+    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [
       { "internalType": "address", "name": "spender", "type": "address" },
       { "internalType": "uint256", "name": "amount", "type": "uint256" }
     ],
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -353,8 +353,16 @@
 	bytes value;
 }
 
-/// @dev the ERC-165 identifier for this interface is 0x65789571
+/// @dev the ERC-165 identifier for this interface is 0x85d7dea6
 interface ERC20UniqueExtensions is Dummy, ERC165 {
+	/// @dev Function to check the amount of tokens that an owner allowed to a spender.
+	/// @param owner crossAddress The address which owns the funds.
+	/// @param spender crossAddress The address which will spend the funds.
+	/// @return A uint256 specifying the amount of tokens still available for the spender.
+	/// @dev EVM selector for this function is: 0xe0af4bd7,
+	///  or in textual repr: allowanceCross((address,uint256),(address,uint256))
+	function allowanceCross(CrossAddress memory owner, CrossAddress memory spender) external view returns (uint256);
+
 	/// @notice A description for the collection.
 	/// @dev EVM selector for this function is: 0x7284e416,
 	///  or in textual repr: description()
@@ -390,7 +398,7 @@
 	/// @param amounts array of pairs of account address and amount
 	/// @dev EVM selector for this function is: 0x1acf2d55,
 	///  or in textual repr: mintBulk((address,uint256)[])
-	function mintBulk(Tuple9[] memory amounts) external returns (bool);
+	function mintBulk(Tuple11[] memory amounts) external returns (bool);
 
 	/// @dev EVM selector for this function is: 0x2ada85ff,
 	///  or in textual repr: transferCross((address,uint256),uint256)
@@ -411,7 +419,7 @@
 }
 
 /// @dev anonymous struct
-struct Tuple9 {
+struct Tuple11 {
 	address field_0;
 	uint256 field_1;
 }
modifiedtests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungibleToken.sol
+++ b/tests/src/eth/api/UniqueRefungibleToken.sol
@@ -23,8 +23,16 @@
 	function parentTokenId() external view returns (uint256);
 }
 
-/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b
+/// @dev the ERC-165 identifier for this interface is 0x01d536fc
 interface ERC20UniqueExtensions is Dummy, ERC165 {
+	/// @dev Function to check the amount of tokens that an owner allowed to a spender.
+	/// @param owner crossAddress The address which owns the funds.
+	/// @param spender crossAddress The address which will spend the funds.
+	/// @return A uint256 specifying the amount of tokens still available for the spender.
+	/// @dev EVM selector for this function is: 0xe0af4bd7,
+	///  or in textual repr: allowanceCross((address,uint256),(address,uint256))
+	function allowanceCross(CrossAddress memory owner, CrossAddress memory spender) external view returns (uint256);
+
 	// /// @dev Function that burns an amount of the token of a given account,
 	// /// deducting from the sender's allowance for said account.
 	// /// @param from The account whose tokens will be burnt.
modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -134,6 +134,12 @@
       const allowance = await contract.methods.allowance(owner, spender).call();
       expect(+allowance).to.equal(100);
     }
+    {
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      const spenderCross = helper.ethCrossAccount.fromAddress(spender);
+      const allowance = await contract.methods.allowanceCross(ownerCross, spenderCross).call();
+      expect(+allowance).to.equal(100);
+    }
   });
 
   itEth('Can perform approveCross()', async ({helper}) => {
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -219,8 +219,16 @@
       await rftToken.methods.approve(operator, 15n).send({from: owner});
       await contract.methods.setApprovalForAll(operator, true).send({from: owner});
       await rftToken.methods.burnFrom(owner, 10n).send({from: operator});
+    }
+    {
       const allowance = await rftToken.methods.allowance(owner, operator).call();
-      expect(allowance).to.be.equal('5');
+      expect(+allowance).to.be.equal(5);
+    }
+    {
+      const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+      const operatorCross = helper.ethCrossAccount.fromAddress(operator);
+      const allowance = await rftToken.methods.allowanceCross(ownerCross, operatorCross).call();
+      expect(+allowance).to.equal(5);
     }
   });