difftreelog
Merge branch 'develop' into tests/eth-helpers
in: master
21 files changed
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -37,6 +37,7 @@
Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
eth::{
EthCrossAccount, convert_cross_account_to_uint256, CollectionPermissions as EvmPermissions,
+ CollectionLimits as EvmCollectionLimits,
},
weights::WeightInfo,
};
@@ -304,6 +305,99 @@
Ok(result)
}
+ /// Get current collection limits.
+ ///
+ /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:
+ /// "accountTokenOwnershipLimit",
+ /// "sponsoredDataSize",
+ /// "sponsoredDataRateLimit",
+ /// "tokenLimit",
+ /// "sponsorTransferTimeout",
+ /// "sponsorApproveTimeout"
+ /// "ownerCanTransfer",
+ /// "ownerCanDestroy",
+ /// "transfersEnabled"
+ /// Return `false` if a limit not set.
+ fn collection_limits(&self) -> Result<Vec<(EvmCollectionLimits, bool, uint256)>> {
+ let convert_value_limit = |limit: EvmCollectionLimits,
+ value: Option<u32>|
+ -> (EvmCollectionLimits, bool, uint256) {
+ value
+ .map(|v| (limit, true, v.into()))
+ .unwrap_or((limit, false, Default::default()))
+ };
+
+ let convert_bool_limit = |limit: EvmCollectionLimits,
+ value: Option<bool>|
+ -> (EvmCollectionLimits, bool, uint256) {
+ value
+ .map(|v| {
+ (
+ limit,
+ true,
+ if v {
+ uint256::from(1)
+ } else {
+ Default::default()
+ },
+ )
+ })
+ .unwrap_or((limit, false, Default::default()))
+ };
+
+ let limits = &self.collection.limits;
+
+ Ok(vec![
+ convert_value_limit(
+ EvmCollectionLimits::AccountTokenOwnership,
+ limits.account_token_ownership_limit,
+ ),
+ convert_value_limit(
+ EvmCollectionLimits::SponsoredDataSize,
+ limits.sponsored_data_size,
+ ),
+ limits
+ .sponsored_data_rate_limit
+ .and_then(|limit| {
+ if let SponsoringRateLimit::Blocks(blocks) = limit {
+ Some((
+ EvmCollectionLimits::SponsoredDataRateLimit,
+ true,
+ blocks.into(),
+ ))
+ } else {
+ None
+ }
+ })
+ .unwrap_or((
+ EvmCollectionLimits::SponsoredDataRateLimit,
+ false,
+ Default::default(),
+ )),
+ convert_value_limit(EvmCollectionLimits::TokenLimit, limits.token_limit),
+ convert_value_limit(
+ EvmCollectionLimits::SponsorTransferTimeout,
+ limits.sponsor_transfer_timeout,
+ ),
+ convert_value_limit(
+ EvmCollectionLimits::SponsorApproveTimeout,
+ limits.sponsor_approve_timeout,
+ ),
+ convert_bool_limit(
+ EvmCollectionLimits::OwnerCanTransfer,
+ limits.owner_can_transfer,
+ ),
+ convert_bool_limit(
+ EvmCollectionLimits::OwnerCanDestroy,
+ limits.owner_can_destroy,
+ ),
+ convert_bool_limit(
+ EvmCollectionLimits::TransferEnabled,
+ limits.transfers_enabled,
+ ),
+ ])
+ }
+
/// Set limits for the collection.
/// @dev Throws error if limit not found.
/// @param limit Name of the limit. Valid names:
@@ -316,11 +410,22 @@
/// "ownerCanTransfer",
/// "ownerCanDestroy",
/// "transfersEnabled"
+ /// @param status enable\disable limit. Works only with `true`.
/// @param value Value of the limit.
#[solidity(rename_selector = "setCollectionLimit")]
- fn set_int_limit(&mut self, caller: caller, limit: string, value: uint256) -> Result<void> {
+ fn set_collection_limit(
+ &mut self,
+ caller: caller,
+ limit: EvmCollectionLimits,
+ status: bool,
+ value: uint256,
+ ) -> Result<void> {
self.consume_store_reads_and_writes(1, 1)?;
+ if !status {
+ return Err(Error::Revert("user can't disable limits".into()));
+ }
+
let value = value
.try_into()
.map_err(|_| Error::Revert(format!("can't convert value to u32 \"{}\"", value)))?;
@@ -338,35 +443,35 @@
let mut limits = self.limits.clone();
- match limit.as_str() {
- "accountTokenOwnershipLimit" => {
+ match limit {
+ EvmCollectionLimits::AccountTokenOwnership => {
limits.account_token_ownership_limit = Some(value);
}
- "sponsoredDataSize" => {
+ EvmCollectionLimits::SponsoredDataSize => {
limits.sponsored_data_size = Some(value);
}
- "sponsoredDataRateLimit" => {
+ EvmCollectionLimits::SponsoredDataRateLimit => {
limits.sponsored_data_rate_limit = Some(SponsoringRateLimit::Blocks(value));
}
- "tokenLimit" => {
+ EvmCollectionLimits::TokenLimit => {
limits.token_limit = Some(value);
}
- "sponsorTransferTimeout" => {
+ EvmCollectionLimits::SponsorTransferTimeout => {
limits.sponsor_transfer_timeout = Some(value);
}
- "sponsorApproveTimeout" => {
+ EvmCollectionLimits::SponsorApproveTimeout => {
limits.sponsor_approve_timeout = Some(value);
}
- "ownerCanTransfer" => {
+ EvmCollectionLimits::OwnerCanTransfer => {
limits.owner_can_transfer = Some(convert_value_to_bool()?);
}
- "ownerCanDestroy" => {
+ EvmCollectionLimits::OwnerCanDestroy => {
limits.owner_can_destroy = Some(convert_value_to_bool()?);
}
- "transfersEnabled" => {
+ EvmCollectionLimits::TransferEnabled => {
limits.transfers_enabled = Some(convert_value_to_bool()?);
}
- _ => return Err(Error::Revert(format!("unknown limit \"{}\"", limit))),
+ _ => return Err(Error::Revert(format!("unknown limit \"{:?}\"", limit))),
}
let caller = T::CrossAccountId::from_eth(caller);
pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -155,6 +155,31 @@
}
}
}
+
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.
+#[derive(Debug, Default, Clone, Copy, AbiCoder)]
+#[repr(u8)]
+pub enum CollectionLimits {
+ /// How many tokens can a user have on one account.
+ #[default]
+ AccountTokenOwnership,
+ /// How many bytes of data are available for sponsorship.
+ SponsoredDataSize,
+ /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+ SponsoredDataRateLimit,
+ /// How many tokens can be mined into this collection.
+ TokenLimit,
+ /// Timeouts for transfer sponsoring.
+ SponsorTransferTimeout,
+ /// Timeout for sponsoring an approval in passed blocks.
+ SponsorApproveTimeout,
+ /// Whether the collection owner of the collection can send tokens (which belong to other users).
+ OwnerCanTransfer,
+ /// Can the collection owner burn other people's tokens.
+ OwnerCanDestroy,
+ /// Is it possible to send tokens from this collection between users.
+ TransferEnabled,
+}
#[derive(Default, Debug, Clone, Copy, AbiCoder)]
#[repr(u8)]
pub enum CollectionPermissions {
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
@@ -18,7 +18,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
+/// @dev the ERC-165 identifier for this interface is 0x81172a75
contract Collection is Dummy, ERC165 {
// /// Set collection property.
// ///
@@ -158,6 +158,27 @@
return Tuple8(0x0000000000000000000000000000000000000000, 0);
}
+ /// Get current collection limits.
+ ///
+ /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:
+ /// "accountTokenOwnershipLimit",
+ /// "sponsoredDataSize",
+ /// "sponsoredDataRateLimit",
+ /// "tokenLimit",
+ /// "sponsorTransferTimeout",
+ /// "sponsorApproveTimeout"
+ /// "ownerCanTransfer",
+ /// "ownerCanDestroy",
+ /// "transfersEnabled"
+ /// Return `false` if a limit not set.
+ /// @dev EVM selector for this function is: 0xf63bc572,
+ /// or in textual repr: collectionLimits()
+ function collectionLimits() public view returns (Tuple20[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple20[](0);
+ }
+
/// Set limits for the collection.
/// @dev Throws error if limit not found.
/// @param limit Name of the limit. Valid names:
@@ -170,12 +191,18 @@
/// "ownerCanTransfer",
/// "ownerCanDestroy",
/// "transfersEnabled"
+ /// @param status enable\disable limit. Works only with `true`.
/// @param value Value of the limit.
- /// @dev EVM selector for this function is: 0x4ad890a8,
- /// or in textual repr: setCollectionLimit(string,uint256)
- function setCollectionLimit(string memory limit, uint256 value) public {
+ /// @dev EVM selector for this function is: 0x88150bd0,
+ /// or in textual repr: setCollectionLimit(uint8,bool,uint256)
+ function setCollectionLimit(
+ CollectionLimits limit,
+ bool status,
+ uint256 value
+ ) public {
require(false, stub_error);
limit;
+ status;
value;
dummy = 0;
}
@@ -257,19 +284,19 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() public view returns (Tuple21 memory) {
+ function collectionNestingRestrictedCollectionIds() public view returns (Tuple26 memory) {
require(false, stub_error);
dummy;
- return Tuple21(false, new uint256[](0));
+ return Tuple26(false, new uint256[](0));
}
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() public view returns (Tuple24[] memory) {
+ function collectionNestingPermissions() public view returns (Tuple29[] memory) {
require(false, stub_error);
dummy;
- return new Tuple24[](0);
+ return new Tuple29[](0);
}
/// Set the collection access method.
@@ -449,17 +476,46 @@
}
/// @dev anonymous struct
-struct Tuple24 {
+struct Tuple29 {
CollectionPermissions field_0;
bool field_1;
}
/// @dev anonymous struct
-struct Tuple21 {
+struct Tuple26 {
bool field_0;
uint256[] field_1;
}
+/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.
+enum CollectionLimits {
+ /// @dev How many tokens can a user have on one account.
+ AccountTokenOwnership,
+ /// @dev How many bytes of data are available for sponsorship.
+ SponsoredDataSize,
+ /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+ SponsoredDataRateLimit,
+ /// @dev How many tokens can be mined into this collection.
+ TokenLimit,
+ /// @dev Timeouts for transfer sponsoring.
+ SponsorTransferTimeout,
+ /// @dev Timeout for sponsoring an approval in passed blocks.
+ SponsorApproveTimeout,
+ /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+ OwnerCanTransfer,
+ /// @dev Can the collection owner burn other people's tokens.
+ OwnerCanDestroy,
+ /// @dev Is it possible to send tokens from this collection between users.
+ TransferEnabled
+}
+
+/// @dev anonymous struct
+struct Tuple20 {
+ CollectionLimits field_0;
+ bool field_1;
+ uint256 field_2;
+}
+
/// @dev Property struct
struct Property {
string key;
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
@@ -42,18 +42,19 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple48[] memory permissions) public {
+ function setTokenPropertyPermissions(Tuple59[] memory permissions) public {
require(false, stub_error);
permissions;
dummy = 0;
}
+ /// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() public view returns (Tuple48[] memory) {
+ function tokenPropertyPermissions() public view returns (Tuple59[] memory) {
require(false, stub_error);
dummy;
- return new Tuple48[](0);
+ return new Tuple59[](0);
}
// /// @notice Set token property value.
@@ -132,26 +133,30 @@
bytes value;
}
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
+ /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
Mutable,
+ /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
TokenOwner,
+ /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
CollectionAdmin
}
/// @dev anonymous struct
-struct Tuple48 {
+struct Tuple59 {
string field_0;
- Tuple46[] field_1;
+ Tuple57[] field_1;
}
/// @dev anonymous struct
-struct Tuple46 {
+struct Tuple57 {
EthTokenPermissions field_0;
bool field_1;
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
+/// @dev the ERC-165 identifier for this interface is 0x81172a75
contract Collection is Dummy, ERC165 {
// /// Set collection property.
// ///
@@ -291,6 +296,27 @@
return Tuple30(0x0000000000000000000000000000000000000000, 0);
}
+ /// Get current collection limits.
+ ///
+ /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:
+ /// "accountTokenOwnershipLimit",
+ /// "sponsoredDataSize",
+ /// "sponsoredDataRateLimit",
+ /// "tokenLimit",
+ /// "sponsorTransferTimeout",
+ /// "sponsorApproveTimeout"
+ /// "ownerCanTransfer",
+ /// "ownerCanDestroy",
+ /// "transfersEnabled"
+ /// Return `false` if a limit not set.
+ /// @dev EVM selector for this function is: 0xf63bc572,
+ /// or in textual repr: collectionLimits()
+ function collectionLimits() public view returns (Tuple33[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple33[](0);
+ }
+
/// Set limits for the collection.
/// @dev Throws error if limit not found.
/// @param limit Name of the limit. Valid names:
@@ -303,12 +329,18 @@
/// "ownerCanTransfer",
/// "ownerCanDestroy",
/// "transfersEnabled"
+ /// @param status enable\disable limit. Works only with `true`.
/// @param value Value of the limit.
- /// @dev EVM selector for this function is: 0x4ad890a8,
- /// or in textual repr: setCollectionLimit(string,uint256)
- function setCollectionLimit(string memory limit, uint256 value) public {
+ /// @dev EVM selector for this function is: 0x88150bd0,
+ /// or in textual repr: setCollectionLimit(uint8,bool,uint256)
+ function setCollectionLimit(
+ CollectionLimits limit,
+ bool status,
+ uint256 value
+ ) public {
require(false, stub_error);
limit;
+ status;
value;
dummy = 0;
}
@@ -390,19 +422,19 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() public view returns (Tuple34 memory) {
+ function collectionNestingRestrictedCollectionIds() public view returns (Tuple39 memory) {
require(false, stub_error);
dummy;
- return Tuple34(false, new uint256[](0));
+ return Tuple39(false, new uint256[](0));
}
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() public view returns (Tuple37[] memory) {
+ function collectionNestingPermissions() public view returns (Tuple42[] memory) {
require(false, stub_error);
dummy;
- return new Tuple37[](0);
+ return new Tuple42[](0);
}
/// Set the collection access method.
@@ -582,17 +614,46 @@
}
/// @dev anonymous struct
-struct Tuple37 {
+struct Tuple42 {
CollectionPermissions field_0;
bool field_1;
}
/// @dev anonymous struct
-struct Tuple34 {
+struct Tuple39 {
bool field_0;
uint256[] field_1;
}
+/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.
+enum CollectionLimits {
+ /// @dev How many tokens can a user have on one account.
+ AccountTokenOwnership,
+ /// @dev How many bytes of data are available for sponsorship.
+ SponsoredDataSize,
+ /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+ SponsoredDataRateLimit,
+ /// @dev How many tokens can be mined into this collection.
+ TokenLimit,
+ /// @dev Timeouts for transfer sponsoring.
+ SponsorTransferTimeout,
+ /// @dev Timeout for sponsoring an approval in passed blocks.
+ SponsorApproveTimeout,
+ /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+ OwnerCanTransfer,
+ /// @dev Can the collection owner burn other people's tokens.
+ OwnerCanDestroy,
+ /// @dev Is it possible to send tokens from this collection between users.
+ TransferEnabled
+}
+
+/// @dev anonymous struct
+struct Tuple33 {
+ CollectionLimits field_0;
+ bool field_1;
+ uint256 field_2;
+}
+
/// @dev anonymous struct
struct Tuple30 {
address field_0;
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -42,7 +42,7 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple53[] memory permissions) public {
+ function setTokenPropertyPermissions(Tuple58[] memory permissions) public {
require(false, stub_error);
permissions;
dummy = 0;
@@ -51,10 +51,10 @@
/// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() public view returns (Tuple53[] memory) {
+ function tokenPropertyPermissions() public view returns (Tuple58[] memory) {
require(false, stub_error);
dummy;
- return new Tuple53[](0);
+ return new Tuple58[](0);
}
// /// @notice Set token property value.
@@ -133,26 +133,30 @@
bytes value;
}
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
+ /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
Mutable,
+ /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
TokenOwner,
+ /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
CollectionAdmin
}
/// @dev anonymous struct
-struct Tuple53 {
+struct Tuple58 {
string field_0;
- Tuple51[] field_1;
+ Tuple56[] field_1;
}
/// @dev anonymous struct
-struct Tuple51 {
+struct Tuple56 {
EthTokenPermissions field_0;
bool field_1;
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
+/// @dev the ERC-165 identifier for this interface is 0x81172a75
contract Collection is Dummy, ERC165 {
// /// Set collection property.
// ///
@@ -292,6 +296,27 @@
return Tuple29(0x0000000000000000000000000000000000000000, 0);
}
+ /// Get current collection limits.
+ ///
+ /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:
+ /// "accountTokenOwnershipLimit",
+ /// "sponsoredDataSize",
+ /// "sponsoredDataRateLimit",
+ /// "tokenLimit",
+ /// "sponsorTransferTimeout",
+ /// "sponsorApproveTimeout"
+ /// "ownerCanTransfer",
+ /// "ownerCanDestroy",
+ /// "transfersEnabled"
+ /// Return `false` if a limit not set.
+ /// @dev EVM selector for this function is: 0xf63bc572,
+ /// or in textual repr: collectionLimits()
+ function collectionLimits() public view returns (Tuple32[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple32[](0);
+ }
+
/// Set limits for the collection.
/// @dev Throws error if limit not found.
/// @param limit Name of the limit. Valid names:
@@ -304,12 +329,18 @@
/// "ownerCanTransfer",
/// "ownerCanDestroy",
/// "transfersEnabled"
+ /// @param status enable\disable limit. Works only with `true`.
/// @param value Value of the limit.
- /// @dev EVM selector for this function is: 0x4ad890a8,
- /// or in textual repr: setCollectionLimit(string,uint256)
- function setCollectionLimit(string memory limit, uint256 value) public {
+ /// @dev EVM selector for this function is: 0x88150bd0,
+ /// or in textual repr: setCollectionLimit(uint8,bool,uint256)
+ function setCollectionLimit(
+ CollectionLimits limit,
+ bool status,
+ uint256 value
+ ) public {
require(false, stub_error);
limit;
+ status;
value;
dummy = 0;
}
@@ -391,19 +422,19 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() public view returns (Tuple33 memory) {
+ function collectionNestingRestrictedCollectionIds() public view returns (Tuple38 memory) {
require(false, stub_error);
dummy;
- return Tuple33(false, new uint256[](0));
+ return Tuple38(false, new uint256[](0));
}
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() public view returns (Tuple36[] memory) {
+ function collectionNestingPermissions() public view returns (Tuple41[] memory) {
require(false, stub_error);
dummy;
- return new Tuple36[](0);
+ return new Tuple41[](0);
}
/// Set the collection access method.
@@ -583,17 +614,46 @@
}
/// @dev anonymous struct
-struct Tuple36 {
+struct Tuple41 {
CollectionPermissions field_0;
bool field_1;
}
/// @dev anonymous struct
-struct Tuple33 {
+struct Tuple38 {
bool field_0;
uint256[] field_1;
}
+/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.
+enum CollectionLimits {
+ /// @dev How many tokens can a user have on one account.
+ AccountTokenOwnership,
+ /// @dev How many bytes of data are available for sponsorship.
+ SponsoredDataSize,
+ /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+ SponsoredDataRateLimit,
+ /// @dev How many tokens can be mined into this collection.
+ TokenLimit,
+ /// @dev Timeouts for transfer sponsoring.
+ SponsorTransferTimeout,
+ /// @dev Timeout for sponsoring an approval in passed blocks.
+ SponsorApproveTimeout,
+ /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+ OwnerCanTransfer,
+ /// @dev Can the collection owner burn other people's tokens.
+ OwnerCanDestroy,
+ /// @dev Is it possible to send tokens from this collection between users.
+ TransferEnabled
+}
+
+/// @dev anonymous struct
+struct Tuple32 {
+ CollectionLimits field_0;
+ bool field_1;
+ uint256 field_2;
+}
+
/// @dev anonymous struct
struct Tuple29 {
address field_0;
tests/src/eth/abi/fungible.jsondiffbeforeafterboth1[2 {3 "anonymous": false,4 "inputs": [5 {6 "indexed": true,7 "internalType": "address",8 "name": "owner",9 "type": "address"10 },11 {12 "indexed": true,13 "internalType": "address",14 "name": "spender",15 "type": "address"16 },17 {18 "indexed": false,19 "internalType": "uint256",20 "name": "value",21 "type": "uint256"22 }23 ],24 "name": "Approval",25 "type": "event"26 },27 {28 "anonymous": false,29 "inputs": [30 {31 "indexed": true,32 "internalType": "address",33 "name": "from",34 "type": "address"35 },36 {37 "indexed": true,38 "internalType": "address",39 "name": "to",40 "type": "address"41 },42 {43 "indexed": false,44 "internalType": "uint256",45 "name": "value",46 "type": "uint256"47 }48 ],49 "name": "Transfer",50 "type": "event"51 },52 {53 "inputs": [54 {55 "components": [56 { "internalType": "address", "name": "eth", "type": "address" },57 { "internalType": "uint256", "name": "sub", "type": "uint256" }58 ],59 "internalType": "struct EthCrossAccount",60 "name": "newAdmin",61 "type": "tuple"62 }63 ],64 "name": "addCollectionAdminCross",65 "outputs": [],66 "stateMutability": "nonpayable",67 "type": "function"68 },69 {70 "inputs": [71 {72 "components": [73 { "internalType": "address", "name": "eth", "type": "address" },74 { "internalType": "uint256", "name": "sub", "type": "uint256" }75 ],76 "internalType": "struct EthCrossAccount",77 "name": "user",78 "type": "tuple"79 }80 ],81 "name": "addToCollectionAllowListCross",82 "outputs": [],83 "stateMutability": "nonpayable",84 "type": "function"85 },86 {87 "inputs": [88 { "internalType": "address", "name": "owner", "type": "address" },89 { "internalType": "address", "name": "spender", "type": "address" }90 ],91 "name": "allowance",92 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],93 "stateMutability": "view",94 "type": "function"95 },96 {97 "inputs": [98 {99 "components": [100 { "internalType": "address", "name": "eth", "type": "address" },101 { "internalType": "uint256", "name": "sub", "type": "uint256" }102 ],103 "internalType": "struct EthCrossAccount",104 "name": "user",105 "type": "tuple"106 }107 ],108 "name": "allowlistedCross",109 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],110 "stateMutability": "view",111 "type": "function"112 },113 {114 "inputs": [115 { "internalType": "address", "name": "spender", "type": "address" },116 { "internalType": "uint256", "name": "amount", "type": "uint256" }117 ],118 "name": "approve",119 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],120 "stateMutability": "nonpayable",121 "type": "function"122 },123 {124 "inputs": [125 {126 "components": [127 { "internalType": "address", "name": "eth", "type": "address" },128 { "internalType": "uint256", "name": "sub", "type": "uint256" }129 ],130 "internalType": "struct EthCrossAccount",131 "name": "spender",132 "type": "tuple"133 },134 { "internalType": "uint256", "name": "amount", "type": "uint256" }135 ],136 "name": "approveCross",137 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],138 "stateMutability": "nonpayable",139 "type": "function"140 },141 {142 "inputs": [143 { "internalType": "address", "name": "owner", "type": "address" }144 ],145 "name": "balanceOf",146 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],147 "stateMutability": "view",148 "type": "function"149 },150 {151 "inputs": [152 {153 "components": [154 { "internalType": "address", "name": "eth", "type": "address" },155 { "internalType": "uint256", "name": "sub", "type": "uint256" }156 ],157 "internalType": "struct EthCrossAccount",158 "name": "from",159 "type": "tuple"160 },161 { "internalType": "uint256", "name": "amount", "type": "uint256" }162 ],163 "name": "burnFromCross",164 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],165 "stateMutability": "nonpayable",166 "type": "function"167 },168 {169 "inputs": [170 {171 "components": [172 { "internalType": "address", "name": "eth", "type": "address" },173 { "internalType": "uint256", "name": "sub", "type": "uint256" }174 ],175 "internalType": "struct EthCrossAccount",176 "name": "newOwner",177 "type": "tuple"178 }179 ],180 "name": "changeCollectionOwnerCross",181 "outputs": [],182 "stateMutability": "nonpayable",183 "type": "function"184 },185 {186 "inputs": [],187 "name": "collectionAdmins",188 "outputs": [189 {190 "components": [191 { "internalType": "address", "name": "eth", "type": "address" },192 { "internalType": "uint256", "name": "sub", "type": "uint256" }193 ],194 "internalType": "struct EthCrossAccount[]",195 "name": "",196 "type": "tuple[]"197 }198 ],199 "stateMutability": "view",200 "type": "function"201 },202 {203 "inputs": [],204 "name": "collectionHelperAddress",205 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],206 "stateMutability": "view",207 "type": "function"208 },209 {210 "inputs": [],211 "name": "collectionNestingPermissions",212 "outputs": [213 {214 "components": [215 {216 "internalType": "enum CollectionPermissions",217 "name": "field_0",218 "type": "uint8"219 },220 { "internalType": "bool", "name": "field_1", "type": "bool" }221 ],222 "internalType": "struct Tuple24[]",223 "name": "",224 "type": "tuple[]"225 }226 ],227 "stateMutability": "view",228 "type": "function"229 },230 {231 "inputs": [],232 "name": "collectionNestingRestrictedCollectionIds",233 "outputs": [234 {235 "components": [236 { "internalType": "bool", "name": "field_0", "type": "bool" },237 {238 "internalType": "uint256[]",239 "name": "field_1",240 "type": "uint256[]"241 }242 ],243 "internalType": "struct Tuple21",244 "name": "",245 "type": "tuple"246 }247 ],248 "stateMutability": "view",249 "type": "function"250 },251 {252 "inputs": [],253 "name": "collectionOwner",254 "outputs": [255 {256 "components": [257 { "internalType": "address", "name": "eth", "type": "address" },258 { "internalType": "uint256", "name": "sub", "type": "uint256" }259 ],260 "internalType": "struct EthCrossAccount",261 "name": "",262 "type": "tuple"263 }264 ],265 "stateMutability": "view",266 "type": "function"267 },268 {269 "inputs": [270 { "internalType": "string[]", "name": "keys", "type": "string[]" }271 ],272 "name": "collectionProperties",273 "outputs": [274 {275 "components": [276 { "internalType": "string", "name": "key", "type": "string" },277 { "internalType": "bytes", "name": "value", "type": "bytes" }278 ],279 "internalType": "struct Property[]",280 "name": "",281 "type": "tuple[]"282 }283 ],284 "stateMutability": "view",285 "type": "function"286 },287 {288 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],289 "name": "collectionProperty",290 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],291 "stateMutability": "view",292 "type": "function"293 },294 {295 "inputs": [],296 "name": "collectionSponsor",297 "outputs": [298 {299 "components": [300 { "internalType": "address", "name": "field_0", "type": "address" },301 { "internalType": "uint256", "name": "field_1", "type": "uint256" }302 ],303 "internalType": "struct Tuple8",304 "name": "",305 "type": "tuple"306 }307 ],308 "stateMutability": "view",309 "type": "function"310 },311 {312 "inputs": [],313 "name": "confirmCollectionSponsorship",314 "outputs": [],315 "stateMutability": "nonpayable",316 "type": "function"317 },318 {319 "inputs": [],320 "name": "contractAddress",321 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],322 "stateMutability": "view",323 "type": "function"324 },325 {326 "inputs": [],327 "name": "decimals",328 "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],329 "stateMutability": "view",330 "type": "function"331 },332 {333 "inputs": [334 { "internalType": "string[]", "name": "keys", "type": "string[]" }335 ],336 "name": "deleteCollectionProperties",337 "outputs": [],338 "stateMutability": "nonpayable",339 "type": "function"340 },341 {342 "inputs": [],343 "name": "description",344 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],345 "stateMutability": "view",346 "type": "function"347 },348 {349 "inputs": [],350 "name": "hasCollectionPendingSponsor",351 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],352 "stateMutability": "view",353 "type": "function"354 },355 {356 "inputs": [357 {358 "components": [359 { "internalType": "address", "name": "eth", "type": "address" },360 { "internalType": "uint256", "name": "sub", "type": "uint256" }361 ],362 "internalType": "struct EthCrossAccount",363 "name": "user",364 "type": "tuple"365 }366 ],367 "name": "isOwnerOrAdminCross",368 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],369 "stateMutability": "view",370 "type": "function"371 },372 {373 "inputs": [374 { "internalType": "address", "name": "to", "type": "address" },375 { "internalType": "uint256", "name": "amount", "type": "uint256" }376 ],377 "name": "mint",378 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],379 "stateMutability": "nonpayable",380 "type": "function"381 },382 {383 "inputs": [384 {385 "components": [386 { "internalType": "address", "name": "field_0", "type": "address" },387 { "internalType": "uint256", "name": "field_1", "type": "uint256" }388 ],389 "internalType": "struct Tuple8[]",390 "name": "amounts",391 "type": "tuple[]"392 }393 ],394 "name": "mintBulk",395 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],396 "stateMutability": "nonpayable",397 "type": "function"398 },399 {400 "inputs": [],401 "name": "name",402 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],403 "stateMutability": "view",404 "type": "function"405 },406 {407 "inputs": [408 {409 "components": [410 { "internalType": "address", "name": "eth", "type": "address" },411 { "internalType": "uint256", "name": "sub", "type": "uint256" }412 ],413 "internalType": "struct EthCrossAccount",414 "name": "admin",415 "type": "tuple"416 }417 ],418 "name": "removeCollectionAdminCross",419 "outputs": [],420 "stateMutability": "nonpayable",421 "type": "function"422 },423 {424 "inputs": [],425 "name": "removeCollectionSponsor",426 "outputs": [],427 "stateMutability": "nonpayable",428 "type": "function"429 },430 {431 "inputs": [432 {433 "components": [434 { "internalType": "address", "name": "eth", "type": "address" },435 { "internalType": "uint256", "name": "sub", "type": "uint256" }436 ],437 "internalType": "struct EthCrossAccount",438 "name": "user",439 "type": "tuple"440 }441 ],442 "name": "removeFromCollectionAllowListCross",443 "outputs": [],444 "stateMutability": "nonpayable",445 "type": "function"446 },447 {448 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],449 "name": "setCollectionAccess",450 "outputs": [],451 "stateMutability": "nonpayable",452 "type": "function"453 },454 {455 "inputs": [456 { "internalType": "string", "name": "limit", "type": "string" },457 { "internalType": "uint256", "name": "value", "type": "uint256" }458 ],459 "name": "setCollectionLimit",460 "outputs": [],461 "stateMutability": "nonpayable",462 "type": "function"463 },464 {465 "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],466 "name": "setCollectionMintMode",467 "outputs": [],468 "stateMutability": "nonpayable",469 "type": "function"470 },471 {472 "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],473 "name": "setCollectionNesting",474 "outputs": [],475 "stateMutability": "nonpayable",476 "type": "function"477 },478 {479 "inputs": [480 { "internalType": "bool", "name": "enable", "type": "bool" },481 {482 "internalType": "address[]",483 "name": "collections",484 "type": "address[]"485 }486 ],487 "name": "setCollectionNesting",488 "outputs": [],489 "stateMutability": "nonpayable",490 "type": "function"491 },492 {493 "inputs": [494 {495 "components": [496 { "internalType": "string", "name": "key", "type": "string" },497 { "internalType": "bytes", "name": "value", "type": "bytes" }498 ],499 "internalType": "struct Property[]",500 "name": "properties",501 "type": "tuple[]"502 }503 ],504 "name": "setCollectionProperties",505 "outputs": [],506 "stateMutability": "nonpayable",507 "type": "function"508 },509 {510 "inputs": [511 {512 "components": [513 { "internalType": "address", "name": "eth", "type": "address" },514 { "internalType": "uint256", "name": "sub", "type": "uint256" }515 ],516 "internalType": "struct EthCrossAccount",517 "name": "sponsor",518 "type": "tuple"519 }520 ],521 "name": "setCollectionSponsorCross",522 "outputs": [],523 "stateMutability": "nonpayable",524 "type": "function"525 },526 {527 "inputs": [528 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }529 ],530 "name": "supportsInterface",531 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],532 "stateMutability": "view",533 "type": "function"534 },535 {536 "inputs": [],537 "name": "symbol",538 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],539 "stateMutability": "view",540 "type": "function"541 },542 {543 "inputs": [],544 "name": "totalSupply",545 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],546 "stateMutability": "view",547 "type": "function"548 },549 {550 "inputs": [551 { "internalType": "address", "name": "to", "type": "address" },552 { "internalType": "uint256", "name": "amount", "type": "uint256" }553 ],554 "name": "transfer",555 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],556 "stateMutability": "nonpayable",557 "type": "function"558 },559 {560 "inputs": [561 {562 "components": [563 { "internalType": "address", "name": "eth", "type": "address" },564 { "internalType": "uint256", "name": "sub", "type": "uint256" }565 ],566 "internalType": "struct EthCrossAccount",567 "name": "to",568 "type": "tuple"569 },570 { "internalType": "uint256", "name": "amount", "type": "uint256" }571 ],572 "name": "transferCross",573 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],574 "stateMutability": "nonpayable",575 "type": "function"576 },577 {578 "inputs": [579 { "internalType": "address", "name": "from", "type": "address" },580 { "internalType": "address", "name": "to", "type": "address" },581 { "internalType": "uint256", "name": "amount", "type": "uint256" }582 ],583 "name": "transferFrom",584 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],585 "stateMutability": "nonpayable",586 "type": "function"587 },588 {589 "inputs": [590 {591 "components": [592 { "internalType": "address", "name": "eth", "type": "address" },593 { "internalType": "uint256", "name": "sub", "type": "uint256" }594 ],595 "internalType": "struct EthCrossAccount",596 "name": "from",597 "type": "tuple"598 },599 {600 "components": [601 { "internalType": "address", "name": "eth", "type": "address" },602 { "internalType": "uint256", "name": "sub", "type": "uint256" }603 ],604 "internalType": "struct EthCrossAccount",605 "name": "to",606 "type": "tuple"607 },608 { "internalType": "uint256", "name": "amount", "type": "uint256" }609 ],610 "name": "transferFromCross",611 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],612 "stateMutability": "nonpayable",613 "type": "function"614 },615 {616 "inputs": [],617 "name": "uniqueCollectionType",618 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],619 "stateMutability": "view",620 "type": "function"621 }622]1[2 {3 "anonymous": false,4 "inputs": [5 {6 "indexed": true,7 "internalType": "address",8 "name": "owner",9 "type": "address"10 },11 {12 "indexed": true,13 "internalType": "address",14 "name": "spender",15 "type": "address"16 },17 {18 "indexed": false,19 "internalType": "uint256",20 "name": "value",21 "type": "uint256"22 }23 ],24 "name": "Approval",25 "type": "event"26 },27 {28 "anonymous": false,29 "inputs": [30 {31 "indexed": true,32 "internalType": "address",33 "name": "from",34 "type": "address"35 },36 {37 "indexed": true,38 "internalType": "address",39 "name": "to",40 "type": "address"41 },42 {43 "indexed": false,44 "internalType": "uint256",45 "name": "value",46 "type": "uint256"47 }48 ],49 "name": "Transfer",50 "type": "event"51 },52 {53 "inputs": [54 {55 "components": [56 { "internalType": "address", "name": "eth", "type": "address" },57 { "internalType": "uint256", "name": "sub", "type": "uint256" }58 ],59 "internalType": "struct EthCrossAccount",60 "name": "newAdmin",61 "type": "tuple"62 }63 ],64 "name": "addCollectionAdminCross",65 "outputs": [],66 "stateMutability": "nonpayable",67 "type": "function"68 },69 {70 "inputs": [71 {72 "components": [73 { "internalType": "address", "name": "eth", "type": "address" },74 { "internalType": "uint256", "name": "sub", "type": "uint256" }75 ],76 "internalType": "struct EthCrossAccount",77 "name": "user",78 "type": "tuple"79 }80 ],81 "name": "addToCollectionAllowListCross",82 "outputs": [],83 "stateMutability": "nonpayable",84 "type": "function"85 },86 {87 "inputs": [88 { "internalType": "address", "name": "owner", "type": "address" },89 { "internalType": "address", "name": "spender", "type": "address" }90 ],91 "name": "allowance",92 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],93 "stateMutability": "view",94 "type": "function"95 },96 {97 "inputs": [98 {99 "components": [100 { "internalType": "address", "name": "eth", "type": "address" },101 { "internalType": "uint256", "name": "sub", "type": "uint256" }102 ],103 "internalType": "struct EthCrossAccount",104 "name": "user",105 "type": "tuple"106 }107 ],108 "name": "allowlistedCross",109 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],110 "stateMutability": "view",111 "type": "function"112 },113 {114 "inputs": [115 { "internalType": "address", "name": "spender", "type": "address" },116 { "internalType": "uint256", "name": "amount", "type": "uint256" }117 ],118 "name": "approve",119 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],120 "stateMutability": "nonpayable",121 "type": "function"122 },123 {124 "inputs": [125 {126 "components": [127 { "internalType": "address", "name": "eth", "type": "address" },128 { "internalType": "uint256", "name": "sub", "type": "uint256" }129 ],130 "internalType": "struct EthCrossAccount",131 "name": "spender",132 "type": "tuple"133 },134 { "internalType": "uint256", "name": "amount", "type": "uint256" }135 ],136 "name": "approveCross",137 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],138 "stateMutability": "nonpayable",139 "type": "function"140 },141 {142 "inputs": [143 { "internalType": "address", "name": "owner", "type": "address" }144 ],145 "name": "balanceOf",146 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],147 "stateMutability": "view",148 "type": "function"149 },150 {151 "inputs": [152 {153 "components": [154 { "internalType": "address", "name": "eth", "type": "address" },155 { "internalType": "uint256", "name": "sub", "type": "uint256" }156 ],157 "internalType": "struct EthCrossAccount",158 "name": "from",159 "type": "tuple"160 },161 { "internalType": "uint256", "name": "amount", "type": "uint256" }162 ],163 "name": "burnFromCross",164 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],165 "stateMutability": "nonpayable",166 "type": "function"167 },168 {169 "inputs": [170 {171 "components": [172 { "internalType": "address", "name": "eth", "type": "address" },173 { "internalType": "uint256", "name": "sub", "type": "uint256" }174 ],175 "internalType": "struct EthCrossAccount",176 "name": "newOwner",177 "type": "tuple"178 }179 ],180 "name": "changeCollectionOwnerCross",181 "outputs": [],182 "stateMutability": "nonpayable",183 "type": "function"184 },185 {186 "inputs": [],187 "name": "collectionAdmins",188 "outputs": [189 {190 "components": [191 { "internalType": "address", "name": "eth", "type": "address" },192 { "internalType": "uint256", "name": "sub", "type": "uint256" }193 ],194 "internalType": "struct EthCrossAccount[]",195 "name": "",196 "type": "tuple[]"197 }198 ],199 "stateMutability": "view",200 "type": "function"201 },202 {203 "inputs": [],204 "name": "collectionHelperAddress",205 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],206 "stateMutability": "view",207 "type": "function"208 },209 {210 "inputs": [],211 "name": "collectionLimits",212 "outputs": [213 {214 "components": [215 {216 "internalType": "enum CollectionLimits",217 "name": "field_0",218 "type": "uint8"219 },220 { "internalType": "bool", "name": "field_1", "type": "bool" },221 { "internalType": "uint256", "name": "field_2", "type": "uint256" }222 ],223 "internalType": "struct Tuple20[]",224 "name": "",225 "type": "tuple[]"226 }227 ],228 "stateMutability": "view",229 "type": "function"230 },231 {232 "inputs": [],233 "name": "collectionNestingPermissions",234 "outputs": [235 {236 "components": [237 {238 "internalType": "enum CollectionPermissions",239 "name": "field_0",240 "type": "uint8"241 },242 { "internalType": "bool", "name": "field_1", "type": "bool" }243 ],244 "internalType": "struct Tuple29[]",245 "name": "",246 "type": "tuple[]"247 }248 ],249 "stateMutability": "view",250 "type": "function"251 },252 {253 "inputs": [],254 "name": "collectionNestingRestrictedCollectionIds",255 "outputs": [256 {257 "components": [258 { "internalType": "bool", "name": "field_0", "type": "bool" },259 {260 "internalType": "uint256[]",261 "name": "field_1",262 "type": "uint256[]"263 }264 ],265 "internalType": "struct Tuple26",266 "name": "",267 "type": "tuple"268 }269 ],270 "stateMutability": "view",271 "type": "function"272 },273 {274 "inputs": [],275 "name": "collectionOwner",276 "outputs": [277 {278 "components": [279 { "internalType": "address", "name": "eth", "type": "address" },280 { "internalType": "uint256", "name": "sub", "type": "uint256" }281 ],282 "internalType": "struct EthCrossAccount",283 "name": "",284 "type": "tuple"285 }286 ],287 "stateMutability": "view",288 "type": "function"289 },290 {291 "inputs": [292 { "internalType": "string[]", "name": "keys", "type": "string[]" }293 ],294 "name": "collectionProperties",295 "outputs": [296 {297 "components": [298 { "internalType": "string", "name": "key", "type": "string" },299 { "internalType": "bytes", "name": "value", "type": "bytes" }300 ],301 "internalType": "struct Property[]",302 "name": "",303 "type": "tuple[]"304 }305 ],306 "stateMutability": "view",307 "type": "function"308 },309 {310 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],311 "name": "collectionProperty",312 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],313 "stateMutability": "view",314 "type": "function"315 },316 {317 "inputs": [],318 "name": "collectionSponsor",319 "outputs": [320 {321 "components": [322 { "internalType": "address", "name": "field_0", "type": "address" },323 { "internalType": "uint256", "name": "field_1", "type": "uint256" }324 ],325 "internalType": "struct Tuple8",326 "name": "",327 "type": "tuple"328 }329 ],330 "stateMutability": "view",331 "type": "function"332 },333 {334 "inputs": [],335 "name": "confirmCollectionSponsorship",336 "outputs": [],337 "stateMutability": "nonpayable",338 "type": "function"339 },340 {341 "inputs": [],342 "name": "contractAddress",343 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],344 "stateMutability": "view",345 "type": "function"346 },347 {348 "inputs": [],349 "name": "decimals",350 "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],351 "stateMutability": "view",352 "type": "function"353 },354 {355 "inputs": [356 { "internalType": "string[]", "name": "keys", "type": "string[]" }357 ],358 "name": "deleteCollectionProperties",359 "outputs": [],360 "stateMutability": "nonpayable",361 "type": "function"362 },363 {364 "inputs": [],365 "name": "description",366 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],367 "stateMutability": "view",368 "type": "function"369 },370 {371 "inputs": [],372 "name": "hasCollectionPendingSponsor",373 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],374 "stateMutability": "view",375 "type": "function"376 },377 {378 "inputs": [379 {380 "components": [381 { "internalType": "address", "name": "eth", "type": "address" },382 { "internalType": "uint256", "name": "sub", "type": "uint256" }383 ],384 "internalType": "struct EthCrossAccount",385 "name": "user",386 "type": "tuple"387 }388 ],389 "name": "isOwnerOrAdminCross",390 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],391 "stateMutability": "view",392 "type": "function"393 },394 {395 "inputs": [396 { "internalType": "address", "name": "to", "type": "address" },397 { "internalType": "uint256", "name": "amount", "type": "uint256" }398 ],399 "name": "mint",400 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],401 "stateMutability": "nonpayable",402 "type": "function"403 },404 {405 "inputs": [406 {407 "components": [408 { "internalType": "address", "name": "field_0", "type": "address" },409 { "internalType": "uint256", "name": "field_1", "type": "uint256" }410 ],411 "internalType": "struct Tuple8[]",412 "name": "amounts",413 "type": "tuple[]"414 }415 ],416 "name": "mintBulk",417 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],418 "stateMutability": "nonpayable",419 "type": "function"420 },421 {422 "inputs": [],423 "name": "name",424 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],425 "stateMutability": "view",426 "type": "function"427 },428 {429 "inputs": [430 {431 "components": [432 { "internalType": "address", "name": "eth", "type": "address" },433 { "internalType": "uint256", "name": "sub", "type": "uint256" }434 ],435 "internalType": "struct EthCrossAccount",436 "name": "admin",437 "type": "tuple"438 }439 ],440 "name": "removeCollectionAdminCross",441 "outputs": [],442 "stateMutability": "nonpayable",443 "type": "function"444 },445 {446 "inputs": [],447 "name": "removeCollectionSponsor",448 "outputs": [],449 "stateMutability": "nonpayable",450 "type": "function"451 },452 {453 "inputs": [454 {455 "components": [456 { "internalType": "address", "name": "eth", "type": "address" },457 { "internalType": "uint256", "name": "sub", "type": "uint256" }458 ],459 "internalType": "struct EthCrossAccount",460 "name": "user",461 "type": "tuple"462 }463 ],464 "name": "removeFromCollectionAllowListCross",465 "outputs": [],466 "stateMutability": "nonpayable",467 "type": "function"468 },469 {470 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],471 "name": "setCollectionAccess",472 "outputs": [],473 "stateMutability": "nonpayable",474 "type": "function"475 },476 {477 "inputs": [478 {479 "internalType": "enum CollectionLimits",480 "name": "limit",481 "type": "uint8"482 },483 { "internalType": "bool", "name": "status", "type": "bool" },484 { "internalType": "uint256", "name": "value", "type": "uint256" }485 ],486 "name": "setCollectionLimit",487 "outputs": [],488 "stateMutability": "nonpayable",489 "type": "function"490 },491 {492 "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],493 "name": "setCollectionMintMode",494 "outputs": [],495 "stateMutability": "nonpayable",496 "type": "function"497 },498 {499 "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],500 "name": "setCollectionNesting",501 "outputs": [],502 "stateMutability": "nonpayable",503 "type": "function"504 },505 {506 "inputs": [507 { "internalType": "bool", "name": "enable", "type": "bool" },508 {509 "internalType": "address[]",510 "name": "collections",511 "type": "address[]"512 }513 ],514 "name": "setCollectionNesting",515 "outputs": [],516 "stateMutability": "nonpayable",517 "type": "function"518 },519 {520 "inputs": [521 {522 "components": [523 { "internalType": "string", "name": "key", "type": "string" },524 { "internalType": "bytes", "name": "value", "type": "bytes" }525 ],526 "internalType": "struct Property[]",527 "name": "properties",528 "type": "tuple[]"529 }530 ],531 "name": "setCollectionProperties",532 "outputs": [],533 "stateMutability": "nonpayable",534 "type": "function"535 },536 {537 "inputs": [538 {539 "components": [540 { "internalType": "address", "name": "eth", "type": "address" },541 { "internalType": "uint256", "name": "sub", "type": "uint256" }542 ],543 "internalType": "struct EthCrossAccount",544 "name": "sponsor",545 "type": "tuple"546 }547 ],548 "name": "setCollectionSponsorCross",549 "outputs": [],550 "stateMutability": "nonpayable",551 "type": "function"552 },553 {554 "inputs": [555 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }556 ],557 "name": "supportsInterface",558 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],559 "stateMutability": "view",560 "type": "function"561 },562 {563 "inputs": [],564 "name": "symbol",565 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],566 "stateMutability": "view",567 "type": "function"568 },569 {570 "inputs": [],571 "name": "totalSupply",572 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],573 "stateMutability": "view",574 "type": "function"575 },576 {577 "inputs": [578 { "internalType": "address", "name": "to", "type": "address" },579 { "internalType": "uint256", "name": "amount", "type": "uint256" }580 ],581 "name": "transfer",582 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],583 "stateMutability": "nonpayable",584 "type": "function"585 },586 {587 "inputs": [588 {589 "components": [590 { "internalType": "address", "name": "eth", "type": "address" },591 { "internalType": "uint256", "name": "sub", "type": "uint256" }592 ],593 "internalType": "struct EthCrossAccount",594 "name": "to",595 "type": "tuple"596 },597 { "internalType": "uint256", "name": "amount", "type": "uint256" }598 ],599 "name": "transferCross",600 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],601 "stateMutability": "nonpayable",602 "type": "function"603 },604 {605 "inputs": [606 { "internalType": "address", "name": "from", "type": "address" },607 { "internalType": "address", "name": "to", "type": "address" },608 { "internalType": "uint256", "name": "amount", "type": "uint256" }609 ],610 "name": "transferFrom",611 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],612 "stateMutability": "nonpayable",613 "type": "function"614 },615 {616 "inputs": [617 {618 "components": [619 { "internalType": "address", "name": "eth", "type": "address" },620 { "internalType": "uint256", "name": "sub", "type": "uint256" }621 ],622 "internalType": "struct EthCrossAccount",623 "name": "from",624 "type": "tuple"625 },626 {627 "components": [628 { "internalType": "address", "name": "eth", "type": "address" },629 { "internalType": "uint256", "name": "sub", "type": "uint256" }630 ],631 "internalType": "struct EthCrossAccount",632 "name": "to",633 "type": "tuple"634 },635 { "internalType": "uint256", "name": "amount", "type": "uint256" }636 ],637 "name": "transferFromCross",638 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],639 "stateMutability": "nonpayable",640 "type": "function"641 },642 {643 "inputs": [],644 "name": "uniqueCollectionType",645 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],646 "stateMutability": "view",647 "type": "function"648 }649]tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -238,6 +238,28 @@
},
{
"inputs": [],
+ "name": "collectionLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "enum CollectionLimits",
+ "name": "field_0",
+ "type": "uint8"
+ },
+ { "internalType": "bool", "name": "field_1", "type": "bool" },
+ { "internalType": "uint256", "name": "field_2", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple33[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionNestingPermissions",
"outputs": [
{
@@ -249,7 +271,7 @@
},
{ "internalType": "bool", "name": "field_1", "type": "bool" }
],
- "internalType": "struct Tuple37[]",
+ "internalType": "struct Tuple42[]",
"name": "",
"type": "tuple[]"
}
@@ -270,7 +292,7 @@
"type": "uint256[]"
}
],
- "internalType": "struct Tuple34",
+ "internalType": "struct Tuple39",
"name": "",
"type": "tuple"
}
@@ -607,7 +629,12 @@
},
{
"inputs": [
- { "internalType": "string", "name": "limit", "type": "string" },
+ {
+ "internalType": "enum CollectionLimits",
+ "name": "limit",
+ "type": "uint8"
+ },
+ { "internalType": "bool", "name": "status", "type": "bool" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "setCollectionLimit",
@@ -709,12 +736,12 @@
},
{ "internalType": "bool", "name": "field_1", "type": "bool" }
],
- "internalType": "struct Tuple46[]",
+ "internalType": "struct Tuple57[]",
"name": "field_1",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple48[]",
+ "internalType": "struct Tuple59[]",
"name": "permissions",
"type": "tuple[]"
}
@@ -775,12 +802,12 @@
},
{ "internalType": "bool", "name": "field_1", "type": "bool" }
],
- "internalType": "struct Tuple46[]",
+ "internalType": "struct Tuple57[]",
"name": "field_1",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple48[]",
+ "internalType": "struct Tuple59[]",
"name": "",
"type": "tuple[]"
}
tests/src/eth/abi/reFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -220,6 +220,28 @@
},
{
"inputs": [],
+ "name": "collectionLimits",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "enum CollectionLimits",
+ "name": "field_0",
+ "type": "uint8"
+ },
+ { "internalType": "bool", "name": "field_1", "type": "bool" },
+ { "internalType": "uint256", "name": "field_2", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple32[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionNestingPermissions",
"outputs": [
{
@@ -231,7 +253,7 @@
},
{ "internalType": "bool", "name": "field_1", "type": "bool" }
],
- "internalType": "struct Tuple36[]",
+ "internalType": "struct Tuple41[]",
"name": "",
"type": "tuple[]"
}
@@ -252,7 +274,7 @@
"type": "uint256[]"
}
],
- "internalType": "struct Tuple33",
+ "internalType": "struct Tuple38",
"name": "",
"type": "tuple"
}
@@ -589,7 +611,12 @@
},
{
"inputs": [
- { "internalType": "string", "name": "limit", "type": "string" },
+ {
+ "internalType": "enum CollectionLimits",
+ "name": "limit",
+ "type": "uint8"
+ },
+ { "internalType": "bool", "name": "status", "type": "bool" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "setCollectionLimit",
@@ -691,12 +718,12 @@
},
{ "internalType": "bool", "name": "field_1", "type": "bool" }
],
- "internalType": "struct Tuple51[]",
+ "internalType": "struct Tuple56[]",
"name": "field_1",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple53[]",
+ "internalType": "struct Tuple58[]",
"name": "permissions",
"type": "tuple[]"
}
@@ -766,12 +793,12 @@
},
{ "internalType": "bool", "name": "field_1", "type": "bool" }
],
- "internalType": "struct Tuple51[]",
+ "internalType": "struct Tuple56[]",
"name": "field_1",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple53[]",
+ "internalType": "struct Tuple58[]",
"name": "",
"type": "tuple[]"
}
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 0xb5e1747f
+/// @dev the ERC-165 identifier for this interface is 0x81172a75
interface Collection is Dummy, ERC165 {
// /// Set collection property.
// ///
@@ -104,6 +104,23 @@
/// or in textual repr: collectionSponsor()
function collectionSponsor() external view returns (Tuple8 memory);
+ /// Get current collection limits.
+ ///
+ /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:
+ /// "accountTokenOwnershipLimit",
+ /// "sponsoredDataSize",
+ /// "sponsoredDataRateLimit",
+ /// "tokenLimit",
+ /// "sponsorTransferTimeout",
+ /// "sponsorApproveTimeout"
+ /// "ownerCanTransfer",
+ /// "ownerCanDestroy",
+ /// "transfersEnabled"
+ /// Return `false` if a limit not set.
+ /// @dev EVM selector for this function is: 0xf63bc572,
+ /// or in textual repr: collectionLimits()
+ function collectionLimits() external view returns (Tuple19[] memory);
+
/// Set limits for the collection.
/// @dev Throws error if limit not found.
/// @param limit Name of the limit. Valid names:
@@ -116,10 +133,15 @@
/// "ownerCanTransfer",
/// "ownerCanDestroy",
/// "transfersEnabled"
+ /// @param status enable\disable limit. Works only with `true`.
/// @param value Value of the limit.
- /// @dev EVM selector for this function is: 0x4ad890a8,
- /// or in textual repr: setCollectionLimit(string,uint256)
- function setCollectionLimit(string memory limit, uint256 value) external;
+ /// @dev EVM selector for this function is: 0x88150bd0,
+ /// or in textual repr: setCollectionLimit(uint8,bool,uint256)
+ function setCollectionLimit(
+ CollectionLimits limit,
+ bool status,
+ uint256 value
+ ) external;
/// Get contract address.
/// @dev EVM selector for this function is: 0xf6b4dfb4,
@@ -169,12 +191,12 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() external view returns (Tuple20 memory);
+ function collectionNestingRestrictedCollectionIds() external view returns (Tuple24 memory);
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() external view returns (Tuple23[] memory);
+ function collectionNestingPermissions() external view returns (Tuple27[] memory);
/// Set the collection access method.
/// @param mode Access mode
@@ -289,7 +311,7 @@
}
/// @dev anonymous struct
-struct Tuple23 {
+struct Tuple27 {
CollectionPermissions field_0;
bool field_1;
}
@@ -300,11 +322,40 @@
}
/// @dev anonymous struct
-struct Tuple20 {
+struct Tuple24 {
bool field_0;
uint256[] field_1;
}
+/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.
+enum CollectionLimits {
+ /// @dev How many tokens can a user have on one account.
+ AccountTokenOwnership,
+ /// @dev How many bytes of data are available for sponsorship.
+ SponsoredDataSize,
+ /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+ SponsoredDataRateLimit,
+ /// @dev How many tokens can be mined into this collection.
+ TokenLimit,
+ /// @dev Timeouts for transfer sponsoring.
+ SponsorTransferTimeout,
+ /// @dev Timeout for sponsoring an approval in passed blocks.
+ SponsorApproveTimeout,
+ /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+ OwnerCanTransfer,
+ /// @dev Can the collection owner burn other people's tokens.
+ OwnerCanDestroy,
+ /// @dev Is it possible to send tokens from this collection between users.
+ TransferEnabled
+}
+
+/// @dev anonymous struct
+struct Tuple19 {
+ CollectionLimits field_0;
+ bool field_1;
+ uint256 field_2;
+}
+
/// @dev Property struct
struct Property {
string key;
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -30,11 +30,12 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple43[] memory permissions) external;
+ function setTokenPropertyPermissions(Tuple52[] memory permissions) external;
+ /// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() external view returns (Tuple43[] memory);
+ function tokenPropertyPermissions() external view returns (Tuple52[] memory);
// /// @notice Set token property value.
// /// @dev Throws error if `msg.sender` has no permission to edit the property.
@@ -85,26 +86,30 @@
bytes value;
}
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
+ /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
Mutable,
+ /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
TokenOwner,
+ /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
CollectionAdmin
}
/// @dev anonymous struct
-struct Tuple43 {
+struct Tuple52 {
string field_0;
- Tuple41[] field_1;
+ Tuple50[] field_1;
}
/// @dev anonymous struct
-struct Tuple41 {
+struct Tuple50 {
EthTokenPermissions field_0;
bool field_1;
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
+/// @dev the ERC-165 identifier for this interface is 0x81172a75
interface Collection is Dummy, ERC165 {
// /// Set collection property.
// ///
@@ -195,6 +200,23 @@
/// or in textual repr: collectionSponsor()
function collectionSponsor() external view returns (Tuple27 memory);
+ /// Get current collection limits.
+ ///
+ /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:
+ /// "accountTokenOwnershipLimit",
+ /// "sponsoredDataSize",
+ /// "sponsoredDataRateLimit",
+ /// "tokenLimit",
+ /// "sponsorTransferTimeout",
+ /// "sponsorApproveTimeout"
+ /// "ownerCanTransfer",
+ /// "ownerCanDestroy",
+ /// "transfersEnabled"
+ /// Return `false` if a limit not set.
+ /// @dev EVM selector for this function is: 0xf63bc572,
+ /// or in textual repr: collectionLimits()
+ function collectionLimits() external view returns (Tuple30[] memory);
+
/// Set limits for the collection.
/// @dev Throws error if limit not found.
/// @param limit Name of the limit. Valid names:
@@ -207,10 +229,15 @@
/// "ownerCanTransfer",
/// "ownerCanDestroy",
/// "transfersEnabled"
+ /// @param status enable\disable limit. Works only with `true`.
/// @param value Value of the limit.
- /// @dev EVM selector for this function is: 0x4ad890a8,
- /// or in textual repr: setCollectionLimit(string,uint256)
- function setCollectionLimit(string memory limit, uint256 value) external;
+ /// @dev EVM selector for this function is: 0x88150bd0,
+ /// or in textual repr: setCollectionLimit(uint8,bool,uint256)
+ function setCollectionLimit(
+ CollectionLimits limit,
+ bool status,
+ uint256 value
+ ) external;
/// Get contract address.
/// @dev EVM selector for this function is: 0xf6b4dfb4,
@@ -260,12 +287,12 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() external view returns (Tuple31 memory);
+ function collectionNestingRestrictedCollectionIds() external view returns (Tuple35 memory);
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() external view returns (Tuple34[] memory);
+ function collectionNestingPermissions() external view returns (Tuple38[] memory);
/// Set the collection access method.
/// @param mode Access mode
@@ -380,7 +407,7 @@
}
/// @dev anonymous struct
-struct Tuple34 {
+struct Tuple38 {
CollectionPermissions field_0;
bool field_1;
}
@@ -391,11 +418,40 @@
}
/// @dev anonymous struct
-struct Tuple31 {
+struct Tuple35 {
bool field_0;
uint256[] field_1;
}
+/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.
+enum CollectionLimits {
+ /// @dev How many tokens can a user have on one account.
+ AccountTokenOwnership,
+ /// @dev How many bytes of data are available for sponsorship.
+ SponsoredDataSize,
+ /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+ SponsoredDataRateLimit,
+ /// @dev How many tokens can be mined into this collection.
+ TokenLimit,
+ /// @dev Timeouts for transfer sponsoring.
+ SponsorTransferTimeout,
+ /// @dev Timeout for sponsoring an approval in passed blocks.
+ SponsorApproveTimeout,
+ /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+ OwnerCanTransfer,
+ /// @dev Can the collection owner burn other people's tokens.
+ OwnerCanDestroy,
+ /// @dev Is it possible to send tokens from this collection between users.
+ TransferEnabled
+}
+
+/// @dev anonymous struct
+struct Tuple30 {
+ CollectionLimits field_0;
+ bool field_1;
+ uint256 field_2;
+}
+
/// @dev anonymous struct
struct Tuple27 {
address field_0;
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -30,12 +30,12 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple47[] memory permissions) external;
+ function setTokenPropertyPermissions(Tuple51[] memory permissions) external;
/// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() external view returns (Tuple47[] memory);
+ function tokenPropertyPermissions() external view returns (Tuple51[] memory);
// /// @notice Set token property value.
// /// @dev Throws error if `msg.sender` has no permission to edit the property.
@@ -86,26 +86,30 @@
bytes value;
}
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
+ /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
Mutable,
+ /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
TokenOwner,
+ /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
CollectionAdmin
}
/// @dev anonymous struct
-struct Tuple47 {
+struct Tuple51 {
string field_0;
- Tuple45[] field_1;
+ Tuple49[] field_1;
}
/// @dev anonymous struct
-struct Tuple45 {
+struct Tuple49 {
EthTokenPermissions field_0;
bool field_1;
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
+/// @dev the ERC-165 identifier for this interface is 0x81172a75
interface Collection is Dummy, ERC165 {
// /// Set collection property.
// ///
@@ -196,6 +200,23 @@
/// or in textual repr: collectionSponsor()
function collectionSponsor() external view returns (Tuple26 memory);
+ /// Get current collection limits.
+ ///
+ /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:
+ /// "accountTokenOwnershipLimit",
+ /// "sponsoredDataSize",
+ /// "sponsoredDataRateLimit",
+ /// "tokenLimit",
+ /// "sponsorTransferTimeout",
+ /// "sponsorApproveTimeout"
+ /// "ownerCanTransfer",
+ /// "ownerCanDestroy",
+ /// "transfersEnabled"
+ /// Return `false` if a limit not set.
+ /// @dev EVM selector for this function is: 0xf63bc572,
+ /// or in textual repr: collectionLimits()
+ function collectionLimits() external view returns (Tuple29[] memory);
+
/// Set limits for the collection.
/// @dev Throws error if limit not found.
/// @param limit Name of the limit. Valid names:
@@ -208,10 +229,15 @@
/// "ownerCanTransfer",
/// "ownerCanDestroy",
/// "transfersEnabled"
+ /// @param status enable\disable limit. Works only with `true`.
/// @param value Value of the limit.
- /// @dev EVM selector for this function is: 0x4ad890a8,
- /// or in textual repr: setCollectionLimit(string,uint256)
- function setCollectionLimit(string memory limit, uint256 value) external;
+ /// @dev EVM selector for this function is: 0x88150bd0,
+ /// or in textual repr: setCollectionLimit(uint8,bool,uint256)
+ function setCollectionLimit(
+ CollectionLimits limit,
+ bool status,
+ uint256 value
+ ) external;
/// Get contract address.
/// @dev EVM selector for this function is: 0xf6b4dfb4,
@@ -261,12 +287,12 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() external view returns (Tuple30 memory);
+ function collectionNestingRestrictedCollectionIds() external view returns (Tuple34 memory);
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() external view returns (Tuple33[] memory);
+ function collectionNestingPermissions() external view returns (Tuple37[] memory);
/// Set the collection access method.
/// @param mode Access mode
@@ -381,7 +407,7 @@
}
/// @dev anonymous struct
-struct Tuple33 {
+struct Tuple37 {
CollectionPermissions field_0;
bool field_1;
}
@@ -392,11 +418,40 @@
}
/// @dev anonymous struct
-struct Tuple30 {
+struct Tuple34 {
bool field_0;
uint256[] field_1;
}
+/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.
+enum CollectionLimits {
+ /// @dev How many tokens can a user have on one account.
+ AccountTokenOwnership,
+ /// @dev How many bytes of data are available for sponsorship.
+ SponsoredDataSize,
+ /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+ SponsoredDataRateLimit,
+ /// @dev How many tokens can be mined into this collection.
+ TokenLimit,
+ /// @dev Timeouts for transfer sponsoring.
+ SponsorTransferTimeout,
+ /// @dev Timeout for sponsoring an approval in passed blocks.
+ SponsorApproveTimeout,
+ /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+ OwnerCanTransfer,
+ /// @dev Can the collection owner burn other people's tokens.
+ OwnerCanDestroy,
+ /// @dev Is it possible to send tokens from this collection between users.
+ TransferEnabled
+}
+
+/// @dev anonymous struct
+struct Tuple29 {
+ CollectionLimits field_0;
+ bool field_1;
+ uint256 field_2;
+}
+
/// @dev anonymous struct
struct Tuple26 {
address field_0;
tests/src/eth/collectionLimits.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionLimits.test.ts
+++ b/tests/src/eth/collectionLimits.test.ts
@@ -1,6 +1,7 @@
import {IKeyringPair} from '@polkadot/types/types';
import {Pallets} from '../util';
import {expect, itEth, usingEthPlaygrounds} from './util';
+import {CollectionLimits} from './util/playgrounds/types';
describe('Can set collection limits', () => {
@@ -44,20 +45,33 @@
transfersEnabled: false,
};
- const collection = helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
- await collection.methods.setCollectionLimit('accountTokenOwnershipLimit', limits.accountTokenOwnershipLimit).send();
- await collection.methods.setCollectionLimit('sponsoredDataSize', limits.sponsoredDataSize).send();
- await collection.methods.setCollectionLimit('sponsoredDataRateLimit', limits.sponsoredDataRateLimit).send();
- await collection.methods.setCollectionLimit('tokenLimit', limits.tokenLimit).send();
- await collection.methods.setCollectionLimit('sponsorTransferTimeout', limits.sponsorTransferTimeout).send();
- await collection.methods.setCollectionLimit('sponsorApproveTimeout', limits.sponsorApproveTimeout).send();
- await collection.methods.setCollectionLimit('ownerCanTransfer', limits.ownerCanTransfer).send();
- await collection.methods.setCollectionLimit('ownerCanDestroy', limits.ownerCanDestroy).send();
- await collection.methods.setCollectionLimit('transfersEnabled', limits.transfersEnabled).send();
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, limits.accountTokenOwnershipLimit).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsoredDataSize, true, limits.sponsoredDataSize).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsoredDataRateLimit, true, limits.sponsoredDataRateLimit).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.TokenLimit, true, limits.tokenLimit).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsorTransferTimeout, true, limits.sponsorTransferTimeout).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsorApproveTimeout, true, limits.sponsorApproveTimeout).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.OwnerCanTransfer, true, limits.ownerCanTransfer).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.OwnerCanDestroy, true, limits.ownerCanDestroy).send();
+ await collectionEvm.methods.setCollectionLimit(CollectionLimits.TransferEnabled, true, limits.transfersEnabled).send();
+ // Check limits from sub:
const data = (await helper.rft.getData(collectionId))!;
expect(data.raw.limits).to.deep.eq(expectedLimits);
expect(await helper.collection.getEffectiveLimits(collectionId)).to.deep.eq(expectedLimits);
+ // Check limits from eth:
+ const limitsEvm = await collectionEvm.methods.collectionLimits().call({from: owner});
+ expect(limitsEvm).to.have.length(9);
+ expect(limitsEvm[0]).to.deep.eq([CollectionLimits.AccountTokenOwnership.toString(), true, limits.accountTokenOwnershipLimit.toString()]);
+ expect(limitsEvm[1]).to.deep.eq([CollectionLimits.SponsoredDataSize.toString(), true, limits.sponsoredDataSize.toString()]);
+ expect(limitsEvm[2]).to.deep.eq([CollectionLimits.SponsoredDataRateLimit.toString(), true, limits.sponsoredDataRateLimit.toString()]);
+ expect(limitsEvm[3]).to.deep.eq([CollectionLimits.TokenLimit.toString(), true, limits.tokenLimit.toString()]);
+ expect(limitsEvm[4]).to.deep.eq([CollectionLimits.SponsorTransferTimeout.toString(), true, limits.sponsorTransferTimeout.toString()]);
+ expect(limitsEvm[5]).to.deep.eq([CollectionLimits.SponsorApproveTimeout.toString(), true, limits.sponsorApproveTimeout.toString()]);
+ expect(limitsEvm[6]).to.deep.eq([CollectionLimits.OwnerCanTransfer.toString(), true, limits.ownerCanTransfer.toString()]);
+ expect(limitsEvm[7]).to.deep.eq([CollectionLimits.OwnerCanDestroy.toString(), true, limits.ownerCanDestroy.toString()]);
+ expect(limitsEvm[8]).to.deep.eq([CollectionLimits.TransferEnabled.toString(), true, limits.transfersEnabled.toString()]);
}));
});
@@ -84,17 +98,48 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress} = await helper.eth.createCollection(testCase.case, owner, 'Limits', 'absolutely anything', 'ISNI', 18);
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
+
+ // Cannot set non-existing limit
await expect(collectionEvm.methods
- .setCollectionLimit('badLimit', '1')
- .call()).to.be.rejectedWith('unknown limit "badLimit"');
-
+ .setCollectionLimit(9, true, 1)
+ .call()).to.be.rejectedWith('Returned error: VM Exception while processing transaction: revert Value not convertible into enum "CollectionLimits"');
+
+ // Cannot disable limits
+ await expect(collectionEvm.methods
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, false, 200)
+ .call()).to.be.rejectedWith('Returned error: VM Exception while processing transaction: revert user can\'t disable limits');
+
await expect(collectionEvm.methods
- .setCollectionLimit(Object.keys(invalidLimits)[0], invalidLimits.accountTokenOwnershipLimit)
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, invalidLimits.accountTokenOwnershipLimit)
.call()).to.be.rejectedWith(`can't convert value to u32 "${invalidLimits.accountTokenOwnershipLimit}"`);
-
+
await expect(collectionEvm.methods
- .setCollectionLimit(Object.keys(invalidLimits)[1], invalidLimits.transfersEnabled)
+ .setCollectionLimit(CollectionLimits.TransferEnabled, true, 3)
.call()).to.be.rejectedWith(`can't convert value to boolean "${invalidLimits.transfersEnabled}"`);
+
+ expect(() => collectionEvm.methods
+ .setCollectionLimit(CollectionLimits.SponsoredDataSize, true, -1).send()).to.throw('value out-of-bounds');
}));
+
+ [
+ {case: 'nft' as const, requiredPallets: []},
+ {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+ {case: 'ft' as const, requiredPallets: []},
+ ].map(testCase =>
+ itEth.ifWithPallets(`Non-owner and non-admin cannot set collection limits for ${testCase.case}`, testCase.requiredPallets || [], async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const nonOwner = await helper.eth.createAccountWithBalance(donor);
+ const {collectionAddress} = await helper.eth.createCollection(testCase.case, owner, 'Limits', 'absolutely anything', 'FLO', 18);
+
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
+ await expect(collectionEvm.methods
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
+ .call({from: nonOwner}))
+ .to.be.rejectedWith('NoPermission');
+
+ await expect(collectionEvm.methods
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
+ .send({from: nonOwner}))
+ .to.be.rejected;
+ }));
});
-
\ No newline at end of file
tests/src/eth/createFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createFTCollection.test.ts
+++ b/tests/src/eth/createFTCollection.test.ts
@@ -18,6 +18,7 @@
import {evmToAddress} from '@polkadot/util-crypto';
import {Pallets, requirePalletsOrSkip} from '../util';
import {expect, itEth, usingEthPlaygrounds} from './util';
+import { CollectionLimits } from './util/playgrounds/types';
const DECIMALS = 18;
@@ -196,7 +197,7 @@
}
{
await expect(peasantCollection.methods
- .setCollectionLimit('accountTokenOwnershipLimit', '1000')
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
}
});
@@ -221,7 +222,7 @@
}
{
await expect(peasantCollection.methods
- .setCollectionLimit('accountTokenOwnershipLimit', '1000')
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
}
});
tests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createNFTCollection.test.ts
+++ b/tests/src/eth/createNFTCollection.test.ts
@@ -17,6 +17,7 @@
import {evmToAddress} from '@polkadot/util-crypto';
import {IKeyringPair} from '@polkadot/types/types';
import {expect, itEth, usingEthPlaygrounds} from './util';
+import { CollectionLimits } from './util/playgrounds/types';
describe('Create NFT collection from EVM', () => {
@@ -207,7 +208,7 @@
}
{
await expect(malfeasantCollection.methods
- .setCollectionLimit('accountTokenOwnershipLimit', '1000')
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
}
});
@@ -232,7 +233,7 @@
}
{
await expect(malfeasantCollection.methods
- .setCollectionLimit('accountTokenOwnershipLimit', '1000')
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
}
});
tests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createRFTCollection.test.ts
+++ b/tests/src/eth/createRFTCollection.test.ts
@@ -18,6 +18,7 @@
import {IKeyringPair} from '@polkadot/types/types';
import {Pallets, requirePalletsOrSkip} from '../util';
import {expect, itEth, usingEthPlaygrounds} from './util';
+import {CollectionLimits} from './util/playgrounds/types';
describe('Create RFT collection from EVM', () => {
@@ -239,7 +240,7 @@
}
{
await expect(peasantCollection.methods
- .setCollectionLimit('accountTokenOwnershipLimit', '1000')
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
}
});
@@ -264,7 +265,7 @@
}
{
await expect(peasantCollection.methods
- .setCollectionLimit('accountTokenOwnershipLimit', '1000')
+ .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
}
});
tests/src/eth/events.test.tsdiffbeforeafterboth--- a/tests/src/eth/events.test.ts
+++ b/tests/src/eth/events.test.ts
@@ -19,7 +19,7 @@
import {EthUniqueHelper, itEth, usingEthPlaygrounds} from './util';
import {IEvent, TCollectionMode} from '../util/playgrounds/types';
import {Pallets, requirePalletsOrSkip} from '../util';
-import {EthTokenPermissions, NormalizedEvent} from './util/playgrounds/types';
+import {CollectionLimits, EthTokenPermissions, NormalizedEvent} from './util/playgrounds/types';
let donor: IKeyringPair;
@@ -234,7 +234,7 @@
});
const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionLimitSet']}]);
{
- await collection.methods.setCollectionLimit('ownerCanTransfer', 0n).send({from: owner});
+ await collection.methods.setCollectionLimit(CollectionLimits.OwnerCanTransfer, true, 0).send({from: owner});
await helper.wait.newBlocks(1);
expect(ethEvents).to.be.like([
{
tests/src/eth/util/playgrounds/types.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/types.ts
+++ b/tests/src/eth/util/playgrounds/types.ts
@@ -24,4 +24,15 @@
Mutable,
TokenOwner,
CollectionAdmin
-}
\ No newline at end of file
+}
+export enum CollectionLimits {
+ AccountTokenOwnership,
+ SponsoredDataSize,
+ SponsoredDataRateLimit,
+ TokenLimit,
+ SponsorTransferTimeout,
+ SponsorApproveTimeout,
+ OwnerCanTransfer,
+ OwnerCanDestroy,
+ TransferEnabled
+}
tests/src/pallet-presence.test.tsdiffbeforeafterboth--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -84,6 +84,7 @@
);
} else if (chain.eq('UNIQUE')) {
// Insert Unique additional pallets here
+ requiredPallets.push(foreignAssets);
}
});
});