difftreelog
Merge pull request #574 from UniqueNetwork/feature/eth_passthrought
in: master
Feature/eth passthrought
19 files changed
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -20,6 +20,7 @@
solidity_interface, solidity, ToLog,
types::*,
execution::{Result, Error},
+ weight,
};
pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};
use pallet_evm_coder_substrate::dispatch_to_evm;
@@ -31,8 +32,12 @@
use alloc::format;
use crate::{
- Pallet, CollectionHandle, Config, CollectionProperties,
- eth::{convert_cross_account_to_uint256, convert_uint256_to_cross_account},
+ Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
+ eth::{
+ convert_cross_account_to_uint256, convert_uint256_to_cross_account,
+ convert_cross_account_to_tuple,
+ },
+ weights::WeightInfo,
};
/// Events for ethereum collection helper.
@@ -69,6 +74,7 @@
///
/// @param key Property key.
/// @param value Propery value.
+ #[weight(<SelfWeightOf<T>>::set_collection_properties(1))]
fn set_collection_property(
&mut self,
caller: caller,
@@ -88,7 +94,10 @@
/// Delete collection property.
///
/// @param key Property key.
+ #[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]
fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let key = <Vec<u8>>::from(key)
.try_into()
@@ -120,6 +129,8 @@
///
/// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
check_is_owner_or_admin(caller, self)?;
let sponsor = T::CrossAccountId::from_eth(sponsor);
@@ -138,6 +149,8 @@
caller: caller,
sponsor: uint256,
) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
check_is_owner_or_admin(caller, self)?;
let sponsor = convert_uint256_to_cross_account::<T>(sponsor);
@@ -146,7 +159,7 @@
save(self)
}
- // /// Whether there is a pending sponsor.
+ /// Whether there is a pending sponsor.
fn has_collection_pending_sponsor(&self) -> Result<bool> {
Ok(matches!(
self.collection.sponsorship,
@@ -158,6 +171,8 @@
///
/// @dev After setting the sponsor for the collection, it must be confirmed with this function.
fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {
+ self.consume_store_writes(1)?;
+
let caller = T::CrossAccountId::from_eth(caller);
if !self
.confirm_sponsorship(caller.as_sub())
@@ -170,6 +185,7 @@
/// Remove collection sponsor.
fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
check_is_owner_or_admin(caller, self)?;
self.remove_sponsor().map_err(dispatch_to_evm::<T>)?;
save(self)
@@ -206,6 +222,8 @@
/// @param value Value of the limit.
#[solidity(rename_selector = "setCollectionLimit")]
fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
check_is_owner_or_admin(caller, self)?;
let mut limits = self.limits.clone();
@@ -249,6 +267,8 @@
/// @param value Value of the limit.
#[solidity(rename_selector = "setCollectionLimit")]
fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
check_is_owner_or_admin(caller, self)?;
let mut limits = self.limits.clone();
@@ -275,7 +295,7 @@
}
/// Get contract address.
- fn contract_address(&self, _caller: caller) -> Result<address> {
+ fn contract_address(&self) -> Result<address> {
Ok(crate::eth::collection_id_to_address(self.id))
}
@@ -286,6 +306,8 @@
caller: caller,
new_admin: uint256,
) -> Result<void> {
+ self.consume_store_writes(2)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let new_admin = convert_uint256_to_cross_account::<T>(new_admin);
<Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
@@ -299,6 +321,8 @@
caller: caller,
admin: uint256,
) -> Result<void> {
+ self.consume_store_writes(2)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let admin = convert_uint256_to_cross_account::<T>(admin);
<Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
@@ -308,6 +332,8 @@
/// Add collection admin.
/// @param newAdmin Address of the added administrator.
fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {
+ self.consume_store_writes(2)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let new_admin = T::CrossAccountId::from_eth(new_admin);
<Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;
@@ -318,6 +344,8 @@
///
/// @param admin Address of the removed administrator.
fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {
+ self.consume_store_writes(2)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let admin = T::CrossAccountId::from_eth(admin);
<Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;
@@ -329,6 +357,8 @@
/// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
#[solidity(rename_selector = "setCollectionNesting")]
fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
check_is_owner_or_admin(caller, self)?;
let mut permissions = self.collection.permissions.clone();
@@ -358,6 +388,8 @@
enable: bool,
collections: Vec<address>,
) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
if collections.is_empty() {
return Err("no addresses provided".into());
}
@@ -401,6 +433,8 @@
/// 0 for Normal
/// 1 for AllowList
fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
check_is_owner_or_admin(caller, self)?;
let permissions = CollectionPermissions {
access: Some(match mode {
@@ -420,30 +454,78 @@
save(self)
}
+ /// Checks that user allowed to operate with collection.
+ ///
+ /// @param user User address to check.
+ fn allowed(&self, user: address) -> Result<bool> {
+ Ok(Pallet::<T>::allowed(
+ self.id,
+ T::CrossAccountId::from_eth(user),
+ ))
+ }
+
/// Add the user to the allowed list.
///
/// @param user Address of a trusted user.
fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
+ self.consume_store_writes(1)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let user = T::CrossAccountId::from_eth(user);
<Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
Ok(())
}
+ /// Add substrate user to allowed list.
+ ///
+ /// @param user User substrate address.
+ fn add_to_collection_allow_list_substrate(
+ &mut self,
+ caller: caller,
+ user: uint256,
+ ) -> Result<void> {
+ self.consume_store_writes(1)?;
+
+ let caller = T::CrossAccountId::from_eth(caller);
+ let user = convert_uint256_to_cross_account::<T>(user);
+ Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;
+ Ok(())
+ }
+
/// Remove the user from the allowed list.
///
/// @param user Address of a removed user.
fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
+ self.consume_store_writes(1)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let user = T::CrossAccountId::from_eth(user);
<Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
Ok(())
}
+ /// Remove substrate user from allowed list.
+ ///
+ /// @param user User substrate address.
+ fn remove_from_collection_allow_list_substrate(
+ &mut self,
+ caller: caller,
+ user: uint256,
+ ) -> Result<void> {
+ self.consume_store_writes(1)?;
+
+ let caller = T::CrossAccountId::from_eth(caller);
+ let user = convert_uint256_to_cross_account::<T>(user);
+ Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;
+ Ok(())
+ }
+
/// Switch permission for minting.
///
/// @param mode Enable if "true".
fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {
+ self.consume_store_reads_and_writes(1, 1)?;
+
check_is_owner_or_admin(caller, self)?;
let permissions = CollectionPermissions {
mint_mode: Some(mode),
@@ -481,7 +563,7 @@
/// Returns collection type
///
/// @return `Fungible` or `NFT` or `ReFungible`
- fn unique_collection_type(&mut self) -> Result<string> {
+ fn unique_collection_type(&self) -> Result<string> {
let mode = match self.collection.mode {
CollectionMode::Fungible(_) => "Fungible",
CollectionMode::NFT => "NFT",
@@ -490,11 +572,23 @@
Ok(mode.into())
}
+ /// Get collection owner.
+ ///
+ /// @return Tuble with sponsor address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ fn collection_owner(&self) -> Result<(address, uint256)> {
+ Ok(convert_cross_account_to_tuple::<T>(
+ &T::CrossAccountId::from_sub(self.owner.clone()),
+ ))
+ }
+
/// Changes collection owner to another account
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {
+ self.consume_store_writes(1)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let new_owner = T::CrossAccountId::from_eth(new_owner);
self.set_owner_internal(caller, new_owner)
@@ -506,13 +600,25 @@
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner substrate account
fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result<void> {
+ self.consume_store_writes(1)?;
+
let caller = T::CrossAccountId::from_eth(caller);
let new_owner = convert_uint256_to_cross_account::<T>(new_owner);
self.set_owner_internal(caller, new_owner)
.map_err(dispatch_to_evm::<T>)
}
+
+ // TODO: need implement AbiWriter for &Vec<T>
+ // fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
+ // let result = pallet_common::IsAdmin::<T>::iter_prefix((self.id,))
+ // .map(|(admin, _)| pallet_common::eth::convert_cross_account_to_tuple::<T>(&admin))
+ // .collect();
+ // Ok(result)
+ // }
}
+/// ### Note
+/// Do not forget to add: `self.consume_store_reads(1)?;`
fn check_is_owner_or_admin<T: Config>(
caller: caller,
collection: &CollectionHandle<T>,
@@ -524,9 +630,9 @@
Ok(caller)
}
+/// ### Note
+/// Do not forget to add: `self.consume_store_writes(1)?;`
fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {
- // TODO possibly delete for the lack of transaction
- collection.consume_store_writes(1)?;
collection
.check_is_internal()
.map_err(dispatch_to_evm::<T>)?;
pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -16,7 +16,7 @@
//! The module contains a number of functions for converting and checking ethereum identifiers.
-use evm_coder::types::uint256;
+use evm_coder::types::{uint256, address};
pub use pallet_evm::account::{Config, CrossAccountId};
use sp_core::H160;
use up_data_structs::CollectionId;
@@ -69,3 +69,19 @@
let account_id = T::AccountId::from(new_admin_arr);
T::CrossAccountId::from_sub(account_id)
}
+
+/// Convert `CrossAccountId` to `(address, uint256)`.
+pub fn convert_cross_account_to_tuple<T: Config>(
+ cross_account_id: &T::CrossAccountId,
+) -> (address, uint256)
+where
+ T::AccountId: AsRef<[u8; 32]>,
+{
+ if cross_account_id.is_canonical_substrate() {
+ let sub = convert_cross_account_to_uint256::<T>(cross_account_id);
+ (Default::default(), sub)
+ } else {
+ let eth = *cross_account_id.as_eth();
+ (eth, Default::default())
+ }
+}
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -112,7 +112,6 @@
RmrkBoundedTheme,
RmrkNftChild,
CollectionPermissions,
- SchemaVersion,
};
pub use pallet::*;
@@ -202,6 +201,21 @@
))
}
+ /// Consume gas for reading and writing.
+ pub fn consume_store_reads_and_writes(
+ &self,
+ reads: u64,
+ writes: u64,
+ ) -> evm_coder::execution::Result<()> {
+ let weight = <T as frame_system::Config>::DbWeight::get();
+ let reads = weight.read.saturating_mul(reads);
+ let writes = weight.read.saturating_mul(writes);
+ self.recorder
+ .consume_gas(T::GasWeightMapping::weight_to_gas(
+ reads.saturating_add(writes),
+ ))
+ }
+
/// Save collection to storage.
pub fn save(&self) -> DispatchResult {
<CollectionById<T>>::insert(self.id, &self.collection);
@@ -310,6 +324,8 @@
}
/// Changes collection owner to another account
+ /// #### Store read/writes
+ /// 1 writes
fn set_owner_internal(
&mut self,
caller: T::CrossAccountId,
@@ -1292,6 +1308,8 @@
}
/// Toggle `user` participation in the `collection`'s allow list.
+ /// #### Store read/writes
+ /// 1 writes
pub fn toggle_allowlist(
collection: &CollectionHandle<T>,
sender: &T::CrossAccountId,
@@ -1312,6 +1330,8 @@
}
/// Toggle `user` participation in the `collection`'s admin list.
+ /// #### Store read/writes
+ /// 2 writes
pub fn toggle_admin(
collection: &CollectionHandle<T>,
sender: &T::CrossAccountId,
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -172,14 +172,9 @@
fn get_sponsor(&self, contract_address: address) -> Result<(address, uint256)> {
let sponsor =
Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?;
- let result: (address, uint256) = if sponsor.is_canonical_substrate() {
- let sponsor = pallet_common::eth::convert_cross_account_to_uint256::<T>(&sponsor);
- (Default::default(), sponsor)
- } else {
- let sponsor = *sponsor.as_eth();
- (sponsor, Default::default())
- };
- Ok(result)
+ Ok(pallet_common::eth::convert_cross_account_to_tuple::<T>(
+ &sponsor,
+ ))
}
/// Check tat contract has confirmed sponsor.
pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -22,7 +22,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xe54be640
+/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -255,6 +255,18 @@
dummy = 0;
}
+ /// Checks that user allowed to operate with collection.
+ ///
+ /// @param user User address to check.
+ /// @dev EVM selector for this function is: 0xd63a8e11,
+ /// or in textual repr: allowed(address)
+ function allowed(address user) public view returns (bool) {
+ require(false, stub_error);
+ user;
+ dummy;
+ return false;
+ }
+
/// Add the user to the allowed list.
///
/// @param user Address of a trusted user.
@@ -266,6 +278,17 @@
dummy = 0;
}
+ /// Add substrate user to allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xd06ad267,
+ /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
+ function addToCollectionAllowListSubstrate(uint256 user) public {
+ require(false, stub_error);
+ user;
+ dummy = 0;
+ }
+
/// Remove the user from the allowed list.
///
/// @param user Address of a removed user.
@@ -277,6 +300,17 @@
dummy = 0;
}
+ /// Remove substrate user from allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xa31913ed,
+ /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
+ function removeFromCollectionAllowListSubstrate(uint256 user) public {
+ require(false, stub_error);
+ user;
+ dummy = 0;
+ }
+
/// Switch permission for minting.
///
/// @param mode Enable if "true".
@@ -325,6 +359,18 @@
return "";
}
+ /// Get collection owner.
+ ///
+ /// @return Tuble with sponsor address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0xdf727d3b,
+ /// or in textual repr: collectionOwner()
+ function collectionOwner() public view returns (Tuple6 memory) {
+ require(false, stub_error);
+ dummy;
+ return Tuple6(0x0000000000000000000000000000000000000000, 0);
+ }
+
/// Changes collection owner to another account
///
/// @dev Owner can be changed only by current owner
pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -99,7 +99,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xe54be640
+/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -332,6 +332,18 @@
dummy = 0;
}
+ /// Checks that user allowed to operate with collection.
+ ///
+ /// @param user User address to check.
+ /// @dev EVM selector for this function is: 0xd63a8e11,
+ /// or in textual repr: allowed(address)
+ function allowed(address user) public view returns (bool) {
+ require(false, stub_error);
+ user;
+ dummy;
+ return false;
+ }
+
/// Add the user to the allowed list.
///
/// @param user Address of a trusted user.
@@ -343,6 +355,17 @@
dummy = 0;
}
+ /// Add substrate user to allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xd06ad267,
+ /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
+ function addToCollectionAllowListSubstrate(uint256 user) public {
+ require(false, stub_error);
+ user;
+ dummy = 0;
+ }
+
/// Remove the user from the allowed list.
///
/// @param user Address of a removed user.
@@ -354,6 +377,17 @@
dummy = 0;
}
+ /// Remove substrate user from allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xa31913ed,
+ /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
+ function removeFromCollectionAllowListSubstrate(uint256 user) public {
+ require(false, stub_error);
+ user;
+ dummy = 0;
+ }
+
/// Switch permission for minting.
///
/// @param mode Enable if "true".
@@ -402,6 +436,18 @@
return "";
}
+ /// Get collection owner.
+ ///
+ /// @return Tuble with sponsor address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0xdf727d3b,
+ /// or in textual repr: collectionOwner()
+ function collectionOwner() public view returns (Tuple17 memory) {
+ require(false, stub_error);
+ dummy;
+ return Tuple17(0x0000000000000000000000000000000000000000, 0);
+ }
+
/// Changes collection owner to another account
///
/// @dev Owner can be changed only by current owner
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID)14 external15 view16 returns (bool)17 {18 require(false, stub_error);19 interfaceID;20 return true;21 }22}2324/// @title A contract that allows to set and delete token properties and change token property permissions.25/// @dev the ERC-165 identifier for this interface is 0x4136937726contract TokenProperties is Dummy, ERC165 {27 /// @notice Set permissions for token property.28 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.29 /// @param key Property key.30 /// @param isMutable Permission to mutate property.31 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.32 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.33 /// @dev EVM selector for this function is: 0x222d97fa,34 /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)35 function setTokenPropertyPermission(36 string memory key,37 bool isMutable,38 bool collectionAdmin,39 bool tokenOwner40 ) public {41 require(false, stub_error);42 key;43 isMutable;44 collectionAdmin;45 tokenOwner;46 dummy = 0;47 }4849 /// @notice Set token property value.50 /// @dev Throws error if `msg.sender` has no permission to edit the property.51 /// @param tokenId ID of the token.52 /// @param key Property key.53 /// @param value Property value.54 /// @dev EVM selector for this function is: 0x1752d67b,55 /// or in textual repr: setProperty(uint256,string,bytes)56 function setProperty(57 uint256 tokenId,58 string memory key,59 bytes memory value60 ) public {61 require(false, stub_error);62 tokenId;63 key;64 value;65 dummy = 0;66 }6768 /// @notice Delete token property value.69 /// @dev Throws error if `msg.sender` has no permission to edit the property.70 /// @param tokenId ID of the token.71 /// @param key Property key.72 /// @dev EVM selector for this function is: 0x066111d1,73 /// or in textual repr: deleteProperty(uint256,string)74 function deleteProperty(uint256 tokenId, string memory key) public {75 require(false, stub_error);76 tokenId;77 key;78 dummy = 0;79 }8081 /// @notice Get token property value.82 /// @dev Throws error if key not found83 /// @param tokenId ID of the token.84 /// @param key Property key.85 /// @return Property value bytes86 /// @dev EVM selector for this function is: 0x7228c327,87 /// or in textual repr: property(uint256,string)88 function property(uint256 tokenId, string memory key)89 public90 view91 returns (bytes memory)92 {93 require(false, stub_error);94 tokenId;95 key;96 dummy;97 return hex"";98 }99}100101/// @title A contract that allows you to work with collections.102/// @dev the ERC-165 identifier for this interface is 0xe54be640103contract Collection is Dummy, ERC165 {104 /// Set collection property.105 ///106 /// @param key Property key.107 /// @param value Propery value.108 /// @dev EVM selector for this function is: 0x2f073f66,109 /// or in textual repr: setCollectionProperty(string,bytes)110 function setCollectionProperty(string memory key, bytes memory value)111 public112 {113 require(false, stub_error);114 key;115 value;116 dummy = 0;117 }118119 /// Delete collection property.120 ///121 /// @param key Property key.122 /// @dev EVM selector for this function is: 0x7b7debce,123 /// or in textual repr: deleteCollectionProperty(string)124 function deleteCollectionProperty(string memory key) public {125 require(false, stub_error);126 key;127 dummy = 0;128 }129130 /// Get collection property.131 ///132 /// @dev Throws error if key not found.133 ///134 /// @param key Property key.135 /// @return bytes The property corresponding to the key.136 /// @dev EVM selector for this function is: 0xcf24fd6d,137 /// or in textual repr: collectionProperty(string)138 function collectionProperty(string memory key)139 public140 view141 returns (bytes memory)142 {143 require(false, stub_error);144 key;145 dummy;146 return hex"";147 }148149 /// Set the sponsor of the collection.150 ///151 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.152 ///153 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.154 /// @dev EVM selector for this function is: 0x7623402e,155 /// or in textual repr: setCollectionSponsor(address)156 function setCollectionSponsor(address sponsor) public {157 require(false, stub_error);158 sponsor;159 dummy = 0;160 }161162 /// Set the substrate sponsor of the collection.163 ///164 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.165 ///166 /// @param sponsor Substrate address of the sponsor from whose account funds will be debited for operations with the contract.167 /// @dev EVM selector for this function is: 0xc74d6751,168 /// or in textual repr: setCollectionSponsorSubstrate(uint256)169 function setCollectionSponsorSubstrate(uint256 sponsor) public {170 require(false, stub_error);171 sponsor;172 dummy = 0;173 }174175 /// @dev EVM selector for this function is: 0x058ac185,176 /// or in textual repr: hasCollectionPendingSponsor()177 function hasCollectionPendingSponsor() public view returns (bool) {178 require(false, stub_error);179 dummy;180 return false;181 }182183 /// Collection sponsorship confirmation.184 ///185 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.186 /// @dev EVM selector for this function is: 0x3c50e97a,187 /// or in textual repr: confirmCollectionSponsorship()188 function confirmCollectionSponsorship() public {189 require(false, stub_error);190 dummy = 0;191 }192193 /// Remove collection sponsor.194 /// @dev EVM selector for this function is: 0x6e0326a3,195 /// or in textual repr: removeCollectionSponsor()196 function removeCollectionSponsor() public {197 require(false, stub_error);198 dummy = 0;199 }200201 /// Get current sponsor.202 ///203 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.204 /// @dev EVM selector for this function is: 0xb66bbc14,205 /// or in textual repr: getCollectionSponsor()206 function getCollectionSponsor() public view returns (Tuple17 memory) {207 require(false, stub_error);208 dummy;209 return Tuple17(0x0000000000000000000000000000000000000000, 0);210 }211212 /// Set limits for the collection.213 /// @dev Throws error if limit not found.214 /// @param limit Name of the limit. Valid names:215 /// "accountTokenOwnershipLimit",216 /// "sponsoredDataSize",217 /// "sponsoredDataRateLimit",218 /// "tokenLimit",219 /// "sponsorTransferTimeout",220 /// "sponsorApproveTimeout"221 /// @param value Value of the limit.222 /// @dev EVM selector for this function is: 0x6a3841db,223 /// or in textual repr: setCollectionLimit(string,uint32)224 function setCollectionLimit(string memory limit, uint32 value) public {225 require(false, stub_error);226 limit;227 value;228 dummy = 0;229 }230231 /// Set limits for the collection.232 /// @dev Throws error if limit not found.233 /// @param limit Name of the limit. Valid names:234 /// "ownerCanTransfer",235 /// "ownerCanDestroy",236 /// "transfersEnabled"237 /// @param value Value of the limit.238 /// @dev EVM selector for this function is: 0x993b7fba,239 /// or in textual repr: setCollectionLimit(string,bool)240 function setCollectionLimit(string memory limit, bool value) public {241 require(false, stub_error);242 limit;243 value;244 dummy = 0;245 }246247 /// Get contract address.248 /// @dev EVM selector for this function is: 0xf6b4dfb4,249 /// or in textual repr: contractAddress()250 function contractAddress() public view returns (address) {251 require(false, stub_error);252 dummy;253 return 0x0000000000000000000000000000000000000000;254 }255256 /// Add collection admin by substrate address.257 /// @param newAdmin Substrate administrator address.258 /// @dev EVM selector for this function is: 0x5730062b,259 /// or in textual repr: addCollectionAdminSubstrate(uint256)260 function addCollectionAdminSubstrate(uint256 newAdmin) public {261 require(false, stub_error);262 newAdmin;263 dummy = 0;264 }265266 /// Remove collection admin by substrate address.267 /// @param admin Substrate administrator address.268 /// @dev EVM selector for this function is: 0x4048fcf9,269 /// or in textual repr: removeCollectionAdminSubstrate(uint256)270 function removeCollectionAdminSubstrate(uint256 admin) public {271 require(false, stub_error);272 admin;273 dummy = 0;274 }275276 /// Add collection admin.277 /// @param newAdmin Address of the added administrator.278 /// @dev EVM selector for this function is: 0x92e462c7,279 /// or in textual repr: addCollectionAdmin(address)280 function addCollectionAdmin(address newAdmin) public {281 require(false, stub_error);282 newAdmin;283 dummy = 0;284 }285286 /// Remove collection admin.287 ///288 /// @param admin Address of the removed administrator.289 /// @dev EVM selector for this function is: 0xfafd7b42,290 /// or in textual repr: removeCollectionAdmin(address)291 function removeCollectionAdmin(address admin) public {292 require(false, stub_error);293 admin;294 dummy = 0;295 }296297 /// Toggle accessibility of collection nesting.298 ///299 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'300 /// @dev EVM selector for this function is: 0x112d4586,301 /// or in textual repr: setCollectionNesting(bool)302 function setCollectionNesting(bool enable) public {303 require(false, stub_error);304 enable;305 dummy = 0;306 }307308 /// Toggle accessibility of collection nesting.309 ///310 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'311 /// @param collections Addresses of collections that will be available for nesting.312 /// @dev EVM selector for this function is: 0x64872396,313 /// or in textual repr: setCollectionNesting(bool,address[])314 function setCollectionNesting(bool enable, address[] memory collections)315 public316 {317 require(false, stub_error);318 enable;319 collections;320 dummy = 0;321 }322323 /// Set the collection access method.324 /// @param mode Access mode325 /// 0 for Normal326 /// 1 for AllowList327 /// @dev EVM selector for this function is: 0x41835d4c,328 /// or in textual repr: setCollectionAccess(uint8)329 function setCollectionAccess(uint8 mode) public {330 require(false, stub_error);331 mode;332 dummy = 0;333 }334335 /// Add the user to the allowed list.336 ///337 /// @param user Address of a trusted user.338 /// @dev EVM selector for this function is: 0x67844fe6,339 /// or in textual repr: addToCollectionAllowList(address)340 function addToCollectionAllowList(address user) public {341 require(false, stub_error);342 user;343 dummy = 0;344 }345346 /// Remove the user from the allowed list.347 ///348 /// @param user Address of a removed user.349 /// @dev EVM selector for this function is: 0x85c51acb,350 /// or in textual repr: removeFromCollectionAllowList(address)351 function removeFromCollectionAllowList(address user) public {352 require(false, stub_error);353 user;354 dummy = 0;355 }356357 /// Switch permission for minting.358 ///359 /// @param mode Enable if "true".360 /// @dev EVM selector for this function is: 0x00018e84,361 /// or in textual repr: setCollectionMintMode(bool)362 function setCollectionMintMode(bool mode) public {363 require(false, stub_error);364 mode;365 dummy = 0;366 }367368 /// Check that account is the owner or admin of the collection369 ///370 /// @param user account to verify371 /// @return "true" if account is the owner or admin372 /// @dev EVM selector for this function is: 0x9811b0c7,373 /// or in textual repr: isOwnerOrAdmin(address)374 function isOwnerOrAdmin(address user) public view returns (bool) {375 require(false, stub_error);376 user;377 dummy;378 return false;379 }380381 /// Check that substrate account is the owner or admin of the collection382 ///383 /// @param user account to verify384 /// @return "true" if account is the owner or admin385 /// @dev EVM selector for this function is: 0x68910e00,386 /// or in textual repr: isOwnerOrAdminSubstrate(uint256)387 function isOwnerOrAdminSubstrate(uint256 user) public view returns (bool) {388 require(false, stub_error);389 user;390 dummy;391 return false;392 }393394 /// Returns collection type395 ///396 /// @return `Fungible` or `NFT` or `ReFungible`397 /// @dev EVM selector for this function is: 0xd34b55b8,398 /// or in textual repr: uniqueCollectionType()399 function uniqueCollectionType() public returns (string memory) {400 require(false, stub_error);401 dummy = 0;402 return "";403 }404405 /// Changes collection owner to another account406 ///407 /// @dev Owner can be changed only by current owner408 /// @param newOwner new owner account409 /// @dev EVM selector for this function is: 0x13af4035,410 /// or in textual repr: setOwner(address)411 function setOwner(address newOwner) public {412 require(false, stub_error);413 newOwner;414 dummy = 0;415 }416417 /// Changes collection owner to another substrate account418 ///419 /// @dev Owner can be changed only by current owner420 /// @param newOwner new owner substrate account421 /// @dev EVM selector for this function is: 0xb212138f,422 /// or in textual repr: setOwnerSubstrate(uint256)423 function setOwnerSubstrate(uint256 newOwner) public {424 require(false, stub_error);425 newOwner;426 dummy = 0;427 }428}429430/// @dev anonymous struct431struct Tuple17 {432 address field_0;433 uint256 field_1;434}435436/// @title ERC721 Token that can be irreversibly burned (destroyed).437/// @dev the ERC-165 identifier for this interface is 0x42966c68438contract ERC721Burnable is Dummy, ERC165 {439 /// @notice Burns a specific ERC721 token.440 /// @dev Throws unless `msg.sender` is the current RFT owner, or an authorized441 /// operator of the current owner.442 /// @param tokenId The RFT to approve443 /// @dev EVM selector for this function is: 0x42966c68,444 /// or in textual repr: burn(uint256)445 function burn(uint256 tokenId) public {446 require(false, stub_error);447 tokenId;448 dummy = 0;449 }450}451452/// @dev inlined interface453contract ERC721MintableEvents {454 event MintingFinished();455}456457/// @title ERC721 minting logic.458/// @dev the ERC-165 identifier for this interface is 0x68ccfe89459contract ERC721Mintable is Dummy, ERC165, ERC721MintableEvents {460 /// @dev EVM selector for this function is: 0x05d2035b,461 /// or in textual repr: mintingFinished()462 function mintingFinished() public view returns (bool) {463 require(false, stub_error);464 dummy;465 return false;466 }467468 /// @notice Function to mint token.469 /// @dev `tokenId` should be obtained with `nextTokenId` method,470 /// unlike standard, you can't specify it manually471 /// @param to The new owner472 /// @param tokenId ID of the minted RFT473 /// @dev EVM selector for this function is: 0x40c10f19,474 /// or in textual repr: mint(address,uint256)475 function mint(address to, uint256 tokenId) public returns (bool) {476 require(false, stub_error);477 to;478 tokenId;479 dummy = 0;480 return false;481 }482483 /// @notice Function to mint token with the given tokenUri.484 /// @dev `tokenId` should be obtained with `nextTokenId` method,485 /// unlike standard, you can't specify it manually486 /// @param to The new owner487 /// @param tokenId ID of the minted RFT488 /// @param tokenUri Token URI that would be stored in the RFT properties489 /// @dev EVM selector for this function is: 0x50bb4e7f,490 /// or in textual repr: mintWithTokenURI(address,uint256,string)491 function mintWithTokenURI(492 address to,493 uint256 tokenId,494 string memory tokenUri495 ) public returns (bool) {496 require(false, stub_error);497 to;498 tokenId;499 tokenUri;500 dummy = 0;501 return false;502 }503504 /// @dev Not implemented505 /// @dev EVM selector for this function is: 0x7d64bcb4,506 /// or in textual repr: finishMinting()507 function finishMinting() public returns (bool) {508 require(false, stub_error);509 dummy = 0;510 return false;511 }512}513514/// @title Unique extensions for ERC721.515/// @dev the ERC-165 identifier for this interface is 0x7c3bef89516contract ERC721UniqueExtensions is Dummy, ERC165 {517 /// @notice Transfer ownership of an RFT518 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`519 /// is the zero address. Throws if `tokenId` is not a valid RFT.520 /// Throws if RFT pieces have multiple owners.521 /// @param to The new owner522 /// @param tokenId The RFT to transfer523 /// @dev EVM selector for this function is: 0xa9059cbb,524 /// or in textual repr: transfer(address,uint256)525 function transfer(address to, uint256 tokenId) public {526 require(false, stub_error);527 to;528 tokenId;529 dummy = 0;530 }531532 /// @notice Burns a specific ERC721 token.533 /// @dev Throws unless `msg.sender` is the current owner or an authorized534 /// operator for this RFT. Throws if `from` is not the current owner. Throws535 /// if `to` is the zero address. Throws if `tokenId` is not a valid RFT.536 /// Throws if RFT pieces have multiple owners.537 /// @param from The current owner of the RFT538 /// @param tokenId The RFT to transfer539 /// @dev EVM selector for this function is: 0x79cc6790,540 /// or in textual repr: burnFrom(address,uint256)541 function burnFrom(address from, uint256 tokenId) public {542 require(false, stub_error);543 from;544 tokenId;545 dummy = 0;546 }547548 /// @notice Returns next free RFT ID.549 /// @dev EVM selector for this function is: 0x75794a3c,550 /// or in textual repr: nextTokenId()551 function nextTokenId() public view returns (uint256) {552 require(false, stub_error);553 dummy;554 return 0;555 }556557 /// @notice Function to mint multiple tokens.558 /// @dev `tokenIds` should be an array of consecutive numbers and first number559 /// should be obtained with `nextTokenId` method560 /// @param to The new owner561 /// @param tokenIds IDs of the minted RFTs562 /// @dev EVM selector for this function is: 0x44a9945e,563 /// or in textual repr: mintBulk(address,uint256[])564 function mintBulk(address to, uint256[] memory tokenIds)565 public566 returns (bool)567 {568 require(false, stub_error);569 to;570 tokenIds;571 dummy = 0;572 return false;573 }574575 /// @notice Function to mint multiple tokens with the given tokenUris.576 /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive577 /// numbers and first number should be obtained with `nextTokenId` method578 /// @param to The new owner579 /// @param tokens array of pairs of token ID and token URI for minted tokens580 /// @dev EVM selector for this function is: 0x36543006,581 /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])582 function mintBulkWithTokenURI(address to, Tuple8[] memory tokens)583 public584 returns (bool)585 {586 require(false, stub_error);587 to;588 tokens;589 dummy = 0;590 return false;591 }592593 /// Returns EVM address for refungible token594 ///595 /// @param token ID of the token596 /// @dev EVM selector for this function is: 0xab76fac6,597 /// or in textual repr: tokenContractAddress(uint256)598 function tokenContractAddress(uint256 token) public view returns (address) {599 require(false, stub_error);600 token;601 dummy;602 return 0x0000000000000000000000000000000000000000;603 }604}605606/// @dev anonymous struct607struct Tuple8 {608 uint256 field_0;609 string field_1;610}611612/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension613/// @dev See https://eips.ethereum.org/EIPS/eip-721614/// @dev the ERC-165 identifier for this interface is 0x780e9d63615contract ERC721Enumerable is Dummy, ERC165 {616 /// @notice Enumerate valid RFTs617 /// @param index A counter less than `totalSupply()`618 /// @return The token identifier for the `index`th NFT,619 /// (sort order not specified)620 /// @dev EVM selector for this function is: 0x4f6ccce7,621 /// or in textual repr: tokenByIndex(uint256)622 function tokenByIndex(uint256 index) public view returns (uint256) {623 require(false, stub_error);624 index;625 dummy;626 return 0;627 }628629 /// Not implemented630 /// @dev EVM selector for this function is: 0x2f745c59,631 /// or in textual repr: tokenOfOwnerByIndex(address,uint256)632 function tokenOfOwnerByIndex(address owner, uint256 index)633 public634 view635 returns (uint256)636 {637 require(false, stub_error);638 owner;639 index;640 dummy;641 return 0;642 }643644 /// @notice Count RFTs tracked by this contract645 /// @return A count of valid RFTs tracked by this contract, where each one of646 /// them has an assigned and queryable owner not equal to the zero address647 /// @dev EVM selector for this function is: 0x18160ddd,648 /// or in textual repr: totalSupply()649 function totalSupply() public view returns (uint256) {650 require(false, stub_error);651 dummy;652 return 0;653 }654}655656/// @dev the ERC-165 identifier for this interface is 0x5b5e139f657contract ERC721Metadata is Dummy, ERC165 {658 /// @notice A descriptive name for a collection of RFTs in this contract659 /// @dev EVM selector for this function is: 0x06fdde03,660 /// or in textual repr: name()661 function name() public view returns (string memory) {662 require(false, stub_error);663 dummy;664 return "";665 }666667 /// @notice An abbreviated name for RFTs in this contract668 /// @dev EVM selector for this function is: 0x95d89b41,669 /// or in textual repr: symbol()670 function symbol() public view returns (string memory) {671 require(false, stub_error);672 dummy;673 return "";674 }675676 /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.677 ///678 /// @dev If the token has a `url` property and it is not empty, it is returned.679 /// Else If the collection does not have a property with key `schemaName` or its value is not equal to `ERC721Metadata`, it return an error `tokenURI not set`.680 /// If the collection property `baseURI` is empty or absent, return "" (empty string)681 /// otherwise, if token property `suffix` present and is non-empty, return concatenation of baseURI and suffix682 /// otherwise, return concatenation of `baseURI` and stringified token id (decimal stringifying, without paddings).683 ///684 /// @return token's const_metadata685 /// @dev EVM selector for this function is: 0xc87b56dd,686 /// or in textual repr: tokenURI(uint256)687 function tokenURI(uint256 tokenId) public view returns (string memory) {688 require(false, stub_error);689 tokenId;690 dummy;691 return "";692 }693}694695/// @dev inlined interface696contract ERC721Events {697 event Transfer(698 address indexed from,699 address indexed to,700 uint256 indexed tokenId701 );702 event Approval(703 address indexed owner,704 address indexed approved,705 uint256 indexed tokenId706 );707 event ApprovalForAll(708 address indexed owner,709 address indexed operator,710 bool approved711 );712}713714/// @title ERC-721 Non-Fungible Token Standard715/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md716/// @dev the ERC-165 identifier for this interface is 0x58800161717contract ERC721 is Dummy, ERC165, ERC721Events {718 /// @notice Count all RFTs assigned to an owner719 /// @dev RFTs assigned to the zero address are considered invalid, and this720 /// function throws for queries about the zero address.721 /// @param owner An address for whom to query the balance722 /// @return The number of RFTs owned by `owner`, possibly zero723 /// @dev EVM selector for this function is: 0x70a08231,724 /// or in textual repr: balanceOf(address)725 function balanceOf(address owner) public view returns (uint256) {726 require(false, stub_error);727 owner;728 dummy;729 return 0;730 }731732 /// @notice Find the owner of an RFT733 /// @dev RFTs assigned to zero address are considered invalid, and queries734 /// about them do throw.735 /// Returns special 0xffffffffffffffffffffffffffffffffffffffff address for736 /// the tokens that are partially owned.737 /// @param tokenId The identifier for an RFT738 /// @return The address of the owner of the RFT739 /// @dev EVM selector for this function is: 0x6352211e,740 /// or in textual repr: ownerOf(uint256)741 function ownerOf(uint256 tokenId) public view returns (address) {742 require(false, stub_error);743 tokenId;744 dummy;745 return 0x0000000000000000000000000000000000000000;746 }747748 /// @dev Not implemented749 /// @dev EVM selector for this function is: 0x60a11672,750 /// or in textual repr: safeTransferFromWithData(address,address,uint256,bytes)751 function safeTransferFromWithData(752 address from,753 address to,754 uint256 tokenId,755 bytes memory data756 ) public {757 require(false, stub_error);758 from;759 to;760 tokenId;761 data;762 dummy = 0;763 }764765 /// @dev Not implemented766 /// @dev EVM selector for this function is: 0x42842e0e,767 /// or in textual repr: safeTransferFrom(address,address,uint256)768 function safeTransferFrom(769 address from,770 address to,771 uint256 tokenId772 ) public {773 require(false, stub_error);774 from;775 to;776 tokenId;777 dummy = 0;778 }779780 /// @notice Transfer ownership of an RFT -- THE CALLER IS RESPONSIBLE781 /// TO CONFIRM THAT `to` IS CAPABLE OF RECEIVING NFTS OR ELSE782 /// THEY MAY BE PERMANENTLY LOST783 /// @dev Throws unless `msg.sender` is the current owner or an authorized784 /// operator for this RFT. Throws if `from` is not the current owner. Throws785 /// if `to` is the zero address. Throws if `tokenId` is not a valid RFT.786 /// Throws if RFT pieces have multiple owners.787 /// @param from The current owner of the NFT788 /// @param to The new owner789 /// @param tokenId The NFT to transfer790 /// @dev EVM selector for this function is: 0x23b872dd,791 /// or in textual repr: transferFrom(address,address,uint256)792 function transferFrom(793 address from,794 address to,795 uint256 tokenId796 ) public {797 require(false, stub_error);798 from;799 to;800 tokenId;801 dummy = 0;802 }803804 /// @dev Not implemented805 /// @dev EVM selector for this function is: 0x095ea7b3,806 /// or in textual repr: approve(address,uint256)807 function approve(address approved, uint256 tokenId) public {808 require(false, stub_error);809 approved;810 tokenId;811 dummy = 0;812 }813814 /// @dev Not implemented815 /// @dev EVM selector for this function is: 0xa22cb465,816 /// or in textual repr: setApprovalForAll(address,bool)817 function setApprovalForAll(address operator, bool approved) public {818 require(false, stub_error);819 operator;820 approved;821 dummy = 0;822 }823824 /// @dev Not implemented825 /// @dev EVM selector for this function is: 0x081812fc,826 /// or in textual repr: getApproved(uint256)827 function getApproved(uint256 tokenId) public view returns (address) {828 require(false, stub_error);829 tokenId;830 dummy;831 return 0x0000000000000000000000000000000000000000;832 }833834 /// @dev Not implemented835 /// @dev EVM selector for this function is: 0xe985e9c5,836 /// or in textual repr: isApprovedForAll(address,address)837 function isApprovedForAll(address owner, address operator)838 public839 view840 returns (address)841 {842 require(false, stub_error);843 owner;844 operator;845 dummy;846 return 0x0000000000000000000000000000000000000000;847 }848}849850contract UniqueRefungible is851 Dummy,852 ERC165,853 ERC721,854 ERC721Metadata,855 ERC721Enumerable,856 ERC721UniqueExtensions,857 ERC721Mintable,858 ERC721Burnable,859 Collection,860 TokenProperties861{}1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID)14 external15 view16 returns (bool)17 {18 require(false, stub_error);19 interfaceID;20 return true;21 }22}2324/// @title A contract that allows to set and delete token properties and change token property permissions.25/// @dev the ERC-165 identifier for this interface is 0x4136937726contract TokenProperties is Dummy, ERC165 {27 /// @notice Set permissions for token property.28 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.29 /// @param key Property key.30 /// @param isMutable Permission to mutate property.31 /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.32 /// @param tokenOwner Permission to mutate property by token owner if property is mutable.33 /// @dev EVM selector for this function is: 0x222d97fa,34 /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)35 function setTokenPropertyPermission(36 string memory key,37 bool isMutable,38 bool collectionAdmin,39 bool tokenOwner40 ) public {41 require(false, stub_error);42 key;43 isMutable;44 collectionAdmin;45 tokenOwner;46 dummy = 0;47 }4849 /// @notice Set token property value.50 /// @dev Throws error if `msg.sender` has no permission to edit the property.51 /// @param tokenId ID of the token.52 /// @param key Property key.53 /// @param value Property value.54 /// @dev EVM selector for this function is: 0x1752d67b,55 /// or in textual repr: setProperty(uint256,string,bytes)56 function setProperty(57 uint256 tokenId,58 string memory key,59 bytes memory value60 ) public {61 require(false, stub_error);62 tokenId;63 key;64 value;65 dummy = 0;66 }6768 /// @notice Delete token property value.69 /// @dev Throws error if `msg.sender` has no permission to edit the property.70 /// @param tokenId ID of the token.71 /// @param key Property key.72 /// @dev EVM selector for this function is: 0x066111d1,73 /// or in textual repr: deleteProperty(uint256,string)74 function deleteProperty(uint256 tokenId, string memory key) public {75 require(false, stub_error);76 tokenId;77 key;78 dummy = 0;79 }8081 /// @notice Get token property value.82 /// @dev Throws error if key not found83 /// @param tokenId ID of the token.84 /// @param key Property key.85 /// @return Property value bytes86 /// @dev EVM selector for this function is: 0x7228c327,87 /// or in textual repr: property(uint256,string)88 function property(uint256 tokenId, string memory key)89 public90 view91 returns (bytes memory)92 {93 require(false, stub_error);94 tokenId;95 key;96 dummy;97 return hex"";98 }99}100101/// @title A contract that allows you to work with collections.102/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0103contract Collection is Dummy, ERC165 {104 /// Set collection property.105 ///106 /// @param key Property key.107 /// @param value Propery value.108 /// @dev EVM selector for this function is: 0x2f073f66,109 /// or in textual repr: setCollectionProperty(string,bytes)110 function setCollectionProperty(string memory key, bytes memory value)111 public112 {113 require(false, stub_error);114 key;115 value;116 dummy = 0;117 }118119 /// Delete collection property.120 ///121 /// @param key Property key.122 /// @dev EVM selector for this function is: 0x7b7debce,123 /// or in textual repr: deleteCollectionProperty(string)124 function deleteCollectionProperty(string memory key) public {125 require(false, stub_error);126 key;127 dummy = 0;128 }129130 /// Get collection property.131 ///132 /// @dev Throws error if key not found.133 ///134 /// @param key Property key.135 /// @return bytes The property corresponding to the key.136 /// @dev EVM selector for this function is: 0xcf24fd6d,137 /// or in textual repr: collectionProperty(string)138 function collectionProperty(string memory key)139 public140 view141 returns (bytes memory)142 {143 require(false, stub_error);144 key;145 dummy;146 return hex"";147 }148149 /// Set the sponsor of the collection.150 ///151 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.152 ///153 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.154 /// @dev EVM selector for this function is: 0x7623402e,155 /// or in textual repr: setCollectionSponsor(address)156 function setCollectionSponsor(address sponsor) public {157 require(false, stub_error);158 sponsor;159 dummy = 0;160 }161162 /// Set the substrate sponsor of the collection.163 ///164 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.165 ///166 /// @param sponsor Substrate address of the sponsor from whose account funds will be debited for operations with the contract.167 /// @dev EVM selector for this function is: 0xc74d6751,168 /// or in textual repr: setCollectionSponsorSubstrate(uint256)169 function setCollectionSponsorSubstrate(uint256 sponsor) public {170 require(false, stub_error);171 sponsor;172 dummy = 0;173 }174175 /// @dev EVM selector for this function is: 0x058ac185,176 /// or in textual repr: hasCollectionPendingSponsor()177 function hasCollectionPendingSponsor() public view returns (bool) {178 require(false, stub_error);179 dummy;180 return false;181 }182183 /// Collection sponsorship confirmation.184 ///185 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.186 /// @dev EVM selector for this function is: 0x3c50e97a,187 /// or in textual repr: confirmCollectionSponsorship()188 function confirmCollectionSponsorship() public {189 require(false, stub_error);190 dummy = 0;191 }192193 /// Remove collection sponsor.194 /// @dev EVM selector for this function is: 0x6e0326a3,195 /// or in textual repr: removeCollectionSponsor()196 function removeCollectionSponsor() public {197 require(false, stub_error);198 dummy = 0;199 }200201 /// Get current sponsor.202 ///203 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.204 /// @dev EVM selector for this function is: 0xb66bbc14,205 /// or in textual repr: getCollectionSponsor()206 function getCollectionSponsor() public view returns (Tuple17 memory) {207 require(false, stub_error);208 dummy;209 return Tuple17(0x0000000000000000000000000000000000000000, 0);210 }211212 /// Set limits for the collection.213 /// @dev Throws error if limit not found.214 /// @param limit Name of the limit. Valid names:215 /// "accountTokenOwnershipLimit",216 /// "sponsoredDataSize",217 /// "sponsoredDataRateLimit",218 /// "tokenLimit",219 /// "sponsorTransferTimeout",220 /// "sponsorApproveTimeout"221 /// @param value Value of the limit.222 /// @dev EVM selector for this function is: 0x6a3841db,223 /// or in textual repr: setCollectionLimit(string,uint32)224 function setCollectionLimit(string memory limit, uint32 value) public {225 require(false, stub_error);226 limit;227 value;228 dummy = 0;229 }230231 /// Set limits for the collection.232 /// @dev Throws error if limit not found.233 /// @param limit Name of the limit. Valid names:234 /// "ownerCanTransfer",235 /// "ownerCanDestroy",236 /// "transfersEnabled"237 /// @param value Value of the limit.238 /// @dev EVM selector for this function is: 0x993b7fba,239 /// or in textual repr: setCollectionLimit(string,bool)240 function setCollectionLimit(string memory limit, bool value) public {241 require(false, stub_error);242 limit;243 value;244 dummy = 0;245 }246247 /// Get contract address.248 /// @dev EVM selector for this function is: 0xf6b4dfb4,249 /// or in textual repr: contractAddress()250 function contractAddress() public view returns (address) {251 require(false, stub_error);252 dummy;253 return 0x0000000000000000000000000000000000000000;254 }255256 /// Add collection admin by substrate address.257 /// @param newAdmin Substrate administrator address.258 /// @dev EVM selector for this function is: 0x5730062b,259 /// or in textual repr: addCollectionAdminSubstrate(uint256)260 function addCollectionAdminSubstrate(uint256 newAdmin) public {261 require(false, stub_error);262 newAdmin;263 dummy = 0;264 }265266 /// Remove collection admin by substrate address.267 /// @param admin Substrate administrator address.268 /// @dev EVM selector for this function is: 0x4048fcf9,269 /// or in textual repr: removeCollectionAdminSubstrate(uint256)270 function removeCollectionAdminSubstrate(uint256 admin) public {271 require(false, stub_error);272 admin;273 dummy = 0;274 }275276 /// Add collection admin.277 /// @param newAdmin Address of the added administrator.278 /// @dev EVM selector for this function is: 0x92e462c7,279 /// or in textual repr: addCollectionAdmin(address)280 function addCollectionAdmin(address newAdmin) public {281 require(false, stub_error);282 newAdmin;283 dummy = 0;284 }285286 /// Remove collection admin.287 ///288 /// @param admin Address of the removed administrator.289 /// @dev EVM selector for this function is: 0xfafd7b42,290 /// or in textual repr: removeCollectionAdmin(address)291 function removeCollectionAdmin(address admin) public {292 require(false, stub_error);293 admin;294 dummy = 0;295 }296297 /// Toggle accessibility of collection nesting.298 ///299 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'300 /// @dev EVM selector for this function is: 0x112d4586,301 /// or in textual repr: setCollectionNesting(bool)302 function setCollectionNesting(bool enable) public {303 require(false, stub_error);304 enable;305 dummy = 0;306 }307308 /// Toggle accessibility of collection nesting.309 ///310 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'311 /// @param collections Addresses of collections that will be available for nesting.312 /// @dev EVM selector for this function is: 0x64872396,313 /// or in textual repr: setCollectionNesting(bool,address[])314 function setCollectionNesting(bool enable, address[] memory collections)315 public316 {317 require(false, stub_error);318 enable;319 collections;320 dummy = 0;321 }322323 /// Set the collection access method.324 /// @param mode Access mode325 /// 0 for Normal326 /// 1 for AllowList327 /// @dev EVM selector for this function is: 0x41835d4c,328 /// or in textual repr: setCollectionAccess(uint8)329 function setCollectionAccess(uint8 mode) public {330 require(false, stub_error);331 mode;332 dummy = 0;333 }334335 /// Checks that user allowed to operate with collection.336 ///337 /// @param user User address to check.338 /// @dev EVM selector for this function is: 0xd63a8e11,339 /// or in textual repr: allowed(address)340 function allowed(address user) public view returns (bool) {341 require(false, stub_error);342 user;343 dummy;344 return false;345 }346347 /// Add the user to the allowed list.348 ///349 /// @param user Address of a trusted user.350 /// @dev EVM selector for this function is: 0x67844fe6,351 /// or in textual repr: addToCollectionAllowList(address)352 function addToCollectionAllowList(address user) public {353 require(false, stub_error);354 user;355 dummy = 0;356 }357358 /// Add substrate user to allowed list.359 ///360 /// @param user User substrate address.361 /// @dev EVM selector for this function is: 0xd06ad267,362 /// or in textual repr: addToCollectionAllowListSubstrate(uint256)363 function addToCollectionAllowListSubstrate(uint256 user) public {364 require(false, stub_error);365 user;366 dummy = 0;367 }368369 /// Remove the user from the allowed list.370 ///371 /// @param user Address of a removed user.372 /// @dev EVM selector for this function is: 0x85c51acb,373 /// or in textual repr: removeFromCollectionAllowList(address)374 function removeFromCollectionAllowList(address user) public {375 require(false, stub_error);376 user;377 dummy = 0;378 }379380 /// Remove substrate user from allowed list.381 ///382 /// @param user User substrate address.383 /// @dev EVM selector for this function is: 0xa31913ed,384 /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)385 function removeFromCollectionAllowListSubstrate(uint256 user) public {386 require(false, stub_error);387 user;388 dummy = 0;389 }390391 /// Switch permission for minting.392 ///393 /// @param mode Enable if "true".394 /// @dev EVM selector for this function is: 0x00018e84,395 /// or in textual repr: setCollectionMintMode(bool)396 function setCollectionMintMode(bool mode) public {397 require(false, stub_error);398 mode;399 dummy = 0;400 }401402 /// Check that account is the owner or admin of the collection403 ///404 /// @param user account to verify405 /// @return "true" if account is the owner or admin406 /// @dev EVM selector for this function is: 0x9811b0c7,407 /// or in textual repr: isOwnerOrAdmin(address)408 function isOwnerOrAdmin(address user) public view returns (bool) {409 require(false, stub_error);410 user;411 dummy;412 return false;413 }414415 /// Check that substrate account is the owner or admin of the collection416 ///417 /// @param user account to verify418 /// @return "true" if account is the owner or admin419 /// @dev EVM selector for this function is: 0x68910e00,420 /// or in textual repr: isOwnerOrAdminSubstrate(uint256)421 function isOwnerOrAdminSubstrate(uint256 user) public view returns (bool) {422 require(false, stub_error);423 user;424 dummy;425 return false;426 }427428 /// Returns collection type429 ///430 /// @return `Fungible` or `NFT` or `ReFungible`431 /// @dev EVM selector for this function is: 0xd34b55b8,432 /// or in textual repr: uniqueCollectionType()433 function uniqueCollectionType() public returns (string memory) {434 require(false, stub_error);435 dummy = 0;436 return "";437 }438439 /// Get collection owner.440 ///441 /// @return Tuble with sponsor address and his substrate mirror.442 /// If address is canonical then substrate mirror is zero and vice versa.443 /// @dev EVM selector for this function is: 0xdf727d3b,444 /// or in textual repr: collectionOwner()445 function collectionOwner() public view returns (Tuple17 memory) {446 require(false, stub_error);447 dummy;448 return Tuple17(0x0000000000000000000000000000000000000000, 0);449 }450451 /// Changes collection owner to another account452 ///453 /// @dev Owner can be changed only by current owner454 /// @param newOwner new owner account455 /// @dev EVM selector for this function is: 0x13af4035,456 /// or in textual repr: setOwner(address)457 function setOwner(address newOwner) public {458 require(false, stub_error);459 newOwner;460 dummy = 0;461 }462463 /// Changes collection owner to another substrate account464 ///465 /// @dev Owner can be changed only by current owner466 /// @param newOwner new owner substrate account467 /// @dev EVM selector for this function is: 0xb212138f,468 /// or in textual repr: setOwnerSubstrate(uint256)469 function setOwnerSubstrate(uint256 newOwner) public {470 require(false, stub_error);471 newOwner;472 dummy = 0;473 }474}475476/// @dev anonymous struct477struct Tuple17 {478 address field_0;479 uint256 field_1;480}481482/// @title ERC721 Token that can be irreversibly burned (destroyed).483/// @dev the ERC-165 identifier for this interface is 0x42966c68484contract ERC721Burnable is Dummy, ERC165 {485 /// @notice Burns a specific ERC721 token.486 /// @dev Throws unless `msg.sender` is the current RFT owner, or an authorized487 /// operator of the current owner.488 /// @param tokenId The RFT to approve489 /// @dev EVM selector for this function is: 0x42966c68,490 /// or in textual repr: burn(uint256)491 function burn(uint256 tokenId) public {492 require(false, stub_error);493 tokenId;494 dummy = 0;495 }496}497498/// @dev inlined interface499contract ERC721MintableEvents {500 event MintingFinished();501}502503/// @title ERC721 minting logic.504/// @dev the ERC-165 identifier for this interface is 0x68ccfe89505contract ERC721Mintable is Dummy, ERC165, ERC721MintableEvents {506 /// @dev EVM selector for this function is: 0x05d2035b,507 /// or in textual repr: mintingFinished()508 function mintingFinished() public view returns (bool) {509 require(false, stub_error);510 dummy;511 return false;512 }513514 /// @notice Function to mint token.515 /// @dev `tokenId` should be obtained with `nextTokenId` method,516 /// unlike standard, you can't specify it manually517 /// @param to The new owner518 /// @param tokenId ID of the minted RFT519 /// @dev EVM selector for this function is: 0x40c10f19,520 /// or in textual repr: mint(address,uint256)521 function mint(address to, uint256 tokenId) public returns (bool) {522 require(false, stub_error);523 to;524 tokenId;525 dummy = 0;526 return false;527 }528529 /// @notice Function to mint token with the given tokenUri.530 /// @dev `tokenId` should be obtained with `nextTokenId` method,531 /// unlike standard, you can't specify it manually532 /// @param to The new owner533 /// @param tokenId ID of the minted RFT534 /// @param tokenUri Token URI that would be stored in the RFT properties535 /// @dev EVM selector for this function is: 0x50bb4e7f,536 /// or in textual repr: mintWithTokenURI(address,uint256,string)537 function mintWithTokenURI(538 address to,539 uint256 tokenId,540 string memory tokenUri541 ) public returns (bool) {542 require(false, stub_error);543 to;544 tokenId;545 tokenUri;546 dummy = 0;547 return false;548 }549550 /// @dev Not implemented551 /// @dev EVM selector for this function is: 0x7d64bcb4,552 /// or in textual repr: finishMinting()553 function finishMinting() public returns (bool) {554 require(false, stub_error);555 dummy = 0;556 return false;557 }558}559560/// @title Unique extensions for ERC721.561/// @dev the ERC-165 identifier for this interface is 0x7c3bef89562contract ERC721UniqueExtensions is Dummy, ERC165 {563 /// @notice Transfer ownership of an RFT564 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`565 /// is the zero address. Throws if `tokenId` is not a valid RFT.566 /// Throws if RFT pieces have multiple owners.567 /// @param to The new owner568 /// @param tokenId The RFT to transfer569 /// @dev EVM selector for this function is: 0xa9059cbb,570 /// or in textual repr: transfer(address,uint256)571 function transfer(address to, uint256 tokenId) public {572 require(false, stub_error);573 to;574 tokenId;575 dummy = 0;576 }577578 /// @notice Burns a specific ERC721 token.579 /// @dev Throws unless `msg.sender` is the current owner or an authorized580 /// operator for this RFT. Throws if `from` is not the current owner. Throws581 /// if `to` is the zero address. Throws if `tokenId` is not a valid RFT.582 /// Throws if RFT pieces have multiple owners.583 /// @param from The current owner of the RFT584 /// @param tokenId The RFT to transfer585 /// @dev EVM selector for this function is: 0x79cc6790,586 /// or in textual repr: burnFrom(address,uint256)587 function burnFrom(address from, uint256 tokenId) public {588 require(false, stub_error);589 from;590 tokenId;591 dummy = 0;592 }593594 /// @notice Returns next free RFT ID.595 /// @dev EVM selector for this function is: 0x75794a3c,596 /// or in textual repr: nextTokenId()597 function nextTokenId() public view returns (uint256) {598 require(false, stub_error);599 dummy;600 return 0;601 }602603 /// @notice Function to mint multiple tokens.604 /// @dev `tokenIds` should be an array of consecutive numbers and first number605 /// should be obtained with `nextTokenId` method606 /// @param to The new owner607 /// @param tokenIds IDs of the minted RFTs608 /// @dev EVM selector for this function is: 0x44a9945e,609 /// or in textual repr: mintBulk(address,uint256[])610 function mintBulk(address to, uint256[] memory tokenIds)611 public612 returns (bool)613 {614 require(false, stub_error);615 to;616 tokenIds;617 dummy = 0;618 return false;619 }620621 /// @notice Function to mint multiple tokens with the given tokenUris.622 /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive623 /// numbers and first number should be obtained with `nextTokenId` method624 /// @param to The new owner625 /// @param tokens array of pairs of token ID and token URI for minted tokens626 /// @dev EVM selector for this function is: 0x36543006,627 /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])628 function mintBulkWithTokenURI(address to, Tuple8[] memory tokens)629 public630 returns (bool)631 {632 require(false, stub_error);633 to;634 tokens;635 dummy = 0;636 return false;637 }638639 /// Returns EVM address for refungible token640 ///641 /// @param token ID of the token642 /// @dev EVM selector for this function is: 0xab76fac6,643 /// or in textual repr: tokenContractAddress(uint256)644 function tokenContractAddress(uint256 token) public view returns (address) {645 require(false, stub_error);646 token;647 dummy;648 return 0x0000000000000000000000000000000000000000;649 }650}651652/// @dev anonymous struct653struct Tuple8 {654 uint256 field_0;655 string field_1;656}657658/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension659/// @dev See https://eips.ethereum.org/EIPS/eip-721660/// @dev the ERC-165 identifier for this interface is 0x780e9d63661contract ERC721Enumerable is Dummy, ERC165 {662 /// @notice Enumerate valid RFTs663 /// @param index A counter less than `totalSupply()`664 /// @return The token identifier for the `index`th NFT,665 /// (sort order not specified)666 /// @dev EVM selector for this function is: 0x4f6ccce7,667 /// or in textual repr: tokenByIndex(uint256)668 function tokenByIndex(uint256 index) public view returns (uint256) {669 require(false, stub_error);670 index;671 dummy;672 return 0;673 }674675 /// Not implemented676 /// @dev EVM selector for this function is: 0x2f745c59,677 /// or in textual repr: tokenOfOwnerByIndex(address,uint256)678 function tokenOfOwnerByIndex(address owner, uint256 index)679 public680 view681 returns (uint256)682 {683 require(false, stub_error);684 owner;685 index;686 dummy;687 return 0;688 }689690 /// @notice Count RFTs tracked by this contract691 /// @return A count of valid RFTs tracked by this contract, where each one of692 /// them has an assigned and queryable owner not equal to the zero address693 /// @dev EVM selector for this function is: 0x18160ddd,694 /// or in textual repr: totalSupply()695 function totalSupply() public view returns (uint256) {696 require(false, stub_error);697 dummy;698 return 0;699 }700}701702/// @dev the ERC-165 identifier for this interface is 0x5b5e139f703contract ERC721Metadata is Dummy, ERC165 {704 /// @notice A descriptive name for a collection of RFTs in this contract705 /// @dev EVM selector for this function is: 0x06fdde03,706 /// or in textual repr: name()707 function name() public view returns (string memory) {708 require(false, stub_error);709 dummy;710 return "";711 }712713 /// @notice An abbreviated name for RFTs in this contract714 /// @dev EVM selector for this function is: 0x95d89b41,715 /// or in textual repr: symbol()716 function symbol() public view returns (string memory) {717 require(false, stub_error);718 dummy;719 return "";720 }721722 /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.723 ///724 /// @dev If the token has a `url` property and it is not empty, it is returned.725 /// Else If the collection does not have a property with key `schemaName` or its value is not equal to `ERC721Metadata`, it return an error `tokenURI not set`.726 /// If the collection property `baseURI` is empty or absent, return "" (empty string)727 /// otherwise, if token property `suffix` present and is non-empty, return concatenation of baseURI and suffix728 /// otherwise, return concatenation of `baseURI` and stringified token id (decimal stringifying, without paddings).729 ///730 /// @return token's const_metadata731 /// @dev EVM selector for this function is: 0xc87b56dd,732 /// or in textual repr: tokenURI(uint256)733 function tokenURI(uint256 tokenId) public view returns (string memory) {734 require(false, stub_error);735 tokenId;736 dummy;737 return "";738 }739}740741/// @dev inlined interface742contract ERC721Events {743 event Transfer(744 address indexed from,745 address indexed to,746 uint256 indexed tokenId747 );748 event Approval(749 address indexed owner,750 address indexed approved,751 uint256 indexed tokenId752 );753 event ApprovalForAll(754 address indexed owner,755 address indexed operator,756 bool approved757 );758}759760/// @title ERC-721 Non-Fungible Token Standard761/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md762/// @dev the ERC-165 identifier for this interface is 0x58800161763contract ERC721 is Dummy, ERC165, ERC721Events {764 /// @notice Count all RFTs assigned to an owner765 /// @dev RFTs assigned to the zero address are considered invalid, and this766 /// function throws for queries about the zero address.767 /// @param owner An address for whom to query the balance768 /// @return The number of RFTs owned by `owner`, possibly zero769 /// @dev EVM selector for this function is: 0x70a08231,770 /// or in textual repr: balanceOf(address)771 function balanceOf(address owner) public view returns (uint256) {772 require(false, stub_error);773 owner;774 dummy;775 return 0;776 }777778 /// @notice Find the owner of an RFT779 /// @dev RFTs assigned to zero address are considered invalid, and queries780 /// about them do throw.781 /// Returns special 0xffffffffffffffffffffffffffffffffffffffff address for782 /// the tokens that are partially owned.783 /// @param tokenId The identifier for an RFT784 /// @return The address of the owner of the RFT785 /// @dev EVM selector for this function is: 0x6352211e,786 /// or in textual repr: ownerOf(uint256)787 function ownerOf(uint256 tokenId) public view returns (address) {788 require(false, stub_error);789 tokenId;790 dummy;791 return 0x0000000000000000000000000000000000000000;792 }793794 /// @dev Not implemented795 /// @dev EVM selector for this function is: 0x60a11672,796 /// or in textual repr: safeTransferFromWithData(address,address,uint256,bytes)797 function safeTransferFromWithData(798 address from,799 address to,800 uint256 tokenId,801 bytes memory data802 ) public {803 require(false, stub_error);804 from;805 to;806 tokenId;807 data;808 dummy = 0;809 }810811 /// @dev Not implemented812 /// @dev EVM selector for this function is: 0x42842e0e,813 /// or in textual repr: safeTransferFrom(address,address,uint256)814 function safeTransferFrom(815 address from,816 address to,817 uint256 tokenId818 ) public {819 require(false, stub_error);820 from;821 to;822 tokenId;823 dummy = 0;824 }825826 /// @notice Transfer ownership of an RFT -- THE CALLER IS RESPONSIBLE827 /// TO CONFIRM THAT `to` IS CAPABLE OF RECEIVING NFTS OR ELSE828 /// THEY MAY BE PERMANENTLY LOST829 /// @dev Throws unless `msg.sender` is the current owner or an authorized830 /// operator for this RFT. Throws if `from` is not the current owner. Throws831 /// if `to` is the zero address. Throws if `tokenId` is not a valid RFT.832 /// Throws if RFT pieces have multiple owners.833 /// @param from The current owner of the NFT834 /// @param to The new owner835 /// @param tokenId The NFT to transfer836 /// @dev EVM selector for this function is: 0x23b872dd,837 /// or in textual repr: transferFrom(address,address,uint256)838 function transferFrom(839 address from,840 address to,841 uint256 tokenId842 ) public {843 require(false, stub_error);844 from;845 to;846 tokenId;847 dummy = 0;848 }849850 /// @dev Not implemented851 /// @dev EVM selector for this function is: 0x095ea7b3,852 /// or in textual repr: approve(address,uint256)853 function approve(address approved, uint256 tokenId) public {854 require(false, stub_error);855 approved;856 tokenId;857 dummy = 0;858 }859860 /// @dev Not implemented861 /// @dev EVM selector for this function is: 0xa22cb465,862 /// or in textual repr: setApprovalForAll(address,bool)863 function setApprovalForAll(address operator, bool approved) public {864 require(false, stub_error);865 operator;866 approved;867 dummy = 0;868 }869870 /// @dev Not implemented871 /// @dev EVM selector for this function is: 0x081812fc,872 /// or in textual repr: getApproved(uint256)873 function getApproved(uint256 tokenId) public view returns (address) {874 require(false, stub_error);875 tokenId;876 dummy;877 return 0x0000000000000000000000000000000000000000;878 }879880 /// @dev Not implemented881 /// @dev EVM selector for this function is: 0xe985e9c5,882 /// or in textual repr: isApprovedForAll(address,address)883 function isApprovedForAll(address owner, address operator)884 public885 view886 returns (address)887 {888 require(false, stub_error);889 owner;890 operator;891 dummy;892 return 0x0000000000000000000000000000000000000000;893 }894}895896contract UniqueRefungible is897 Dummy,898 ERC165,899 ERC721,900 ERC721Metadata,901 ERC721Enumerable,902 ERC721UniqueExtensions,903 ERC721Mintable,904 ERC721Burnable,905 Collection,906 TokenProperties907{}tests/src/eth/allowlist.test.tsdiffbeforeafterboth--- a/tests/src/eth/allowlist.test.ts
+++ b/tests/src/eth/allowlist.test.ts
@@ -14,10 +14,22 @@
// 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 {IKeyringPair} from '@polkadot/types/types';
import {expect} from 'chai';
-import {contractHelpers, createEthAccountWithBalance, deployFlipper, itWeb3} from './util/helpers';
+import {isAllowlisted, normalizeAccountId} from '../util/helpers';
+import {
+ contractHelpers,
+ createEthAccount,
+ createEthAccountWithBalance,
+ deployFlipper,
+ evmCollection,
+ evmCollectionHelpers,
+ getCollectionAddressFromResult,
+ itWeb3,
+} from './util/helpers';
+import {itEth, usingEthPlaygrounds} from './util/playgrounds';
-describe('EVM allowlist', () => {
+describe('EVM contract allowlist', () => {
itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {
const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
const flipper = await deployFlipper(web3, owner);
@@ -58,3 +70,79 @@
expect(await flipper.methods.getValue().call()).to.be.false;
});
});
+
+describe('EVM collection allowlist', () => {
+ let donor: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (_helper, privateKey) => {
+ donor = privateKey('//Alice');
+ });
+ });
+
+ itEth('Collection allowlist can be added and removed by [eth] address', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const user = helper.eth.createAccount();
+
+ const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
+ await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
+ expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
+
+ await collectionEvm.methods.removeFromCollectionAllowList(user).send({from: owner});
+ expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
+ });
+
+ itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const user = donor;
+
+ const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
+ await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
+ expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
+
+ await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
+ expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
+ });
+
+ itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const notOwner = await helper.eth.createAccountWithBalance(donor);
+ const user = helper.eth.createAccount();
+
+ const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
+ await expect(collectionEvm.methods.addToCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
+ expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;
+ await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
+
+ expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
+ await expect(collectionEvm.methods.removeFromCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');
+ expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;
+ });
+
+ itEth('Collection allowlist can not be add and remove [sub] address by not owner', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const notOwner = await helper.eth.createAccountWithBalance(donor);
+ const user = donor;
+
+ const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
+ await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
+ expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
+ await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});
+
+ expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
+ await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');
+ expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
+ });
+});
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -13,7 +13,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xe54be640
+/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -164,6 +164,13 @@
/// or in textual repr: setCollectionAccess(uint8)
function setCollectionAccess(uint8 mode) external;
+ /// Checks that user allowed to operate with collection.
+ ///
+ /// @param user User address to check.
+ /// @dev EVM selector for this function is: 0xd63a8e11,
+ /// or in textual repr: allowed(address)
+ function allowed(address user) external view returns (bool);
+
/// Add the user to the allowed list.
///
/// @param user Address of a trusted user.
@@ -171,6 +178,13 @@
/// or in textual repr: addToCollectionAllowList(address)
function addToCollectionAllowList(address user) external;
+ /// Add substrate user to allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xd06ad267,
+ /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
+ function addToCollectionAllowListSubstrate(uint256 user) external;
+
/// Remove the user from the allowed list.
///
/// @param user Address of a removed user.
@@ -178,6 +192,13 @@
/// or in textual repr: removeFromCollectionAllowList(address)
function removeFromCollectionAllowList(address user) external;
+ /// Remove substrate user from allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xa31913ed,
+ /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
+ function removeFromCollectionAllowListSubstrate(uint256 user) external;
+
/// Switch permission for minting.
///
/// @param mode Enable if "true".
@@ -208,6 +229,14 @@
/// or in textual repr: uniqueCollectionType()
function uniqueCollectionType() external returns (string memory);
+ /// Get collection owner.
+ ///
+ /// @return Tuble with sponsor address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0xdf727d3b,
+ /// or in textual repr: collectionOwner()
+ function collectionOwner() external view returns (Tuple6 memory);
+
/// Changes collection owner to another account
///
/// @dev Owner can be changed only by current owner
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -65,7 +65,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xe54be640
+/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -216,6 +216,13 @@
/// or in textual repr: setCollectionAccess(uint8)
function setCollectionAccess(uint8 mode) external;
+ /// Checks that user allowed to operate with collection.
+ ///
+ /// @param user User address to check.
+ /// @dev EVM selector for this function is: 0xd63a8e11,
+ /// or in textual repr: allowed(address)
+ function allowed(address user) external view returns (bool);
+
/// Add the user to the allowed list.
///
/// @param user Address of a trusted user.
@@ -223,6 +230,13 @@
/// or in textual repr: addToCollectionAllowList(address)
function addToCollectionAllowList(address user) external;
+ /// Add substrate user to allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xd06ad267,
+ /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
+ function addToCollectionAllowListSubstrate(uint256 user) external;
+
/// Remove the user from the allowed list.
///
/// @param user Address of a removed user.
@@ -230,6 +244,13 @@
/// or in textual repr: removeFromCollectionAllowList(address)
function removeFromCollectionAllowList(address user) external;
+ /// Remove substrate user from allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xa31913ed,
+ /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
+ function removeFromCollectionAllowListSubstrate(uint256 user) external;
+
/// Switch permission for minting.
///
/// @param mode Enable if "true".
@@ -260,6 +281,14 @@
/// or in textual repr: uniqueCollectionType()
function uniqueCollectionType() external returns (string memory);
+ /// Get collection owner.
+ ///
+ /// @return Tuble with sponsor address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0xdf727d3b,
+ /// or in textual repr: collectionOwner()
+ function collectionOwner() external view returns (Tuple17 memory);
+
/// Changes collection owner to another account
///
/// @dev Owner can be changed only by current owner
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -65,7 +65,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xe54be640
+/// @dev the ERC-165 identifier for this interface is 0x9f70d4e0
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -216,6 +216,13 @@
/// or in textual repr: setCollectionAccess(uint8)
function setCollectionAccess(uint8 mode) external;
+ /// Checks that user allowed to operate with collection.
+ ///
+ /// @param user User address to check.
+ /// @dev EVM selector for this function is: 0xd63a8e11,
+ /// or in textual repr: allowed(address)
+ function allowed(address user) external view returns (bool);
+
/// Add the user to the allowed list.
///
/// @param user Address of a trusted user.
@@ -223,6 +230,13 @@
/// or in textual repr: addToCollectionAllowList(address)
function addToCollectionAllowList(address user) external;
+ /// Add substrate user to allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xd06ad267,
+ /// or in textual repr: addToCollectionAllowListSubstrate(uint256)
+ function addToCollectionAllowListSubstrate(uint256 user) external;
+
/// Remove the user from the allowed list.
///
/// @param user Address of a removed user.
@@ -230,6 +244,13 @@
/// or in textual repr: removeFromCollectionAllowList(address)
function removeFromCollectionAllowList(address user) external;
+ /// Remove substrate user from allowed list.
+ ///
+ /// @param user User substrate address.
+ /// @dev EVM selector for this function is: 0xa31913ed,
+ /// or in textual repr: removeFromCollectionAllowListSubstrate(uint256)
+ function removeFromCollectionAllowListSubstrate(uint256 user) external;
+
/// Switch permission for minting.
///
/// @param mode Enable if "true".
@@ -260,6 +281,14 @@
/// or in textual repr: uniqueCollectionType()
function uniqueCollectionType() external returns (string memory);
+ /// Get collection owner.
+ ///
+ /// @return Tuble with sponsor address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0xdf727d3b,
+ /// or in textual repr: collectionOwner()
+ function collectionOwner() external view returns (Tuple17 memory);
+
/// Changes collection owner to another account
///
/// @dev Owner can be changed only by current owner
tests/src/eth/fungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/fungibleAbi.json
+++ b/tests/src/eth/fungibleAbi.json
@@ -78,6 +78,15 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "user", "type": "uint256" }
+ ],
+ "name": "addToCollectionAllowListSubstrate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "address", "name": "spender", "type": "address" }
],
@@ -88,6 +97,15 @@
},
{
"inputs": [
+ { "internalType": "address", "name": "user", "type": "address" }
+ ],
+ "name": "allowed",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "spender", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
@@ -116,6 +134,23 @@
"type": "function"
},
{
+ "inputs": [],
+ "name": "collectionOwner",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple6",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
"name": "collectionProperty",
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
@@ -261,6 +296,15 @@
"type": "function"
},
{
+ "inputs": [
+ { "internalType": "uint256", "name": "user", "type": "uint256" }
+ ],
+ "name": "removeFromCollectionAllowListSubstrate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
"name": "setCollectionAccess",
"outputs": [],
tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -109,6 +109,24 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "user", "type": "uint256" }
+ ],
+ "name": "addToCollectionAllowListSubstrate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "user", "type": "address" }
+ ],
+ "name": "allowed",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "approved", "type": "address" },
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }
],
@@ -146,6 +164,23 @@
"type": "function"
},
{
+ "inputs": [],
+ "name": "collectionOwner",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple17",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
"name": "collectionProperty",
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
@@ -376,6 +411,15 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "user", "type": "uint256" }
+ ],
+ "name": "removeFromCollectionAllowListSubstrate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "from", "type": "address" },
{ "internalType": "address", "name": "to", "type": "address" },
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }
tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/reFungibleAbi.json
+++ b/tests/src/eth/reFungibleAbi.json
@@ -109,6 +109,24 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "user", "type": "uint256" }
+ ],
+ "name": "addToCollectionAllowListSubstrate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "user", "type": "address" }
+ ],
+ "name": "allowed",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "approved", "type": "address" },
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }
],
@@ -146,6 +164,23 @@
"type": "function"
},
{
+ "inputs": [],
+ "name": "collectionOwner",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple17",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
"name": "collectionProperty",
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
@@ -376,6 +411,15 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "user", "type": "uint256" }
+ ],
+ "name": "removeFromCollectionAllowListSubstrate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "from", "type": "address" },
{ "internalType": "address", "name": "to", "type": "address" },
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }
tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -1651,7 +1651,7 @@
});
}
-export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId) {
+export async function isAllowlisted(api: ApiPromise, collectionId: number, address: string | CrossAccountId | IKeyringPair) {
return (await api.rpc.unique.allowed(collectionId, normalizeAccountId(address))).toJSON();
}
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -730,6 +730,18 @@
}
/**
+ * Check if user is in allow list.
+ *
+ * @param collectionId ID of collection
+ * @param user Account to check
+ * @example await getAdmins(1)
+ * @returns is user in allow list
+ */
+ async allowed(collectionId: number, user: ICrossAccountId): Promise<boolean> {
+ return (await this.helper.callRpc('api.rpc.unique.allowed', [collectionId, user])).toJSON();
+ }
+
+ /**
* Adds an address to allow list
* @param signer keyring of signer
* @param collectionId ID of collection