diff --git a/Cargo.lock b/Cargo.lock index 23b66e533..030695fb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,6 +411,7 @@ name = "asset-manager" version = "0.1.0" dependencies = [ "bit-country-primitives", + "core-primitives", "frame-support", "frame-system", "hex", @@ -5771,6 +5772,15 @@ dependencies = [ "auction-manager", "bit-country-primitives", "core-primitives", + "cumulus-pallet-aura-ext", + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-session-benchmarking", + "cumulus-pallet-xcm", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", + "cumulus-primitives-timestamp", + "cumulus-primitives-utility", "currencies", "fp-evm", "fp-rpc", @@ -5790,6 +5800,7 @@ dependencies = [ "orml-currencies", "orml-nft", "orml-oracle", + "orml-rewards", "orml-tokens", "orml-traits", "pallet-auction", @@ -5822,6 +5833,7 @@ dependencies = [ "pallet-reward", "pallet-scheduler", "pallet-session", + "pallet-spp", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", @@ -5829,6 +5841,7 @@ dependencies = [ "pallet-treasury", "pallet-utility", "pallet-vesting", + "parachain-info", "parity-scale-codec", "polkadot-primitives", "scale-info", @@ -6636,6 +6649,23 @@ dependencies = [ "sp-std", ] +[[package]] +name = "orml-rewards" +version = "0.4.1-dev" +source = "git+https://github.com/bit-country/open-runtime-module-library?branch=v-9.38#5861b6707c69031e8d70515b0aea6d222f5a5053" +dependencies = [ + "frame-support", + "frame-system", + "orml-traits", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "orml-tokens" version = "0.4.1-dev" @@ -8020,6 +8050,33 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-spp" +version = "2.0.0-rc6" +dependencies = [ + "asset-manager", + "auction-manager", + "bit-country-primitives", + "core-primitives", + "currencies", + "frame-benchmarking", + "frame-support", + "frame-system", + "orml-rewards", + "orml-tokens", + "orml-traits", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", + "substrate-fixed", +] + [[package]] name = "pallet-staking" version = "4.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index 41220719b..3f959a986 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ url = "2.3.1" tracing-core = "0.1.28" impl-trait-for-tuples = "0.2.2" num_enum = { version = "0.5.3", default-features = false } -getrandom = { version = "0.2.7", features = ["js"]} +getrandom = { version = "0.2.7", features = ["js"] } blake2-rfc = { version = "0.2.18", default-features = false } hex = { version = "0.4", default-features = false } funty = { version = "=1.1.0", default-features = false } @@ -38,13 +38,13 @@ similar-asserts = { version = "1.1.0" } # General (ethereum) ethabi = { version = "18.0.0", default-features = false } -evm = { git = "https://github.com/rust-blockchain/evm", rev = "51b8c2ce3104265e1fd5bb0fe5cdfd2e0938239c", default-features = false, features = [ "with-codec" ] } +evm = { git = "https://github.com/rust-blockchain/evm", rev = "51b8c2ce3104265e1fd5bb0fe5cdfd2e0938239c", default-features = false, features = ["with-codec"] } # General (precompile macro) proc-macro2 = "1.0" quote = "1.0" sha3 = "0.8" -syn = { version = "1.0", features = [ "extra-traits", "fold", "full", "visit" ] } +syn = { version = "1.0", features = ["extra-traits", "fold", "full", "visit"] } # General (node only) parking_lot = "0.12.1" @@ -60,7 +60,7 @@ frame-executive = { git = 'https://github.com/paritytech/substrate', branch = 'p frame-benchmarking = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } frame-support = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } frame-system = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -frame-system-benchmarking = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false} +frame-system-benchmarking = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } frame-system-rpc-runtime-api = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } frame-try-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false } @@ -85,7 +85,7 @@ sc-consensus-epochs = { git = "https://github.com/paritytech/substrate", branch sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sc-consensus-manual-seal = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } -sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38"} +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sc-finality-grandpa-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } @@ -101,22 +101,22 @@ sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkad # Substrate Primitive Dependencies (general) sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sp-block-builder = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } -sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } +sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sp-api = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } sp-core = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-consensus-aura = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-inherents = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-io = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-runtime = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-std = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-version = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } -sp-application-crypto = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -sp-arithmetic = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-consensus-aura = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-inherents = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-io = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-runtime = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-std = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-version = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } +sp-application-crypto = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } +sp-arithmetic = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } # Substrate Utilities -node-primitives = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38"} +node-primitives = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } try-runtime-cli = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38" } substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } @@ -128,13 +128,13 @@ sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "polkad sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } -pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38"} +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } # Substrate Pallets pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } pallet-balances = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } -pallet-collective = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false} +pallet-collective = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } pallet-democracy = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } pallet-randomness-collective-flip = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } pallet-sudo = { git = 'https://github.com/paritytech/substrate', branch = 'polkadot-v0.9.38', default-features = false } @@ -186,38 +186,39 @@ pallet-collator-selection = { git = 'https://github.com/paritytech/cumulus', bra # Polkadot polkadot-cli = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" } polkadot-service = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" } -polkadot-parachain = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" , default-features = false } -polkadot-runtime-parachains = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" , default-features = false } -polkadot-primitives = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" , default-features = false } -xcm = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" , default-features = false } -xcm-builder = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" , default-features = false } -xcm-executor = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" , default-features = false } -pallet-xcm = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38" , default-features = false } +polkadot-parachain = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } +polkadot-runtime-parachains = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } +polkadot-primitives = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } +xcm = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } +xcm-builder = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } +xcm-executor = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } +pallet-xcm = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } polkadot-runtime-common = { git = 'https://github.com/paritytech/polkadot', branch = "release-v0.9.38", default-features = false } kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.38", default-features = false } # ORML -orml-currencies = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-tokens = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-traits = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-nft = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-unknown-tokens = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-xtokens = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-xcm = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-xcm-support = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } -orml-oracle = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-currencies = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-tokens = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-traits = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-nft = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-unknown-tokens = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-xtokens = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-xcm = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-xcm-support = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-oracle = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } orml-benchmarking = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } +orml-rewards = { git = "https://github.com/bit-country/open-runtime-module-library", branch = "v-9.38", default-features = false } # EVM pallet-dynamic-fee = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } -fp-consensus = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} -fp-storage = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} -fc-cli = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} -fc-rpc = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} -fc-rpc-core = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} -fc-consensus = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} -fc-mapping-sync = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} -fc-db = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38"} +fp-consensus = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } +fp-storage = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } +fc-cli = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } +fc-rpc = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } +fc-rpc-core = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } +fc-consensus = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } +fc-mapping-sync = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } +fc-db = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38" } fp-self-contained = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38", default-features = false } fp-rpc = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38", default-features = false } fp-evm = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38", default-features = false } @@ -231,7 +232,7 @@ pallet-evm-precompile-ed25519 = { git = "https://github.com/justinphamnz/frontie pallet-evm-precompile-modexp = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38", default-features = false } pallet-evm-precompile-sha3fips = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38", default-features = false } pallet-evm-precompile-simple = { git = "https://github.com/justinphamnz/frontier", branch = "polkadot-v0.9.38", default-features = false } -libsecp256k1 = { version = "0.6", default-features = false, features = ["hmac", "static-context"]} +libsecp256k1 = { version = "0.6", default-features = false, features = ["hmac", "static-context"] } # ink! pallet-contracts = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } diff --git a/modules/bridge/src/lib.rs b/modules/bridge/src/lib.rs index e8c26764e..5390eda15 100644 --- a/modules/bridge/src/lib.rs +++ b/modules/bridge/src/lib.rs @@ -11,7 +11,7 @@ use sp_core::{H160, U256}; use sp_std::prelude::*; pub use pallet::*; -use primitives::{Balance, FungibleTokenId}; +use primitives::FungibleTokenId; pub type ResourceId = H160; pub type ChainId = u8; @@ -29,12 +29,12 @@ pub mod pallet { use frame_support::traits::{Currency, ExistenceRequirement, LockableCurrency, ReservableCurrency}; use frame_support::PalletId; use orml_traits::MultiCurrency; - use sp_arithmetic::traits::{CheckedMul, Saturating, Zero}; - use sp_runtime::traits::{AccountIdConversion, CheckedDiv}; - use sp_runtime::{ArithmeticError, ModuleError}; + use sp_arithmetic::traits::{Saturating, Zero}; + use sp_runtime::traits::AccountIdConversion; + use sp_runtime::ModuleError; use core_primitives::NFTTrait; - use primitives::evm::CurrencyIdType::FungibleToken; + use primitives::{Attributes, ClassId, NftMetadata, TokenId}; use super::*; @@ -300,7 +300,11 @@ pub mod pallet { Ok(()) } Err(err) => match err { - DispatchError::Module(ModuleError { index, error, message }) => { + DispatchError::Module(ModuleError { + index: _, + error: _, + message, + }) => { if message == Some("AssetInfoNotFound") { if let Ok(_mint_succeeded) = T::NFTHandler::mint_token_with_id(&to, class_id, token_id, metadata, Attributes::new()) @@ -335,7 +339,7 @@ pub mod pallet { let bridge_id = T::PalletId::get().into_account_truncating(); ensure!(BridgeFee::::contains_key(&chain_id), Error::::FeeOptionsMissing); - let (min_fee, fee_scale) = Self::bridge_fee(chain_id); + let (min_fee, _fee_scale) = Self::bridge_fee(chain_id); T::Currency::transfer(&source, &bridge_id, min_fee.into(), ExistenceRequirement::AllowDeath)?; diff --git a/modules/bridge/src/mock.rs b/modules/bridge/src/mock.rs index 1fbfa7bd9..32894d6bf 100644 --- a/modules/bridge/src/mock.rs +++ b/modules/bridge/src/mock.rs @@ -3,22 +3,18 @@ use std::collections::BTreeMap; use std::vec; -use frame_support::traits::{EqualPrivilegeOnly, Nothing}; +use frame_support::traits::Nothing; use frame_support::{construct_runtime, ord_parameter_types, pallet_prelude::Hooks, parameter_types, PalletId}; -use frame_system::{EnsureRoot, EnsureSignedBy}; +use frame_system::EnsureRoot; use orml_traits::parameter_type_with_key; use sp_core::H256; use sp_runtime::traits::AccountIdConversion; use sp_runtime::{testing::Header, traits::IdentityLookup, ModuleError, Perbill}; -use auction_manager::{Auction, AuctionInfo, AuctionItem, AuctionType, CheckAuctionItemHandler, ListingLevel}; -use core_primitives::{ - Attributes, CollectionType, MetaverseInfo, MetaverseMetadata, MetaverseTrait, NFTTrait, NftAssetData, NftClassData, - NftMetadata, TokenType, -}; +use core_primitives::{Attributes, CollectionType, NFTTrait, NftClassData, NftMetadata, TokenType}; use primitives::{ - continuum::MapTrait, estate::Estate, Amount, AuctionId, ClassId, EstateId, FungibleTokenId, GroupCollectionId, - ItemId, MapSpotId, NftOffer, TokenId, UndeployedLandBlockId, + continuum::MapTrait, Amount, ClassId, EstateId, FungibleTokenId, GroupCollectionId, MapSpotId, TokenId, + UndeployedLandBlockId, }; use crate as bridge; @@ -283,7 +279,7 @@ impl NFTTrait for MockNFTHandler { { return Ok(true); } - if (nft_value.1 == 5) { + if nft_value.1 == 5 { return Err(DispatchError::Module(ModuleError { index: 5, error: [0, 0, 0, 0], @@ -293,7 +289,7 @@ impl NFTTrait for MockNFTHandler { Ok(false) } - fn is_stackable(asset_id: (Self::ClassId, Self::TokenId)) -> Result { + fn is_stackable(_asset_id: (Self::ClassId, Self::TokenId)) -> Result { Ok(false) } @@ -306,19 +302,19 @@ impl NFTTrait for MockNFTHandler { } Ok(false) } - fn get_nft_group_collection(nft_collection: &Self::ClassId) -> Result { + fn get_nft_group_collection(_nft_collection: &Self::ClassId) -> Result { Ok(ASSET_COLLECTION_ID) } fn create_token_class( sender: &AccountId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, collection_id: GroupCollectionId, - token_type: TokenType, - collection_type: CollectionType, - royalty_fee: Perbill, - mint_limit: Option, + _token_type: TokenType, + _collection_type: CollectionType, + _royalty_fee: Perbill, + _mint_limit: Option, ) -> Result { match *sender { ALICE => { @@ -339,8 +335,8 @@ impl NFTTrait for MockNFTHandler { fn mint_token( sender: &AccountId, class_id: ClassId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -364,26 +360,26 @@ impl NFTTrait for MockNFTHandler { } } - fn transfer_nft(from: &AccountId, to: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn transfer_nft(_from: &AccountId, _to: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn check_item_on_listing(class_id: Self::ClassId, token_id: Self::TokenId) -> Result { + fn check_item_on_listing(_class_id: Self::ClassId, _token_id: Self::TokenId) -> Result { Ok(true) } - fn burn_nft(account: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn burn_nft(_account: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn is_transferable(nft: &(Self::ClassId, Self::TokenId)) -> Result { + fn is_transferable(_nft: &(Self::ClassId, Self::TokenId)) -> Result { Ok(true) } - fn get_class_fund(class_id: &Self::ClassId) -> AccountId { + fn get_class_fund(_class_id: &Self::ClassId) -> AccountId { CLASS_FUND_ID } - fn get_nft_detail(asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { + fn get_nft_detail(_asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { let new_data = NftClassData { deposit: 0, attributes: test_attributes(1), @@ -397,11 +393,11 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn set_lock_collection(class_id: Self::ClassId, is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_collection(_class_id: Self::ClassId, _is_locked: bool) -> sp_runtime::DispatchResult { todo!() } - fn set_lock_nft(token_id: (Self::ClassId, Self::TokenId), is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_nft(_token_id: (Self::ClassId, Self::TokenId), _is_locked: bool) -> sp_runtime::DispatchResult { todo!() } @@ -419,20 +415,20 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn get_total_issuance(class_id: Self::ClassId) -> Result { + fn get_total_issuance(_class_id: Self::ClassId) -> Result { Ok(10u64) } - fn get_asset_owner(asset_id: &(Self::ClassId, Self::TokenId)) -> Result { + fn get_asset_owner(_asset_id: &(Self::ClassId, Self::TokenId)) -> Result { Ok(ALICE) } fn mint_token_with_id( sender: &AccountId, class_id: Self::ClassId, - token_id: Self::TokenId, - metadata: NftMetadata, - attributes: Attributes, + _token_id: Self::TokenId, + _metadata: NftMetadata, + _attributes: Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -456,31 +452,31 @@ impl NFTTrait for MockNFTHandler { } } - fn get_free_stackable_nft_balance(who: &AccountId, asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { + fn get_free_stackable_nft_balance(_who: &AccountId, _asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { 1000 } fn reserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> DispatchResult { Ok(()) } fn unreserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } fn transfer_stackable_nft( - sender: &AccountId, - to: &AccountId, - nft: &(Self::ClassId, Self::TokenId), - amount: Balance, + _sender: &AccountId, + _to: &AccountId, + _nft: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } diff --git a/modules/bridge/src/tests.rs b/modules/bridge/src/tests.rs index c3e5f13a4..0308dcb72 100644 --- a/modules/bridge/src/tests.rs +++ b/modules/bridge/src/tests.rs @@ -1,16 +1,13 @@ #![cfg(test)] -use std::str::{from_utf8, FromStr}; +use std::str::FromStr; -use frame_support::{assert_noop, assert_ok}; +use frame_support::assert_ok; use sp_core::H160; -use mock::{Balances, BridgeModule, ExtBuilder, One, Runtime, RuntimeEvent, RuntimeOrigin, System, Tokens}; -use primitives::evm::{CurrencyIdType, EvmAddress, H160_POSITION_CURRENCY_ID_TYPE, H160_POSITION_TOKEN}; -use primitives::FungibleTokenId::FungibleToken; -use primitives::{TokenId, TokenSymbol}; +use mock::{Balances, BridgeModule, ExtBuilder, RuntimeOrigin}; -use crate::mock::{BridgeSovereignPalletId, ALICE, BOB}; +use crate::mock::{ALICE, BOB}; use super::*; diff --git a/node/src/chain_spec/metaverse.rs b/node/src/chain_spec/metaverse.rs index 64d0d0010..1c88f618a 100644 --- a/node/src/chain_spec/metaverse.rs +++ b/node/src/chain_spec/metaverse.rs @@ -1,4 +1,3 @@ -use std::collections::BTreeMap; use std::str::FromStr; use hex_literal::hex; @@ -8,16 +7,13 @@ use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::crypto::UncheckedInto; use sp_core::{sr25519, Pair, Public, H160, U256}; use sp_finality_grandpa::AuthorityId as GrandpaId; -use sp_runtime::{ - traits::{IdentifyAccount, Verify}, - Perbill, -}; +use sp_runtime::traits::{IdentifyAccount, Verify}; use metaverse_runtime::{ constants::currency::*, opaque::SessionKeys, wasm_binary_unwrap, AccountId, AuraConfig, BalancesConfig, BaseFeeConfig, CollatorSelectionConfig, DemocracyConfig, EVMConfig, EstateConfig, EthereumConfig, GenesisAccount, - GenesisConfig, GrandpaConfig, MintingRange, MintingRateInfo, OracleMembershipConfig, SessionConfig, Signature, - SudoConfig, SystemConfig, + GenesisConfig, GrandpaConfig, MintingRateInfo, OracleMembershipConfig, SessionConfig, Signature, SudoConfig, + SystemConfig, }; use primitives::Balance; diff --git a/node/src/cli.rs b/node/src/cli.rs index 53d21dab7..10454a8e5 100644 --- a/node/src/cli.rs +++ b/node/src/cli.rs @@ -5,7 +5,6 @@ use cumulus_client_cli; use url::Url; use crate::chain_spec; -use crate::chain_spec::Extensions; fn validate_relay_chain_url(arg: &str) -> Result<(), String> { let url = Url::parse(arg).map_err(|e| e.to_string())?; diff --git a/node/src/command.rs b/node/src/command.rs index 41a6fc8a6..c2be223b2 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{io::Write, net::SocketAddr, sync::Arc}; +use std::{io::Write, net::SocketAddr}; use codec::Encode; use cumulus_client_cli::generate_genesis_block; @@ -23,13 +23,14 @@ use cumulus_primitives_core::ParaId; use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; use log::info; use sc_cli::{ - ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, NetworkParams, Result, Role, + ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli, }; use sc_service::config::{BasePath, PrometheusConfig}; use sc_service::PartialComponents; use sp_core::hexdisplay::HexDisplay; -use sp_runtime::traits::{AccountIdConversion, Block as BlockT}; +use sp_runtime::traits::AccountIdConversion; +use sp_runtime::traits::Block as BlockT; #[cfg(feature = "with-continuum-runtime")] use continuum_runtime::RuntimeApi; @@ -41,12 +42,11 @@ use pioneer_runtime::RuntimeApi; use crate::service::{continuum_partial, ContinuumParachainRuntimeExecutor}; #[cfg(feature = "with-pioneer-runtime")] use crate::service::{pioneer_partial, ParachainRuntimeExecutor}; -use crate::service::{CONTINUUM_RUNTIME_NOT_AVAILABLE, METAVERSE_RUNTIME_NOT_AVAILABLE, PIONEER_RUNTIME_NOT_AVAILABLE}; +use crate::service::{CONTINUUM_RUNTIME_NOT_AVAILABLE, PIONEER_RUNTIME_NOT_AVAILABLE}; use crate::{ chain_spec, cli::{Cli, RelayChainCli, Subcommand}, service, - service::ExecutorDispatch, }; fn load_spec(id: &str) -> std::result::Result, String> { diff --git a/node/src/rpc/rpc_metaverse.rs b/node/src/rpc/rpc_metaverse.rs index f46faed58..b4113a02e 100644 --- a/node/src/rpc/rpc_metaverse.rs +++ b/node/src/rpc/rpc_metaverse.rs @@ -6,12 +6,12 @@ use fc_rpc::{ EthBlockDataCacheTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override, SchemaV2Override, SchemaV3Override, StorageOverride, }; -use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool}; +use fc_rpc_core::types::{FeeHistoryCache, FilterPool}; use fp_storage::EthereumStorageSchema; -use jsonrpc_pubsub::manager::SubscriptionManager; + use jsonrpsee::RpcModule; use pallet_transaction_payment_rpc; -use sc_cli::SubstrateCli; + // Substrate use sc_client_api::{ backend::{AuxStore, Backend, StateBackend, StorageProvider}, @@ -23,7 +23,7 @@ use sc_transaction_pool::{ChainApi, Pool}; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; -use sp_blockchain::{Backend as BlockchainBackend, Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; use sp_runtime::traits::BlakeTwo256; use substrate_frame_rpc_system::{System, SystemApiServer}; @@ -138,8 +138,8 @@ where A: ChainApi + 'static, { use fc_rpc::{ - Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer, EthSigner, Net, - NetApiServer, Web3, Web3ApiServer, + Eth, EthApiServer, EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer, Net, NetApiServer, Web3, + Web3ApiServer, }; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; use substrate_frame_rpc_system::SystemApiServer; diff --git a/node/src/service/metaverse.rs b/node/src/service/metaverse.rs index 2dacd366b..1c4c478d1 100644 --- a/node/src/service/metaverse.rs +++ b/node/src/service/metaverse.rs @@ -14,7 +14,7 @@ use fc_consensus::FrontierBlockImport; use fc_rpc::EthTask; use fc_rpc_core::types::{FeeHistoryCache, FilterPool}; use futures::StreamExt; -use sc_client_api::{BlockBackend, BlockchainEvents, ExecutorProvider}; +use sc_client_api::{BlockBackend, BlockchainEvents}; use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams}; use sc_executor::NativeElseWasmExecutor; use sc_finality_grandpa::SharedVoterState; diff --git a/pallets/asset-manager/Cargo.toml b/pallets/asset-manager/Cargo.toml index ca6303094..61d84ad3b 100644 --- a/pallets/asset-manager/Cargo.toml +++ b/pallets/asset-manager/Cargo.toml @@ -12,12 +12,13 @@ version = '0.1.0' log = { workspace = true } serde = { workspace = true, optional = true } scale-info = { workspace = true } -codec = { package = "parity-scale-codec", version ="3.1.5", default-features = false } +codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false } sp-runtime = { workspace = true } sp-std = { workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } primitives = { package = "bit-country-primitives", path = "../../primitives/metaverse", default-features = false } +core-primitives = { path = "../../traits/core-primitives", default-features = false } xcm = { workspace = true } [dev-dependencies] @@ -42,5 +43,6 @@ std = [ "frame-support/std", "frame-system/std", "primitives/std", + "core-primitives/std", "xcm/std", ] \ No newline at end of file diff --git a/pallets/asset-manager/src/lib.rs b/pallets/asset-manager/src/lib.rs index c8c33008d..7a793cb42 100644 --- a/pallets/asset-manager/src/lib.rs +++ b/pallets/asset-manager/src/lib.rs @@ -23,7 +23,6 @@ #![allow(clippy::unused_unit)] use frame_support::{ - assert_ok, dispatch::DispatchResult, ensure, pallet_prelude::*, @@ -31,16 +30,14 @@ use frame_support::{ transactional, }; use frame_system::pallet_prelude::*; -use scale_info::prelude::format; use sp_runtime::{traits::One, ArithmeticError, FixedPointNumber, FixedU128}; -use sp_std::{boxed::Box, vec::Vec}; +use sp_std::boxed::Box; use xcm::v3::MultiLocation; use xcm::VersionedMultiLocation; +use core_primitives::CurrencyIdManagement; pub use pallet::*; -use primitives::{ - AssetIds, AssetMetadata, BuyWeightRate, CurrencyId, ForeignAssetIdMapping, FungibleTokenId, Ratio, TokenId, -}; +use primitives::{AssetIds, AssetMetadata, BuyWeightRate, ForeignAssetIdMapping, FungibleTokenId, Ratio, TokenId}; mod mock; mod tests; @@ -346,3 +343,23 @@ where None } } + +impl CurrencyIdManagement for ForeignAssetMapping { + fn check_token_exist(_token_id: FungibleTokenId) -> bool { + return true; + } + + fn convert_to_rcurrency(currency_id: FungibleTokenId) -> Result { + match currency_id { + FungibleTokenId::NativeToken(token_id) => Ok(FungibleTokenId::FungibleToken(token_id)), + _ => Err(()), + } + } + + fn convert_to_currency(currency_id: FungibleTokenId) -> Result { + match currency_id { + FungibleTokenId::FungibleToken(token_id) => Ok(FungibleTokenId::NativeToken(token_id)), + _ => Err(()), + } + } +} diff --git a/pallets/auction/src/lib.rs b/pallets/auction/src/lib.rs index 8afd48829..e338a1cf7 100644 --- a/pallets/auction/src/lib.rs +++ b/pallets/auction/src/lib.rs @@ -31,7 +31,7 @@ use frame_system::{self as system, ensure_signed}; use sp_core::sp_std::convert::TryInto; use sp_runtime::SaturatedConversion; use sp_runtime::{ - traits::{CheckedDiv, One, Saturating, Zero}, + traits::{One, Saturating, Zero}, DispatchError, DispatchResult, Perbill, }; use sp_std::vec::Vec; @@ -58,17 +58,12 @@ pub mod weights; pub struct AuctionLogicHandler; pub mod migration_v2 { - use codec::FullCodec; use codec::{Decode, Encode}; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; - use sp_runtime::{traits::AtLeast32BitUnsigned, DispatchError, RuntimeDebug}; - use sp_std::{ - cmp::{Eq, PartialEq}, - fmt::Debug, - vec::Vec, - }; + use sp_runtime::RuntimeDebug; + use sp_std::cmp::{Eq, PartialEq}; use auction_manager::{AuctionType, ListingLevel}; use primitives::{AssetId, EstateId, FungibleTokenId, MetaverseId}; @@ -104,20 +99,17 @@ pub mod migration_v2 { #[frame_support::pallet] pub mod pallet { + use frame_support::dispatch::DispatchResultWithPostInfo; use frame_support::log; use frame_support::sp_runtime::traits::CheckedSub; - use frame_support::{dispatch::DispatchResultWithPostInfo, traits::tokens::currency}; - use frame_system::ensure_root; use frame_system::pallet_prelude::OriginFor; use orml_traits::{MultiCurrency, MultiReservableCurrency}; use sp_runtime::traits::CheckedAdd; use sp_runtime::ArithmeticError; - use auction_manager::{AuctionItemV1, CheckAuctionItemHandler, ListingLevel}; + use auction_manager::{CheckAuctionItemHandler, ListingLevel}; use core_primitives::{MetaverseTrait, NFTTrait}; - use primitives::{AssetId, Balance, ClassId, FungibleTokenId, MetaverseId, TokenId}; - - use crate::migration_v2::V1ItemId; + use primitives::{Balance, ClassId, FungibleTokenId, MetaverseId, TokenId}; use super::*; @@ -1191,7 +1183,7 @@ pub mod pallet { /// Internal auction bid handler fn auction_bid_handler(from: T::AccountId, id: AuctionId, value: Self::Balance) -> DispatchResult { - let mut auction_item: AuctionItem> = + let auction_item: AuctionItem> = Self::get_auction_item(id.clone()).ok_or(Error::::AuctionDoesNotExist)?; ensure!( auction_item.auction_type == AuctionType::Auction, @@ -1426,7 +1418,7 @@ pub mod pallet { ::Currency::unreserve(&auction_item.recipient, T::NetworkFeeReserve::get()); // Transfer balance from buy it now user to asset owner - let mut currency_transfer; + let currency_transfer; if auction_item.currency_id == FungibleTokenId::NativeToken(0) { currency_transfer = ::Currency::transfer( &from, @@ -1618,7 +1610,7 @@ pub mod pallet { } // Handle balance transfer - let mut currency_transfer; + let currency_transfer; if auction_item.currency_id == FungibleTokenId::NativeToken(0) { currency_transfer = ::Currency::transfer( &high_bidder, diff --git a/pallets/auction/src/mock.rs b/pallets/auction/src/mock.rs index be22e2920..0352d86ce 100644 --- a/pallets/auction/src/mock.rs +++ b/pallets/auction/src/mock.rs @@ -12,7 +12,7 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, MultiSignature, Perbil use auction_manager::{CheckAuctionItemHandler, ListingLevel}; use core_primitives::{MetaverseInfo, MetaverseMetadata, MetaverseTrait, NftAssetData, NftClassData}; use primitives::{ - continuum::MapTrait, estate::Estate, Amount, AuctionId, ClassId, EstateId, FungibleTokenId, MapSpotId, NftOffer, + continuum::MapTrait, estate::Estate, Amount, AuctionId, ClassId, EstateId, FungibleTokenId, MapSpotId, UndeployedLandBlockId, }; @@ -117,9 +117,9 @@ impl Estate for EstateHandler { } fn transfer_undeployed_land_block( - who: &AccountId, - to: &AccountId, - undeployed_land_block_id: UndeployedLandBlockId, + _who: &AccountId, + _to: &AccountId, + _undeployed_land_block_id: UndeployedLandBlockId, ) -> Result { Ok(2) } @@ -141,7 +141,7 @@ impl Estate for EstateHandler { } fn check_undeployed_land_block( - owner: &AccountId, + _owner: &AccountId, undeployed_land_block_id: UndeployedLandBlockId, ) -> Result { match undeployed_land_block_id { @@ -151,7 +151,7 @@ impl Estate for EstateHandler { } } - fn get_total_land_units(estate_id: Option) -> u64 { + fn get_total_land_units(_estate_id: Option) -> u64 { 100 } @@ -159,15 +159,15 @@ impl Estate for EstateHandler { 100 } - fn check_estate_ownership(owner: AccountId, estate_id: EstateId) -> Result { + fn check_estate_ownership(_owner: AccountId, _estate_id: EstateId) -> Result { Ok(false) } - fn is_estate_leasor(leasor: AccountId, estate_id: EstateId) -> Result { + fn is_estate_leasor(_leasor: AccountId, _estate_id: EstateId) -> Result { Ok(false) } - fn is_estate_leased(estate_id: EstateId) -> Result { + fn is_estate_leased(_estate_id: EstateId) -> Result { Ok(false) } } @@ -241,7 +241,7 @@ parameter_types! { pub struct MetaverseInfoSource {} impl MetaverseTrait for MetaverseInfoSource { - fn create_metaverse(who: &AccountId, metadata: MetaverseMetadata) -> MetaverseId { + fn create_metaverse(_who: &AccountId, _metadata: MetaverseMetadata) -> MetaverseId { 1u64 } @@ -267,19 +267,19 @@ impl MetaverseTrait for MetaverseInfoSource { Ok(()) } - fn get_metaverse_land_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_land_class(_metaverse_id: MetaverseId) -> Result { Ok(15u32) } - fn get_metaverse_estate_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_estate_class(_metaverse_id: MetaverseId) -> Result { Ok(16u32) } - fn get_metaverse_marketplace_listing_fee(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_marketplace_listing_fee(_metaverse_id: MetaverseId) -> Result { Ok(Perbill::from_percent(1u32)) } - fn get_metaverse_treasury(metaverse_id: MetaverseId) -> AccountId { + fn get_metaverse_treasury(_metaverse_id: MetaverseId) -> AccountId { [102; 32].into() } @@ -288,7 +288,7 @@ impl MetaverseTrait for MetaverseInfoSource { } fn check_if_metaverse_estate( - metaverse_id: primitives::MetaverseId, + _metaverse_id: primitives::MetaverseId, class_id: &ClassId, ) -> Result { if class_id == &15u32 || class_id == &16u32 { @@ -490,7 +490,7 @@ impl Auction for MockAuctionManager { None } - fn auction_item(id: AuctionId) -> Option> { + fn auction_item(_id: AuctionId) -> Option> { None } @@ -498,7 +498,7 @@ impl Auction for MockAuctionManager { Ok(()) } - fn update_auction_item(id: AuctionId, item_id: ItemId) -> frame_support::dispatch::DispatchResult { + fn update_auction_item(_id: AuctionId, _item_id: ItemId) -> frame_support::dispatch::DispatchResult { Ok(()) } @@ -528,17 +528,17 @@ impl Auction for MockAuctionManager { fn remove_auction(_id: u64, _item_id: ItemId) {} fn auction_bid_handler( - from: AccountId, - id: AuctionId, - value: Self::Balance, + _from: AccountId, + _id: AuctionId, + _value: Self::Balance, ) -> frame_support::dispatch::DispatchResult { Ok(()) } fn buy_now_handler( - from: AccountId, - auction_id: AuctionId, - value: Self::Balance, + _from: AccountId, + _auction_id: AuctionId, + _value: Self::Balance, ) -> frame_support::dispatch::DispatchResult { Ok(()) } diff --git a/pallets/auction/src/tests.rs b/pallets/auction/src/tests.rs index d40984cdd..9a0616e6d 100644 --- a/pallets/auction/src/tests.rs +++ b/pallets/auction/src/tests.rs @@ -7,8 +7,8 @@ use sp_std::collections::btree_map::BTreeMap; use auction_manager::ListingLevel; use core_primitives::{Attributes, CollectionType, NFTTrait, TokenType}; use mock::{RuntimeEvent, *}; -use primitives::ItemId::NFT; -use primitives::{ClassId, FungibleTokenId}; + +use primitives::FungibleTokenId; use super::*; @@ -1691,7 +1691,7 @@ fn auction_bundle_should_update_new_price_according_new_bid() { assert_eq!(Balances::free_balance(ALICE), 99991); let tokens_after_bid = vec![(0, 0, 150), (0, 1, 150)]; - let item_updated_after_bid = AuctionModule::items_in_auction(ItemId::Bundle(tokens.clone())); + let _item_updated_after_bid = AuctionModule::items_in_auction(ItemId::Bundle(tokens.clone())); let auction_item = AuctionModule::get_auction_item(0).unwrap(); assert_eq!(auction_item.item_id, ItemId::Bundle(tokens_after_bid)); @@ -2112,7 +2112,7 @@ fn withdraw_offer_should_work() { fn finalize_auction_should_fail() { ExtBuilder::default().build().execute_with(|| { let owner = RuntimeOrigin::signed(BOB); - let bidder = RuntimeOrigin::signed(ALICE); + let _bidder = RuntimeOrigin::signed(ALICE); init_test_nft(owner.clone()); init_test_nft(owner.clone()); assert_ok!(AuctionModule::create_auction( @@ -2152,7 +2152,7 @@ fn finalize_auction_should_fail() { fn cancel_listing_should_work() { ExtBuilder::default().build().execute_with(|| { let owner = RuntimeOrigin::signed(BOB); - let bidder = RuntimeOrigin::signed(ALICE); + let _bidder = RuntimeOrigin::signed(ALICE); init_test_nft(owner.clone()); assert_ok!(AuctionModule::create_auction( AuctionType::Auction, @@ -2192,7 +2192,7 @@ fn cancel_listing_should_work() { fn cancel_listing_should_fail() { ExtBuilder::default().build().execute_with(|| { let owner = RuntimeOrigin::signed(BOB); - let bidder = RuntimeOrigin::signed(ALICE); + let _bidder = RuntimeOrigin::signed(ALICE); init_test_nft(owner.clone()); init_test_nft(owner.clone()); assert_ok!(AuctionModule::create_auction( diff --git a/pallets/continuum/src/lib.rs b/pallets/continuum/src/lib.rs index e73c0aca7..52649c14f 100644 --- a/pallets/continuum/src/lib.rs +++ b/pallets/continuum/src/lib.rs @@ -47,18 +47,15 @@ use codec::{Decode, Encode}; use frame_support::{ dispatch::DispatchResult, - ensure, log, + ensure, traits::ExistenceRequirement, traits::{Currency, Get, LockableCurrency, ReservableCurrency}, transactional, PalletId, }; use frame_system::{ensure_root, ensure_signed}; use scale_info::TypeInfo; -use sp_runtime::traits::CheckedAdd; -use sp_runtime::{ - traits::{AccountIdConversion, One, Zero}, - DispatchError, Perbill, RuntimeDebug, -}; + +use sp_runtime::{traits::AccountIdConversion, DispatchError, Perbill, RuntimeDebug}; use sp_std::vec; use sp_std::vec::Vec; @@ -112,7 +109,6 @@ pub struct AuctionSlot { pub mod pallet { use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*}; use frame_system::pallet_prelude::OriginFor; - use sp_arithmetic::traits::UniqueSaturatedInto; use core_primitives::TokenType; use primitives::{AuctionId, MapSpotId}; diff --git a/pallets/continuum/src/mock.rs b/pallets/continuum/src/mock.rs index a49353f1f..a57a3abf0 100644 --- a/pallets/continuum/src/mock.rs +++ b/pallets/continuum/src/mock.rs @@ -25,7 +25,7 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, Perbill}; use auction_manager::{Auction, AuctionInfo, AuctionItem, CheckAuctionItemHandler, ListingLevel}; use core_primitives::{MetaverseInfo, MetaverseMetadata, MetaverseTrait}; -use primitives::FungibleTokenId::FungibleToken; + use primitives::{AuctionId, ClassId, FungibleTokenId}; use crate as continuum; @@ -147,11 +147,11 @@ impl Auction for MockAuctionManager { return None; } - fn update_auction(id: AuctionId, _info: AuctionInfo) -> DispatchResult { + fn update_auction(_id: AuctionId, _info: AuctionInfo) -> DispatchResult { Ok(()) } - fn update_auction_item(id: AuctionId, item_id: ItemId) -> DispatchResult { + fn update_auction_item(_id: AuctionId, _item_id: ItemId) -> DispatchResult { Ok(()) } @@ -180,11 +180,11 @@ impl Auction for MockAuctionManager { fn remove_auction(_id: u64, _item_id: ItemId) {} - fn auction_bid_handler(from: AccountId, id: AuctionId, value: Self::Balance) -> DispatchResult { + fn auction_bid_handler(_from: AccountId, _id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } - fn buy_now_handler(from: AccountId, auction_id: AuctionId, value: Self::Balance) -> DispatchResult { + fn buy_now_handler(_from: AccountId, _auction_id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } @@ -228,7 +228,7 @@ parameter_types! { pub struct MetaverseInfoSource {} impl MetaverseTrait for MetaverseInfoSource { - fn create_metaverse(who: &AccountId, metadata: MetaverseMetadata) -> MetaverseId { + fn create_metaverse(_who: &AccountId, _metadata: MetaverseMetadata) -> MetaverseId { 1u64 } @@ -253,15 +253,15 @@ impl MetaverseTrait for MetaverseInfoSource { Ok(()) } - fn get_metaverse_land_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_land_class(_metaverse_id: MetaverseId) -> Result { Ok(15u32) } - fn get_metaverse_estate_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_estate_class(_metaverse_id: MetaverseId) -> Result { Ok(16u32) } - fn get_metaverse_marketplace_listing_fee(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_marketplace_listing_fee(_metaverse_id: MetaverseId) -> Result { Ok(Perbill::from_percent(1u32)) } @@ -278,7 +278,7 @@ impl MetaverseTrait for MetaverseInfoSource { } fn check_if_metaverse_estate( - metaverse_id: primitives::MetaverseId, + _metaverse_id: primitives::MetaverseId, class_id: &ClassId, ) -> Result { if class_id == &15u32 || class_id == &16u32 { @@ -295,7 +295,7 @@ impl MetaverseTrait for MetaverseInfoSource { } } - fn is_metaverse_owner(who: &AccountId) -> bool { + fn is_metaverse_owner(_who: &AccountId) -> bool { true } } diff --git a/pallets/continuum/src/tests.rs b/pallets/continuum/src/tests.rs index db3b7c10c..048f61345 100644 --- a/pallets/continuum/src/tests.rs +++ b/pallets/continuum/src/tests.rs @@ -21,8 +21,8 @@ use frame_support::{assert_noop, assert_ok}; use sp_runtime::traits::BadOrigin; use core_primitives::TokenType; -use mock::BlockNumber as MBlockNumber; -use mock::{RuntimeEvent, *}; + +use mock::*; use super::*; diff --git a/pallets/crowdloan/src/lib.rs b/pallets/crowdloan/src/lib.rs index ebe710e1e..ed189b346 100644 --- a/pallets/crowdloan/src/lib.rs +++ b/pallets/crowdloan/src/lib.rs @@ -18,26 +18,17 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::pallet_prelude::*; -use frame_support::traits::{Currency, ExistenceRequirement, VestingSchedule}; -use frame_support::{dispatch::DispatchResult, ensure, traits::Get, PalletId}; +use frame_support::traits::{Currency, VestingSchedule}; +use frame_support::{dispatch::DispatchResult, ensure, traits::Get}; use frame_system::pallet_prelude::*; use frame_system::{ensure_root, ensure_signed}; use pallet_vesting::{Pallet as VestingModule, VestingInfo}; -use scale_info::TypeInfo; -use sp_runtime::traits::Convert; -use sp_runtime::{ - traits::{AccountIdConversion, One, Saturating, Zero}, - DispatchError, -}; + +use sp_runtime::traits::Saturating; use sp_std::{convert::TryInto, vec::Vec}; -use auction_manager::{Auction, CheckAuctionItemHandler}; -use core_primitives::*; pub use pallet::*; -use primitives::{ - estate::Estate, Balance, EstateId, ItemId, MetaverseId, UndeployedLandBlock, UndeployedLandBlockId, - UndeployedLandBlockType, -}; + pub use weights::WeightInfo; #[cfg(feature = "runtime-benchmarks")] @@ -53,11 +44,9 @@ pub mod weights; #[frame_support::pallet] pub mod pallet { - use frame_support::traits::{Currency, ExistenceRequirement, Imbalance, ReservableCurrency, VestingSchedule}; + use frame_support::traits::{Currency, ExistenceRequirement, VestingSchedule}; use pallet_vesting::VestingInfo; - use sp_runtime::traits::{CheckedAdd, CheckedSub, Convert, ConvertInto, StaticLookup, Zero}; - - use primitives::UndeployedLandBlockId; + use sp_runtime::traits::{Convert, StaticLookup}; use super::*; diff --git a/pallets/crowdloan/src/mock.rs b/pallets/crowdloan/src/mock.rs index d13741bbb..d7366fa24 100644 --- a/pallets/crowdloan/src/mock.rs +++ b/pallets/crowdloan/src/mock.rs @@ -1,14 +1,11 @@ #![cfg(test)] use frame_support::traits::WithdrawReasons; -use frame_support::{construct_runtime, ord_parameter_types, parameter_types, PalletId}; -use frame_system::EnsureSignedBy; -use sp_core::H256; -use sp_runtime::traits::{ConvertInto, Identity}; -use sp_runtime::{testing::Header, traits::IdentityLookup, DispatchError, Perbill}; +use frame_support::{construct_runtime, ord_parameter_types, parameter_types}; -use auction_manager::{Auction, AuctionInfo, AuctionType, CheckAuctionItemHandler, ListingLevel}; -use primitives::FungibleTokenId; +use sp_core::H256; +use sp_runtime::traits::ConvertInto; +use sp_runtime::{testing::Header, traits::IdentityLookup, Perbill}; use crate as crowdloan; @@ -124,29 +121,29 @@ impl VestingSchedule for VestingScheduleTrait { type Moment = (); type Currency = Balances; - fn vesting_balance(who: &AccountId) -> Option { + fn vesting_balance(_who: &AccountId) -> Option { None } fn add_vesting_schedule( - who: &AccountId, - locked: Balance, - per_block: Balance, - starting_block: Self::Moment, + _who: &AccountId, + _locked: Balance, + _per_block: Balance, + _starting_block: Self::Moment, ) -> DispatchResult { Ok(()) } fn can_add_vesting_schedule( - who: &AccountId, - locked: Balance, - per_block: Balance, - starting_block: Self::Moment, + _who: &AccountId, + _locked: Balance, + _per_block: Balance, + _starting_block: Self::Moment, ) -> DispatchResult { Ok(()) } - fn remove_vesting_schedule(who: &AccountId, schedule_index: u32) -> DispatchResult { + fn remove_vesting_schedule(_who: &AccountId, _schedule_index: u32) -> DispatchResult { Ok(()) } } diff --git a/pallets/crowdloan/src/tests.rs b/pallets/crowdloan/src/tests.rs index e64629b57..79d295b2d 100644 --- a/pallets/crowdloan/src/tests.rs +++ b/pallets/crowdloan/src/tests.rs @@ -17,7 +17,7 @@ #![cfg(test)] -use frame_support::{assert_err, assert_noop, assert_ok}; +use frame_support::{assert_noop, assert_ok}; use sp_runtime::traits::BadOrigin; use mock::{RuntimeEvent, *}; diff --git a/pallets/economy/src/lib.rs b/pallets/economy/src/lib.rs index be695632a..124e7997a 100644 --- a/pallets/economy/src/lib.rs +++ b/pallets/economy/src/lib.rs @@ -17,16 +17,15 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode, HasCompact}; -use frame_support::traits::{LockIdentifier, WithdrawReasons}; +use codec::Encode; use frame_support::{ - ensure, log, + ensure, pallet_prelude::*, - traits::{Currency, ExistenceRequirement, LockableCurrency, ReservableCurrency}, + traits::{Currency, LockableCurrency, ReservableCurrency}, transactional, PalletId, }; use frame_system::{ensure_signed, pallet_prelude::*}; -use orml_traits::{DataFeeder, DataProvider, MultiCurrency, MultiReservableCurrency}; +use orml_traits::{DataProvider, MultiCurrency, MultiReservableCurrency}; use sp_runtime::traits::{BlockNumberProvider, CheckedAdd, CheckedMul, Saturating}; use sp_runtime::{ traits::{AccountIdConversion, One, Zero}, @@ -38,7 +37,7 @@ use core_primitives::NFTTrait; use core_primitives::*; pub use pallet::*; use primitives::{estate::Estate, EstateId}; -use primitives::{AssetId, Balance, ClassId, DomainId, FungibleTokenId, MetaverseId, NftId, PowerAmount, RoundIndex}; +use primitives::{Balance, ClassId, DomainId, FungibleTokenId, PowerAmount, RoundIndex}; pub use weights::WeightInfo; //#[cfg(feature = "runtime-benchmarks")] @@ -54,12 +53,11 @@ pub mod weights; #[frame_support::pallet] pub mod pallet { - use orml_traits::MultiCurrencyExtended; use sp_runtime::traits::{CheckedAdd, CheckedSub, Saturating}; use sp_runtime::ArithmeticError; - use primitives::staking::{Bond, RoundInfo}; - use primitives::{ClassId, GroupCollectionId, NftId}; + use primitives::staking::Bond; + use primitives::{ClassId, NftId}; use super::*; @@ -338,7 +336,7 @@ pub mod pallet { Error::::ExitQueueAlreadyScheduled ); - let mut staked_balance = StakingInfo::::get(&who); + let staked_balance = StakingInfo::::get(&who); let total = staked_balance.checked_add(&amount).ok_or(ArithmeticError::Overflow)?; ensure!(total >= T::MinimumStake::get(), Error::::StakeBelowMinimum); @@ -440,7 +438,7 @@ pub mod pallet { match estate { None => { - let mut staked_balance = StakingInfo::::get(&who); + let staked_balance = StakingInfo::::get(&who); ensure!(amount <= staked_balance, Error::::UnstakeAmountExceedStakedAmount); let remaining = staked_balance.checked_sub(&amount).ok_or(ArithmeticError::Underflow)?; @@ -672,7 +670,7 @@ pub mod pallet { match estate { None => { - let mut staked_balance = StakingInfo::::get(&who); + let staked_balance = StakingInfo::::get(&who); ensure!(amount <= staked_balance, Error::::UnstakeAmountExceedStakedAmount); let remaining = staked_balance.checked_sub(&amount).ok_or(ArithmeticError::Underflow)?; @@ -771,7 +769,7 @@ pub mod pallet { ensure!(!amount.is_zero(), Error::::UnstakeAmountIsZero); // Update staking info - let mut staked_reserved_balance = T::Currency::reserved_balance(&who); + let staked_reserved_balance = T::Currency::reserved_balance(&who); ensure!( amount <= staked_reserved_balance, Error::::UnstakeAmountExceedStakedAmount @@ -795,7 +793,7 @@ impl Pallet { pub fn convert_power_to_bit(power_amount: Balance, commission: Perbill) -> (Balance, Balance) { let rate = Self::get_bit_power_exchange_rate(); - let mut bit_required = power_amount + let bit_required = power_amount .checked_mul(rate) .ok_or(ArithmeticError::Overflow) .unwrap_or(Zero::zero()); diff --git a/pallets/economy/src/mock.rs b/pallets/economy/src/mock.rs index caccaa029..6969f2bf4 100644 --- a/pallets/economy/src/mock.rs +++ b/pallets/economy/src/mock.rs @@ -3,7 +3,7 @@ use frame_support::traits::Nothing; use frame_support::{construct_runtime, ord_parameter_types, parameter_types, PalletId}; use frame_system::EnsureSignedBy; -use orml_traits::currency::MutationHooks; + use orml_traits::parameter_type_with_key; use sp_core::crypto::AccountId32; use sp_core::H256; @@ -139,9 +139,9 @@ impl Estate for EstateHandler { } fn transfer_undeployed_land_block( - who: &AccountId, - to: &AccountId, - undeployed_land_block_id: UndeployedLandBlockId, + _who: &AccountId, + _to: &AccountId, + _undeployed_land_block_id: UndeployedLandBlockId, ) -> Result { Ok(2) } @@ -160,18 +160,18 @@ impl Estate for EstateHandler { Ok(false) } - fn check_landunit(_metaverse_id: primitives::MetaverseId, coordinate: (i32, i32)) -> Result { + fn check_landunit(_metaverse_id: primitives::MetaverseId, _coordinate: (i32, i32)) -> Result { Ok(true) } fn check_undeployed_land_block( - owner: &AccountId, - undeployed_land_block_id: UndeployedLandBlockId, + _owner: &AccountId, + _undeployed_land_block_id: UndeployedLandBlockId, ) -> Result { Ok(true) } - fn get_total_land_units(estate_id: Option) -> u64 { + fn get_total_land_units(_estate_id: Option) -> u64 { 10 } @@ -179,11 +179,11 @@ impl Estate for EstateHandler { 10 } - fn is_estate_leasor(leasor: AccountId, estate_id: EstateId) -> Result { + fn is_estate_leasor(_leasor: AccountId, _estate_id: EstateId) -> Result { Ok(false) } - fn is_estate_leased(estate_id: EstateId) -> Result { + fn is_estate_leased(_estate_id: EstateId) -> Result { Ok(false) } } @@ -191,7 +191,7 @@ impl Estate for EstateHandler { pub struct MetaverseStakingHandler; impl MetaverseStakingTrait for MetaverseStakingHandler { - fn update_staking_reward(round: RoundIndex, total_reward: u128) -> sp_runtime::DispatchResult { + fn update_staking_reward(_round: RoundIndex, _total_reward: u128) -> sp_runtime::DispatchResult { Ok(()) } } @@ -284,7 +284,7 @@ impl Auction for MockAuctionManager { None } - fn auction_item(id: AuctionId) -> Option> { + fn auction_item(_id: AuctionId) -> Option> { None } @@ -292,7 +292,7 @@ impl Auction for MockAuctionManager { Ok(()) } - fn update_auction_item(id: AuctionId, item_id: ItemId) -> DispatchResult { + fn update_auction_item(_id: AuctionId, _item_id: ItemId) -> DispatchResult { Ok(()) } @@ -321,11 +321,11 @@ impl Auction for MockAuctionManager { fn remove_auction(_id: u64, _item_id: ItemId) {} - fn auction_bid_handler(from: AccountId, id: AuctionId, value: Self::Balance) -> DispatchResult { + fn auction_bid_handler(_from: AccountId, _id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } - fn buy_now_handler(from: AccountId, auction_id: AuctionId, value: Self::Balance) -> DispatchResult { + fn buy_now_handler(_from: AccountId, _auction_id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } diff --git a/pallets/economy/src/tests.rs b/pallets/economy/src/tests.rs index 957d005d9..64e848a46 100644 --- a/pallets/economy/src/tests.rs +++ b/pallets/economy/src/tests.rs @@ -17,12 +17,11 @@ #![cfg(test)] -use frame_support::{assert_err, assert_noop, assert_ok}; -use orml_nft::Tokens; +use frame_support::{assert_noop, assert_ok}; + use sp_runtime::traits::BadOrigin; use sp_std::default::Default; -use auction_manager::ListingLevel; use core_primitives::{Attributes, CollectionType, TokenType}; use mock::{RuntimeEvent, *}; use primitives::staking::Bond; diff --git a/pallets/estate/src/lib.rs b/pallets/estate/src/lib.rs index 3c124e779..b7a31ca30 100644 --- a/pallets/estate/src/lib.rs +++ b/pallets/estate/src/lib.rs @@ -26,11 +26,10 @@ use frame_support::{ }; use frame_system::pallet_prelude::*; use frame_system::{ensure_root, ensure_signed}; -use scale_info::TypeInfo; use sp_runtime::{ - traits::{AccountIdConversion, Convert, One, Saturating, Zero}, - ArithmeticError, DispatchError, Perbill, SaturatedConversion, + traits::{AccountIdConversion, Convert, One, Saturating}, + DispatchError, Perbill, SaturatedConversion, }; use sp_std::vec::Vec; @@ -40,7 +39,7 @@ pub use pallet::*; use primitives::estate::EstateInfo; use primitives::{ estate::{Estate, LandUnitStatus, LeaseContract, OwnerId}, - Attributes, ClassId, EstateId, FungibleTokenId, ItemId, MetaverseId, NftMetadata, TokenId, UndeployedLandBlock, + Attributes, ClassId, EstateId, ItemId, MetaverseId, NftMetadata, TokenId, UndeployedLandBlock, UndeployedLandBlockId, UndeployedLandBlockType, }; pub use rate::{MintingRateInfo, Range}; @@ -61,11 +60,11 @@ pub mod weights; #[frame_support::pallet] pub mod pallet { use frame_support::traits::{Currency, Imbalance, ReservableCurrency}; - use sp_runtime::traits::{CheckedAdd, CheckedSub, Zero}; + use sp_runtime::traits::{CheckedSub, Zero}; use primitives::estate::EstateInfo; - use primitives::staking::{Bond, RoundInfo, StakeSnapshot}; - use primitives::{Balance, RoundIndex, UndeployedLandBlockId}; + use primitives::staking::RoundInfo; + use primitives::{RoundIndex, UndeployedLandBlockId}; use crate::rate::{round_issuance_range, MintingRateInfo}; @@ -1047,7 +1046,7 @@ pub mod pallet { T::NFTTokenizationSource::burn_nft(&who, &(class_id, token_id)); *estate_owner = None; } - OwnerId::Account(ref a) => { + OwnerId::Account(ref _a) => { *estate_owner = None; } } @@ -1063,7 +1062,7 @@ pub mod pallet { AllEstatesCount::::put(new_total_estates_count); // Mint new land tokens to replace the lands in the dissolved estate - let estate_account_id: T::AccountId = + let _estate_account_id: T::AccountId = T::LandTreasury::get().into_sub_account_truncating(estate_id); let storage_fee: BalanceOf = Perbill::from_percent(100u32.saturating_mul(estate_info.land_units.len() as u32)) @@ -1207,11 +1206,12 @@ pub mod pallet { Error::::NoPermission ); let estate_info: EstateInfo = Estates::::get(estate_id).ok_or(Error::::EstateDoesNotExist)?; - let estate_account_id: T::AccountId = T::LandTreasury::get().into_sub_account_truncating(estate_id); + let _estate_account_id: T::AccountId = + T::LandTreasury::get().into_sub_account_truncating(estate_id); // Mutate estates Estates::::try_mutate_exists(&estate_id, |maybe_estate_info| { - let mut mut_estate_info = maybe_estate_info.as_mut().ok_or(Error::::EstateDoesNotExist)?; + let mut_estate_info = maybe_estate_info.as_mut().ok_or(Error::::EstateDoesNotExist)?; let storage_fee: BalanceOf = Perbill::from_percent(100u32.saturating_mul(land_units.len() as u32)) @@ -1549,7 +1549,7 @@ pub mod pallet { ); let current_block = >::block_number(); EstateLeases::::try_mutate_exists(&estate_id, |estate_lease_value| { - let mut lease = estate_lease_value.as_mut().ok_or(Error::::LeaseDoesNotExist)?; + let lease = estate_lease_value.as_mut().ok_or(Error::::LeaseDoesNotExist)?; ensure!(lease.end_block > current_block, Error::::LeaseIsExpired); @@ -1615,7 +1615,7 @@ impl Pallet { Error::::NoPermission ); - if let OwnerId::Token(owner_class_id, owner_token_id) = token_owner { + if let OwnerId::Token(owner_class_id, _owner_token_id) = token_owner { ensure!(owner_class_id != class_id, Error::::LandUnitAlreadyInEstate) } @@ -1881,11 +1881,11 @@ impl Pallet { from: &T::AccountId, to: &T::AccountId, ) -> Result { - EstateOwner::::try_mutate_exists(&estate_id, |estate_owner| -> Result { + EstateOwner::::try_mutate_exists(&estate_id, |_estate_owner| -> Result { //ensure there is record of the estate owner with estate id and account id ensure!(from != to, Error::::AlreadyOwnTheEstate); let estate_owner_value = Self::get_estate_owner(&estate_id).ok_or(Error::::NoPermission)?; - let estate_info = Estates::::get(estate_id).ok_or(Error::::EstateDoesNotExist)?; + let _estate_info = Estates::::get(estate_id).ok_or(Error::::EstateDoesNotExist)?; ensure!( !EstateLeases::::contains_key(estate_id), Error::::EstateIsAlreadyLeased @@ -2081,8 +2081,8 @@ impl Pallet { } fn verify_land_unit_in_bound(block_coordinate: &(i32, i32), land_unit_coordinates: &Vec<(i32, i32)>) -> bool { - let mut vec_axis = land_unit_coordinates.iter().map(|lu| lu.0).collect::>(); - let mut vec_yaxis = land_unit_coordinates.iter().map(|lu| lu.1).collect::>(); + let vec_axis = land_unit_coordinates.iter().map(|lu| lu.0).collect::>(); + let vec_yaxis = land_unit_coordinates.iter().map(|lu| lu.1).collect::>(); let max_axis = vec_axis.iter().max().unwrap_or(&i32::MAX); let max_yaxis = vec_yaxis.iter().max().unwrap_or(&i32::MAX); diff --git a/pallets/estate/src/mock.rs b/pallets/estate/src/mock.rs index 3856a489b..c20c8137d 100644 --- a/pallets/estate/src/mock.rs +++ b/pallets/estate/src/mock.rs @@ -14,9 +14,7 @@ use sp_std::vec::Vec; use auction_manager::{Auction, AuctionInfo, AuctionItem, AuctionType, CheckAuctionItemHandler, ListingLevel}; use core_primitives::{CollectionType, NftClassData, TokenType}; -use primitives::{ - AssetId, Attributes, AuctionId, ClassId, FungibleTokenId, GroupCollectionId, NftMetadata, TokenId, LAND_CLASS_ID, -}; +use primitives::{Attributes, AuctionId, ClassId, FungibleTokenId, GroupCollectionId, NftMetadata, TokenId}; use crate as estate; @@ -144,7 +142,7 @@ parameter_types! { pub struct MetaverseInfoSource {} impl MetaverseTrait for MetaverseInfoSource { - fn create_metaverse(who: &AccountId, metadata: MetaverseMetadata) -> MetaverseId { + fn create_metaverse(_who: &AccountId, _metadata: MetaverseMetadata) -> MetaverseId { 1u64 } @@ -168,19 +166,19 @@ impl MetaverseTrait for MetaverseInfoSource { Ok(()) } - fn get_metaverse_land_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_land_class(_metaverse_id: MetaverseId) -> Result { Ok(METAVERSE_LAND_CLASS) } - fn get_metaverse_estate_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_estate_class(_metaverse_id: MetaverseId) -> Result { Ok(METAVERSE_ESTATE_CLASS) } - fn get_metaverse_marketplace_listing_fee(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_marketplace_listing_fee(_metaverse_id: MetaverseId) -> Result { Ok(Perbill::from_percent(1u32)) } - fn get_metaverse_treasury(metaverse_id: MetaverseId) -> AccountId { + fn get_metaverse_treasury(_metaverse_id: MetaverseId) -> AccountId { GENERAL_METAVERSE_FUND } @@ -189,7 +187,7 @@ impl MetaverseTrait for MetaverseInfoSource { } fn check_if_metaverse_estate( - metaverse_id: primitives::MetaverseId, + _metaverse_id: primitives::MetaverseId, class_id: &ClassId, ) -> Result { if class_id == &METAVERSE_LAND_CLASS || class_id == &METAVERSE_ESTATE_CLASS { @@ -202,7 +200,7 @@ impl MetaverseTrait for MetaverseInfoSource { Ok(true) } - fn is_metaverse_owner(who: &AccountId) -> bool { + fn is_metaverse_owner(_who: &AccountId) -> bool { true } } @@ -216,7 +214,7 @@ impl Auction for MockAuctionManager { None } - fn auction_item(id: AuctionId) -> Option> { + fn auction_item(_id: AuctionId) -> Option> { None } @@ -224,7 +222,7 @@ impl Auction for MockAuctionManager { Ok(()) } - fn update_auction_item(id: AuctionId, item_id: ItemId) -> DispatchResult { + fn update_auction_item(_id: AuctionId, _item_id: ItemId) -> DispatchResult { Ok(()) } @@ -253,11 +251,11 @@ impl Auction for MockAuctionManager { fn remove_auction(_id: u64, _item_id: ItemId) {} - fn auction_bid_handler(from: AccountId, id: AuctionId, value: Self::Balance) -> DispatchResult { + fn auction_bid_handler(_from: AccountId, _id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } - fn buy_now_handler(from: AccountId, auction_id: AuctionId, value: Self::Balance) -> DispatchResult { + fn buy_now_handler(_from: AccountId, _auction_id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } @@ -335,23 +333,23 @@ impl NFTTrait for MockNFTHandler { } Ok(false) } - fn get_nft_group_collection(nft_collection: &Self::ClassId) -> Result { + fn get_nft_group_collection(_nft_collection: &Self::ClassId) -> Result { Ok(ASSET_COLLECTION_ID) } - fn is_stackable(asset_id: (Self::ClassId, Self::TokenId)) -> Result { + fn is_stackable(_asset_id: (Self::ClassId, Self::TokenId)) -> Result { Ok(false) } fn create_token_class( sender: &AccountId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, collection_id: GroupCollectionId, - token_type: TokenType, - collection_type: CollectionType, - royalty_fee: Perbill, - mint_limit: Option, + _token_type: TokenType, + _collection_type: CollectionType, + _royalty_fee: Perbill, + _mint_limit: Option, ) -> Result { match *sender { ALICE => { @@ -372,8 +370,8 @@ impl NFTTrait for MockNFTHandler { fn mint_token( sender: &AccountId, class_id: ClassId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -406,26 +404,26 @@ impl NFTTrait for MockNFTHandler { } } - fn transfer_nft(from: &AccountId, to: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn transfer_nft(_from: &AccountId, _to: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn check_item_on_listing(class_id: Self::ClassId, token_id: Self::TokenId) -> Result { + fn check_item_on_listing(_class_id: Self::ClassId, _token_id: Self::TokenId) -> Result { Ok(true) } - fn burn_nft(account: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn burn_nft(_account: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn is_transferable(nft: &(Self::ClassId, Self::TokenId)) -> Result { + fn is_transferable(_nft: &(Self::ClassId, Self::TokenId)) -> Result { Ok(true) } - fn get_class_fund(class_id: &Self::ClassId) -> AccountId { + fn get_class_fund(_class_id: &Self::ClassId) -> AccountId { CLASS_FUND_ID } - fn get_nft_detail(asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { + fn get_nft_detail(_asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { let new_data = NftClassData { deposit: 0, attributes: test_attributes(1), @@ -439,11 +437,11 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn set_lock_collection(class_id: Self::ClassId, is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_collection(_class_id: Self::ClassId, _is_locked: bool) -> sp_runtime::DispatchResult { Ok(()) } - fn set_lock_nft(token_id: (Self::ClassId, Self::TokenId), is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_nft(_token_id: (Self::ClassId, Self::TokenId), _is_locked: bool) -> sp_runtime::DispatchResult { Ok(()) } @@ -461,20 +459,20 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn get_total_issuance(class_id: Self::ClassId) -> Result { + fn get_total_issuance(_class_id: Self::ClassId) -> Result { Ok(10u64) } - fn get_asset_owner(asset_id: &(Self::ClassId, Self::TokenId)) -> Result { + fn get_asset_owner(_asset_id: &(Self::ClassId, Self::TokenId)) -> Result { Ok(ALICE) } fn mint_token_with_id( sender: &AccountId, class_id: Self::ClassId, - token_id: Self::TokenId, - metadata: core_primitives::NftMetadata, - attributes: core_primitives::Attributes, + _token_id: Self::TokenId, + _metadata: core_primitives::NftMetadata, + _attributes: core_primitives::Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -507,31 +505,31 @@ impl NFTTrait for MockNFTHandler { } } - fn get_free_stackable_nft_balance(who: &AccountId, asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { + fn get_free_stackable_nft_balance(_who: &AccountId, _asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { 1000 } fn reserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> DispatchResult { Ok(()) } fn unreserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } fn transfer_stackable_nft( - sender: &AccountId, - to: &AccountId, - nft: &(Self::ClassId, Self::TokenId), - amount: Balance, + _sender: &AccountId, + _to: &AccountId, + _nft: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } diff --git a/pallets/governance/src/lib.rs b/pallets/governance/src/lib.rs index 0f748ebf7..a1dfa13bd 100644 --- a/pallets/governance/src/lib.rs +++ b/pallets/governance/src/lib.rs @@ -459,7 +459,7 @@ pub mod pallet { let mut metaverse_has_referendum_running: bool = false; for (_, referendum_info) in ReferendumInfoOf::::iter_prefix(metaverse_id) { match referendum_info { - ReferendumInfo::Ongoing(status) => { + ReferendumInfo::Ongoing(_status) => { metaverse_has_referendum_running = true; break; } @@ -514,7 +514,7 @@ pub mod pallet { metaverse_id: MetaverseId, ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - let proposal_info = Self::proposals(metaverse_id, proposal).ok_or(Error::::ProposalDoesNotExist)?; + let _proposal_info = Self::proposals(metaverse_id, proposal).ok_or(Error::::ProposalDoesNotExist)?; if let Some((depositors, deposit)) = >::take(proposal) { >::remove(metaverse_id, proposal); Self::update_proposals_per_metaverse_number(metaverse_id, false); // slash depositors @@ -670,7 +670,7 @@ pub mod pallet { ReferendumInfoOf::::insert(&metaverse, &referendum, ReferendumInfo::Ongoing(status)); Self::deposit_event(Event::VoteRemoved(from, referendum)); } - Some(ReferendumInfo::Finished { end, passed, title }) => { + Some(ReferendumInfo::Finished { end, passed, title: _ }) => { let prior = &mut voting_record.prior; if let Some((lock_periods, balance)) = vote.locked_if(passed) { let mut lock_value: T::BlockNumber = @@ -893,7 +893,7 @@ impl Pallet { } /// Table the waiting public proposal with the highest backing for a vote. - fn launch_public(now: T::BlockNumber, metaverse_id: MetaverseId) -> DispatchResult { + fn launch_public(_now: T::BlockNumber, metaverse_id: MetaverseId) -> DispatchResult { let launch_block = Self::get_proposal_launch_block(metaverse_id)?; if let Some((_, proposal)) = Proposals::::iter_prefix(metaverse_id).enumerate().max_by_key( // defensive only: All current public proposals have an amount locked @@ -1059,7 +1059,7 @@ impl Pallet { } else { let preimage = >::take(&metaverse_id, &referendum_status.proposal_hash); if let Some(PreimageStatus::Available { - data, + data: _, provider, deposit, .. @@ -1075,7 +1075,7 @@ impl Pallet { /// Internal enacting of successfully passed proposal fn do_enact_proposal( - proposal_id: ProposalId, + _proposal_id: ProposalId, metaverse_id: MetaverseId, referendum_id: ReferendumId, proposal_hash: T::Hash, diff --git a/pallets/governance/src/mock.rs b/pallets/governance/src/mock.rs index 85d0294b0..6e9f212f8 100644 --- a/pallets/governance/src/mock.rs +++ b/pallets/governance/src/mock.rs @@ -136,7 +136,7 @@ impl pallet_scheduler::Config for Runtime { pub struct MetaverseInfo {} impl MetaverseTrait for MetaverseInfo { - fn create_metaverse(who: &AccountId, metadata: MetaverseMetadata) -> MetaverseId { + fn create_metaverse(_who: &AccountId, _metadata: MetaverseMetadata) -> MetaverseId { 1u64 } @@ -160,19 +160,19 @@ impl MetaverseTrait for MetaverseInfo { Ok(()) } - fn get_metaverse_land_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_land_class(_metaverse_id: MetaverseId) -> Result { Ok(15u32) } - fn get_metaverse_estate_class(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_estate_class(_metaverse_id: MetaverseId) -> Result { Ok(16u32) } - fn get_metaverse_marketplace_listing_fee(metaverse_id: MetaverseId) -> Result { + fn get_metaverse_marketplace_listing_fee(_metaverse_id: MetaverseId) -> Result { Ok(Perbill::from_percent(1u32)) } - fn get_metaverse_treasury(metaverse_id: MetaverseId) -> AccountId { + fn get_metaverse_treasury(_metaverse_id: MetaverseId) -> AccountId { GENERAL_METAVERSE_FUND } @@ -181,7 +181,7 @@ impl MetaverseTrait for MetaverseInfo { } fn check_if_metaverse_estate( - metaverse_id: primitives::MetaverseId, + _metaverse_id: primitives::MetaverseId, class_id: &ClassId, ) -> Result { if class_id == &15u32 || class_id == &16u32 { @@ -194,7 +194,7 @@ impl MetaverseTrait for MetaverseInfo { Ok(true) } - fn is_metaverse_owner(who: &AccountId) -> bool { + fn is_metaverse_owner(_who: &AccountId) -> bool { true } } @@ -213,7 +213,7 @@ impl MetaverseLandTrait for MetaverseLandInfo { _ => false, } } - fn check_landunit(metaverse_id: MetaverseId, coordinate: (i32, i32)) -> Result { + fn check_landunit(_metaverse_id: MetaverseId, _coordinate: (i32, i32)) -> Result { Ok(false) } } @@ -258,7 +258,7 @@ impl NFTTrait for MockNFTHandler { Ok(false) } - fn is_stackable(asset_id: (Self::ClassId, Self::TokenId)) -> Result { + fn is_stackable(_asset_id: (Self::ClassId, Self::TokenId)) -> Result { Ok(false) } @@ -271,19 +271,19 @@ impl NFTTrait for MockNFTHandler { } Ok(false) } - fn get_nft_group_collection(nft_collection: &Self::ClassId) -> Result { + fn get_nft_group_collection(_nft_collection: &Self::ClassId) -> Result { Ok(ASSET_COLLECTION_ID) } fn create_token_class( sender: &AccountId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, collection_id: GroupCollectionId, - token_type: TokenType, - collection_type: CollectionType, - royalty_fee: Perbill, - mint_limit: Option, + _token_type: TokenType, + _collection_type: CollectionType, + _royalty_fee: Perbill, + _mint_limit: Option, ) -> Result { match *sender { ALICE => { @@ -304,8 +304,8 @@ impl NFTTrait for MockNFTHandler { fn mint_token( sender: &AccountId, class_id: ClassId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -329,26 +329,26 @@ impl NFTTrait for MockNFTHandler { } } - fn transfer_nft(from: &AccountId, to: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn transfer_nft(_from: &AccountId, _to: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn check_item_on_listing(class_id: Self::ClassId, token_id: Self::TokenId) -> Result { + fn check_item_on_listing(_class_id: Self::ClassId, _token_id: Self::TokenId) -> Result { Ok(true) } - fn burn_nft(account: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn burn_nft(_account: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn is_transferable(nft: &(Self::ClassId, Self::TokenId)) -> Result { + fn is_transferable(_nft: &(Self::ClassId, Self::TokenId)) -> Result { Ok(true) } - fn get_class_fund(class_id: &Self::ClassId) -> AccountId { + fn get_class_fund(_class_id: &Self::ClassId) -> AccountId { CLASS_FUND_ID } - fn get_nft_detail(asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { + fn get_nft_detail(_asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { let new_data = NftClassData { deposit: 0, attributes: test_attributes(1), @@ -362,11 +362,11 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn set_lock_collection(class_id: Self::ClassId, is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_collection(_class_id: Self::ClassId, _is_locked: bool) -> sp_runtime::DispatchResult { todo!() } - fn set_lock_nft(token_id: (Self::ClassId, Self::TokenId), is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_nft(_token_id: (Self::ClassId, Self::TokenId), _is_locked: bool) -> sp_runtime::DispatchResult { todo!() } @@ -384,20 +384,20 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn get_total_issuance(class_id: Self::ClassId) -> Result { + fn get_total_issuance(_class_id: Self::ClassId) -> Result { Ok(10u64) } - fn get_asset_owner(asset_id: &(Self::ClassId, Self::TokenId)) -> Result { + fn get_asset_owner(_asset_id: &(Self::ClassId, Self::TokenId)) -> Result { Ok(ALICE) } fn mint_token_with_id( sender: &AccountId, class_id: Self::ClassId, - token_id: Self::TokenId, - metadata: NftMetadata, - attributes: Attributes, + _token_id: Self::TokenId, + _metadata: NftMetadata, + _attributes: Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -420,31 +420,31 @@ impl NFTTrait for MockNFTHandler { } } } - fn get_free_stackable_nft_balance(who: &AccountId, asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { + fn get_free_stackable_nft_balance(_who: &AccountId, _asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { 1000 } fn reserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> DispatchResult { Ok(()) } fn unreserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } fn transfer_stackable_nft( - sender: &AccountId, - to: &AccountId, - nft: &(Self::ClassId, Self::TokenId), - amount: Balance, + _sender: &AccountId, + _to: &AccountId, + _nft: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } diff --git a/pallets/governance/src/tests.rs b/pallets/governance/src/tests.rs index 6433a6905..886638493 100644 --- a/pallets/governance/src/tests.rs +++ b/pallets/governance/src/tests.rs @@ -382,7 +382,7 @@ fn vote_work() { #[test] fn vote_when_not_country_member_does_not_work() { ExtBuilder::default().build().execute_with(|| { - let origin = RuntimeOrigin::signed(BOB); + let _origin = RuntimeOrigin::signed(BOB); let hash = set_freeze_metaverse_proposal_hash(1); add_freeze_metaverse_preimage_alice(hash); assert_ok!(GovernanceModule::propose( diff --git a/pallets/metaverse/src/lib.rs b/pallets/metaverse/src/lib.rs index 68bca1bce..a0621c741 100644 --- a/pallets/metaverse/src/lib.rs +++ b/pallets/metaverse/src/lib.rs @@ -80,7 +80,7 @@ pub struct MetaverseStakingPoints { #[frame_support::pallet] pub mod pallet { use orml_traits::MultiCurrencyExtended; - use sp_runtime::traits::{CheckedAdd, Saturating}; + use sp_runtime::ArithmeticError; use primitives::staking::RoundInfo; @@ -545,7 +545,7 @@ impl Pallet { } /// Minting of a land class for the metaverse - fn mint_metaverse_land_class(sender: &T::AccountId, metaverse_id: MetaverseId) -> Result { + fn mint_metaverse_land_class(_sender: &T::AccountId, metaverse_id: MetaverseId) -> Result { // Pre-mint class for lands let mut land_class_attributes = Attributes::new(); land_class_attributes.insert("MetaverseId:".as_bytes().to_vec(), "MetaverseId:".as_bytes().to_vec()); @@ -565,7 +565,10 @@ impl Pallet { } /// Minting of an estate class for the metaverse - fn mint_metaverse_estate_class(sender: &T::AccountId, metaverse_id: MetaverseId) -> Result { + fn mint_metaverse_estate_class( + _sender: &T::AccountId, + metaverse_id: MetaverseId, + ) -> Result { // Pre-mint class for estates let mut estate_class_attributes = Attributes::new(); estate_class_attributes.insert("MetaverseId:".as_bytes().to_vec(), metaverse_id.to_be_bytes().to_vec()); @@ -611,7 +614,7 @@ impl Pallet { let default_land_class_id = TryInto::::try_into(0u32).unwrap_or_default(); let default_estate_class_id = TryInto::::try_into(1u32).unwrap_or_default(); - Metaverses::::translate(|k, metaverse_info_v1: MetaverseInfoV1| { + Metaverses::::translate(|_k, metaverse_info_v1: MetaverseInfoV1| { upgraded_metaverse_items += 1; let v2: MetaverseInfo = MetaverseInfo { diff --git a/pallets/metaverse/src/mock.rs b/pallets/metaverse/src/mock.rs index 5b12d9bf5..a238459de 100644 --- a/pallets/metaverse/src/mock.rs +++ b/pallets/metaverse/src/mock.rs @@ -7,7 +7,6 @@ use orml_traits::parameter_type_with_key; use sp_core::H256; use sp_runtime::{testing::Header, traits::IdentityLookup, Perbill}; -use primitives::staking::RoundInfo; use primitives::{Amount, ClassId, GroupCollectionId, TokenId}; use crate as metaverse; @@ -128,22 +127,22 @@ impl NFTTrait for MockNFTHandler { } Ok(false) } - fn get_nft_group_collection(nft_collection: &Self::ClassId) -> Result { + fn get_nft_group_collection(_nft_collection: &Self::ClassId) -> Result { Ok(ASSET_COLLECTION_ID) } - fn is_stackable(asset_id: (Self::ClassId, Self::TokenId)) -> Result { + fn is_stackable(_asset_id: (Self::ClassId, Self::TokenId)) -> Result { Ok(false) } fn create_token_class( sender: &AccountId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, collection_id: GroupCollectionId, - token_type: TokenType, - collection_type: CollectionType, - royalty_fee: Perbill, - mint_limit: Option, + _token_type: TokenType, + _collection_type: CollectionType, + _royalty_fee: Perbill, + _mint_limit: Option, ) -> Result { match *sender { ALICE => Ok(100), @@ -164,8 +163,8 @@ impl NFTTrait for MockNFTHandler { fn mint_token( sender: &AccountId, class_id: ClassId, - metadata: NftMetadata, - attributes: Attributes, + _metadata: NftMetadata, + _attributes: Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -189,26 +188,26 @@ impl NFTTrait for MockNFTHandler { } } - fn transfer_nft(from: &AccountId, to: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn transfer_nft(_from: &AccountId, _to: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn check_item_on_listing(class_id: Self::ClassId, token_id: Self::TokenId) -> Result { + fn check_item_on_listing(_class_id: Self::ClassId, _token_id: Self::TokenId) -> Result { Ok(true) } - fn burn_nft(account: &AccountId, nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { + fn burn_nft(_account: &AccountId, _nft: &(Self::ClassId, Self::TokenId)) -> DispatchResult { Ok(()) } - fn is_transferable(nft: &(Self::ClassId, Self::TokenId)) -> Result { + fn is_transferable(_nft: &(Self::ClassId, Self::TokenId)) -> Result { Ok(true) } - fn get_class_fund(class_id: &Self::ClassId) -> AccountId { + fn get_class_fund(_class_id: &Self::ClassId) -> AccountId { CLASS_FUND_ID } - fn get_nft_detail(asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { + fn get_nft_detail(_asset_id: (Self::ClassId, Self::TokenId)) -> Result, DispatchError> { let new_data = NftClassData { deposit: 0, attributes: test_attributes(1), @@ -222,11 +221,11 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn set_lock_collection(class_id: Self::ClassId, is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_collection(_class_id: Self::ClassId, _is_locked: bool) -> sp_runtime::DispatchResult { todo!() } - fn set_lock_nft(token_id: (Self::ClassId, Self::TokenId), is_locked: bool) -> sp_runtime::DispatchResult { + fn set_lock_nft(_token_id: (Self::ClassId, Self::TokenId), _is_locked: bool) -> sp_runtime::DispatchResult { todo!() } @@ -244,20 +243,20 @@ impl NFTTrait for MockNFTHandler { Ok(new_data) } - fn get_total_issuance(class_id: Self::ClassId) -> Result { + fn get_total_issuance(_class_id: Self::ClassId) -> Result { Ok(10u64) } - fn get_asset_owner(asset_id: &(Self::ClassId, Self::TokenId)) -> Result { + fn get_asset_owner(_asset_id: &(Self::ClassId, Self::TokenId)) -> Result { Ok(ALICE) } fn mint_token_with_id( sender: &AccountId, class_id: Self::ClassId, - token_id: Self::TokenId, - metadata: NftMetadata, - attributes: Attributes, + _token_id: Self::TokenId, + _metadata: NftMetadata, + _attributes: Attributes, ) -> Result { match *sender { ALICE => Ok(1), @@ -281,31 +280,31 @@ impl NFTTrait for MockNFTHandler { } } - fn get_free_stackable_nft_balance(who: &AccountId, asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { + fn get_free_stackable_nft_balance(_who: &AccountId, _asset_id: &(Self::ClassId, Self::TokenId)) -> Balance { 1000 } fn reserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> DispatchResult { Ok(()) } fn unreserve_stackable_nft_balance( - who: &AccountId, - asset_id: &(Self::ClassId, Self::TokenId), - amount: Balance, + _who: &AccountId, + _asset_id: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } fn transfer_stackable_nft( - sender: &AccountId, - to: &AccountId, - nft: &(Self::ClassId, Self::TokenId), - amount: Balance, + _sender: &AccountId, + _to: &AccountId, + _nft: &(Self::ClassId, Self::TokenId), + _amount: Balance, ) -> sp_runtime::DispatchResult { Ok(()) } diff --git a/pallets/metaverse/src/tests.rs b/pallets/metaverse/src/tests.rs index 39ba4822c..f75e1203d 100644 --- a/pallets/metaverse/src/tests.rs +++ b/pallets/metaverse/src/tests.rs @@ -17,12 +17,11 @@ #![cfg(test)] -use frame_support::{assert_err, assert_noop, assert_ok}; +use frame_support::{assert_noop, assert_ok}; use sp_runtime::traits::BadOrigin; use sp_runtime::Perbill; use mock::{RuntimeEvent, *}; -use primitives::staking::RoundInfo; #[cfg(test)] use super::*; diff --git a/pallets/mining/src/lib.rs b/pallets/mining/src/lib.rs index 1d1b34f55..bdb6ce7f4 100644 --- a/pallets/mining/src/lib.rs +++ b/pallets/mining/src/lib.rs @@ -19,34 +19,28 @@ #![cfg_attr(not(feature = "std"), no_std)] use codec::{Decode, Encode}; -use frame_support::traits::{Currency, Get, WithdrawReasons}; +use frame_support::traits::{Currency, Get}; use frame_support::PalletId; use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo}, ensure, pallet_prelude::*, traits::ExistenceRequirement, - transactional, Parameter, }; use frame_system::pallet_prelude::*; use frame_system::{self as system, ensure_signed}; -use orml_traits::{ - arithmetic::{Signed, SimpleArithmetic}, - BalanceStatus, BasicCurrency, BasicCurrencyExtended, BasicLockableCurrency, BasicReservableCurrency, - LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency, MultiReservableCurrency, -}; +use orml_traits::{BasicCurrency, LockIdentifier, MultiCurrency, MultiCurrencyExtended}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{AccountIdConversion, AtLeast32Bit, One, StaticLookup, Zero}, - DispatchError, Perbill, + traits::{AccountIdConversion, Zero}, + DispatchError, }; use sp_std::vec::Vec; -use auction_manager::SwapManager; use core_primitives::*; pub use pallet::*; use primitives::staking::RoundInfo; -use primitives::{Balance, CurrencyId, FungibleTokenId, MetaverseId}; +use primitives::{Balance, FungibleTokenId}; pub use weights::WeightInfo; #[cfg(feature = "runtime-benchmarks")] @@ -80,16 +74,15 @@ pub mod weights; #[frame_support::pallet] pub mod pallet { - use frame_support::sp_runtime::traits::Saturating; - use frame_support::sp_runtime::{FixedPointNumber, SaturatedConversion}; - use frame_support::traits::OnUnbalanced; - use pallet_balances::NegativeImbalance; + + use frame_support::sp_runtime::SaturatedConversion; + use sp_runtime::Perbill; use sp_std::convert::TryInto; use primitives::estate::Estate; use primitives::staking::{MetaverseStakingTrait, RoundInfo}; - use primitives::{FungibleTokenId, RoundIndex, TokenId, VestingSchedule}; + use primitives::{FungibleTokenId, RoundIndex, VestingSchedule}; use crate::mining::round_issuance_range; diff --git a/pallets/mining/src/mining.rs b/pallets/mining/src/mining.rs index 750e698bf..a35a4a0ff 100644 --- a/pallets/mining/src/mining.rs +++ b/pallets/mining/src/mining.rs @@ -15,17 +15,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use codec::{Decode, Encode}; -use orml_traits::arithmetic::{CheckedDiv, CheckedMul}; use orml_traits::MultiCurrency; -use scale_info::TypeInfo; -#[cfg(feature = "std")] -use serde::{Deserialize, Serialize}; -use sp_runtime::traits::{Saturating, Zero}; -use sp_runtime::{ArithmeticError, Perbill, RuntimeDebug}; + +use sp_runtime::Perbill; use core_primitives::{MiningRange, MiningResourceRateInfo}; -use primitives::{estate::Estate, Balance, FungibleTokenId}; +use primitives::{Balance, FungibleTokenId}; // Helper methods to compute the issuance rate for undeployed land. use crate::pallet::{Config, Pallet}; diff --git a/pallets/mining/src/mock.rs b/pallets/mining/src/mock.rs index cac0f11ba..007245e98 100644 --- a/pallets/mining/src/mock.rs +++ b/pallets/mining/src/mock.rs @@ -1,8 +1,8 @@ -use frame_support::pallet_prelude::{GenesisBuild, Hooks, MaybeSerializeDeserialize}; -use frame_support::sp_runtime::traits::AtLeast32Bit; +use frame_support::pallet_prelude::GenesisBuild; + use frame_support::traits::Nothing; -use frame_support::{construct_runtime, ord_parameter_types, parameter_types, traits::EnsureOrigin, weights::Weight}; -use frame_system::{EnsureRoot, EnsureSignedBy}; +use frame_support::{construct_runtime, ord_parameter_types, parameter_types}; +use frame_system::EnsureSignedBy; use orml_traits::parameter_type_with_key; use sp_core::H256; use sp_runtime::{ @@ -13,11 +13,11 @@ use sp_runtime::{ use primitives::estate::Estate; use primitives::staking::MetaverseStakingTrait; -use primitives::FungibleTokenId::FungibleToken; + use primitives::{Amount, CurrencyId, EstateId, FungibleTokenId, RoundIndex, UndeployedLandBlockId}; use crate as mining; -use crate::{Config, Module}; +use crate::Config; use super::*; @@ -137,22 +137,22 @@ parameter_types! { pub struct EstateHandler; impl Estate for EstateHandler { - fn transfer_estate(estate_id: EstateId, from: &u128, to: &u128) -> Result { + fn transfer_estate(estate_id: EstateId, _from: &u128, _to: &u128) -> Result { Ok(estate_id) } fn transfer_landunit( coordinate: (i32, i32), - from: &u128, - to: &(u128, primitives::MetaverseId), + _from: &u128, + _to: &(u128, primitives::MetaverseId), ) -> Result<(i32, i32), DispatchError> { Ok(coordinate) } fn transfer_undeployed_land_block( - who: &AccountId, - to: &AccountId, - undeployed_land_block_id: UndeployedLandBlockId, + _who: &AccountId, + _to: &AccountId, + _undeployed_land_block_id: UndeployedLandBlockId, ) -> Result { Ok(2) } @@ -161,18 +161,18 @@ impl Estate for EstateHandler { Ok(true) } - fn check_landunit(_metaverse_id: primitives::MetaverseId, coordinate: (i32, i32)) -> Result { + fn check_landunit(_metaverse_id: primitives::MetaverseId, _coordinate: (i32, i32)) -> Result { Ok(true) } fn check_undeployed_land_block( - owner: &AccountId, - undeployed_land_block_id: UndeployedLandBlockId, + _owner: &AccountId, + _undeployed_land_block_id: UndeployedLandBlockId, ) -> Result { Ok(true) } - fn get_total_land_units(estate_id: Option) -> u64 { + fn get_total_land_units(_estate_id: Option) -> u64 { 10 } @@ -180,15 +180,15 @@ impl Estate for EstateHandler { 10 } - fn check_estate_ownership(owner: AccountId, estate_id: EstateId) -> Result { + fn check_estate_ownership(_owner: AccountId, _estate_id: EstateId) -> Result { Ok(false) } - fn is_estate_leasor(leasor: AccountId, estate_id: EstateId) -> Result { + fn is_estate_leasor(_leasor: AccountId, _estate_id: EstateId) -> Result { Ok(false) } - fn is_estate_leased(estate_id: EstateId) -> Result { + fn is_estate_leased(_estate_id: EstateId) -> Result { Ok(false) } } @@ -196,7 +196,7 @@ impl Estate for EstateHandler { pub struct MetaverseStakingHandler; impl MetaverseStakingTrait for MetaverseStakingHandler { - fn update_staking_reward(round: RoundIndex, total_reward: u128) -> sp_runtime::DispatchResult { + fn update_staking_reward(_round: RoundIndex, _total_reward: u128) -> sp_runtime::DispatchResult { Ok(()) } } diff --git a/pallets/mining/src/tests.rs b/pallets/mining/src/tests.rs index 52586b8ef..3b6198186 100644 --- a/pallets/mining/src/tests.rs +++ b/pallets/mining/src/tests.rs @@ -1,10 +1,8 @@ use frame_support::{assert_noop, assert_ok}; -use sp_core::blake2_256; -use sp_runtime::traits::BadOrigin; -use sp_runtime::{AccountId32, Perbill}; -use sp_std::vec::Vec; -use mock::{RuntimeEvent, *}; +use sp_runtime::Perbill; + +use mock::*; use primitives::Balance; // Unit testing for metaverse currency, metaverse treasury @@ -55,7 +53,7 @@ fn burn_mining_resource_should_work() { assert_eq!(get_mining_balance(), 1000); - let event = mock::RuntimeEvent::MiningModule(crate::Event::MiningResourceMintedTo(BOB, 1000)); + let _event = mock::RuntimeEvent::MiningModule(crate::Event::MiningResourceMintedTo(BOB, 1000)); assert_ok!(MiningModule::burn(origin, BOB, 300)); assert_eq!(get_mining_balance(), 700); diff --git a/pallets/nft/src/lib.rs b/pallets/nft/src/lib.rs index a2709e35e..fc1b14d09 100644 --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -26,8 +26,6 @@ #![allow(clippy::upper_case_acronyms)] #![cfg_attr(not(feature = "std"), no_std)] -use core::result; - use codec::Encode; use frame_support::traits::Len; use frame_support::{ @@ -39,7 +37,6 @@ use frame_support::{ }; use frame_system::pallet_prelude::*; use orml_nft::{ClassInfo, ClassInfoOf, Classes, Pallet as NftModule, TokenInfo, TokenInfoOf, TokenMetadataOf, Tokens}; -use scale_info::TypeInfo; use sp_runtime::traits::Saturating; use sp_runtime::Perbill; use sp_runtime::{ @@ -52,8 +49,8 @@ use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use auction_manager::{Auction, CheckAuctionItemHandler}; pub use pallet::*; pub use primitive_traits::{Attributes, NFTTrait, NftClassData, NftGroupCollectionData, NftMetadata, TokenType}; -use primitive_traits::{CollectionType, NftAssetData, NftAssetDataV1, NftClassDataV1, PreSignedMint}; -use primitives::{AssetId, BlockNumber, ClassId, GroupCollectionId, Hash, ItemId, TokenId}; +use primitive_traits::{CollectionType, NftAssetData, NftClassDataV1, PreSignedMint}; +use primitives::{AssetId, ClassId, GroupCollectionId, ItemId, TokenId}; pub use weights::WeightInfo; #[cfg(feature = "runtime-benchmarks")] @@ -76,7 +73,6 @@ pub enum StorageVersion { #[frame_support::pallet] pub mod pallet { - use frame_system::offchain::Signer; use orml_traits::{MultiCurrency, MultiCurrencyExtended}; use sp_runtime::traits::{CheckedSub, IdentifyAccount, Verify}; use sp_runtime::ArithmeticError; @@ -160,6 +156,7 @@ pub mod pallet { ::ClassId, ::TokenId, ::AccountId, + BlockNumberFor, BalanceOf, >; @@ -407,6 +404,8 @@ pub mod pallet { InvalidCurrentTotalIssuance, /// Wrong signature WrongSignature, + /// Signature expired + SignatureExpired, } #[pallet::call] @@ -474,7 +473,7 @@ pub mod pallet { mint_limit: Option, ) -> DispatchResultWithPostInfo { let sender = ensure_signed(origin)?; - let class_id = Self::do_create_class( + let _class_id = Self::do_create_class( &sender, metadata, attributes, @@ -556,7 +555,7 @@ pub mod pallet { let result = NftModule::::mint_stackable_nft(&sender, class_id, metadata, new_stackable_nft_data, amount); match result { - Ok((token_id, balance)) => { + Ok((token_id, _balance)) => { Self::deposit_event(Event::::NewStackableNftMinted(sender, class_id, token_id, amount)); Ok(().into()) } @@ -1178,6 +1177,7 @@ impl Pallet { attributes, metadata, only_account, + expired, mint_price, } = mint_data; @@ -1195,6 +1195,9 @@ impl Pallet { ensure!(account == mint_to, Error::::NoPermission); } + let now = frame_system::Pallet::::block_number(); + ensure!(expired >= now, Error::::SignatureExpired); + // Get class info of the collection let class_info = NftModule::::classes(class_id).ok_or(Error::::ClassIdNotFound)?; @@ -1370,8 +1373,8 @@ impl Pallet { log::info!("Start upgrading nft class data v2"); log::info!("Start upgrading nft token data v2"); let mut num_nft_classes = 0; - let mut num_nft_tokens = 0; - let mut asset_by_owner_updates = 0; + let _num_nft_tokens = 0; + let _asset_by_owner_updates = 0; Classes::::translate( |k, diff --git a/pallets/nft/src/mock.rs b/pallets/nft/src/mock.rs index 6fc8ecaf0..ab7304ee9 100644 --- a/pallets/nft/src/mock.rs +++ b/pallets/nft/src/mock.rs @@ -99,7 +99,7 @@ impl Auction for MockAuctionManager { None } - fn auction_item(id: AuctionId) -> Option> { + fn auction_item(_id: AuctionId) -> Option> { None } @@ -107,7 +107,7 @@ impl Auction for MockAuctionManager { Ok(()) } - fn update_auction_item(id: AuctionId, item_id: ItemId) -> DispatchResult { + fn update_auction_item(_id: AuctionId, _item_id: ItemId) -> DispatchResult { Ok(()) } @@ -136,11 +136,11 @@ impl Auction for MockAuctionManager { fn remove_auction(_id: u64, _item_id: ItemId) {} - fn auction_bid_handler(from: AccountId, id: AuctionId, value: Self::Balance) -> DispatchResult { + fn auction_bid_handler(_from: AccountId, _id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } - fn buy_now_handler(from: AccountId, auction_id: AuctionId, value: Self::Balance) -> DispatchResult { + fn buy_now_handler(_from: AccountId, _auction_id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } diff --git a/pallets/nft/src/tests.rs b/pallets/nft/src/tests.rs index a54463fbe..d2cd87bda 100644 --- a/pallets/nft/src/tests.rs +++ b/pallets/nft/src/tests.rs @@ -863,7 +863,7 @@ fn setting_hard_limit_should_work() { fn force_updating_total_issuance_should_work() { ExtBuilder::default().build().execute_with(|| { let origin = RuntimeOrigin::signed(account(1)); - let class_deposit = ::ClassMintingFee::get(); + let _class_deposit = ::ClassMintingFee::get(); assert_ok!(Nft::create_group(RuntimeOrigin::root(), vec![1], vec![1],)); assert_ok!(Nft::create_class( origin.clone(), @@ -894,7 +894,7 @@ fn force_updating_total_issuance_should_work() { fn force_updating_total_issuance_should_fail() { ExtBuilder::default().build().execute_with(|| { let origin = RuntimeOrigin::signed(account(1)); - let class_deposit = ::ClassMintingFee::get(); + let _class_deposit = ::ClassMintingFee::get(); assert_ok!(Nft::create_group(RuntimeOrigin::root(), vec![1], vec![1],)); assert_ok!(Nft::create_class( origin.clone(), @@ -922,7 +922,7 @@ fn force_updating_total_issuance_should_fail() { fn force_updating_new_royal_fee_should_work() { ExtBuilder::default().build().execute_with(|| { let origin = RuntimeOrigin::signed(account(1)); - let class_deposit = ::ClassMintingFee::get(); + let _class_deposit = ::ClassMintingFee::get(); assert_ok!(Nft::create_group(RuntimeOrigin::root(), vec![1], vec![1],)); assert_ok!(Nft::create_class( origin.clone(), @@ -956,7 +956,7 @@ fn force_updating_new_royal_fee_should_work() { fn force_updating_new_royal_fee_should_fail() { ExtBuilder::default().build().execute_with(|| { let origin = RuntimeOrigin::signed(account(2)); - let class_deposit = ::ClassMintingFee::get(); + let _class_deposit = ::ClassMintingFee::get(); assert_ok!(Nft::create_group(RuntimeOrigin::root(), vec![1], vec![1],)); assert_ok!(Nft::create_class( origin.clone(), diff --git a/pallets/reward/src/lib.rs b/pallets/reward/src/lib.rs index 28681399c..ac4a96a4c 100644 --- a/pallets/reward/src/lib.rs +++ b/pallets/reward/src/lib.rs @@ -17,9 +17,9 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode, HasCompact}; +use codec::Encode; use frame_support::storage::{child, ChildTriePrefixIterator}; -use frame_support::traits::{LockIdentifier, WithdrawReasons}; + use frame_support::{ ensure, log, pallet_prelude::*, @@ -27,23 +27,21 @@ use frame_support::{ transactional, PalletId, }; use frame_system::{ensure_signed, pallet_prelude::*}; -use orml_traits::{DataFeeder, DataProvider, MultiCurrency, MultiReservableCurrency}; +use orml_traits::{DataProvider, MultiCurrency, MultiReservableCurrency}; use sp_core::Encode as SPEncode; use sp_io::hashing::keccak_256; -use sp_runtime::traits::{BlockNumberProvider, CheckedAdd, CheckedMul, Hash as Hasher, Saturating}; +use sp_runtime::traits::{Hash as Hasher, Saturating}; use sp_runtime::{ - traits::{AccountIdConversion, One, Zero}, - ArithmeticError, DispatchError, Perbill, SaturatedConversion, + traits::{AccountIdConversion, Zero}, + DispatchError, Perbill, SaturatedConversion, }; -use sp_std::{collections::btree_map::BTreeMap, prelude::*, vec::Vec}; +use sp_std::{prelude::*, vec::Vec}; use core_primitives::NFTTrait; use core_primitives::*; pub use pallet::*; -use primitives::{ - estate::Estate, CampaignId, CampaignInfo, CampaignInfoV1, CampaignInfoV2, EstateId, Hash, RewardType, TrieIndex, -}; -use primitives::{Balance, ClassId, FungibleTokenId, NftId}; +use primitives::{Balance, ClassId, FungibleTokenId}; +use primitives::{CampaignId, CampaignInfo, CampaignInfoV2, Hash, RewardType, TrieIndex}; pub use weights::WeightInfo; //#[cfg(feature = "runtime-benchmarks")] @@ -59,13 +57,12 @@ pub mod weights; #[frame_support::pallet] pub mod pallet { - use frame_support::traits::tokens::currency; + use frame_support::traits::ExistenceRequirement::AllowDeath; - use orml_traits::{rewards, MultiCurrencyExtended}; - use sp_runtime::traits::{CheckedAdd, CheckedSub, Saturating}; + + use sp_runtime::traits::{CheckedAdd, Saturating}; use sp_runtime::ArithmeticError; - use primitives::staking::RoundInfo; use primitives::{CampaignId, CampaignInfo, ClassId, NftId}; use super::*; @@ -379,7 +376,7 @@ pub mod pallet { /// - `properties`: information relevant for the campaign. /// /// Emits `NewRewardCampaignCreated` if successful. - #[pallet::weight(T::WeightInfo::create_campaign().saturating_mul((1u64.saturating_add(reward.len() as u64))))] + #[pallet::weight(T::WeightInfo::create_campaign().saturating_mul(1u64.saturating_add(reward.len() as u64)))] #[transactional] pub fn create_nft_campaign( origin: OriginFor, @@ -518,7 +515,7 @@ pub mod pallet { /// - `leaf_nodes`: list of the merkle tree nodes required for merkle-proof calculation. /// /// Emits `RewardClaimed` if successful. - #[pallet::weight(T::WeightInfo::claim_reward_root().saturating_mul((1u64.saturating_add(leaf_nodes.len() as u64))))] + #[pallet::weight(T::WeightInfo::claim_reward_root().saturating_mul(1u64.saturating_add(leaf_nodes.len() as u64)))] #[transactional] pub fn claim_reward_root( origin: OriginFor, @@ -582,7 +579,7 @@ pub mod pallet { /// - `amount`: the amount of NFTs that the account is going to claim /// /// Emits `RewardClaimed` if successful. - #[pallet::weight(T::WeightInfo::claim_nft_reward().saturating_mul((1u64.saturating_add(*amount))))] + #[pallet::weight(T::WeightInfo::claim_nft_reward().saturating_mul(1u64.saturating_add(*amount)))] #[transactional] pub fn claim_nft_reward(origin: OriginFor, id: CampaignId, amount: u64) -> DispatchResult { let who = ensure_signed(origin)?; @@ -641,7 +638,7 @@ pub mod pallet { /// - `leaf_nodes`: list of the merkle tree nodes required for merkle-proof calculation. /// /// Emits `RewardClaimed` if successful. - #[pallet::weight(T::WeightInfo::claim_nft_reward_root().saturating_mul((1u64.saturating_add(reward_tokens.len() as u64))))] + #[pallet::weight(T::WeightInfo::claim_nft_reward_root().saturating_mul(1u64.saturating_add(reward_tokens.len() as u64)))] #[transactional] pub fn claim_nft_reward_root( origin: OriginFor, @@ -855,7 +852,7 @@ pub mod pallet { let mut new_cap = cap.clone(); let mut rewards_list: Vec<(T::AccountId, Vec<(ClassId, NftId)>)> = Vec::new(); let mut tokens: Vec<(ClassId, TokenId)> = Vec::new(); - let mut total_amount_left: u64 = total_nfts_amount; + let total_amount_left: u64 = total_nfts_amount; for (to, amount) in rewards { let (t, _) = Self::reward_get_nft(campaign.trie_index, &to); ensure!(t.is_empty(), Error::::AccountAlreadyRewarded); @@ -866,7 +863,7 @@ pub mod pallet { ); total_amount_left.saturating_sub(amount); - for l in 0..amount { + for _l in 0..amount { let token = new_cap.pop().ok_or(Error::::RewardExceedCap)?; tokens.push(token); } @@ -945,13 +942,13 @@ pub mod pallet { /// - `merkle_roots_quanity`: the amount of merkle roots that were used for setting rewards. /// /// Emits `RewardCampaignClosed` and/or `RewardCampaignRootClosed` if successful. - #[pallet::weight(T::WeightInfo::close_campaign().saturating_mul((1u64.saturating_add(*merkle_roots_quantity))))] + #[pallet::weight(T::WeightInfo::close_campaign().saturating_mul(1u64.saturating_add(*merkle_roots_quantity)))] #[transactional] pub fn close_campaign(origin: OriginFor, id: CampaignId, merkle_roots_quantity: u64) -> DispatchResult { let who = ensure_signed(origin)?; let now = frame_system::Pallet::::block_number(); - let mut campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; + let campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; ensure!(who == campaign.creator, Error::::NotCampaignCreator); @@ -1012,7 +1009,7 @@ pub mod pallet { let who = ensure_signed(origin)?; let now = frame_system::Pallet::::block_number(); - let mut campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; + let campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; ensure!(who == campaign.creator, Error::::NotCampaignCreator); @@ -1069,7 +1066,7 @@ pub mod pallet { T::AdminOrigin::ensure_origin(origin)?; let now = frame_system::Pallet::::block_number(); - let mut campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; + let campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; ensure!(campaign.end > now, Error::::CampaignEnded); @@ -1100,7 +1097,7 @@ pub mod pallet { T::AdminOrigin::ensure_origin(origin)?; let now = frame_system::Pallet::::block_number(); - let mut campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; + let campaign = Self::campaigns(id).ok_or(Error::::CampaignIsNotFound)?; ensure!(campaign.end > now, Error::::CampaignEnded); @@ -1179,7 +1176,7 @@ pub mod pallet { impl Hooks for Pallet { /// Hook that is called every time a new block is finalized. fn on_finalize(block_number: T::BlockNumber) { - for (id, info) in Campaigns::::iter() + for (id, _info) in Campaigns::::iter() .filter(|(_, campaign_info)| campaign_info.end == block_number) .collect::>() { @@ -1394,7 +1391,7 @@ impl Pallet { let mut upgraded_campaign_items = 0; Campaigns::::translate( - |k, campaign_info_v2: CampaignInfoV2, T::BlockNumber>| { + |_k, campaign_info_v2: CampaignInfoV2, T::BlockNumber>| { upgraded_campaign_items += 1; let v3_reward = RewardType::FungibleTokens(FungibleTokenId::NativeToken(0), campaign_info_v2.reward); diff --git a/pallets/reward/src/mock.rs b/pallets/reward/src/mock.rs index 6c045b21b..2fa488767 100644 --- a/pallets/reward/src/mock.rs +++ b/pallets/reward/src/mock.rs @@ -11,9 +11,8 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, MultiSignature, Perbil use auction_manager::*; use core_primitives::NftAssetData; -use primitives::estate::Estate; -use primitives::staking::MetaverseStakingTrait; -use primitives::{Amount, AuctionId, EstateId, FungibleTokenId, ItemId, UndeployedLandBlockId}; + +use primitives::{Amount, AuctionId, FungibleTokenId, ItemId}; use crate as reward; @@ -170,7 +169,7 @@ impl Auction for MockAuctionManager { None } - fn auction_item(id: AuctionId) -> Option> { + fn auction_item(_id: AuctionId) -> Option> { None } @@ -178,7 +177,7 @@ impl Auction for MockAuctionManager { Ok(()) } - fn update_auction_item(id: AuctionId, item_id: ItemId) -> DispatchResult { + fn update_auction_item(_id: AuctionId, _item_id: ItemId) -> DispatchResult { Ok(()) } @@ -207,11 +206,11 @@ impl Auction for MockAuctionManager { fn remove_auction(_id: u64, _item_id: ItemId) {} - fn auction_bid_handler(from: AccountId, id: AuctionId, value: Self::Balance) -> DispatchResult { + fn auction_bid_handler(_from: AccountId, _id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } - fn buy_now_handler(from: AccountId, auction_id: AuctionId, value: Self::Balance) -> DispatchResult { + fn buy_now_handler(_from: AccountId, _auction_id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } diff --git a/pallets/reward/src/tests.rs b/pallets/reward/src/tests.rs index ea8d3466d..7cf44dbcb 100644 --- a/pallets/reward/src/tests.rs +++ b/pallets/reward/src/tests.rs @@ -17,13 +17,13 @@ #![cfg(test)] -use frame_support::{assert_err, assert_noop, assert_ok, sp_runtime::runtime_logger}; +use frame_support::{assert_noop, assert_ok}; use hex_literal::hex; use sp_std::collections::btree_map::BTreeMap; use sp_std::default::Default; use core_primitives::Attributes; -use mock::{Balance, RuntimeEvent, *}; +use mock::{Balance, *}; use primitives::{CampaignInfo, FungibleTokenId, Hash}; use super::*; @@ -235,7 +235,7 @@ fn create_multicurrency_campaign_works() { #[test] fn create_nft_campaign_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); assert_noop!( @@ -270,7 +270,7 @@ fn create_nft_campaign_fails() { #[test] fn create_campaign_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_noop!( Reward::create_campaign( @@ -718,7 +718,7 @@ fn set_reward_root_fails() { #[test] fn set_nft_reward_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_ok!(Reward::add_set_reward_origin(RuntimeOrigin::signed(ALICE), ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); @@ -814,7 +814,7 @@ fn set_nft_reward_fails() { #[test] fn set_nft_reward_root_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_ok!(Reward::add_set_reward_origin(RuntimeOrigin::signed(ALICE), ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); @@ -1397,7 +1397,7 @@ fn claim_reward_root_fails() { #[test] fn claim_nft_reward_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_ok!(Reward::add_set_reward_origin(RuntimeOrigin::signed(ALICE), ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); @@ -1480,7 +1480,7 @@ fn claim_nft_reward_fails() { #[test] fn claim_nft_reward_root_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_ok!(Reward::add_set_reward_origin(RuntimeOrigin::signed(ALICE), ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); @@ -1816,7 +1816,7 @@ fn close_multicurrency_campaign_works() { #[test] fn close_campaign_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_ok!(Reward::create_campaign( RuntimeOrigin::signed(ALICE), BOB, @@ -1869,7 +1869,7 @@ fn close_campaign_fails() { #[test] fn close_campaign_using_merkle_root_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_ok!(Reward::add_set_reward_origin(RuntimeOrigin::signed(ALICE), ALICE)); assert_ok!(Reward::create_campaign( RuntimeOrigin::signed(ALICE), @@ -1951,7 +1951,7 @@ fn close_campaign_using_merkle_root_fails() { #[test] fn close_nft_campaign_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); @@ -2108,7 +2108,7 @@ fn cancel_multicurrency_campaign_works() { #[test] fn cancel_nft_campaign_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); init_test_nft(RuntimeOrigin::signed(ALICE)); @@ -2159,7 +2159,7 @@ fn cancel_nft_campaign_fails() { #[test] fn cancel_campaign_fails() { ExtBuilder::default().build().execute_with(|| { - let campaign_id = 0; + let _campaign_id = 0; assert_ok!(Reward::create_campaign( RuntimeOrigin::signed(ALICE), BOB, @@ -2288,7 +2288,7 @@ fn js_generated_leafs_match_blockchain_generated_leafs() { } #[test] -fn merkle_proof_based_cmapaing_works_with_js_generated_root() { +fn merkle_proof_based_campaign_works_with_js_generated_root() { ExtBuilder::default().build().execute_with(|| { let campaign_id = 0; assert_ok!(Reward::add_set_reward_origin(RuntimeOrigin::signed(ALICE), ALICE)); diff --git a/pallets/spp/Cargo.toml b/pallets/spp/Cargo.toml new file mode 100644 index 000000000..30082b8de --- /dev/null +++ b/pallets/spp/Cargo.toml @@ -0,0 +1,71 @@ +[package] +authors = ['Metaverse Network '] +description = 'Metaverse Network pallet for land minting logic.' +edition = '2021' +homepage = 'https://metaverse.network' +license = 'Unlicense' +name = 'pallet-spp' +repository = 'https://github.com/bit-country' +version = '2.0.0-rc6' + +[package.metadata.docs.rs] +targets = ['x86_64-unknown-linux-gnu'] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } +serde = { workspace = true, optional = true } +scale-info = { workspace = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +frame-benchmarking = { workspace = true, optional = true } +sp-core = { workspace = true } +sp-runtime = { workspace = true } +sp-version = { workspace = true } +sp-std = { workspace = true } +sp-io = { workspace = true } +substrate-fixed = { workspace = true } +pallet-balances = { workspace = true, optional = true } +orml-traits = { workspace = true } +orml-tokens = { workspace = true } +orml-rewards = { workspace = true } + +# local packages +core-primitives = { path = "../../traits/core-primitives", default-features = false } +primitives = { package = "bit-country-primitives", path = "../../primitives/metaverse", default-features = false } +currencies = { package = "currencies", path = "../currencies", default-features = false } +asset-manager = { package = "asset-manager", path = "../asset-manager", default-features = false } + +[dependencies.auction-manager] +default-features = false +package = 'auction-manager' +path = '../../traits/auction-manager' +version = '2.0.0-rc6' + + + +[features] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] +default = ['std'] +std = [ + 'codec/std', + "serde", + 'scale-info/std', + 'frame-support/std', + 'frame-system/std', + 'sp-runtime/std', + 'sp-core/std', + 'core-primitives/std', + 'primitives/std', + 'sp-io/std', + 'pallet-balances/std', + 'auction-manager/std', + 'frame-benchmarking/std', + 'orml-tokens/std', + "currencies/std", + "asset-manager/std", + "orml-rewards/std" +] \ No newline at end of file diff --git a/pallets/spp/src/lib.rs b/pallets/spp/src/lib.rs new file mode 100644 index 000000000..460888b2d --- /dev/null +++ b/pallets/spp/src/lib.rs @@ -0,0 +1,1341 @@ +// This file is part of Metaverse.Network & Bit.Country. + +// Copyright (C) 2020-2022 Metaverse.Network & Bit.Country . +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_support::pallet_prelude::*; +use frame_support::traits::{ExistenceRequirement, LockIdentifier}; +use frame_support::{ + dispatch::DispatchResult, + ensure, log, + traits::{Currency, Get}, + transactional, PalletId, +}; +use frame_system::ensure_signed; +use frame_system::pallet_prelude::*; +use orml_traits::{MultiCurrency, RewardHandler}; +use sp_runtime::traits::{ + BlockNumberProvider, Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, One, UniqueSaturatedInto, +}; +use sp_runtime::{ + traits::{AccountIdConversion, Convert, Saturating, Zero}, + ArithmeticError, DispatchError, FixedPointNumber, Perbill, Permill, SaturatedConversion, +}; + +use core_primitives::*; +pub use pallet::*; +use primitives::bounded::Rate; +use primitives::{ClassId, EraIndex, FungibleTokenId, PoolId, Ratio, StakingRound, TokenId}; +pub use weights::WeightInfo; + +pub type QueueId = u32; +//#[cfg(feature = "runtime-benchmarks")] +//pub mod benchmarking; + +#[cfg(test)] +mod mock; +mod utils; + +#[cfg(test)] +mod tests; + +pub mod weights; + +const BOOSTING_ID: LockIdentifier = *b"bc/boost"; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::traits::{Currency, LockableCurrency, ReservableCurrency, WithdrawReasons}; + use orml_traits::{MultiCurrency, MultiReservableCurrency}; + use sp_core::U256; + use sp_runtime::traits::{BlockNumberProvider, CheckedAdd, CheckedMul, CheckedSub, One, UniqueSaturatedInto}; + use sp_runtime::Permill; + use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; + + use primitives::bounded::FractionalRate; + use primitives::{PoolId, StakingRound}; + + use crate::utils::{BoostInfo, BoostingRecord, PoolInfo}; + + use super::*; + + #[pallet::pallet] + #[pallet::generate_store(trait Store)] + #[pallet::without_storage_info] + pub struct Pallet(PhantomData); + + #[pallet::config] + pub trait Config: + frame_system::Config + + orml_rewards::Config< + Share = BalanceOf, + Balance = BalanceOf, + PoolId = PoolId, + CurrencyId = FungibleTokenId, + > + { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Currency type + type Currency: Currency + + ReservableCurrency + + LockableCurrency; + /// Multi currencies type that handles different currency type in auction + type MultiCurrency: MultiReservableCurrency< + Self::AccountId, + CurrencyId = FungibleTokenId, + Balance = BalanceOf, + >; + + /// Weight implementation for estate extrinsics + type WeightInfo: WeightInfo; + + /// Minimum staking balance + #[pallet::constant] + type MinimumStake: Get>; + + /// Network fee charged on pool creation + #[pallet::constant] + type NetworkFee: Get>; + + /// Storage deposit free charged when saving data into the blockchain. + /// The fee will be unreserved after the storage is freed. + #[pallet::constant] + type StorageDepositFee: Get>; + + /// Block number provider for the relaychain. + type RelayChainBlockNumber: BlockNumberProvider>; + + #[pallet::constant] + type PoolAccount: Get; + + #[pallet::constant] + type RewardPayoutAccount: Get; + + #[pallet::constant] + type RewardHoldingAccount: Get; + + #[pallet::constant] + type MaximumQueue: Get; + + type CurrencyIdConversion: CurrencyIdManagement; + + /// Origin represented Governance + type GovernanceOrigin: EnsureOrigin<::RuntimeOrigin>; + } + + pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; + + #[pallet::storage] + #[pallet::getter(fn next_class_id)] + pub type NextPoolId = StorageValue<_, PoolId, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn fees)] + pub type Fees = StorageValue<_, (FractionalRate, FractionalRate), ValueQuery>; + + /// Keep track of Pool detail + #[pallet::storage] + #[pallet::getter(fn pool)] + pub type Pool = StorageMap<_, Twox64Concat, PoolId, PoolInfo, OptionQuery>; + + /// Pool ledger that keeps track of Pool id and balance of base currency + #[pallet::storage] + #[pallet::getter(fn pool_ledger)] + pub type PoolLedger = StorageMap<_, Twox64Concat, PoolId, BalanceOf, ValueQuery>; + + /// Network ledger that keep track of all staking across all pools + #[pallet::storage] + #[pallet::getter(fn network_ledger)] + pub type NetworkLedger = StorageMap<_, Twox64Concat, FungibleTokenId, BalanceOf, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn minimum_redeem)] + pub type MinimumRedeem = StorageMap<_, Twox64Concat, FungibleTokenId, BalanceOf, ValueQuery>; + + /// Keep track of each staking round, how many items in queue need to be redeem + #[pallet::storage] + #[pallet::getter(fn staking_round_redeem_requests)] + pub type StakingRoundRedeemQueue = StorageDoubleMap< + _, + Blake2_128Concat, + StakingRound, + Blake2_128Concat, + FungibleTokenId, + (BalanceOf, BoundedVec, FungibleTokenId), + OptionQuery, + >; + + /// Keep track of user ledger that how many queue items that needs to be unlocked + #[pallet::storage] + #[pallet::getter(fn user_redeem_requests)] + pub type UserCurrencyRedeemQueue = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Blake2_128Concat, + FungibleTokenId, + (BalanceOf, BoundedVec), + OptionQuery, + >; + + /// Keep track of queue item as well as account that locked amount of currency can be redeemed + #[pallet::storage] + #[pallet::getter(fn currency_redeem_requests)] + pub type CurrencyRedeemQueue = StorageDoubleMap< + _, + Blake2_128Concat, + FungibleTokenId, + Blake2_128Concat, + QueueId, + (T::AccountId, BalanceOf, StakingRound), + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn unlock_duration)] + pub type UnlockDuration = StorageMap<_, Twox64Concat, FungibleTokenId, StakingRound>; + + #[pallet::storage] + #[pallet::getter(fn current_staking_round)] + pub type CurrentStakingRound = StorageMap<_, Twox64Concat, FungibleTokenId, StakingRound>; + + /// The current era of relaychain + /// + /// RelayChainCurrentEra : EraIndex + #[pallet::storage] + #[pallet::getter(fn relay_chain_current_era)] + pub type RelayChainCurrentEra = StorageValue<_, EraIndex, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn last_staking_round)] + pub type LastStakingRound = StorageMap<_, Twox64Concat, FungibleTokenId, StakingRound, ValueQuery>; + + /// The relaychain block number of last staking round + #[pallet::storage] + #[pallet::getter(fn last_era_updated_block)] + pub type LastEraUpdatedBlock = StorageValue<_, BlockNumberFor, ValueQuery>; + + /// The internal of relaychain block number between era. + #[pallet::storage] + #[pallet::getter(fn update_era_frequency)] + pub type UpdateEraFrequency = StorageValue<_, BlockNumberFor, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn queue_next_id)] + pub type QueueNextId = StorageMap<_, Twox64Concat, FungibleTokenId, u32, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn iteration_limit)] + pub type IterationLimit = StorageValue<_, u32, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn boosting_record)] + /// Store boosting records for each account + pub type BoostingOf = + StorageMap<_, Twox64Concat, T::AccountId, BoostingRecord, T::BlockNumber>, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn network_boost_info)] + /// Store boosting records for each pool + pub type NetworkBoostingInfo = StorageMap<_, Twox64Concat, PoolId, BalanceOf, ValueQuery>; + + /// PoolRewardAmountPerEra: double_map Pool, FungibleTokenId => RewardAmountPerEra + #[pallet::storage] + #[pallet::getter(fn incentive_reward_amounts)] + pub type PoolRewardAmountPerEra = + StorageDoubleMap<_, Twox64Concat, PoolId, Twox64Concat, FungibleTokenId, BalanceOf, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn reward_frequency_per_era)] + pub type RewardEraFrequency = StorageValue<_, BalanceOf, ValueQuery>; + + /// The pending rewards amount, actual available rewards amount may be deducted + /// + /// PendingRewards: double_map PoolId, AccountId => BTreeMap + #[pallet::storage] + #[pallet::getter(fn pending_multi_rewards)] + pub type PendingRewards = StorageDoubleMap< + _, + Twox64Concat, + PoolId, + Twox64Concat, + T::AccountId, + BTreeMap>, + ValueQuery, + >; + + /// The estimated staking reward rate per era on relaychain. + /// + /// EstimatedRewardRatePerEra: value: Rate + #[pallet::storage] + pub type EstimatedRewardRatePerEra = StorageValue<_, FractionalRate, ValueQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub (crate) fn deposit_event)] + pub enum Event { + /// New pool created + PoolCreated { + from: T::AccountId, + pool_id: PoolId, + currency_id: FungibleTokenId, + }, + /// Deposited + Deposited { + from: T::AccountId, + pool_id: PoolId, + amount: BalanceOf, + }, + /// Redeemed + Redeemed { + from: T::AccountId, + pool_id: PoolId, + amount: BalanceOf, + }, + /// Redeemed success + RedeemSuccess { + queue_id: QueueId, + currency_id: FungibleTokenId, + to: T::AccountId, + token_amount: BalanceOf, + }, + /// Current era updated + CurrentEraUpdated { new_era_index: EraIndex }, + /// Last era updated + LastEraUpdated { last_era_block: BlockNumberFor }, + /// Update era frequency + UpdateEraFrequency { frequency: BlockNumberFor }, + /// Boosted successful + Boosted { + booster: T::AccountId, + pool_id: PoolId, + boost_info: BoostInfo>, + }, + /// Claim rewards. + ClaimRewards { + who: T::AccountId, + pool: PoolId, + reward_currency_id: FungibleTokenId, + claimed_amount: BalanceOf, + }, + /// Reward rate per era updated. + EstimatedRewardRatePerEraUpdated { reward_rate_per_era: Rate }, + /// Unlock duration updated. + UnlockDurationUpdated { + currency_id: FungibleTokenId, + unlock_duration: StakingRound, + }, + /// Iterator limit updated. + IterationLimitUpdated { new_limit: u32 }, + } + + #[pallet::error] + pub enum Error { + /// No permission + NoPermission, + /// Currency is not supported + CurrencyIsNotSupported, + /// No available next pool id + NoAvailablePoolId, + /// Pool doesn't exists + PoolDoesNotExist, + /// Overflow + Overflow, + /// Below minimum redemption + BelowMinimumRedeem, + /// No current staking round + NoCurrentStakingRound, + /// Unexpected + Unexpected, + /// Too many redeems + TooManyRedeems, + /// Arthimetic Overflow + ArithmeticOverflow, + /// Token type is not supported + NotSupportTokenType, + /// Unlock duration not found + UnlockDurationNotFound, + /// Staking round not found + StakingRoundNotFound, + /// Staking round redeem queue not found + StakingRoundRedeemNotFound, + /// User currency redeem queue not found + UserCurrencyRedeemQueueNotFound, + /// Redeem queue per currency not found + CurrencyRedeemQueueNotFound, + /// The last era updated block is invalid + InvalidLastEraUpdatedBlock, + /// Fail to process redeem requests + FailedToProcessRedemption, + /// Insufficient Fund + InsufficientFund, + /// Error while adding new boost + MaxVotesReached, + /// Reward distribution origin already exists + OriginsAlreadyExist, + /// Origin doesn't exists + OriginDoesNotExists, + /// Invalid rate input + InvalidRate, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(_n: BlockNumberFor) -> Weight { + // let era_number = Self::get_era_index(T::RelayChainBlockNumber::current_block_number()); + let era_number = Self::get_era_index(>::block_number()); + + if !era_number.is_zero() { + let _ = Self::update_current_era(era_number).map_err(|err| err).ok(); + } + + T::WeightInfo::on_initialize() + } + } + + #[pallet::call] + impl Pallet { + #[pallet::weight(T::WeightInfo::mint_land())] + pub fn create_pool( + origin: OriginFor, + currency_id: FungibleTokenId, + max_nft_reward: u32, + commission: Rate, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + // Ensure currency_id supported + ensure!( + currency_id == FungibleTokenId::NativeToken(0) || currency_id == FungibleTokenId::NativeToken(1), + Error::::CurrencyIsNotSupported + ); + + // Collect pool creation fee + Self::collect_pool_creation_fee(&who, currency_id)?; + + // Ensure no pool id is zero + let current_pool_id = NextPoolId::::get(); + if current_pool_id.is_zero() { + NextPoolId::::put(1u32); + } + + // Next pool id + let next_pool_id = NextPoolId::::try_mutate(|id| -> Result { + let current_id = *id; + *id = id.checked_add(1u32).ok_or(Error::::NoAvailablePoolId)?; + Ok(current_id) + })?; + + let new_pool = PoolInfo { + creator: who.clone(), + commission, + currency_id, + max: max_nft_reward, + }; + + // Add tuple class_id, currency_id + Pool::::insert(next_pool_id, new_pool); + + // Emit event for pool creation + Self::deposit_event(Event::PoolCreated { + from: who, + pool_id: next_pool_id, + currency_id, + }); + Ok(().into()) + } + + #[pallet::weight(T::WeightInfo::mint_land())] + pub fn deposit(origin: OriginFor, pool_id: PoolId, amount: BalanceOf) -> DispatchResult { + // Ensure user is signed + let who = ensure_signed(origin)?; + // Check if pool exists + let pool_instance = Pool::::get(pool_id).ok_or(Error::::PoolDoesNotExist)?; + + // Get currencyId from pool detail + let currency_id = pool_instance.currency_id; + + // Get network ledger balance from currency id + let network_ledger_balance = Self::network_ledger(currency_id); + + // Collect deposit fee for protocol + // Assuming there's a function `collect_deposit_fee` that deducts a fee for deposits. + let amount_after_fee = Self::collect_deposit_fee(&who, currency_id, amount)?; + + let r_currency_id = T::CurrencyIdConversion::convert_to_rcurrency(currency_id) + .map_err(|_| Error::::CurrencyIsNotSupported)?; + // Calculate rAmount as receipt of amount locked. The formula based on rAmount = (amount * rAmount + // total issuance)/network ledger balance + let r_amount_total_issuance = T::MultiCurrency::total_issuance(r_currency_id); + let mut r_amount = amount_after_fee; + // This will apply for subsequence deposits - the first deposit r_amount = amount_after_fee + if network_ledger_balance != BalanceOf::::zero() { + r_amount = U256::from(amount_after_fee.saturated_into::()) + .saturating_mul(r_amount_total_issuance.saturated_into::().into()) + .checked_div(network_ledger_balance.saturated_into::().into()) + .ok_or(Error::::ArithmeticOverflow)? + .as_u128() + .saturated_into(); + } + + // Deposit rAmount to user using T::MultiCurrency::deposit + T::MultiCurrency::deposit(r_currency_id, &who, r_amount)?; + + // Update this specific pool ledger to keep track of pool balance + PoolLedger::::mutate(&pool_id, |pool| -> Result<(), Error> { + *pool = pool + .checked_add(&amount_after_fee) + .ok_or(Error::::ArithmeticOverflow)?; + Ok(()) + })?; + + NetworkLedger::::mutate(¤cy_id, |pool| -> Result<(), Error> { + *pool = pool + .checked_add(&amount_after_fee) + .ok_or(Error::::ArithmeticOverflow)?; + Ok(()) + })?; + // Transfer amount to PoolAccount using T::MultiCurrency::transfer + // Assuming `PoolAccount` is an associated type that represents the pool's account ID or a method to + // get it. + T::MultiCurrency::transfer( + currency_id, + &who, + &T::PoolAccount::get().into_account_truncating(), + amount_after_fee, + )?; + + // Emit deposit event + Self::deposit_event(Event::Deposited { + from: who, + pool_id, + amount, + }); + Ok(().into()) + } + + #[pallet::weight(T::WeightInfo::mint_land())] + pub fn redeem( + origin: OriginFor, + pool_id: PoolId, + v_currency_id: FungibleTokenId, + r_amount: BalanceOf, + ) -> DispatchResult { + // Ensure user is signed + let who = ensure_signed(origin)?; + ensure!( + r_amount >= MinimumRedeem::::get(v_currency_id), + Error::::BelowMinimumRedeem + ); + + let currency_id = T::CurrencyIdConversion::convert_to_currency(v_currency_id) + .map_err(|_| Error::::NotSupportTokenType)?; + + // Check if pool exists + let pool_instance = Pool::::get(pool_id).ok_or(Error::::PoolDoesNotExist)?; + + ensure!( + currency_id == pool_instance.currency_id, + Error::::CurrencyIsNotSupported + ); + + // Get network ledger balance from currency id + let network_ledger_balance = Self::network_ledger(currency_id); + + // Collect deposit fee for protocol + let amount_after_fee = Self::collect_redeem_fee(&who, v_currency_id, r_amount)?; + let r_amount = amount_after_fee; + // Calculate rAmount as receipt of amount locked. The formula based on rAmount = (amount * rAmount + // total issuance)/network ledger balance + let r_amount_total_issuance = T::MultiCurrency::total_issuance(v_currency_id); + let currency_amount = U256::from(r_amount.saturated_into::()) + .saturating_mul(network_ledger_balance.saturated_into::().into()) + .checked_div(r_amount_total_issuance.saturated_into::().into()) + .ok_or(Error::::ArithmeticOverflow)? + .as_u128() + .saturated_into(); + + // Check current staking era - only failed when there is no current staking era + // Staking era get checked and updated every blocks + match CurrentStakingRound::::get(currency_id) { + Some(staking_round) => { + // Calculate the staking duration to be locked + let new_staking_round = Self::calculate_next_staking_round( + Self::unlock_duration(currency_id).ok_or(Error::::UnlockDurationNotFound)?, + staking_round, + )?; + // Burn currency + T::MultiCurrency::withdraw(v_currency_id, &who, amount_after_fee)?; + + // Update pool ledger + PoolLedger::::mutate(&pool_id, |pool| -> Result<(), Error> { + *pool = pool + .checked_sub(¤cy_amount) + .ok_or(Error::::ArithmeticOverflow)?; + Ok(()) + })?; + + // Get current queue_id + let next_queue_id = Self::queue_next_id(currency_id); + + // Add request into network currency redeem queue + CurrencyRedeemQueue::::insert( + ¤cy_id, + &next_queue_id, + (&who, currency_amount, &new_staking_round), + ); + + // Handle ledger of user and currency - user,currency: total_amount_unlocked, vec![queue_id] + // Check if you already has any redeem requests + if UserCurrencyRedeemQueue::::get(&who, ¤cy_id).is_some() { + // Add new queue id into the list + UserCurrencyRedeemQueue::::mutate(&who, ¤cy_id, |value| -> Result<(), Error> { + // + if let Some((amount_need_unlocked, existing_queue)) = value { + existing_queue + .try_push(next_queue_id) + .map_err(|_| Error::::TooManyRedeems)?; + + *amount_need_unlocked = amount_need_unlocked + .checked_add(¤cy_amount) + .ok_or(Error::::ArithmeticOverflow)?; + }; + Ok(()) + })?; + } else { + let mut new_queue = BoundedVec::::default(); + new_queue + .try_push(next_queue_id) + .map_err(|_| Error::::TooManyRedeems)?; + UserCurrencyRedeemQueue::::insert(&who, ¤cy_id, (currency_amount, new_queue)); + } + + // Handle ledger of staking round - executed by hooks on every block - staking_round,currency: + // total_amount_unlocked, vec![queue_id], currency + + // Check if there any existing claim of the next staking round + if let Some((_, _, _token_id)) = StakingRoundRedeemQueue::::get(&new_staking_round, ¤cy_id) + { + StakingRoundRedeemQueue::::mutate( + &new_staking_round, + ¤cy_id, + |value| -> Result<(), Error> { + // Add new queue item + if let Some((amount_need_unlocked, existing_queue, _token_id)) = value { + existing_queue + .try_push(next_queue_id) + .map_err(|_| Error::::TooManyRedeems)?; + *amount_need_unlocked = amount_need_unlocked + .checked_add(¤cy_amount) + .ok_or(Error::::ArithmeticOverflow)?; + }; + Ok(()) + }, + )?; + } else { + let mut new_queue = BoundedVec::::default(); + new_queue + .try_push(next_queue_id) + .map_err(|_| Error::::TooManyRedeems)?; + + StakingRoundRedeemQueue::::insert( + &new_staking_round, + ¤cy_id, + (currency_amount, new_queue, currency_id), + ); + } + } + None => return Err(Error::::NoCurrentStakingRound.into()), + } + + QueueNextId::::mutate(¤cy_id, |queue_id| -> Result<(), Error> { + *queue_id = queue_id.checked_add(1).ok_or(Error::::ArithmeticOverflow)?; + Ok(()) + })?; + + // Emit deposit event + Self::deposit_event(Event::Redeemed { + from: who, + pool_id, + amount: r_amount, + }); + Ok(().into()) + } + + /// This function only for governance origin to execute when starting the protocol or + /// changes of era duration. + #[pallet::weight(< T as Config >::WeightInfo::mint_land())] + pub fn update_era_config( + origin: OriginFor, + last_era_updated_block: Option>, + frequency: Option>, + last_staking_round: StakingRound, + estimated_reward_rate_per_era: Option, + unlock_duration: Option<(FungibleTokenId, StakingRound)>, + iteration_limit: Option, + ) -> DispatchResult { + T::GovernanceOrigin::ensure_origin(origin)?; + + if let Some(change) = frequency { + UpdateEraFrequency::::put(change); + Self::deposit_event(Event::::UpdateEraFrequency { frequency: change }); + } + + if let Some(change) = last_era_updated_block { + let update_era_frequency = UpdateEraFrequency::::get(); + let current_relay_chain_block = T::RelayChainBlockNumber::current_block_number(); + if !update_era_frequency.is_zero() { + ensure!( + change > current_relay_chain_block.saturating_sub(update_era_frequency) + && change <= current_relay_chain_block, + Error::::InvalidLastEraUpdatedBlock + ); + + LastEraUpdatedBlock::::put(change); + LastStakingRound::::insert(FungibleTokenId::NativeToken(1), last_staking_round); + Self::deposit_event(Event::::LastEraUpdated { last_era_block: change }); + } + } + + if let Some(reward_rate_per_era) = estimated_reward_rate_per_era { + EstimatedRewardRatePerEra::::mutate(|rate| -> DispatchResult { + rate.try_set(reward_rate_per_era) + .map_err(|_| Error::::InvalidRate.into()) + })?; + Self::deposit_event(Event::::EstimatedRewardRatePerEraUpdated { reward_rate_per_era }); + } + + if let Some((currency_id, staking_round)) = unlock_duration { + UnlockDuration::::insert(currency_id, staking_round); + Self::deposit_event(Event::::UnlockDurationUpdated { + currency_id, + unlock_duration: staking_round, + }) + } + + if let Some(new_limit) = iteration_limit { + IterationLimit::::put(new_limit); + Self::deposit_event(Event::::IterationLimitUpdated { new_limit }) + } + + Ok(()) + } + + /// This function allow reward voting for the pool + #[pallet::weight(< T as Config >::WeightInfo::mint_land())] + pub fn boost(origin: OriginFor, pool_id: PoolId, vote: BoostInfo>) -> DispatchResult { + // Ensure user is signed + let who = ensure_signed(origin)?; + + // Ensure user has balance to vote + ensure!( + vote.balance <= T::Currency::free_balance(&who), + Error::::InsufficientFund + ); + + // Check if pool exists + ensure!(Pool::::get(pool_id).is_some(), Error::::PoolDoesNotExist); + // Still need to work out some + // Convert boost conviction into shares + let vote_conviction = vote.conviction.lock_periods(); + // Calculate lock period from UnlockDuration block number x conviction + let current_block: T::BlockNumber = >::block_number(); + + let mut unlock_at = current_block.saturating_add(UpdateEraFrequency::::get()); + let mut total_balance = vote.balance; + if !vote_conviction.is_zero() { + unlock_at.saturating_mul(vote_conviction.into()); + total_balance.saturating_mul(vote_conviction.into()); + } + // Locked token + + BoostingOf::::try_mutate(who.clone(), |voting| -> DispatchResult { + let votes = &mut voting.votes; + match votes.binary_search_by_key(&pool_id, |i| i.0) { + Ok(i) => { + // User already boosted, this is adding up their boosting weight + votes[i] + .1 + .add(total_balance.clone()) + .ok_or(Error::::ArithmeticOverflow)?; + voting + .prior + .accumulate(unlock_at, votes[i].1.balance.saturating_add(total_balance)) + } + Err(i) => { + votes.insert(i, (pool_id, vote.clone())); + voting.prior.accumulate(unlock_at, total_balance); + } + } + Ok(()) + })?; + T::Currency::extend_lock( + BOOSTING_ID, + &who, + vote.balance, + frame_support::traits::WithdrawReasons::TRANSFER, + ); + + // Add shares into the rewards pool + >::add_share(&who, &pool_id, total_balance.unique_saturated_into()); + // Add shares into the network pool + >::add_share(&who, &Zero::zero(), total_balance.unique_saturated_into()); + + // Emit Boosted event + Self::deposit_event(Event::::Boosted { + booster: who.clone(), + pool_id, + boost_info: vote.clone(), + }); + + Ok(()) + } + + #[pallet::weight(< T as pallet::Config >::WeightInfo::mint_land())] + pub fn claim_rewards(origin: OriginFor, pool_id: PoolId) -> DispatchResult { + let who = ensure_signed(origin)?; + + Self::do_claim_rewards(who, pool_id) + } + } +} + +impl Pallet { + pub fn calculate_next_staking_round(a: StakingRound, b: StakingRound) -> Result { + let result = match a { + StakingRound::Era(era_a) => match b { + StakingRound::Era(era_b) => { + StakingRound::Era(era_a.checked_add(era_b).ok_or(Error::::ArithmeticOverflow)?) + } + _ => return Err(Error::::Unexpected.into()), + }, + StakingRound::Round(round_a) => match b { + StakingRound::Round(round_b) => { + StakingRound::Round(round_a.checked_add(round_b).ok_or(Error::::ArithmeticOverflow)?) + } + _ => return Err(Error::::Unexpected.into()), + }, + StakingRound::Epoch(epoch_a) => match b { + StakingRound::Epoch(epoch_b) => { + StakingRound::Epoch(epoch_a.checked_add(epoch_b).ok_or(Error::::ArithmeticOverflow)?) + } + _ => return Err(Error::::Unexpected.into()), + }, + StakingRound::Hour(hour_a) => match b { + StakingRound::Hour(hour_b) => { + StakingRound::Hour(hour_a.checked_add(hour_b).ok_or(Error::::ArithmeticOverflow)?) + } + _ => return Err(Error::::Unexpected.into()), + }, + }; + + Ok(result) + } + + pub fn collect_deposit_fee( + who: &T::AccountId, + currency_id: FungibleTokenId, + amount: BalanceOf, + ) -> Result, DispatchError> { + let (deposit_rate, _redeem_rate) = Fees::::get(); + + let deposit_fee = deposit_rate.into_inner().saturating_mul_int(amount); + let amount_exclude_fee = amount.checked_sub(&deposit_fee).ok_or(Error::::ArithmeticOverflow)?; + T::MultiCurrency::transfer( + currency_id, + who, + &T::PoolAccount::get().into_account_truncating(), + deposit_fee, + )?; + + return Ok(amount_exclude_fee); + } + + pub fn collect_redeem_fee( + who: &T::AccountId, + currency_id: FungibleTokenId, + amount: BalanceOf, + ) -> Result, DispatchError> { + let (_mint_rate, redeem_rate) = Fees::::get(); + let redeem_fee = redeem_rate.into_inner().saturating_mul_int(amount); + let amount_exclude_fee = amount.checked_sub(&redeem_fee).ok_or(Error::::ArithmeticOverflow)?; + T::MultiCurrency::transfer( + currency_id, + who, + &T::PoolAccount::get().into_account_truncating(), + redeem_fee, + )?; + + return Ok(amount_exclude_fee); + } + + pub fn collect_pool_creation_fee(who: &T::AccountId, currency_id: FungibleTokenId) -> DispatchResult { + let pool_fee = T::NetworkFee::get(); + T::MultiCurrency::transfer( + currency_id, + who, + &T::PoolAccount::get().into_account_truncating(), + pool_fee, + ) + } + + fn handle_update_staking_round(era_index: EraIndex, currency: FungibleTokenId) -> DispatchResult { + let last_staking_round = StakingRound::Era(era_index as u32); + let unlock_duration = match UnlockDuration::::get(currency) { + Some(StakingRound::Era(unlock_duration_era)) => unlock_duration_era, + Some(StakingRound::Round(unlock_duration_round)) => unlock_duration_round, + Some(StakingRound::Epoch(unlock_duration_epoch)) => unlock_duration_epoch, + Some(StakingRound::Hour(unlock_duration_hour)) => unlock_duration_hour, + _ => 0, + }; + + let current_staking_round = era_index; + + // Check current staking round queue with last staking round if there is any pending redeem requests + if let Some((_total_locked, existing_queue, currency_id)) = + StakingRoundRedeemQueue::::get(last_staking_round.clone(), currency) + { + for queue_id in existing_queue.iter().take(Self::iteration_limit() as usize) { + if let Some((account, unlock_amount, staking_round)) = + CurrencyRedeemQueue::::get(currency_id, queue_id) + { + let pool_account_balance = + T::MultiCurrency::free_balance(currency_id, &T::PoolAccount::get().into_account_truncating()); + if pool_account_balance != BalanceOf::::zero() { + Self::update_queue_request( + currency_id, + account, + queue_id, + unlock_amount, + pool_account_balance, + staking_round, + ) + .ok(); + } + } + } + } else { + LastStakingRound::::mutate(currency, |last_staking_round| -> Result<(), Error> { + match last_staking_round { + StakingRound::Era(era) => { + if current_staking_round + unlock_duration > *era { + *era = era.checked_add(1).ok_or(Error::::ArithmeticOverflow)?; + } + Ok(()) + } + StakingRound::Round(round) => { + if current_staking_round + unlock_duration > *round { + *round = round.checked_add(1).ok_or(Error::::ArithmeticOverflow)?; + } + Ok(()) + } + StakingRound::Epoch(epoch) => { + if current_staking_round + unlock_duration > *epoch { + *epoch = epoch.checked_add(1).ok_or(Error::::ArithmeticOverflow)?; + } + Ok(()) + } + StakingRound::Hour(hour) => { + if current_staking_round + unlock_duration > *hour { + *hour = hour.checked_add(1).ok_or(Error::::ArithmeticOverflow)?; + } + Ok(()) + } + _ => Ok(()), + } + })?; + }; + + Ok(()) + } + + fn handle_reward_distribution_to_network_pool() -> DispatchResult { + // Get reward per era that set up Governance + let reward_per_era = RewardEraFrequency::::get(); + // Get reward holding account + let reward_holding_origin = T::RewardHoldingAccount::get().into_account_truncating(); + let reward_holding_balance = T::Currency::free_balance(&reward_holding_origin); + + if reward_holding_balance.is_zero() { + // Ignore if reward distributor balance is zero + return Ok(()); + } + + let mut amount_to_send = reward_per_era.clone(); + // Make sure user distributor account has enough balance + if amount_to_send > reward_holding_balance { + amount_to_send = reward_holding_balance + } + + T::Currency::transfer( + &reward_holding_origin, + &Self::get_reward_payout_account_id(), + amount_to_send, + ExistenceRequirement::KeepAlive, + )?; + >::accumulate_reward(&Zero::zero(), FungibleTokenId::NativeToken(0), amount_to_send)?; + Ok(()) + } + + pub(crate) fn estimated_reward_rate_per_era() -> Rate { + EstimatedRewardRatePerEra::::get().into_inner() + } + + fn handle_reward_distribution_to_pool_treasury(previous_era: EraIndex, new_era: EraIndex) -> DispatchResult { + let era_changes = new_era.saturating_sub(previous_era); + ensure!(!era_changes.is_zero(), Error::::Unexpected); + // Get reward per era for pool treasury + let reward_rate_per_era = Self::estimated_reward_rate_per_era(); + // Get total compound reward rate based on number of era. + let reward_rate = reward_rate_per_era + .saturating_add(Rate::one()) + .saturating_pow(era_changes.unique_saturated_into()) + .saturating_sub(Rate::one()); + let mut total_reward_staking: BalanceOf = Zero::zero(); + + if !reward_rate.is_zero() { + // iterate all pool ledgers + for (pool_id, pool_amount) in PoolLedger::::iter() { + let mut reward_staking = reward_rate.saturating_mul_int(pool_amount); + + if !reward_staking.is_zero() { + let pool_treasury_account = Self::get_pool_treasury(pool_id); + total_reward_staking = total_reward_staking.saturating_add(reward_staking); + + let pool_treasury_commission = Rate::checked_from_rational(1, 100).unwrap_or_default(); + let pool_treasury_reward_commission_amount = + pool_treasury_commission.saturating_mul_int(reward_staking); + + // Increase reward staking of pool ledger + PoolLedger::::mutate(pool_id, |total_staked| -> Result<(), Error> { + *total_staked = total_staked + .checked_add(&reward_staking) + .ok_or(Error::::ArithmeticOverflow)?; + + Ok(()) + })?; + + T::MultiCurrency::deposit( + FungibleTokenId::FungibleToken(1), + &pool_treasury_account, + pool_treasury_reward_commission_amount, + )?; + >::accumulate_reward( + &pool_id, + FungibleTokenId::FungibleToken(1), + pool_treasury_reward_commission_amount, + )?; + } + } + + if !total_reward_staking.is_zero() { + NetworkLedger::::mutate( + &FungibleTokenId::NativeToken(1), + |total_staked| -> Result<(), Error> { + *total_staked = total_staked + .checked_add(&total_reward_staking) + .ok_or(Error::::ArithmeticOverflow)?; + Ok(()) + }, + )?; + } + } + + Ok(()) + } + + #[transactional] + fn update_queue_request( + currency_id: FungibleTokenId, + account: T::AccountId, + queue_id: &QueueId, + mut unlock_amount: BalanceOf, + pool_account_balance: BalanceOf, + staking_round: StakingRound, + ) -> DispatchResult { + // Get minimum balance of currency + let ed = T::MultiCurrency::minimum_balance(currency_id); + let mut account_to_send = account.clone(); + + // If unlock amount less than existential deposit, to avoid error kill the process, transfer the + // unlock_amount to pool address instead + if unlock_amount < ed { + let receiver_balance = T::MultiCurrency::total_balance(currency_id, &account); + + // Check if even after receiving unlock amount, account still below ED then transfer fund to + // PoolAccount + let receiver_balance_after = receiver_balance + .checked_add(&unlock_amount) + .ok_or(ArithmeticError::Overflow)?; + if receiver_balance_after < ed { + account_to_send = T::PoolAccount::get().into_account_truncating(); + } + } + + // If pool account balance greater than unlock amount + if pool_account_balance >= unlock_amount { + // Transfer amount from PoolAccount to users + T::MultiCurrency::transfer( + currency_id, + &T::PoolAccount::get().into_account_truncating(), + &account_to_send, + unlock_amount, + )?; + + // Remove currency redeem queue + CurrencyRedeemQueue::::remove(¤cy_id, &queue_id); + + // Edit staking round redeem queue with locked amount + StakingRoundRedeemQueue::::mutate_exists( + &staking_round, + ¤cy_id, + |value| -> Result<(), Error> { + if let Some((total_locked_origin, existing_queue, _)) = value { + // If total locked == unlock_amount, then set value to zero + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + // Otherwise, deduct unlock amount + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::ArithmeticOverflow)?; + // Only keep items that not with processed queue_id + existing_queue.retain(|x| x != queue_id); + } else { + return Err(Error::::StakingRoundRedeemNotFound); + } + Ok(()) + }, + )?; + + UserCurrencyRedeemQueue::::mutate_exists(&account, ¤cy_id, |value| -> Result<(), Error> { + if let Some((total_locked_origin, existing_queue)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + existing_queue.retain(|x| x != queue_id); + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::ArithmeticOverflow)?; + } else { + return Err(Error::::UserCurrencyRedeemQueueNotFound); + } + Ok(()) + })?; + } else { + // When pool account balance less than amount need to be unlocked then use pool remaining balance as + // unlock amount + unlock_amount = pool_account_balance; + T::MultiCurrency::transfer( + currency_id, + &T::PoolAccount::get().into_account_truncating(), + &account_to_send, + unlock_amount, + )?; + + CurrencyRedeemQueue::::mutate_exists(¤cy_id, &queue_id, |value| -> Result<(), Error> { + if let Some((_, total_locked_origin, _)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::ArithmeticOverflow)?; + } else { + return Err(Error::::CurrencyRedeemQueueNotFound); + } + Ok(()) + })?; + + StakingRoundRedeemQueue::::mutate_exists( + &staking_round, + ¤cy_id, + |value| -> Result<(), Error> { + if let Some((total_locked_origin, _existing_queue, _)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::ArithmeticOverflow)?; + } else { + return Err(Error::::StakingRoundRedeemNotFound); + } + Ok(()) + }, + )?; + + UserCurrencyRedeemQueue::::mutate_exists(&account, ¤cy_id, |value| -> Result<(), Error> { + if let Some((total_locked_origin, _existing_queue)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::ArithmeticOverflow)?; + } else { + return Err(Error::::UserCurrencyRedeemQueueNotFound); + } + Ok(()) + })?; + } + + pool_account_balance + .checked_sub(&unlock_amount) + .ok_or(Error::::ArithmeticOverflow)?; + + NetworkLedger::::mutate(¤cy_id, |pool| -> Result<(), Error> { + *pool = pool.checked_sub(&unlock_amount).ok_or(Error::::ArithmeticOverflow)?; + Ok(()) + })?; + + Self::deposit_event(Event::RedeemSuccess { + queue_id: *queue_id, + currency_id, + to: account_to_send, + token_amount: unlock_amount, + }); + Ok(()) + } + + pub fn get_era_index(relaychain_block_number: BlockNumberFor) -> EraIndex { + relaychain_block_number + .checked_sub(&Self::last_era_updated_block()) + .and_then(|n| n.checked_div(&Self::update_era_frequency())) + .and_then(|n| TryInto::::try_into(n).ok()) + .unwrap_or_else(Zero::zero) + } + + fn handle_redeem_requests(era_index: EraIndex) -> DispatchResult { + for currency in CurrentStakingRound::::iter_keys() { + Self::handle_update_staking_round(era_index, currency)?; + } + Ok(()) + } + + #[transactional] + pub fn update_current_era(era_index: EraIndex) -> DispatchResult { + let previous_era = Self::relay_chain_current_era(); + let new_era = previous_era.saturating_add(era_index); + + RelayChainCurrentEra::::put(new_era); + LastEraUpdatedBlock::::put(T::RelayChainBlockNumber::current_block_number()); + Self::handle_redeem_requests(new_era)?; + Self::handle_reward_distribution_to_network_pool()?; + Self::deposit_event(Event::::CurrentEraUpdated { new_era_index: new_era }); + Ok(()) + } + + pub fn get_pool_account() -> T::AccountId { + T::PoolAccount::get().into_account_truncating() + } + + pub fn get_pool_treasury(pool_id: PoolId) -> T::AccountId { + return T::PoolAccount::get().into_sub_account_truncating(pool_id); + } + + pub fn get_reward_payout_account_id() -> T::AccountId { + T::RewardPayoutAccount::get().into_account_truncating() + } + + pub fn get_reward_holding_account_id() -> T::AccountId { + T::RewardHoldingAccount::get().into_account_truncating() + } + + fn do_claim_rewards(who: T::AccountId, pool_id: PoolId) -> DispatchResult { + if pool_id.is_zero() { + >::claim_rewards(&who, &pool_id); + + PendingRewards::::mutate_exists(pool_id, &who, |maybe_pending_multi_rewards| { + if let Some(pending_multi_rewards) = maybe_pending_multi_rewards { + for (currency_id, pending_reward) in pending_multi_rewards.iter_mut() { + if pending_reward.is_zero() { + continue; + } + + let payout_amount = pending_reward.clone(); + + match Self::payout_reward(pool_id, &who, *currency_id, payout_amount) { + Ok(_) => { + // update state + *pending_reward = Zero::zero(); + + Self::deposit_event(Event::ClaimRewards { + who: who.clone(), + pool: pool_id, + reward_currency_id: FungibleTokenId::NativeToken(0), + claimed_amount: payout_amount, + }); + } + Err(e) => { + log::error!( + target: "spp", + "payout_reward: failed to payout {:?} to {:?} to pool {:?}: {:?}", + pending_reward, who, pool_id, e + ); + } + } + } + } + }) + } + + Ok(()) + } + + /// Ensure atomic + #[transactional] + fn payout_reward( + pool_id: PoolId, + who: &T::AccountId, + reward_currency_id: FungibleTokenId, + payout_amount: BalanceOf, + ) -> DispatchResult { + T::MultiCurrency::transfer( + reward_currency_id, + &Self::get_reward_payout_account_id(), + who, + payout_amount, + )?; + Ok(()) + } +} + +impl RewardHandler for Pallet { + type Balance = BalanceOf; + type PoolId = PoolId; + + /// This function trigger by orml_reward claim_rewards, it will modify and add pending reward + /// into PendingRewards for users to claim + fn payout(who: &T::AccountId, pool_id: &Self::PoolId, currency_id: FungibleTokenId, payout_amount: Self::Balance) { + if payout_amount.is_zero() { + return; + } + PendingRewards::::mutate(pool_id, who, |rewards| { + rewards + .entry(currency_id) + .and_modify(|current| *current = current.saturating_add(payout_amount)) + .or_insert(payout_amount); + }); + } +} diff --git a/pallets/spp/src/mock.rs b/pallets/spp/src/mock.rs new file mode 100644 index 000000000..ae1304727 --- /dev/null +++ b/pallets/spp/src/mock.rs @@ -0,0 +1,299 @@ +#![cfg(test)] + +use frame_support::traits::Nothing; +use frame_support::{construct_runtime, ord_parameter_types, parameter_types, PalletId}; +use frame_system::EnsureSignedBy; +use orml_traits::parameter_type_with_key; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{ConvertInto, IdentityLookup}, + DispatchError, Perbill, +}; +use sp_std::collections::btree_map::BTreeMap; +use sp_std::default::Default; +use sp_std::vec::Vec; + +use asset_manager::ForeignAssetMapping; +use auction_manager::{Auction, AuctionInfo, AuctionItem, AuctionType, CheckAuctionItemHandler, ListingLevel}; +use core_primitives::{CollectionType, NftClassData, TokenType}; +use primitives::{ + Amount, AssetId, Attributes, AuctionId, ClassId, FungibleTokenId, GroupCollectionId, NftMetadata, PoolId, TokenId, + LAND_CLASS_ID, +}; + +use crate as spp; + +use super::*; + +pub type AccountId = u128; +pub type Balance = u128; +pub type MetaverseId = u64; +pub type BlockNumber = u64; +pub type EstateId = u64; + +pub const ALICE: AccountId = 1; +pub const BOB: AccountId = 5; +pub const CHARLIE: AccountId = 6; +pub const DOM: AccountId = 7; +pub const BENEFICIARY_ID: AccountId = 99; +pub const AUCTION_BENEFICIARY_ID: AccountId = 100; +pub const CLASS_FUND_ID: AccountId = 123; +pub const METAVERSE_ID: MetaverseId = 0; +pub const DOLLARS: Balance = 1_000_000_000_000_000_000; + +pub const BOND_AMOUNT_1: Balance = 1000; +pub const BOND_AMOUNT_2: Balance = 2000; +pub const BOND_AMOUNT_BELOW_MINIMUM: Balance = 100; +pub const BOND_LESS_AMOUNT_1: Balance = 100; + +ord_parameter_types! { + pub const One: AccountId = ALICE; + pub const Admin: AccountId = ALICE; +} + +// Configure a mock runtime to test the pallet. + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = BlockNumber; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = frame_support::traits::Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type MaxLocks = (); + type WeightInfo = (); + type MaxReserves = (); + type ReserveIdentifier = (); +} + +// pub type AdaptedBasicCurrency = +// currencies::BasicCurrencyAdapter; + +parameter_types! { + pub const GetNativeCurrencyId: FungibleTokenId = FungibleTokenId::NativeToken(0); + pub const PoolAccountPalletId: PalletId = PalletId(*b"bit/pool"); + pub const RewardPayoutAccount: PalletId = PalletId(*b"bit/payo"); + pub const RewardHoldingAccount: PalletId = PalletId(*b"bit/hold"); +} + +fn test_attributes(x: u8) -> Attributes { + let mut attr: Attributes = BTreeMap::new(); + attr.insert(vec![x, x + 5], vec![x, x + 10]); + attr +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: FungibleTokenId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = FungibleTokenId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type CurrencyHooks = (); + type MaxLocks = (); + type ReserveIdentifier = [u8; 8]; + type MaxReserves = (); + type DustRemovalWhitelist = Nothing; +} + +pub type AdaptedBasicCurrency = currencies::BasicCurrencyAdapter; + +parameter_types! { + pub const NativeCurrencyId: FungibleTokenId = FungibleTokenId::NativeToken(0); + pub const MiningCurrencyId: FungibleTokenId = FungibleTokenId::MiningResource(0); +} + +impl currencies::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MultiSocialCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type GetNativeCurrencyId = NativeCurrencyId; + type WeightInfo = (); +} + +impl asset_manager::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type RegisterOrigin = EnsureSignedBy; +} + +impl BlockNumberProvider for MockRelayBlockNumberProvider { + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + Self::get() + } +} + +impl orml_rewards::Config for Runtime { + type Share = Balance; + type Balance = Balance; + type PoolId = PoolId; + type CurrencyId = FungibleTokenId; + type Handler = SppModule; +} + +parameter_types! { + pub const MinBlocksPerRound: u32 = 10; + pub const MinimumStake: Balance = 200; + /// Reward payments are delayed by 2 hours (2 * 300 * block_time) + pub const RewardPaymentDelay: u32 = 2; + pub const NetworkFee: Balance = 1; // Network fee + pub const MaxOffersPerEstate: u32 = 2; + pub const MinLeasePricePerBlock: Balance = 1u128; + pub const MaxLeasePeriod: u32 = 9; + pub const LeaseOfferExpiryPeriod: u32 = 6; + pub StorageDepositFee: Balance = 1; + pub const MaximumQueue: u32 = 50; + pub static MockRelayBlockNumberProvider: BlockNumber = 0; +} + +impl Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type WeightInfo = (); + type MinimumStake = MinimumStake; + type RewardPaymentDelay = RewardPaymentDelay; + type NetworkFee = NetworkFee; + type BlockNumberToBalance = ConvertInto; + type StorageDepositFee = StorageDepositFee; + type MultiCurrency = Currencies; + type PoolAccount = PoolAccountPalletId; + type MaximumQueue = MaximumQueue; + type CurrencyIdConversion = ForeignAssetMapping; + type RelayChainBlockNumber = MockRelayBlockNumberProvider; + type GovernanceOrigin = EnsureSignedBy; + type RewardPayoutAccount = RewardPayoutAccount; + type RewardHoldingAccount = RewardHoldingAccount; +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + AssetManager: asset_manager::{ Pallet, Storage, Call, Event}, + Currencies: currencies::{ Pallet, Storage, Call, Event}, + Tokens: orml_tokens::{Pallet, Call, Storage, Config, Event}, + Spp: spp:: {Pallet, Call, Storage, Event}, + RewardsModule: orml_rewards + } +); + +pub type SppModule = Pallet; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +pub struct ExtBuilder { + endowed_accounts: Vec<(AccountId, FungibleTokenId, Balance)>, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + endowed_accounts: vec![], + } + } +} + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, 1000000000), (BOB, 100000), (CHARLIE, 100000), (DOM, 100000)], + } + .assimilate_storage(&mut t) + .unwrap(); + + orml_tokens::GenesisConfig:: { + balances: self.endowed_accounts.into_iter().collect::>(), + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } + + pub fn balances(mut self, endowed_accounts: Vec<(AccountId, FungibleTokenId, Balance)>) -> Self { + self.endowed_accounts = endowed_accounts; + self + } + + pub fn ksm_setup_for_alice_and_bob(self) -> Self { + self.balances(vec![ + (ALICE, FungibleTokenId::NativeToken(1), 20000), //KSM + (BOB, FungibleTokenId::NativeToken(1), 20000), //KSM + ]) + } +} + +pub fn last_event() -> RuntimeEvent { + frame_system::Pallet::::events() + .pop() + .expect("Event expected") + .event +} + +fn next_block() { + SppModule::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); +} + +pub fn run_to_block(n: u64) { + while System::block_number() < n { + next_block(); + } +} diff --git a/pallets/spp/src/tests.rs b/pallets/spp/src/tests.rs new file mode 100644 index 000000000..e1afb21ba --- /dev/null +++ b/pallets/spp/src/tests.rs @@ -0,0 +1,781 @@ +// This file is part of Metaverse.Network & Bit.Country. + +// Copyright (C) 2020-2022 Metaverse.Network & Bit.Country . +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +use frame_support::{assert_err, assert_noop, assert_ok}; +use pallet_balances::BalanceLock; +use sp_runtime::traits::BadOrigin; +use sp_runtime::{Perbill, Permill}; + +use mock::{RuntimeEvent, *}; +use primitives::bounded::FractionalRate; + +use crate::utils::{BoostInfo, BoostingConviction, BoostingRecord, PoolInfo, PriorLock}; + +use super::*; + +#[test] +fn test_one() { + ExtBuilder::default().build().execute_with(|| assert_eq!(1, 1)); +} + +fn the_lock(amount: Balance) -> BalanceLock { + BalanceLock { + id: BOOSTING_ID, + amount, + reasons: pallet_balances::Reasons::Misc, + } +} + +#[test] +fn create_ksm_pool_works() { + ExtBuilder::default() + .ksm_setup_for_alice_and_bob() + .build() + .execute_with(|| { + + // Create the first pool + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(ALICE), + FungibleTokenId::NativeToken(1), + 50, + Rate::saturating_from_rational(5, 100) + )); + + // Check the next pool id will increment + let next_pool_id: u32 = NextPoolId::::get(); + assert_eq!(next_pool_id, 2); + + // Check if the pool details as expected. + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: ALICE, + commission: Rate::saturating_from_rational(5, 100), + currency_id: FungibleTokenId::NativeToken(1), + max: 50 + } + ); + + // Create a second pool + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(BOB), + FungibleTokenId::NativeToken(1), + 10, + Permill::from_percent(1) + )); + + // Check Id will increment + let next_pool_id: u32 = NextPoolId::::get(); + assert_eq!(next_pool_id, 3); + // Check the second pool has the right information as expected + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: BOB, + commission: Permill::from_percent(1), + currency_id: FungibleTokenId::NativeToken(1), + max: 10 + } + ); + }); +} + +#[test] +fn deposit_ksm_works() { + ExtBuilder::default() + .ksm_setup_for_alice_and_bob() + .build() + .execute_with(|| { + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(ALICE), + FungibleTokenId::NativeToken(1), + 50, + Rate::saturating_from_rational(5, 100) + )); + + let next_pool_id = NextPoolId::::get(); + assert_eq!(next_pool_id, 2); + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: ALICE, + commission: Rate::saturating_from_rational(5, 100), + currency_id: FungibleTokenId::NativeToken(1), + max: 50 + } + ); + + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + // This is true because fee hasn't been set up. + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 10000); + + assert_eq!(PoolLedger::::get(1), 10000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 10000); + + // Deposit another 10000 KSM + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 20000); + + assert_eq!(PoolLedger::::get(1), 20000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 20000); + }); +} + +#[test] +fn redeem_rksm_request_works() { + ExtBuilder::default() + .ksm_setup_for_alice_and_bob() + .build() + .execute_with(|| { + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(ALICE), + FungibleTokenId::NativeToken(1), + 50, + Rate::saturating_from_rational(5, 100) + )); + + let next_pool_id = NextPoolId::::get(); + assert_eq!(next_pool_id, 2); + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: ALICE, + commission: Rate::saturating_from_rational(5, 100), + currency_id: FungibleTokenId::NativeToken(1), + max: 50 + } + ); + + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + // This is true because fee hasn't been set up. + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 10000); + + assert_eq!(PoolLedger::::get(1), 10000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 10000); + + // Deposit another 10000 KSM + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 20000); + + assert_eq!(PoolLedger::::get(1), 20000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 20000); + + assert_noop!( + SppModule::redeem(RuntimeOrigin::signed(BOB), 2, FungibleTokenId::FungibleToken(1), 10000), + Error::::PoolDoesNotExist + ); + + assert_noop!( + SppModule::redeem(RuntimeOrigin::signed(BOB), 1, FungibleTokenId::FungibleToken(0), 10000), + Error::::CurrencyIsNotSupported + ); + + assert_noop!( + SppModule::redeem(RuntimeOrigin::signed(BOB), 1, FungibleTokenId::FungibleToken(1), 10000), + Error::::NoCurrentStakingRound + ); + + UnlockDuration::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(1)); + // Bump current staking round to 1 + CurrentStakingRound::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(1)); + assert_ok!(SppModule::redeem( + RuntimeOrigin::signed(BOB), + 1, + FungibleTokenId::FungibleToken(1), + 10000 + )); + + // After Bob redeems, pool ledger 1 should have only 10000 + assert_eq!(PoolLedger::::get(1), 10000); + + // Verify if redeem queue has requests + + let queue_id = QueueNextId::::get(FungibleTokenId::NativeToken(1)); + assert_eq!(queue_id, 1); + let mut queue_items = BoundedVec::default(); + assert_ok!(queue_items.try_push(0)); + let user_redeem_queue = UserCurrencyRedeemQueue::::get(BOB, FungibleTokenId::NativeToken(1)); + let currency_redeem_queue = CurrencyRedeemQueue::::get(FungibleTokenId::NativeToken(1), 0); + let staking_round_redeem_queue = + StakingRoundRedeemQueue::::get(StakingRound::Era(2), FungibleTokenId::NativeToken(1)); + // Verify if user redeem queue has total unlocked and queue items + assert_eq!(user_redeem_queue, Some((10000, queue_items.clone()))); + // If user redeem of Era 1, fund will be released at Era 2 + assert_eq!(currency_redeem_queue, Some((BOB, 10000, StakingRound::Era(2)))); + // Redeem added into staking round redeem queue for Era 2 + assert_eq!( + staking_round_redeem_queue, + Some((10000, queue_items.clone(), FungibleTokenId::NativeToken(1))) + ); + }); +} + +#[test] +fn current_era_update_works() { + ExtBuilder::default() + .ksm_setup_for_alice_and_bob() + .build() + .execute_with(|| { + assert_eq!(SppModule::last_era_updated_block(), 0); + assert_eq!(SppModule::update_era_frequency(), 0); + assert_eq!(MockRelayBlockNumberProvider::current_block_number(), 0); + // Current relaychain block is 102. + MockRelayBlockNumberProvider::set(102); + RelayChainCurrentEra::::put(1); + IterationLimit::::put(50); + // The correct set up era config is the last era block records is 101 with duration is 100 blocks + assert_ok!(SppModule::update_era_config( + RuntimeOrigin::signed(Admin::get()), + Some(101), + Some(100), + StakingRound::Era(1), + Some(Rate::saturating_from_rational(35, 100000)) + )); + + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(ALICE), + FungibleTokenId::NativeToken(1), + 50, + Rate::saturating_from_rational(5, 100) + )); + + let next_pool_id = NextPoolId::::get(); + assert_eq!(next_pool_id, 2); + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: ALICE, + commission: Rate::saturating_from_rational(5, 100), + currency_id: FungibleTokenId::NativeToken(1), + max: 50, + } + ); + // Verify BOB account with 20000 KSM + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::NativeToken(1)).free, 20000); + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + // This is true because fee hasn't been set up. + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 10000); + // Bob KSM balance become 10000 + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::NativeToken(1)).free, 10000); + + assert_eq!(PoolLedger::::get(1), 10000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 10000); + + // Deposit another 10000 KSM + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 20000); + // Bob KSM now is 0 + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::NativeToken(1)).free, 0); + + assert_eq!(PoolLedger::::get(1), 20000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 20000); + + // Pool summary + // Pool Total deposited: 20000 + // Network deposited: 20000, NativeToken(1) + + // Bob summary + // Holding: 20000 FungibleToken(1) reciept token of NativeToken(1) + + assert_noop!( + SppModule::redeem(RuntimeOrigin::signed(BOB), 2, FungibleTokenId::FungibleToken(1), 10000), + Error::::PoolDoesNotExist + ); + + assert_noop!( + SppModule::redeem(RuntimeOrigin::signed(BOB), 1, FungibleTokenId::FungibleToken(0), 10000), + Error::::CurrencyIsNotSupported + ); + + assert_noop!( + SppModule::redeem(RuntimeOrigin::signed(BOB), 1, FungibleTokenId::FungibleToken(1), 10000), + Error::::NoCurrentStakingRound + ); + + UnlockDuration::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(1)); // Bump current staking round to 1 + CurrentStakingRound::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(1)); + + // Bob successfully redeemed + assert_ok!(SppModule::redeem( + RuntimeOrigin::signed(BOB), + 1, + FungibleTokenId::FungibleToken(1), + 10000 + )); + + // After Bob redeems, pool ledger 0 should have only 10000 + assert_eq!(PoolLedger::::get(1), 10000); + + // After Bob redeem, make sure BOB KSM balance remains the same as it will only released next era + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::NativeToken(1)).free, 0); + + // Verify if redeem queue has requests + let queue_id = QueueNextId::::get(FungibleTokenId::NativeToken(1)); + assert_eq!(queue_id, 1); + let mut queue_items = BoundedVec::default(); + assert_ok!(queue_items.try_push(0)); + let user_redeem_queue = UserCurrencyRedeemQueue::::get(BOB, FungibleTokenId::NativeToken(1)); + let currency_redeem_queue = CurrencyRedeemQueue::::get(FungibleTokenId::NativeToken(1), 0); + let staking_round_redeem_queue = + StakingRoundRedeemQueue::::get(StakingRound::Era(2), FungibleTokenId::NativeToken(1)); + // Verify if user redeem queue has total unlocked and queue items + assert_eq!(user_redeem_queue, Some((10000, queue_items.clone()))); + // If user redeem of Era 1, fund will be released at Era 2 + assert_eq!(currency_redeem_queue, Some((BOB, 10000, StakingRound::Era(2)))); + // Redeem added into staking round redeem queue for Era 2 + assert_eq!( + staking_round_redeem_queue, + Some((10000, queue_items.clone(), FungibleTokenId::NativeToken(1))) + ); + + // Move to era 2 to allow user redeem token successfully + MockRelayBlockNumberProvider::set(202); + SppModule::on_initialize(200); + + let pool_account = SppModule::get_pool_account(); + assert_eq!( + Tokens::accounts(pool_account, FungibleTokenId::NativeToken(1)).free, + 10001 + ); + + // After KSM released, BOB balance now is + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::NativeToken(1)).free, 10000); + assert_eq!( + CurrencyRedeemQueue::::get(FungibleTokenId::NativeToken(1), 0), + None + ); + assert_eq!( + UserCurrencyRedeemQueue::::get(BOB, FungibleTokenId::NativeToken(1)), + None + ); + assert_eq!( + StakingRoundRedeemQueue::::get(StakingRound::Era(2), FungibleTokenId::NativeToken(1)), + None + ); + + // Move to era 3, make sure no double redeem process + MockRelayBlockNumberProvider::set(302); + SppModule::on_initialize(300); + + // Pool account remain the same + assert_eq!( + Tokens::accounts(pool_account, FungibleTokenId::NativeToken(1)).free, + 10001 + ); + + // BOB balance remain the same + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::NativeToken(1)).free, 10000); + assert_eq!( + CurrencyRedeemQueue::::get(FungibleTokenId::NativeToken(1), 0), + None + ); + assert_eq!( + UserCurrencyRedeemQueue::::get(BOB, FungibleTokenId::NativeToken(1)), + None + ); + assert_eq!( + StakingRoundRedeemQueue::::get(StakingRound::Era(2), FungibleTokenId::NativeToken(1)), + None + ); + assert_eq!( + StakingRoundRedeemQueue::::get(StakingRound::Era(3), FungibleTokenId::NativeToken(1)), + None + ); + }); +} + +#[test] +fn boosting_works() { + ExtBuilder::default() + .ksm_setup_for_alice_and_bob() + .build() + .execute_with(|| { + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(ALICE), + FungibleTokenId::NativeToken(1), + 50, + Rate::saturating_from_rational(5, 100) + )); + + let next_pool_id = NextPoolId::::get(); + assert_eq!(next_pool_id, 2); + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: ALICE, + commission: Rate::saturating_from_rational(5, 100), + currency_id: FungibleTokenId::NativeToken(1), + max: 50 + } + ); + + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + // This is true because fee hasn't been set up. + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 10000); + + assert_eq!(PoolLedger::::get(1), 10000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 10000); + + // Deposit another 10000 KSM + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 20000); + + assert_eq!(PoolLedger::::get(1), 20000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 20000); + + // Boosting works + let bob_free_balance = Balances::free_balance(BOB); + assert_ok!(SppModule::boost( + RuntimeOrigin::signed(BOB), + 1, + BoostInfo { + balance: bob_free_balance, + conviction: BoostingConviction::None + } + )); + let boosting_of = BoostingOf::::get(BOB); + let some_record = BoostingRecord { + votes: vec![( + 1, + BoostInfo { + balance: bob_free_balance, + conviction: BoostingConviction::None, + }, + )], + prior: PriorLock(1, bob_free_balance), + }; + assert_eq!(boosting_of, some_record); + assert_eq!(Balances::usable_balance(&BOB), 0); + let pool_1_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(1, BOB); + let network_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(0, BOB); + assert_eq!(pool_1_shared_rewards, (bob_free_balance, Default::default())); + assert_eq!(network_shared_rewards, (bob_free_balance, Default::default())); + }); +} + +#[test] +fn boosting_and_claim_reward_works() { + ExtBuilder::default() + .ksm_setup_for_alice_and_bob() + .build() + .execute_with(|| { + // Era config set up + // Current relaychain block is 102. + MockRelayBlockNumberProvider::set(102); + RelayChainCurrentEra::::put(1); + IterationLimit::::put(50); + // The correct set up era config is the last era block records is 101 with duration is 100 blocks + assert_ok!(SppModule::update_era_config( + RuntimeOrigin::signed(Admin::get()), + Some(101), + Some(100), + StakingRound::Era(1), + Some(Rate::saturating_from_rational(35, 100000)) + )); + + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(ALICE), + FungibleTokenId::NativeToken(1), + 50, + Rate::saturating_from_rational(5, 100) + )); + + let next_pool_id = NextPoolId::::get(); + assert_eq!(next_pool_id, 2); + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: ALICE, + commission: Rate::saturating_from_rational(5, 100), + currency_id: FungibleTokenId::NativeToken(1), + max: 50 + } + ); + + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + // This is true because fee hasn't been set up. + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 10000); + + assert_eq!(PoolLedger::::get(1), 10000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 10000); + + // Deposit another 10000 KSM + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 20000); + + assert_eq!(PoolLedger::::get(1), 20000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 20000); + + // Boosting works + let bob_free_balance = Balances::free_balance(BOB); + assert_ok!(SppModule::boost( + RuntimeOrigin::signed(BOB), + 1, + BoostInfo { + balance: 15000, + conviction: BoostingConviction::None + } + )); + let boosting_of = BoostingOf::::get(BOB); + let some_record = BoostingRecord { + votes: vec![( + 1, + BoostInfo { + balance: 15000, + conviction: BoostingConviction::None, + }, + )], + prior: PriorLock(101, 15000), + }; + assert_eq!(boosting_of, some_record); + assert_eq!(Balances::usable_balance(&BOB), bob_free_balance - 15000); + let pool_1_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(1, BOB); + let network_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(0, BOB); + assert_eq!(pool_1_shared_rewards, (15000, Default::default())); + assert_eq!(network_shared_rewards, (15000, Default::default())); + + // Set reward per era. - 1000 NativeToken(0) per 100 blocks + RewardEraFrequency::::put(1000); + // Simulate Council transfer 10000 NativeToken to reward_payout_account so that account has + // sufficient balance for reward distribution + let reward_holding_account = SppModule::get_reward_holding_account_id(); + assert_ok!(Balances::transfer( + RuntimeOrigin::signed(ALICE), + reward_holding_account.clone(), + 10000 + )); + + // Move to era 2, now protocol distribute 1000 NEER to incentivise boosters + MockRelayBlockNumberProvider::set(202); + SppModule::on_initialize(200); + + let network_reward_pool = RewardsModule::pool_infos(0u32); + let reward_accumulated = RewardsModule::shares_and_withdrawn_rewards(0, BOB); + + // Verify after 1 era, total rewards should have 1000 NEER and 0 claimed + assert_eq!( + network_reward_pool, + orml_rewards::PoolInfo { + total_shares: 15000, + rewards: vec![(FungibleTokenId::NativeToken(0), (1000, 0))].into_iter().collect() + } + ); + + // Reward records of BOB holding 15000 shares and 0 claimed + assert_eq!(reward_accumulated, (15000, Default::default())); + // Reward distribution works, now claim rewards + let bob_balance_before_claiming_boosting_reward = Balances::free_balance(BOB); + // Bob claim rewards + assert_ok!(SppModule::claim_rewards(RuntimeOrigin::signed(BOB), 0)); + assert_eq!( + last_event(), + mock::RuntimeEvent::Spp(crate::Event::ClaimRewards { + who: BOB, + pool: 0, + reward_currency_id: FungibleTokenId::NativeToken(0), + claimed_amount: 1000, + }) + ); + + // Bob free balance now will be bob_balance_before_claiming_boosting_reward + 1000 as claimed reward + assert_eq!( + Balances::free_balance(BOB), + bob_balance_before_claiming_boosting_reward + 1000 + ); + + // Bob try to claim again but getting no reward + assert_ok!(SppModule::claim_rewards(RuntimeOrigin::signed(BOB), 0)); + // Bob balance doesn't increase + assert_eq!( + Balances::free_balance(BOB), + bob_balance_before_claiming_boosting_reward + 1000 + ); + + // Move to era 3, now protocol distribute another 1000 NEER to incentivise boosters + MockRelayBlockNumberProvider::set(302); + SppModule::on_initialize(300); + + // Bob try to claim reward for new era + assert_ok!(SppModule::claim_rewards(RuntimeOrigin::signed(BOB), 0)); + // Bob balance should increase 2000 + assert_eq!( + Balances::free_balance(BOB), + bob_balance_before_claiming_boosting_reward + 2000 + ); + + // Charlie now boost pool 1 with 15000 (share 50% of reward with Bob) + assert_ok!(SppModule::boost( + RuntimeOrigin::signed(CHARLIE), + 1, + BoostInfo { + balance: 15000, + conviction: BoostingConviction::None + } + )); + // Charlie now should have 15000 shares in the pool + assert_eq!( + RewardsModule::shares_and_withdrawn_rewards(1, CHARLIE), + (15000, Default::default()) + ); + + // Network pool ledger should have total shares of 30,000 , 2000 total reward and claimed 2000 by + // Bob. However, as Charlie boosted, network pool inflate 15,000 shares, added 50% reward and 50% + // claimed reward to avoid dilution. + assert_eq!( + RewardsModule::pool_infos(0u32), + orml_rewards::PoolInfo { + total_shares: 30000, + rewards: vec![(FungibleTokenId::NativeToken(0), (4000, 4000))] + .into_iter() + .collect() + } + ); + + let charlie_balance_before_claiming_boosting_reward = Balances::free_balance(CHARLIE); + + // Move to era 4, now protocol distribute another 1000 NEER to incentivise boosters + MockRelayBlockNumberProvider::set(402); + SppModule::on_initialize(400); + + // Bob try to claim reward for new era + assert_ok!(SppModule::claim_rewards(RuntimeOrigin::signed(BOB), 0)); + // Bob balance should increase 500 as Charlie shares 50% rewards + assert_eq!( + Balances::free_balance(BOB), + bob_balance_before_claiming_boosting_reward + 2500 + ); + + // Charlie try to claim reward for new era + assert_ok!(SppModule::claim_rewards(RuntimeOrigin::signed(CHARLIE), 0)); + // Charlie balance should increase 500 + assert_eq!( + Balances::free_balance(CHARLIE), + charlie_balance_before_claiming_boosting_reward + 500 + ); + }); +} + +#[test] +fn reward_distribution_works() { + ExtBuilder::default() + .ksm_setup_for_alice_and_bob() + .build() + .execute_with(|| { + // Era config set up + // Current relaychain block is 102. + MockRelayBlockNumberProvider::set(102); + RelayChainCurrentEra::::put(1); + IterationLimit::::put(50); + UnlockDuration::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(1)); // Bump current staking round to 1 + CurrentStakingRound::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(1)); + // The correct set up era config is the last era block records is 101 with duration is 100 blocks + assert_ok!(SppModule::update_era_config( + RuntimeOrigin::signed(Admin::get()), + Some(101), + Some(100), + StakingRound::Era(1), + Some(Rate::saturating_from_rational(20, 100)) // Set reward rate per era is 20%. + )); + + assert_ok!(SppModule::create_pool( + RuntimeOrigin::signed(ALICE), + FungibleTokenId::NativeToken(1), + 50, + Rate::saturating_from_rational(5, 100) + )); + + let next_pool_id = NextPoolId::::get(); + assert_eq!(next_pool_id, 2); + assert_eq!( + Pool::::get(next_pool_id - 1).unwrap(), + PoolInfo:: { + creator: ALICE, + commission: Rate::saturating_from_rational(5, 100), + currency_id: FungibleTokenId::NativeToken(1), + max: 50 + } + ); + + assert_ok!(SppModule::deposit(RuntimeOrigin::signed(BOB), 1, 10000)); + // This is true because fee hasn't been set up. + assert_eq!(Tokens::accounts(BOB, FungibleTokenId::FungibleToken(1)).free, 10000); + + assert_eq!(PoolLedger::::get(1), 10000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 10000); + + // Boosting works + let bob_free_balance = Balances::free_balance(BOB); + assert_ok!(SppModule::boost( + RuntimeOrigin::signed(BOB), + 1, + BoostInfo { + balance: 15000, + conviction: BoostingConviction::None + } + )); + let boosting_of = BoostingOf::::get(BOB); + let some_record = BoostingRecord { + votes: vec![( + 1, + BoostInfo { + balance: 15000, + conviction: BoostingConviction::None, + }, + )], + prior: PriorLock(101, 15000), + }; + assert_eq!(boosting_of, some_record); + assert_eq!(Balances::usable_balance(&BOB), bob_free_balance - 15000); + let pool_1_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(1, BOB); + let network_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(0, BOB); + assert_eq!(pool_1_shared_rewards, (15000, Default::default())); + assert_eq!(network_shared_rewards, (15000, Default::default())); + + // Charlie boosted with 15000 Native token + assert_ok!(SppModule::boost( + RuntimeOrigin::signed(CHARLIE), + 1, + BoostInfo { + balance: 15000, + conviction: BoostingConviction::None + } + )); + // Charlie now should have 15000 shares in the pool + assert_eq!( + RewardsModule::shares_and_withdrawn_rewards(1, CHARLIE), + (15000, Default::default()) + ); + + // Move to era 2 + MockRelayBlockNumberProvider::set(202); + SppModule::on_initialize(200); + + assert_ok!(SppModule::handle_reward_distribution_to_pool_treasury(1, 2)); + let pool_treasury = SppModule::get_pool_treasury(1); + + assert_eq!( + Currencies::free_balance(FungibleTokenId::FungibleToken(1), &pool_treasury), + 20 + ); + + assert_eq!(Currencies::total_issuance(FungibleTokenId::FungibleToken(1)), 10020); + assert_eq!(PoolLedger::::get(1), 12000); + assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 12000); + }); +} diff --git a/pallets/spp/src/utils.rs b/pallets/spp/src/utils.rs new file mode 100644 index 000000000..f5c70a688 --- /dev/null +++ b/pallets/spp/src/utils.rs @@ -0,0 +1,205 @@ +// This file is part of Metaverse.Network & Bit.Country. + +// Copyright (C) 2020-2022 Metaverse.Network & Bit.Country . +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; +use sp_runtime::{ + traits::{Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, IntegerSquareRoot, Saturating, Zero}, + Permill, RuntimeDebug, +}; +use sp_std::vec::Vec; + +use primitives::bounded::{FractionalRate, Rate}; +use primitives::{FungibleTokenId, PoolId}; + +// Helper methods to compute the issuance rate for undeployed land. + +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct PoolInfo { + pub creator: AccountId, + pub commission: Rate, + /// Currency id of the pool + pub currency_id: FungibleTokenId, + /// Max nft rewards + pub max: u32, +} + +/// Amount of votes and capital placed in delegation for an account. +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct BoostingDelegations { + /// The number of votes (this is post-conviction). + pub votes: Balance, + /// The amount of raw capital, used for the turnout. + pub capital: Balance, +} + +/// A value denoting the strength of conviction of a vote. +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo)] +pub enum BoostingConviction { + /// 0.1x votes, unlocked. + None, + /// 1x votes, locked for an enactment period following a successful vote. + Locked1x, + /// 2x votes, locked for 2x enactment periods following a successful vote. + Locked2x, + /// 3x votes, locked for 4x... + Locked3x, + /// 4x votes, locked for 8x... + Locked4x, + /// 5x votes, locked for 16x... + Locked5x, + /// 6x votes, locked for 32x... + Locked6x, +} + +impl Default for BoostingConviction { + fn default() -> Self { + BoostingConviction::None + } +} + +impl From for u8 { + fn from(c: BoostingConviction) -> u8 { + match c { + BoostingConviction::None => 0, + BoostingConviction::Locked1x => 1, + BoostingConviction::Locked2x => 2, + BoostingConviction::Locked3x => 3, + BoostingConviction::Locked4x => 4, + BoostingConviction::Locked5x => 5, + BoostingConviction::Locked6x => 6, + } + } +} + +impl TryFrom for BoostingConviction { + type Error = (); + fn try_from(i: u8) -> Result { + Ok(match i { + 0 => BoostingConviction::None, + 1 => BoostingConviction::Locked1x, + 2 => BoostingConviction::Locked2x, + 3 => BoostingConviction::Locked3x, + 4 => BoostingConviction::Locked4x, + 5 => BoostingConviction::Locked5x, + 6 => BoostingConviction::Locked6x, + _ => return Err(()), + }) + } +} + +impl BoostingConviction { + /// The amount of time (in number of periods) that our conviction implies a successful voter's + /// balance should be locked for. + pub fn lock_periods(self) -> u32 { + match self { + BoostingConviction::None => 0, + BoostingConviction::Locked1x => 1, + BoostingConviction::Locked2x => 2, + BoostingConviction::Locked3x => 4, + BoostingConviction::Locked4x => 8, + BoostingConviction::Locked5x => 16, + BoostingConviction::Locked6x => 32, + } + } + + /// The votes of a voter of the given `balance` with our conviction. + pub fn votes + Zero + Copy + CheckedMul + CheckedDiv + Bounded>( + self, + capital: B, + ) -> BoostingDelegations { + let votes = match self { + BoostingConviction::None => capital.checked_div(&10u8.into()).unwrap_or_else(Zero::zero), + x => capital.checked_mul(&u8::from(x).into()).unwrap_or_else(B::max_value), + }; + BoostingDelegations { votes, capital } + } +} + +impl Bounded for BoostingConviction { + fn min_value() -> Self { + BoostingConviction::None + } + fn max_value() -> Self { + BoostingConviction::Locked6x + } +} + +#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct BoostInfo { + pub(crate) balance: Balance, + pub(crate) conviction: BoostingConviction, +} + +impl BoostInfo { + /// Returns `Some` of the lock periods that the account is locked for, assuming that the + /// referendum passed if `approved` is `true`. + pub fn get_locked_period(self) -> (u32, Balance) { + return (self.conviction.lock_periods(), self.balance); + } + + pub fn add(&mut self, balance: Balance) -> Option<()> { + self.balance.saturating_add(balance.into()); + Some(()) + } +} + +/// A "prior" lock, i.e. a lock for some now-forgotten reason. +#[derive(Encode, Decode, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo)] +pub struct PriorLock(pub(crate) BlockNumber, pub(crate) Balance); + +impl PriorLock { + /// Accumulates an additional lock. + pub fn accumulate(&mut self, until: BlockNumber, amount: Balance) { + self.0 = self.0.max(until); + self.1 = self.1.max(amount); + } + + pub fn locked(&self) -> Balance { + self.1 + } + + pub fn update(&mut self, now: BlockNumber) { + if now >= self.0 { + self.0 = Zero::zero(); + self.1 = Zero::zero(); + } + } +} + +#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct BoostingRecord { + pub(crate) votes: Vec<(PoolId, BoostInfo)>, + pub(crate) prior: PriorLock, +} + +impl BoostingRecord { + pub fn update(&mut self, now: BlockNumber) { + self.prior.update(now); + } + + /// The amount of this account's balance that much currently be locked due to voting. + pub fn locked_balance(&self) -> Balance { + self.votes + .iter() + .map(|i| i.1.balance) + .fold(self.prior.locked(), |a, i| a.max(i)) + } +} diff --git a/pallets/spp/src/weights.rs b/pallets/spp/src/weights.rs new file mode 100644 index 000000000..f848ec15c --- /dev/null +++ b/pallets/spp/src/weights.rs @@ -0,0 +1,699 @@ +// This file is part of Metaverse.Network & Bit.Country. + +// Copyright (C) 2020-2022 Metaverse.Network & Bit.Country . +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for estate +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-18, STEPS: `20`, REPEAT: 10, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// ./target/release/metaverse-node +// benchmark +// pallet +// --execution=wasm +// --wasm-execution=compiled +// --pallet +// estate +// --extrinsic +// * +// --steps +// 20 +// --repeat +// 10 +// --template=./template/weight-template.hbs +// --output +// ./pallets/estate/src/weights.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for estate. +pub trait WeightInfo { fn mint_land() -> Weight; fn mint_lands() -> Weight; fn transfer_land() -> Weight; fn mint_estate() -> Weight; fn dissolve_estate() -> Weight; fn add_land_unit_to_estate() -> Weight; fn remove_land_unit_from_estate() -> Weight; fn create_estate() -> Weight; fn transfer_estate() -> Weight; fn issue_undeployed_land_blocks() -> Weight; fn freeze_undeployed_land_blocks() -> Weight; fn unfreeze_undeployed_land_blocks() -> Weight; fn approve_undeployed_land_blocks() -> Weight; fn unapprove_undeployed_land_blocks() -> Weight; fn transfer_undeployed_land_blocks() -> Weight; fn deploy_land_block() -> Weight; fn burn_undeployed_land_blocks() -> Weight; fn create_lease_offer() -> Weight; fn accept_lease_offer() -> Weight; fn cancel_lease() -> Weight; fn remove_expired_lease() -> Weight; fn remove_lease_offer() -> Weight; fn collect_rent() -> Weight; fn on_initialize() -> Weight;} + +/// Weights for estate using the for collator node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { // Storage: Estate LandUnits (r:1 w:1) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: Metaverse Metaverses (r:1 w:0) + // Proof Skipped: Metaverse Metaverses (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: OrmlNFT NextTokenId (r:1 w:1) + // Proof Skipped: OrmlNFT NextTokenId (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:1) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: Estate AllLandUnitsCount (r:1 w:1) + // Proof Skipped: Estate AllLandUnitsCount (max_values: Some(1), max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:1) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn mint_land() -> Weight { + // Proof Size summary in bytes: + // Measured: `2339` + // Estimated: `36660` + // Minimum execution time: 56_882 nanoseconds. + Weight::from_parts(59_273_000, 36660) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + // Storage: Estate LandUnits (r:2 w:2) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: Metaverse Metaverses (r:1 w:0) + // Proof Skipped: Metaverse Metaverses (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: OrmlNFT NextTokenId (r:1 w:1) + // Proof Skipped: OrmlNFT NextTokenId (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:2 w:2) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:1) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: Estate AllLandUnitsCount (r:1 w:1) + // Proof Skipped: Estate AllLandUnitsCount (max_values: Some(1), max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:2) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn mint_lands() -> Weight { + // Proof Size summary in bytes: + // Measured: `2339` + // Estimated: `41610` + // Minimum execution time: 82_026 nanoseconds. + Weight::from_parts(83_541_000, 41610) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(10)) + } + // Storage: Estate LandUnits (r:1 w:1) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT StackableCollection (r:1 w:0) + // Proof Skipped: OrmlNFT StackableCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:0) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:2) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn transfer_land() -> Weight { + // Proof Size summary in bytes: + // Measured: `1915` + // Estimated: `28255` + // Minimum execution time: 46_193 nanoseconds. + Weight::from_parts(47_423_000, 28255) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Estate NextEstateId (r:1 w:1) + // Proof Skipped: Estate NextEstateId (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Metaverse Metaverses (r:1 w:0) + // Proof Skipped: Metaverse Metaverses (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: OrmlNFT NextTokenId (r:1 w:1) + // Proof Skipped: OrmlNFT NextTokenId (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:1) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: Estate LandUnits (r:1 w:1) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: Estate AllLandUnitsCount (r:1 w:1) + // Proof Skipped: Estate AllLandUnitsCount (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate AllEstatesCount (r:1 w:1) + // Proof Skipped: Estate AllEstatesCount (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate EstateOwner (r:0 w:1) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Estate Estates (r:0 w:1) + // Proof Skipped: Estate Estates (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:1) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn mint_estate() -> Weight { + // Proof Size summary in bytes: + // Measured: `2356` + // Estimated: `47210` + // Minimum execution time: 62_931 nanoseconds. + Weight::from_parts(64_479_000, 47210) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(11)) + } + // Storage: Estate EstateOwner (r:1 w:1) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:2 w:2) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Estate Estates (r:1 w:1) + // Proof Skipped: Estate Estates (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:2 w:2) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: Estate AllEstatesCount (r:1 w:1) + // Proof Skipped: Estate AllEstatesCount (max_values: Some(1), max_size: None, mode: Measured) + // Storage: System Account (r:2 w:2) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate LandUnits (r:1 w:1) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: Metaverse Metaverses (r:1 w:0) + // Proof Skipped: Metaverse Metaverses (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT NextTokenId (r:1 w:1) + // Proof Skipped: OrmlNFT NextTokenId (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:2) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn dissolve_estate() -> Weight { + // Proof Size summary in bytes: + // Measured: `3118` + // Estimated: `67224` + // Minimum execution time: 99_063 nanoseconds. + Weight::from_parts(110_008_000, 67224) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(13)) + } + // Storage: Estate EstateOwner (r:1 w:0) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:2 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Estate Estates (r:1 w:1) + // Proof Skipped: Estate Estates (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate LandUnits (r:1 w:1) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:1) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:1) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn add_land_unit_to_estate() -> Weight { + // Proof Size summary in bytes: + // Measured: `2593` + // Estimated: `38079` + // Minimum execution time: 69_608 nanoseconds. + Weight::from_parts(71_706_000, 38079) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: Estate EstateOwner (r:1 w:0) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:2 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Estate Estates (r:1 w:1) + // Proof Skipped: Estate Estates (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:2 w:2) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate LandUnits (r:1 w:1) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: Metaverse Metaverses (r:1 w:0) + // Proof Skipped: Metaverse Metaverses (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT NextTokenId (r:1 w:1) + // Proof Skipped: OrmlNFT NextTokenId (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:1) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:1) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn remove_land_unit_from_estate() -> Weight { + // Proof Size summary in bytes: + // Measured: `3027` + // Estimated: `60226` + // Minimum execution time: 86_578 nanoseconds. + Weight::from_parts(90_257_000, 60226) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(8)) + } + // Storage: System Account (r:2 w:2) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate NextEstateId (r:1 w:1) + // Proof Skipped: Estate NextEstateId (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Metaverse Metaverses (r:1 w:0) + // Proof Skipped: Metaverse Metaverses (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT NextTokenId (r:1 w:1) + // Proof Skipped: OrmlNFT NextTokenId (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:3 w:3) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:2 w:2) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: Estate LandUnits (r:2 w:2) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: Estate AllEstatesCount (r:1 w:1) + // Proof Skipped: Estate AllEstatesCount (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate EstateOwner (r:0 w:1) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Estate Estates (r:0 w:1) + // Proof Skipped: Estate Estates (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:3) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn create_estate() -> Weight { + // Proof Size summary in bytes: + // Measured: `3192` + // Estimated: `66058` + // Minimum execution time: 121_302 nanoseconds. + Weight::from_parts(131_741_000, 66058) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(17)) + } + // Storage: Estate EstateOwner (r:1 w:1) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Estate Estates (r:1 w:0) + // Proof Skipped: Estate Estates (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeases (r:1 w:0) + // Proof Skipped: Estate EstateLeases (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT StackableCollection (r:1 w:0) + // Proof Skipped: OrmlNFT StackableCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:0) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:2) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn transfer_estate() -> Weight { + // Proof Size summary in bytes: + // Measured: `2025` + // Estimated: `38025` + // Minimum execution time: 52_643 nanoseconds. + Weight::from_parts(54_808_000, 38025) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate NextUndeployedLandBlockId (r:1 w:1) + // Proof Skipped: Estate NextUndeployedLandBlockId (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate TotalUndeployedLandUnit (r:1 w:1) + // Proof Skipped: Estate TotalUndeployedLandUnit (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate UndeployedLandBlocks (r:0 w:20) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: Estate UndeployedLandBlocksOwner (r:0 w:20) + // Proof Skipped: Estate UndeployedLandBlocksOwner (max_values: None, max_size: None, mode: Measured) + fn issue_undeployed_land_blocks() -> Weight { + // Proof Size summary in bytes: + // Measured: `1558` + // Estimated: `9825` + // Minimum execution time: 159_581 nanoseconds. + Weight::from_parts(162_875_000, 9825) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(43)) + } + // Storage: Estate UndeployedLandBlocks (r:1 w:1) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + fn freeze_undeployed_land_blocks() -> Weight { + // Proof Size summary in bytes: + // Measured: `1442` + // Estimated: `7834` + // Minimum execution time: 21_762 nanoseconds. + Weight::from_parts(22_833_000, 7834) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Estate UndeployedLandBlocks (r:1 w:1) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + fn unfreeze_undeployed_land_blocks() -> Weight { + // Proof Size summary in bytes: + // Measured: `1442` + // Estimated: `7834` + // Minimum execution time: 20_225 nanoseconds. + Weight::from_parts(21_423_000, 7834) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Estate UndeployedLandBlocks (r:1 w:1) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + fn approve_undeployed_land_blocks() -> Weight { + // Proof Size summary in bytes: + // Measured: `1442` + // Estimated: `7834` + // Minimum execution time: 20_246 nanoseconds. + Weight::from_parts(21_819_000, 7834) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Estate UndeployedLandBlocks (r:1 w:1) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + fn unapprove_undeployed_land_blocks() -> Weight { + // Proof Size summary in bytes: + // Measured: `1475` + // Estimated: `7900` + // Minimum execution time: 20_346 nanoseconds. + Weight::from_parts(21_237_000, 7900) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate UndeployedLandBlocks (r:1 w:1) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: Estate UndeployedLandBlocksOwner (r:0 w:2) + // Proof Skipped: Estate UndeployedLandBlocksOwner (max_values: None, max_size: None, mode: Measured) + fn transfer_undeployed_land_blocks() -> Weight { + // Proof Size summary in bytes: + // Measured: `2040` + // Estimated: `13673` + // Minimum execution time: 38_679 nanoseconds. + Weight::from_parts(41_173_000, 13673) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: Metaverse MetaverseOwner (r:1 w:0) + // Proof Skipped: Metaverse MetaverseOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Estate UndeployedLandBlocks (r:1 w:1) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:2 w:2) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate LandUnits (r:1 w:1) + // Proof Skipped: Estate LandUnits (max_values: None, max_size: None, mode: Measured) + // Storage: Metaverse Metaverses (r:1 w:0) + // Proof Skipped: Metaverse Metaverses (max_values: None, max_size: None, mode: Measured) + // Storage: Nft LockedCollection (r:1 w:0) + // Proof Skipped: Nft LockedCollection (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT NextTokenId (r:1 w:1) + // Proof Skipped: OrmlNFT NextTokenId (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Classes (r:1 w:1) + // Proof Skipped: OrmlNFT Classes (max_values: None, max_size: None, mode: Measured) + // Storage: Estate AllLandUnitsCount (r:1 w:1) + // Proof Skipped: Estate AllLandUnitsCount (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate TotalUndeployedLandUnit (r:1 w:1) + // Proof Skipped: Estate TotalUndeployedLandUnit (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate UndeployedLandBlocksOwner (r:0 w:1) + // Proof Skipped: Estate UndeployedLandBlocksOwner (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT TokensByOwner (r:0 w:1) + // Proof Skipped: OrmlNFT TokensByOwner (max_values: None, max_size: None, mode: Measured) + fn deploy_land_block() -> Weight { + // Proof Size summary in bytes: + // Measured: `2802` + // Estimated: `64897` + // Minimum execution time: 91_163 nanoseconds. + Weight::from_parts(100_659_000, 64897) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(11)) + } + // Storage: Estate UndeployedLandBlocks (r:1 w:1) + // Proof Skipped: Estate UndeployedLandBlocks (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: Estate TotalUndeployedLandUnit (r:1 w:1) + // Proof Skipped: Estate TotalUndeployedLandUnit (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Estate UndeployedLandBlocksOwner (r:0 w:1) + // Proof Skipped: Estate UndeployedLandBlocksOwner (max_values: None, max_size: None, mode: Measured) + fn burn_undeployed_land_blocks() -> Weight { + // Proof Size summary in bytes: + // Measured: `1304` + // Estimated: `10661` + // Minimum execution time: 23_162 nanoseconds. + Weight::from_parts(32_196_000, 10661) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: Estate EstateOwner (r:1 w:0) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:0) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeaseOffers (r:2 w:1) + // Proof Skipped: Estate EstateLeaseOffers (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeases (r:1 w:0) + // Proof Skipped: Estate EstateLeases (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn create_lease_offer() -> Weight { + // Proof Size summary in bytes: + // Measured: `1986` + // Estimated: `27383` + // Minimum execution time: 94_497 nanoseconds. + Weight::from_parts(98_902_000, 27383) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Estate EstateLeases (r:1 w:1) + // Proof Skipped: Estate EstateLeases (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateOwner (r:1 w:0) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: Auction ItemsInAuction (r:1 w:0) + // Proof Skipped: Auction ItemsInAuction (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeaseOffers (r:1 w:1) + // Proof Skipped: Estate EstateLeaseOffers (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: Estate EstateLeasors (r:0 w:1) + // Proof Skipped: Estate EstateLeasors (max_values: None, max_size: None, mode: Measured) + fn accept_lease_offer() -> Weight { + // Proof Size summary in bytes: + // Measured: `2311` + // Estimated: `28844` + // Minimum execution time: 53_956 nanoseconds. + Weight::from_parts(57_019_000, 28844) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: Estate EstateLeases (r:1 w:1) + // Proof Skipped: Estate EstateLeases (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeasors (r:1 w:1) + // Proof Skipped: Estate EstateLeasors (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateOwner (r:1 w:0) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn cancel_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `4017` + // Estimated: `28571` + // Minimum execution time: 55_907 nanoseconds. + Weight::from_parts(57_720_000, 28571) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Estate EstateLeases (r:1 w:1) + // Proof Skipped: Estate EstateLeases (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeasors (r:1 w:1) + // Proof Skipped: Estate EstateLeasors (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateOwner (r:1 w:0) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:1) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn remove_expired_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `4017` + // Estimated: `28571` + // Minimum execution time: 56_789 nanoseconds. + Weight::from_parts(57_681_000, 28571) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Estate EstateLeaseOffers (r:1 w:1) + // Proof Skipped: Estate EstateLeaseOffers (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn remove_lease_offer() -> Weight { + // Proof Size summary in bytes: + // Measured: `3250` + // Estimated: `8328` + // Minimum execution time: 33_999 nanoseconds. + Weight::from_parts(41_923_000, 8328) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Estate EstateOwner (r:1 w:0) + // Proof Skipped: Estate EstateOwner (max_values: None, max_size: None, mode: Measured) + // Storage: OrmlNFT Tokens (r:1 w:0) + // Proof Skipped: OrmlNFT Tokens (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeasors (r:1 w:0) + // Proof Skipped: Estate EstateLeasors (max_values: None, max_size: None, mode: Measured) + // Storage: Estate EstateLeases (r:1 w:1) + // Proof Skipped: Estate EstateLeases (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:1 w:1) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn collect_rent() -> Weight { + // Proof Size summary in bytes: + // Measured: `4017` + // Estimated: `28571` + // Minimum execution time: 51_821 nanoseconds. + Weight::from_parts(53_171_000, 28571) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + fn on_initialize() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 176 nanoseconds. + Weight::from_parts(191_000, 0) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { fn mint_land() -> Weight { + Weight::from_parts(59_273_000, 36660) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(7)) + } + fn mint_lands() -> Weight { + Weight::from_parts(83_541_000, 41610) + .saturating_add(RocksDbWeight::get().reads(10)) + .saturating_add(RocksDbWeight::get().writes(10)) + } + fn transfer_land() -> Weight { + Weight::from_parts(47_423_000, 28255) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + fn mint_estate() -> Weight { + Weight::from_parts(64_479_000, 47210) + .saturating_add(RocksDbWeight::get().reads(10)) + .saturating_add(RocksDbWeight::get().writes(11)) + } + fn dissolve_estate() -> Weight { + Weight::from_parts(110_008_000, 67224) + .saturating_add(RocksDbWeight::get().reads(14)) + .saturating_add(RocksDbWeight::get().writes(13)) + } + fn add_land_unit_to_estate() -> Weight { + Weight::from_parts(71_706_000, 38079) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + fn remove_land_unit_from_estate() -> Weight { + Weight::from_parts(90_257_000, 60226) + .saturating_add(RocksDbWeight::get().reads(12)) + .saturating_add(RocksDbWeight::get().writes(8)) + } + fn create_estate() -> Weight { + Weight::from_parts(131_741_000, 66058) + .saturating_add(RocksDbWeight::get().reads(14)) + .saturating_add(RocksDbWeight::get().writes(17)) + } + fn transfer_estate() -> Weight { + Weight::from_parts(54_808_000, 38025) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + fn issue_undeployed_land_blocks() -> Weight { + Weight::from_parts(162_875_000, 9825) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(43)) + } + fn freeze_undeployed_land_blocks() -> Weight { + Weight::from_parts(22_833_000, 7834) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + fn unfreeze_undeployed_land_blocks() -> Weight { + Weight::from_parts(21_423_000, 7834) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + fn approve_undeployed_land_blocks() -> Weight { + Weight::from_parts(21_819_000, 7834) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + fn unapprove_undeployed_land_blocks() -> Weight { + Weight::from_parts(21_237_000, 7900) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + fn transfer_undeployed_land_blocks() -> Weight { + Weight::from_parts(41_173_000, 13673) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + fn deploy_land_block() -> Weight { + Weight::from_parts(100_659_000, 64897) + .saturating_add(RocksDbWeight::get().reads(13)) + .saturating_add(RocksDbWeight::get().writes(11)) + } + fn burn_undeployed_land_blocks() -> Weight { + Weight::from_parts(32_196_000, 10661) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + fn create_lease_offer() -> Weight { + Weight::from_parts(98_902_000, 27383) + .saturating_add(RocksDbWeight::get().reads(7)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + fn accept_lease_offer() -> Weight { + Weight::from_parts(57_019_000, 28844) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(5)) + } + fn cancel_lease() -> Weight { + Weight::from_parts(57_720_000, 28571) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + fn remove_expired_lease() -> Weight { + Weight::from_parts(57_681_000, 28571) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + fn remove_lease_offer() -> Weight { + Weight::from_parts(41_923_000, 8328) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + fn collect_rent() -> Weight { + Weight::from_parts(53_171_000, 28571) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + fn on_initialize() -> Weight { + Weight::from_parts(191_000, 0) + } +} diff --git a/primitives/metaverse/src/bounded.rs b/primitives/metaverse/src/bounded.rs new file mode 100644 index 000000000..991640223 --- /dev/null +++ b/primitives/metaverse/src/bounded.rs @@ -0,0 +1,240 @@ +// This file is part of Metaverse.Network & Bit.Country. + +// Copyright (C) 2020-2022 Metaverse.Network & Bit.Country . +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::traits::Get; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize}; +use sp_runtime::{ + traits::{CheckedSub, One, Zero}, + FixedPointNumber, FixedU128, RuntimeDebug, +}; +use sp_std::{marker::PhantomData, prelude::*, result::Result}; + +use crate::{Balance, BlockNumber}; + +pub type Rate = FixedU128; + +/// The bounded type errors. +#[derive(RuntimeDebug, PartialEq, Eq)] +pub enum Error { + /// The value is out of bound. + OutOfBounds, + /// The change diff exceeds the max absolute value. + ExceedMaxChangeAbs, +} +/// An abstract definition of bounded type. The type is within the range of `Range` +/// and while update the inner value, the max absolute value of the diff is `MaxChangeAbs`. +/// The `Default` value is minimum value of the range. +#[cfg_attr(feature = "std", derive(Serialize), serde(transparent))] +#[derive(Encode, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, TypeInfo, MaxEncodedLen, RuntimeDebug)] +#[scale_info(skip_type_params(Range, MaxChangeAbs))] +pub struct BoundedType( + T, + #[cfg_attr(feature = "std", serde(skip_serializing))] PhantomData<(Range, MaxChangeAbs)>, +); + +impl, MaxChangeAbs: Get> Decode + for BoundedType +{ + fn decode(input: &mut I) -> Result { + let inner = T::decode(input)?; + Self::try_from(inner).map_err(|_| "BoundedType: value out of bounds".into()) + } +} + +#[cfg(feature = "std")] +impl<'de, T, Range, MaxChangeAbs> Deserialize<'de> for BoundedType +where + T: Encode + Decode + CheckedSub + PartialOrd + Deserialize<'de>, + Range: Get<(T, T)>, + MaxChangeAbs: Get, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value: T = T::deserialize(deserializer)?; + Self::try_from(value).map_err(|_| SerdeError::custom("out of bounds")) + } +} + +impl, MaxChangeAbs: Get> Default + for BoundedType +{ + fn default() -> Self { + let (min, _) = Range::get(); + Self(min, PhantomData) + } +} + +impl BoundedType +where + T: Encode + Decode + CheckedSub + PartialOrd, + Range: Get<(T, T)>, + MaxChangeAbs: Get, +{ + /// Try to create a new instance of `BoundedType`. Returns `Err` if out of bound. + pub fn try_from(value: T) -> Result { + let (min, max) = Range::get(); + if value < min || value > max { + return Err(Error::OutOfBounds); + } + Ok(Self(value, PhantomData)) + } + + /// Set the inner value. Returns `Err` if out of bound or the diff with current value exceeds + /// the max absolute value. + pub fn try_set(&mut self, value: T) -> Result<(), Error> { + let (min, max) = Range::get(); + let max_change_abs = MaxChangeAbs::get(); + let old_value = &self.0; + if value < min || value > max { + return Err(Error::OutOfBounds); + } + + let abs = if value > *old_value { + value + .checked_sub(old_value) + .expect("greater number subtracting smaller one can't underflow; qed") + } else { + old_value + .checked_sub(&value) + .expect("greater number subtracting smaller one can't underflow; qed") + }; + if abs > max_change_abs { + return Err(Error::ExceedMaxChangeAbs); + } + + self.0 = value; + Ok(()) + } + + pub fn into_inner(self) -> T { + self.0 + } + + pub fn inner(&self) -> &T { + &self.0 + } +} + +/// Fractional range between `Rate::zero()` and `Rate::one()`. +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] +pub struct Fractional; +impl Get<(Rate, Rate)> for Fractional { + fn get() -> (Rate, Rate) { + (Rate::zero(), Rate::one()) + } +} + +/// Maximum absolute change is 1/5. +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] +pub struct OneFifth; +impl Get for OneFifth { + fn get() -> Rate { + Rate::saturating_from_rational(1, 5) + } +} + +pub type BoundedRate = BoundedType; + +/// Fractional rate. +/// +/// The range is between 0 to 1, and max absolute value of change diff is 1/5. +pub type FractionalRate = BoundedRate; + +pub type BoundedBalance = BoundedType; + +pub type BoundedBlockNumber = BoundedType; + +#[cfg(test)] +mod tests { + use frame_support::{assert_err, assert_ok}; + + use super::*; + + #[test] + fn fractional_rate_works() { + assert_err!( + FractionalRate::try_from(Rate::from_rational(11, 10)), + Error::OutOfBounds + ); + + let mut rate = FractionalRate::try_from(Rate::from_rational(8, 10)).unwrap(); + assert_ok!(rate.try_set(Rate::from_rational(10, 10))); + assert_err!(rate.try_set(Rate::from_rational(11, 10)), Error::OutOfBounds); + assert_err!(rate.try_set(Rate::from_rational(79, 100)), Error::ExceedMaxChangeAbs); + + assert_eq!(FractionalRate::default().into_inner(), Rate::zero()); + } + + #[test] + fn encode_decode_works() { + let rate = FractionalRate::try_from(Rate::from_rational(8, 10)).unwrap(); + let encoded = rate.encode(); + assert_eq!(FractionalRate::decode(&mut &encoded[..]).unwrap(), rate); + + assert_eq!(encoded, Rate::from_rational(8, 10).encode()); + } + + #[test] + fn decode_fails_if_out_of_bounds() { + let bad_rate = BoundedType::(Rate::from_rational(11, 10), PhantomData); + let bad_rate_encoded = bad_rate.encode(); + assert_err!( + FractionalRate::decode(&mut &bad_rate_encoded[..]), + "BoundedType: value out of bounds" + ); + } + + #[test] + fn ser_de_works() { + let rate = FractionalRate::try_from(Rate::from_rational(8, 10)).unwrap(); + assert_eq!(serde_json::json!(&rate).to_string(), r#""800000000000000000""#); + + let deserialized: FractionalRate = serde_json::from_str(r#""800000000000000000""#).unwrap(); + assert_eq!(deserialized, rate); + } + + #[test] + fn deserialize_fails_if_out_of_bounds() { + let failed: Result = serde_json::from_str(r#""1100000000000000000""#); + match failed { + Err(msg) => assert_eq!(msg.to_string(), "out of bounds"), + _ => panic!("should fail"), + } + } + + #[test] + fn bounded_type_default_is_range_min() { + #[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] + pub struct OneToTwo; + impl Get<(Rate, Rate)> for OneToTwo { + fn get() -> (Rate, Rate) { + (Rate::one(), Rate::from_rational(2, 1)) + } + } + + type BoundedRateOneToTwo = BoundedRate; + + assert_eq!(BoundedRateOneToTwo::default().into_inner(), Rate::one()); + } +} diff --git a/primitives/metaverse/src/lib.rs b/primitives/metaverse/src/lib.rs index c149368ba..ad1544bc9 100644 --- a/primitives/metaverse/src/lib.rs +++ b/primitives/metaverse/src/lib.rs @@ -34,6 +34,7 @@ use sp_std::prelude::*; use sp_std::vec::Vec; use xcm::v3::MultiLocation; +pub mod bounded; pub mod continuum; pub mod estate; pub mod evm; @@ -104,6 +105,8 @@ pub type ReferendumId = u64; pub type LandId = u64; /// EstateId pub type EstateId = u64; +/// Number of era on relaychain +pub type EraIndex = u32; /// Social Token Id type pub type TokenId = u64; /// Undeployed LandBlock Id type @@ -132,6 +135,8 @@ pub type TrieIndex = u32; pub type CampaignId = u32; /// Index used for claim rewrads for merkle root campaigns pub type ClaimId = u64; +/// Pool Id to keep track of each pool +pub type PoolId = u32; /// Land Token Class Id pub const LAND_CLASS_ID: ClassId = 15; @@ -192,7 +197,7 @@ impl FungibleTokenId { pub fn decimals(&self) -> u8 { match self { FungibleTokenId::NativeToken(0) => 18, // Native token - FungibleTokenId::NativeToken(1) | FungibleTokenId::NativeToken(2) | FungibleTokenId::Stable(0) => 12, // KSM KAR KUSD + FungibleTokenId::NativeToken(1) | FungibleTokenId::NativeToken(2) | FungibleTokenId::Stable(0) => 12, // KSM FungibleTokenId::MiningResource(0) => 18, _ => 18, } @@ -460,3 +465,53 @@ pub struct CampaignInfo, } +// For multiple time calculation type +#[derive(Encode, Decode, Clone, RuntimeDebug, Eq, TypeInfo, MaxEncodedLen)] +pub enum StakingRound { + Era(#[codec(compact)] u32), + Round(#[codec(compact)] u32), + Epoch(#[codec(compact)] u32), + Hour(#[codec(compact)] u32), +} + +impl Default for StakingRound { + fn default() -> Self { + StakingRound::Era(0u32) + } +} + +impl PartialEq for StakingRound { + fn eq(&self, other: &Self) -> bool { + match (&self, other) { + (Self::Era(a), Self::Era(b)) => a.eq(b), + (Self::Round(a), Self::Round(b)) => a.eq(b), + (Self::Epoch(a), Self::Epoch(b)) => a.eq(b), + (Self::Hour(a), Self::Hour(b)) => a.eq(b), + _ => false, + } + } +} + +impl Ord for StakingRound { + fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { + match (&self, other) { + (Self::Era(a), Self::Era(b)) => a.cmp(b), + (Self::Round(a), Self::Round(b)) => a.cmp(b), + (Self::Epoch(a), Self::Epoch(b)) => a.cmp(b), + (Self::Hour(a), Self::Hour(b)) => a.cmp(b), + _ => sp_std::cmp::Ordering::Less, + } + } +} + +impl PartialOrd for StakingRound { + fn partial_cmp(&self, other: &Self) -> Option { + match (&self, other) { + (Self::Era(a), Self::Era(b)) => Some(a.cmp(b)), + (Self::Round(a), Self::Round(b)) => Some(a.cmp(b)), + (Self::Epoch(a), Self::Epoch(b)) => Some(a.cmp(b)), + (Self::Hour(a), Self::Hour(b)) => Some(a.cmp(b)), + _ => None, + } + } +} diff --git a/runtime/common/src/currencies.rs b/runtime/common/src/currencies.rs index 540aae788..3a9fc1e6e 100644 --- a/runtime/common/src/currencies.rs +++ b/runtime/common/src/currencies.rs @@ -1,24 +1,23 @@ use frame_support::pallet_prelude::Get; use frame_support::traits::{Currency, OriginTrait}; use orml_traits::{BasicCurrency, MultiCurrency as MultiCurrencyTrait}; -use pallet_evm::Context; + use pallet_evm::{ - AddressMapping, ExitRevert, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, - PrecompileResult, PrecompileSet, + ExitRevert, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet, }; use sp_core::{H160, U256}; -use sp_runtime::traits::{AccountIdConversion, Dispatchable, Zero}; +use sp_runtime::traits::Dispatchable; use sp_std::{marker::PhantomData, prelude::*}; use evm_mapping::AddressMapping as EvmMapping; -use evm_mapping::EvmAddressMapping; + use precompile_utils::data::{Address, EvmData, EvmDataWriter}; use precompile_utils::handle::PrecompileHandleExt; use precompile_utils::modifier::FunctionModifier; use precompile_utils::prelude::RuntimeHelper; use precompile_utils::{succeed, EvmResult}; use primitives::evm::{Erc20Mapping, Output}; -use primitives::{evm, AssetIds, AssetMetadata, Balance, FungibleTokenId}; +use primitives::{AssetIds, Balance, FungibleTokenId}; #[precompile_utils_macro::generate_function_selector] #[derive(Debug, PartialEq)] @@ -114,7 +113,7 @@ where })) } - fn is_precompile(&self, address: H160) -> bool { + fn is_precompile(&self, _address: H160) -> bool { todo!() } } @@ -143,7 +142,7 @@ where if let Some(currency_id) = Runtime::decode_evm_address(address) { log::debug!(target: "evm", "multicurrency: currency id: {:?}", currency_id); - let result = { + let _result = { let selector = match handle.read_selector() { Ok(selector) => selector, Err(e) => return Err(e), @@ -193,7 +192,10 @@ where >, BalanceOf: TryFrom + Into + EvmData, { - fn not_supported(currency_id: FungibleTokenId, handle: &mut impl PrecompileHandle) -> EvmResult { + fn not_supported( + _currency_id: FungibleTokenId, + _handle: &mut impl PrecompileHandle, + ) -> EvmResult { Err(PrecompileFailure::Error { exit_status: pallet_evm::ExitError::Other("not supported".into()), }) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 7dd0aa42d..56fc2368e 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -16,22 +16,17 @@ // limitations under the License. #![cfg_attr(not(feature = "std"), no_std)] -use codec::Encode; -use cumulus_pallet_parachain_system::CheckAssociatedRelayNumber; use frame_support::{ traits::Get, weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, }; use orml_traits::currency::MutationHooks; -use polkadot_parachain::primitives::RelayChainBlockNumber; + use sp_runtime::{FixedPointNumber, FixedU128}; use sp_std::{marker::PhantomData, prelude::*}; use xcm::latest::prelude::*; use xcm_builder::TakeRevenue; -use xcm_executor::{ - traits::{DropAssets, WeightTrader}, - Assets, -}; +use xcm_executor::{traits::WeightTrader, Assets}; use primitives::BuyWeightRate; diff --git a/runtime/common/src/mock.rs b/runtime/common/src/mock.rs index 2fefd33be..dbe1ecb1c 100644 --- a/runtime/common/src/mock.rs +++ b/runtime/common/src/mock.rs @@ -1,22 +1,19 @@ -use std::ptr::hash; - use frame_support::{ construct_runtime, dispatch::DispatchResult, parameter_types, - traits::{AsEnsureOriginWithArg, Everything, Nothing}, + traits::{Everything, Nothing}, weights::Weight, PalletId, }; -use frame_system::{EnsureNever, EnsureRoot}; -use hex_literal::hex; +use frame_system::EnsureRoot; + use orml_traits::parameter_type_with_key; -use pallet_evm::{AddressMapping, PrecompileHandle, PrecompileOutput}; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot, HashedAddressMapping, Precompile, PrecompileSet}; -use scale_info::TypeInfo; -use serde::{Deserialize, Serialize}; -use sp_core::{Blake2Hasher, Decode, Encode, Hasher, MaxEncodedLen, H160, H256, U256}; -use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, ConstU32, IdentityLookup, Verify}; +use pallet_evm::{PrecompileHandle, PrecompileOutput}; + +use sp_core::{MaxEncodedLen, H160, H256, U256}; +use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, IdentityLookup, Verify}; use sp_runtime::{AccountId32, DispatchError, MultiSignature, Perbill}; use auction_manager::{Auction, AuctionInfo, AuctionItem, AuctionType, CheckAuctionItemHandler, ListingLevel}; @@ -29,11 +26,10 @@ use primitives::evm::{ CurrencyIdType, Erc20Mapping, EvmAddress, H160_POSITION_CURRENCY_ID_TYPE, H160_POSITION_TOKEN, H160_POSITION_TOKEN_NFT, H160_POSITION_TOKEN_NFT_CLASS_ID_END, }; -use primitives::{Amount, AuctionId, ClassId, FungibleTokenId, GroupCollectionId, ItemId, TokenId}; +use primitives::{Amount, AuctionId, ClassId, FungibleTokenId, ItemId, TokenId}; use crate::currencies::MultiCurrencyPrecompile; use crate::nft::NftPrecompile; -use crate::precompiles::MetaverseNetworkPrecompiles; use super::*; @@ -142,7 +138,7 @@ where } } - fn is_precompile(&self, address: H160) -> bool { + fn is_precompile(&self, _address: H160) -> bool { true } } @@ -311,7 +307,7 @@ impl Auction for MockAuctionManager { None } - fn auction_item(id: AuctionId) -> Option> { + fn auction_item(_id: AuctionId) -> Option> { None } @@ -319,7 +315,7 @@ impl Auction for MockAuctionManager { Ok(()) } - fn update_auction_item(id: AuctionId, item_id: ItemId) -> DispatchResult { + fn update_auction_item(_id: AuctionId, _item_id: ItemId) -> DispatchResult { Ok(()) } @@ -348,11 +344,11 @@ impl Auction for MockAuctionManager { fn remove_auction(_id: u64, _item_id: ItemId) {} - fn auction_bid_handler(from: AccountId, id: AuctionId, value: Self::Balance) -> DispatchResult { + fn auction_bid_handler(_from: AccountId, _id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } - fn buy_now_handler(from: AccountId, auction_id: AuctionId, value: Self::Balance) -> DispatchResult { + fn buy_now_handler(_from: AccountId, _auction_id: AuctionId, _value: Self::Balance) -> DispatchResult { Ok(()) } diff --git a/runtime/common/src/nft.rs b/runtime/common/src/nft.rs index e10cebea6..e03599195 100644 --- a/runtime/common/src/nft.rs +++ b/runtime/common/src/nft.rs @@ -1,27 +1,25 @@ use core_primitives::{Attributes, CollectionType, NftMetadata, TokenType}; use evm_mapping::AddressMapping as EvmMapping; -use evm_mapping::EvmAddressMapping; + use frame_support::pallet_prelude::Get; use frame_support::traits::{Currency, OriginTrait}; use frame_system::RawOrigin; use orml_traits::{BasicCurrency, MultiCurrency}; use pallet_evm::{ - AddressMapping, ExitRevert, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, - PrecompileResult, PrecompileSet, + ExitRevert, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet, }; use sp_core::{H160, U256}; use sp_runtime::traits::{AccountIdConversion, Dispatchable}; use sp_runtime::Perbill; use sp_std::{marker::PhantomData, prelude::*}; -use codec::{DecodeAll, Encode}; use precompile_utils::data::{Address, EvmData, EvmDataWriter}; use precompile_utils::handle::PrecompileHandleExt; use precompile_utils::modifier::FunctionModifier; use precompile_utils::prelude::RuntimeHelper; use precompile_utils::{succeed, EvmResult}; use primitives::evm::{Erc20Mapping, Output}; -use primitives::{evm, Balance, ClassId, GroupCollectionId, TokenId}; +use primitives::{ClassId, GroupCollectionId, TokenId}; #[precompile_utils_macro::generate_function_selector] #[derive(Debug, PartialEq)] @@ -119,7 +117,7 @@ where Some(result) } - fn is_precompile(&self, address: H160) -> bool { + fn is_precompile(&self, _address: H160) -> bool { todo!() } } @@ -449,7 +447,7 @@ where let class_id = input.read::>()?.into(); // Build call info - let owner: H160 = input.read::
()?.into(); + let _owner: H160 = input.read::
()?.into(); let who = ::AddressMapping::get_account_id(&handle.context().caller); log::debug!(target: "evm", "withdraw funds from class {:?} fund", class_id); diff --git a/runtime/common/src/precompiles.rs b/runtime/common/src/precompiles.rs index 6774a1d83..6f1ce2d1e 100644 --- a/runtime/common/src/precompiles.rs +++ b/runtime/common/src/precompiles.rs @@ -1,4 +1,4 @@ -use pallet_evm::{ExitRevert, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult, PrecompileSet}; +use pallet_evm::{Precompile, PrecompileHandle, PrecompileResult, PrecompileSet}; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dispatch::Dispatch; @@ -78,7 +78,7 @@ where } } - fn is_precompile(&self, address: H160) -> bool { + fn is_precompile(&self, _address: H160) -> bool { // sp_std::vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 1024, 1025, 1026, 1027, 400] // .into_iter() // .map(hash) diff --git a/runtime/common/src/tests/currencies.rs b/runtime/common/src/tests/currencies.rs index 8ab5cf926..612cede31 100644 --- a/runtime/common/src/tests/currencies.rs +++ b/runtime/common/src/tests/currencies.rs @@ -1,5 +1,3 @@ -use asset_manager::BalanceOf; -use frame_support::assert_noop; use hex_literal::hex; use sp_core::{H160, U256}; use sp_runtime::traits::Zero; @@ -242,7 +240,7 @@ fn balance_of_native_currencies_works() { .with_balances(vec![(alice_account_id(), 100000)]) .build() .execute_with(|| { - let mut evm_writer = EvmDataWriter::new_with_selector(Action::BalanceOf); + let _evm_writer = EvmDataWriter::new_with_selector(Action::BalanceOf); EvmMapping::claim_default_account(RuntimeOrigin::signed(alice_account_id())); precompiles() .prepare_test( diff --git a/runtime/common/src/tests/nft.rs b/runtime/common/src/tests/nft.rs index e17f1cc46..06701033c 100644 --- a/runtime/common/src/tests/nft.rs +++ b/runtime/common/src/tests/nft.rs @@ -1,23 +1,20 @@ -use frame_support::assert_noop; -use hex_literal::hex; -use sp_core::{ByteArray, H160, U256}; -use sp_runtime::traits::{AccountIdConversion, Zero}; +use sp_core::{ByteArray, U256}; +use sp_runtime::traits::AccountIdConversion; use sp_runtime::Perbill; use sp_std::collections::btree_map::BTreeMap; use precompile_utils::data::{Address, Bytes, EvmDataWriter}; use precompile_utils::testing::*; -use primitives::evm::Output; + use primitives::FungibleTokenId; use crate::mock::*; use crate::nft::Action; -use evm_mapping::AddressMapping as AddressMappingEvm; + use orml_nft::Pallet as NftModule; use orml_traits::BasicCurrency; -use pallet_evm::AddressMapping; -use core_primitives::{Attributes, CollectionType, NftAssetData, NftClassData, NftMetadata, TokenType}; +use core_primitives::{Attributes, CollectionType, NftMetadata, TokenType}; fn precompiles() -> Precompiles { PrecompilesValue::get() diff --git a/runtime/metaverse/Cargo.toml b/runtime/metaverse/Cargo.toml index 03fe82227..216dca109 100644 --- a/runtime/metaverse/Cargo.toml +++ b/runtime/metaverse/Cargo.toml @@ -84,6 +84,7 @@ orml-tokens = { workspace = true } orml-traits = { workspace = true } orml-nft = { workspace = true } orml-oracle = { workspace = true } +orml-rewards = { workspace = true } orml-benchmarking = { workspace = true, optional = true } # metaverse dependencies primitives = { package = "bit-country-primitives", path = "../../primitives/metaverse", default-features = false } @@ -104,6 +105,7 @@ core-primitives = { path = "../../traits/core-primitives", default-features = fa metaverse-runtime-common = { path = "../common", default-features = false } asset-manager = { path = "../../pallets/asset-manager", default-features = false } evm-mapping = { package = "pallet-evm-mapping", path = "../../pallets/evm-mapping", default-features = false } +spp = { package = "pallet-spp", path = "../../pallets/spp", default-features = false } modules-bridge = { path = "../../modules/bridge", default-features = false } @@ -114,6 +116,18 @@ pallet-contracts-primitives = { workspace = true } # XCM builder ( need to be used to build the runtime benchmarking correctly) xcm-builder = { workspace = true } +# Cumulus Dependencies +cumulus-pallet-aura-ext = { workspace = true } +cumulus-pallet-parachain-system = { workspace = true } +cumulus-pallet-dmp-queue = { workspace = true } +cumulus-pallet-xcm = { workspace = true } +cumulus-pallet-xcmp-queue = { workspace = true } +cumulus-primitives-core = { workspace = true } +cumulus-primitives-timestamp = { workspace = true } +cumulus-primitives-utility = { workspace = true } +cumulus-pallet-session-benchmarking = { workspace = true } +parachain-info = { workspace = true } + [build-dependencies] substrate-wasm-builder = { workspace = true } @@ -162,6 +176,7 @@ std = [ "orml-tokens/std", "orml-nft/std", "orml-oracle/std", + "orml-rewards/std", "primitives/std", "metaverse/std", "auction/std", @@ -176,6 +191,7 @@ std = [ "economy/std", "emergency/std", "evm-mapping/std", + "spp/std", "pallet-utility/std", "pallet-collator-selection/std", "orml-benchmarking/std", @@ -189,7 +205,14 @@ std = [ "pallet-contracts-primitives/std", "frame-try-runtime/std", "metaverse-runtime-common/std", - "modules-bridge/std" + "modules-bridge/std", + "cumulus-pallet-aura-ext/std", + "cumulus-pallet-parachain-system/std", + "cumulus-pallet-xcmp-queue/std", + "cumulus-pallet-xcm/std", + "cumulus-primitives-core/std", + "cumulus-primitives-timestamp/std", + "cumulus-primitives-utility/std", ] runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", diff --git a/runtime/metaverse/src/lib.rs b/runtime/metaverse/src/lib.rs index 66fda6b2c..f90678a72 100644 --- a/runtime/metaverse/src/lib.rs +++ b/runtime/metaverse/src/lib.rs @@ -24,6 +24,7 @@ extern crate orml_benchmarking; use codec::{Decode, Encode, MaxEncodedLen}; +use cumulus_pallet_parachain_system::RelaychainBlockNumberProvider; // pub use this so we can import it in the chain spec. #[cfg(feature = "std")] pub use fp_evm::GenesisAccount; @@ -60,7 +61,6 @@ use pallet_evm::{ }; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; pub use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment}; -//use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping}; use polkadot_primitives::v2::MAX_POV_SIZE; use scale_info::TypeInfo; use sp_api::impl_runtime_apis; @@ -70,7 +70,7 @@ use sp_core::{ sp_std::marker::PhantomData, ConstBool, OpaqueMetadata, H160, H256, U256, }; -use sp_runtime::traits::DispatchInfoOf; +use sp_runtime::traits::{BlockNumberProvider, DispatchInfoOf}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; use sp_runtime::{ @@ -87,6 +87,8 @@ use sp_std::prelude::*; use sp_version::NativeVersion; use sp_version::RuntimeVersion; +//use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping}; +use asset_manager::ForeignAssetMapping; pub use constants::{currency::*, time::*}; use core_primitives::{NftAssetData, NftClassData}; // External imports @@ -98,7 +100,7 @@ use primitives::evm::{ CurrencyIdType, Erc20Mapping, EvmAddress, H160_POSITION_CURRENCY_ID_TYPE, H160_POSITION_FUNGIBLE_TOKEN, H160_POSITION_MINING_RESOURCE, H160_POSITION_TOKEN, H160_POSITION_TOKEN_NFT, H160_POSITION_TOKEN_NFT_CLASS_ID_END, }; -use primitives::{Amount, Balance, BlockNumber, ClassId, FungibleTokenId, Moment, NftId, RoundIndex, TokenId}; +use primitives::{Amount, Balance, BlockNumber, ClassId, FungibleTokenId, Moment, NftId, PoolId, RoundIndex, TokenId}; // primitives imports use crate::opaque::SessionKeys; @@ -180,7 +182,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 92, + spec_version: 93, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -364,6 +366,10 @@ parameter_types! { pub const EconomyTreasury: PalletId = PalletId(*b"bit/econ"); pub const LocalMetaverseFundPalletId: PalletId = PalletId(*b"bit/meta"); pub const BridgeSovereignPalletId: PalletId = PalletId(*b"bit/brgd"); + pub const PoolAccountPalletId: PalletId = PalletId(*b"bit/pool"); + pub const RewardPayoutAccountPalletId: PalletId = PalletId(*b"bit/pout"); + pub const RewardHoldingAccountPalletId: PalletId = PalletId(*b"bit/hold"); + pub const MaxAuthorities: u32 = 50; pub const MaxSetIdSessionEntries: u64 = u64::MAX; } @@ -1437,6 +1443,44 @@ impl modules_bridge::Config for Runtime { type PalletId = BridgeSovereignPalletId; } +impl orml_rewards::Config for Runtime { + type Share = Balance; + type Balance = Balance; + type PoolId = PoolId; + type CurrencyId = FungibleTokenId; + type Handler = Spp; +} + +parameter_types! { + pub const MaximumQueue: u32 = 50; + pub const MockRelayBlockNumberProvider: BlockNumber = 0; +} + +impl BlockNumberProvider for MockRelayBlockNumberProvider { + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + Self::get() + } +} + +impl spp::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type MultiCurrency = Currencies; + type WeightInfo = weights::module_spp::WeightInfo; + type MinimumStake = MinimumStake; + type NetworkFee = NetworkFee; + type StorageDepositFee = StorageDepositFee; + type RelayChainBlockNumber = MockRelayBlockNumberProvider; + type PoolAccount = PoolAccountPalletId; + type RewardPayoutAccount = RewardPayoutAccountPalletId; + type RewardHoldingAccount = RewardHoldingAccountPalletId; + type MaximumQueue = MaximumQueue; + type CurrencyIdConversion = ForeignAssetMapping; + type GovernanceOrigin = EnsureRootOrTwoThirdsCouncilCollective; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime where @@ -1510,6 +1554,10 @@ construct_runtime!( // Bridge BridgeSupport: modules_bridge::{Pallet, Call, Storage, Event}, + + // Spp + Spp: spp::{Pallet, Call, Storage, Event}, + Rewards: orml_rewards::{Pallet, Storage} } ); diff --git a/runtime/metaverse/src/weights/mod.rs b/runtime/metaverse/src/weights/mod.rs index 8d70a266d..f934833ce 100644 --- a/runtime/metaverse/src/weights/mod.rs +++ b/runtime/metaverse/src/weights/mod.rs @@ -9,3 +9,4 @@ pub mod module_metaverse; pub mod module_mining; pub mod module_nft; pub mod module_reward; +pub mod module_spp; diff --git a/runtime/metaverse/src/weights/module_spp.rs b/runtime/metaverse/src/weights/module_spp.rs new file mode 100644 index 000000000..8e4985b6e --- /dev/null +++ b/runtime/metaverse/src/weights/module_spp.rs @@ -0,0 +1,168 @@ +// This file is part of Metaverse.Network & Bit.Country. + +// Copyright (C) 2020-2022 Metaverse.Network & Bit.Country . +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for estate +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-11-03, STEPS: `20`, REPEAT: 10, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// ./target/release/metaverse-node +// benchmark +// --chain=dev +// --pallet=estate +// --extrinsic=* +// --steps=20 +// --repeat=10 +// --execution=wasm +// --wasm-execution=compiled +// --template=./template/runtime-weight-template.hbs +// --output +// ./pallets/estate/src/weights.rs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for estate. +pub struct WeightInfo(PhantomData); + +impl spp::WeightInfo for WeightInfo { + fn mint_land() -> Weight { + Weight::from_parts(59_273_000, 36660) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + fn mint_lands() -> Weight { + Weight::from_parts(83_541_000, 41610) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(10)) + } + fn transfer_land() -> Weight { + Weight::from_parts(47_423_000, 28255) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn mint_estate() -> Weight { + Weight::from_parts(64_479_000, 47210) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(11)) + } + fn dissolve_estate() -> Weight { + Weight::from_parts(110_008_000, 67224) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(13)) + } + fn add_land_unit_to_estate() -> Weight { + Weight::from_parts(71_706_000, 38079) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + fn remove_land_unit_from_estate() -> Weight { + Weight::from_parts(90_257_000, 60226) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(8)) + } + fn create_estate() -> Weight { + Weight::from_parts(131_741_000, 66058) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(17)) + } + fn transfer_estate() -> Weight { + Weight::from_parts(54_808_000, 38025) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn issue_undeployed_land_blocks() -> Weight { + Weight::from_parts(162_875_000, 9825) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(43)) + } + fn freeze_undeployed_land_blocks() -> Weight { + Weight::from_parts(22_833_000, 7834) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn unfreeze_undeployed_land_blocks() -> Weight { + Weight::from_parts(21_423_000, 7834) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn approve_undeployed_land_blocks() -> Weight { + Weight::from_parts(21_819_000, 7834) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn unapprove_undeployed_land_blocks() -> Weight { + Weight::from_parts(21_237_000, 7900) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn transfer_undeployed_land_blocks() -> Weight { + Weight::from_parts(41_173_000, 13673) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn deploy_land_block() -> Weight { + Weight::from_parts(100_659_000, 64897) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(11)) + } + fn burn_undeployed_land_blocks() -> Weight { + Weight::from_parts(32_196_000, 10661) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + fn create_lease_offer() -> Weight { + Weight::from_parts(98_902_000, 27383) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(2)) + } + fn accept_lease_offer() -> Weight { + Weight::from_parts(57_019_000, 28844) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) + } + fn cancel_lease() -> Weight { + Weight::from_parts(57_720_000, 28571) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn remove_expired_lease() -> Weight { + Weight::from_parts(57_681_000, 28571) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + fn remove_lease_offer() -> Weight { + Weight::from_parts(41_923_000, 8328) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + fn collect_rent() -> Weight { + Weight::from_parts(53_171_000, 28571) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + fn on_initialize() -> Weight { + Weight::from_parts(191_000, 0) + } +} \ No newline at end of file diff --git a/traits/core-primitives/src/lib.rs b/traits/core-primitives/src/lib.rs index 4ea550bab..5aa8b55df 100644 --- a/traits/core-primitives/src/lib.rs +++ b/traits/core-primitives/src/lib.rs @@ -163,7 +163,7 @@ pub struct MetaverseFund { } #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct PreSignedMint { +pub struct PreSignedMint { /// A collection of the item to be minted. pub class_id: ClassId, /// TokenId. @@ -174,6 +174,8 @@ pub struct PreSignedMint { pub metadata: NftMetadata, /// Restrict the claim to a particular account. pub only_account: Option, + /// A deadline for the signature. + pub expired: BlockNumber, /// An optional price the claimer would need to pay for the mint. pub mint_price: Option, } @@ -400,3 +402,9 @@ impl MiningResourceRateInfo { self.mining_reward = mining_reward; } } + +pub trait CurrencyIdManagement { + fn check_token_exist(currency_id: FungibleTokenId) -> bool; + fn convert_to_rcurrency(currency_id: FungibleTokenId) -> Result; + fn convert_to_currency(currency_id: FungibleTokenId) -> Result; +}