difftreelog
refactor remove last anonimous structs
in: master
14 files changed
pallets/common/src/erc.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! This module contains the implementation of pallet methods for evm.1819pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};20use evm_coder::{21 abi::AbiType,22 solidity_interface, solidity, ToLog,23 types::*,24 execution::{Result, Error},25 weight,26};27use pallet_evm_coder_substrate::dispatch_to_evm;28use sp_std::{vec, vec::Vec};29use up_data_structs::{30 AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,31 SponsoringRateLimit, SponsorshipState,32};33use alloc::format;3435use crate::{36 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,37 eth::{CollectionLimitField as EvmCollectionLimits, self},38 weights::WeightInfo,39};4041/// Events for ethereum collection helper.42#[derive(ToLog)]43pub enum CollectionHelpersEvents {44 /// The collection has been created.45 CollectionCreated {46 /// Collection owner.47 #[indexed]48 owner: address,4950 /// Collection ID.51 #[indexed]52 collection_id: address,53 },54 /// The collection has been destroyed.55 CollectionDestroyed {56 /// Collection ID.57 #[indexed]58 collection_id: address,59 },60 /// The collection has been changed.61 CollectionChanged {62 /// Collection ID.63 #[indexed]64 collection_id: address,65 },6667 /// The token has been changed.68 TokenChanged {69 /// Collection ID.70 #[indexed]71 collection_id: address,72 /// Token ID.73 token_id: uint256,74 },75}7677/// Does not always represent a full collection, for RFT it is either78/// collection (Implementing ERC721), or specific collection token (Implementing ERC20).79pub trait CommonEvmHandler {80 /// Raw compiled binary code of the contract stub81 const CODE: &'static [u8];8283 /// Call precompiled handle.84 fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult>;85}8687/// @title A contract that allows you to work with collections.88#[solidity_interface(name = Collection)]89impl<T: Config> CollectionHandle<T>90where91 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,92{93 /// Set collection property.94 ///95 /// @param key Property key.96 /// @param value Propery value.97 #[solidity(hide)]98 #[weight(<SelfWeightOf<T>>::set_collection_properties(1))]99 fn set_collection_property(100 &mut self,101 caller: caller,102 key: string,103 value: bytes,104 ) -> Result<void> {105 let caller = T::CrossAccountId::from_eth(caller);106 let key = <Vec<u8>>::from(key)107 .try_into()108 .map_err(|_| "key too large")?;109 let value = value.0.try_into().map_err(|_| "value too large")?;110111 <Pallet<T>>::set_collection_property(self, &caller, Property { key, value })112 .map_err(dispatch_to_evm::<T>)113 }114115 /// Set collection properties.116 ///117 /// @param properties Vector of properties key/value pair.118 #[weight(<SelfWeightOf<T>>::set_collection_properties(properties.len() as u32))]119 fn set_collection_properties(120 &mut self,121 caller: caller,122 properties: Vec<eth::Property>,123 ) -> Result<void> {124 let caller = T::CrossAccountId::from_eth(caller);125126 let properties = properties127 .into_iter()128 .map(|eth::Property { key, value }| {129 let key = <Vec<u8>>::from(key)130 .try_into()131 .map_err(|_| "key too large")?;132133 let value = value.0.try_into().map_err(|_| "value too large")?;134135 Ok(Property { key, value })136 })137 .collect::<Result<Vec<_>>>()?;138139 <Pallet<T>>::set_collection_properties(self, &caller, properties)140 .map_err(dispatch_to_evm::<T>)141 }142143 /// Delete collection property.144 ///145 /// @param key Property key.146 #[solidity(hide)]147 #[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]148 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {149 let caller = T::CrossAccountId::from_eth(caller);150 let key = <Vec<u8>>::from(key)151 .try_into()152 .map_err(|_| "key too large")?;153154 <Pallet<T>>::delete_collection_property(self, &caller, key).map_err(dispatch_to_evm::<T>)155 }156157 /// Delete collection properties.158 ///159 /// @param keys Properties keys.160 #[weight(<SelfWeightOf<T>>::delete_collection_properties(keys.len() as u32))]161 fn delete_collection_properties(&mut self, caller: caller, keys: Vec<string>) -> Result<()> {162 let caller = T::CrossAccountId::from_eth(caller);163 let keys = keys164 .into_iter()165 .map(|key| {166 <Vec<u8>>::from(key)167 .try_into()168 .map_err(|_| Error::Revert("key too large".into()))169 })170 .collect::<Result<Vec<_>>>()?;171172 <Pallet<T>>::delete_collection_properties(self, &caller, keys).map_err(dispatch_to_evm::<T>)173 }174175 /// Get collection property.176 ///177 /// @dev Throws error if key not found.178 ///179 /// @param key Property key.180 /// @return bytes The property corresponding to the key.181 fn collection_property(&self, key: string) -> Result<bytes> {182 let key = <Vec<u8>>::from(key)183 .try_into()184 .map_err(|_| "key too large")?;185186 let props = CollectionProperties::<T>::get(self.id);187 let prop = props.get(&key).ok_or("key not found")?;188189 Ok(bytes(prop.to_vec()))190 }191192 /// Get collection properties.193 ///194 /// @param keys Properties keys. Empty keys for all propertyes.195 /// @return Vector of properties key/value pairs.196 fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<eth::Property>> {197 let keys = keys198 .into_iter()199 .map(|key| {200 <Vec<u8>>::from(key)201 .try_into()202 .map_err(|_| Error::Revert("key too large".into()))203 })204 .collect::<Result<Vec<_>>>()?;205206 let properties = Pallet::<T>::filter_collection_properties(207 self.id,208 if keys.is_empty() { None } else { Some(keys) },209 )210 .map_err(dispatch_to_evm::<T>)?;211212 let properties = properties213 .into_iter()214 .map(|p| {215 let key =216 string::from_utf8(p.key.into()).map_err(|e| Error::Revert(format!("{}", e)))?;217 let value = bytes(p.value.to_vec());218 Ok(eth::Property { key, value })219 })220 .collect::<Result<Vec<_>>>()?;221 Ok(properties)222 }223224 /// Set the sponsor of the collection.225 ///226 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.227 ///228 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.229 #[solidity(hide)]230 fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {231 self.consume_store_reads_and_writes(1, 1)?;232233 let caller = T::CrossAccountId::from_eth(caller);234235 let sponsor = T::CrossAccountId::from_eth(sponsor);236 self.set_sponsor(&caller, sponsor.as_sub().clone())237 .map_err(dispatch_to_evm::<T>)238 }239240 /// Set the sponsor of the collection.241 ///242 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.243 ///244 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.245 fn set_collection_sponsor_cross(246 &mut self,247 caller: caller,248 sponsor: eth::CrossAccount,249 ) -> Result<void> {250 self.consume_store_reads_and_writes(1, 1)?;251252 let caller = T::CrossAccountId::from_eth(caller);253254 let sponsor = sponsor.into_sub_cross_account::<T>()?;255 self.set_sponsor(&caller, sponsor.as_sub().clone())256 .map_err(dispatch_to_evm::<T>)257 }258259 /// Whether there is a pending sponsor.260 fn has_collection_pending_sponsor(&self) -> Result<bool> {261 Ok(matches!(262 self.collection.sponsorship,263 SponsorshipState::Unconfirmed(_)264 ))265 }266267 /// Collection sponsorship confirmation.268 ///269 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.270 fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {271 self.consume_store_writes(1)?;272273 let caller = T::CrossAccountId::from_eth(caller);274 self.confirm_sponsorship(caller.as_sub())275 .map_err(dispatch_to_evm::<T>)276 }277278 /// Remove collection sponsor.279 fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {280 self.consume_store_reads_and_writes(1, 1)?;281 let caller = T::CrossAccountId::from_eth(caller);282 self.remove_sponsor(&caller).map_err(dispatch_to_evm::<T>)283 }284285 /// Get current sponsor.286 ///287 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.288 fn collection_sponsor(&self) -> Result<eth::CrossAccount> {289 let sponsor = match self.collection.sponsorship.sponsor() {290 Some(sponsor) => sponsor,291 None => return Ok(Default::default()),292 };293294 Ok(eth::CrossAccount::from_sub::<T>(&sponsor))295 }296297 /// Get current collection limits.298 ///299 /// @return Array of collection limits300 fn collection_limits(&self) -> Result<Vec<eth::CollectionLimit>> {301 let limits = &self.collection.limits;302303 Ok(vec![304 eth::CollectionLimit::from_opt_int(305 EvmCollectionLimits::AccountTokenOwnership,306 limits.account_token_ownership_limit,307 ),308 eth::CollectionLimit::from_opt_int(309 EvmCollectionLimits::SponsoredDataSize,310 limits.sponsored_data_size,311 ),312 limits313 .sponsored_data_rate_limit314 .and_then(|limit| {315 if let SponsoringRateLimit::Blocks(blocks) = limit {316 Some(eth::CollectionLimit::from_int(317 EvmCollectionLimits::SponsoredDataRateLimit,318 blocks,319 ))320 } else {321 None322 }323 })324 .unwrap_or(eth::CollectionLimit::from_int(325 EvmCollectionLimits::SponsoredDataRateLimit,326 Default::default(),327 )),328 eth::CollectionLimit::from_opt_int(EvmCollectionLimits::TokenLimit, limits.token_limit),329 eth::CollectionLimit::from_opt_int(330 EvmCollectionLimits::SponsorTransferTimeout,331 limits.sponsor_transfer_timeout,332 ),333 eth::CollectionLimit::from_opt_int(334 EvmCollectionLimits::SponsorApproveTimeout,335 limits.sponsor_approve_timeout,336 ),337 eth::CollectionLimit::from_opt_bool(338 EvmCollectionLimits::OwnerCanTransfer,339 limits.owner_can_transfer,340 ),341 eth::CollectionLimit::from_opt_bool(342 EvmCollectionLimits::OwnerCanDestroy,343 limits.owner_can_destroy,344 ),345 eth::CollectionLimit::from_opt_bool(346 EvmCollectionLimits::TransferEnabled,347 limits.transfers_enabled,348 ),349 ])350 }351352 /// Set limits for the collection.353 /// @dev Throws error if limit not found.354 /// @param limit Some limit.355 #[solidity(rename_selector = "setCollectionLimit")]356 fn set_collection_limit(357 &mut self,358 caller: caller,359 limit: eth::CollectionLimit,360 ) -> Result<void> {361 self.consume_store_reads_and_writes(1, 1)?;362363 let caller = T::CrossAccountId::from_eth(caller);364 <Pallet<T>>::update_limits(&caller, self, limit.try_into()?).map_err(dispatch_to_evm::<T>)365 }366367 /// Get contract address.368 fn contract_address(&self) -> Result<address> {369 Ok(crate::eth::collection_id_to_address(self.id))370 }371372 /// Add collection admin.373 /// @param newAdmin Cross account administrator address.374 fn add_collection_admin_cross(375 &mut self,376 caller: caller,377 new_admin: eth::CrossAccount,378 ) -> Result<void> {379 self.consume_store_reads_and_writes(2, 2)?;380381 let caller = T::CrossAccountId::from_eth(caller);382 let new_admin = new_admin.into_sub_cross_account::<T>()?;383 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;384 Ok(())385 }386387 /// Remove collection admin.388 /// @param admin Cross account administrator address.389 fn remove_collection_admin_cross(390 &mut self,391 caller: caller,392 admin: eth::CrossAccount,393 ) -> Result<void> {394 self.consume_store_reads_and_writes(2, 2)?;395396 let caller = T::CrossAccountId::from_eth(caller);397 let admin = admin.into_sub_cross_account::<T>()?;398 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;399 Ok(())400 }401402 /// Add collection admin.403 /// @param newAdmin Address of the added administrator.404 #[solidity(hide)]405 fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {406 self.consume_store_reads_and_writes(2, 2)?;407408 let caller = T::CrossAccountId::from_eth(caller);409 let new_admin = T::CrossAccountId::from_eth(new_admin);410 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;411 Ok(())412 }413414 /// Remove collection admin.415 ///416 /// @param admin Address of the removed administrator.417 #[solidity(hide)]418 fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {419 self.consume_store_reads_and_writes(2, 2)?;420421 let caller = T::CrossAccountId::from_eth(caller);422 let admin = T::CrossAccountId::from_eth(admin);423 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;424 Ok(())425 }426427 /// Toggle accessibility of collection nesting.428 ///429 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'430 #[solidity(rename_selector = "setCollectionNesting")]431 fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {432 self.consume_store_reads_and_writes(1, 1)?;433434 let caller = T::CrossAccountId::from_eth(caller);435436 let mut permissions = self.collection.permissions.clone();437 let mut nesting = permissions.nesting().clone();438 nesting.token_owner = enable;439 nesting.restricted = None;440 permissions.nesting = Some(nesting);441442 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)443 }444445 /// Toggle accessibility of collection nesting.446 ///447 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'448 /// @param collections Addresses of collections that will be available for nesting.449 #[solidity(rename_selector = "setCollectionNesting")]450 fn set_nesting(451 &mut self,452 caller: caller,453 enable: bool,454 collections: Vec<address>,455 ) -> Result<void> {456 self.consume_store_reads_and_writes(1, 1)?;457458 if collections.is_empty() {459 return Err("no addresses provided".into());460 }461 let caller = T::CrossAccountId::from_eth(caller);462463 let mut permissions = self.collection.permissions.clone();464 match enable {465 false => {466 let mut nesting = permissions.nesting().clone();467 nesting.token_owner = false;468 nesting.restricted = None;469 permissions.nesting = Some(nesting);470 }471 true => {472 let mut bv = OwnerRestrictedSet::new();473 for i in collections {474 bv.try_insert(crate::eth::map_eth_to_id(&i).ok_or_else(|| {475 Error::Revert("Can't convert address into collection id".into())476 })?)477 .map_err(|_| "too many collections")?;478 }479 let mut nesting = permissions.nesting().clone();480 nesting.token_owner = true;481 nesting.restricted = Some(bv);482 permissions.nesting = Some(nesting);483 }484 };485486 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)487 }488489 /// Returns nesting for a collection490 #[solidity(rename_selector = "collectionNestingRestrictedCollectionIds")]491 fn collection_nesting_restricted_ids(&self) -> Result<eth::CollectionNesting> {492 let nesting = self.collection.permissions.nesting();493494 Ok(eth::CollectionNesting::new(495 nesting.token_owner,496 nesting497 .restricted498 .clone()499 .map(|b| b.0.into_inner().iter().map(|id| id.0.into()).collect())500 .unwrap_or_default(),501 ))502 }503504 /// Returns permissions for a collection505 fn collection_nesting_permissions(&self) -> Result<Vec<eth::CollectionNestingPermission>> {506 let nesting = self.collection.permissions.nesting();507 Ok(vec![508 eth::CollectionNestingPermission::new(509 eth::CollectionPermissionField::CollectionAdmin,510 nesting.collection_admin,511 ),512 eth::CollectionNestingPermission::new(513 eth::CollectionPermissionField::TokenOwner,514 nesting.token_owner,515 ),516 ])517 }518 /// Set the collection access method.519 /// @param mode Access mode520 /// 0 for Normal521 /// 1 for AllowList522 fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {523 self.consume_store_reads_and_writes(1, 1)?;524525 let caller = T::CrossAccountId::from_eth(caller);526 let permissions = CollectionPermissions {527 access: Some(match mode {528 0 => AccessMode::Normal,529 1 => AccessMode::AllowList,530 _ => return Err("not supported access mode".into()),531 }),532 ..Default::default()533 };534 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)535 }536537 /// Checks that user allowed to operate with collection.538 ///539 /// @param user User address to check.540 fn allowlisted_cross(&self, user: eth::CrossAccount) -> Result<bool> {541 let user = user.into_sub_cross_account::<T>()?;542 Ok(Pallet::<T>::allowed(self.id, user))543 }544545 /// Add the user to the allowed list.546 ///547 /// @param user Address of a trusted user.548 #[solidity(hide)]549 fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {550 self.consume_store_writes(1)?;551552 let caller = T::CrossAccountId::from_eth(caller);553 let user = T::CrossAccountId::from_eth(user);554 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;555 Ok(())556 }557558 /// Add user to allowed list.559 ///560 /// @param user User cross account address.561 fn add_to_collection_allow_list_cross(562 &mut self,563 caller: caller,564 user: eth::CrossAccount,565 ) -> Result<void> {566 self.consume_store_writes(1)?;567568 let caller = T::CrossAccountId::from_eth(caller);569 let user = user.into_sub_cross_account::<T>()?;570 Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;571 Ok(())572 }573574 /// Remove the user from the allowed list.575 ///576 /// @param user Address of a removed user.577 #[solidity(hide)]578 fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {579 self.consume_store_writes(1)?;580581 let caller = T::CrossAccountId::from_eth(caller);582 let user = T::CrossAccountId::from_eth(user);583 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;584 Ok(())585 }586587 /// Remove user from allowed list.588 ///589 /// @param user User cross account address.590 fn remove_from_collection_allow_list_cross(591 &mut self,592 caller: caller,593 user: eth::CrossAccount,594 ) -> Result<void> {595 self.consume_store_writes(1)?;596597 let caller = T::CrossAccountId::from_eth(caller);598 let user = user.into_sub_cross_account::<T>()?;599 Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;600 Ok(())601 }602603 /// Switch permission for minting.604 ///605 /// @param mode Enable if "true".606 fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {607 self.consume_store_reads_and_writes(1, 1)?;608609 let caller = T::CrossAccountId::from_eth(caller);610 let permissions = CollectionPermissions {611 mint_mode: Some(mode),612 ..Default::default()613 };614 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)615 }616617 /// Check that account is the owner or admin of the collection618 ///619 /// @param user account to verify620 /// @return "true" if account is the owner or admin621 #[solidity(hide, rename_selector = "isOwnerOrAdmin")]622 fn is_owner_or_admin_eth(&self, user: address) -> Result<bool> {623 let user = T::CrossAccountId::from_eth(user);624 Ok(self.is_owner_or_admin(&user))625 }626627 /// Check that account is the owner or admin of the collection628 ///629 /// @param user User cross account to verify630 /// @return "true" if account is the owner or admin631 fn is_owner_or_admin_cross(&self, user: eth::CrossAccount) -> Result<bool> {632 let user = user.into_sub_cross_account::<T>()?;633 Ok(self.is_owner_or_admin(&user))634 }635636 /// Returns collection type637 ///638 /// @return `Fungible` or `NFT` or `ReFungible`639 fn unique_collection_type(&self) -> Result<string> {640 let mode = match self.collection.mode {641 CollectionMode::Fungible(_) => "Fungible",642 CollectionMode::NFT => "NFT",643 CollectionMode::ReFungible => "ReFungible",644 };645 Ok(mode.into())646 }647648 /// Get collection owner.649 ///650 /// @return Tuble with sponsor address and his substrate mirror.651 /// If address is canonical then substrate mirror is zero and vice versa.652 fn collection_owner(&self) -> Result<eth::CrossAccount> {653 Ok(eth::CrossAccount::from_sub_cross_account::<T>(654 &T::CrossAccountId::from_sub(self.owner.clone()),655 ))656 }657658 /// Changes collection owner to another account659 ///660 /// @dev Owner can be changed only by current owner661 /// @param newOwner new owner account662 #[solidity(hide, rename_selector = "changeCollectionOwner")]663 fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {664 self.consume_store_writes(1)?;665666 let caller = T::CrossAccountId::from_eth(caller);667 let new_owner = T::CrossAccountId::from_eth(new_owner);668 self.change_owner(caller, new_owner)669 .map_err(dispatch_to_evm::<T>)670 }671672 /// Get collection administrators673 ///674 /// @return Vector of tuples with admins address and his substrate mirror.675 /// If address is canonical then substrate mirror is zero and vice versa.676 fn collection_admins(&self) -> Result<Vec<eth::CrossAccount>> {677 let result = crate::IsAdmin::<T>::iter_prefix((self.id,))678 .map(|(admin, _)| eth::CrossAccount::from_sub_cross_account::<T>(&admin))679 .collect();680 Ok(result)681 }682683 /// Changes collection owner to another account684 ///685 /// @dev Owner can be changed only by current owner686 /// @param newOwner new owner cross account687 fn change_collection_owner_cross(688 &mut self,689 caller: caller,690 new_owner: eth::CrossAccount,691 ) -> Result<void> {692 self.consume_store_writes(1)?;693694 let caller = T::CrossAccountId::from_eth(caller);695 let new_owner = new_owner.into_sub_cross_account::<T>()?;696 self.change_owner(caller, new_owner)697 .map_err(dispatch_to_evm::<T>)698 }699}700701/// Contains static property keys and values.702pub mod static_property {703 use evm_coder::{704 execution::{Result, Error},705 };706 use alloc::format;707708 const EXPECT_CONVERT_ERROR: &str = "length < limit";709710 /// Keys.711 pub mod key {712 use super::*;713714 /// Key "baseURI".715 pub fn base_uri() -> up_data_structs::PropertyKey {716 property_key_from_bytes(b"baseURI").expect(EXPECT_CONVERT_ERROR)717 }718719 /// Key "url".720 pub fn url() -> up_data_structs::PropertyKey {721 property_key_from_bytes(b"URI").expect(EXPECT_CONVERT_ERROR)722 }723724 /// Key "suffix".725 pub fn suffix() -> up_data_structs::PropertyKey {726 property_key_from_bytes(b"URISuffix").expect(EXPECT_CONVERT_ERROR)727 }728729 /// Key "parentNft".730 pub fn parent_nft() -> up_data_structs::PropertyKey {731 property_key_from_bytes(b"parentNft").expect(EXPECT_CONVERT_ERROR)732 }733 }734735 /// Convert `byte` to [`PropertyKey`].736 pub fn property_key_from_bytes(bytes: &[u8]) -> Result<up_data_structs::PropertyKey> {737 bytes.to_vec().try_into().map_err(|_| {738 Error::Revert(format!(739 "Property key is too long. Max length is {}.",740 up_data_structs::PropertyKey::bound()741 ))742 })743 }744745 /// Convert `bytes` to [`PropertyValue`].746 pub fn property_value_from_bytes(bytes: &[u8]) -> Result<up_data_structs::PropertyValue> {747 bytes.to_vec().try_into().map_err(|_| {748 Error::Revert(format!(749 "Property key is too long. Max length is {}.",750 up_data_structs::PropertyKey::bound()751 ))752 })753 }754}pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -306,7 +306,7 @@
/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
#[derive(Default, Debug, Clone, Copy, AbiCoder)]
#[repr(u8)]
-pub enum CollectionPermissions {
+pub enum CollectionPermissionField {
/// Owner of token can nest tokens under it.
#[default]
TokenOwner,
@@ -431,3 +431,31 @@
Ok(perms)
}
}
+
+/// Nested collections.
+#[derive(Debug, Default, AbiCoder)]
+pub struct CollectionNesting {
+ token_owner: bool,
+ ids: Vec<uint256>,
+}
+
+impl CollectionNesting {
+ /// Create [`CollectionNesting`].
+ pub fn new(token_owner: bool, ids: Vec<uint256>) -> Self {
+ Self { token_owner, ids }
+ }
+}
+
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+#[derive(Debug, Default, AbiCoder)]
+pub struct CollectionNestingPermission {
+ field: CollectionPermissionField,
+ value: bool,
+}
+
+impl CollectionNestingPermission {
+ /// Create [`CollectionNestingPermission`].
+ pub fn new(field: CollectionPermissionField, value: bool) -> Self {
+ Self { field, value }
+ }
+}
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
@@ -257,19 +257,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 (CollectionNesting memory) {
require(false, stub_error);
dummy;
- return Tuple33(false, new uint256[](0));
+ return CollectionNesting(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 (CollectionNestingPermission[] memory) {
require(false, stub_error);
dummy;
- return new Tuple36[](0);
+ return new CollectionNestingPermission[](0);
}
/// Set the collection access method.
@@ -443,24 +443,24 @@
uint256 sub;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+struct CollectionNestingPermission {
+ CollectionPermissionField field;
+ bool value;
+}
+
/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
-enum CollectionPermissions {
+enum CollectionPermissionField {
/// @dev Owner of token can nest tokens under it.
TokenOwner,
/// @dev Admin of token collection can nest tokens under token.
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple36 {
- CollectionPermissions field_0;
- bool field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple33 {
- bool field_0;
- uint256[] field_1;
+/// @dev Nested collections.
+struct CollectionNesting {
+ bool token_owner;
+ uint256[] ids;
}
/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
@@ -469,6 +469,7 @@
OptionUint value;
}
+/// @dev Ethereum representation of Optional value with uint256.
struct OptionUint {
bool status;
uint256 value;
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
@@ -401,19 +401,19 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() public view returns (Tuple45 memory) {
+ function collectionNestingRestrictedCollectionIds() public view returns (CollectionNesting memory) {
require(false, stub_error);
dummy;
- return Tuple45(false, new uint256[](0));
+ return CollectionNesting(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 (Tuple48[] memory) {
+ function collectionNestingPermissions() public view returns (CollectionNestingPermission[] memory) {
require(false, stub_error);
dummy;
- return new Tuple48[](0);
+ return new CollectionNestingPermission[](0);
}
/// Set the collection access method.
@@ -587,24 +587,24 @@
uint256 sub;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+struct CollectionNestingPermission {
+ CollectionPermissionField field;
+ bool value;
+}
+
/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
-enum CollectionPermissions {
+enum CollectionPermissionField {
/// @dev Owner of token can nest tokens under it.
TokenOwner,
/// @dev Admin of token collection can nest tokens under token.
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple48 {
- CollectionPermissions field_0;
- bool field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple45 {
- bool field_0;
- uint256[] field_1;
+/// @dev Nested collections.
+struct CollectionNesting {
+ bool token_owner;
+ uint256[] ids;
}
/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
@@ -613,6 +613,7 @@
OptionUint value;
}
+/// @dev Ethereum representation of Optional value with uint256.
struct OptionUint {
bool status;
uint256 value;
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
@@ -401,19 +401,19 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() public view returns (Tuple44 memory) {
+ function collectionNestingRestrictedCollectionIds() public view returns (CollectionNesting memory) {
require(false, stub_error);
dummy;
- return Tuple44(false, new uint256[](0));
+ return CollectionNesting(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 (Tuple47[] memory) {
+ function collectionNestingPermissions() public view returns (CollectionNestingPermission[] memory) {
require(false, stub_error);
dummy;
- return new Tuple47[](0);
+ return new CollectionNestingPermission[](0);
}
/// Set the collection access method.
@@ -587,24 +587,24 @@
uint256 sub;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+struct CollectionNestingPermission {
+ CollectionPermissionField field;
+ bool value;
+}
+
/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
-enum CollectionPermissions {
+enum CollectionPermissionField {
/// @dev Owner of token can nest tokens under it.
TokenOwner,
/// @dev Admin of token collection can nest tokens under token.
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple47 {
- CollectionPermissions field_0;
- bool field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple44 {
- bool field_0;
- uint256[] field_1;
+/// @dev Nested collections.
+struct CollectionNesting {
+ bool token_owner;
+ uint256[] ids;
}
/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
@@ -613,6 +613,7 @@
OptionUint value;
}
+/// @dev Ethereum representation of Optional value with uint256.
struct OptionUint {
bool status;
uint256 value;
tests/src/eth/abi/fungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/fungible.json
+++ b/tests/src/eth/abi/fungible.json
@@ -242,13 +242,13 @@
{
"components": [
{
- "internalType": "enum CollectionPermissions",
- "name": "field_0",
+ "internalType": "enum CollectionPermissionField",
+ "name": "field",
"type": "uint8"
},
- { "internalType": "bool", "name": "field_1", "type": "bool" }
+ { "internalType": "bool", "name": "value", "type": "bool" }
],
- "internalType": "struct Tuple36[]",
+ "internalType": "struct CollectionNestingPermission[]",
"name": "",
"type": "tuple[]"
}
@@ -262,14 +262,10 @@
"outputs": [
{
"components": [
- { "internalType": "bool", "name": "field_0", "type": "bool" },
- {
- "internalType": "uint256[]",
- "name": "field_1",
- "type": "uint256[]"
- }
+ { "internalType": "bool", "name": "token_owner", "type": "bool" },
+ { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }
],
- "internalType": "struct Tuple33",
+ "internalType": "struct CollectionNesting",
"name": "",
"type": "tuple"
}
tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -272,13 +272,13 @@
{
"components": [
{
- "internalType": "enum CollectionPermissions",
- "name": "field_0",
+ "internalType": "enum CollectionPermissionField",
+ "name": "field",
"type": "uint8"
},
- { "internalType": "bool", "name": "field_1", "type": "bool" }
+ { "internalType": "bool", "name": "value", "type": "bool" }
],
- "internalType": "struct Tuple48[]",
+ "internalType": "struct CollectionNestingPermission[]",
"name": "",
"type": "tuple[]"
}
@@ -292,14 +292,10 @@
"outputs": [
{
"components": [
- { "internalType": "bool", "name": "field_0", "type": "bool" },
- {
- "internalType": "uint256[]",
- "name": "field_1",
- "type": "uint256[]"
- }
+ { "internalType": "bool", "name": "token_owner", "type": "bool" },
+ { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }
],
- "internalType": "struct Tuple45",
+ "internalType": "struct CollectionNesting",
"name": "",
"type": "tuple"
}
tests/src/eth/abi/reFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -254,13 +254,13 @@
{
"components": [
{
- "internalType": "enum CollectionPermissions",
- "name": "field_0",
+ "internalType": "enum CollectionPermissionField",
+ "name": "field",
"type": "uint8"
},
- { "internalType": "bool", "name": "field_1", "type": "bool" }
+ { "internalType": "bool", "name": "value", "type": "bool" }
],
- "internalType": "struct Tuple47[]",
+ "internalType": "struct CollectionNestingPermission[]",
"name": "",
"type": "tuple[]"
}
@@ -274,14 +274,10 @@
"outputs": [
{
"components": [
- { "internalType": "bool", "name": "field_0", "type": "bool" },
- {
- "internalType": "uint256[]",
- "name": "field_1",
- "type": "uint256[]"
- }
+ { "internalType": "bool", "name": "token_owner", "type": "bool" },
+ { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }
],
- "internalType": "struct Tuple44",
+ "internalType": "struct CollectionNesting",
"name": "",
"type": "tuple"
}
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -166,12 +166,12 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() external view returns (Tuple28 memory);
+ function collectionNestingRestrictedCollectionIds() external view returns (CollectionNesting memory);
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() external view returns (Tuple31[] memory);
+ function collectionNestingPermissions() external view returns (CollectionNestingPermission[] memory);
/// Set the collection access method.
/// @param mode Access mode
@@ -285,24 +285,24 @@
uint256 sub;
}
-/// @dev anonymous struct
-struct Tuple31 {
- CollectionPermissions field_0;
- bool field_1;
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+struct CollectionNestingPermission {
+ CollectionPermissionField field;
+ bool value;
}
/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
-enum CollectionPermissions {
+enum CollectionPermissionField {
/// @dev Owner of token can nest tokens under it.
TokenOwner,
/// @dev Admin of token collection can nest tokens under token.
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple28 {
- bool field_0;
- uint256[] field_1;
+/// @dev Nested collections.
+struct CollectionNesting {
+ bool token_owner;
+ uint256[] ids;
}
/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
@@ -311,6 +311,7 @@
OptionUint value;
}
+/// @dev Ethereum representation of Optional value with uint256.
struct OptionUint {
bool status;
uint256 value;
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -268,12 +268,12 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() external view returns (Tuple38 memory);
+ function collectionNestingRestrictedCollectionIds() external view returns (CollectionNesting memory);
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() external view returns (Tuple41[] memory);
+ function collectionNestingPermissions() external view returns (CollectionNestingPermission[] memory);
/// Set the collection access method.
/// @param mode Access mode
@@ -387,24 +387,24 @@
uint256 sub;
}
-/// @dev anonymous struct
-struct Tuple41 {
- CollectionPermissions field_0;
- bool field_1;
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+struct CollectionNestingPermission {
+ CollectionPermissionField field;
+ bool value;
}
/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
-enum CollectionPermissions {
+enum CollectionPermissionField {
/// @dev Owner of token can nest tokens under it.
TokenOwner,
/// @dev Admin of token collection can nest tokens under token.
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple38 {
- bool field_0;
- uint256[] field_1;
+/// @dev Nested collections.
+struct CollectionNesting {
+ bool token_owner;
+ uint256[] ids;
}
/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
@@ -413,6 +413,7 @@
OptionUint value;
}
+/// @dev Ethereum representation of Optional value with uint256.
struct OptionUint {
bool status;
uint256 value;
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -268,12 +268,12 @@
/// Returns nesting for a collection
/// @dev EVM selector for this function is: 0x22d25bfe,
/// or in textual repr: collectionNestingRestrictedCollectionIds()
- function collectionNestingRestrictedCollectionIds() external view returns (Tuple37 memory);
+ function collectionNestingRestrictedCollectionIds() external view returns (CollectionNesting memory);
/// Returns permissions for a collection
/// @dev EVM selector for this function is: 0x5b2eaf4b,
/// or in textual repr: collectionNestingPermissions()
- function collectionNestingPermissions() external view returns (Tuple40[] memory);
+ function collectionNestingPermissions() external view returns (CollectionNestingPermission[] memory);
/// Set the collection access method.
/// @param mode Access mode
@@ -387,24 +387,24 @@
uint256 sub;
}
-/// @dev anonymous struct
-struct Tuple40 {
- CollectionPermissions field_0;
- bool field_1;
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+struct CollectionNestingPermission {
+ CollectionPermissionField field;
+ bool value;
}
/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
-enum CollectionPermissions {
+enum CollectionPermissionField {
/// @dev Owner of token can nest tokens under it.
TokenOwner,
/// @dev Admin of token collection can nest tokens under token.
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple37 {
- bool field_0;
- uint256[] field_1;
+/// @dev Nested collections.
+struct CollectionNesting {
+ bool token_owner;
+ uint256[] ids;
}
/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
@@ -413,6 +413,7 @@
OptionUint value;
}
+/// @dev Ethereum representation of Optional value with uint256.
struct OptionUint {
bool status;
uint256 value;