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]
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);
     }
   });