difftreelog
refactor review storage hasher security
in: master
1 file changed
pallets/nft/src/lib.rsdiffbeforeafterboth403403404// #endregion404// #endregion405405406// # Used definitions407//408// ## User control levels409//410// chain-controlled - key is uncontrolled by user411// i.e autoincrementing index412// can use non-cryptographic hash413// real - key is controlled by user414// but it is hard to generate enough colliding values, i.e owner of signed txs415// can use non-cryptographic hash416// controlled - key is completly controlled by users417// i.e maps with mutable keys418// should use cryptographic hash419//420// ## User control level downgrade reasons421//422// ?1 - chain-controlled -> controlled423// collections/tokens can be destroyed, resulting in massive holes424// ?2 - chain-controlled -> controlled425// same as ?1, but can be only added, resulting in easier exploitation426// ?3 - real -> controlled427// no confirmation required, so addresses can be easily generated406decl_storage! {428decl_storage! {407 trait Store for Module<T: Config> as Nft {429 trait Store for Module<T: Config> as Nft {408430409 // Private members431 //#region Private members410 NextCollectionID: CollectionId;432 /// Id of next collection411 CreatedCollectionCount: u32;433 CreatedCollectionCount: u32;434 /// Used for migrations412 ChainVersion: u64;435 ChainVersion: u64;436 /// Id of last collection token437 /// Collection id (controlled?1)413 ItemListIndex: map hasher(identity) CollectionId => TokenId;438 ItemListIndex: map hasher(blake2_128_concat) CollectionId => TokenId;439 //#endregion414440415 // Chain limits struct441 //#region Chain limits struct416 pub ChainLimit get(fn chain_limit) config(): ChainLimits;442 pub ChainLimit get(fn chain_limit) config(): ChainLimits;443 //#endregion417444418 // Bound counters445 //#region Bound counters446 /// Amount of collections destroyed, used for total amount tracking with447 /// CreatedCollectionCount419 CollectionCount: u32;448 DestroyedCollectionCount: u32;449 /// Total amount of account owned tokens (NFTs + RFTs + unique fungibles)450 /// Account id (real)420 pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;451 pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;452 //#endregion421453422 // Basic collections454 //#region Basic collections455 /// Collection info456 /// Collection id (controlled?1)423 pub Collection get(fn collection) config(): map hasher(identity) CollectionId => CollectionType<T::AccountId>;457 pub Collection get(fn collection) config(): map hasher(blake2_128_concat) CollectionId => CollectionType<T::AccountId>;458 /// List of collection admins459 /// Collection id (controlled?2)424 pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;460 pub AdminList get(fn admin_list_collection): map hasher(blake2_128_concat) CollectionId => Vec<T::AccountId>;461 /// Whitelisted collection users462 /// Collection id (controlled?2), user id (controlled?3)425 pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;463 pub WhiteList get(fn white_list): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) T::AccountId => bool;426464 //#endregion427 /// Balance owner per collection map465466 /// How many of collection items user have467 /// Collection id (controlled?2), account id (real)428 pub Balance get(fn balance_count): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => u128;468 pub Balance get(fn balance_count): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => u128;429469430 /// second parameter: item id + owner account id + spender account id470 /// Amount of items which spender can transfer out of owners account (via transferFrom)471 /// Collection id (controlled?2), (token id (controlled ?2) + owner account id (real) + spender account id (controlled?3))431 pub Allowances get(fn approved): double_map hasher(identity) CollectionId, hasher(twox_64_concat) (TokenId, T::AccountId, T::AccountId) => u128;472 pub Allowances get(fn approved): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) (TokenId, T::AccountId, T::AccountId) => u128;432473433 /// Item collections474 //#region Item collections475 /// Collection id (controlled?2), token id (controlled?1)434 pub NftItemList get(fn nft_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => NftItemType<T::AccountId>;476 pub NftItemList get(fn nft_item_id) config(): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => NftItemType<T::AccountId>;477 /// Collection id (controlled?2), owner (controlled?2)435 pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => FungibleItemType;478 pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) T::AccountId => FungibleItemType;479 /// Collection id (controlled?2), token id (controlled?1)436 pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => ReFungibleItemType<T::AccountId>;480 pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => ReFungibleItemType<T::AccountId>;481 //#endregion437482438 /// Index list483 //#region Index list484 /// Collection id (controlled?2), tokens owner (controlled?2)439 pub AddressTokens get(fn address_tokens): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => Vec<TokenId>;485 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) T::AccountId => Vec<TokenId>;486 //#endregion440487441 /// Tokens transfer baskets488 //#region Tokens transfer rate limit baskets489 /// (Collection id (controlled?2), who created (real))442 pub CreateItemBasket get(fn create_item_basket): map hasher(twox_64_concat) (CollectionId, T::AccountId) => T::BlockNumber;490 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => T::BlockNumber;491 /// Collection id (controlled?2), token id (controlled?2)443 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;492 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;493 /// Collection id (controlled?2), owning user (real)444 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;494 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;495 /// Collection id (controlled?2), token id (controlled?2)445 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;496 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;497 //#endregion446498447 // Contract Sponsorship and Ownership499 //#region Contract Sponsorship and Ownership500 /// Contract address (real)448 pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;501 pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;502 /// Contract address (real)449 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;503 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;504 /// (Contract address(real), caller (real))450 pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;505 pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;506 /// Contract address (real)451 pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;507 pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;508 /// Contract address (real)452 pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool; 509 pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool; 510 /// Contract address (real) => Whitelisted user (controlled?3)453 pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(twox_64_concat) T::AccountId => bool; 511 pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) T::AccountId => bool; 512 //#endregion454 }513 }455 add_extra_genesis {514 add_extra_genesis {456 build(|config: &GenesisConfig<T>| {515 build(|config: &GenesisConfig<T>| {535594536 fn on_initialize(now: T::BlockNumber) -> Weight {595 fn on_initialize(now: T::BlockNumber) -> Weight {537538 if ChainVersion::get() < 2539 {540 let value = NextCollectionID::get();541 CreatedCollectionCount::put(value);542 ChainVersion::put(2);543 }544545 0596 0546 }597 }578629579 let chain_limit = ChainLimit::get();630 let chain_limit = ChainLimit::get();631632 let created_count = CreatedCollectionCount::get();633 let destroyed_count = DestroyedCollectionCount::get();580634581 // bound Total number of collections635 // bound Total number of collections582 ensure!(CollectionCount::get() < chain_limit.collection_numbers_limit, Error::<T>::TotalCollectionsLimitExceeded);636 ensure!(created_count - destroyed_count < chain_limit.collection_numbers_limit, Error::<T>::TotalCollectionsLimitExceeded);583637584 // check params638 // check params585 ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);639 ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);588 ensure!(token_prefix.len() <= 16, Error::<T>::CollectionTokenPrefixLimitExceeded);642 ensure!(token_prefix.len() <= 16, Error::<T>::CollectionTokenPrefixLimitExceeded);589643590 // Generate next collection ID644 // Generate next collection ID591 let next_id = CreatedCollectionCount::get()645 let next_id = created_count592 .checked_add(1)646 .checked_add(1)593 .ok_or(Error::<T>::NumOverflow)?;647 .ok_or(Error::<T>::NumOverflow)?;594595 // bound counter596 let total = CollectionCount::get()597 .checked_add(1)598 .ok_or(Error::<T>::NumOverflow)?;599648600 CreatedCollectionCount::put(next_id);649 CreatedCollectionCount::put(next_id);601 CollectionCount::put(total);602650603 let limits = CollectionLimits {651 let limits = CollectionLimits {604 sponsored_data_size: chain_limit.custom_data_limit,652 sponsored_data_size: chain_limit.custom_data_limit,669 <FungibleTransferBasket<T>>::remove_prefix(collection_id);717 <FungibleTransferBasket<T>>::remove_prefix(collection_id);670 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);718 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);671719672 if CollectionCount::get() > 0720 DestroyedCollectionCount::put(DestroyedCollectionCount::get()673 {674 // bound couter675 let total = CollectionCount::get()676 .checked_sub(1)721 .checked_add(1)677 .ok_or(Error::<T>::NumOverflow)?;722 .ok_or(Error::<T>::NumOverflow)?);678679 CollectionCount::put(total);680 }681723682 Ok(())724 Ok(())683 }725 }