From d66df3d9335e4092d4dc6a779ab81058dd6668c1 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 5 Jun 2023 15:06:04 +0800 Subject: [PATCH 01/26] add farming Signed-off-by: zqhxuyuan --- Cargo.lock | 55 ++ manta-farming.rs | 172 ++++ node/Cargo.toml | 2 + node/src/rpc/calamari.rs | 10 +- pallets/farming/Cargo.toml | 62 ++ pallets/farming/rpc/Cargo.toml | 22 + pallets/farming/rpc/runtime-api/Cargo.toml | 24 + pallets/farming/rpc/runtime-api/src/lib.rs | 40 + pallets/farming/rpc/src/lib.rs | 130 +++ pallets/farming/src/benchmarking.rs | 184 ++++ pallets/farming/src/gauge.rs | 494 +++++++++++ pallets/farming/src/lib.rs | 838 ++++++++++++++++++ pallets/farming/src/migration.rs | 84 ++ pallets/farming/src/mock.rs | 366 ++++++++ pallets/farming/src/rewards.rs | 479 ++++++++++ pallets/farming/src/tests.rs | 573 ++++++++++++ pallets/farming/src/weights.rs | 174 ++++ primitives/manta/Cargo.toml | 3 + primitives/manta/src/currencies.rs | 186 ++++ primitives/manta/src/lib.rs | 1 + runtime/calamari/Cargo.toml | 6 + runtime/calamari/src/lib.rs | 41 +- runtime/calamari/src/weights/manta_farming.rs | 172 ++++ runtime/calamari/src/weights/mod.rs | 1 + 24 files changed, 4116 insertions(+), 3 deletions(-) create mode 100644 manta-farming.rs create mode 100644 pallets/farming/Cargo.toml create mode 100644 pallets/farming/rpc/Cargo.toml create mode 100644 pallets/farming/rpc/runtime-api/Cargo.toml create mode 100644 pallets/farming/rpc/runtime-api/src/lib.rs create mode 100644 pallets/farming/rpc/src/lib.rs create mode 100644 pallets/farming/src/benchmarking.rs create mode 100644 pallets/farming/src/gauge.rs create mode 100644 pallets/farming/src/lib.rs create mode 100644 pallets/farming/src/migration.rs create mode 100644 pallets/farming/src/mock.rs create mode 100644 pallets/farming/src/rewards.rs create mode 100644 pallets/farming/src/tests.rs create mode 100644 pallets/farming/src/weights.rs create mode 100644 primitives/manta/src/currencies.rs create mode 100644 runtime/calamari/src/weights/manta_farming.rs diff --git a/Cargo.lock b/Cargo.lock index 80880dbdd..fc4bbf232 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1103,6 +1103,8 @@ dependencies = [ "lazy_static", "log", "manta-collator-selection", + "manta-farming", + "manta-farming-rpc-runtime-api", "manta-primitives", "nimbus-primitives", "orml-traits", @@ -5332,6 +5334,8 @@ dependencies = [ "hex-literal", "jsonrpsee", "log", + "manta-farming-rpc-api", + "manta-farming-rpc-runtime-api", "manta-primitives", "manta-runtime", "nimbus-consensus", @@ -5465,6 +5469,56 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "manta-farming" +version = "4.0.7" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "hex-literal", + "log", + "manta-primitives", + "orml-traits", + "pallet-asset-manager", + "pallet-assets", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", +] + +[[package]] +name = "manta-farming-rpc-api" +version = "4.0.7" +dependencies = [ + "jsonrpsee", + "manta-farming-rpc-runtime-api", + "manta-primitives", + "parity-scale-codec", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", +] + +[[package]] +name = "manta-farming-rpc-runtime-api" +version = "4.0.7" +dependencies = [ + "manta-primitives", + "parity-scale-codec", + "sp-api", + "sp-std", +] + [[package]] name = "manta-parameters" version = "0.5.15" @@ -5505,6 +5559,7 @@ dependencies = [ "frame-support", "frame-system", "log", + "orml-traits", "parity-scale-codec", "scale-info", "smallvec", diff --git a/manta-farming.rs b/manta-farming.rs new file mode 100644 index 000000000..e03fcafa5 --- /dev/null +++ b/manta-farming.rs @@ -0,0 +1,172 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Autogenerated weights for manta_farming +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-05, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("calamari-dev"), DB CACHE: 1024 + +// Executed Command: +// target/debug/manta +// benchmark +// pallet +// --chain=calamari-dev +// --pallet=manta_farming +// --extrinsic=* +// --heap-pages=4096 +// --repeat=1 +// --steps=1 +// --template=.github/resources/frame-weight-template.hbs +// --output=manta-farming.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; + +/// Weight functions needed for manta_farming. +pub trait WeightInfo { + fn on_initialize() -> Weight; + fn create_farming_pool() -> Weight; + fn deposit() -> Weight; + fn withdraw() -> Weight; + fn claim() -> Weight; + fn gauge_withdraw() -> Weight; +} + +/// Weights for manta_farming using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl manta_farming::WeightInfo for SubstrateWeight { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 75_000 nanoseconds. + Weight::from_ref_time(75_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 658_000 nanoseconds. + Weight::from_ref_time(658_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 3_884_000 nanoseconds. + Weight::from_ref_time(3_884_000_000) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 439_000 nanoseconds. + Weight::from_ref_time(439_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 473_000 nanoseconds. + Weight::from_ref_time(473_000_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 640_000 nanoseconds. + Weight::from_ref_time(640_000_000) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 75_000 nanoseconds. + Weight::from_ref_time(75_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 658_000 nanoseconds. + Weight::from_ref_time(658_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 3_884_000 nanoseconds. + Weight::from_ref_time(3_884_000_000) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 439_000 nanoseconds. + Weight::from_ref_time(439_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 473_000 nanoseconds. + Weight::from_ref_time(473_000_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 640_000 nanoseconds. + Weight::from_ref_time(640_000_000) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(2)) + } +} diff --git a/node/Cargo.toml b/node/Cargo.toml index da4fce5bf..ab8b08ec2 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -36,6 +36,8 @@ jsonrpsee = { version = "0.16.2", features = ["server"] } pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +manta-farming-rpc-api = { path = "../pallets/farming/rpc" } +manta-farming-rpc-runtime-api = { path = "../pallets/farming/rpc/runtime-api" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" } zenlink-protocol-rpc = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" } diff --git a/node/src/rpc/calamari.rs b/node/src/rpc/calamari.rs index 4319e2b21..e3ff3abf6 100644 --- a/node/src/rpc/calamari.rs +++ b/node/src/rpc/calamari.rs @@ -17,6 +17,9 @@ //! Calamari RPC Extensions use super::*; +use manta_farming_rpc_api::{FarmingRpc, FarmingRpcApiServer}; +use manta_farming_rpc_runtime_api::FarmingRuntimeApi; +use manta_primitives::types::{CalamariAssetId, PoolId}; use pallet_manta_pay::{ rpc::{Pull, PullApiServer}, runtime::PullLedgerDiffApi, @@ -44,6 +47,7 @@ where C::Api: BlockBuilder, C::Api: PullLedgerDiffApi, C::Api: SBTPullLedgerDiffApi, + C::Api: FarmingRuntimeApi, C::Api: ZenlinkProtocolRuntimeApi, P: TransactionPool + Sync + Send + 'static, { @@ -76,7 +80,11 @@ where .map_err(|e| sc_service::Error::Other(e.to_string()))?; module - .merge(ZenlinkProtocol::new(client).into_rpc()) + .merge(ZenlinkProtocol::new(client.clone()).into_rpc()) + .map_err(|e| sc_service::Error::Other(e.to_string()))?; + + module + .merge(FarmingRpc::new(client).into_rpc()) .map_err(|e| sc_service::Error::Other(e.to_string()))?; Ok(module) diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml new file mode 100644 index 000000000..393503432 --- /dev/null +++ b/pallets/farming/Cargo.toml @@ -0,0 +1,62 @@ +[package] +authors = ['Manta Network'] +edition = "2021" +homepage = "https://manta.network" +license = "GPL-3.0" +name = "manta-farming" +repository = 'https://github.com/Manta-Network/Manta/' +version = "4.0.7" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } +hex-literal = { version = "0.3.1" } +log = { version = "0.4.16", default-features = false } +scale-info = { version = "2.3.1", default-features = false, features = ["derive"] } + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } + +manta-primitives = { path = '../../primitives/manta', default-features = false } +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.37", default-features = false } +pallet-asset-manager = { path = "../asset-manager", default-features = false, optional = true } +pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37", default-features = false, optional = true } +xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "release-v0.9.37", default-features = false, optional = true } + +[dev-dependencies] +pallet-assets = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } +pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[features] +default = ["std"] +std = [ + "codec/std", + "log/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "manta-primitives/std", + "scale-info/std", + "pallet-assets/std", + "pallet-asset-manager/std", + "xcm/std", +] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "xcm", + "pallet-asset-manager", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/farming/rpc/Cargo.toml b/pallets/farming/rpc/Cargo.toml new file mode 100644 index 000000000..5a222e5e7 --- /dev/null +++ b/pallets/farming/rpc/Cargo.toml @@ -0,0 +1,22 @@ +[package] +authors = ['Manta Network'] +edition = "2021" +homepage = "https://manta.network" +license = "GPL-3.0" +name = "manta-farming-rpc-api" +repository = 'https://github.com/Manta-Network/Manta/' +version = "4.0.7" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } +jsonrpsee = { version = "0.16.2", features = ["server", "macros"] } +serde = { version = "1.0.140", features = ["derive"] } + +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } +sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } + +manta-farming-rpc-runtime-api = { path = "./runtime-api" } +manta-primitives = { path = '../../../primitives/manta', default-features = false } diff --git a/pallets/farming/rpc/runtime-api/Cargo.toml b/pallets/farming/rpc/runtime-api/Cargo.toml new file mode 100644 index 000000000..2889aa3a5 --- /dev/null +++ b/pallets/farming/rpc/runtime-api/Cargo.toml @@ -0,0 +1,24 @@ +[package] +authors = ['Manta Network'] +edition = "2021" +homepage = "https://manta.network" +license = "GPL-3.0" +name = "manta-farming-rpc-runtime-api" +repository = 'https://github.com/Manta-Network/Manta/' +version = "4.0.7" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } + +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } + +manta-primitives = { path = '../../../../primitives/manta', default-features = false } + +[features] +default = ["std"] +std = [ + "codec/std", + "sp-api/std", + "manta-primitives/std", +] diff --git a/pallets/farming/rpc/runtime-api/src/lib.rs b/pallets/farming/rpc/runtime-api/src/lib.rs new file mode 100644 index 000000000..fa70e446e --- /dev/null +++ b/pallets/farming/rpc/runtime-api/src/lib.rs @@ -0,0 +1,40 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::Codec; +use manta_primitives::types::Balance; +use sp_api::decl_runtime_apis; +use sp_std::vec::Vec; + +decl_runtime_apis! { + pub trait FarmingRuntimeApi where + AccountId: Codec, + PoolId: Codec, + CurrencyId: Codec, + { + fn get_farming_rewards( + who: AccountId, + pid: PoolId, + ) -> Vec<(CurrencyId, Balance)>; + + fn get_gauge_rewards( + who: AccountId, + pid: PoolId, + ) -> Vec<(CurrencyId, Balance)>; + } +} diff --git a/pallets/farming/rpc/src/lib.rs b/pallets/farming/rpc/src/lib.rs new file mode 100644 index 000000000..91931c737 --- /dev/null +++ b/pallets/farming/rpc/src/lib.rs @@ -0,0 +1,130 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +use std::{marker::PhantomData, sync::Arc}; + +use codec::Codec; +use jsonrpsee::{ + core::{async_trait, RpcResult}, + proc_macros::rpc, + types::error::{CallError, ErrorCode, ErrorObject}, +}; +pub use manta_farming_rpc_runtime_api::{self as runtime_api, FarmingRuntimeApi}; +use manta_primitives::types::Balance; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::HeaderBackend; +use sp_rpc::number::NumberOrHex; +use sp_runtime::{generic::BlockId, traits::Block as BlockT}; + +#[rpc(client, server)] +pub trait FarmingRpcApi { + /// rpc method for getting farming rewards + #[method(name = "farming_getFarmingRewards")] + fn get_farming_rewards( + &self, + who: AccountId, + pid: PoolId, + at: Option, + ) -> RpcResult>; + + /// rpc method for getting gauge rewards + #[method(name = "farming_getGaugeRewards")] + fn get_gauge_rewards( + &self, + who: AccountId, + pid: PoolId, + at: Option, + ) -> RpcResult>; +} + +#[derive(Clone, Debug)] +pub struct FarmingRpc { + client: Arc, + _marker: PhantomData, +} + +impl FarmingRpc { + pub fn new(client: Arc) -> Self { + Self { + client, + _marker: PhantomData, + } + } +} + +#[async_trait] +impl + FarmingRpcApiServer<::Hash, AccountId, CurrencyId, PoolId> + for FarmingRpc +where + Block: BlockT, + C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, + C::Api: FarmingRuntimeApi, + AccountId: Codec, + CurrencyId: Codec, + PoolId: Codec, +{ + fn get_farming_rewards( + &self, + who: AccountId, + pid: PoolId, + at: Option<::Hash>, + ) -> RpcResult> { + let lm_rpc_api = self.client.runtime_api(); + let at = BlockId::::hash(at.unwrap_or_else(|| self.client.info().best_hash)); + + let rs: Result, _> = + lm_rpc_api.get_farming_rewards(&at, who, pid); + + match rs { + Ok(rewards) => Ok(rewards + .into_iter() + .map(|(token, amount)| (token, NumberOrHex::Hex(amount.into()))) + .collect()), + Err(e) => Err(CallError::Custom(ErrorObject::owned( + ErrorCode::InternalError.code(), + "Failed to get farming rewards.", + Some(format!("{:?}", e)), + ))), + } + .map_err(jsonrpsee::core::Error::Call) + } + + fn get_gauge_rewards( + &self, + who: AccountId, + pid: PoolId, + at: Option<::Hash>, + ) -> RpcResult> { + let lm_rpc_api = self.client.runtime_api(); + let at = BlockId::::hash(at.unwrap_or_else(|| self.client.info().best_hash)); + + let rs: Result, _> = lm_rpc_api.get_gauge_rewards(&at, who, pid); + + match rs { + Ok(rewards) => Ok(rewards + .into_iter() + .map(|(token, amount)| (token, NumberOrHex::Hex(amount.into()))) + .collect()), + Err(e) => Err(CallError::Custom(ErrorObject::owned( + ErrorCode::InternalError.code(), + "Failed to get gauge rewards.", + Some(format!("{:?}", e)), + ))), + } + .map_err(jsonrpsee::core::Error::Call) + } +} diff --git a/pallets/farming/src/benchmarking.rs b/pallets/farming/src/benchmarking.rs new file mode 100644 index 000000000..2e20180f8 --- /dev/null +++ b/pallets/farming/src/benchmarking.rs @@ -0,0 +1,184 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg(feature = "runtime-benchmarks")] + +use crate::{Pallet as Farming, *}; +use frame_benchmarking::{benchmarks, vec, whitelisted_caller}; +use frame_support::{assert_ok, sp_runtime::traits::UniqueSaturatedFrom}; +use frame_system::{Pallet as System, RawOrigin}; +use manta_primitives::assets::{AssetConfig, FungibleLedger, TestingDefault}; +use pallet_asset_manager::Pallet as AssetManager; + +pub const INITIAL_VALUE: u128 = 1_000_000_000_000_000_000_000u128; + +benchmarks! { + where_clause { where T: pallet_assets::Config + pallet_asset_manager::Config, ::Balance: From, ::AssetId: From } + on_initialize {}:{Farming::::on_initialize(T::BlockNumber::from(10u32));} + + create_farming_pool { + let ksm_asset_id = CurrencyIdOf::::unique_saturated_from(8u128); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let tokens_proportion = vec![(ksm_asset_id, Perbill::from_percent(100))]; + let basic_rewards = vec![(ksm_asset_id, token_amount)]; + let gauge_basic_rewards = vec![(ksm_asset_id, token_amount)]; + }: _(RawOrigin::Root, + tokens_proportion, + basic_rewards, + Some((ksm_asset_id, BlockNumberFor::::from(1000u32), gauge_basic_rewards)), + BalanceOf::::unique_saturated_from(0u128), + BlockNumberFor::::from(0u32), + BlockNumberFor::::from(7u32), + BlockNumberFor::::from(6u32), + 5 + ) + + deposit { + let location = T::Location::default(); + let metadata = >::AssetRegistryMetadata::testing_default(); + AssetManager::::do_register_asset(Some(&location), &metadata)?; + + let ksm_asset_id = CurrencyIdOf::::unique_saturated_from(8u128); + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let tokens_proportion = vec![(ksm_asset_id, Perbill::from_percent(100))]; + let basic_rewards = vec![(ksm_asset_id, token_amount)]; + let gauge_basic_rewards = vec![(ksm_asset_id, token_amount)]; + assert_ok!(Farming::::create_farming_pool( + RawOrigin::Root.into(), + tokens_proportion, + basic_rewards, + Some((ksm_asset_id, BlockNumberFor::::from(1000u32), gauge_basic_rewards)), + BalanceOf::::unique_saturated_from(0u128), + BlockNumberFor::::from(0u32), + BlockNumberFor::::from(7u32), + BlockNumberFor::::from(6u32), + 5, + )); + let charge_rewards = vec![(ksm_asset_id, BalanceOf::::unique_saturated_from(300000u128))]; + + // init balance + let _ = >::FungibleLedger::deposit_minting( + 8.into(), + &caller, + INITIAL_VALUE.try_into().unwrap(), + ); + assert_ok!(Farming::::charge(RawOrigin::Signed(caller.clone()).into(), 0, charge_rewards)); + }: _(RawOrigin::Signed(caller.clone()), 0, token_amount, None) + + withdraw { + let location = T::Location::default(); + let metadata = >::AssetRegistryMetadata::testing_default(); + AssetManager::::do_register_asset(Some(&location), &metadata)?; + + let ksm_asset_id = CurrencyIdOf::::unique_saturated_from(8u128); + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let tokens_proportion = vec![(ksm_asset_id, Perbill::from_percent(100))]; + let basic_rewards = vec![(ksm_asset_id, token_amount)]; + let gauge_basic_rewards = vec![(ksm_asset_id, token_amount)]; + assert_ok!(Farming::::create_farming_pool( + RawOrigin::Root.into(), + tokens_proportion, + basic_rewards, + Some((ksm_asset_id, BlockNumberFor::::from(1000u32), gauge_basic_rewards)), + BalanceOf::::unique_saturated_from(0u128), + BlockNumberFor::::from(0u32), + BlockNumberFor::::from(7u32), + BlockNumberFor::::from(6u32), + 5, + )); + + let _ = >::FungibleLedger::deposit_minting( + 8.into(), + &caller, + INITIAL_VALUE.try_into().unwrap(), + ); + let charge_rewards = vec![(ksm_asset_id,BalanceOf::::unique_saturated_from(300000u128))]; + assert_ok!(Farming::::charge(RawOrigin::Signed(caller.clone()).into(), 0, charge_rewards)); + assert_ok!(Farming::::deposit(RawOrigin::Signed(caller.clone()).into(), 0, token_amount, None)); + }: _(RawOrigin::Signed(caller.clone()), 0, None) + + claim { + let location = T::Location::default(); + let metadata = >::AssetRegistryMetadata::testing_default(); + AssetManager::::do_register_asset(Some(&location), &metadata)?; + + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let ksm_asset_id = CurrencyIdOf::::unique_saturated_from(8u128); + let tokens_proportion = vec![(ksm_asset_id, Perbill::from_percent(100))]; + let basic_rewards = vec![(ksm_asset_id, token_amount)]; + let gauge_basic_rewards = vec![(ksm_asset_id, token_amount)]; + assert_ok!(Farming::::create_farming_pool( + RawOrigin::Root.into(), + tokens_proportion, + basic_rewards, + Some((ksm_asset_id, BlockNumberFor::::from(1000u32), gauge_basic_rewards)), + BalanceOf::::unique_saturated_from(0u128), + BlockNumberFor::::from(0u32), + BlockNumberFor::::from(7u32), + BlockNumberFor::::from(6u32), + 5, + )); + + let _ = >::FungibleLedger::deposit_minting( + 8.into(), + &caller, + INITIAL_VALUE.try_into().unwrap(), + ); + let charge_rewards = vec![(ksm_asset_id,BalanceOf::::unique_saturated_from(300000u128))]; + assert_ok!(Farming::::charge(RawOrigin::Signed(caller.clone()).into(), 0, charge_rewards)); + assert_ok!(Farming::::deposit(RawOrigin::Signed(caller.clone()).into(), 0, token_amount, None)); + System::::set_block_number(System::::block_number() + BlockNumberFor::::from(10u32)); + Farming::::on_initialize(BlockNumberFor::::from(0u32)); + }: _(RawOrigin::Signed(caller.clone()), 0) + + gauge_withdraw { + let location = T::Location::default(); + let metadata = >::AssetRegistryMetadata::testing_default(); + AssetManager::::do_register_asset(Some(&location), &metadata)?; + + let ksm_asset_id = CurrencyIdOf::::unique_saturated_from(8u128); + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let tokens_proportion = vec![(ksm_asset_id, Perbill::from_percent(100))]; + let basic_rewards = vec![(ksm_asset_id, token_amount)]; + let gauge_basic_rewards = vec![(ksm_asset_id, token_amount)]; + assert_ok!(Farming::::create_farming_pool( + RawOrigin::Root.into(), + tokens_proportion, + basic_rewards, + Some((ksm_asset_id, BlockNumberFor::::from(1000u32), gauge_basic_rewards)), + BalanceOf::::unique_saturated_from(0u128), + BlockNumberFor::::from(0u32), + BlockNumberFor::::from(7u32), + BlockNumberFor::::from(6u32), + 5, + )); + + let _ = >::FungibleLedger::deposit_minting( + 8.into(), + &caller, + INITIAL_VALUE.try_into().unwrap(), + ); + let charge_rewards = vec![(ksm_asset_id,BalanceOf::::unique_saturated_from(300000u128))]; + assert_ok!(Farming::::charge(RawOrigin::Signed(caller.clone()).into(), 0, charge_rewards)); + assert_ok!(Farming::::deposit(RawOrigin::Signed(caller.clone()).into(), 0, token_amount, Some((BalanceOf::::unique_saturated_from(100u128), BlockNumberFor::::from(100u32))))); + // System::::set_block_number(System::::block_number() + BlockNumberFor::::from(10u32)); + }: _(RawOrigin::Signed(caller.clone()), 0) +} diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs new file mode 100644 index 000000000..1de698975 --- /dev/null +++ b/pallets/farming/src/gauge.rs @@ -0,0 +1,494 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +use codec::HasCompact; +use frame_support::pallet_prelude::*; +use scale_info::TypeInfo; +use sp_core::U256; +use sp_runtime::{ + traits::{Zero, *}, + ArithmeticError, Perbill, RuntimeDebug, SaturatedConversion, +}; +use sp_std::prelude::*; + +use crate::*; + +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct GaugeInfo { + pub who: AccountIdOf, + pub gauge_amount: BalanceOf, + pub total_time_factor: u128, + pub latest_time_factor: u128, + pub claimed_time_factor: u128, + pub gauge_start_block: BlockNumberFor, + pub gauge_stop_block: BlockNumberFor, + pub gauge_last_block: BlockNumberFor, + pub last_claim_block: BlockNumberFor, +} + +impl GaugeInfo +where + BalanceOf: Default + HasCompact, + BlockNumberFor: Default, +{ + fn new(who: AccountIdOf) -> Self { + Self { + who, + gauge_amount: Default::default(), + total_time_factor: Default::default(), + latest_time_factor: Default::default(), + claimed_time_factor: Default::default(), + gauge_start_block: Default::default(), + gauge_stop_block: Default::default(), + gauge_last_block: Default::default(), + last_claim_block: Default::default(), + } + } +} + +/// The Reward Pool Info. +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct GaugePoolInfo { + pub pid: PoolId, + pub token: CurrencyIdOf, + pub keeper: AccountIdOf, + pub reward_issuer: AccountIdOf, + pub rewards: BTreeMap, + pub gauge_basic_rewards: BTreeMap, + pub max_block: BlockNumberFor, + pub gauge_amount: BalanceOf, + pub total_time_factor: u128, + pub gauge_state: GaugeState, + pub gauge_last_block: BlockNumberFor, +} + +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub enum GaugeState { + Unbond, + Bonded, +} + +impl + GaugePoolInfo +where + BalanceOf: Default + HasCompact, + CurrencyIdOf: Ord + Default, + BlockNumberFor: Clone, +{ + pub fn new( + pid: PoolId, + token: CurrencyIdOf, + keeper: AccountIdOf, + reward_issuer: AccountIdOf, + gauge_basic_rewards: BTreeMap, + max_block: BlockNumberFor, + current_block_number: BlockNumberFor, + ) -> Self { + Self { + pid, + token, + keeper, + reward_issuer, + rewards: BTreeMap::new(), + gauge_basic_rewards, + max_block, + gauge_amount: Default::default(), + total_time_factor: Default::default(), + gauge_last_block: current_block_number, + gauge_state: GaugeState::Bonded, + } + } +} + +impl Pallet +where + BlockNumberFor: AtLeast32BitUnsigned + Copy, + BalanceOf: AtLeast32BitUnsigned + Copy, +{ + pub fn create_gauge_pool( + pid: PoolId, + pool_info: &mut PoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, + gauge_token: CurrencyIdOf, + gauge_basic_rewards: BTreeMap, BalanceOf>, + max_block: BlockNumberFor, + ) -> DispatchResult { + let gid = Self::gauge_pool_next_id(); + pool_info.gauge = Some(gid); + let current_block_number = frame_system::Pallet::::block_number(); + let gauge_pool_info = GaugePoolInfo::new( + pid, + gauge_token, + pool_info.keeper.clone(), + pool_info.reward_issuer.clone(), + gauge_basic_rewards, + max_block, + current_block_number, + ); + + GaugePoolInfos::::insert(gid, &gauge_pool_info); + GaugePoolNextId::::mutate(|id| -> DispatchResult { + *id = id.checked_add(1).ok_or(ArithmeticError::Overflow)?; + Ok(()) + })?; + Ok(()) + } + + pub fn gauge_add( + who: &AccountIdOf, + gid: PoolId, + gauge_value: BalanceOf, + gauge_block: BlockNumberFor, + ) -> DispatchResult { + GaugePoolInfos::::mutate(gid, |gauge_pool_info_old| -> DispatchResult { + if let Some(mut gauge_pool_info) = gauge_pool_info_old.take() { + let current_block_number = frame_system::Pallet::::block_number(); + gauge_pool_info.gauge_last_block = current_block_number; + gauge_pool_info.gauge_amount = gauge_pool_info + .gauge_amount + .checked_add(&gauge_value) + .ok_or(ArithmeticError::Overflow)?; + let mut gauge_info = + GaugeInfos::::get(gid, who).unwrap_or_else(|| GaugeInfo::new(who.clone())); + + ensure!( + gauge_info.gauge_stop_block >= current_block_number + || gauge_info.gauge_stop_block == Default::default(), + Error::::LastGaugeNotClaim + ); + + ensure!( + gauge_pool_info.max_block + >= gauge_info.gauge_stop_block - gauge_info.gauge_start_block + gauge_block, + Error::::GaugeMaxBlockOverflow + ); + + let incease_total_time_factor = if gauge_info.gauge_amount.is_zero() { + gauge_info.gauge_stop_block = current_block_number; + gauge_info.gauge_start_block = current_block_number; + gauge_info.last_claim_block = current_block_number; + gauge_info.total_time_factor = gauge_block + .saturated_into::() + .checked_mul(gauge_value.saturated_into::()) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.total_time_factor + } else { + let time_factor_a = gauge_value + .saturated_into::() + .checked_mul( + (gauge_info.gauge_stop_block - current_block_number) + .saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let time_factor_b = gauge_block + .saturated_into::() + .checked_mul( + (gauge_value + gauge_info.gauge_amount).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let incease_total_time_factor = time_factor_a + time_factor_b; + gauge_info.total_time_factor = gauge_info + .total_time_factor + .checked_add(incease_total_time_factor) + .ok_or(ArithmeticError::Overflow)?; + // latest_time_factor only increases in not first gauge_deposit + let increase_latest_time_factor = gauge_info + .gauge_amount + .saturated_into::() + .checked_mul( + (current_block_number - gauge_info.gauge_last_block) + .saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.latest_time_factor = gauge_info + .latest_time_factor + .checked_add(increase_latest_time_factor) + .ok_or(ArithmeticError::Overflow)?; + incease_total_time_factor + }; + + gauge_info.gauge_last_block = current_block_number; + gauge_info.gauge_amount = gauge_info + .gauge_amount + .checked_add(&gauge_value) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.gauge_stop_block = gauge_info + .gauge_stop_block + .checked_add(&gauge_block) + .ok_or(ArithmeticError::Overflow)?; + + gauge_pool_info.total_time_factor = gauge_pool_info + .total_time_factor + .checked_add(incease_total_time_factor) + .ok_or(ArithmeticError::Overflow)?; + T::MultiCurrency::transfer( + gauge_pool_info.token, + who, + &gauge_pool_info.keeper, + gauge_value, + )?; + GaugeInfos::::insert(gid, who, gauge_info); + *gauge_pool_info_old = Some(gauge_pool_info); + Ok(()) + } else { + Err(Error::::GaugePoolNotExist)? + } + })?; + Ok(()) + } + + pub fn gauge_claim_inner(who: &AccountIdOf, gid: PoolId) -> DispatchResult { + if !GaugeInfos::::contains_key(gid, who) { + return Ok(()); + } + let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); + let mut gauge_pool_info = + GaugePoolInfos::::get(gid).ok_or(Error::::GaugePoolNotExist)?; + let pool_info = + PoolInfos::::get(gauge_pool_info.pid).ok_or(Error::::PoolDoesNotExist)?; + GaugeInfos::::mutate_exists(gid, who, |maybe_gauge_info| -> DispatchResult { + if let Some(mut gauge_info) = maybe_gauge_info.take() { + ensure!( + gauge_info.gauge_start_block <= current_block_number, + Error::::CanNotClaim + ); + let start_block = if current_block_number > gauge_info.gauge_stop_block { + gauge_info.gauge_stop_block + } else { + current_block_number + }; + + let latest_claimed_time_factor = gauge_info.latest_time_factor + + gauge_info + .gauge_amount + .saturated_into::() + .checked_mul( + (start_block - gauge_info.gauge_last_block).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let gauge_rate = Perbill::from_rational( + latest_claimed_time_factor - gauge_info.claimed_time_factor, + gauge_pool_info.total_time_factor, + ); + let total_shares = + U256::from(pool_info.total_shares.to_owned().saturated_into::()); + let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) + .ok_or(Error::::ShareInfoNotExists)?; + gauge_pool_info.rewards.iter_mut().try_for_each( + |( + reward_currency, + (reward_amount, total_gauged_reward, total_withdrawn_reward), + )| + -> DispatchResult { + let reward = reward_amount + .checked_sub(total_gauged_reward) + .ok_or(ArithmeticError::Overflow)?; + // gauge_reward = gauge rate * gauge rewards * existing rewards in the + // gauge pool + let gauge_reward = gauge_rate * reward; + // reward_to_claim = farming rate * gauge rate * gauge rewards * + // existing rewards in the gauge pool + let reward_to_claim: BalanceOf = + U256::from(share_info.share.to_owned().saturated_into::()) + .saturating_mul(U256::from( + gauge_reward.to_owned().saturated_into::(), + )) + .checked_div(total_shares) + .unwrap_or_default() + .as_u128() + .unique_saturated_into(); + *total_gauged_reward = total_gauged_reward + .checked_add(&gauge_reward) + .ok_or(ArithmeticError::Overflow)?; + *total_withdrawn_reward = total_withdrawn_reward + .checked_add(&reward_to_claim) + .ok_or(ArithmeticError::Overflow)?; + + let ed = T::MultiCurrency::minimum_balance(*reward_currency); + let mut account_to_send = who.clone(); + + if reward_to_claim < ed { + let receiver_balance = + T::MultiCurrency::total_balance(*reward_currency, who); + + let receiver_balance_after = receiver_balance + .checked_add(&reward_to_claim) + .ok_or(ArithmeticError::Overflow)?; + if receiver_balance_after < ed { + account_to_send = T::TreasuryAccount::get(); + } + } + T::MultiCurrency::transfer( + *reward_currency, + &gauge_pool_info.reward_issuer, + &account_to_send, + reward_to_claim, + ) + }, + )?; + gauge_info.last_claim_block = current_block_number; + gauge_info.claimed_time_factor = latest_claimed_time_factor; + if gauge_info.gauge_stop_block <= current_block_number { + let ed = T::MultiCurrency::minimum_balance(gauge_pool_info.token); + let mut account_to_send = who.clone(); + + if gauge_info.gauge_amount < ed { + let receiver_balance = + T::MultiCurrency::total_balance(gauge_pool_info.token, who); + + let receiver_balance_after = receiver_balance + .checked_add(&gauge_info.gauge_amount) + .ok_or(ArithmeticError::Overflow)?; + if receiver_balance_after < ed { + account_to_send = T::TreasuryAccount::get(); + } + } + T::MultiCurrency::transfer( + gauge_pool_info.token, + &gauge_pool_info.keeper, + &account_to_send, + gauge_info.gauge_amount, + )?; + gauge_pool_info.total_time_factor = gauge_pool_info + .total_time_factor + .checked_sub(gauge_info.total_time_factor) + .ok_or(ArithmeticError::Overflow)?; + gauge_pool_info.gauge_amount = gauge_pool_info + .gauge_amount + .checked_sub(&gauge_info.gauge_amount) + .ok_or(ArithmeticError::Overflow)?; + } else { + *maybe_gauge_info = Some(gauge_info); + }; + GaugePoolInfos::::insert(gid, gauge_pool_info); + } + Ok(()) + })?; + Ok(()) + } + + pub fn get_farming_rewards( + who: &T::AccountId, + pid: PoolId, + ) -> Result, DispatchError> { + let share_info = + SharesAndWithdrawnRewards::::get(pid, who).ok_or(Error::::ShareInfoNotExists)?; + let pool_info = PoolInfos::::get(pid).ok_or(Error::::PoolDoesNotExist)?; + let total_shares = U256::from(pool_info.total_shares.to_owned().saturated_into::()); + let mut result_vec = Vec::<(CurrencyIdOf, BalanceOf)>::new(); + + pool_info.rewards.iter().try_for_each( + |(reward_currency, (total_reward, total_withdrawn_reward))| -> DispatchResult { + let withdrawn_reward = share_info + .withdrawn_rewards + .get(reward_currency) + .copied() + .unwrap_or_default(); + + let total_reward_proportion: BalanceOf = + U256::from(share_info.share.to_owned().saturated_into::()) + .saturating_mul(U256::from( + total_reward.to_owned().saturated_into::(), + )) + .checked_div(total_shares) + .unwrap_or_default() + .as_u128() + .unique_saturated_into(); + + let reward_to_withdraw = total_reward_proportion + .saturating_sub(withdrawn_reward) + .min(total_reward.saturating_sub(*total_withdrawn_reward)); + + if reward_to_withdraw.is_zero() { + return Ok(()); + }; + + result_vec.push((*reward_currency, reward_to_withdraw)); + Ok(()) + }, + )?; + Ok(result_vec) + } + + pub fn get_gauge_rewards( + who: &T::AccountId, + pid: PoolId, + ) -> Result, DispatchError> { + let pool_info = PoolInfos::::get(pid).ok_or(Error::::PoolDoesNotExist)?; + let mut result_vec = Vec::<(CurrencyIdOf, BalanceOf)>::new(); + + match pool_info.gauge { + None => (), + Some(gid) => { + let current_block_number: BlockNumberFor = + frame_system::Pallet::::block_number(); + let gauge_pool_info = + GaugePoolInfos::::get(gid).ok_or(Error::::GaugePoolNotExist)?; + let gauge_info = + GaugeInfos::::get(gid, who).ok_or(Error::::GaugeInfoNotExist)?; + let start_block = if current_block_number > gauge_info.gauge_stop_block { + gauge_info.gauge_stop_block + } else { + current_block_number + }; + + let latest_claimed_time_factor = gauge_info.latest_time_factor + + gauge_info + .gauge_amount + .saturated_into::() + .checked_mul( + (start_block - gauge_info.gauge_last_block).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let gauge_rate = Perbill::from_rational( + latest_claimed_time_factor - gauge_info.claimed_time_factor, + gauge_pool_info.total_time_factor, + ); + let total_shares = + U256::from(pool_info.total_shares.to_owned().saturated_into::()); + let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) + .ok_or(Error::::ShareInfoNotExists)?; + gauge_pool_info.rewards.iter().try_for_each( + |( + reward_currency, + (reward_amount, total_gauged_reward, _total_withdrawn_reward), + )| + -> DispatchResult { + let reward = reward_amount + .checked_sub(total_gauged_reward) + .ok_or(ArithmeticError::Overflow)?; + // gauge_reward = gauge rate * gauge rewards * existing rewards in the + // gauge pool + let gauge_reward = gauge_rate * reward; + // reward_to_claim = farming rate * gauge rate * gauge rewards * + // existing rewards in the gauge pool + let reward_to_claim: BalanceOf = + U256::from(share_info.share.to_owned().saturated_into::()) + .saturating_mul(U256::from( + gauge_reward.to_owned().saturated_into::(), + )) + .checked_div(total_shares) + .unwrap_or_default() + .as_u128() + .unique_saturated_into(); + result_vec.push((*reward_currency, reward_to_claim)); + Ok(()) + }, + )?; + } + }; + Ok(result_vec) + } +} diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs new file mode 100644 index 000000000..dda9bb22c --- /dev/null +++ b/pallets/farming/src/lib.rs @@ -0,0 +1,838 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +use frame_support::{ + pallet_prelude::*, + sp_runtime::{ + traits::{AccountIdConversion, AtLeast32BitUnsigned, Saturating, Zero}, + ArithmeticError, Perbill, + }, + PalletId, +}; +use frame_system::pallet_prelude::*; +use manta_primitives::types::PoolId; +use orml_traits::MultiCurrency; +use sp_runtime::SaturatedConversion; +use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; + +pub mod gauge; +pub mod rewards; +pub mod weights; + +pub use gauge::*; +pub use pallet::*; +pub use rewards::*; +pub use weights::WeightInfo; + +#[allow(type_alias_bounds)] +pub type AccountIdOf = ::AccountId; + +#[allow(type_alias_bounds)] +pub type CurrencyIdOf = <::MultiCurrency as MultiCurrency< + ::AccountId, +>>::CurrencyId; + +#[allow(type_alias_bounds)] +type BalanceOf = + <::MultiCurrency as MultiCurrency>>::Balance; + +#[allow(type_alias_bounds)] +type GauseInitType = ( + CurrencyIdOf, + BlockNumberFor, + Vec<(CurrencyIdOf, BalanceOf)>, +); + +#[allow(type_alias_bounds)] +type PoolInfoOf = + PoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>; + +#[allow(type_alias_bounds)] +type GaugePoolInfoOf = + GaugePoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>; + +#[allow(type_alias_bounds)] +type GaugeInfoOf = GaugeInfo, BlockNumberFor, AccountIdOf>; + +#[allow(type_alias_bounds)] +type ShareInfoOf = ShareInfo, CurrencyIdOf, BlockNumberFor, AccountIdOf>; + +#[allow(type_alias_bounds)] +type RewardOf = Vec<(CurrencyIdOf, BalanceOf)>; + +#[frame_support::pallet] +#[allow(clippy::too_many_arguments)] +pub mod pallet { + use super::*; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The currency ID type + type CurrencyId: Parameter + + AtLeast32BitUnsigned + + Default //TODO: remove Default trait bound + + Member + + Copy + + MaybeSerializeDeserialize + + Ord + + TypeInfo + + MaxEncodedLen; + + /// ORML MultiCurrency + type MultiCurrency: MultiCurrency, CurrencyId = Self::CurrencyId>; + + /// ROOT Origin + type ControlOrigin: EnsureOrigin; + + /// Set default weight. + type WeightInfo: WeightInfo; + + #[pallet::constant] + type TreasuryAccount: Get; + + /// ModuleID for creating sub account + #[pallet::constant] + type Keeper: Get; + + #[pallet::constant] + type RewardIssuer: Get; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + FarmingPoolCreated { + pid: PoolId, + }, + FarmingPoolReset { + pid: PoolId, + }, + FarmingPoolClosed { + pid: PoolId, + }, + FarmingPoolKilled { + pid: PoolId, + }, + FarmingPoolEdited { + pid: PoolId, + }, + Charged { + who: AccountIdOf, + pid: PoolId, + rewards: Vec<(CurrencyIdOf, BalanceOf)>, + }, + Deposited { + who: AccountIdOf, + pid: PoolId, + add_value: BalanceOf, + gauge_info: Option<(BalanceOf, BlockNumberFor)>, + }, + Withdrawn { + who: AccountIdOf, + pid: PoolId, + remove_value: Option>, + }, + Claimed { + who: AccountIdOf, + pid: PoolId, + }, + WithdrawClaimed { + who: AccountIdOf, + pid: PoolId, + }, + GaugeWithdrawn { + who: AccountIdOf, + gid: PoolId, + }, + AllForceGaugeClaimed { + gid: PoolId, + }, + PartiallyForceGaugeClaimed { + gid: PoolId, + }, + AllRetired { + pid: PoolId, + }, + PartiallyRetired { + pid: PoolId, + }, + RetireLimitSet { + limit: u32, + }, + } + + #[pallet::error] + pub enum Error { + CalculationOverflow, + PoolDoesNotExist, + GaugePoolNotExist, + GaugeInfoNotExist, + InvalidPoolState, + LastGaugeNotClaim, + /// claim_limit_time exceeded + CanNotClaim, + /// gauge pool max_block exceeded + GaugeMaxBlockOverflow, + /// withdraw_limit_time exceeded + WithdrawLimitCountExceeded, + ShareInfoNotExists, + CanNotDeposit, + } + + #[pallet::storage] + #[pallet::getter(fn pool_next_id)] + pub type PoolNextId = StorageValue<_, PoolId, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn gauge_pool_next_id)] + pub type GaugePoolNextId = StorageValue<_, PoolId, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn retire_limit)] + pub type RetireLimit = StorageValue<_, u32, ValueQuery>; + + /// Record reward pool info. + /// + /// map PoolId => PoolInfo + #[pallet::storage] + #[pallet::getter(fn pool_infos)] + pub type PoolInfos = StorageMap<_, Twox64Concat, PoolId, PoolInfoOf>; + + /// Record gauge farming pool info. + /// + /// map PoolId => GaugePoolInfo + #[pallet::storage] + #[pallet::getter(fn gauge_pool_infos)] + pub type GaugePoolInfos = StorageMap<_, Twox64Concat, PoolId, GaugePoolInfoOf>; + + #[pallet::storage] + #[pallet::getter(fn gauge_infos)] + pub type GaugeInfos = + StorageDoubleMap<_, Twox64Concat, PoolId, Twox64Concat, T::AccountId, GaugeInfoOf>; + + /// Record share amount, reward currency and withdrawn reward amount for + /// specific `AccountId` under `PoolId`. + /// + /// double_map (PoolId, AccountId) => ShareInfo + #[pallet::storage] + #[pallet::getter(fn shares_and_withdrawn_rewards)] + pub type SharesAndWithdrawnRewards = + StorageDoubleMap<_, Twox64Concat, PoolId, Twox64Concat, T::AccountId, ShareInfoOf>; + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: BlockNumberFor) -> Weight { + PoolInfos::::iter().for_each(|(pid, mut pool_info)| match pool_info.state { + PoolState::Ongoing => { + pool_info.basic_rewards.clone().iter().for_each( + |(reward_currency_id, reward_amount)| { + pool_info + .rewards + .entry(*reward_currency_id) + .and_modify(|(total_reward, _)| { + *total_reward = total_reward.saturating_add(*reward_amount); + }) + .or_insert((*reward_amount, Zero::zero())); + }, + ); + PoolInfos::::insert(pid, &pool_info); + } + PoolState::Charged => { + if n >= pool_info.after_block_to_start + && pool_info.total_shares >= pool_info.min_deposit_to_start + { + pool_info.block_startup = Some(n); + pool_info.state = PoolState::Ongoing; + } + PoolInfos::::insert(pid, &pool_info); + } + _ => (), + }); + + GaugePoolInfos::::iter().for_each(|(gid, mut gauge_pool_info)| { + if gauge_pool_info.gauge_state == GaugeState::Bonded { + gauge_pool_info.gauge_basic_rewards.clone().iter().for_each( + |(reward_currency_id, reward_amount)| { + gauge_pool_info + .rewards + .entry(*reward_currency_id) + .and_modify(|(total_reward, _, _)| { + *total_reward = total_reward.saturating_add(*reward_amount); + }) + .or_insert((*reward_amount, Zero::zero(), Zero::zero())); + }, + ); + GaugePoolInfos::::insert(gid, &gauge_pool_info); + } + }); + + T::WeightInfo::on_initialize() + } + } + + #[pallet::call] + impl Pallet + where + BlockNumberFor: AtLeast32BitUnsigned + Copy, + BalanceOf: AtLeast32BitUnsigned + Copy, + { + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::create_farming_pool())] + pub fn create_farming_pool( + origin: OriginFor, + tokens_proportion: Vec<(CurrencyIdOf, Perbill)>, + basic_rewards: Vec<(CurrencyIdOf, BalanceOf)>, + gauge_init: Option>, + min_deposit_to_start: BalanceOf, + #[pallet::compact] after_block_to_start: BlockNumberFor, + #[pallet::compact] withdraw_limit_time: BlockNumberFor, + #[pallet::compact] claim_limit_time: BlockNumberFor, + withdraw_limit_count: u8, + ) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let pid = Self::pool_next_id(); + let keeper = T::Keeper::get().into_sub_account_truncating(pid); + let reward_issuer = T::RewardIssuer::get().into_sub_account_truncating(pid); + let basic_token = tokens_proportion[0]; + let tokens_proportion_map: BTreeMap, Perbill> = + tokens_proportion.into_iter().map(|(k, v)| (k, v)).collect(); + let basic_rewards_map: BTreeMap, BalanceOf> = + basic_rewards.into_iter().map(|(k, v)| (k, v)).collect(); + + let mut pool_info = PoolInfo::new( + keeper, + reward_issuer, + tokens_proportion_map, + basic_token, + basic_rewards_map, + None, + min_deposit_to_start, + after_block_to_start, + withdraw_limit_time, + claim_limit_time, + withdraw_limit_count, + ); + + if let Some((gauge_token, max_block, gauge_basic_rewards)) = gauge_init { + let gauge_basic_rewards_map: BTreeMap, BalanceOf> = + gauge_basic_rewards + .into_iter() + .map(|(k, v)| (k, v)) + .collect(); + + Self::create_gauge_pool( + pid, + &mut pool_info, + gauge_token, + gauge_basic_rewards_map, + max_block, + )?; + }; + + PoolInfos::::insert(pid, &pool_info); + PoolNextId::::mutate(|id| -> DispatchResult { + *id = id.checked_add(1).ok_or(ArithmeticError::Overflow)?; + Ok(()) + })?; + + Self::deposit_event(Event::FarmingPoolCreated { pid }); + Ok(()) + } + + #[pallet::call_index(1)] + #[pallet::weight(0)] + pub fn charge( + origin: OriginFor, + pid: PoolId, + rewards: Vec<(CurrencyIdOf, BalanceOf)>, + ) -> DispatchResult { + let exchanger = ensure_signed(origin)?; + + let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + // ensure!(pool_info.state == PoolState::UnCharged, Error::::InvalidPoolState); + rewards + .iter() + .try_for_each(|(reward_currency, reward)| -> DispatchResult { + // let bal = T::MultiCurrency::free_balance(reward_currency.clone(), &exchanger); + // log::info!("token:{:?},balance:{:?},ex:{:?}", reward_currency.clone(), bal, &exchanger); + T::MultiCurrency::transfer( + *reward_currency, + &exchanger, + &pool_info.reward_issuer, + *reward, + ) + })?; + pool_info.state = PoolState::Charged; + PoolInfos::::insert(pid, pool_info); + + Self::deposit_event(Event::Charged { + who: exchanger, + pid, + rewards, + }); + Ok(()) + } + + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::deposit())] + pub fn deposit( + origin: OriginFor, + pid: PoolId, + add_value: BalanceOf, + gauge_info: Option<(BalanceOf, BlockNumberFor)>, + ) -> DispatchResult { + let exchanger = ensure_signed(origin)?; + + let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::Deposit, pool_info.state), + Error::::InvalidPoolState + ); + + if let PoolState::Charged = pool_info.state { + let n: BlockNumberFor = frame_system::Pallet::::block_number(); + ensure!( + n >= pool_info.after_block_to_start, + Error::::CanNotDeposit + ); + } + + let native_amount = pool_info.basic_token.1.saturating_reciprocal_mul(add_value); + pool_info.tokens_proportion.iter().try_for_each( + |(token, proportion)| -> DispatchResult { + // let bal = T::MultiCurrency::free_balance(token.clone(), &exchanger); + // log::info!("token:{:?},balance:{:?},ex:{:?}", token.clone(), bal, &exchanger); + T::MultiCurrency::transfer( + *token, + &exchanger, + &pool_info.keeper, + *proportion * native_amount, + ) + }, + )?; + Self::add_share(&exchanger, pid, &mut pool_info, add_value); + + if let Some((gauge_value, gauge_block)) = gauge_info { + Self::gauge_add( + &exchanger, + pool_info.gauge.ok_or(Error::::GaugePoolNotExist)?, + gauge_value, + gauge_block, + )?; + } + + Self::deposit_event(Event::Deposited { + who: exchanger, + pid, + add_value, + gauge_info, + }); + Ok(()) + } + + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::withdraw())] + pub fn withdraw( + origin: OriginFor, + pid: PoolId, + remove_value: Option>, + ) -> DispatchResult { + let exchanger = ensure_signed(origin)?; + + let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::Withdraw, pool_info.state), + Error::::InvalidPoolState + ); + + let share_info = Self::shares_and_withdrawn_rewards(pid, &exchanger) + .ok_or(Error::::ShareInfoNotExists)?; + ensure!( + share_info.withdraw_list.len() < pool_info.withdraw_limit_count.into(), + Error::::WithdrawLimitCountExceeded + ); + + Self::remove_share(&exchanger, pid, remove_value, pool_info.withdraw_limit_time)?; + + Self::deposit_event(Event::Withdrawn { + who: exchanger, + pid, + remove_value, + }); + Ok(()) + } + + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::claim())] + pub fn claim(origin: OriginFor, pid: PoolId) -> DispatchResult { + let exchanger = ensure_signed(origin)?; + + let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::Claim, pool_info.state), + Error::::InvalidPoolState + ); + + let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); + let share_info = Self::shares_and_withdrawn_rewards(pid, &exchanger) + .ok_or(Error::::ShareInfoNotExists)?; + ensure!( + share_info.claim_last_block + pool_info.claim_limit_time <= current_block_number, + Error::::CanNotClaim + ); + + Self::claim_rewards(&exchanger, pid)?; + if let Some(ref gid) = pool_info.gauge { + Self::gauge_claim_inner(&exchanger, *gid)?; + } + Self::process_withdraw_list(&exchanger, pid, &pool_info, true)?; + + Self::deposit_event(Event::Claimed { + who: exchanger, + pid, + }); + Ok(()) + } + + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::claim())] + pub fn withdraw_claim(origin: OriginFor, pid: PoolId) -> DispatchResult { + let exchanger = ensure_signed(origin)?; + + let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + Self::process_withdraw_list(&exchanger, pid, &pool_info, false)?; + + Self::deposit_event(Event::WithdrawClaimed { + who: exchanger, + pid, + }); + Ok(()) + } + + #[pallet::call_index(6)] + #[pallet::weight(0)] + pub fn force_retire_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::ForceRetirePool, pool_info.state), + Error::::InvalidPoolState + ); + + let withdraw_limit_time = BlockNumberFor::::default(); + let retire_limit = RetireLimit::::get(); + let mut all_retired = true; + let share_infos = SharesAndWithdrawnRewards::::iter_prefix_values(pid); + for (retire_count, share_info) in share_infos.enumerate() { + if retire_count.saturated_into::() >= retire_limit { + all_retired = false; + break; + } + let who = share_info.who; + Self::remove_share(&who, pid, None, withdraw_limit_time)?; + Self::claim_rewards(&who, pid)?; + if let Some(ref gid) = pool_info.gauge { + Self::gauge_claim_inner(&who, *gid)?; + } + Self::process_withdraw_list(&who, pid, &pool_info, true)?; + } + + if all_retired { + if let Some(ref gid) = pool_info.gauge { + let mut gauge_pool_info = + Self::gauge_pool_infos(gid).ok_or(Error::::GaugePoolNotExist)?; + gauge_pool_info.gauge_state = GaugeState::Unbond; + GaugePoolInfos::::insert(gid, gauge_pool_info); + } + pool_info.state = PoolState::Retired; + pool_info.gauge = None; + PoolInfos::::insert(pid, pool_info); + Self::deposit_event(Event::AllRetired { pid }); + } else { + Self::deposit_event(Event::PartiallyRetired { pid }); + } + Ok(()) + } + + #[pallet::call_index(7)] + #[pallet::weight(0)] + pub fn set_retire_limit(origin: OriginFor, limit: u32) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + RetireLimit::::mutate(|old_limit| { + *old_limit = limit; + }); + + Self::deposit_event(Event::RetireLimitSet { limit }); + Ok(()) + } + + #[pallet::call_index(8)] + #[pallet::weight(0)] + pub fn close_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::ClosePool, pool_info.state), + Error::::InvalidPoolState + ); + + pool_info.state = PoolState::Dead; + PoolInfos::::insert(pid, pool_info); + + Self::deposit_event(Event::FarmingPoolClosed { pid }); + Ok(()) + } + + #[pallet::call_index(9)] + #[pallet::weight(0)] + pub fn reset_pool( + origin: OriginFor, + pid: PoolId, + basic_rewards: Option, BalanceOf)>>, + min_deposit_to_start: Option>, + after_block_to_start: Option>, + withdraw_limit_time: Option>, + claim_limit_time: Option>, + withdraw_limit_count: Option, + gauge_init: Option>, + ) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::ResetPool, pool_info.state), + Error::::InvalidPoolState + ); + + if let Some(basic_rewards) = basic_rewards { + let basic_rewards_map: BTreeMap, BalanceOf> = + basic_rewards.into_iter().map(|(k, v)| (k, v)).collect(); + pool_info.basic_rewards = basic_rewards_map; + }; + if let Some(min_deposit_to_start) = min_deposit_to_start { + pool_info.min_deposit_to_start = min_deposit_to_start; + }; + if let Some(after_block_to_start) = after_block_to_start { + pool_info.after_block_to_start = after_block_to_start; + }; + if let Some(withdraw_limit_time) = withdraw_limit_time { + pool_info.withdraw_limit_time = withdraw_limit_time; + }; + if let Some(claim_limit_time) = claim_limit_time { + pool_info.claim_limit_time = claim_limit_time; + }; + if let Some(withdraw_limit_count) = withdraw_limit_count { + pool_info.withdraw_limit_count = withdraw_limit_count; + }; + if let Some((gauge_token, max_block, gauge_basic_rewards)) = gauge_init { + let gauge_basic_rewards_map: BTreeMap, BalanceOf> = + gauge_basic_rewards + .into_iter() + .map(|(k, v)| (k, v)) + .collect(); + + Self::create_gauge_pool( + pid, + &mut pool_info, + gauge_token, + gauge_basic_rewards_map, + max_block, + )?; + }; + pool_info.total_shares = Default::default(); + pool_info.rewards = BTreeMap::new(); + pool_info.state = PoolState::UnCharged; + pool_info.block_startup = None; + PoolInfos::::insert(pid, &pool_info); + + Self::deposit_event(Event::FarmingPoolReset { pid }); + Ok(()) + } + + #[pallet::call_index(10)] + #[pallet::weight(0)] + pub fn kill_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + pool_info.state == PoolState::Retired || pool_info.state == PoolState::UnCharged, + Error::::InvalidPoolState + ); + #[allow(deprecated)] + SharesAndWithdrawnRewards::::remove_prefix(pid, None); + PoolInfos::::remove(pid); + + Self::deposit_event(Event::FarmingPoolKilled { pid }); + Ok(()) + } + + #[pallet::call_index(11)] + #[pallet::weight(0)] + pub fn edit_pool( + origin: OriginFor, + pid: PoolId, + basic_rewards: Option, BalanceOf)>>, + withdraw_limit_time: Option>, + claim_limit_time: Option>, + gauge_basic_rewards: Option, BalanceOf)>>, + withdraw_limit_count: Option, + ) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::EditPool, pool_info.state), + Error::::InvalidPoolState + ); + + if let Some(basic_rewards) = basic_rewards { + let basic_rewards_map: BTreeMap, BalanceOf> = + basic_rewards.into_iter().map(|(k, v)| (k, v)).collect(); + pool_info.basic_rewards = basic_rewards_map; + }; + if let Some(withdraw_limit_time) = withdraw_limit_time { + pool_info.withdraw_limit_time = withdraw_limit_time; + }; + if let Some(claim_limit_time) = claim_limit_time { + pool_info.claim_limit_time = claim_limit_time; + }; + if let Some(withdraw_limit_count) = withdraw_limit_count { + pool_info.withdraw_limit_count = withdraw_limit_count; + }; + if let Some(gauge_basic_rewards) = gauge_basic_rewards { + let gauge_basic_rewards_map: BTreeMap, BalanceOf> = + gauge_basic_rewards + .into_iter() + .map(|(k, v)| (k, v)) + .collect(); + GaugePoolInfos::::mutate( + pool_info.gauge.ok_or(Error::::GaugePoolNotExist)?, + |gauge_pool_info_old| { + if let Some(mut gauge_pool_info) = gauge_pool_info_old.take() { + gauge_pool_info.gauge_basic_rewards = gauge_basic_rewards_map; + *gauge_pool_info_old = Some(gauge_pool_info); + } + }, + ); + }; + PoolInfos::::insert(pid, &pool_info); + + Self::deposit_event(Event::FarmingPoolEdited { pid }); + Ok(()) + } + + #[pallet::call_index(12)] + #[pallet::weight(T::WeightInfo::gauge_withdraw())] + pub fn gauge_withdraw(origin: OriginFor, gid: PoolId) -> DispatchResult { + let who = ensure_signed(origin)?; + + let mut gauge_pool_info = + GaugePoolInfos::::get(gid).ok_or(Error::::GaugePoolNotExist)?; + match gauge_pool_info.gauge_state { + GaugeState::Bonded => { + Self::gauge_claim_inner(&who, gid)?; + } + GaugeState::Unbond => { + let current_block_number: BlockNumberFor = + frame_system::Pallet::::block_number(); + GaugeInfos::::mutate(gid, &who, |maybe_gauge_info| -> DispatchResult { + if let Some(gauge_info) = maybe_gauge_info.take() { + if gauge_info.gauge_stop_block <= current_block_number { + T::MultiCurrency::transfer( + gauge_pool_info.token, + &gauge_pool_info.keeper, + &who, + gauge_info.gauge_amount, + )?; + gauge_pool_info.total_time_factor = gauge_pool_info + .total_time_factor + .checked_sub(gauge_info.total_time_factor) + .ok_or(ArithmeticError::Overflow)?; + GaugePoolInfos::::insert(gid, gauge_pool_info); + } else { + *maybe_gauge_info = Some(gauge_info); + }; + } + Ok(()) + })?; + } + } + + Self::deposit_event(Event::GaugeWithdrawn { who, gid }); + Ok(()) + } + + #[pallet::call_index(13)] + #[pallet::weight(0)] + pub fn force_gauge_claim(origin: OriginFor, gid: PoolId) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let gauge_infos = GaugeInfos::::iter_prefix_values(gid); + let retire_limit = RetireLimit::::get(); + let mut all_retired = true; + for (retire_count, gauge_info) in gauge_infos.enumerate() { + if retire_count.saturated_into::() >= retire_limit { + all_retired = false; + break; + } + Self::gauge_claim_inner(&gauge_info.who, gid)?; + } + + if all_retired { + Self::deposit_event(Event::AllForceGaugeClaimed { gid }); + } else { + Self::deposit_event(Event::PartiallyForceGaugeClaimed { gid }); + } + Ok(()) + } + } +} + +// impl FarmingInfo, CurrencyIdOf> for Pallet { +// fn get_token_shares(pool_id: PoolId, currency_id: CurrencyIdOf) -> BalanceOf { +// if let Some(pool_info) = Self::pool_infos(&pool_id) { +// if let Some(token_proportion_value) = pool_info.tokens_proportion.get(¤cy_id) { +// let native_amount = +// pool_info.basic_token.1.saturating_reciprocal_mul(pool_info.total_shares); +// return *token_proportion_value * native_amount; +// } +// } +// Zero::zero() +// } +// } diff --git a/pallets/farming/src/migration.rs b/pallets/farming/src/migration.rs new file mode 100644 index 000000000..c170f2ea8 --- /dev/null +++ b/pallets/farming/src/migration.rs @@ -0,0 +1,84 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +// use super::{Config, RelaychainLease, Weight}; +use crate::*; +use codec::HasCompact; +use frame_support::traits::Get; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; + +/// The Reward Pool Info. +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct DeprecatedPoolInfo +{ + pub tokens_proportion: BTreeMap, + /// Total shares amount + pub total_shares: BalanceOf, + pub basic_rewards: BTreeMap, + /// Reward infos + pub rewards: BTreeMap, + pub state: PoolState, + pub keeper: AccountIdOf, + pub reward_issuer: AccountIdOf, + /// Gauge pool id + pub gauge: Option, + pub block_startup: Option, + pub min_deposit_to_start: BalanceOf, + pub after_block_to_start: BlockNumberFor, + pub withdraw_limit_time: BlockNumberFor, + pub claim_limit_time: BlockNumberFor, + pub withdraw_limit_count: u8, +} + +#[allow(dead_code)] +pub fn update_pool_info() -> Weight { + let _ = PoolInfos::::translate::< + DeprecatedPoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, + _, + >( + |_key, + pool| + -> Option, CurrencyIdOf, AccountIdOf, BlockNumberFor>> { + // if let Some(pool) = pool_info { + let a = pool.tokens_proportion.keys().cloned().collect::>>()[0]; + let b = pool.tokens_proportion.values().cloned().collect::>()[0]; + let new_entry = + PoolInfo::, CurrencyIdOf, AccountIdOf, BlockNumberFor> { + tokens_proportion: pool.tokens_proportion, + basic_token: (a, b), + total_shares: pool.total_shares, + basic_rewards: pool.basic_rewards, + rewards: pool.rewards, + state: pool.state, + keeper: pool.keeper, + reward_issuer: pool.reward_issuer, + gauge: pool.gauge, + block_startup: pool.block_startup, + min_deposit_to_start: pool.min_deposit_to_start, + after_block_to_start: pool.after_block_to_start, + withdraw_limit_time: pool.withdraw_limit_time, + claim_limit_time: pool.claim_limit_time, + withdraw_limit_count: pool.withdraw_limit_count, + }; + Some(new_entry) + // } else { + // None + // } + }, + ); + + T::DbWeight::get().reads(1) + T::DbWeight::get().writes(1) +} diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs new file mode 100644 index 000000000..847ccae97 --- /dev/null +++ b/pallets/farming/src/mock.rs @@ -0,0 +1,366 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +// Ensure we're `no_std` when compiling for Wasm. + +#![cfg(test)] +#![allow(non_upper_case_globals)] + +use frame_support::{ + dispatch::DispatchResult, + ord_parameter_types, parameter_types, + traits::{AsEnsureOriginWithArg, EitherOfDiverse, GenesisBuild}, + PalletId, +}; +use frame_system::{EnsureNever, EnsureRoot, EnsureSignedBy}; +// use manta_primitives::{CurrencyId, TokenSymbol}; +use manta_primitives::{ + assets::{ + AssetConfig, AssetIdType, AssetLocation, AssetRegistry, AssetRegistryMetadata, + AssetStorageMetadata, BalanceType, LocationType, NativeAndNonNative, + }, + constants::ASSET_MANAGER_PALLET_ID, + currencies::Currencies, + types::{CalamariAssetId, DolphinAssetId}, +}; +use sp_core::{ConstU32, H256}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + AccountId32, +}; +use xcm::{ + prelude::{Parachain, X1}, + v2::MultiLocation, + VersionedMultiLocation, +}; + +use crate as manta_farming; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +pub const KSM: DolphinAssetId = 8; + +pub const ALICE: AccountId = AccountId32::new([0u8; 32]); +pub const BOB: AccountId = AccountId32::new([1u8; 32]); +pub const CHARLIE: AccountId = AccountId32::new([3u8; 32]); +pub const TREASURY_ACCOUNT: AccountId = AccountId32::new([9u8; 32]); + +frame_support::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}, + Assets: pallet_assets::{Pallet, Storage, Config, Event}, + AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event}, + Farming: manta_farming::{Pallet, Call, Storage, Event} + } +); + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} +impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData; + type AccountId = AccountId; + type BaseCallFilter = frame_support::traits::Everything; + type BlockHashCount = BlockHashCount; + type BlockLength = (); + type BlockNumber = u64; + type BlockWeights = (); + type RuntimeCall = RuntimeCall; + type DbWeight = (); + type RuntimeEvent = RuntimeEvent; + type Hash = H256; + type Hashing = BlakeTwo256; + type Header = Header; + type Index = u64; + type Lookup = IdentityLookup; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type RuntimeOrigin = RuntimeOrigin; + type PalletInfo = PalletInfo; + type SS58Prefix = (); + type SystemWeightInfo = (); + type Version = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1; +} +impl pallet_balances::Config for Runtime { + type AccountStore = frame_system::Pallet; + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); +} + +parameter_types! { + // Does not really matter as this will be only called by root + pub const AssetDeposit: Balance = 0; + pub const AssetAccountDeposit: Balance = 0; + pub const ApprovalDeposit: Balance = 0; + pub const AssetsStringLimit: u32 = 50; + pub const MetadataDepositBase: Balance = 0; + pub const MetadataDepositPerByte: Balance = 0; +} + +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type AssetId = CalamariAssetId; + type Currency = Balances; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type AssetAccountDeposit = AssetAccountDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = pallet_assets::weights::SubstrateWeight; + type RemoveItemsLimit = ConstU32<1000>; + type AssetIdParameter = CalamariAssetId; + type CreateOrigin = AsEnsureOriginWithArg>; + type CallbackHandle = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + +pub struct MantaAssetRegistry; +impl BalanceType for MantaAssetRegistry { + type Balance = Balance; +} +impl AssetIdType for MantaAssetRegistry { + type AssetId = CalamariAssetId; +} +impl AssetRegistry for MantaAssetRegistry { + type Metadata = AssetStorageMetadata; + type Error = sp_runtime::DispatchError; + + fn create_asset( + asset_id: CalamariAssetId, + metadata: AssetStorageMetadata, + min_balance: Balance, + is_sufficient: bool, + ) -> DispatchResult { + Assets::force_create( + RuntimeOrigin::root(), + asset_id, + AssetManager::account_id(), + is_sufficient, + min_balance, + )?; + + Assets::force_set_metadata( + RuntimeOrigin::root(), + asset_id, + metadata.name, + metadata.symbol, + metadata.decimals, + metadata.is_frozen, + )?; + + Assets::force_asset_status( + RuntimeOrigin::root(), + asset_id, + AssetManager::account_id(), + AssetManager::account_id(), + AssetManager::account_id(), + AssetManager::account_id(), + min_balance, + is_sufficient, + metadata.is_frozen, + ) + } + + fn update_asset_metadata( + asset_id: &CalamariAssetId, + metadata: AssetStorageMetadata, + ) -> DispatchResult { + Assets::force_set_metadata( + RuntimeOrigin::root(), + *asset_id, + metadata.name, + metadata.symbol, + metadata.decimals, + metadata.is_frozen, + ) + } +} + +parameter_types! { + pub const DummyAssetId: CalamariAssetId = 0; + pub const NativeAssetId: CalamariAssetId = 1; + pub const StartNonNativeAssetId: CalamariAssetId = 8; + pub NativeAssetLocation: AssetLocation = AssetLocation( + VersionedMultiLocation::V1(MultiLocation::new(1, X1(Parachain(1024))))); + pub NativeAssetMetadata: AssetRegistryMetadata = AssetRegistryMetadata { + metadata: AssetStorageMetadata { + name: b"Calamari".to_vec(), + symbol: b"KAR".to_vec(), + decimals: 12, + is_frozen: false, + }, + min_balance: 1u128, + is_sufficient: true, + }; + pub const AssetManagerPalletId: PalletId = ASSET_MANAGER_PALLET_ID; +} + +/// AssetConfig implementations for this runtime +#[derive(Clone, Eq, PartialEq)] +pub struct MantaAssetConfig; +impl LocationType for MantaAssetConfig { + type Location = AssetLocation; +} +impl AssetIdType for MantaAssetConfig { + type AssetId = CalamariAssetId; +} +impl BalanceType for MantaAssetConfig { + type Balance = Balance; +} +impl AssetConfig for MantaAssetConfig { + type NativeAssetId = NativeAssetId; + type StartNonNativeAssetId = StartNonNativeAssetId; + type AssetRegistryMetadata = AssetRegistryMetadata; + type NativeAssetLocation = NativeAssetLocation; + type NativeAssetMetadata = NativeAssetMetadata; + type StorageMetadata = AssetStorageMetadata; + type AssetRegistry = MantaAssetRegistry; + type FungibleLedger = NativeAndNonNative; +} + +impl pallet_asset_manager::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AssetId = CalamariAssetId; + type Balance = Balance; + type Location = AssetLocation; + type AssetConfig = MantaAssetConfig; + type ModifierOrigin = EnsureRoot; + type SuspenderOrigin = EnsureRoot; + type PalletId = AssetManagerPalletId; + type WeightInfo = (); +} + +parameter_types! { + pub const FarmingKeeperPalletId: PalletId = PalletId(*b"bf/fmkpr"); + pub const FarmingRewardIssuerPalletId: PalletId = PalletId(*b"bf/fmrir"); + pub const TreasuryAccount: AccountId32 = TREASURY_ACCOUNT; +} + +ord_parameter_types! { + pub const One: AccountId = ALICE; +} + +type MantaCurrencies = Currencies; + +impl manta_farming::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CurrencyId = CalamariAssetId; + type MultiCurrency = MantaCurrencies; + type ControlOrigin = EitherOfDiverse, EnsureSignedBy>; + type TreasuryAccount = TreasuryAccount; + type Keeper = FarmingKeeperPalletId; + type RewardIssuer = FarmingRewardIssuerPalletId; + type WeightInfo = (); +} + +#[derive(Default)] +pub struct ExtBuilder { + endowed_accounts: Vec<(AccountId, CalamariAssetId, Balance)>, +} + +impl ExtBuilder { + pub fn balances( + mut self, + endowed_accounts: Vec<(AccountId, CalamariAssetId, Balance)>, + ) -> Self { + self.endowed_accounts = endowed_accounts; + self + } + + pub fn one_hundred_for_alice_n_bob(self) -> Self { + self.balances(vec![ + (ALICE, 1, 100), + (BOB, 1, 100), + (CHARLIE, 1, 100), + (ALICE, KSM, 3000), + (BOB, KSM, 10000000), + ]) + } + + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + let initial_asset_accounts = self + .endowed_accounts + .clone() + .into_iter() + .filter(|(_, asset_id, _)| *asset_id != 1) + .map(|(account_id, asset_id, initial_balance)| (asset_id, account_id, initial_balance)) + .collect::>(); + + let config: pallet_assets::GenesisConfig = pallet_assets::GenesisConfig { + assets: vec![ + // id, owner, is_sufficient, min_balance + (KSM, ALICE, true, 1), + ], + metadata: vec![ + // id, name, symbol, decimals + (KSM, "KSM".into(), "Kusama".into(), 12), + ], + accounts: initial_asset_accounts, + }; + config.assimilate_storage(&mut t).unwrap(); + + pallet_asset_manager::GenesisConfig:: { + start_id: >::StartNonNativeAssetId::get() + 1, + } + .assimilate_storage(&mut t) + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: self + .endowed_accounts + .into_iter() + .filter(|(_, asset_id, _)| *asset_id == 1) + .map(|(account_id, _, initial_balance)| (account_id, initial_balance)) + .collect::>(), + } + .assimilate_storage(&mut t) + .unwrap(); + + sp_io::TestExternalities::new(t) + } +} diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs new file mode 100644 index 000000000..66ee2746d --- /dev/null +++ b/pallets/farming/src/rewards.rs @@ -0,0 +1,479 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +use crate::*; +use codec::HasCompact; +use scale_info::TypeInfo; +use sp_core::U256; +use sp_runtime::{ + traits::{CheckedAdd, Saturating, UniqueSaturatedInto, Zero}, + RuntimeDebug, SaturatedConversion, +}; +use sp_std::{borrow::ToOwned, collections::btree_map::BTreeMap, prelude::*}; + +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct ShareInfo { + pub who: AccountIdOf, + pub share: BalanceOf, + pub withdrawn_rewards: BTreeMap, + pub claim_last_block: BlockNumberFor, + pub withdraw_list: Vec<(BlockNumberFor, BalanceOf)>, +} + +impl + ShareInfo +where + BalanceOf: Default + HasCompact, + CurrencyIdOf: Ord, +{ + fn new(who: AccountIdOf, claim_last_block: BlockNumberFor) -> Self { + Self { + who, + share: Default::default(), + withdrawn_rewards: BTreeMap::new(), + claim_last_block, + withdraw_list: Default::default(), + } + } +} + +/// The Reward Pool Info. +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct PoolInfo { + pub tokens_proportion: BTreeMap, + pub basic_token: (CurrencyIdOf, Perbill), + /// Total shares amount + pub total_shares: BalanceOf, + pub basic_rewards: BTreeMap, + /// Reward infos + pub rewards: BTreeMap, + pub state: PoolState, + pub keeper: AccountIdOf, + pub reward_issuer: AccountIdOf, + /// Gauge pool id + pub gauge: Option, + pub block_startup: Option, + pub min_deposit_to_start: BalanceOf, + pub after_block_to_start: BlockNumberFor, + pub withdraw_limit_time: BlockNumberFor, + pub claim_limit_time: BlockNumberFor, + pub withdraw_limit_count: u8, +} + +impl + PoolInfo +where + BalanceOf: Default + HasCompact, + CurrencyIdOf: Ord, +{ + #[allow(clippy::too_many_arguments)] + pub fn new( + keeper: AccountIdOf, + reward_issuer: AccountIdOf, + tokens_proportion: BTreeMap, + basic_token: (CurrencyIdOf, Perbill), + basic_rewards: BTreeMap, + gauge: Option, + min_deposit_to_start: BalanceOf, + after_block_to_start: BlockNumberFor, + withdraw_limit_time: BlockNumberFor, + claim_limit_time: BlockNumberFor, + withdraw_limit_count: u8, + ) -> Self { + Self { + tokens_proportion, + basic_token, + total_shares: Default::default(), + basic_rewards, + rewards: BTreeMap::new(), + state: PoolState::UnCharged, + keeper, + reward_issuer, + gauge, + block_startup: None, + min_deposit_to_start, + after_block_to_start, + withdraw_limit_time, + claim_limit_time, + withdraw_limit_count, + } + } +} + +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub enum PoolState { + UnCharged, + Charged, + Ongoing, + Dead, + Retired, +} + +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub enum Action { + Deposit, + Withdraw, + Claim, + ForceRetirePool, + ClosePool, + ResetPool, + KillPool, + EditPool, +} + +impl PoolState { + pub fn state_valid(action: Action, state: PoolState) -> bool { + match action { + Action::Deposit => state == PoolState::Ongoing || state == PoolState::Charged, + Action::Withdraw => { + state == PoolState::Ongoing + || state == PoolState::Charged + || state == PoolState::Dead + } + Action::Claim => state == PoolState::Ongoing || state == PoolState::Dead, + Action::ForceRetirePool => state == PoolState::Dead, + Action::ClosePool => state == PoolState::Ongoing, + Action::ResetPool => state == PoolState::Retired, + Action::KillPool => state == PoolState::Retired || state == PoolState::UnCharged, + Action::EditPool => { + state == PoolState::Retired + || state == PoolState::Ongoing + || state == PoolState::Charged + || state == PoolState::UnCharged + } + } + } +} + +impl Pallet { + pub fn accumulate_reward( + pool: PoolId, + reward_currency: CurrencyIdOf, + reward_increment: BalanceOf, + ) -> DispatchResult { + if reward_increment.is_zero() { + return Ok(()); + } + PoolInfos::::mutate_exists(pool, |maybe_pool_info| -> DispatchResult { + let pool_info = maybe_pool_info + .as_mut() + .ok_or(Error::::PoolDoesNotExist)?; + + pool_info + .rewards + .entry(reward_currency) + .and_modify(|(total_reward, _)| { + *total_reward = total_reward.saturating_add(reward_increment); + }) + .or_insert((reward_increment, Zero::zero())); + + Ok(()) + }) + } + + pub fn add_share( + who: &T::AccountId, + pid: PoolId, + pool_info: &mut PoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, + add_amount: BalanceOf, + ) { + if add_amount.is_zero() { + return; + } + + let initial_total_shares = pool_info.total_shares; + pool_info.total_shares = pool_info.total_shares.saturating_add(add_amount); + + let mut withdrawn_inflation = Vec::<(CurrencyIdOf, BalanceOf)>::new(); + + pool_info.rewards.iter_mut().for_each( + |(reward_currency, (total_reward, total_withdrawn_reward))| { + let reward_inflation = if initial_total_shares.is_zero() { + Zero::zero() + } else { + U256::from(add_amount.to_owned().saturated_into::()) + .saturating_mul(total_reward.to_owned().saturated_into::().into()) + .checked_div( + initial_total_shares + .to_owned() + .saturated_into::() + .into(), + ) + .unwrap_or_default() + .as_u128() + .saturated_into() + }; + *total_reward = total_reward.saturating_add(reward_inflation); + *total_withdrawn_reward = total_withdrawn_reward.saturating_add(reward_inflation); + + withdrawn_inflation.push((*reward_currency, reward_inflation)); + }, + ); + + let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); + + let mut share_info = SharesAndWithdrawnRewards::::get(pid, who) + .unwrap_or_else(|| ShareInfo::new(who.clone(), current_block_number)); + share_info.share = share_info.share.saturating_add(add_amount); + // update withdrawn inflation for each reward currency + withdrawn_inflation + .into_iter() + .for_each(|(reward_currency, reward_inflation)| { + share_info + .withdrawn_rewards + .entry(reward_currency) + .and_modify(|withdrawn_reward| { + *withdrawn_reward = withdrawn_reward.saturating_add(reward_inflation); + }) + .or_insert(reward_inflation); + }); + SharesAndWithdrawnRewards::::insert(pid, who, share_info); + PoolInfos::::insert(pid, pool_info); + } + + pub fn remove_share( + who: &T::AccountId, + pool: PoolId, + remove_amount_input: Option>, + withdraw_limit_time: BlockNumberFor, + ) -> DispatchResult { + if let Some(remove_amount_input) = remove_amount_input { + if remove_amount_input.is_zero() { + return Ok(()); + } + } + + // claim rewards firstly + Self::claim_rewards(who, pool)?; + + SharesAndWithdrawnRewards::::mutate(pool, who, |share_info_old| -> DispatchResult { + let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); + if let Some(mut share_info) = share_info_old.take() { + let remove_amount; + if let Some(remove_amount_input) = remove_amount_input { + remove_amount = remove_amount_input.min(share_info.share); + } else { + remove_amount = share_info.share; + } + + if remove_amount.is_zero() { + return Ok(()); + } + + PoolInfos::::mutate(pool, |maybe_pool_info| -> DispatchResult { + let pool_info = maybe_pool_info + .as_mut() + .ok_or(Error::::PoolDoesNotExist)?; + + share_info + .withdraw_list + .push((current_block_number + withdraw_limit_time, remove_amount)); + + let removing_share = U256::from(remove_amount.saturated_into::()); + + pool_info.total_shares = pool_info.total_shares.saturating_sub(remove_amount); + + // update withdrawn rewards for each reward currency + share_info.withdrawn_rewards.iter_mut().try_for_each( + |(reward_currency, withdrawn_reward)| -> DispatchResult { + let withdrawn_reward_to_remove: BalanceOf = removing_share + .saturating_mul( + withdrawn_reward.to_owned().saturated_into::().into(), + ) + .checked_div(share_info.share.saturated_into::().into()) + .unwrap_or_default() + .as_u128() + .saturated_into(); + + if let Some((total_reward, total_withdrawn_reward)) = + pool_info.rewards.get_mut(reward_currency) + { + *total_reward = + total_reward.saturating_sub(withdrawn_reward_to_remove); + *total_withdrawn_reward = total_withdrawn_reward + .saturating_sub(withdrawn_reward_to_remove); + + // remove if all reward is withdrawn + if total_reward.is_zero() { + pool_info.rewards.remove(reward_currency); + } + } + *withdrawn_reward = + withdrawn_reward.saturating_sub(withdrawn_reward_to_remove); + Ok(()) + }, + )?; + Ok(()) + })?; + + share_info.share = share_info.share.saturating_sub(remove_amount); + *share_info_old = Some(share_info); + } + Ok(()) + })?; + Ok(()) + } + + pub fn claim_rewards(who: &T::AccountId, pool: PoolId) -> DispatchResult { + SharesAndWithdrawnRewards::::mutate_exists( + pool, + who, + |maybe_share_withdrawn| -> DispatchResult { + let current_block_number: BlockNumberFor = + frame_system::Pallet::::block_number(); + if let Some(share_info) = maybe_share_withdrawn { + if share_info.share.is_zero() { + return Ok(()); + } + + PoolInfos::::mutate(pool, |maybe_pool_info| -> DispatchResult { + let pool_info = maybe_pool_info + .as_mut() + .ok_or(Error::::PoolDoesNotExist)?; + + let total_shares = + U256::from(pool_info.total_shares.to_owned().saturated_into::()); + pool_info.rewards.iter_mut().try_for_each( + |(reward_currency, (total_reward, total_withdrawn_reward))| -> DispatchResult { + let withdrawn_reward = share_info + .withdrawn_rewards + .get(reward_currency) + .copied() + .unwrap_or_default(); + + let total_reward_proportion: BalanceOf = U256::from( + share_info.share.to_owned().saturated_into::(), + ) + .saturating_mul(U256::from( + total_reward.to_owned().saturated_into::(), + )) + .checked_div(total_shares) + .unwrap_or_default() + .as_u128() + .unique_saturated_into(); + + let reward_to_withdraw = total_reward_proportion + .saturating_sub(withdrawn_reward) + .min(total_reward.saturating_sub(*total_withdrawn_reward)); + + if reward_to_withdraw.is_zero() { + return Ok(()); + } + + *total_withdrawn_reward = + total_withdrawn_reward.saturating_add(reward_to_withdraw); + share_info.withdrawn_rewards.insert( + *reward_currency, + withdrawn_reward.saturating_add(reward_to_withdraw), + ); + + let ed = T::MultiCurrency::minimum_balance(*reward_currency); + let mut account_to_send = who.clone(); + + if reward_to_withdraw < ed { + let receiver_balance = T::MultiCurrency::total_balance(*reward_currency, who); + + let receiver_balance_after = + receiver_balance.checked_add(&reward_to_withdraw).ok_or(ArithmeticError::Overflow)?; + if receiver_balance_after < ed { + account_to_send = T::TreasuryAccount::get(); + } + } + // pay reward to `who` + T::MultiCurrency::transfer( + *reward_currency, + &pool_info.reward_issuer, + &account_to_send, + reward_to_withdraw, + ) + }, + )?; + Ok(()) + })?; + share_info.claim_last_block = current_block_number; + }; + Ok(()) + }, + )?; + Ok(()) + } + + pub fn process_withdraw_list( + who: &T::AccountId, + pool: PoolId, + pool_info: &PoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, + if_remove: bool, + ) -> DispatchResult { + SharesAndWithdrawnRewards::::mutate_exists( + pool, + who, + |share_info_old| -> DispatchResult { + if let Some(mut share_info) = share_info_old.take() { + let n: BlockNumberFor = frame_system::Pallet::::block_number(); + let mut tmp: Vec<(BlockNumberFor, BalanceOf)> = Default::default(); + share_info.withdraw_list.iter().try_for_each( + |(dest_block, remove_value)| -> DispatchResult { + if *dest_block <= n { + let native_amount = pool_info + .basic_token + .1 + .saturating_reciprocal_mul(*remove_value); + pool_info.tokens_proportion.iter().try_for_each( + |(token, &proportion)| -> DispatchResult { + let withdraw_amount = proportion * native_amount; + let ed = T::MultiCurrency::minimum_balance(*token); + let mut account_to_send = who.clone(); + + if withdraw_amount < ed { + let receiver_balance = + T::MultiCurrency::total_balance(*token, who); + + let receiver_balance_after = receiver_balance + .checked_add(&withdraw_amount) + .ok_or(ArithmeticError::Overflow)?; + if receiver_balance_after < ed { + account_to_send = T::TreasuryAccount::get(); + } + } + T::MultiCurrency::transfer( + *token, + &pool_info.keeper, + &account_to_send, + withdraw_amount, + ) + }, + )?; + } else { + tmp.push((*dest_block, *remove_value)); + }; + Ok(()) + }, + )?; + share_info.withdraw_list = tmp; + + // if withdraw_list and share both are empty, and if_remove is true, remove it. + if !share_info.withdraw_list.is_empty() + || !share_info.share.is_zero() + || !if_remove + { + *share_info_old = Some(share_info); + }; + }; + Ok(()) + }, + ) + } +} diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs new file mode 100644 index 000000000..c964defac --- /dev/null +++ b/pallets/farming/src/tests.rs @@ -0,0 +1,573 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +#![cfg(test)] + +use frame_support::{assert_err, assert_ok}; +use sp_runtime::traits::AccountIdConversion; + +use crate::{mock::*, *}; + +fn init_gauge() -> (PoolId, BalanceOf) { + let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); + tokens_proportion_map + .entry(KSM) + .or_insert(Perbill::from_percent(100)); + let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; + let tokens = 1000; + let basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = vec![(KSM, 900)]; + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + Some((KSM, 1000, gauge_basic_rewards)), + 0, + 0, + 0, + 0, + 5 + )); + + let pid = 0; + let charge_rewards = vec![(KSM, 300000)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + Some((100, 100)) + )); + (pid, tokens) +} + +fn init_no_gauge() -> (PoolId, BalanceOf) { + let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); + tokens_proportion_map + .entry(KSM) + .or_insert(Perbill::from_percent(100)); + let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; + let tokens = 1000; + let basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = vec![(KSM, 1000)]; + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + Some((KSM, 1000, gauge_basic_rewards)), + 0, + 0, + 10, + 0, + 1 + )); + + let pid = 0; + let charge_rewards = vec![(KSM, 100000)]; + + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + None + )); + (pid, tokens) +} + +#[test] +fn claim() { + let keeper_account = FarmingKeeperPalletId::get().into_account_truncating(); + + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, _tokens) = init_no_gauge(); + // assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), ShareInfo::default()); + assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); + assert_err!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + System::set_block_number(System::block_number() + 100); + Farming::on_initialize(0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 2000); + Farming::on_initialize(0); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 2000); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + Farming::on_initialize(0); + assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + + // Fund token to keeper_account + assert_ok!(Assets::mint( + RuntimeOrigin::signed(ALICE), + KSM, + keeper_account, + 100 + )); + + assert_ok!(Farming::force_retire_pool( + RuntimeOrigin::signed(ALICE), + pid + )); + assert_eq!(Assets::balance(KSM, &ALICE), 5000); // 3000 + 1000 + 1000 + Farming::on_initialize(0); + assert_err!( + Farming::force_retire_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + }); +} + +#[test] +fn deposit() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, tokens) = init_no_gauge(); + System::set_block_number(System::block_number() + 1); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + Some((100, 100)) + )); + System::set_block_number(System::block_number() + 1); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + 0, + Some((100, 100)) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 800); + let keeper: AccountId = + ::Keeper::get().into_sub_account_truncating(pid); + let reward_issuer: AccountId = + ::RewardIssuer::get().into_sub_account_truncating(pid); + let mut gauge_basic_rewards = + BTreeMap::, BalanceOf>::new(); + gauge_basic_rewards.entry(KSM).or_insert(1000); + let gauge_pool_info2 = GaugePoolInfo { + pid, + token: KSM, + keeper, + reward_issuer, + rewards: BTreeMap::< + CurrencyIdOf, + (BalanceOf, BalanceOf, BalanceOf), + >::new(), + gauge_basic_rewards, + max_block: 1000, + gauge_amount: 200, + total_time_factor: 39900, + gauge_last_block: System::block_number(), + gauge_state: GaugeState::Bonded, + }; + assert_eq!(Farming::gauge_pool_infos(0), Some(gauge_pool_info2)); + Farming::on_initialize(0); + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 1000); + }) +} + +#[test] +fn withdraw() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, tokens) = init_no_gauge(); + assert_eq!(Assets::balance(KSM, &ALICE), 2000); + Farming::on_initialize(0); + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 1); + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(800) + )); + assert_err!( + Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, Some(100)), + Error::::WithdrawLimitCountExceeded + ); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(BOB), + pid, + tokens, + None + )); + Farming::on_initialize(0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3966); + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(200) + )); + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 4166); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); + assert_eq!(Assets::balance(KSM, &ALICE), 4166); + // let ed = ::MultiCurrency::minimum_balance(KSM); + // assert_eq!(Assets::balance(KSM, &TREASURY_ACCOUNT), ed); + }) +} + +#[test] +fn gauge() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, tokens) = init_gauge(); + assert_eq!(Assets::balance(KSM, &ALICE), 1900); + if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { + assert_eq!( + gauge_pool_infos.rewards, + BTreeMap::< + CurrencyIdOf, + (BalanceOf, BalanceOf, BalanceOf), + >::new() + ) + }; + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 1); + Farming::on_initialize(0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 2918); + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 10); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + Some((100, 100)) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 1818); + System::set_block_number(System::block_number() + 20); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3163); + assert_ok!(Farming::deposit(RuntimeOrigin::signed(BOB), pid, 10, None)); + assert_eq!(Assets::balance(KSM, &BOB), 9699990); + System::set_block_number(System::block_number() + 200); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 5383); + assert_eq!(Assets::balance(KSM, &BOB), 9699990); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(BOB), + pid, + 0, + Some((100, 100)) + )); + System::set_block_number(System::block_number() + 200); + assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); + assert_ok!(Farming::force_gauge_claim( + RuntimeOrigin::signed(ALICE), + pid + )); + assert_eq!(Assets::balance(KSM, &BOB), 9699991); + }) +} + +#[test] +fn gauge_withdraw() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, _tokens) = init_gauge(); + assert_eq!(Assets::balance(KSM, &ALICE), 1900); + if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { + assert_eq!(gauge_pool_infos.gauge_amount, 100) + }; + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 1); + Farming::on_initialize(0); + assert_ok!(Farming::gauge_withdraw(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 1918); + System::set_block_number(System::block_number() + 1000); + assert_ok!(Farming::gauge_withdraw(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3782); + if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { + assert_eq!(gauge_pool_infos.gauge_amount, 0) + }; + }) +} + +#[test] +fn retire() { + let keeper_account = FarmingKeeperPalletId::get().into_account_truncating(); + + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, tokens) = init_no_gauge(); + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 1); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + Some((100, 100)) + )); + System::set_block_number(System::block_number() + 1); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + 0, + Some((100, 100)) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 800); + assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + + // Fund token to keeper_account + assert_ok!(Assets::mint( + RuntimeOrigin::signed(ALICE), + KSM, + keeper_account, + 100 + )); + + assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); + System::set_block_number(System::block_number() + 1000); + assert_ok!(Farming::force_retire_pool( + RuntimeOrigin::signed(ALICE), + pid + )); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); + }) +} + +#[test] +fn reset() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, _tokens) = init_gauge(); + assert_eq!(Assets::balance(KSM, &ALICE), 1900); + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 1); + Farming::on_initialize(0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 2918); + assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); + assert_ok!(Farming::force_retire_pool( + RuntimeOrigin::signed(ALICE), + pid + )); + let basic_rewards = vec![(KSM, 1000)]; + assert_ok!(Farming::reset_pool( + RuntimeOrigin::signed(ALICE), + pid, + None, + None, + None, + None, + None, + None, + Some((KSM, 1000, basic_rewards)), + )); + let keeper: AccountId = + ::Keeper::get().into_sub_account_truncating(pid); + let reward_issuer: AccountId = + ::RewardIssuer::get().into_sub_account_truncating(pid); + let mut basic_rewards_map = + BTreeMap::, BalanceOf>::new(); + basic_rewards_map.entry(KSM).or_insert(1000); + let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); + tokens_proportion_map + .entry(KSM) + .or_insert(Perbill::from_percent(100)); + let pool_infos = PoolInfo { + tokens_proportion: tokens_proportion_map, + total_shares: Default::default(), + basic_token: (KSM, Perbill::from_percent(100)), + basic_rewards: basic_rewards_map.clone(), + rewards: BTreeMap::new(), + state: PoolState::UnCharged, + keeper: keeper.clone(), + reward_issuer: reward_issuer.clone(), + gauge: Some(1), + block_startup: None, + min_deposit_to_start: Default::default(), + after_block_to_start: Default::default(), + withdraw_limit_time: Default::default(), + claim_limit_time: Default::default(), + withdraw_limit_count: 5, + }; + assert_eq!(Farming::pool_infos(0), Some(pool_infos)); + let gauge_pool_info = GaugePoolInfo { + pid, + token: KSM, + keeper, + reward_issuer, + rewards: BTreeMap::< + CurrencyIdOf, + (BalanceOf, BalanceOf, BalanceOf), + >::new(), + gauge_basic_rewards: basic_rewards_map, + max_block: 1000, + gauge_amount: 0, + total_time_factor: 0, + gauge_last_block: System::block_number(), + gauge_state: GaugeState::Bonded, + }; + assert_eq!(Farming::gauge_pool_infos(1), Some(gauge_pool_info)); + assert_eq!(Assets::balance(KSM, &ALICE), 3918); + let charge_rewards = vec![(KSM, 300000)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + 1, + Some((100, 100)) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 3817); + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 20); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 4017); + }) +} + +#[test] +fn create_farming_pool() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); + tokens_proportion_map + .entry(KSM) + .or_insert(Perbill::from_percent(100)); + let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; + let tokens = 1000; + let basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = vec![(KSM, 900)]; + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion.clone(), + basic_rewards.clone(), + Some((KSM, 1000, gauge_basic_rewards.clone())), + 2, + 1, + 7, + 6, + 5 + )); + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + Some((KSM, 1000, gauge_basic_rewards)), + 2, + 1, + 7, + 6, + 5 + )); + if let Some(pool_infos) = Farming::pool_infos(0) { + assert_eq!(pool_infos.state, PoolState::UnCharged) + }; + assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), 0)); + + let pid = 1; + let charge_rewards = vec![(KSM, 300000)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + if let Some(pool_infos) = Farming::pool_infos(0) { + assert_eq!(pool_infos.total_shares, 0); + assert_eq!(pool_infos.min_deposit_to_start, 2); + assert_eq!(pool_infos.state, PoolState::Charged) + }; + assert_err!( + Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 100))), + Error::::CanNotDeposit + ); + System::set_block_number(System::block_number() + 3); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + Some((100, 100)) + )); + Farming::on_initialize(System::block_number() + 3); + Farming::on_initialize(0); + if let Some(pool_infos) = Farming::pool_infos(0) { + assert_eq!(pool_infos.total_shares, 1000); + assert_eq!(pool_infos.min_deposit_to_start, 2); + assert_eq!(pool_infos.state, PoolState::Ongoing) + }; + assert_err!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::CanNotClaim + ); + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3008); + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 4698); + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(800) + )); + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_err!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::CanNotClaim + ); + assert_eq!(Assets::balance(KSM, &ALICE), 4698); + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 5498); + }) +} diff --git a/pallets/farming/src/weights.rs b/pallets/farming/src/weights.rs new file mode 100644 index 000000000..0766c2535 --- /dev/null +++ b/pallets/farming/src/weights.rs @@ -0,0 +1,174 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Autogenerated weights for manta_farming +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-14, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dolphin-dev"), DB CACHE: 1024 + +// Executed Command: +// target/release/manta +// benchmark +// pallet +// --chain=dolphin-dev +// --pallet=manta-farming +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --output=./pallets/farming/src/weights.rs +// --template=.github/resources/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; + +/// Weight functions needed for manta_farming. +pub trait WeightInfo { + fn on_initialize() -> Weight; + fn create_farming_pool() -> Weight; + fn deposit() -> Weight; + fn withdraw() -> Weight; + fn claim() -> Weight; + fn gauge_withdraw() -> Weight; +} + +/// Weights for manta_farming using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 5_170 nanoseconds. + Weight::from_ref_time(5_433_000) + .saturating_add(T::DbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 27_007 nanoseconds. + Weight::from_ref_time(27_448_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 64_240 nanoseconds. + Weight::from_ref_time(65_244_000) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 36_542 nanoseconds. + Weight::from_ref_time(37_369_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 35_822 nanoseconds. + Weight::from_ref_time(37_226_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 37_084 nanoseconds. + Weight::from_ref_time(37_875_000) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 5_170 nanoseconds. + Weight::from_ref_time(5_433_000) + .saturating_add(RocksDbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 27_007 nanoseconds. + Weight::from_ref_time(27_448_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 64_240 nanoseconds. + Weight::from_ref_time(65_244_000) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 36_542 nanoseconds. + Weight::from_ref_time(37_369_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 35_822 nanoseconds. + Weight::from_ref_time(37_226_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 37_084 nanoseconds. + Weight::from_ref_time(37_875_000) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(2)) + } +} diff --git a/primitives/manta/Cargo.toml b/primitives/manta/Cargo.toml index 423c2faca..b9c6081b1 100644 --- a/primitives/manta/Cargo.toml +++ b/primitives/manta/Cargo.toml @@ -28,6 +28,8 @@ xcm = { git = 'https://github.com/paritytech/polkadot.git', default-features = f xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-features = false, branch = "release-v0.9.37" } +orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', branch = "polkadot-v0.9.37", default-features = false } + [features] default = ["std"] runtime-benchmarks = [ @@ -49,4 +51,5 @@ std = [ 'xcm-executor/std', 'xcm-builder/std', 'xcm/std', + 'orml-traits/std', ] diff --git a/primitives/manta/src/currencies.rs b/primitives/manta/src/currencies.rs new file mode 100644 index 000000000..f328afb35 --- /dev/null +++ b/primitives/manta/src/currencies.rs @@ -0,0 +1,186 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Manta Currencies Implementation + +use crate::assets::AssetConfig; +use codec::{FullCodec, MaxEncodedLen}; +use frame_support::{ + ensure, + traits::{ + fungible, fungibles, + fungibles::{Mutate, Transfer}, + Currency, ExistenceRequirement, WithdrawReasons, + }, + Parameter, +}; +use frame_system::Config; +use orml_traits::{arithmetic::CheckedSub, MultiCurrency}; +use scale_info::TypeInfo; +use sp_core::Get; +use sp_runtime::{ + traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Member, Zero}, + ArithmeticError, DispatchError, DispatchResult, +}; +use sp_std::{fmt::Debug, marker::PhantomData}; + +/// Currencies implements for orml_traits::MultiCurrency. +pub struct Currencies(PhantomData<(C, A, Native, NonNative)>); + +impl MultiCurrency for Currencies +where + C: Config, + A: AssetConfig, + A::AssetId: + Parameter + Member + Copy + MaybeSerializeDeserialize + Ord + TypeInfo + MaxEncodedLen, + A::Balance: AtLeast32BitUnsigned + + FullCodec + + Copy + + MaybeSerializeDeserialize + + Debug + + Default + + scale_info::TypeInfo + + MaxEncodedLen, + Native: fungible::Inspect + + fungible::Mutate + + Currency, + NonNative: fungibles::Inspect + + Mutate + + Transfer, +{ + type CurrencyId = A::AssetId; + type Balance = A::Balance; + + fn minimum_balance(currency_id: Self::CurrencyId) -> Self::Balance { + if currency_id == A::NativeAssetId::get() { + >::minimum_balance() + } else { + NonNative::minimum_balance(currency_id) + } + } + + fn total_issuance(currency_id: Self::CurrencyId) -> Self::Balance { + if currency_id == A::NativeAssetId::get() { + >::total_issuance() + } else { + NonNative::total_issuance(currency_id) + } + } + + fn total_balance(currency_id: Self::CurrencyId, who: &C::AccountId) -> Self::Balance { + if currency_id == A::NativeAssetId::get() { + Native::balance(who) + } else { + NonNative::balance(currency_id, who) + } + } + + fn free_balance(currency_id: Self::CurrencyId, who: &C::AccountId) -> Self::Balance { + if currency_id == A::NativeAssetId::get() { + Native::free_balance(who) + } else { + // NonNative::reducible_balance(currency_id, who, true) + NonNative::balance(currency_id, who) + } + } + + fn ensure_can_withdraw( + currency_id: Self::CurrencyId, + who: &C::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + if amount == Zero::zero() { + return Ok(()); + } + let new_balance = Self::free_balance(currency_id, who) + .checked_sub(&amount) + .ok_or(DispatchError::Arithmetic(ArithmeticError::Underflow))?; + if currency_id == A::NativeAssetId::get() { + Native::ensure_can_withdraw(who, amount, WithdrawReasons::empty(), new_balance) + } else { + ensure!( + new_balance >= Self::minimum_balance(currency_id), + DispatchError::Other("balance too low") + ); + Ok(()) + } + } + + fn transfer( + currency_id: Self::CurrencyId, + from: &C::AccountId, + to: &C::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + if currency_id == A::NativeAssetId::get() { + Native::transfer(from, to, amount, ExistenceRequirement::KeepAlive)?; + } else { + NonNative::transfer(currency_id, from, to, amount, true)?; + } + Ok(()) + } + + fn deposit( + currency_id: Self::CurrencyId, + who: &C::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + if currency_id == A::NativeAssetId::get() { + Native::deposit_creating(who, amount); + Ok(()) + } else { + NonNative::mint_into(currency_id, who, amount) + } + } + + fn withdraw( + currency_id: Self::CurrencyId, + who: &C::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + if currency_id == A::NativeAssetId::get() { + Native::withdraw( + who, + amount, + WithdrawReasons::empty(), + ExistenceRequirement::KeepAlive, + )?; + } else { + NonNative::burn_from(currency_id, who, amount)?; + } + Ok(()) + } + + fn can_slash(currency_id: Self::CurrencyId, who: &C::AccountId, value: Self::Balance) -> bool { + if value == Zero::zero() { + return true; + } + Self::free_balance(currency_id, who) >= value + } + + fn slash( + currency_id: Self::CurrencyId, + who: &C::AccountId, + amount: Self::Balance, + ) -> Self::Balance { + if currency_id == A::NativeAssetId::get() { + >::slash(who, amount) + .expect("slash should not failed") + } else { + NonNative::slash(currency_id, who, amount).expect("slash should not failed") + } + } +} diff --git a/primitives/manta/src/lib.rs b/primitives/manta/src/lib.rs index b5ab1bd96..2a066147d 100644 --- a/primitives/manta/src/lib.rs +++ b/primitives/manta/src/lib.rs @@ -25,5 +25,6 @@ extern crate alloc; pub mod assets; pub mod constants; +pub mod currencies; pub mod types; pub mod xcm; diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 1caea7bfb..031ded1f5 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -87,6 +87,8 @@ xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-fea # Self dependencies calamari-vesting = { path = '../../pallets/vesting', default-features = false } manta-collator-selection = { path = '../../pallets/collator-selection', default-features = false } +manta-farming = { path = '../../pallets/farming', default-features = false } +manta-farming-rpc-runtime-api = { path = '../../pallets/farming/rpc/runtime-api', default-features = false } manta-primitives = { path = '../../primitives/manta', default-features = false } manta-support = { package = "pallet-manta-support", path = "../../pallets/manta-support", default-features = false } pallet-asset-manager = { path = '../../pallets/asset-manager', default-features = false } @@ -163,6 +165,7 @@ runtime-benchmarks = [ 'pallet-xcm-benchmarks/runtime-benchmarks', 'pallet-manta-sbt/runtime-benchmarks', "zenlink-protocol/runtime-benchmarks", + 'manta-farming/runtime-benchmarks', ] try-runtime = [ 'frame-try-runtime', @@ -202,6 +205,7 @@ try-runtime = [ 'calamari-vesting/try-runtime', 'pallet-manta-sbt/try-runtime', "zenlink-protocol/try-runtime", + "manta-farming/try-runtime", ] # Set timing constants (e.g. session period) to faster versions to speed up testing. fast-runtime = [] @@ -275,6 +279,8 @@ std = [ 'manta-support/std', "zenlink-protocol/std", "zenlink-protocol-runtime-api/std", + "manta-farming/std", + "manta-farming-rpc-runtime-api/std", ] # A feature that should be enabled when the runtime should be build for on-chain # deployment. This will disable stuff that shouldn't be part of the on-chain wasm diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index 9957ce522..ebad4a4ac 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -29,7 +29,7 @@ use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT}, + traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Percent, Permill, }; @@ -56,7 +56,10 @@ use frame_system::{ }; use manta_primitives::{ constants::{time::*, RocksDbWeight, STAKING_PALLET_ID, TREASURY_PALLET_ID, WEIGHT_PER_SECOND}, - types::{AccountId, Balance, BlockNumber, Hash, Header, Index, Signature}, + currencies::Currencies, + types::{ + AccountId, Balance, BlockNumber, CalamariAssetId, Hash, Header, Index, PoolId, Signature, + }, }; use manta_support::manta_pay::{InitialSyncResponse, PullResponse, RawCheckpoint}; pub use pallet_parachain_staking::{InflationInfo, Range}; @@ -82,6 +85,7 @@ pub mod staking; pub mod xcm_config; pub mod zenlink; +use crate::assets_config::CalamariAssetConfig; use currency::*; use impls::DealWithFees; @@ -300,6 +304,7 @@ impl Contains for BaseFilter { | orml_xtokens::Call::transfer_multicurrencies {..}) | RuntimeCall::TransactionPause(_) | RuntimeCall::ZenlinkProtocol(_) + | RuntimeCall::Farming(_) | RuntimeCall::AssetManager(pallet_asset_manager::Call::update_outgoing_filtered_assets {..}) | RuntimeCall::Utility(_) => true, @@ -790,6 +795,26 @@ impl calamari_vesting::Config for Runtime { type WeightInfo = weights::calamari_vesting::SubstrateWeight; } +parameter_types! { + pub const FarmingKeeperPalletId: PalletId = PalletId(*b"mt/fmkpr"); + pub const FarmingRewardIssuerPalletId: PalletId = PalletId(*b"mt/fmrir"); + pub TreasuryAccount: AccountId = TreasuryPalletId::get().into_account_truncating(); +} + +/// Zenlink protocol Asset adaptor for orml_traits::MultiCurrency. +type MantaCurrencies = Currencies; + +impl manta_farming::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CurrencyId = CalamariAssetId; + type MultiCurrency = MantaCurrencies; + type ControlOrigin = CollatorSelectionUpdateOrigin; + type TreasuryAccount = TreasuryAccount; + type Keeper = FarmingKeeperPalletId; + type RewardIssuer = FarmingRewardIssuerPalletId; + type WeightInfo = weights::manta_farming::SubstrateWeight; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime where @@ -857,6 +882,7 @@ construct_runtime!( // Calamari stuff CalamariVesting: calamari_vesting::{Pallet, Call, Storage, Event} = 50, ZenlinkProtocol: zenlink_protocol::{Pallet, Call, Storage, Event} = 51, + Farming: manta_farming::{Pallet, Call, Storage, Event} = 54, } ); @@ -928,6 +954,7 @@ mod benches { [pallet_manta_sbt, MantaSbt] // Dex [zenlink_protocol, ZenlinkProtocol] + [manta_farming, Farming] // XCM [cumulus_pallet_xcmp_queue, XcmpQueue] [pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::] @@ -1186,6 +1213,16 @@ impl_runtime_apis! { } } + impl manta_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { + fn get_farming_rewards(who: AccountId, pid: PoolId) -> Vec<(CalamariAssetId, Balance)> { + Farming::get_farming_rewards(&who, pid).unwrap_or(Vec::new()) + } + + fn get_gauge_rewards(who: AccountId, pid: PoolId) -> Vec<(CalamariAssetId, Balance)> { + Farming::get_gauge_rewards(&who, pid).unwrap_or(Vec::new()) + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { diff --git a/runtime/calamari/src/weights/manta_farming.rs b/runtime/calamari/src/weights/manta_farming.rs new file mode 100644 index 000000000..f41f5e88a --- /dev/null +++ b/runtime/calamari/src/weights/manta_farming.rs @@ -0,0 +1,172 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Autogenerated weights for manta_farming +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-05, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("calamari-dev"), DB CACHE: 1024 + +// Executed Command: +// target/debug/manta +// benchmark +// pallet +// --chain=calamari-dev +// --pallet=manta_farming +// --extrinsic=* +// --heap-pages=4096 +// --repeat=1 +// --steps=1 +// --template=.github/resources/frame-weight-template.hbs +// --output=manta-farming.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; + +/// Weight functions needed for manta_farming. +pub trait WeightInfo { + fn on_initialize() -> Weight; + fn create_farming_pool() -> Weight; + fn deposit() -> Weight; + fn withdraw() -> Weight; + fn claim() -> Weight; + fn gauge_withdraw() -> Weight; +} + +/// Weights for manta_farming using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl manta_farming::WeightInfo for SubstrateWeight { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 75_000 nanoseconds. + Weight::from_ref_time(75_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 658_000 nanoseconds. + Weight::from_ref_time(658_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 3_884_000 nanoseconds. + Weight::from_ref_time(3_884_000_000) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 439_000 nanoseconds. + Weight::from_ref_time(439_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 473_000 nanoseconds. + Weight::from_ref_time(473_000_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 640_000 nanoseconds. + Weight::from_ref_time(640_000_000) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 75_000 nanoseconds. + Weight::from_ref_time(75_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 658_000 nanoseconds. + Weight::from_ref_time(658_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 3_884_000 nanoseconds. + Weight::from_ref_time(3_884_000_000) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 439_000 nanoseconds. + Weight::from_ref_time(439_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 473_000 nanoseconds. + Weight::from_ref_time(473_000_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 640_000 nanoseconds. + Weight::from_ref_time(640_000_000) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(2)) + } +} diff --git a/runtime/calamari/src/weights/mod.rs b/runtime/calamari/src/weights/mod.rs index f0f2b6a8a..0e16f4c3e 100644 --- a/runtime/calamari/src/weights/mod.rs +++ b/runtime/calamari/src/weights/mod.rs @@ -20,6 +20,7 @@ pub mod calamari_vesting; pub mod cumulus_pallet_xcmp_queue; pub mod frame_system; pub mod manta_collator_selection; +pub mod manta_farming; pub mod pallet_asset_manager; pub mod pallet_assets; pub mod pallet_author_inherent; From c006a34831342c58f9afee614c3ad44ff2a365f3 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 5 Jun 2023 15:12:07 +0800 Subject: [PATCH 02/26] clean Signed-off-by: zqhxuyuan --- manta-farming.rs | 172 ----------------------------------------------- 1 file changed, 172 deletions(-) delete mode 100644 manta-farming.rs diff --git a/manta-farming.rs b/manta-farming.rs deleted file mode 100644 index e03fcafa5..000000000 --- a/manta-farming.rs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2020-2023 Manta Network. -// This file is part of Manta. -// -// Manta is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Manta is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Manta. If not, see . - -//! Autogenerated weights for manta_farming -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-05, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("calamari-dev"), DB CACHE: 1024 - -// Executed Command: -// target/debug/manta -// benchmark -// pallet -// --chain=calamari-dev -// --pallet=manta_farming -// --extrinsic=* -// --heap-pages=4096 -// --repeat=1 -// --steps=1 -// --template=.github/resources/frame-weight-template.hbs -// --output=manta-farming.rs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(clippy::unnecessary_cast)] - -use frame_support::{traits::Get, weights::Weight}; -use sp_std::marker::PhantomData; -use manta_primitives::constants::RocksDbWeight; - -/// Weight functions needed for manta_farming. -pub trait WeightInfo { - fn on_initialize() -> Weight; - fn create_farming_pool() -> Weight; - fn deposit() -> Weight; - fn withdraw() -> Weight; - fn claim() -> Weight; - fn gauge_withdraw() -> Weight; -} - -/// Weights for manta_farming using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl manta_farming::WeightInfo for SubstrateWeight { - // Storage: Farming PoolInfos (r:1 w:0) - // Storage: Farming GaugePoolInfos (r:1 w:0) - fn on_initialize() -> Weight { - // Minimum execution time: 75_000 nanoseconds. - Weight::from_ref_time(75_000_000) - .saturating_add(T::DbWeight::get().reads(2)) - } - // Storage: Farming PoolNextId (r:1 w:1) - // Storage: Farming GaugePoolNextId (r:1 w:1) - // Storage: Farming GaugePoolInfos (r:0 w:1) - // Storage: Farming PoolInfos (r:0 w:1) - fn create_farming_pool() -> Weight { - // Minimum execution time: 658_000 nanoseconds. - Weight::from_ref_time(658_000_000) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(4)) - } - // Storage: Farming PoolInfos (r:1 w:1) - // Storage: Assets Asset (r:1 w:1) - // Storage: Assets Account (r:2 w:2) - // Storage: System Account (r:1 w:1) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) - fn deposit() -> Weight { - // Minimum execution time: 3_884_000 nanoseconds. - Weight::from_ref_time(3_884_000_000) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(6)) - } - // Storage: Farming PoolInfos (r:1 w:1) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) - fn withdraw() -> Weight { - // Minimum execution time: 439_000 nanoseconds. - Weight::from_ref_time(439_000_000) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } - // Storage: Farming PoolInfos (r:1 w:1) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) - // Storage: Farming GaugeInfos (r:1 w:0) - fn claim() -> Weight { - // Minimum execution time: 473_000 nanoseconds. - Weight::from_ref_time(473_000_000) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) - } - // Storage: Farming GaugePoolInfos (r:1 w:1) - // Storage: Farming GaugeInfos (r:1 w:1) - // Storage: Farming PoolInfos (r:1 w:0) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) - fn gauge_withdraw() -> Weight { - // Minimum execution time: 640_000 nanoseconds. - Weight::from_ref_time(640_000_000) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} - -// For backwards compatibility and tests -impl WeightInfo for () { - // Storage: Farming PoolInfos (r:1 w:0) - // Storage: Farming GaugePoolInfos (r:1 w:0) - fn on_initialize() -> Weight { - // Minimum execution time: 75_000 nanoseconds. - Weight::from_ref_time(75_000_000) - .saturating_add(RocksDbWeight::get().reads(2)) - } - // Storage: Farming PoolNextId (r:1 w:1) - // Storage: Farming GaugePoolNextId (r:1 w:1) - // Storage: Farming GaugePoolInfos (r:0 w:1) - // Storage: Farming PoolInfos (r:0 w:1) - fn create_farming_pool() -> Weight { - // Minimum execution time: 658_000 nanoseconds. - Weight::from_ref_time(658_000_000) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(4)) - } - // Storage: Farming PoolInfos (r:1 w:1) - // Storage: Assets Asset (r:1 w:1) - // Storage: Assets Account (r:2 w:2) - // Storage: System Account (r:1 w:1) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) - fn deposit() -> Weight { - // Minimum execution time: 3_884_000 nanoseconds. - Weight::from_ref_time(3_884_000_000) - .saturating_add(RocksDbWeight::get().reads(6)) - .saturating_add(RocksDbWeight::get().writes(6)) - } - // Storage: Farming PoolInfos (r:1 w:1) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) - fn withdraw() -> Weight { - // Minimum execution time: 439_000 nanoseconds. - Weight::from_ref_time(439_000_000) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(2)) - } - // Storage: Farming PoolInfos (r:1 w:1) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) - // Storage: Farming GaugeInfos (r:1 w:0) - fn claim() -> Weight { - // Minimum execution time: 473_000 nanoseconds. - Weight::from_ref_time(473_000_000) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(2)) - } - // Storage: Farming GaugePoolInfos (r:1 w:1) - // Storage: Farming GaugeInfos (r:1 w:1) - // Storage: Farming PoolInfos (r:1 w:0) - // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) - fn gauge_withdraw() -> Weight { - // Minimum execution time: 640_000 nanoseconds. - Weight::from_ref_time(640_000_000) - .saturating_add(RocksDbWeight::get().reads(4)) - .saturating_add(RocksDbWeight::get().writes(2)) - } -} From bce3c298cf8d61a6b4611f4da6ceab6beeaabf14 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 5 Jun 2023 16:22:07 +0800 Subject: [PATCH 03/26] update origin Signed-off-by: zqhxuyuan --- pallets/farming/src/benchmarking.rs | 1 - primitives/manta/src/currencies.rs | 1 - runtime/calamari/src/lib.rs | 8 +++++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pallets/farming/src/benchmarking.rs b/pallets/farming/src/benchmarking.rs index 2e20180f8..57b76d17c 100644 --- a/pallets/farming/src/benchmarking.rs +++ b/pallets/farming/src/benchmarking.rs @@ -179,6 +179,5 @@ benchmarks! { let charge_rewards = vec![(ksm_asset_id,BalanceOf::::unique_saturated_from(300000u128))]; assert_ok!(Farming::::charge(RawOrigin::Signed(caller.clone()).into(), 0, charge_rewards)); assert_ok!(Farming::::deposit(RawOrigin::Signed(caller.clone()).into(), 0, token_amount, Some((BalanceOf::::unique_saturated_from(100u128), BlockNumberFor::::from(100u32))))); - // System::::set_block_number(System::::block_number() + BlockNumberFor::::from(10u32)); }: _(RawOrigin::Signed(caller.clone()), 0) } diff --git a/primitives/manta/src/currencies.rs b/primitives/manta/src/currencies.rs index f328afb35..44a16b812 100644 --- a/primitives/manta/src/currencies.rs +++ b/primitives/manta/src/currencies.rs @@ -92,7 +92,6 @@ where if currency_id == A::NativeAssetId::get() { Native::free_balance(who) } else { - // NonNative::reducible_balance(currency_id, who, true) NonNative::balance(currency_id, who) } } diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index ebad4a4ac..83e630171 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -85,7 +85,6 @@ pub mod staking; pub mod xcm_config; pub mod zenlink; -use crate::assets_config::CalamariAssetConfig; use currency::*; use impls::DealWithFees; @@ -802,13 +801,16 @@ parameter_types! { } /// Zenlink protocol Asset adaptor for orml_traits::MultiCurrency. -type MantaCurrencies = Currencies; +type MantaCurrencies = Currencies; impl manta_farming::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CurrencyId = CalamariAssetId; type MultiCurrency = MantaCurrencies; - type ControlOrigin = CollatorSelectionUpdateOrigin; + type ControlOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, + >; type TreasuryAccount = TreasuryAccount; type Keeper = FarmingKeeperPalletId; type RewardIssuer = FarmingRewardIssuerPalletId; From b04002632f60775895d944be32269c07a8a8b0ba Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 5 Jun 2023 17:48:59 +0800 Subject: [PATCH 04/26] clean Signed-off-by: zqhxuyuan --- pallets/farming/Cargo.toml | 3 +- pallets/farming/rpc/Cargo.toml | 2 +- pallets/farming/rpc/runtime-api/Cargo.toml | 2 +- pallets/farming/src/lib.rs | 20 +----- pallets/farming/src/migration.rs | 84 ---------------------- 5 files changed, 5 insertions(+), 106 deletions(-) delete mode 100644 pallets/farming/src/migration.rs diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 393503432..5ee0b73d0 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -1,11 +1,12 @@ [package] authors = ['Manta Network'] +description = 'Pallet implementing farming protocol.' edition = "2021" homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.0.7" +version = "4.0.8" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/rpc/Cargo.toml b/pallets/farming/rpc/Cargo.toml index 5a222e5e7..9f6bd0335 100644 --- a/pallets/farming/rpc/Cargo.toml +++ b/pallets/farming/rpc/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming-rpc-api" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.0.7" +version = "4.0.8" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/rpc/runtime-api/Cargo.toml b/pallets/farming/rpc/runtime-api/Cargo.toml index 2889aa3a5..f4b6fd135 100644 --- a/pallets/farming/rpc/runtime-api/Cargo.toml +++ b/pallets/farming/rpc/runtime-api/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming-rpc-runtime-api" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.0.7" +version = "4.0.8" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index dda9bb22c..4b9e69df5 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -101,7 +101,7 @@ pub mod pallet { /// The currency ID type type CurrencyId: Parameter + AtLeast32BitUnsigned - + Default //TODO: remove Default trait bound + + Default + Member + Copy + MaybeSerializeDeserialize @@ -381,12 +381,9 @@ pub mod pallet { let exchanger = ensure_signed(origin)?; let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; - // ensure!(pool_info.state == PoolState::UnCharged, Error::::InvalidPoolState); rewards .iter() .try_for_each(|(reward_currency, reward)| -> DispatchResult { - // let bal = T::MultiCurrency::free_balance(reward_currency.clone(), &exchanger); - // log::info!("token:{:?},balance:{:?},ex:{:?}", reward_currency.clone(), bal, &exchanger); T::MultiCurrency::transfer( *reward_currency, &exchanger, @@ -432,8 +429,6 @@ pub mod pallet { let native_amount = pool_info.basic_token.1.saturating_reciprocal_mul(add_value); pool_info.tokens_proportion.iter().try_for_each( |(token, proportion)| -> DispatchResult { - // let bal = T::MultiCurrency::free_balance(token.clone(), &exchanger); - // log::info!("token:{:?},balance:{:?},ex:{:?}", token.clone(), bal, &exchanger); T::MultiCurrency::transfer( *token, &exchanger, @@ -823,16 +818,3 @@ pub mod pallet { } } } - -// impl FarmingInfo, CurrencyIdOf> for Pallet { -// fn get_token_shares(pool_id: PoolId, currency_id: CurrencyIdOf) -> BalanceOf { -// if let Some(pool_info) = Self::pool_infos(&pool_id) { -// if let Some(token_proportion_value) = pool_info.tokens_proportion.get(¤cy_id) { -// let native_amount = -// pool_info.basic_token.1.saturating_reciprocal_mul(pool_info.total_shares); -// return *token_proportion_value * native_amount; -// } -// } -// Zero::zero() -// } -// } diff --git a/pallets/farming/src/migration.rs b/pallets/farming/src/migration.rs deleted file mode 100644 index c170f2ea8..000000000 --- a/pallets/farming/src/migration.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2020-2023 Manta Network. -// This file is part of Manta. -// -// Manta is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Manta is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Manta. If not, see . - -// use super::{Config, RelaychainLease, Weight}; -use crate::*; -use codec::HasCompact; -use frame_support::traits::Get; -use sp_std::{collections::btree_map::BTreeMap, prelude::*}; - -/// The Reward Pool Info. -#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] -pub struct DeprecatedPoolInfo -{ - pub tokens_proportion: BTreeMap, - /// Total shares amount - pub total_shares: BalanceOf, - pub basic_rewards: BTreeMap, - /// Reward infos - pub rewards: BTreeMap, - pub state: PoolState, - pub keeper: AccountIdOf, - pub reward_issuer: AccountIdOf, - /// Gauge pool id - pub gauge: Option, - pub block_startup: Option, - pub min_deposit_to_start: BalanceOf, - pub after_block_to_start: BlockNumberFor, - pub withdraw_limit_time: BlockNumberFor, - pub claim_limit_time: BlockNumberFor, - pub withdraw_limit_count: u8, -} - -#[allow(dead_code)] -pub fn update_pool_info() -> Weight { - let _ = PoolInfos::::translate::< - DeprecatedPoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, - _, - >( - |_key, - pool| - -> Option, CurrencyIdOf, AccountIdOf, BlockNumberFor>> { - // if let Some(pool) = pool_info { - let a = pool.tokens_proportion.keys().cloned().collect::>>()[0]; - let b = pool.tokens_proportion.values().cloned().collect::>()[0]; - let new_entry = - PoolInfo::, CurrencyIdOf, AccountIdOf, BlockNumberFor> { - tokens_proportion: pool.tokens_proportion, - basic_token: (a, b), - total_shares: pool.total_shares, - basic_rewards: pool.basic_rewards, - rewards: pool.rewards, - state: pool.state, - keeper: pool.keeper, - reward_issuer: pool.reward_issuer, - gauge: pool.gauge, - block_startup: pool.block_startup, - min_deposit_to_start: pool.min_deposit_to_start, - after_block_to_start: pool.after_block_to_start, - withdraw_limit_time: pool.withdraw_limit_time, - claim_limit_time: pool.claim_limit_time, - withdraw_limit_count: pool.withdraw_limit_count, - }; - Some(new_entry) - // } else { - // None - // } - }, - ); - - T::DbWeight::get().reads(1) + T::DbWeight::get().writes(1) -} From 5d61914450ebbd72109af1b7d0d67cf807f4b398 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Wed, 7 Jun 2023 00:29:48 +0800 Subject: [PATCH 05/26] comments and clean Signed-off-by: zqhxuyuan --- Cargo.lock | 360 ++++++++++++++++----------------- pallets/farming/src/lib.rs | 33 ++- pallets/farming/src/rewards.rs | 15 +- pallets/farming/src/tests.rs | 116 +++++++---- 4 files changed, 295 insertions(+), 229 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc4bbf232..5a0e9d386 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -746,7 +746,7 @@ dependencies = [ [[package]] name = "beefy-gadget" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -780,7 +780,7 @@ dependencies = [ [[package]] name = "beefy-gadget-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "beefy-gadget", "futures 0.3.28", @@ -799,7 +799,7 @@ dependencies = [ [[package]] name = "beefy-merkle-tree" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sp-api", "sp-beefy", @@ -3176,7 +3176,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", ] @@ -3199,7 +3199,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -3222,7 +3222,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "Inflector", "array-bytes 4.2.0", @@ -3269,7 +3269,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -3280,7 +3280,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -3297,7 +3297,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -3326,7 +3326,7 @@ dependencies = [ [[package]] name = "frame-remote-externalities" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "log", @@ -3342,7 +3342,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "bitflags", "frame-metadata", @@ -3374,7 +3374,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "Inflector", "cfg-expr", @@ -3388,7 +3388,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -3400,7 +3400,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro2", "quote", @@ -3410,7 +3410,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "log", @@ -3428,7 +3428,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -3443,7 +3443,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-api", @@ -3452,7 +3452,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "parity-scale-codec", @@ -5471,7 +5471,7 @@ dependencies = [ [[package]] name = "manta-farming" -version = "4.0.7" +version = "4.0.8" dependencies = [ "frame-benchmarking", "frame-support", @@ -5495,7 +5495,7 @@ dependencies = [ [[package]] name = "manta-farming-rpc-api" -version = "4.0.7" +version = "4.0.8" dependencies = [ "jsonrpsee", "manta-farming-rpc-runtime-api", @@ -5511,7 +5511,7 @@ dependencies = [ [[package]] name = "manta-farming-rpc-runtime-api" -version = "4.0.7" +version = "4.0.8" dependencies = [ "manta-primitives", "parity-scale-codec", @@ -5822,7 +5822,7 @@ dependencies = [ [[package]] name = "mmr-gadget" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "log", @@ -5841,7 +5841,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "anyhow", "jsonrpsee", @@ -6560,7 +6560,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6575,7 +6575,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6627,7 +6627,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6643,7 +6643,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6658,7 +6658,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6682,7 +6682,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6702,7 +6702,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6717,7 +6717,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6733,7 +6733,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "beefy-merkle-tree", @@ -6756,7 +6756,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6774,7 +6774,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6793,7 +6793,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6810,7 +6810,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "assert_matches", "frame-benchmarking", @@ -6827,7 +6827,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6845,7 +6845,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6868,7 +6868,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6881,7 +6881,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6899,7 +6899,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6917,7 +6917,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6940,7 +6940,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "enumflags2", "frame-benchmarking", @@ -6956,7 +6956,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6976,7 +6976,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7092,7 +7092,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7109,7 +7109,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7126,7 +7126,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7142,7 +7142,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7158,7 +7158,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "1.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7175,7 +7175,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "1.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7195,7 +7195,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "1.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-api", @@ -7205,7 +7205,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7222,7 +7222,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7270,7 +7270,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7287,7 +7287,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7302,7 +7302,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7320,7 +7320,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7335,7 +7335,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "assert_matches", "frame-benchmarking", @@ -7354,7 +7354,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7371,7 +7371,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7392,7 +7392,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7408,7 +7408,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7422,7 +7422,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7445,7 +7445,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7456,7 +7456,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "sp-arithmetic", @@ -7465,7 +7465,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7482,7 +7482,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7496,7 +7496,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7514,7 +7514,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7533,7 +7533,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7549,7 +7549,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -7565,7 +7565,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -7577,7 +7577,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7611,7 +7611,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7627,7 +7627,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7642,7 +7642,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -10160,7 +10160,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "sp-core", @@ -10171,7 +10171,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10198,7 +10198,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "futures-timer", @@ -10221,7 +10221,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -10237,7 +10237,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "memmap2", "sc-chain-spec-derive", @@ -10252,7 +10252,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -10263,7 +10263,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "chrono", @@ -10303,7 +10303,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "fnv", "futures 0.3.28", @@ -10329,7 +10329,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hash-db", "kvdb", @@ -10354,7 +10354,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10379,7 +10379,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10408,7 +10408,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "fork-tree", @@ -10446,7 +10446,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "jsonrpsee", @@ -10468,7 +10468,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "fork-tree", "parity-scale-codec", @@ -10481,7 +10481,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "assert_matches", "async-trait", @@ -10515,7 +10515,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10538,7 +10538,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "lru", "parity-scale-codec", @@ -10562,7 +10562,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", @@ -10575,7 +10575,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "sc-allocator", @@ -10588,7 +10588,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "cfg-if", "libc", @@ -10605,7 +10605,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ahash", "array-bytes 4.2.0", @@ -10645,7 +10645,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "finality-grandpa", "futures 0.3.28", @@ -10665,7 +10665,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ansi_term", "futures 0.3.28", @@ -10680,7 +10680,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -10695,7 +10695,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -10737,7 +10737,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "cid", "futures 0.3.28", @@ -10756,7 +10756,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "bitflags", @@ -10782,7 +10782,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ahash", "futures 0.3.28", @@ -10800,7 +10800,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "futures 0.3.28", @@ -10821,7 +10821,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -10853,7 +10853,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "futures 0.3.28", @@ -10872,7 +10872,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "bytes", @@ -10902,7 +10902,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "libp2p", @@ -10915,7 +10915,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -10924,7 +10924,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "jsonrpsee", @@ -10953,7 +10953,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -10972,7 +10972,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "http", "jsonrpsee", @@ -10987,7 +10987,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "futures 0.3.28", @@ -11013,7 +11013,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "directories", @@ -11078,7 +11078,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "parity-scale-codec", @@ -11089,7 +11089,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -11108,7 +11108,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "libc", @@ -11127,7 +11127,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "chrono", "futures 0.3.28", @@ -11146,7 +11146,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ansi_term", "atty", @@ -11177,7 +11177,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -11188,7 +11188,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -11214,7 +11214,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -11228,7 +11228,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "backtrace", "futures 0.3.28", @@ -11780,7 +11780,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hash-db", "log", @@ -11798,7 +11798,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "blake2 0.10.6", "proc-macro-crate", @@ -11810,7 +11810,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11823,7 +11823,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "integer-sqrt", "num-traits", @@ -11837,7 +11837,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11850,7 +11850,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "parity-scale-codec", @@ -11862,7 +11862,7 @@ dependencies = [ [[package]] name = "sp-beefy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11879,7 +11879,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-api", @@ -11891,7 +11891,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "log", @@ -11909,7 +11909,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -11927,7 +11927,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "parity-scale-codec", @@ -11945,7 +11945,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "merlin", @@ -11968,7 +11968,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11980,7 +11980,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11993,7 +11993,7 @@ dependencies = [ [[package]] name = "sp-core" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "base58", @@ -12035,7 +12035,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "blake2 0.10.6", "byteorder", @@ -12049,7 +12049,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro2", "quote", @@ -12060,7 +12060,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -12069,7 +12069,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro2", "quote", @@ -12079,7 +12079,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.13.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "environmental", "parity-scale-codec", @@ -12090,7 +12090,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "finality-grandpa", "log", @@ -12108,7 +12108,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -12122,7 +12122,7 @@ dependencies = [ [[package]] name = "sp-io" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "bytes", "ed25519", @@ -12147,7 +12147,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "lazy_static", "sp-core", @@ -12158,7 +12158,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.13.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -12175,7 +12175,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "thiserror", "zstd", @@ -12184,7 +12184,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ckb-merkle-mountain-range", "log", @@ -12202,7 +12202,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12216,7 +12216,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sp-api", "sp-core", @@ -12226,7 +12226,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "backtrace", "lazy_static", @@ -12236,7 +12236,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "rustc-hash", "serde", @@ -12246,7 +12246,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "either", "hash256-std-hasher", @@ -12268,7 +12268,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -12286,7 +12286,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "Inflector", "proc-macro-crate", @@ -12298,7 +12298,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12312,7 +12312,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12324,7 +12324,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.13.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hash-db", "log", @@ -12344,12 +12344,12 @@ dependencies = [ [[package]] name = "sp-std" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" [[package]] name = "sp-storage" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12362,7 +12362,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures-timer", @@ -12377,7 +12377,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-std", @@ -12389,7 +12389,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sp-api", "sp-runtime", @@ -12398,7 +12398,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "log", @@ -12414,7 +12414,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ahash", "hash-db", @@ -12437,7 +12437,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12454,7 +12454,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -12465,7 +12465,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "impl-trait-for-tuples", "log", @@ -12478,7 +12478,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12675,7 +12675,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "platforms 2.0.0", ] @@ -12705,7 +12705,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.28", @@ -12724,7 +12724,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hyper", "log", @@ -12736,7 +12736,7 @@ dependencies = [ [[package]] name = "substrate-rpc-client" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "jsonrpsee", @@ -12749,7 +12749,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "log", @@ -12768,7 +12768,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ansi_term", "build-helper", @@ -13386,7 +13386,7 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "clap", "frame-remote-externalities", diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 4b9e69df5..3a893c913 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -61,7 +61,7 @@ type BalanceOf = <::MultiCurrency as MultiCurrency>>::Balance; #[allow(type_alias_bounds)] -type GauseInitType = ( +type GaugeInitType = ( CurrencyIdOf, BlockNumberFor, Vec<(CurrencyIdOf, BalanceOf)>, @@ -194,11 +194,17 @@ pub mod pallet { #[pallet::error] pub enum Error { - CalculationOverflow, + /// Pool not exist PoolDoesNotExist, + /// Gauge pool not exist GaugePoolNotExist, + /// Gauge info not exist GaugeInfoNotExist, + /// Share info is not exist + ShareInfoNotExists, + /// Pool state is invalid InvalidPoolState, + /// Can not claim gauge LastGaugeNotClaim, /// claim_limit_time exceeded CanNotClaim, @@ -206,18 +212,21 @@ pub mod pallet { GaugeMaxBlockOverflow, /// withdraw_limit_time exceeded WithdrawLimitCountExceeded, - ShareInfoNotExists, + /// Can not deposit to pool yet CanNotDeposit, } + /// The next farming pool id. #[pallet::storage] #[pallet::getter(fn pool_next_id)] pub type PoolNextId = StorageValue<_, PoolId, ValueQuery>; + /// The next gauge farming pool id. #[pallet::storage] #[pallet::getter(fn gauge_pool_next_id)] pub type GaugePoolNextId = StorageValue<_, PoolId, ValueQuery>; + /// The retire limit of one operation when retire farming pool. #[pallet::storage] #[pallet::getter(fn retire_limit)] pub type RetireLimit = StorageValue<_, u32, ValueQuery>; @@ -236,6 +245,7 @@ pub mod pallet { #[pallet::getter(fn gauge_pool_infos)] pub type GaugePoolInfos = StorageMap<_, Twox64Concat, PoolId, GaugePoolInfoOf>; + /// #[pallet::storage] #[pallet::getter(fn gauge_infos)] pub type GaugeInfos = @@ -274,8 +284,8 @@ pub mod pallet { { pool_info.block_startup = Some(n); pool_info.state = PoolState::Ongoing; + PoolInfos::::insert(pid, &pool_info); } - PoolInfos::::insert(pid, &pool_info); } _ => (), }); @@ -307,13 +317,14 @@ pub mod pallet { BlockNumberFor: AtLeast32BitUnsigned + Copy, BalanceOf: AtLeast32BitUnsigned + Copy, { + /// `ControlOrigin` create the farming pool. #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::create_farming_pool())] pub fn create_farming_pool( origin: OriginFor, tokens_proportion: Vec<(CurrencyIdOf, Perbill)>, basic_rewards: Vec<(CurrencyIdOf, BalanceOf)>, - gauge_init: Option>, + gauge_init: Option>, min_deposit_to_start: BalanceOf, #[pallet::compact] after_block_to_start: BlockNumberFor, #[pallet::compact] withdraw_limit_time: BlockNumberFor, @@ -371,6 +382,7 @@ pub mod pallet { Ok(()) } + /// After create farming pool, need to deposit reward token into the pool. #[pallet::call_index(1)] #[pallet::weight(0)] pub fn charge( @@ -402,6 +414,7 @@ pub mod pallet { Ok(()) } + /// User can deposit token to farming pool, and get share of pool. #[pallet::call_index(2)] #[pallet::weight(T::WeightInfo::deposit())] pub fn deposit( @@ -426,6 +439,8 @@ pub mod pallet { ); } + // basic token proportion * add_value * token_proportion + // if basic token proportion and token_proportion both equals to 100%, then the final amount to transfer is equal to add_value let native_amount = pool_info.basic_token.1.saturating_reciprocal_mul(add_value); pool_info.tokens_proportion.iter().try_for_each( |(token, proportion)| -> DispatchResult { @@ -457,6 +472,8 @@ pub mod pallet { Ok(()) } + /// User can withdraw token from farming pool, and remove share of pool, also this operation + /// will claim rewards. #[pallet::call_index(3)] #[pallet::weight(T::WeightInfo::withdraw())] pub fn withdraw( @@ -489,6 +506,7 @@ pub mod pallet { Ok(()) } + /// User claim rewards when deposit token into the farming pool. #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::claim())] pub fn claim(origin: OriginFor, pid: PoolId) -> DispatchResult { @@ -521,6 +539,7 @@ pub mod pallet { Ok(()) } + /// User can withdraw but not claim rewards from farming pool. #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::claim())] pub fn withdraw_claim(origin: OriginFor, pid: PoolId) -> DispatchResult { @@ -624,7 +643,7 @@ pub mod pallet { withdraw_limit_time: Option>, claim_limit_time: Option>, withdraw_limit_count: Option, - gauge_init: Option>, + gauge_init: Option>, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -686,7 +705,7 @@ pub mod pallet { let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; ensure!( - pool_info.state == PoolState::Retired || pool_info.state == PoolState::UnCharged, + PoolState::state_valid(Action::KillPool, pool_info.state), Error::::InvalidPoolState ); #[allow(deprecated)] diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs index 66ee2746d..38dc0a079 100644 --- a/pallets/farming/src/rewards.rs +++ b/pallets/farming/src/rewards.rs @@ -66,10 +66,15 @@ pub struct PoolInfo, pub block_startup: Option, + /// The minimum share to starting farming pub min_deposit_to_start: BalanceOf, + /// The minimum block number to starting farming pub after_block_to_start: BlockNumberFor, + /// The limit block number to withdraw pub withdraw_limit_time: BlockNumberFor, + /// The limit block number to claim pub claim_limit_time: BlockNumberFor, + /// The withdraw limit length pub withdraw_limit_count: u8, } @@ -298,6 +303,10 @@ impl Pallet { .as_u128() .saturated_into(); + if withdrawn_reward_to_remove.is_zero() { + return Ok(()); + } + if let Some((total_reward, total_withdrawn_reward)) = pool_info.rewards.get_mut(reward_currency) { @@ -425,12 +434,12 @@ impl Pallet { let n: BlockNumberFor = frame_system::Pallet::::block_number(); let mut tmp: Vec<(BlockNumberFor, BalanceOf)> = Default::default(); share_info.withdraw_list.iter().try_for_each( - |(dest_block, remove_value)| -> DispatchResult { + |(dest_block, remove_amount)| -> DispatchResult { if *dest_block <= n { let native_amount = pool_info .basic_token .1 - .saturating_reciprocal_mul(*remove_value); + .saturating_reciprocal_mul(*remove_amount); pool_info.tokens_proportion.iter().try_for_each( |(token, &proportion)| -> DispatchResult { let withdraw_amount = proportion * native_amount; @@ -457,7 +466,7 @@ impl Pallet { }, )?; } else { - tmp.push((*dest_block, *remove_value)); + tmp.push((*dest_block, *remove_amount)); }; Ok(()) }, diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index c964defac..fbb1ee099 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -21,11 +21,7 @@ use sp_runtime::traits::AccountIdConversion; use crate::{mock::*, *}; -fn init_gauge() -> (PoolId, BalanceOf) { - let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); - tokens_proportion_map - .entry(KSM) - .or_insert(Perbill::from_percent(100)); +fn init_gauge_900() -> (PoolId, BalanceOf) { let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; let tokens = 1000; let basic_rewards = vec![(KSM, 1000)]; @@ -59,21 +55,17 @@ fn init_gauge() -> (PoolId, BalanceOf) { (pid, tokens) } -fn init_no_gauge() -> (PoolId, BalanceOf) { - let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); - tokens_proportion_map - .entry(KSM) - .or_insert(Perbill::from_percent(100)); +fn init_gauge_1000() -> (PoolId, BalanceOf) { let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; let tokens = 1000; let basic_rewards = vec![(KSM, 1000)]; - let gauge_basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = (KSM, 1000, vec![(KSM, 1000)]); assert_ok!(Farming::create_farming_pool( RuntimeOrigin::signed(ALICE), tokens_proportion, basic_rewards, - Some((KSM, 1000, gauge_basic_rewards)), + Some(gauge_basic_rewards), 0, 0, 10, @@ -106,7 +98,7 @@ fn claim() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, _tokens) = init_no_gauge(); + let (pid, _tokens) = init_gauge_1000(); // assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), ShareInfo::default()); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); assert_err!( @@ -147,12 +139,15 @@ fn claim() { } #[test] -fn deposit() { +fn deposit_gause_should_work() { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, tokens) = init_no_gauge(); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + let (pid, tokens) = init_gauge_1000(); + assert_eq!(Assets::balance(KSM, &ALICE), 2000); + System::set_block_number(System::block_number() + 1); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), @@ -160,6 +155,7 @@ fn deposit() { tokens, Some((100, 100)) )); + assert_eq!(Assets::balance(KSM, &ALICE), 900); System::set_block_number(System::block_number() + 1); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), @@ -168,13 +164,14 @@ fn deposit() { Some((100, 100)) )); assert_eq!(Assets::balance(KSM, &ALICE), 800); + let keeper: AccountId = ::Keeper::get().into_sub_account_truncating(pid); let reward_issuer: AccountId = ::RewardIssuer::get().into_sub_account_truncating(pid); let mut gauge_basic_rewards = BTreeMap::, BalanceOf>::new(); - gauge_basic_rewards.entry(KSM).or_insert(1000); + gauge_basic_rewards.entry(KSM).or_insert(tokens); let gauge_pool_info2 = GaugePoolInfo { pid, token: KSM, @@ -193,8 +190,33 @@ fn deposit() { }; assert_eq!(Farming::gauge_pool_infos(0), Some(gauge_pool_info2)); Farming::on_initialize(0); + assert_eq!(Farming::pool_infos(0).unwrap().state, PoolState::Ongoing); + assert!(Farming::pool_infos(0).unwrap().rewards.is_empty()); + assert_eq!( + Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(1000, 0, 0)) + ); + Farming::on_initialize(0); + assert_eq!( + Farming::pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(1000, 0)) + ); + assert_eq!( + Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(2000, 0, 0)) + ); + System::set_block_number(System::block_number() + 1000); + Farming::on_initialize(0); + assert_eq!( + Farming::pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(2000, 0)) + ); + assert_eq!( + Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(3000, 0, 0)) + ); }) } @@ -204,7 +226,7 @@ fn withdraw() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, tokens) = init_no_gauge(); + let (pid, tokens) = init_gauge_1000(); assert_eq!(Assets::balance(KSM, &ALICE), 2000); Farming::on_initialize(0); Farming::on_initialize(0); @@ -253,7 +275,7 @@ fn gauge() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, tokens) = init_gauge(); + let (pid, tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { assert_eq!( @@ -309,7 +331,7 @@ fn gauge_withdraw() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, _tokens) = init_gauge(); + let (pid, _tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { assert_eq!(gauge_pool_infos.gauge_amount, 100) @@ -336,7 +358,7 @@ fn retire() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, tokens) = init_no_gauge(); + let (pid, tokens) = init_gauge_1000(); Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); assert_ok!(Farming::deposit( @@ -380,7 +402,7 @@ fn reset() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, _tokens) = init_gauge(); + let (pid, _tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); @@ -473,15 +495,11 @@ fn reset() { } #[test] -fn create_farming_pool() { +fn gauge_farming_pool_should_work() { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); - tokens_proportion_map - .entry(KSM) - .or_insert(Perbill::from_percent(100)); let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; let tokens = 1000; let basic_rewards = vec![(KSM, 1000)]; @@ -498,6 +516,7 @@ fn create_farming_pool() { 6, 5 )); + assert_eq!(PoolNextId::::get(), 1); assert_ok!(Farming::create_farming_pool( RuntimeOrigin::signed(ALICE), tokens_proportion, @@ -509,11 +528,14 @@ fn create_farming_pool() { 6, 5 )); - if let Some(pool_infos) = Farming::pool_infos(0) { - assert_eq!(pool_infos.state, PoolState::UnCharged) - }; + assert_eq!(PoolNextId::::get(), 2); + + // Query pool initial state, kill the pool + assert_eq!(Farming::pool_infos(0).unwrap().state, PoolState::UnCharged); assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), 0)); + assert_eq!(Farming::pool_infos(0), None); + // Charge to the pool let pid = 1; let charge_rewards = vec![(KSM, 300000)]; assert_ok!(Farming::charge( @@ -521,29 +543,39 @@ fn create_farming_pool() { pid, charge_rewards )); - if let Some(pool_infos) = Farming::pool_infos(0) { - assert_eq!(pool_infos.total_shares, 0); - assert_eq!(pool_infos.min_deposit_to_start, 2); - assert_eq!(pool_infos.state, PoolState::Charged) - }; + let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 0); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Charged); + + // Deposit to the pool assert_err!( Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 100))), Error::::CanNotDeposit ); System::set_block_number(System::block_number() + 3); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 100)) )); + assert_eq!(Assets::balance(KSM, &ALICE), 1900); + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 1000); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Charged); + + // OnInitialize hook change the pool state Farming::on_initialize(System::block_number() + 3); Farming::on_initialize(0); - if let Some(pool_infos) = Farming::pool_infos(0) { - assert_eq!(pool_infos.total_shares, 1000); - assert_eq!(pool_infos.min_deposit_to_start, 2); - assert_eq!(pool_infos.state, PoolState::Ongoing) - }; + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 1000); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Ongoing); + + // Claim to get rewards assert_err!( Farming::claim(RuntimeOrigin::signed(ALICE), pid), Error::::CanNotClaim @@ -551,14 +583,20 @@ fn create_farming_pool() { System::set_block_number(System::block_number() + 6); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 3008); + System::set_block_number(System::block_number() + 100); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 4698); + + // Withdraw part tokens assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), pid, Some(800) )); + assert_eq!(Assets::balance(KSM, &ALICE), 4698); + + // Claim again System::set_block_number(System::block_number() + 6); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_err!( From 13794db3038879e05dce70c8030566cb24d2d41d Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Fri, 9 Jun 2023 16:37:52 +0800 Subject: [PATCH 06/26] fix comments Signed-off-by: zqhxuyuan --- Cargo.lock | 360 ++++++++++----------- pallets/farming/Cargo.toml | 2 +- pallets/farming/rpc/Cargo.toml | 2 +- pallets/farming/rpc/runtime-api/Cargo.toml | 2 +- pallets/farming/src/gauge.rs | 4 +- pallets/farming/src/lib.rs | 12 +- 6 files changed, 193 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6026d8eea..95f2c8e45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -746,7 +746,7 @@ dependencies = [ [[package]] name = "beefy-gadget" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -780,7 +780,7 @@ dependencies = [ [[package]] name = "beefy-gadget-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "beefy-gadget", "futures 0.3.28", @@ -799,7 +799,7 @@ dependencies = [ [[package]] name = "beefy-merkle-tree" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sp-api", "sp-beefy", @@ -3176,7 +3176,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", ] @@ -3199,7 +3199,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -3222,7 +3222,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "Inflector", "array-bytes 4.2.0", @@ -3269,7 +3269,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -3280,7 +3280,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -3297,7 +3297,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -3326,7 +3326,7 @@ dependencies = [ [[package]] name = "frame-remote-externalities" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "log", @@ -3342,7 +3342,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "bitflags", "frame-metadata", @@ -3374,7 +3374,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "Inflector", "cfg-expr", @@ -3388,7 +3388,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -3400,7 +3400,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro2", "quote", @@ -3410,7 +3410,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "log", @@ -3428,7 +3428,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -3443,7 +3443,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-api", @@ -3452,7 +3452,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "parity-scale-codec", @@ -5471,7 +5471,7 @@ dependencies = [ [[package]] name = "manta-farming" -version = "4.0.8" +version = "4.1.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -5495,7 +5495,7 @@ dependencies = [ [[package]] name = "manta-farming-rpc-api" -version = "4.0.8" +version = "4.1.0" dependencies = [ "jsonrpsee", "manta-farming-rpc-runtime-api", @@ -5511,7 +5511,7 @@ dependencies = [ [[package]] name = "manta-farming-rpc-runtime-api" -version = "4.0.8" +version = "4.1.0" dependencies = [ "manta-primitives", "parity-scale-codec", @@ -5823,7 +5823,7 @@ dependencies = [ [[package]] name = "mmr-gadget" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "log", @@ -5842,7 +5842,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "anyhow", "jsonrpsee", @@ -6561,7 +6561,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6576,7 +6576,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6628,7 +6628,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6644,7 +6644,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6659,7 +6659,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6683,7 +6683,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6703,7 +6703,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6718,7 +6718,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -6734,7 +6734,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "beefy-merkle-tree", @@ -6757,7 +6757,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6775,7 +6775,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6794,7 +6794,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6811,7 +6811,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "assert_matches", "frame-benchmarking", @@ -6828,7 +6828,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6846,7 +6846,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6869,7 +6869,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6882,7 +6882,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6900,7 +6900,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6918,7 +6918,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6941,7 +6941,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "enumflags2", "frame-benchmarking", @@ -6957,7 +6957,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -6977,7 +6977,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7093,7 +7093,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7110,7 +7110,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7127,7 +7127,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7143,7 +7143,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7159,7 +7159,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "1.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7176,7 +7176,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "1.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7196,7 +7196,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "1.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-api", @@ -7206,7 +7206,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7223,7 +7223,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7271,7 +7271,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7288,7 +7288,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7303,7 +7303,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7321,7 +7321,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7336,7 +7336,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "assert_matches", "frame-benchmarking", @@ -7355,7 +7355,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7372,7 +7372,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7393,7 +7393,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7409,7 +7409,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7423,7 +7423,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7446,7 +7446,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7457,7 +7457,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "sp-arithmetic", @@ -7466,7 +7466,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7483,7 +7483,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7497,7 +7497,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7515,7 +7515,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7534,7 +7534,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-support", "frame-system", @@ -7550,7 +7550,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -7566,7 +7566,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -7578,7 +7578,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7612,7 +7612,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7628,7 +7628,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -7643,7 +7643,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-benchmarking", "frame-support", @@ -10161,7 +10161,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "sp-core", @@ -10172,7 +10172,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10199,7 +10199,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "futures-timer", @@ -10222,7 +10222,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -10238,7 +10238,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "memmap2", "sc-chain-spec-derive", @@ -10253,7 +10253,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -10264,7 +10264,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "chrono", @@ -10304,7 +10304,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "fnv", "futures 0.3.28", @@ -10330,7 +10330,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hash-db", "kvdb", @@ -10355,7 +10355,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10380,7 +10380,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10409,7 +10409,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "fork-tree", @@ -10447,7 +10447,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "jsonrpsee", @@ -10469,7 +10469,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "fork-tree", "parity-scale-codec", @@ -10482,7 +10482,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "assert_matches", "async-trait", @@ -10516,7 +10516,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -10539,7 +10539,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "lru", "parity-scale-codec", @@ -10563,7 +10563,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", @@ -10576,7 +10576,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "sc-allocator", @@ -10589,7 +10589,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "cfg-if", "libc", @@ -10606,7 +10606,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ahash", "array-bytes 4.2.0", @@ -10646,7 +10646,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "finality-grandpa", "futures 0.3.28", @@ -10666,7 +10666,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ansi_term", "futures 0.3.28", @@ -10681,7 +10681,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -10696,7 +10696,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -10738,7 +10738,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "cid", "futures 0.3.28", @@ -10757,7 +10757,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "bitflags", @@ -10783,7 +10783,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ahash", "futures 0.3.28", @@ -10801,7 +10801,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "futures 0.3.28", @@ -10822,7 +10822,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -10854,7 +10854,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "futures 0.3.28", @@ -10873,7 +10873,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "bytes", @@ -10903,7 +10903,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "libp2p", @@ -10916,7 +10916,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -10925,7 +10925,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "jsonrpsee", @@ -10954,7 +10954,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -10973,7 +10973,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "http", "jsonrpsee", @@ -10988,7 +10988,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "futures 0.3.28", @@ -11014,7 +11014,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "directories", @@ -11079,7 +11079,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "log", "parity-scale-codec", @@ -11090,7 +11090,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -11109,7 +11109,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "libc", @@ -11128,7 +11128,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "chrono", "futures 0.3.28", @@ -11147,7 +11147,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ansi_term", "atty", @@ -11178,7 +11178,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -11189,7 +11189,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -11215,7 +11215,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -11229,7 +11229,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "backtrace", "futures 0.3.28", @@ -11781,7 +11781,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hash-db", "log", @@ -11799,7 +11799,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "blake2 0.10.6", "proc-macro-crate", @@ -11811,7 +11811,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11824,7 +11824,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "integer-sqrt", "num-traits", @@ -11838,7 +11838,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11851,7 +11851,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "parity-scale-codec", @@ -11863,7 +11863,7 @@ dependencies = [ [[package]] name = "sp-beefy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11880,7 +11880,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-api", @@ -11892,7 +11892,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "futures 0.3.28", "log", @@ -11910,7 +11910,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -11928,7 +11928,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "parity-scale-codec", @@ -11946,7 +11946,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "merlin", @@ -11969,7 +11969,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11981,7 +11981,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -11994,7 +11994,7 @@ dependencies = [ [[package]] name = "sp-core" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "array-bytes 4.2.0", "base58", @@ -12036,7 +12036,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "blake2 0.10.6", "byteorder", @@ -12050,7 +12050,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro2", "quote", @@ -12061,7 +12061,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -12070,7 +12070,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "proc-macro2", "quote", @@ -12080,7 +12080,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.13.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "environmental", "parity-scale-codec", @@ -12091,7 +12091,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "finality-grandpa", "log", @@ -12109,7 +12109,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -12123,7 +12123,7 @@ dependencies = [ [[package]] name = "sp-io" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "bytes", "ed25519", @@ -12148,7 +12148,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "lazy_static", "sp-core", @@ -12159,7 +12159,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.13.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures 0.3.28", @@ -12176,7 +12176,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "thiserror", "zstd", @@ -12185,7 +12185,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ckb-merkle-mountain-range", "log", @@ -12203,7 +12203,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12217,7 +12217,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sp-api", "sp-core", @@ -12227,7 +12227,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "backtrace", "lazy_static", @@ -12237,7 +12237,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "rustc-hash", "serde", @@ -12247,7 +12247,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "either", "hash256-std-hasher", @@ -12269,7 +12269,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -12287,7 +12287,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "Inflector", "proc-macro-crate", @@ -12299,7 +12299,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12313,7 +12313,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12325,7 +12325,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.13.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hash-db", "log", @@ -12345,12 +12345,12 @@ dependencies = [ [[package]] name = "sp-std" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" [[package]] name = "sp-storage" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12363,7 +12363,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "futures-timer", @@ -12378,7 +12378,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "sp-std", @@ -12390,7 +12390,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "sp-api", "sp-runtime", @@ -12399,7 +12399,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "log", @@ -12415,7 +12415,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ahash", "hash-db", @@ -12438,7 +12438,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12455,7 +12455,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -12466,7 +12466,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "7.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "impl-trait-for-tuples", "log", @@ -12479,7 +12479,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "parity-scale-codec", "scale-info", @@ -12676,7 +12676,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "platforms 2.0.0", ] @@ -12706,7 +12706,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.28", @@ -12725,7 +12725,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "hyper", "log", @@ -12737,7 +12737,7 @@ dependencies = [ [[package]] name = "substrate-rpc-client" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "async-trait", "jsonrpsee", @@ -12750,7 +12750,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "jsonrpsee", "log", @@ -12769,7 +12769,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "ansi_term", "build-helper", @@ -13387,7 +13387,7 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.37#6fa7fe1326ecaab9921c2c3888530ad679cfbb87" dependencies = [ "clap", "frame-remote-externalities", diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 5ee0b73d0..3bb7ea236 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.0.8" +version = "4.1.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/rpc/Cargo.toml b/pallets/farming/rpc/Cargo.toml index 9f6bd0335..205133aea 100644 --- a/pallets/farming/rpc/Cargo.toml +++ b/pallets/farming/rpc/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming-rpc-api" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.0.8" +version = "4.1.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/rpc/runtime-api/Cargo.toml b/pallets/farming/rpc/runtime-api/Cargo.toml index f4b6fd135..39920828e 100644 --- a/pallets/farming/rpc/runtime-api/Cargo.toml +++ b/pallets/farming/rpc/runtime-api/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming-rpc-runtime-api" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.0.8" +version = "4.1.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 1de698975..bbd83b98a 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -140,7 +140,9 @@ where GaugePoolInfos::::insert(gid, &gauge_pool_info); GaugePoolNextId::::mutate(|id| -> DispatchResult { - *id = id.checked_add(1).ok_or(ArithmeticError::Overflow)?; + *id = id + .checked_add(One::one()) + .ok_or(ArithmeticError::Overflow)?; Ok(()) })?; Ok(()) diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 3a893c913..defbba4ad 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -36,7 +36,7 @@ use frame_support::{ use frame_system::pallet_prelude::*; use manta_primitives::types::PoolId; use orml_traits::MultiCurrency; -use sp_runtime::SaturatedConversion; +use sp_runtime::{traits::One, SaturatedConversion}; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; pub mod gauge; @@ -325,11 +325,11 @@ pub mod pallet { tokens_proportion: Vec<(CurrencyIdOf, Perbill)>, basic_rewards: Vec<(CurrencyIdOf, BalanceOf)>, gauge_init: Option>, - min_deposit_to_start: BalanceOf, + #[pallet::compact] min_deposit_to_start: BalanceOf, #[pallet::compact] after_block_to_start: BlockNumberFor, #[pallet::compact] withdraw_limit_time: BlockNumberFor, #[pallet::compact] claim_limit_time: BlockNumberFor, - withdraw_limit_count: u8, + #[pallet::compact] withdraw_limit_count: u8, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -374,7 +374,9 @@ pub mod pallet { PoolInfos::::insert(pid, &pool_info); PoolNextId::::mutate(|id| -> DispatchResult { - *id = id.checked_add(1).ok_or(ArithmeticError::Overflow)?; + *id = id + .checked_add(One::one()) + .ok_or(ArithmeticError::Overflow)?; Ok(()) })?; @@ -420,7 +422,7 @@ pub mod pallet { pub fn deposit( origin: OriginFor, pid: PoolId, - add_value: BalanceOf, + #[pallet::compact] add_value: BalanceOf, gauge_info: Option<(BalanceOf, BlockNumberFor)>, ) -> DispatchResult { let exchanger = ensure_signed(origin)?; From 616206001ae50e61c7621b3771216f07a88758a7 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 27 Jun 2023 17:46:29 +0800 Subject: [PATCH 07/26] refactor reward calculation Signed-off-by: zqhxuyuan --- pallets/farming/src/gauge.rs | 87 +--------------- pallets/farming/src/lib.rs | 180 ++++++++++++++++++++++++--------- pallets/farming/src/rewards.rs | 155 ++++++---------------------- pallets/farming/src/tests.rs | 8 +- 4 files changed, 166 insertions(+), 264 deletions(-) diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index bbd83b98a..adef6caf0 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -297,8 +297,7 @@ where let reward = reward_amount .checked_sub(total_gauged_reward) .ok_or(ArithmeticError::Overflow)?; - // gauge_reward = gauge rate * gauge rewards * existing rewards in the - // gauge pool + // gauge_reward = gauge rate * gauge rewards * existing rewards let gauge_reward = gauge_rate * reward; // reward_to_claim = farming rate * gauge rate * gauge rewards * // existing rewards in the gauge pool @@ -318,51 +317,14 @@ where .checked_add(&reward_to_claim) .ok_or(ArithmeticError::Overflow)?; - let ed = T::MultiCurrency::minimum_balance(*reward_currency); - let mut account_to_send = who.clone(); - - if reward_to_claim < ed { - let receiver_balance = - T::MultiCurrency::total_balance(*reward_currency, who); - - let receiver_balance_after = receiver_balance - .checked_add(&reward_to_claim) - .ok_or(ArithmeticError::Overflow)?; - if receiver_balance_after < ed { - account_to_send = T::TreasuryAccount::get(); - } - } - T::MultiCurrency::transfer( - *reward_currency, - &gauge_pool_info.reward_issuer, - &account_to_send, - reward_to_claim, - ) + Self::reward_token_transfer(reward_currency, reward_to_claim, who, &gauge_pool_info.reward_issuer) }, )?; gauge_info.last_claim_block = current_block_number; gauge_info.claimed_time_factor = latest_claimed_time_factor; if gauge_info.gauge_stop_block <= current_block_number { - let ed = T::MultiCurrency::minimum_balance(gauge_pool_info.token); - let mut account_to_send = who.clone(); - - if gauge_info.gauge_amount < ed { - let receiver_balance = - T::MultiCurrency::total_balance(gauge_pool_info.token, who); + Self::reward_token_transfer(&gauge_pool_info.token, gauge_info.gauge_amount, who, &gauge_pool_info.keeper)?; - let receiver_balance_after = receiver_balance - .checked_add(&gauge_info.gauge_amount) - .ok_or(ArithmeticError::Overflow)?; - if receiver_balance_after < ed { - account_to_send = T::TreasuryAccount::get(); - } - } - T::MultiCurrency::transfer( - gauge_pool_info.token, - &gauge_pool_info.keeper, - &account_to_send, - gauge_info.gauge_amount, - )?; gauge_pool_info.total_time_factor = gauge_pool_info .total_time_factor .checked_sub(gauge_info.total_time_factor) @@ -381,49 +343,6 @@ where Ok(()) } - pub fn get_farming_rewards( - who: &T::AccountId, - pid: PoolId, - ) -> Result, DispatchError> { - let share_info = - SharesAndWithdrawnRewards::::get(pid, who).ok_or(Error::::ShareInfoNotExists)?; - let pool_info = PoolInfos::::get(pid).ok_or(Error::::PoolDoesNotExist)?; - let total_shares = U256::from(pool_info.total_shares.to_owned().saturated_into::()); - let mut result_vec = Vec::<(CurrencyIdOf, BalanceOf)>::new(); - - pool_info.rewards.iter().try_for_each( - |(reward_currency, (total_reward, total_withdrawn_reward))| -> DispatchResult { - let withdrawn_reward = share_info - .withdrawn_rewards - .get(reward_currency) - .copied() - .unwrap_or_default(); - - let total_reward_proportion: BalanceOf = - U256::from(share_info.share.to_owned().saturated_into::()) - .saturating_mul(U256::from( - total_reward.to_owned().saturated_into::(), - )) - .checked_div(total_shares) - .unwrap_or_default() - .as_u128() - .unique_saturated_into(); - - let reward_to_withdraw = total_reward_proportion - .saturating_sub(withdrawn_reward) - .min(total_reward.saturating_sub(*total_withdrawn_reward)); - - if reward_to_withdraw.is_zero() { - return Ok(()); - }; - - result_vec.push((*reward_currency, reward_to_withdraw)); - Ok(()) - }, - )?; - Ok(result_vec) - } - pub fn get_gauge_rewards( who: &T::AccountId, pid: PoolId, diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index defbba4ad..78a68d125 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -16,33 +16,29 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(test)] -mod mock; - -#[cfg(test)] -mod tests; - -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - use frame_support::{ pallet_prelude::*, - sp_runtime::{ - traits::{AccountIdConversion, AtLeast32BitUnsigned, Saturating, Zero}, - ArithmeticError, Perbill, - }, PalletId, }; use frame_system::pallet_prelude::*; use manta_primitives::types::PoolId; -use orml_traits::MultiCurrency; -use sp_runtime::{traits::One, SaturatedConversion}; -use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; +use orml_traits::{arithmetic::CheckedAdd, MultiCurrency}; +use sp_core::U256; +use sp_runtime::{ + traits::{AccountIdConversion, AtLeast32BitUnsigned, Saturating, Zero, One}, + ArithmeticError, Perbill, SaturatedConversion +}; +use sp_std::{borrow::ToOwned, collections::btree_map::BTreeMap, vec::Vec}; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; pub mod gauge; pub mod rewards; pub mod weights; - pub use gauge::*; pub use pallet::*; pub use rewards::*; @@ -559,12 +555,43 @@ pub mod pallet { #[pallet::call_index(6)] #[pallet::weight(0)] - pub fn force_retire_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + pub fn close_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; ensure!( - PoolState::state_valid(Action::ForceRetirePool, pool_info.state), + PoolState::state_valid(Action::ClosePool, pool_info.state), + Error::::InvalidPoolState + ); + + pool_info.state = PoolState::Dead; + PoolInfos::::insert(pid, pool_info); + + Self::deposit_event(Event::FarmingPoolClosed { pid }); + Ok(()) + } + + #[pallet::call_index(7)] + #[pallet::weight(0)] + pub fn set_retire_limit(origin: OriginFor, limit: u32) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + RetireLimit::::mutate(|old_limit| { + *old_limit = limit; + }); + + Self::deposit_event(Event::RetireLimitSet { limit }); + Ok(()) + } + + #[pallet::call_index(8)] + #[pallet::weight(0)] + pub fn retire_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + ensure!( + PoolState::state_valid(Action::RetirePool, pool_info.state), Error::::InvalidPoolState ); @@ -603,37 +630,6 @@ pub mod pallet { Ok(()) } - #[pallet::call_index(7)] - #[pallet::weight(0)] - pub fn set_retire_limit(origin: OriginFor, limit: u32) -> DispatchResult { - T::ControlOrigin::ensure_origin(origin)?; - - RetireLimit::::mutate(|old_limit| { - *old_limit = limit; - }); - - Self::deposit_event(Event::RetireLimitSet { limit }); - Ok(()) - } - - #[pallet::call_index(8)] - #[pallet::weight(0)] - pub fn close_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { - T::ControlOrigin::ensure_origin(origin)?; - - let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; - ensure!( - PoolState::state_valid(Action::ClosePool, pool_info.state), - Error::::InvalidPoolState - ); - - pool_info.state = PoolState::Dead; - PoolInfos::::insert(pid, pool_info); - - Self::deposit_event(Event::FarmingPoolClosed { pid }); - Ok(()) - } - #[pallet::call_index(9)] #[pallet::weight(0)] pub fn reset_pool( @@ -839,3 +835,87 @@ pub mod pallet { } } } + +impl Pallet { + fn reward_token_transfer(reward_currency: &CurrencyIdOf, reward_to_withdraw: BalanceOf, who: &T::AccountId, from: &T::AccountId) -> DispatchResult { + let ed = T::MultiCurrency::minimum_balance(*reward_currency); + let mut account_to_send = who.clone(); + + if reward_to_withdraw < ed { + let receiver_balance = T::MultiCurrency::total_balance(*reward_currency, who); + + let receiver_balance_after = + receiver_balance.checked_add(&reward_to_withdraw).ok_or(ArithmeticError::Overflow)?; + if receiver_balance_after < ed { + account_to_send = T::TreasuryAccount::get(); + } + } + // pay reward to `who` + T::MultiCurrency::transfer( + *reward_currency, + from, + &account_to_send, + reward_to_withdraw, + ) + } + + pub fn get_farming_rewards( + who: &T::AccountId, + pid: PoolId, + ) -> Result, DispatchError> { + let share_info = + SharesAndWithdrawnRewards::::get(pid, who).ok_or(Error::::ShareInfoNotExists)?; + let pool_info = PoolInfos::::get(pid).ok_or(Error::::PoolDoesNotExist)?; + let total_shares = pool_info.total_shares; + let mut result_vec = Vec::<(CurrencyIdOf, BalanceOf)>::new(); + + pool_info.rewards.iter().try_for_each( + |(reward_currency, (total_reward, total_withdrawn_reward))| -> DispatchResult { + let (_, reward_to_withdraw) = Self::get_reward_amount( + &share_info, total_reward, total_withdrawn_reward, total_shares, reward_currency)?; + + if reward_to_withdraw.is_zero() { + return Ok(()); + }; + + result_vec.push((*reward_currency, reward_to_withdraw)); + Ok(()) + }, + )?; + Ok(result_vec) + } + + fn get_reward_amount(share_info: &ShareInfoOf, + total_reward: &BalanceOf, + total_withdrawn_reward: &BalanceOf, + total_shares: BalanceOf, + reward_currency: &CurrencyIdOf + ) -> Result<(BalanceOf, BalanceOf), DispatchError> { + let withdrawn_reward = share_info + .withdrawn_rewards + .get(reward_currency) + .copied() + .unwrap_or_default(); + + let total_reward_proportion: BalanceOf = Self::get_reward_inflation(share_info.share, total_reward, total_shares); + + let reward_to_withdraw = total_reward_proportion + .saturating_sub(withdrawn_reward) + .min(total_reward.saturating_sub(*total_withdrawn_reward)); + + Ok((withdrawn_reward, reward_to_withdraw)) + } + + fn get_reward_inflation(amount: BalanceOf, total_reward: &BalanceOf, total_share: BalanceOf) -> BalanceOf { + let total_reward_proportion: BalanceOf = + U256::from(amount.to_owned().saturated_into::()) + .saturating_mul(U256::from( + total_reward.to_owned().saturated_into::(), + )) + .checked_div(U256::from(total_share.to_owned().saturated_into::())) + .unwrap_or_default() + .as_u128() + .saturated_into(); + total_reward_proportion + } +} diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs index 38dc0a079..009085ffa 100644 --- a/pallets/farming/src/rewards.rs +++ b/pallets/farming/src/rewards.rs @@ -17,12 +17,11 @@ use crate::*; use codec::HasCompact; use scale_info::TypeInfo; -use sp_core::U256; use sp_runtime::{ - traits::{CheckedAdd, Saturating, UniqueSaturatedInto, Zero}, - RuntimeDebug, SaturatedConversion, + traits::{Saturating, Zero}, + RuntimeDebug, }; -use sp_std::{borrow::ToOwned, collections::btree_map::BTreeMap, prelude::*}; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] pub struct ShareInfo { @@ -132,7 +131,7 @@ pub enum Action { Deposit, Withdraw, Claim, - ForceRetirePool, + RetirePool, ClosePool, ResetPool, KillPool, @@ -149,8 +148,8 @@ impl PoolState { || state == PoolState::Dead } Action::Claim => state == PoolState::Ongoing || state == PoolState::Dead, - Action::ForceRetirePool => state == PoolState::Dead, Action::ClosePool => state == PoolState::Ongoing, + Action::RetirePool => state == PoolState::Dead, Action::ResetPool => state == PoolState::Retired, Action::KillPool => state == PoolState::Retired || state == PoolState::UnCharged, Action::EditPool => { @@ -164,31 +163,6 @@ impl PoolState { } impl Pallet { - pub fn accumulate_reward( - pool: PoolId, - reward_currency: CurrencyIdOf, - reward_increment: BalanceOf, - ) -> DispatchResult { - if reward_increment.is_zero() { - return Ok(()); - } - PoolInfos::::mutate_exists(pool, |maybe_pool_info| -> DispatchResult { - let pool_info = maybe_pool_info - .as_mut() - .ok_or(Error::::PoolDoesNotExist)?; - - pool_info - .rewards - .entry(reward_currency) - .and_modify(|(total_reward, _)| { - *total_reward = total_reward.saturating_add(reward_increment); - }) - .or_insert((reward_increment, Zero::zero())); - - Ok(()) - }) - } - pub fn add_share( who: &T::AccountId, pid: PoolId, @@ -199,27 +173,25 @@ impl Pallet { return; } + // update pool total share let initial_total_shares = pool_info.total_shares; pool_info.total_shares = pool_info.total_shares.saturating_add(add_amount); + // update user share + let n: BlockNumberFor = frame_system::Pallet::::block_number(); + let mut share_info = SharesAndWithdrawnRewards::::get(pid, who) + .unwrap_or_else(|| ShareInfo::new(who.clone(), n)); + share_info.share = share_info.share.saturating_add(add_amount); + let mut withdrawn_inflation = Vec::<(CurrencyIdOf, BalanceOf)>::new(); + // update pool rewards pool_info.rewards.iter_mut().for_each( |(reward_currency, (total_reward, total_withdrawn_reward))| { let reward_inflation = if initial_total_shares.is_zero() { Zero::zero() } else { - U256::from(add_amount.to_owned().saturated_into::()) - .saturating_mul(total_reward.to_owned().saturated_into::().into()) - .checked_div( - initial_total_shares - .to_owned() - .saturated_into::() - .into(), - ) - .unwrap_or_default() - .as_u128() - .saturated_into() + Self::get_reward_inflation(add_amount, total_reward, initial_total_shares) }; *total_reward = total_reward.saturating_add(reward_inflation); *total_withdrawn_reward = total_withdrawn_reward.saturating_add(reward_inflation); @@ -228,12 +200,7 @@ impl Pallet { }, ); - let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); - - let mut share_info = SharesAndWithdrawnRewards::::get(pid, who) - .unwrap_or_else(|| ShareInfo::new(who.clone(), current_block_number)); - share_info.share = share_info.share.saturating_add(add_amount); - // update withdrawn inflation for each reward currency + // update withdrawn inflation for each reward currency of user share withdrawn_inflation .into_iter() .for_each(|(reward_currency, reward_inflation)| { @@ -245,6 +212,7 @@ impl Pallet { }) .or_insert(reward_inflation); }); + SharesAndWithdrawnRewards::::insert(pid, who, share_info); PoolInfos::::insert(pid, pool_info); } @@ -265,7 +233,7 @@ impl Pallet { Self::claim_rewards(who, pool)?; SharesAndWithdrawnRewards::::mutate(pool, who, |share_info_old| -> DispatchResult { - let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); + let n: BlockNumberFor = frame_system::Pallet::::block_number(); if let Some(mut share_info) = share_info_old.take() { let remove_amount; if let Some(remove_amount_input) = remove_amount_input { @@ -273,7 +241,6 @@ impl Pallet { } else { remove_amount = share_info.share; } - if remove_amount.is_zero() { return Ok(()); } @@ -285,24 +252,16 @@ impl Pallet { share_info .withdraw_list - .push((current_block_number + withdraw_limit_time, remove_amount)); - - let removing_share = U256::from(remove_amount.saturated_into::()); + .push((n + withdraw_limit_time, remove_amount)); pool_info.total_shares = pool_info.total_shares.saturating_sub(remove_amount); // update withdrawn rewards for each reward currency share_info.withdrawn_rewards.iter_mut().try_for_each( |(reward_currency, withdrawn_reward)| -> DispatchResult { - let withdrawn_reward_to_remove: BalanceOf = removing_share - .saturating_mul( - withdrawn_reward.to_owned().saturated_into::().into(), - ) - .checked_div(share_info.share.saturated_into::().into()) - .unwrap_or_default() - .as_u128() - .saturated_into(); - + let withdrawn_reward_to_remove = Self::get_reward_inflation( + remove_amount,withdrawn_reward,share_info.share + ); if withdrawn_reward_to_remove.is_zero() { return Ok(()); } @@ -341,8 +300,7 @@ impl Pallet { pool, who, |maybe_share_withdrawn| -> DispatchResult { - let current_block_number: BlockNumberFor = - frame_system::Pallet::::block_number(); + let n: BlockNumberFor = frame_system::Pallet::::block_number(); if let Some(share_info) = maybe_share_withdrawn { if share_info.share.is_zero() { return Ok(()); @@ -353,30 +311,11 @@ impl Pallet { .as_mut() .ok_or(Error::::PoolDoesNotExist)?; - let total_shares = - U256::from(pool_info.total_shares.to_owned().saturated_into::()); + let total_shares = pool_info.total_shares; pool_info.rewards.iter_mut().try_for_each( |(reward_currency, (total_reward, total_withdrawn_reward))| -> DispatchResult { - let withdrawn_reward = share_info - .withdrawn_rewards - .get(reward_currency) - .copied() - .unwrap_or_default(); - - let total_reward_proportion: BalanceOf = U256::from( - share_info.share.to_owned().saturated_into::(), - ) - .saturating_mul(U256::from( - total_reward.to_owned().saturated_into::(), - )) - .checked_div(total_shares) - .unwrap_or_default() - .as_u128() - .unique_saturated_into(); - - let reward_to_withdraw = total_reward_proportion - .saturating_sub(withdrawn_reward) - .min(total_reward.saturating_sub(*total_withdrawn_reward)); + let (withdrawn_reward, reward_to_withdraw) = Self::get_reward_amount( + share_info, total_reward, total_withdrawn_reward, total_shares, reward_currency)?; if reward_to_withdraw.is_zero() { return Ok(()); @@ -389,30 +328,12 @@ impl Pallet { withdrawn_reward.saturating_add(reward_to_withdraw), ); - let ed = T::MultiCurrency::minimum_balance(*reward_currency); - let mut account_to_send = who.clone(); - - if reward_to_withdraw < ed { - let receiver_balance = T::MultiCurrency::total_balance(*reward_currency, who); - - let receiver_balance_after = - receiver_balance.checked_add(&reward_to_withdraw).ok_or(ArithmeticError::Overflow)?; - if receiver_balance_after < ed { - account_to_send = T::TreasuryAccount::get(); - } - } - // pay reward to `who` - T::MultiCurrency::transfer( - *reward_currency, - &pool_info.reward_issuer, - &account_to_send, - reward_to_withdraw, - ) + Self::reward_token_transfer(reward_currency, reward_to_withdraw, who, &pool_info.reward_issuer) }, )?; Ok(()) })?; - share_info.claim_last_block = current_block_number; + share_info.claim_last_block = n; }; Ok(()) }, @@ -443,26 +364,8 @@ impl Pallet { pool_info.tokens_proportion.iter().try_for_each( |(token, &proportion)| -> DispatchResult { let withdraw_amount = proportion * native_amount; - let ed = T::MultiCurrency::minimum_balance(*token); - let mut account_to_send = who.clone(); - - if withdraw_amount < ed { - let receiver_balance = - T::MultiCurrency::total_balance(*token, who); - - let receiver_balance_after = receiver_balance - .checked_add(&withdraw_amount) - .ok_or(ArithmeticError::Overflow)?; - if receiver_balance_after < ed { - account_to_send = T::TreasuryAccount::get(); - } - } - T::MultiCurrency::transfer( - *token, - &pool_info.keeper, - &account_to_send, - withdraw_amount, - ) + + Self::reward_token_transfer(token, withdraw_amount, who, &pool_info.keeper) }, )?; } else { diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index fbb1ee099..bb250891d 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -125,14 +125,14 @@ fn claim() { 100 )); - assert_ok!(Farming::force_retire_pool( + assert_ok!(Farming::retire_pool( RuntimeOrigin::signed(ALICE), pid )); assert_eq!(Assets::balance(KSM, &ALICE), 5000); // 3000 + 1000 + 1000 Farming::on_initialize(0); assert_err!( - Farming::force_retire_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), Error::::InvalidPoolState ); }); @@ -387,7 +387,7 @@ fn retire() { assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); System::set_block_number(System::block_number() + 1000); - assert_ok!(Farming::force_retire_pool( + assert_ok!(Farming::retire_pool( RuntimeOrigin::signed(ALICE), pid )); @@ -411,7 +411,7 @@ fn reset() { assert_eq!(Assets::balance(KSM, &ALICE), 2918); assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); - assert_ok!(Farming::force_retire_pool( + assert_ok!(Farming::retire_pool( RuntimeOrigin::signed(ALICE), pid )); From 7e1664ac763a40b0e2e567cdc820459eed1ff9c3 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 27 Jun 2023 17:48:22 +0800 Subject: [PATCH 08/26] update version Signed-off-by: zqhxuyuan --- pallets/farming/Cargo.toml | 2 +- pallets/farming/rpc/Cargo.toml | 2 +- pallets/farming/rpc/runtime-api/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 3bb7ea236..8d3bc337e 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.1.0" +version = "4.2.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/rpc/Cargo.toml b/pallets/farming/rpc/Cargo.toml index 205133aea..0cb5a08ab 100644 --- a/pallets/farming/rpc/Cargo.toml +++ b/pallets/farming/rpc/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming-rpc-api" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.1.0" +version = "4.2.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } diff --git a/pallets/farming/rpc/runtime-api/Cargo.toml b/pallets/farming/rpc/runtime-api/Cargo.toml index 39920828e..49219a8a1 100644 --- a/pallets/farming/rpc/runtime-api/Cargo.toml +++ b/pallets/farming/rpc/runtime-api/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://manta.network" license = "GPL-3.0" name = "manta-farming-rpc-runtime-api" repository = 'https://github.com/Manta-Network/Manta/' -version = "4.1.0" +version = "4.2.0" [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } From 4497fddec57b1cbd87fb1281cb9df93d68acc255 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 27 Jun 2023 18:26:33 +0800 Subject: [PATCH 09/26] format Signed-off-by: zqhxuyuan --- Cargo.lock | 6 +-- pallets/farming/src/gauge.rs | 14 ++++++- pallets/farming/src/lib.rs | 67 +++++++++++++++++++--------------- pallets/farming/src/rewards.rs | 11 +++++- pallets/farming/src/tests.rs | 15 ++------ 5 files changed, 64 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54348fd5b..8ac764c79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5471,7 +5471,7 @@ dependencies = [ [[package]] name = "manta-farming" -version = "4.1.0" +version = "4.2.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -5495,7 +5495,7 @@ dependencies = [ [[package]] name = "manta-farming-rpc-api" -version = "4.1.0" +version = "4.2.0" dependencies = [ "jsonrpsee", "manta-farming-rpc-runtime-api", @@ -5511,7 +5511,7 @@ dependencies = [ [[package]] name = "manta-farming-rpc-runtime-api" -version = "4.1.0" +version = "4.2.0" dependencies = [ "manta-primitives", "parity-scale-codec", diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index adef6caf0..0f6d38255 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -317,13 +317,23 @@ where .checked_add(&reward_to_claim) .ok_or(ArithmeticError::Overflow)?; - Self::reward_token_transfer(reward_currency, reward_to_claim, who, &gauge_pool_info.reward_issuer) + Self::reward_token_transfer( + reward_currency, + reward_to_claim, + who, + &gauge_pool_info.reward_issuer, + ) }, )?; gauge_info.last_claim_block = current_block_number; gauge_info.claimed_time_factor = latest_claimed_time_factor; if gauge_info.gauge_stop_block <= current_block_number { - Self::reward_token_transfer(&gauge_pool_info.token, gauge_info.gauge_amount, who, &gauge_pool_info.keeper)?; + Self::reward_token_transfer( + &gauge_pool_info.token, + gauge_info.gauge_amount, + who, + &gauge_pool_info.keeper, + )?; gauge_pool_info.total_time_factor = gauge_pool_info .total_time_factor diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 78a68d125..6db6aa368 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -16,28 +16,25 @@ #![cfg_attr(not(feature = "std"), no_std)] -use frame_support::{ - pallet_prelude::*, - PalletId, -}; +use frame_support::{pallet_prelude::*, PalletId}; use frame_system::pallet_prelude::*; use manta_primitives::types::PoolId; use orml_traits::{arithmetic::CheckedAdd, MultiCurrency}; use sp_core::U256; use sp_runtime::{ - traits::{AccountIdConversion, AtLeast32BitUnsigned, Saturating, Zero, One}, - ArithmeticError, Perbill, SaturatedConversion + traits::{AccountIdConversion, AtLeast32BitUnsigned, One, Saturating, Zero}, + ArithmeticError, Perbill, SaturatedConversion, }; use sp_std::{borrow::ToOwned, collections::btree_map::BTreeMap, vec::Vec}; -#[cfg(test)] -mod mock; -#[cfg(test)] -mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; pub mod gauge; +#[cfg(test)] +mod mock; pub mod rewards; +#[cfg(test)] +mod tests; pub mod weights; pub use gauge::*; pub use pallet::*; @@ -837,26 +834,27 @@ pub mod pallet { } impl Pallet { - fn reward_token_transfer(reward_currency: &CurrencyIdOf, reward_to_withdraw: BalanceOf, who: &T::AccountId, from: &T::AccountId) -> DispatchResult { + fn reward_token_transfer( + reward_currency: &CurrencyIdOf, + reward_to_withdraw: BalanceOf, + who: &T::AccountId, + from: &T::AccountId, + ) -> DispatchResult { let ed = T::MultiCurrency::minimum_balance(*reward_currency); let mut account_to_send = who.clone(); if reward_to_withdraw < ed { let receiver_balance = T::MultiCurrency::total_balance(*reward_currency, who); - let receiver_balance_after = - receiver_balance.checked_add(&reward_to_withdraw).ok_or(ArithmeticError::Overflow)?; + let receiver_balance_after = receiver_balance + .checked_add(&reward_to_withdraw) + .ok_or(ArithmeticError::Overflow)?; if receiver_balance_after < ed { account_to_send = T::TreasuryAccount::get(); } } // pay reward to `who` - T::MultiCurrency::transfer( - *reward_currency, - from, - &account_to_send, - reward_to_withdraw, - ) + T::MultiCurrency::transfer(*reward_currency, from, &account_to_send, reward_to_withdraw) } pub fn get_farming_rewards( @@ -872,7 +870,12 @@ impl Pallet { pool_info.rewards.iter().try_for_each( |(reward_currency, (total_reward, total_withdrawn_reward))| -> DispatchResult { let (_, reward_to_withdraw) = Self::get_reward_amount( - &share_info, total_reward, total_withdrawn_reward, total_shares, reward_currency)?; + &share_info, + total_reward, + total_withdrawn_reward, + total_shares, + reward_currency, + )?; if reward_to_withdraw.is_zero() { return Ok(()); @@ -885,11 +888,12 @@ impl Pallet { Ok(result_vec) } - fn get_reward_amount(share_info: &ShareInfoOf, - total_reward: &BalanceOf, - total_withdrawn_reward: &BalanceOf, - total_shares: BalanceOf, - reward_currency: &CurrencyIdOf + fn get_reward_amount( + share_info: &ShareInfoOf, + total_reward: &BalanceOf, + total_withdrawn_reward: &BalanceOf, + total_shares: BalanceOf, + reward_currency: &CurrencyIdOf, ) -> Result<(BalanceOf, BalanceOf), DispatchError> { let withdrawn_reward = share_info .withdrawn_rewards @@ -897,7 +901,8 @@ impl Pallet { .copied() .unwrap_or_default(); - let total_reward_proportion: BalanceOf = Self::get_reward_inflation(share_info.share, total_reward, total_shares); + let total_reward_proportion: BalanceOf = + Self::get_reward_inflation(share_info.share, total_reward, total_shares); let reward_to_withdraw = total_reward_proportion .saturating_sub(withdrawn_reward) @@ -906,12 +911,14 @@ impl Pallet { Ok((withdrawn_reward, reward_to_withdraw)) } - fn get_reward_inflation(amount: BalanceOf, total_reward: &BalanceOf, total_share: BalanceOf) -> BalanceOf { + fn get_reward_inflation( + amount: BalanceOf, + total_reward: &BalanceOf, + total_share: BalanceOf, + ) -> BalanceOf { let total_reward_proportion: BalanceOf = U256::from(amount.to_owned().saturated_into::()) - .saturating_mul(U256::from( - total_reward.to_owned().saturated_into::(), - )) + .saturating_mul(U256::from(total_reward.to_owned().saturated_into::())) .checked_div(U256::from(total_share.to_owned().saturated_into::())) .unwrap_or_default() .as_u128() diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs index 009085ffa..ee16fe1ea 100644 --- a/pallets/farming/src/rewards.rs +++ b/pallets/farming/src/rewards.rs @@ -260,7 +260,9 @@ impl Pallet { share_info.withdrawn_rewards.iter_mut().try_for_each( |(reward_currency, withdrawn_reward)| -> DispatchResult { let withdrawn_reward_to_remove = Self::get_reward_inflation( - remove_amount,withdrawn_reward,share_info.share + remove_amount, + withdrawn_reward, + share_info.share, ); if withdrawn_reward_to_remove.is_zero() { return Ok(()); @@ -365,7 +367,12 @@ impl Pallet { |(token, &proportion)| -> DispatchResult { let withdraw_amount = proportion * native_amount; - Self::reward_token_transfer(token, withdraw_amount, who, &pool_info.keeper) + Self::reward_token_transfer( + token, + withdraw_amount, + who, + &pool_info.keeper, + ) }, )?; } else { diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index bb250891d..d9a0b0886 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -125,10 +125,7 @@ fn claim() { 100 )); - assert_ok!(Farming::retire_pool( - RuntimeOrigin::signed(ALICE), - pid - )); + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 5000); // 3000 + 1000 + 1000 Farming::on_initialize(0); assert_err!( @@ -387,10 +384,7 @@ fn retire() { assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); System::set_block_number(System::block_number() + 1000); - assert_ok!(Farming::retire_pool( - RuntimeOrigin::signed(ALICE), - pid - )); + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 3000); assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); }) @@ -411,10 +405,7 @@ fn reset() { assert_eq!(Assets::balance(KSM, &ALICE), 2918); assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); - assert_ok!(Farming::retire_pool( - RuntimeOrigin::signed(ALICE), - pid - )); + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); let basic_rewards = vec![(KSM, 1000)]; assert_ok!(Farming::reset_pool( RuntimeOrigin::signed(ALICE), From 2db5d5ab3ed0312c36f04273c88b760a0aa5fe01 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 27 Jun 2023 18:46:59 +0800 Subject: [PATCH 10/26] set non-native asset allow death Signed-off-by: zqhxuyuan --- primitives/manta/src/currencies.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/manta/src/currencies.rs b/primitives/manta/src/currencies.rs index 44a16b812..8af0c8d4c 100644 --- a/primitives/manta/src/currencies.rs +++ b/primitives/manta/src/currencies.rs @@ -127,7 +127,7 @@ where if currency_id == A::NativeAssetId::get() { Native::transfer(from, to, amount, ExistenceRequirement::KeepAlive)?; } else { - NonNative::transfer(currency_id, from, to, amount, true)?; + NonNative::transfer(currency_id, from, to, amount, false)?; } Ok(()) } From fcae9923892516ac50b136ac7e9af39ad92aa70a Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 27 Jun 2023 22:23:05 +0800 Subject: [PATCH 11/26] refactor gauge too Signed-off-by: zqhxuyuan --- pallets/farming/src/gauge.rs | 61 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 0f6d38255..290bfe5d8 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -284,8 +284,8 @@ where latest_claimed_time_factor - gauge_info.claimed_time_factor, gauge_pool_info.total_time_factor, ); - let total_shares = - U256::from(pool_info.total_shares.to_owned().saturated_into::()); + let total_shares = pool_info.total_shares; + let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) .ok_or(Error::::ShareInfoNotExists)?; gauge_pool_info.rewards.iter_mut().try_for_each( @@ -299,17 +299,9 @@ where .ok_or(ArithmeticError::Overflow)?; // gauge_reward = gauge rate * gauge rewards * existing rewards let gauge_reward = gauge_rate * reward; - // reward_to_claim = farming rate * gauge rate * gauge rewards * - // existing rewards in the gauge pool + // reward_to_claim = farming rate * gauge_reward let reward_to_claim: BalanceOf = - U256::from(share_info.share.to_owned().saturated_into::()) - .saturating_mul(U256::from( - gauge_reward.to_owned().saturated_into::(), - )) - .checked_div(total_shares) - .unwrap_or_default() - .as_u128() - .unique_saturated_into(); + Self::get_reward_inflation(share_info.share, &gauge_reward, total_shares); *total_gauged_reward = total_gauged_reward .checked_add(&gauge_reward) .ok_or(ArithmeticError::Overflow)?; @@ -387,8 +379,7 @@ where latest_claimed_time_factor - gauge_info.claimed_time_factor, gauge_pool_info.total_time_factor, ); - let total_shares = - U256::from(pool_info.total_shares.to_owned().saturated_into::()); + let total_shares = pool_info.total_shares; let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) .ok_or(Error::::ShareInfoNotExists)?; gauge_pool_info.rewards.iter().try_for_each( @@ -400,20 +391,11 @@ where let reward = reward_amount .checked_sub(total_gauged_reward) .ok_or(ArithmeticError::Overflow)?; - // gauge_reward = gauge rate * gauge rewards * existing rewards in the - // gauge pool + // gauge_reward = gauge rate * gauge rewards * existing rewards let gauge_reward = gauge_rate * reward; - // reward_to_claim = farming rate * gauge rate * gauge rewards * - // existing rewards in the gauge pool + // reward_to_claim = farming rate * gauge_reward let reward_to_claim: BalanceOf = - U256::from(share_info.share.to_owned().saturated_into::()) - .saturating_mul(U256::from( - gauge_reward.to_owned().saturated_into::(), - )) - .checked_div(total_shares) - .unwrap_or_default() - .as_u128() - .unique_saturated_into(); + Self::get_reward_inflation(share_info.share, &gauge_reward, total_shares); result_vec.push((*reward_currency, reward_to_claim)); Ok(()) }, @@ -422,4 +404,31 @@ where }; Ok(result_vec) } + + fn get_gauge_rate(who: &T::AccountId, gid: PoolId,) -> Result { + let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); + let gauge_pool_info = + GaugePoolInfos::::get(gid).ok_or(Error::::GaugePoolNotExist)?; + let gauge_info = + GaugeInfos::::get(gid, who).ok_or(Error::::GaugeInfoNotExist)?; + let start_block = if current_block_number > gauge_info.gauge_stop_block { + gauge_info.gauge_stop_block + } else { + current_block_number + }; + + let latest_claimed_time_factor = gauge_info.latest_time_factor + + gauge_info + .gauge_amount + .saturated_into::() + .checked_mul( + (start_block - gauge_info.gauge_last_block).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let gauge_rate = Perbill::from_rational( + latest_claimed_time_factor - gauge_info.claimed_time_factor, + gauge_pool_info.total_time_factor, + ); + Ok(gauge_rate) + } } From b162343f3edc62f988c889c3996d32fe5e8fad24 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 27 Jun 2023 23:47:54 +0800 Subject: [PATCH 12/26] refactor gauge rate Signed-off-by: zqhxuyuan --- pallets/farming/src/gauge.rs | 62 ++++++------------------------------ 1 file changed, 10 insertions(+), 52 deletions(-) diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 290bfe5d8..6beba613d 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -17,9 +17,8 @@ use codec::HasCompact; use frame_support::pallet_prelude::*; use scale_info::TypeInfo; -use sp_core::U256; use sp_runtime::{ - traits::{Zero, *}, + traits::{AtLeast32BitUnsigned, CheckedSub, One, Zero}, ArithmeticError, Perbill, RuntimeDebug, SaturatedConversion, }; use sp_std::prelude::*; @@ -177,7 +176,7 @@ where Error::::GaugeMaxBlockOverflow ); - let incease_total_time_factor = if gauge_info.gauge_amount.is_zero() { + let increase_total_time_factor = if gauge_info.gauge_amount.is_zero() { gauge_info.gauge_stop_block = current_block_number; gauge_info.gauge_start_block = current_block_number; gauge_info.last_claim_block = current_block_number; @@ -200,10 +199,10 @@ where (gauge_value + gauge_info.gauge_amount).saturated_into::(), ) .ok_or(ArithmeticError::Overflow)?; - let incease_total_time_factor = time_factor_a + time_factor_b; + let increase_total_time_factor = time_factor_a + time_factor_b; gauge_info.total_time_factor = gauge_info .total_time_factor - .checked_add(incease_total_time_factor) + .checked_add(increase_total_time_factor) .ok_or(ArithmeticError::Overflow)?; // latest_time_factor only increases in not first gauge_deposit let increase_latest_time_factor = gauge_info @@ -218,7 +217,7 @@ where .latest_time_factor .checked_add(increase_latest_time_factor) .ok_or(ArithmeticError::Overflow)?; - incease_total_time_factor + increase_total_time_factor }; gauge_info.gauge_last_block = current_block_number; @@ -233,7 +232,7 @@ where gauge_pool_info.total_time_factor = gauge_pool_info .total_time_factor - .checked_add(incease_total_time_factor) + .checked_add(increase_total_time_factor) .ok_or(ArithmeticError::Overflow)?; T::MultiCurrency::transfer( gauge_pool_info.token, @@ -266,26 +265,8 @@ where gauge_info.gauge_start_block <= current_block_number, Error::::CanNotClaim ); - let start_block = if current_block_number > gauge_info.gauge_stop_block { - gauge_info.gauge_stop_block - } else { - current_block_number - }; - - let latest_claimed_time_factor = gauge_info.latest_time_factor - + gauge_info - .gauge_amount - .saturated_into::() - .checked_mul( - (start_block - gauge_info.gauge_last_block).saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - let gauge_rate = Perbill::from_rational( - latest_claimed_time_factor - gauge_info.claimed_time_factor, - gauge_pool_info.total_time_factor, - ); + let (gauge_rate, latest_claimed_time_factor) = Self::get_gauge_rate(&gauge_pool_info, &gauge_info)?; let total_shares = pool_info.total_shares; - let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) .ok_or(Error::::ShareInfoNotExists)?; gauge_pool_info.rewards.iter_mut().try_for_each( @@ -355,30 +336,11 @@ where match pool_info.gauge { None => (), Some(gid) => { - let current_block_number: BlockNumberFor = - frame_system::Pallet::::block_number(); let gauge_pool_info = GaugePoolInfos::::get(gid).ok_or(Error::::GaugePoolNotExist)?; let gauge_info = GaugeInfos::::get(gid, who).ok_or(Error::::GaugeInfoNotExist)?; - let start_block = if current_block_number > gauge_info.gauge_stop_block { - gauge_info.gauge_stop_block - } else { - current_block_number - }; - - let latest_claimed_time_factor = gauge_info.latest_time_factor - + gauge_info - .gauge_amount - .saturated_into::() - .checked_mul( - (start_block - gauge_info.gauge_last_block).saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - let gauge_rate = Perbill::from_rational( - latest_claimed_time_factor - gauge_info.claimed_time_factor, - gauge_pool_info.total_time_factor, - ); + let (gauge_rate, _) = Self::get_gauge_rate(&gauge_pool_info, &gauge_info)?; let total_shares = pool_info.total_shares; let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) .ok_or(Error::::ShareInfoNotExists)?; @@ -405,12 +367,8 @@ where Ok(result_vec) } - fn get_gauge_rate(who: &T::AccountId, gid: PoolId,) -> Result { + fn get_gauge_rate(gauge_pool_info: &GaugePoolInfoOf, gauge_info: &GaugeInfoOf) -> Result<(Perbill, u128), DispatchError> { let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); - let gauge_pool_info = - GaugePoolInfos::::get(gid).ok_or(Error::::GaugePoolNotExist)?; - let gauge_info = - GaugeInfos::::get(gid, who).ok_or(Error::::GaugeInfoNotExist)?; let start_block = if current_block_number > gauge_info.gauge_stop_block { gauge_info.gauge_stop_block } else { @@ -429,6 +387,6 @@ where latest_claimed_time_factor - gauge_info.claimed_time_factor, gauge_pool_info.total_time_factor, ); - Ok(gauge_rate) + Ok((gauge_rate, latest_claimed_time_factor)) } } From 1b4a9087984be60b6e0c07e3726f9aff987c6bdf Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Wed, 28 Jun 2023 09:43:19 +0800 Subject: [PATCH 13/26] add charge weight and refactor gauge add Signed-off-by: zqhxuyuan --- pallets/farming/src/benchmarking.rs | 32 +++ pallets/farming/src/gauge.rs | 197 ++++++++++-------- pallets/farming/src/lib.rs | 2 +- pallets/farming/src/weights.rs | 21 ++ runtime/calamari/src/weights/manta_farming.rs | 21 ++ 5 files changed, 185 insertions(+), 88 deletions(-) diff --git a/pallets/farming/src/benchmarking.rs b/pallets/farming/src/benchmarking.rs index 57b76d17c..db0360706 100644 --- a/pallets/farming/src/benchmarking.rs +++ b/pallets/farming/src/benchmarking.rs @@ -47,6 +47,38 @@ benchmarks! { 5 ) + charge { + let location = T::Location::default(); + let metadata = >::AssetRegistryMetadata::testing_default(); + AssetManager::::do_register_asset(Some(&location), &metadata)?; + + let ksm_asset_id = CurrencyIdOf::::unique_saturated_from(8u128); + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let tokens_proportion = vec![(ksm_asset_id, Perbill::from_percent(100))]; + let basic_rewards = vec![(ksm_asset_id, token_amount)]; + let gauge_basic_rewards = vec![(ksm_asset_id, token_amount)]; + assert_ok!(Farming::::create_farming_pool( + RawOrigin::Root.into(), + tokens_proportion, + basic_rewards, + Some((ksm_asset_id, BlockNumberFor::::from(1000u32), gauge_basic_rewards)), + BalanceOf::::unique_saturated_from(0u128), + BlockNumberFor::::from(0u32), + BlockNumberFor::::from(7u32), + BlockNumberFor::::from(6u32), + 5, + )); + let charge_rewards = vec![(ksm_asset_id, BalanceOf::::unique_saturated_from(300000u128))]; + + let _ = >::FungibleLedger::deposit_minting( + 8.into(), + &caller, + INITIAL_VALUE.try_into().unwrap(), + ); + // assert_ok!(Farming::::charge(RawOrigin::Signed(caller.clone()).into(), 0, charge_rewards)); + }: _(RawOrigin::Signed(caller.clone()), 0, charge_rewards) + deposit { let location = T::Location::default(); let metadata = >::AssetRegistryMetadata::testing_default(); diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 6beba613d..b5762badd 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -155,91 +155,23 @@ where ) -> DispatchResult { GaugePoolInfos::::mutate(gid, |gauge_pool_info_old| -> DispatchResult { if let Some(mut gauge_pool_info) = gauge_pool_info_old.take() { - let current_block_number = frame_system::Pallet::::block_number(); - gauge_pool_info.gauge_last_block = current_block_number; - gauge_pool_info.gauge_amount = gauge_pool_info - .gauge_amount - .checked_add(&gauge_value) - .ok_or(ArithmeticError::Overflow)?; let mut gauge_info = GaugeInfos::::get(gid, who).unwrap_or_else(|| GaugeInfo::new(who.clone())); - ensure!( - gauge_info.gauge_stop_block >= current_block_number - || gauge_info.gauge_stop_block == Default::default(), - Error::::LastGaugeNotClaim - ); - - ensure!( - gauge_pool_info.max_block - >= gauge_info.gauge_stop_block - gauge_info.gauge_start_block + gauge_block, - Error::::GaugeMaxBlockOverflow - ); - - let increase_total_time_factor = if gauge_info.gauge_amount.is_zero() { - gauge_info.gauge_stop_block = current_block_number; - gauge_info.gauge_start_block = current_block_number; - gauge_info.last_claim_block = current_block_number; - gauge_info.total_time_factor = gauge_block - .saturated_into::() - .checked_mul(gauge_value.saturated_into::()) - .ok_or(ArithmeticError::Overflow)?; - gauge_info.total_time_factor - } else { - let time_factor_a = gauge_value - .saturated_into::() - .checked_mul( - (gauge_info.gauge_stop_block - current_block_number) - .saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - let time_factor_b = gauge_block - .saturated_into::() - .checked_mul( - (gauge_value + gauge_info.gauge_amount).saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - let increase_total_time_factor = time_factor_a + time_factor_b; - gauge_info.total_time_factor = gauge_info - .total_time_factor - .checked_add(increase_total_time_factor) - .ok_or(ArithmeticError::Overflow)?; - // latest_time_factor only increases in not first gauge_deposit - let increase_latest_time_factor = gauge_info - .gauge_amount - .saturated_into::() - .checked_mul( - (current_block_number - gauge_info.gauge_last_block) - .saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - gauge_info.latest_time_factor = gauge_info - .latest_time_factor - .checked_add(increase_latest_time_factor) - .ok_or(ArithmeticError::Overflow)?; - increase_total_time_factor - }; - - gauge_info.gauge_last_block = current_block_number; - gauge_info.gauge_amount = gauge_info - .gauge_amount - .checked_add(&gauge_value) - .ok_or(ArithmeticError::Overflow)?; - gauge_info.gauge_stop_block = gauge_info - .gauge_stop_block - .checked_add(&gauge_block) - .ok_or(ArithmeticError::Overflow)?; + Self::process_gauge_add( + &mut gauge_pool_info, + &mut gauge_info, + gauge_value, + gauge_block, + )?; - gauge_pool_info.total_time_factor = gauge_pool_info - .total_time_factor - .checked_add(increase_total_time_factor) - .ok_or(ArithmeticError::Overflow)?; T::MultiCurrency::transfer( gauge_pool_info.token, who, &gauge_pool_info.keeper, gauge_value, )?; + GaugeInfos::::insert(gid, who, gauge_info); *gauge_pool_info_old = Some(gauge_pool_info); Ok(()) @@ -250,6 +182,89 @@ where Ok(()) } + fn process_gauge_add( + gauge_pool_info: &mut GaugePoolInfoOf, + gauge_info: &mut GaugeInfoOf, + gauge_value: BalanceOf, + gauge_block: BlockNumberFor, + ) -> DispatchResult { + let current_block_number = frame_system::Pallet::::block_number(); + gauge_pool_info.gauge_last_block = current_block_number; + gauge_pool_info.gauge_amount = gauge_pool_info + .gauge_amount + .checked_add(&gauge_value) + .ok_or(ArithmeticError::Overflow)?; + + ensure!( + gauge_info.gauge_stop_block >= current_block_number + || gauge_info.gauge_stop_block == Default::default(), + Error::::LastGaugeNotClaim + ); + + ensure!( + gauge_pool_info.max_block + >= gauge_info.gauge_stop_block - gauge_info.gauge_start_block + gauge_block, + Error::::GaugeMaxBlockOverflow + ); + + let increase_total_time_factor = if gauge_info.gauge_amount.is_zero() { + gauge_info.gauge_stop_block = current_block_number; + gauge_info.gauge_start_block = current_block_number; + gauge_info.last_claim_block = current_block_number; + gauge_info.total_time_factor = gauge_block + .saturated_into::() + .checked_mul(gauge_value.saturated_into::()) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.total_time_factor + } else { + let time_factor_a = gauge_value + .saturated_into::() + .checked_mul( + (gauge_info.gauge_stop_block - current_block_number).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let time_factor_b = gauge_block + .saturated_into::() + .checked_mul((gauge_value + gauge_info.gauge_amount).saturated_into::()) + .ok_or(ArithmeticError::Overflow)?; + let increase_total_time_factor = time_factor_a + time_factor_b; + gauge_info.total_time_factor = gauge_info + .total_time_factor + .checked_add(increase_total_time_factor) + .ok_or(ArithmeticError::Overflow)?; + // latest_time_factor only increases in not first gauge_deposit + let increase_latest_time_factor = gauge_info + .gauge_amount + .saturated_into::() + .checked_mul( + (current_block_number - gauge_info.gauge_last_block).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.latest_time_factor = gauge_info + .latest_time_factor + .checked_add(increase_latest_time_factor) + .ok_or(ArithmeticError::Overflow)?; + increase_total_time_factor + }; + + gauge_info.gauge_last_block = current_block_number; + gauge_info.gauge_amount = gauge_info + .gauge_amount + .checked_add(&gauge_value) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.gauge_stop_block = gauge_info + .gauge_stop_block + .checked_add(&gauge_block) + .ok_or(ArithmeticError::Overflow)?; + + gauge_pool_info.total_time_factor = gauge_pool_info + .total_time_factor + .checked_add(increase_total_time_factor) + .ok_or(ArithmeticError::Overflow)?; + + Ok(()) + } + pub fn gauge_claim_inner(who: &AccountIdOf, gid: PoolId) -> DispatchResult { if !GaugeInfos::::contains_key(gid, who) { return Ok(()); @@ -265,7 +280,8 @@ where gauge_info.gauge_start_block <= current_block_number, Error::::CanNotClaim ); - let (gauge_rate, latest_claimed_time_factor) = Self::get_gauge_rate(&gauge_pool_info, &gauge_info)?; + let (gauge_rate, latest_claimed_time_factor) = + Self::get_gauge_rate(&gauge_pool_info, &gauge_info)?; let total_shares = pool_info.total_shares; let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) .ok_or(Error::::ShareInfoNotExists)?; @@ -281,8 +297,11 @@ where // gauge_reward = gauge rate * gauge rewards * existing rewards let gauge_reward = gauge_rate * reward; // reward_to_claim = farming rate * gauge_reward - let reward_to_claim: BalanceOf = - Self::get_reward_inflation(share_info.share, &gauge_reward, total_shares); + let reward_to_claim: BalanceOf = Self::get_reward_inflation( + share_info.share, + &gauge_reward, + total_shares, + ); *total_gauged_reward = total_gauged_reward .checked_add(&gauge_reward) .ok_or(ArithmeticError::Overflow)?; @@ -356,8 +375,11 @@ where // gauge_reward = gauge rate * gauge rewards * existing rewards let gauge_reward = gauge_rate * reward; // reward_to_claim = farming rate * gauge_reward - let reward_to_claim: BalanceOf = - Self::get_reward_inflation(share_info.share, &gauge_reward, total_shares); + let reward_to_claim: BalanceOf = Self::get_reward_inflation( + share_info.share, + &gauge_reward, + total_shares, + ); result_vec.push((*reward_currency, reward_to_claim)); Ok(()) }, @@ -367,7 +389,10 @@ where Ok(result_vec) } - fn get_gauge_rate(gauge_pool_info: &GaugePoolInfoOf, gauge_info: &GaugeInfoOf) -> Result<(Perbill, u128), DispatchError> { + fn get_gauge_rate( + gauge_pool_info: &GaugePoolInfoOf, + gauge_info: &GaugeInfoOf, + ) -> Result<(Perbill, u128), DispatchError> { let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); let start_block = if current_block_number > gauge_info.gauge_stop_block { gauge_info.gauge_stop_block @@ -377,12 +402,10 @@ where let latest_claimed_time_factor = gauge_info.latest_time_factor + gauge_info - .gauge_amount - .saturated_into::() - .checked_mul( - (start_block - gauge_info.gauge_last_block).saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; + .gauge_amount + .saturated_into::() + .checked_mul((start_block - gauge_info.gauge_last_block).saturated_into::()) + .ok_or(ArithmeticError::Overflow)?; let gauge_rate = Perbill::from_rational( latest_claimed_time_factor - gauge_info.claimed_time_factor, gauge_pool_info.total_time_factor, diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 6db6aa368..8df607c67 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -379,7 +379,7 @@ pub mod pallet { /// After create farming pool, need to deposit reward token into the pool. #[pallet::call_index(1)] - #[pallet::weight(0)] + #[pallet::weight(T::WeightInfo::charge())] pub fn charge( origin: OriginFor, pid: PoolId, diff --git a/pallets/farming/src/weights.rs b/pallets/farming/src/weights.rs index 0766c2535..7dfab7a0c 100644 --- a/pallets/farming/src/weights.rs +++ b/pallets/farming/src/weights.rs @@ -48,6 +48,7 @@ use manta_primitives::constants::RocksDbWeight; pub trait WeightInfo { fn on_initialize() -> Weight; fn create_farming_pool() -> Weight; + fn charge() -> Weight; fn deposit() -> Weight; fn withdraw() -> Weight; fn claim() -> Weight; @@ -78,6 +79,16 @@ impl WeightInfo for SubstrateWeight { // Storage: Assets Asset (r:1 w:1) // Storage: Assets Account (r:2 w:2) // Storage: System Account (r:1 w:1) + fn charge() -> Weight { + // Minimum execution time: 897_000 nanoseconds. + Weight::from_ref_time(902_000_000) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) fn deposit() -> Weight { // Minimum execution time: 64_240 nanoseconds. @@ -137,6 +148,16 @@ impl WeightInfo for () { // Storage: Assets Asset (r:1 w:1) // Storage: Assets Account (r:2 w:2) // Storage: System Account (r:1 w:1) + fn charge() -> Weight { + // Minimum execution time: 897_000 nanoseconds. + Weight::from_ref_time(902_000_000) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(5)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) fn deposit() -> Weight { // Minimum execution time: 64_240 nanoseconds. diff --git a/runtime/calamari/src/weights/manta_farming.rs b/runtime/calamari/src/weights/manta_farming.rs index f41f5e88a..aa02e995d 100644 --- a/runtime/calamari/src/weights/manta_farming.rs +++ b/runtime/calamari/src/weights/manta_farming.rs @@ -46,6 +46,7 @@ use manta_primitives::constants::RocksDbWeight; pub trait WeightInfo { fn on_initialize() -> Weight; fn create_farming_pool() -> Weight; + fn charge() -> Weight; fn deposit() -> Weight; fn withdraw() -> Weight; fn claim() -> Weight; @@ -76,6 +77,16 @@ impl manta_farming::WeightInfo for SubstrateWeight { // Storage: Assets Asset (r:1 w:1) // Storage: Assets Account (r:2 w:2) // Storage: System Account (r:1 w:1) + fn charge() -> Weight { + // Minimum execution time: 897_000 nanoseconds. + Weight::from_ref_time(902_000_000) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) fn deposit() -> Weight { // Minimum execution time: 3_884_000 nanoseconds. @@ -135,6 +146,16 @@ impl WeightInfo for () { // Storage: Assets Asset (r:1 w:1) // Storage: Assets Account (r:2 w:2) // Storage: System Account (r:1 w:1) + fn charge() -> Weight { + // Minimum execution time: 897_000 nanoseconds. + Weight::from_ref_time(902_000_000) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(5)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) fn deposit() -> Weight { // Minimum execution time: 3_884_000 nanoseconds. From 25ca1e518cf4038aa7ee50ab11ab0a859a2d71f1 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Wed, 28 Jun 2023 10:58:43 +0800 Subject: [PATCH 14/26] rpc async Signed-off-by: zqhxuyuan --- pallets/farming/rpc/src/lib.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/pallets/farming/rpc/src/lib.rs b/pallets/farming/rpc/src/lib.rs index 91931c737..5aadff978 100644 --- a/pallets/farming/rpc/src/lib.rs +++ b/pallets/farming/rpc/src/lib.rs @@ -30,10 +30,14 @@ use sp_rpc::number::NumberOrHex; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; #[rpc(client, server)] -pub trait FarmingRpcApi { +pub trait FarmingRpcApi +where + AccountId: Send + Sync + 'static, + PoolId: Send + Sync + 'static, +{ /// rpc method for getting farming rewards #[method(name = "farming_getFarmingRewards")] - fn get_farming_rewards( + async fn get_farming_rewards( &self, who: AccountId, pid: PoolId, @@ -42,7 +46,7 @@ pub trait FarmingRpcApi { /// rpc method for getting gauge rewards #[method(name = "farming_getGaugeRewards")] - fn get_gauge_rewards( + async fn get_gauge_rewards( &self, who: AccountId, pid: PoolId, @@ -73,21 +77,20 @@ where Block: BlockT, C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, C::Api: FarmingRuntimeApi, - AccountId: Codec, + AccountId: Codec + Send + Sync + 'static, CurrencyId: Codec, - PoolId: Codec, + PoolId: Codec + Send + Sync + 'static, { - fn get_farming_rewards( + async fn get_farming_rewards( &self, who: AccountId, pid: PoolId, at: Option<::Hash>, ) -> RpcResult> { - let lm_rpc_api = self.client.runtime_api(); + let api = self.client.runtime_api(); let at = BlockId::::hash(at.unwrap_or_else(|| self.client.info().best_hash)); - let rs: Result, _> = - lm_rpc_api.get_farming_rewards(&at, who, pid); + let rs: Result, _> = api.get_farming_rewards(&at, who, pid); match rs { Ok(rewards) => Ok(rewards @@ -103,16 +106,16 @@ where .map_err(jsonrpsee::core::Error::Call) } - fn get_gauge_rewards( + async fn get_gauge_rewards( &self, who: AccountId, pid: PoolId, at: Option<::Hash>, ) -> RpcResult> { - let lm_rpc_api = self.client.runtime_api(); + let api = self.client.runtime_api(); let at = BlockId::::hash(at.unwrap_or_else(|| self.client.info().best_hash)); - let rs: Result, _> = lm_rpc_api.get_gauge_rewards(&at, who, pid); + let rs: Result, _> = api.get_gauge_rewards(&at, who, pid); match rs { Ok(rewards) => Ok(rewards From 16c023074ec28bfe1984951023f9cfaa8b577567 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Wed, 28 Jun 2023 18:47:14 +0800 Subject: [PATCH 15/26] update tests Signed-off-by: zqhxuyuan --- pallets/farming/src/gauge.rs | 4 +- pallets/farming/src/lib.rs | 3 +- pallets/farming/src/mock.rs | 3 +- pallets/farming/src/rewards.rs | 4 +- pallets/farming/src/tests.rs | 941 +++++++++++++++++++++++++++------ 5 files changed, 788 insertions(+), 167 deletions(-) diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index b5762badd..36f979890 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -309,7 +309,7 @@ where .checked_add(&reward_to_claim) .ok_or(ArithmeticError::Overflow)?; - Self::reward_token_transfer( + Self::farming_token_transfer( reward_currency, reward_to_claim, who, @@ -320,7 +320,7 @@ where gauge_info.last_claim_block = current_block_number; gauge_info.claimed_time_factor = latest_claimed_time_factor; if gauge_info.gauge_stop_block <= current_block_number { - Self::reward_token_transfer( + Self::farming_token_transfer( &gauge_pool_info.token, gauge_info.gauge_amount, who, diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 8df607c67..9bf546da9 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -535,6 +535,7 @@ pub mod pallet { } /// User can withdraw but not claim rewards from farming pool. + /// This operation will transfer back user staked token from keeper account. #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::claim())] pub fn withdraw_claim(origin: OriginFor, pid: PoolId) -> DispatchResult { @@ -834,7 +835,7 @@ pub mod pallet { } impl Pallet { - fn reward_token_transfer( + fn farming_token_transfer( reward_currency: &CurrencyIdOf, reward_to_withdraw: BalanceOf, who: &T::AccountId, diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index 847ccae97..471041ee4 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -26,7 +26,6 @@ use frame_support::{ PalletId, }; use frame_system::{EnsureNever, EnsureRoot, EnsureSignedBy}; -// use manta_primitives::{CurrencyId, TokenSymbol}; use manta_primitives::{ assets::{ AssetConfig, AssetIdType, AssetLocation, AssetRegistry, AssetRegistryMetadata, @@ -226,7 +225,7 @@ parameter_types! { pub NativeAssetMetadata: AssetRegistryMetadata = AssetRegistryMetadata { metadata: AssetStorageMetadata { name: b"Calamari".to_vec(), - symbol: b"KAR".to_vec(), + symbol: b"KMA".to_vec(), decimals: 12, is_frozen: false, }, diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs index ee16fe1ea..0a35256ce 100644 --- a/pallets/farming/src/rewards.rs +++ b/pallets/farming/src/rewards.rs @@ -330,7 +330,7 @@ impl Pallet { withdrawn_reward.saturating_add(reward_to_withdraw), ); - Self::reward_token_transfer(reward_currency, reward_to_withdraw, who, &pool_info.reward_issuer) + Self::farming_token_transfer(reward_currency, reward_to_withdraw, who, &pool_info.reward_issuer) }, )?; Ok(()) @@ -367,7 +367,7 @@ impl Pallet { |(token, &proportion)| -> DispatchResult { let withdraw_amount = proportion * native_amount; - Self::reward_token_transfer( + Self::farming_token_transfer( token, withdraw_amount, who, diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index d9a0b0886..7971a3e81 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -16,7 +16,7 @@ #![cfg(test)] -use frame_support::{assert_err, assert_ok}; +use frame_support::{assert_err, assert_noop, assert_ok}; use sp_runtime::traits::AccountIdConversion; use crate::{mock::*, *}; @@ -32,11 +32,11 @@ fn init_gauge_900() -> (PoolId, BalanceOf) { tokens_proportion, basic_rewards, Some((KSM, 1000, gauge_basic_rewards)), - 0, - 0, - 0, - 0, - 5 + 0, // min_deposit_to_start + 0, // after_block_to_start + 0, // withdraw_limit_time + 0, // claim_limit_time + 5 // withdraw_limit_count )); let pid = 0; @@ -66,11 +66,11 @@ fn init_gauge_1000() -> (PoolId, BalanceOf) { tokens_proportion, basic_rewards, Some(gauge_basic_rewards), - 0, - 0, - 10, - 0, - 1 + 0, // min_deposit_to_start + 0, // after_block_to_start + 10, // withdraw_limit_time + 0, // claim_limit_time + 1 // withdraw_limit_count )); let pid = 0; @@ -87,56 +87,597 @@ fn init_gauge_1000() -> (PoolId, BalanceOf) { tokens, None )); + + let share_info = Farming::shares_and_withdrawn_rewards(pid, &ALICE).unwrap(); + assert_eq!(share_info.share, tokens); (pid, tokens) } #[test] -fn claim() { - let keeper_account = FarmingKeeperPalletId::get().into_account_truncating(); +fn precondition_check_should_work() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid0, tokens) = init_gauge_1000(); + let pid = 1; + let charge_rewards = vec![(KSM, 300000)]; + + assert_noop!( + Farming::charge(RuntimeOrigin::signed(BOB), pid, charge_rewards), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 100))), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, Some(200)), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::close_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::reset_pool( + RuntimeOrigin::signed(ALICE), + pid, + None, + None, + None, + None, + None, + None, + None + ), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::PoolDoesNotExist + ); + assert_noop!( + Farming::gauge_withdraw(RuntimeOrigin::signed(ALICE), pid), + Error::::GaugePoolNotExist + ); + assert_noop!( + Farming::edit_pool( + RuntimeOrigin::signed(ALICE), + pid, + None, + None, + None, + None, + None + ), + Error::::PoolDoesNotExist + ); + + // Pool state is Charged + let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + assert_eq!(pool1.state, PoolState::Charged); + // Charge again + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid0, + vec![(KSM, 1000)] + )); + let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + assert_eq!(pool1.state, PoolState::Charged); + + assert_noop!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid0), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::close_pool(RuntimeOrigin::signed(ALICE), pid0), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid0), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::reset_pool( + RuntimeOrigin::signed(ALICE), + pid0, + None, + None, + None, + None, + None, + None, + None, + ), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid0), + Error::::InvalidPoolState + ); + + // Pool state is Ongoing + Farming::on_initialize(System::block_number() + 10); + let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + assert_eq!(pool1.state, PoolState::Ongoing); + + assert_noop!( + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid0), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::reset_pool( + RuntimeOrigin::signed(ALICE), + pid0, + None, + None, + None, + None, + None, + None, + None, + ), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid0), + Error::::InvalidPoolState + ); + + // Charge again, change back state from Ongoing to Charged. + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid0, + vec![(KSM, 1000)] + )); + let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + assert_eq!(pool1.state, PoolState::Charged); + }) +} +#[test] +fn no_gauge_farming_pool_should_work() { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, _tokens) = init_gauge_1000(); - // assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), ShareInfo::default()); - assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); + // Stake KSM, get KSM reward + let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; + let deposit_amount = 1000; + let reward_amount: Balance = 1000; + let basic_rewards = vec![(KSM, 1000)]; + let total_rewards = 300000; + let alice_init_balance = 3000; + assert_eq!(Assets::balance(KSM, &ALICE), alice_init_balance); + + let withdraw_limit_time = 7; + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion.clone(), + basic_rewards.clone(), + None, + 2, // min_deposit_to_start + 1, // after_block_to_start + withdraw_limit_time, + 6, // claim_limit_time + 5 // withdraw_limit_count + )); + assert_eq!(PoolNextId::::get(), 1); + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + None, + 2, // min_deposit_to_start + 1, // after_block_to_start + withdraw_limit_time, + 6, // claim_limit_time + 5 // withdraw_limit_count + )); + assert_eq!(PoolNextId::::get(), 2); + + // Query pool initial state, kill first pool with pool id = 0 + assert_eq!(Farming::pool_infos(0).unwrap().state, PoolState::UnCharged); + assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), 0)); + assert_eq!(Farming::pool_infos(0), None); + + // Charge to the pool reward issuer + let pid = 1; + let charge_rewards = vec![(KSM, total_rewards)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 0); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Charged); + assert!(pool1.rewards.is_empty()); + + // Deposit failed because block number is not large then pool_info.after_block_to_start + assert!(System::block_number() < pool1.after_block_to_start); + assert_noop!( + Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + deposit_amount, + Some((100, 100)) + ), + Error::::CanNotDeposit + ); + + System::set_block_number(System::block_number() + 3); + // Deposit failed because Gauge pool is not exist + assert_noop!( + Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + deposit_amount, + Some((100, 100)) + ), + Error::::GaugePoolNotExist + ); + // Deposit success + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + deposit_amount, + None + )); + + // User staked token transfer to keeper account + assert_eq!( + Assets::balance(KSM, &ALICE), + alice_init_balance - deposit_amount + ); + assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); + + // reward info + let mut reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.share, deposit_amount); + assert!(reward.withdrawn_rewards.is_empty()); + assert!(reward.withdraw_list.is_empty()); + assert_eq!(reward.claim_last_block, 3); + + // The pool state is still on Charged until new block + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, deposit_amount); + assert_eq!(pool1.state, PoolState::Charged); + assert!(pool1.rewards.is_empty()); + + // Claim failed because of pool state is still Charged assert_err!( Farming::claim(RuntimeOrigin::signed(ALICE), pid), Error::::InvalidPoolState ); - System::set_block_number(System::block_number() + 100); - Farming::on_initialize(0); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 2000); + + // OnInitialize hook change the pool state + Farming::on_initialize(System::block_number() + 3); Farming::on_initialize(0); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 2000); + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, deposit_amount); + assert_eq!(pool1.state, PoolState::Ongoing); + assert_eq!(pool1.claim_limit_time, 6); + assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 0)); + + // new block didn't change the reward info + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.share, deposit_amount); + assert!(reward.withdrawn_rewards.is_empty()); + assert!(reward.withdraw_list.is_empty()); + assert_eq!(reward.claim_last_block, 3); + + // Claim failed because of share info not exist + assert_err!( + Farming::claim(RuntimeOrigin::signed(BOB), pid), + Error::::ShareInfoNotExists + ); + // Claim failed because of block not reached, at least 3+6=9 + assert!(System::block_number() < reward.claim_last_block + pool1.claim_limit_time); + assert_err!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::CanNotClaim + ); + + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, deposit_amount); + + // Claim success, user get reward. + System::set_block_number(System::block_number() + 6); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 3000); - Farming::on_initialize(0); - assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!( + Assets::balance(KSM, &pool1.reward_issuer), + total_rewards - 1000 + ); - // Fund token to keeper_account - assert_ok!(Assets::mint( + // Claim operation update pool info's rewards and also share info's withdrawn_rewards + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 1000)); + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &reward_amount); + // The withdraw list of user share info is still empty. + assert!(reward.withdraw_list.is_empty()); + + // Claim without new block. + for i in 0..5 { + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &reward_amount); + assert_eq!(reward.claim_last_block, 109 + i * 100); + assert_eq!(reward.share, 1000); + assert!(reward.withdraw_list.is_empty()); + + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 1000)); + assert_eq!(pool1.total_shares, 1000); + + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_eq!( + Assets::balance(KSM, &pool1.reward_issuer), + total_rewards - 1000 + ); + assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); + } + assert_eq!(Assets::balance(KSM, &pool1.reward_issuer), 299000); + assert_eq!(Assets::balance(KSM, &pool1.keeper), 1000); + // Claim with new block + for i in 1..5 { + System::set_block_number(System::block_number() + 6); + Farming::on_initialize(System::block_number() + 3); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!( + reward.withdrawn_rewards.get(&KSM).unwrap(), + &(1000 * (i + 1)) + ); + assert_eq!(reward.claim_last_block as u128, 509 + i * 6); + assert_eq!(reward.share, 1000); + assert!(reward.withdraw_list.is_empty()); + + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!( + pool1.rewards.get(&KSM).unwrap(), + &(1000 * (i + 1), 1000 * (i + 1)) + ); + assert_eq!(pool1.total_shares, 1000); + + assert_eq!(Assets::balance(KSM, &ALICE), 3000 + 1000 * i); + assert_eq!( + Assets::balance(KSM, &pool1.reward_issuer), + total_rewards - 1000 * (i + 1) + ); + // Because withdraw_list of user share is empty, keeper not return token to user. + assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); + } + assert_eq!(Assets::balance(KSM, &pool1.reward_issuer), 295000); + assert_eq!(Assets::balance(KSM, &pool1.keeper), 1000); + assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(5000, 5000)); + + // Withdraw failed because of share info not exist. + assert_err!( + Farming::withdraw(RuntimeOrigin::signed(BOB), pid, Some(800)), + Error::::ShareInfoNotExists + ); + + // Claim again without new blocks, no new rewards + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pid).unwrap(); + assert!(reward.withdraw_list.is_empty()); + + let share_reward = reward.withdrawn_rewards.get(&KSM).unwrap(); + assert_eq!(share_reward, &(5000)); + let (total_reward, total_withdrawn_reward) = pool1.rewards.get(&KSM).unwrap(); + assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(5000, 5000)); + + let reward_amount = Farming::get_reward_amount( + &reward, + total_reward, + total_withdrawn_reward, + pool1.total_shares, + &KSM, + ) + .unwrap(); + assert_eq!(reward_amount, (5000, 0)); + let reward_inflation = + Farming::get_reward_inflation(reward.share, total_reward, pool1.total_shares); + assert_eq!(reward_inflation, 5000); + + let reward_inflation = Farming::get_reward_inflation(800, share_reward, reward.share); + assert_eq!(reward_inflation, 4000); + let reward_inflation = Farming::get_reward_inflation(200, share_reward, reward.share); + assert_eq!(reward_inflation, 1000); + let reward_inflation = Farming::get_reward_inflation(100, share_reward, reward.share); + assert_eq!(reward_inflation, 500); + + // Withdraw partial tokens + assert_eq!(System::block_number(), 533); + assert_eq!(Assets::balance(KSM, &ALICE), 7000); + assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - KSM, - keeper_account, - 100 + pid, + Some(800) )); - assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 5000); // 3000 + 1000 + 1000 + // Although withdraw also has claim, but no new rewards due to no new block + // So both user and reward issuer account balance not change. + assert_eq!(Assets::balance(KSM, &ALICE), 7000); + assert_eq!(Assets::balance(KSM, &pool1.reward_issuer), 295000); + assert_eq!(Assets::balance(KSM, &pool1.keeper), 1000); + + // Withdraw operation has only one operation `remove_share`. + // And `remove_share` will claim rewards and also update user share info. + // We already know that due to no new block, claim rewards actually has no reward. + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pid).unwrap(); + + assert_eq!(pool1.total_shares, 200); + assert_eq!(reward.withdraw_list, vec![(533 + withdraw_limit_time, 800)]); + assert_eq!(reward.share, 200); + assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &1000); + assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 1000)); + + System::set_block_number(System::block_number() + 6); + Farming::on_initialize(System::block_number() + 3); + + // Withdraw rest all of share + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(300) + )); + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 0); + assert!(pool1.rewards.is_empty()); + assert_eq!(reward.share, 0); + assert_eq!(reward.withdraw_list, vec![(540, 800), (546, 200)]); + assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &0); + }) +} + +#[test] +fn gauge_farming_pool_should_work() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + // Stake KSM, get KSM reward + let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; + let deposit_amount = 1000; + let basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = vec![(KSM, 900)]; + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion.clone(), + basic_rewards.clone(), + Some((KSM, 1000, gauge_basic_rewards.clone())), + 2, + 1, + 7, + 6, + 5 + )); + assert_eq!(PoolNextId::::get(), 1); + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + Some((KSM, 1000, gauge_basic_rewards)), + 2, + 1, + 7, + 6, + 5 + )); + assert_eq!(PoolNextId::::get(), 2); + + // Query pool initial state, kill the pool + assert_eq!(Farming::pool_infos(0).unwrap().state, PoolState::UnCharged); + assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), 0)); + assert_eq!(Farming::pool_infos(0), None); + + // Charge to the pool + let pid = 1; + let charge_rewards = vec![(KSM, 300000)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 0); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Charged); + + // Deposit to the pool + assert_err!( + Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + deposit_amount, + Some((100, 100)) + ), + Error::::CanNotDeposit + ); + System::set_block_number(System::block_number() + 3); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + deposit_amount, + Some((100, 100)) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 1900); + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 1000); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Charged); + + // OnInitialize hook change the pool state + Farming::on_initialize(System::block_number() + 3); Farming::on_initialize(0); + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 1000); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Ongoing); + + // Claim to get rewards assert_err!( - Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), - Error::::InvalidPoolState + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::CanNotClaim ); - }); + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3008); + + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 4698); + + // Withdraw part tokens + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(800) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 4698); + + // Claim again + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_err!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::CanNotClaim + ); + assert_eq!(Assets::balance(KSM, &ALICE), 4698); + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 5498); + }) } #[test] -fn deposit_gause_should_work() { +fn deposit_gauge_should_work() { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() @@ -224,22 +765,49 @@ fn withdraw() { .build() .execute_with(|| { let (pid, tokens) = init_gauge_1000(); - assert_eq!(Assets::balance(KSM, &ALICE), 2000); + let pool = PoolInfos::::get(pid).unwrap(); + let reward_issuer = pool.reward_issuer; + let token_keeper = pool.keeper; + + assert_eq!(Assets::balance(KSM, &ALICE), 2_000); + assert_eq!(Assets::balance(KSM, &reward_issuer), 100_000); + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + Farming::on_initialize(0); Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); + + let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert!(reward.withdraw_list.is_empty()); + assert_eq!(pool.withdraw_limit_count, 1); + + // withdraw assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), pid, Some(800) )); + + // withdraw contains claim reward operation + // reward issuer transfer 1000 reward token to user + assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); + assert_eq!(Assets::balance(KSM, &ALICE), 3_000); + + let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.withdraw_list.len(), 1); + // user share info withdraw list size is not less than pool info `withdraw_limit_count` assert_err!( Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, Some(100)), Error::::WithdrawLimitCountExceeded ); - assert_eq!(Assets::balance(KSM, &ALICE), 3000); + + // Alice claim reward manually, but due to no new block, so no reward assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_eq!(Assets::balance(KSM, &ALICE), 3_000); + assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + + // Bob deposit System::set_block_number(System::block_number() + 100); assert_ok!(Farming::deposit( RuntimeOrigin::signed(BOB), @@ -247,25 +815,92 @@ fn withdraw() { tokens, None )); + // deposit operation transfer user staked token to pool keeper account + assert_eq!(Assets::balance(KSM, &token_keeper), 2_000); + + // Alice claim again, because new block produces, so has reward now Farming::on_initialize(0); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 3966); + assert_eq!(Assets::balance(KSM, &ALICE), 3_966); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + + // withdraw assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), pid, Some(200) )); + assert_eq!(Assets::balance(KSM, &ALICE), 3_966); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + assert_eq!(Assets::balance(KSM, &token_keeper), 1_200); + + // `withdraw_claim` operation will transfer back user stake token + // User unStake 200 KSM, so keeper transfer back 200 KSM to user. System::set_block_number(System::block_number() + 100); assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 4166); + assert_eq!(Assets::balance(KSM, &ALICE), 4_166); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + + // claim + let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert!(reward.withdraw_list.is_empty()); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 4_166); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + + // `process_withdraw_list` remove the share info. + // due to withdraw_list of share info is empty, so there's no token transfer. assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); - assert_eq!(Assets::balance(KSM, &ALICE), 4166); - // let ed = ::MultiCurrency::minimum_balance(KSM); - // assert_eq!(Assets::balance(KSM, &TREASURY_ACCOUNT), ed); + assert_eq!(Assets::balance(KSM, &TREASURY_ACCOUNT), 0); }) } +#[test] +fn claim() { + let keeper_account = FarmingKeeperPalletId::get().into_account_truncating(); + + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let (pid, _tokens) = init_gauge_1000(); + assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); + assert_err!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + System::set_block_number(System::block_number() + 100); + Farming::on_initialize(0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 2000); + Farming::on_initialize(0); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 2000); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + Farming::on_initialize(0); + assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + + // Fund token to keeper_account + assert_ok!(Assets::mint( + RuntimeOrigin::signed(ALICE), + KSM, + keeper_account, + 100 + )); + + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 5000); // 3000 + 1000 + 1000 + Farming::on_initialize(0); + assert_err!( + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + }); +} + #[test] fn gauge() { ExtBuilder::default() @@ -348,7 +983,7 @@ fn gauge_withdraw() { } #[test] -fn retire() { +fn pool_admin_operation_should_work() { let keeper_account = FarmingKeeperPalletId::get().into_account_truncating(); ExtBuilder::default() @@ -372,7 +1007,37 @@ fn retire() { Some((100, 100)) )); assert_eq!(Assets::balance(KSM, &ALICE), 800); + + // Not allow retire or reset, kill pool if pool is not Dead + assert_noop!( + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::reset_pool( + RuntimeOrigin::signed(ALICE), + pid, + None, + None, + None, + None, + None, + None, + None + ), + Error::::InvalidPoolState + ); + + // Close the pool + let pool: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool.state, PoolState::Ongoing); assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + let pool: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool.state, PoolState::Dead); // Fund token to keeper_account assert_ok!(Assets::mint( @@ -384,9 +1049,81 @@ fn retire() { assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); System::set_block_number(System::block_number() + 1000); + + // Pool is dead, not allow to close again, deposit, reset, kill or edit. + assert_noop!( + Farming::close_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::reset_pool( + RuntimeOrigin::signed(ALICE), + pid, + None, + None, + None, + None, + None, + None, + None + ), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::edit_pool( + RuntimeOrigin::signed(ALICE), + pid, + None, + None, + None, + None, + None + ), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::deposit(RuntimeOrigin::signed(ALICE), pid, 0, Some((100, 100))), + Error::::InvalidPoolState + ); + + // Retire pool assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); + let pool: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool.state, PoolState::Retired); + + // claim all rewards automatically to user assert_eq!(Assets::balance(KSM, &ALICE), 3000); assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); + + // Pool is retired, not allow to retire again, deposit, withdraw, claim, close + assert_noop!( + Farming::close_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::deposit(RuntimeOrigin::signed(ALICE), pid, 0, Some((100, 100))), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, None), + Error::::InvalidPoolState + ); + assert_noop!( + Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Error::::InvalidPoolState + ); + + // Kill the pool + assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Farming::pool_infos(pid), None); }) } @@ -484,119 +1221,3 @@ fn reset() { assert_eq!(Assets::balance(KSM, &ALICE), 4017); }) } - -#[test] -fn gauge_farming_pool_should_work() { - ExtBuilder::default() - .one_hundred_for_alice_n_bob() - .build() - .execute_with(|| { - let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; - let tokens = 1000; - let basic_rewards = vec![(KSM, 1000)]; - let gauge_basic_rewards = vec![(KSM, 900)]; - - assert_ok!(Farming::create_farming_pool( - RuntimeOrigin::signed(ALICE), - tokens_proportion.clone(), - basic_rewards.clone(), - Some((KSM, 1000, gauge_basic_rewards.clone())), - 2, - 1, - 7, - 6, - 5 - )); - assert_eq!(PoolNextId::::get(), 1); - assert_ok!(Farming::create_farming_pool( - RuntimeOrigin::signed(ALICE), - tokens_proportion, - basic_rewards, - Some((KSM, 1000, gauge_basic_rewards)), - 2, - 1, - 7, - 6, - 5 - )); - assert_eq!(PoolNextId::::get(), 2); - - // Query pool initial state, kill the pool - assert_eq!(Farming::pool_infos(0).unwrap().state, PoolState::UnCharged); - assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), 0)); - assert_eq!(Farming::pool_infos(0), None); - - // Charge to the pool - let pid = 1; - let charge_rewards = vec![(KSM, 300000)]; - assert_ok!(Farming::charge( - RuntimeOrigin::signed(BOB), - pid, - charge_rewards - )); - let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); - assert_eq!(pool1.total_shares, 0); - assert_eq!(pool1.min_deposit_to_start, 2); - assert_eq!(pool1.state, PoolState::Charged); - - // Deposit to the pool - assert_err!( - Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 100))), - Error::::CanNotDeposit - ); - System::set_block_number(System::block_number() + 3); - assert_eq!(Assets::balance(KSM, &ALICE), 3000); - assert_ok!(Farming::deposit( - RuntimeOrigin::signed(ALICE), - pid, - tokens, - Some((100, 100)) - )); - assert_eq!(Assets::balance(KSM, &ALICE), 1900); - pool1 = Farming::pool_infos(pid).unwrap(); - assert_eq!(pool1.total_shares, 1000); - assert_eq!(pool1.min_deposit_to_start, 2); - assert_eq!(pool1.state, PoolState::Charged); - - // OnInitialize hook change the pool state - Farming::on_initialize(System::block_number() + 3); - Farming::on_initialize(0); - pool1 = Farming::pool_infos(pid).unwrap(); - assert_eq!(pool1.total_shares, 1000); - assert_eq!(pool1.min_deposit_to_start, 2); - assert_eq!(pool1.state, PoolState::Ongoing); - - // Claim to get rewards - assert_err!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), - Error::::CanNotClaim - ); - System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 3008); - - System::set_block_number(System::block_number() + 100); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 4698); - - // Withdraw part tokens - assert_ok!(Farming::withdraw( - RuntimeOrigin::signed(ALICE), - pid, - Some(800) - )); - assert_eq!(Assets::balance(KSM, &ALICE), 4698); - - // Claim again - System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_err!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), - Error::::CanNotClaim - ); - assert_eq!(Assets::balance(KSM, &ALICE), 4698); - System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 5498); - }) -} From 04ef987420ab6ce1639a7d2144f673a89563d291 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Fri, 9 Jun 2023 20:12:56 +0800 Subject: [PATCH 16/26] manta farming Signed-off-by: zqhxuyuan --- Cargo.lock | 4 + .../manta/local_testnets_geneses.rs | 66 +-- node/src/chain_specs/manta/mod.rs | 4 +- node/src/command.rs | 3 +- node/src/rpc/manta.rs | 19 +- runtime/manta/Cargo.toml | 13 + runtime/manta/src/lib.rs | 109 ++++- runtime/manta/src/weights/manta_farming.rs | 172 ++++++++ runtime/manta/src/weights/mod.rs | 2 + runtime/manta/src/weights/zenlink_protocol.rs | 383 ++++++++++++++++++ runtime/manta/src/zenlink.rs | 244 +++++++++++ 11 files changed, 986 insertions(+), 33 deletions(-) create mode 100644 runtime/manta/src/weights/manta_farming.rs create mode 100644 runtime/manta/src/weights/zenlink_protocol.rs create mode 100644 runtime/manta/src/zenlink.rs diff --git a/Cargo.lock b/Cargo.lock index 8ac764c79..1bfe75dfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5594,6 +5594,8 @@ dependencies = [ "hex-literal", "log", "manta-collator-selection", + "manta-farming", + "manta-farming-rpc-runtime-api", "manta-primitives", "nimbus-primitives", "orml-traits", @@ -5655,6 +5657,8 @@ dependencies = [ "xcm-builder", "xcm-executor", "xcm-simulator", + "zenlink-protocol", + "zenlink-protocol-runtime-api", ] [[package]] diff --git a/node/src/chain_specs/manta/local_testnets_geneses.rs b/node/src/chain_specs/manta/local_testnets_geneses.rs index eb069e6da..bd8629fe7 100644 --- a/node/src/chain_specs/manta/local_testnets_geneses.rs +++ b/node/src/chain_specs/manta/local_testnets_geneses.rs @@ -47,39 +47,51 @@ pub fn genesis_spec_dev() -> MantaChainSpec { ) } -pub fn genesis_spec_local() -> MantaChainSpec { - let genesis_collators: Vec = vec![ - Collator::new( +pub fn genesis_spec_local(localdev: bool) -> MantaChainSpec { + let genesis_collators: Vec = if localdev { + vec![Collator::new( unchecked_account_id::("Alice"), None, SessionKeys::from_seed_unchecked("Alice"), - ), - Collator::new( - unchecked_account_id::("Bob"), - None, - SessionKeys::from_seed_unchecked("Bob"), - ), - Collator::new( - unchecked_account_id::("Charlie"), - None, - SessionKeys::from_seed_unchecked("Charlie"), - ), - Collator::new( - unchecked_account_id::("Dave"), - None, - SessionKeys::from_seed_unchecked("Dave"), - ), - Collator::new( - unchecked_account_id::("Eve"), - None, - SessionKeys::from_seed_unchecked("Eve"), - ), - ]; + )] + } else { + vec![ + Collator::new( + unchecked_account_id::("Alice"), + None, + SessionKeys::from_seed_unchecked("Alice"), + ), + Collator::new( + unchecked_account_id::("Bob"), + None, + SessionKeys::from_seed_unchecked("Bob"), + ), + Collator::new( + unchecked_account_id::("Charlie"), + None, + SessionKeys::from_seed_unchecked("Charlie"), + ), + Collator::new( + unchecked_account_id::("Dave"), + None, + SessionKeys::from_seed_unchecked("Dave"), + ), + Collator::new( + unchecked_account_id::("Eve"), + None, + SessionKeys::from_seed_unchecked("Eve"), + ), + ] + }; let genesis_collators_clone = genesis_collators.clone(); // so we can move it into the constructor closure - + let id = if localdev { + "manta_localdev" + } else { + "manta_local" + }; MantaChainSpec::from_genesis( "Manta Parachain Local", - "manta", + id, ChainType::Local, move || manta_devnet_genesis(genesis_collators_clone.clone()), genesis_collators diff --git a/node/src/chain_specs/manta/mod.rs b/node/src/chain_specs/manta/mod.rs index fa281b2c0..d3596ad63 100644 --- a/node/src/chain_specs/manta/mod.rs +++ b/node/src/chain_specs/manta/mod.rs @@ -80,8 +80,8 @@ pub fn manta_testnet_config() -> MantaChainSpec { public_testnet_genesis::genesis_spec() } /// Returns the Manta development chainspec. -pub fn manta_local_config() -> MantaChainSpec { - local_testnets_geneses::genesis_spec_local() +pub fn manta_local_config(localdev: bool) -> MantaChainSpec { + local_testnets_geneses::genesis_spec_local(localdev) } /// Returns the Manta development chainspec. pub fn manta_development_config() -> MantaChainSpec { diff --git a/node/src/command.rs b/node/src/command.rs index 29fe302c9..a5bf072a4 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -101,7 +101,8 @@ fn load_spec(id: &str) -> Result, String> { match id { // manta chainspec "manta-dev" => Ok(Box::new(chain_specs::manta_development_config())), - "manta-local" => Ok(Box::new(chain_specs::manta_local_config())), + "manta-local" => Ok(Box::new(chain_specs::manta_local_config(false))), + "manta-localdev" => Ok(Box::new(chain_specs::manta_local_config(true))), "manta-testnet" => Ok(Box::new(chain_specs::manta_testnet_config())), "manta" => Ok(Box::new(chain_specs::manta_mainnet_config()?)), // calamari chainspec diff --git a/node/src/rpc/manta.rs b/node/src/rpc/manta.rs index 489ce75ce..455fea364 100644 --- a/node/src/rpc/manta.rs +++ b/node/src/rpc/manta.rs @@ -17,6 +17,9 @@ //! Manta RPC Extensions use super::*; +use manta_farming_rpc_api::{FarmingRpc, FarmingRpcApiServer}; +use manta_farming_rpc_runtime_api::FarmingRuntimeApi; +use manta_primitives::types::{MantaAssetId, PoolId}; use pallet_manta_pay::{ rpc::{Pull, PullApiServer}, runtime::PullLedgerDiffApi, @@ -25,6 +28,9 @@ use pallet_manta_sbt::{ rpc::{SBTPull, SBTPullApiServer}, runtime::SBTPullLedgerDiffApi, }; +use zenlink_protocol::AssetId as ZenlinkAssetId; +use zenlink_protocol_rpc::{ZenlinkProtocol, ZenlinkProtocolApiServer}; +use zenlink_protocol_runtime_api::ZenlinkProtocolApi as ZenlinkProtocolRuntimeApi; /// Instantiate all RPC extensions for manta. pub fn create_manta_full(deps: FullDeps) -> Result @@ -41,6 +47,8 @@ where C::Api: BlockBuilder, C::Api: PullLedgerDiffApi, C::Api: SBTPullLedgerDiffApi, + C::Api: FarmingRuntimeApi, + C::Api: ZenlinkProtocolRuntimeApi, P: TransactionPool + Sync + Send + 'static, { use frame_rpc_system::{System, SystemApiServer}; @@ -65,10 +73,19 @@ where .merge(manta_pay_rpc) .map_err(|e| sc_service::Error::Other(e.to_string()))?; - let manta_sbt_rpc: jsonrpsee::RpcModule> = SBTPull::new(client).into_rpc(); + let manta_sbt_rpc: jsonrpsee::RpcModule> = + SBTPull::new(client.clone()).into_rpc(); module .merge(manta_sbt_rpc) .map_err(|e| sc_service::Error::Other(e.to_string()))?; + module + .merge(ZenlinkProtocol::new(client.clone()).into_rpc()) + .map_err(|e| sc_service::Error::Other(e.to_string()))?; + + module + .merge(FarmingRpc::new(client).into_rpc()) + .map_err(|e| sc_service::Error::Other(e.to_string()))?; + Ok(module) } diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index 488c8510f..a33b1bf86 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -88,8 +88,13 @@ xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-fea orml-traits = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } orml-xtokens = { git = 'https://github.com/manta-network/open-runtime-module-library.git', default-features = false, branch = "polkadot-v0.9.37" } +zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } +zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37", default-features = false } + # Self dependencies manta-collator-selection = { path = '../../pallets/collator-selection', default-features = false } +manta-farming = { path = '../../pallets/farming', default-features = false } +manta-farming-rpc-runtime-api = { path = '../../pallets/farming/rpc/runtime-api', default-features = false } manta-primitives = { path = '../../primitives/manta', default-features = false } manta-support = { package = "pallet-manta-support", path = "../../pallets/manta-support", default-features = false } pallet-asset-manager = { path = '../../pallets/asset-manager', default-features = false } @@ -148,6 +153,8 @@ runtime-benchmarks = [ 'pallet-manta-pay/runtime-benchmarks', 'pallet-xcm-benchmarks/runtime-benchmarks', 'pallet-manta-sbt/runtime-benchmarks', + "zenlink-protocol/runtime-benchmarks", + 'manta-farming/runtime-benchmarks', ] try-runtime = [ 'frame-try-runtime', @@ -187,6 +194,8 @@ try-runtime = [ 'pallet-manta-pay/try-runtime', 'orml-xtokens/try-runtime', 'pallet-manta-sbt/try-runtime', + "zenlink-protocol/try-runtime", + "manta-farming/try-runtime", ] # Set timing constants (e.g. session period) to faster versions to speed up testing. fast-runtime = [] @@ -258,6 +267,10 @@ std = [ 'orml-xtokens/std', 'pallet-manta-sbt/std', 'manta-support/std', + "zenlink-protocol/std", + "zenlink-protocol-runtime-api/std", + "manta-farming/std", + "manta-farming-rpc-runtime-api/std", ] # A feature that should be enabled when the runtime should be build for on-chain # deployment. This will disable stuff that shouldn't be part of the on-chain wasm diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index 30023d2a6..3e258d3ab 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -30,7 +30,7 @@ use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT}, + traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Percent, Permill, }; @@ -62,7 +62,7 @@ use frame_system::{ }; use manta_primitives::{ constants::{time::*, RocksDbWeight, STAKING_PALLET_ID, TREASURY_PALLET_ID, WEIGHT_PER_SECOND}, - types::{AccountId, Balance, BlockNumber, Hash, Header, Index, Signature}, + types::{AccountId, Balance, BlockNumber, Hash, Header, Index, PoolId, Signature}, }; use manta_support::manta_pay::{InitialSyncResponse, PullResponse, RawCheckpoint}; pub use pallet_parachain_staking::{InflationInfo, Range}; @@ -72,6 +72,7 @@ use runtime_common::{ MantaSlowAdjustingFeeUpdate, }; use session_key_primitives::{AuraId, NimbusId, VrfId}; +use zenlink_protocol::{AssetBalance, AssetId as ZenlinkAssetId, MultiAssetsHandler, PairInfo}; #[cfg(feature = "runtime-benchmarks")] use xcm::latest::prelude::*; @@ -87,9 +88,11 @@ pub mod migrations; mod nimbus_session_adapter; pub mod staking; pub mod xcm_config; +pub mod zenlink; use currency::*; use impls::DealWithFees; +use manta_primitives::{currencies::Currencies, types::MantaAssetId}; pub type NegativeImbalance = >::NegativeImbalance; @@ -265,6 +268,8 @@ impl Contains for MantaFilter { | RuntimeCall::MantaPay(_) | RuntimeCall::MantaSbt(_) | RuntimeCall::TransactionPause(_) + | RuntimeCall::ZenlinkProtocol(_) + | RuntimeCall::Farming(_) | RuntimeCall::AssetManager(pallet_asset_manager::Call::update_outgoing_filtered_assets {..}) | RuntimeCall::Utility(_) => true, @@ -755,6 +760,29 @@ impl pallet_treasury::Config for Runtime { type SpendOrigin = NeverEnsureOrigin; } +parameter_types! { + pub const FarmingKeeperPalletId: PalletId = PalletId(*b"mt/fmkpr"); + pub const FarmingRewardIssuerPalletId: PalletId = PalletId(*b"mt/fmrir"); + pub TreasuryAccount: AccountId = TreasuryPalletId::get().into_account_truncating(); +} + +/// Zenlink protocol Asset adaptor for orml_traits::MultiCurrency. +type MantaCurrencies = Currencies; + +impl manta_farming::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CurrencyId = MantaAssetId; + type MultiCurrency = MantaCurrencies; + type ControlOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, + >; + type TreasuryAccount = TreasuryAccount; + type Keeper = FarmingKeeperPalletId; + type RewardIssuer = FarmingRewardIssuerPalletId; + type WeightInfo = weights::manta_farming::SubstrateWeight; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime where @@ -816,6 +844,9 @@ construct_runtime!( AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Config, Event} = 46, MantaPay: pallet_manta_pay::{Pallet, Call, Storage, Event} = 47, MantaSbt: pallet_manta_sbt::{Pallet, Call, Storage, Event} = 49, + + ZenlinkProtocol: zenlink_protocol::{Pallet, Call, Storage, Event} = 51, + Farming: manta_farming::{Pallet, Call, Storage, Event} = 54, } ); @@ -888,6 +919,8 @@ mod benches { [pallet_parachain_staking, ParachainStaking] [pallet_manta_pay, MantaPay] [pallet_manta_sbt, MantaSbt] + [zenlink_protocol, ZenlinkProtocol] + [manta_farming, Farming] // Nimbus pallets [pallet_author_inherent, AuthorInherent] ); @@ -1088,6 +1121,78 @@ impl_runtime_apis! { } } + // zenlink runtime outer apis + impl zenlink_protocol_runtime_api::ZenlinkProtocolApi for Runtime { + + fn get_balance( + asset_id: ZenlinkAssetId, + owner: AccountId + ) -> AssetBalance { + <::MultiAssetsHandler as MultiAssetsHandler>::balance_of(asset_id, &owner) + } + + fn get_pair_by_asset_id( + asset_0: ZenlinkAssetId, + asset_1: ZenlinkAssetId + ) -> Option> { + ZenlinkProtocol::get_pair_by_asset_id(asset_0, asset_1) + } + + fn get_amount_in_price( + supply: AssetBalance, + path: Vec + ) -> AssetBalance { + ZenlinkProtocol::desired_in_amount(supply, path) + } + + fn get_amount_out_price( + supply: AssetBalance, + path: Vec + ) -> AssetBalance { + ZenlinkProtocol::supply_out_amount(supply, path) + } + + fn get_estimate_lptoken( + token_0: ZenlinkAssetId, + token_1: ZenlinkAssetId, + amount_0_desired: AssetBalance, + amount_1_desired: AssetBalance, + amount_0_min: AssetBalance, + amount_1_min: AssetBalance, + ) -> AssetBalance{ + ZenlinkProtocol::get_estimate_lptoken( + token_0, + token_1, + amount_0_desired, + amount_1_desired, + amount_0_min, + amount_1_min + ) + } + + fn calculate_remove_liquidity( + asset_0: ZenlinkAssetId, + asset_1: ZenlinkAssetId, + amount: AssetBalance, + ) -> Option<(AssetBalance, AssetBalance)> { + ZenlinkProtocol::calculate_remove_liquidity( + asset_0, + asset_1, + amount + ) + } + } + + impl manta_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { + fn get_farming_rewards(who: AccountId, pid: PoolId) -> Vec<(MantaAssetId, Balance)> { + Farming::get_farming_rewards(&who, pid).unwrap_or(Vec::new()) + } + + fn get_gauge_rewards(who: AccountId, pid: PoolId) -> Vec<(MantaAssetId, Balance)> { + Farming::get_gauge_rewards(&who, pid).unwrap_or(Vec::new()) + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { diff --git a/runtime/manta/src/weights/manta_farming.rs b/runtime/manta/src/weights/manta_farming.rs new file mode 100644 index 000000000..f41f5e88a --- /dev/null +++ b/runtime/manta/src/weights/manta_farming.rs @@ -0,0 +1,172 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Autogenerated weights for manta_farming +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-05, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("calamari-dev"), DB CACHE: 1024 + +// Executed Command: +// target/debug/manta +// benchmark +// pallet +// --chain=calamari-dev +// --pallet=manta_farming +// --extrinsic=* +// --heap-pages=4096 +// --repeat=1 +// --steps=1 +// --template=.github/resources/frame-weight-template.hbs +// --output=manta-farming.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; + +/// Weight functions needed for manta_farming. +pub trait WeightInfo { + fn on_initialize() -> Weight; + fn create_farming_pool() -> Weight; + fn deposit() -> Weight; + fn withdraw() -> Weight; + fn claim() -> Weight; + fn gauge_withdraw() -> Weight; +} + +/// Weights for manta_farming using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl manta_farming::WeightInfo for SubstrateWeight { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 75_000 nanoseconds. + Weight::from_ref_time(75_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 658_000 nanoseconds. + Weight::from_ref_time(658_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 3_884_000 nanoseconds. + Weight::from_ref_time(3_884_000_000) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 439_000 nanoseconds. + Weight::from_ref_time(439_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 473_000 nanoseconds. + Weight::from_ref_time(473_000_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 640_000 nanoseconds. + Weight::from_ref_time(640_000_000) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming GaugePoolInfos (r:1 w:0) + fn on_initialize() -> Weight { + // Minimum execution time: 75_000 nanoseconds. + Weight::from_ref_time(75_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + } + // Storage: Farming PoolNextId (r:1 w:1) + // Storage: Farming GaugePoolNextId (r:1 w:1) + // Storage: Farming GaugePoolInfos (r:0 w:1) + // Storage: Farming PoolInfos (r:0 w:1) + fn create_farming_pool() -> Weight { + // Minimum execution time: 658_000 nanoseconds. + Weight::from_ref_time(658_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn deposit() -> Weight { + // Minimum execution time: 3_884_000 nanoseconds. + Weight::from_ref_time(3_884_000_000) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + fn withdraw() -> Weight { + // Minimum execution time: 439_000 nanoseconds. + Weight::from_ref_time(439_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:0) + fn claim() -> Weight { + // Minimum execution time: 473_000 nanoseconds. + Weight::from_ref_time(473_000_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: Farming GaugePoolInfos (r:1 w:1) + // Storage: Farming GaugeInfos (r:1 w:1) + // Storage: Farming PoolInfos (r:1 w:0) + // Storage: Farming SharesAndWithdrawnRewards (r:1 w:0) + fn gauge_withdraw() -> Weight { + // Minimum execution time: 640_000 nanoseconds. + Weight::from_ref_time(640_000_000) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(2)) + } +} diff --git a/runtime/manta/src/weights/mod.rs b/runtime/manta/src/weights/mod.rs index 868036cdd..3be189619 100644 --- a/runtime/manta/src/weights/mod.rs +++ b/runtime/manta/src/weights/mod.rs @@ -19,6 +19,7 @@ pub mod cumulus_pallet_xcmp_queue; pub mod frame_system; pub mod manta_collator_selection; +pub mod manta_farming; pub mod pallet_asset_manager; pub mod pallet_assets; pub mod pallet_author_inherent; @@ -38,3 +39,4 @@ pub mod pallet_treasury; pub mod pallet_tx_pause; pub mod pallet_utility; pub mod xcm; +pub mod zenlink_protocol; diff --git a/runtime/manta/src/weights/zenlink_protocol.rs b/runtime/manta/src/weights/zenlink_protocol.rs new file mode 100644 index 000000000..c0d6c75a3 --- /dev/null +++ b/runtime/manta/src/weights/zenlink_protocol.rs @@ -0,0 +1,383 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +//! Autogenerated weights for zenlink_protocol +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-29, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("calamari-dev"), DB CACHE: 1024 + +// Executed Command: +// target/debug/manta +// benchmark +// pallet +// --chain=calamari-dev +// --pallet=zenlink_protocol +// --extrinsic=* +// --heap-pages=4096 +// --repeat=1 +// --steps=1 +// --template=.github/resources/frame-weight-template.hbs +// --output=zenlink_protocol.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; +use manta_primitives::constants::RocksDbWeight; + +/// Weight functions needed for zenlink_protocol. +pub trait WeightInfo { + fn set_fee_receiver() -> Weight; + fn set_fee_point() -> Weight; + fn create_pair() -> Weight; + fn bootstrap_create() -> Weight; + fn bootstrap_contribute() -> Weight; + fn bootstrap_claim() -> Weight; + fn bootstrap_end() -> Weight; + fn bootstrap_update() -> Weight; + fn bootstrap_refund() -> Weight; + fn add_liquidity() -> Weight; + fn remove_liquidity() -> Weight; + fn swap_exact_assets_for_assets() -> Weight; + fn swap_assets_for_exact_assets() -> Weight; +} + +/// Weights for zenlink_protocol using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl zenlink_protocol::WeightInfo for SubstrateWeight { + // Storage: ZenlinkProtocol FeeMeta (r:1 w:1) + fn set_fee_receiver() -> Weight { + // Minimum execution time: 68_000 nanoseconds. + Weight::from_ref_time(68_000_000) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: ZenlinkProtocol FeeMeta (r:1 w:1) + fn set_fee_point() -> Weight { + // Minimum execution time: 66_000 nanoseconds. + Weight::from_ref_time(66_000_000) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignList (r:1 w:0) + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol LiquidityPairs (r:0 w:1) + fn create_pair() -> Weight { + // Minimum execution time: 308_000 nanoseconds. + Weight::from_ref_time(308_000_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapLimits (r:0 w:1) + // Storage: ZenlinkProtocol BootstrapRewards (r:0 w:1) + fn bootstrap_create() -> Weight { + // Minimum execution time: 212_000 nanoseconds. + Weight::from_ref_time(212_000_000) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: ZenlinkProtocol BootstrapLimits (r:1 w:0) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapPersonalSupply (r:1 w:1) + fn bootstrap_contribute() -> Weight { + // Minimum execution time: 608_000 nanoseconds. + Weight::from_ref_time(608_000_000) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:0) + // Storage: ZenlinkProtocol BootstrapPersonalSupply (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapEndStatus (r:1 w:0) + // Storage: ZenlinkProtocol LiquidityPairs (r:1 w:0) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: AssetManager LocationAssetId (r:3 w:0) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:5 w:5) + // Storage: Assets Metadata (r:4 w:4) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapRewards (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:2 w:2) + // Storage: AssetManager AssetIdMetadata (r:0 w:4) + fn bootstrap_claim() -> Weight { + // Minimum execution time: 2_419_000 nanoseconds. + Weight::from_ref_time(2_419_000_000) + .saturating_add(T::DbWeight::get().reads(24)) + .saturating_add(T::DbWeight::get().writes(20)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: AssetManager LocationAssetId (r:3 w:3) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:5 w:5) + // Storage: Assets Metadata (r:5 w:5) + // Storage: Assets Account (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: AssetManager AssetIdMetadata (r:0 w:5) + // Storage: AssetManager AssetIdLocation (r:0 w:3) + // Storage: ZenlinkProtocol LiquidityPairs (r:0 w:1) + // Storage: ZenlinkProtocol BootstrapEndStatus (r:0 w:1) + fn bootstrap_end() -> Weight { + // Minimum execution time: 1_836_000 nanoseconds. + Weight::from_ref_time(1_836_000_000) + .saturating_add(T::DbWeight::get().reads(22)) + .saturating_add(T::DbWeight::get().writes(31)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapRewards (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapLimits (r:0 w:1) + fn bootstrap_update() -> Weight { + // Minimum execution time: 275_000 nanoseconds. + Weight::from_ref_time(275_000_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapPersonalSupply (r:1 w:1) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + fn bootstrap_refund() -> Weight { + // Minimum execution time: 796_000 nanoseconds. + Weight::from_ref_time(796_000_000) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: ZenlinkProtocol LiquidityPairs (r:1 w:0) + // Storage: ZenlinkProtocol KLast (r:1 w:0) + // Storage: ZenlinkProtocol FeeMeta (r:1 w:0) + // Storage: AssetManager LocationAssetId (r:3 w:3) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:5 w:5) + // Storage: Assets Metadata (r:5 w:5) + // Storage: Assets Account (r:1 w:1) + // Storage: AssetManager AssetIdMetadata (r:0 w:5) + // Storage: AssetManager AssetIdLocation (r:0 w:3) + fn add_liquidity() -> Weight { + // Minimum execution time: 1_926_000 nanoseconds. + Weight::from_ref_time(1_926_000_000) + .saturating_add(T::DbWeight::get().reads(24)) + .saturating_add(T::DbWeight::get().writes(28)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: ZenlinkProtocol LiquidityPairs (r:1 w:0) + // Storage: ZenlinkProtocol KLast (r:1 w:0) + // Storage: ZenlinkProtocol FeeMeta (r:1 w:0) + // Storage: AssetManager LocationAssetId (r:3 w:0) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:3 w:3) + // Storage: Assets Metadata (r:2 w:2) + // Storage: Assets Account (r:1 w:1) + // Storage: AssetManager AssetIdMetadata (r:0 w:2) + fn remove_liquidity() -> Weight { + // Minimum execution time: 1_571_000 nanoseconds. + Weight::from_ref_time(1_571_000_000) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().writes(14)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:6 w:6) + // Storage: ZenlinkProtocol PairStatuses (r:2 w:0) + fn swap_exact_assets_for_assets() -> Weight { + // Minimum execution time: 993_000 nanoseconds. + Weight::from_ref_time(993_000_000) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:6 w:6) + // Storage: ZenlinkProtocol PairStatuses (r:2 w:0) + fn swap_assets_for_exact_assets() -> Weight { + // Minimum execution time: 1_005_000 nanoseconds. + Weight::from_ref_time(1_005_000_000) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: ZenlinkProtocol FeeMeta (r:1 w:1) + fn set_fee_receiver() -> Weight { + // Minimum execution time: 68_000 nanoseconds. + Weight::from_ref_time(68_000_000) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: ZenlinkProtocol FeeMeta (r:1 w:1) + fn set_fee_point() -> Weight { + // Minimum execution time: 66_000 nanoseconds. + Weight::from_ref_time(66_000_000) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignList (r:1 w:0) + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol LiquidityPairs (r:0 w:1) + fn create_pair() -> Weight { + // Minimum execution time: 308_000 nanoseconds. + Weight::from_ref_time(308_000_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapLimits (r:0 w:1) + // Storage: ZenlinkProtocol BootstrapRewards (r:0 w:1) + fn bootstrap_create() -> Weight { + // Minimum execution time: 212_000 nanoseconds. + Weight::from_ref_time(212_000_000) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + // Storage: ZenlinkProtocol BootstrapLimits (r:1 w:0) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapPersonalSupply (r:1 w:1) + fn bootstrap_contribute() -> Weight { + // Minimum execution time: 608_000 nanoseconds. + Weight::from_ref_time(608_000_000) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:0) + // Storage: ZenlinkProtocol BootstrapPersonalSupply (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapEndStatus (r:1 w:0) + // Storage: ZenlinkProtocol LiquidityPairs (r:1 w:0) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: AssetManager LocationAssetId (r:3 w:0) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:5 w:5) + // Storage: Assets Metadata (r:4 w:4) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapRewards (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:2 w:2) + // Storage: AssetManager AssetIdMetadata (r:0 w:4) + fn bootstrap_claim() -> Weight { + // Minimum execution time: 2_419_000 nanoseconds. + Weight::from_ref_time(2_419_000_000) + .saturating_add(RocksDbWeight::get().reads(24)) + .saturating_add(RocksDbWeight::get().writes(20)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: AssetManager LocationAssetId (r:3 w:3) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:5 w:5) + // Storage: Assets Metadata (r:5 w:5) + // Storage: Assets Account (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: AssetManager AssetIdMetadata (r:0 w:5) + // Storage: AssetManager AssetIdLocation (r:0 w:3) + // Storage: ZenlinkProtocol LiquidityPairs (r:0 w:1) + // Storage: ZenlinkProtocol BootstrapEndStatus (r:0 w:1) + fn bootstrap_end() -> Weight { + // Minimum execution time: 1_836_000 nanoseconds. + Weight::from_ref_time(1_836_000_000) + .saturating_add(RocksDbWeight::get().reads(22)) + .saturating_add(RocksDbWeight::get().writes(31)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapRewards (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapLimits (r:0 w:1) + fn bootstrap_update() -> Weight { + // Minimum execution time: 275_000 nanoseconds. + Weight::from_ref_time(275_000_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ZenlinkProtocol BootstrapPersonalSupply (r:1 w:1) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + fn bootstrap_refund() -> Weight { + // Minimum execution time: 796_000 nanoseconds. + Weight::from_ref_time(796_000_000) + .saturating_add(RocksDbWeight::get().reads(7)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: ZenlinkProtocol LiquidityPairs (r:1 w:0) + // Storage: ZenlinkProtocol KLast (r:1 w:0) + // Storage: ZenlinkProtocol FeeMeta (r:1 w:0) + // Storage: AssetManager LocationAssetId (r:3 w:3) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:5 w:5) + // Storage: Assets Metadata (r:5 w:5) + // Storage: Assets Account (r:1 w:1) + // Storage: AssetManager AssetIdMetadata (r:0 w:5) + // Storage: AssetManager AssetIdLocation (r:0 w:3) + fn add_liquidity() -> Weight { + // Minimum execution time: 1_926_000 nanoseconds. + Weight::from_ref_time(1_926_000_000) + .saturating_add(RocksDbWeight::get().reads(24)) + .saturating_add(RocksDbWeight::get().writes(28)) + } + // Storage: ZenlinkProtocol PairStatuses (r:1 w:1) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:4 w:4) + // Storage: ZenlinkProtocol LiquidityPairs (r:1 w:0) + // Storage: ZenlinkProtocol KLast (r:1 w:0) + // Storage: ZenlinkProtocol FeeMeta (r:1 w:0) + // Storage: AssetManager LocationAssetId (r:3 w:0) + // Storage: AssetManager NextAssetId (r:1 w:1) + // Storage: Assets Asset (r:3 w:3) + // Storage: Assets Metadata (r:2 w:2) + // Storage: Assets Account (r:1 w:1) + // Storage: AssetManager AssetIdMetadata (r:0 w:2) + fn remove_liquidity() -> Weight { + // Minimum execution time: 1_571_000 nanoseconds. + Weight::from_ref_time(1_571_000_000) + .saturating_add(RocksDbWeight::get().reads(19)) + .saturating_add(RocksDbWeight::get().writes(14)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:6 w:6) + // Storage: ZenlinkProtocol PairStatuses (r:2 w:0) + fn swap_exact_assets_for_assets() -> Weight { + // Minimum execution time: 993_000 nanoseconds. + Weight::from_ref_time(993_000_000) + .saturating_add(RocksDbWeight::get().reads(9)) + .saturating_add(RocksDbWeight::get().writes(6)) + } + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Storage: ZenlinkProtocol ForeignLedger (r:6 w:6) + // Storage: ZenlinkProtocol PairStatuses (r:2 w:0) + fn swap_assets_for_exact_assets() -> Weight { + // Minimum execution time: 1_005_000 nanoseconds. + Weight::from_ref_time(1_005_000_000) + .saturating_add(RocksDbWeight::get().reads(9)) + .saturating_add(RocksDbWeight::get().writes(6)) + } +} diff --git a/runtime/manta/src/zenlink.rs b/runtime/manta/src/zenlink.rs new file mode 100644 index 000000000..b59065d1a --- /dev/null +++ b/runtime/manta/src/zenlink.rs @@ -0,0 +1,244 @@ +// Copyright 2020-2023 Manta Network. +// This file is part of Manta. +// +// Manta is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Manta is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Manta. If not, see . + +use super::{AssetManager, Balances, ParachainInfo, Runtime, RuntimeEvent, ZenlinkProtocol}; +use crate::assets_config::MantaConcreteFungibleLedger; +use frame_support::{parameter_types, traits::ExistenceRequirement, PalletId}; +use manta_primitives::{ + assets::{AssetIdLpMap, FungibleLedger}, + types::MantaAssetId, +}; +use sp_runtime::{traits::Zero, DispatchError}; +use zenlink_protocol::{ + AssetBalance, AssetId as ZenlinkAssetId, GenerateLpAssetId, LocalAssetHandler, + ZenlinkMultiAssets, LOCAL, +}; + +// Normal Coin AMM +parameter_types! { + pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink"); + pub SelfParaId: u32 = ParachainInfo::parachain_id().into(); + pub MantaNativeAssetId: MantaAssetId = 1; + pub ZenlinkNativeAssetId: u64 = 0; +} + +type MultiAssets = ZenlinkMultiAssets; + +impl zenlink_protocol::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MultiAssetsHandler = MultiAssets; + type PalletId = ZenlinkPalletId; + type SelfParaId = SelfParaId; + type AssetId = ZenlinkAssetId; + #[cfg(not(feature = "runtime-benchmarks"))] + type LpGenerate = AssetManagerLpGenerate; + #[cfg(feature = "runtime-benchmarks")] + type LpGenerate = mock_benchmark::MockAssetManagerLpGenerate; + type WeightInfo = crate::weights::zenlink_protocol::SubstrateWeight; +} + +pub struct AssetManagerLpGenerate; +impl GenerateLpAssetId for AssetManagerLpGenerate { + fn generate_lp_asset_id( + asset_0: ZenlinkAssetId, + asset_1: ZenlinkAssetId, + ) -> Option { + if asset_0 == asset_1 { + return None; + } + // LP asset id is registered on AssetManager based on two asset id. + let asset_id_0 = LocalAssetAdaptor::asset_id_convert(asset_0); + let asset_id_1 = LocalAssetAdaptor::asset_id_convert(asset_1); + match (asset_id_0, asset_id_1) { + (Some(asset_id0), Some(asset_id1)) => { + let lp_asset_id: Option = + ::lp_asset_id(&asset_id0, &asset_id1); + lp_asset_id.map(|lp_asset| ZenlinkAssetId { + chain_id: SelfParaId::get(), + asset_type: LOCAL, + asset_index: lp_asset as u64, + }) + } + _ => None, + } + } +} + +pub struct LocalAssetAdaptor; + +impl LocalAssetAdaptor { + #[cfg(not(feature = "runtime-benchmarks"))] + fn asset_id_convert(asset_id: ZenlinkAssetId) -> Option { + // Notice: Manta native asset id is 1, but Zenlink native asset id is 0. + if asset_id.asset_index == ZenlinkNativeAssetId::get() { + // When Zenlink asset index is 0, the asset type need to be NATIVE(0). + return if asset_id.asset_type != zenlink_protocol::NATIVE { + None + } else { + Some(MantaNativeAssetId::get()) + }; + } + let manta_asset_id = asset_id.asset_index as MantaAssetId; + Some(manta_asset_id) + } + #[cfg(feature = "runtime-benchmarks")] + fn asset_id_convert(asset_id: ZenlinkAssetId) -> Option { + mock_benchmark::asset_id_convert(asset_id) + } +} + +impl LocalAssetHandler for LocalAssetAdaptor { + fn local_balance_of(asset_id: ZenlinkAssetId, who: &sp_runtime::AccountId32) -> AssetBalance { + let manta_asset_id = LocalAssetAdaptor::asset_id_convert(asset_id); + if let Some(manta_asset_id) = manta_asset_id { + ::balance(manta_asset_id, who) + } else { + AssetBalance::zero() + } + } + + fn local_total_supply(asset_id: ZenlinkAssetId) -> AssetBalance { + let manta_asset_id = LocalAssetAdaptor::asset_id_convert(asset_id); + if let Some(manta_asset_id) = manta_asset_id { + ::supply(manta_asset_id) + } else { + AssetBalance::zero() + } + } + + fn local_is_exists(asset_id: ZenlinkAssetId) -> bool { + let manta_asset_id = LocalAssetAdaptor::asset_id_convert(asset_id); + manta_asset_id.is_some() + } + + fn local_deposit( + asset_id: ZenlinkAssetId, + origin: &sp_runtime::AccountId32, + amount: AssetBalance, + ) -> Result { + let manta_asset_id = LocalAssetAdaptor::asset_id_convert(asset_id); + if let Some(manta_asset_id) = manta_asset_id { + ::deposit_minting( + manta_asset_id, + origin, + amount, + ) + .map_err(|_e| DispatchError::Other("deposit lp asset error"))?; + Ok(amount) + } else { + Err(DispatchError::Other("unknown asset in local deposit")) + } + } + + fn local_withdraw( + asset_id: ZenlinkAssetId, + origin: &sp_runtime::AccountId32, + amount: AssetBalance, + ) -> Result { + let manta_asset_id = LocalAssetAdaptor::asset_id_convert(asset_id); + if let Some(manta_asset_id) = manta_asset_id { + ::withdraw_burning( + manta_asset_id, + origin, + amount, + ExistenceRequirement::AllowDeath, + ) + .map_err(|_e| DispatchError::Other("withdraw lp asset error"))?; + Ok(amount) + } else { + Err(DispatchError::Other("unknown asset in local withdraw")) + } + } +} + +#[cfg(feature = "runtime-benchmarks")] +mod mock_benchmark { + use super::super::*; + use crate::{ + zenlink::{MantaNativeAssetId, SelfParaId, ZenlinkNativeAssetId}, + ZenlinkAssetId, + }; + use manta_primitives::{ + assets::{AssetLocation, AssetRegistryMetadata, AssetStorageMetadata}, + types::{Balance, MantaAssetId}, + }; + use xcm::{ + latest::MultiLocation, + prelude::{GeneralIndex, PalletInstance, Parachain, X3}, + VersionedMultiLocation, + }; + use zenlink_protocol::{GenerateLpAssetId, LOCAL, NATIVE}; + + pub struct MockAssetManagerLpGenerate; + impl GenerateLpAssetId for MockAssetManagerLpGenerate { + fn generate_lp_asset_id( + _asset_0: ZenlinkAssetId, + asset_1: ZenlinkAssetId, + ) -> Option { + Some(ZenlinkAssetId { + chain_id: SelfParaId::get(), + asset_type: LOCAL, + asset_index: asset_1.asset_index + 1u64, + }) + } + } + + pub fn mock_asset(name: &str, index: u128) -> (AssetRegistryMetadata, AssetLocation) { + let metadata = AssetRegistryMetadata { + metadata: AssetStorageMetadata { + name: name.as_bytes().to_vec(), + symbol: name.as_bytes().to_vec(), + decimals: 12, + is_frozen: false, + }, + min_balance: 1u128, + is_sufficient: true, + }; + let location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::new( + 1, + X3( + Parachain(SelfParaId::get()), + PalletInstance(45), + GeneralIndex(index), + ), + ))); + (metadata, location) + } + + pub fn asset_id_convert(asset_id: ZenlinkAssetId) -> Option { + // Notice: Manta native asset id is 1, but Zenlink native asset id is 0. + if asset_id.asset_index == ZenlinkNativeAssetId::get() { + // When Zenlink asset index is 0, the asset type need to be NATIVE(0). + return if asset_id.asset_type != NATIVE { + None + } else { + Some(MantaNativeAssetId::get()) + }; + } + // Manual create asset if not exist to make sure deposit_mint is fine. + let (metadata1, location1) = mock_asset("Asset0", 8); + let (metadata2, location2) = mock_asset("Asset1", 9); + let (metadata3, _location3) = mock_asset("LPAsset01", 10); + let (metadata4, location4) = mock_asset("Asset2", 11); + let (metadata5, _location5) = mock_asset("LPAsset12", 12); + let _ = AssetManager::do_register_asset(Some(&location1), &metadata1); + let _ = AssetManager::do_register_asset(Some(&location2), &metadata2); + let _ = AssetManager::do_register_asset(None, &metadata3); + let _ = AssetManager::do_register_asset(Some(&location4), &metadata4); + let _ = AssetManager::do_register_asset(None, &metadata5); + Some(asset_id.asset_index as MantaAssetId) + } +} From cd8c22441ecdba3e883507d221fceaa9048d99de Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Wed, 28 Jun 2023 20:23:48 +0800 Subject: [PATCH 17/26] add to manta Signed-off-by: zqhxuyuan --- pallets/farming/src/lib.rs | 8 +++----- pallets/farming/src/rewards.rs | 19 ++++++++----------- runtime/manta/src/weights/manta_farming.rs | 21 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 9bf546da9..f434eacb3 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -467,8 +467,7 @@ pub mod pallet { Ok(()) } - /// User can withdraw token from farming pool, and remove share of pool, also this operation - /// will claim rewards. + /// User can withdraw token from farming pool. This only remove share and get claim rewards. #[pallet::call_index(3)] #[pallet::weight(T::WeightInfo::withdraw())] pub fn withdraw( @@ -501,7 +500,7 @@ pub mod pallet { Ok(()) } - /// User claim rewards when deposit token into the farming pool. + /// User can claim rewards and also unStake. #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::claim())] pub fn claim(origin: OriginFor, pid: PoolId) -> DispatchResult { @@ -534,8 +533,7 @@ pub mod pallet { Ok(()) } - /// User can withdraw but not claim rewards from farming pool. - /// This operation will transfer back user staked token from keeper account. + /// User can unStake token from farm pool. #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::claim())] pub fn withdraw_claim(origin: OriginFor, pid: PoolId) -> DispatchResult { diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs index 0a35256ce..541cf0048 100644 --- a/pallets/farming/src/rewards.rs +++ b/pallets/farming/src/rewards.rs @@ -249,32 +249,26 @@ impl Pallet { let pool_info = maybe_pool_info .as_mut() .ok_or(Error::::PoolDoesNotExist)?; - - share_info - .withdraw_list - .push((n + withdraw_limit_time, remove_amount)); - pool_info.total_shares = pool_info.total_shares.saturating_sub(remove_amount); // update withdrawn rewards for each reward currency share_info.withdrawn_rewards.iter_mut().try_for_each( |(reward_currency, withdrawn_reward)| -> DispatchResult { - let withdrawn_reward_to_remove = Self::get_reward_inflation( + let withdrawn_amount = Self::get_reward_inflation( remove_amount, withdrawn_reward, share_info.share, ); - if withdrawn_reward_to_remove.is_zero() { + if withdrawn_amount.is_zero() { return Ok(()); } if let Some((total_reward, total_withdrawn_reward)) = pool_info.rewards.get_mut(reward_currency) { - *total_reward = - total_reward.saturating_sub(withdrawn_reward_to_remove); + *total_reward = total_reward.saturating_sub(withdrawn_amount); *total_withdrawn_reward = total_withdrawn_reward - .saturating_sub(withdrawn_reward_to_remove); + .saturating_sub(withdrawn_amount); // remove if all reward is withdrawn if total_reward.is_zero() { @@ -282,13 +276,16 @@ impl Pallet { } } *withdrawn_reward = - withdrawn_reward.saturating_sub(withdrawn_reward_to_remove); + withdrawn_reward.saturating_sub(withdrawn_amount); Ok(()) }, )?; Ok(()) })?; + share_info + .withdraw_list + .push((n + withdraw_limit_time, remove_amount)); share_info.share = share_info.share.saturating_sub(remove_amount); *share_info_old = Some(share_info); } diff --git a/runtime/manta/src/weights/manta_farming.rs b/runtime/manta/src/weights/manta_farming.rs index f41f5e88a..aa02e995d 100644 --- a/runtime/manta/src/weights/manta_farming.rs +++ b/runtime/manta/src/weights/manta_farming.rs @@ -46,6 +46,7 @@ use manta_primitives::constants::RocksDbWeight; pub trait WeightInfo { fn on_initialize() -> Weight; fn create_farming_pool() -> Weight; + fn charge() -> Weight; fn deposit() -> Weight; fn withdraw() -> Weight; fn claim() -> Weight; @@ -76,6 +77,16 @@ impl manta_farming::WeightInfo for SubstrateWeight { // Storage: Assets Asset (r:1 w:1) // Storage: Assets Account (r:2 w:2) // Storage: System Account (r:1 w:1) + fn charge() -> Weight { + // Minimum execution time: 897_000 nanoseconds. + Weight::from_ref_time(902_000_000) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) fn deposit() -> Weight { // Minimum execution time: 3_884_000 nanoseconds. @@ -135,6 +146,16 @@ impl WeightInfo for () { // Storage: Assets Asset (r:1 w:1) // Storage: Assets Account (r:2 w:2) // Storage: System Account (r:1 w:1) + fn charge() -> Weight { + // Minimum execution time: 897_000 nanoseconds. + Weight::from_ref_time(902_000_000) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(5)) + } + // Storage: Farming PoolInfos (r:1 w:1) + // Storage: Assets Asset (r:1 w:1) + // Storage: Assets Account (r:2 w:2) + // Storage: System Account (r:1 w:1) // Storage: Farming SharesAndWithdrawnRewards (r:1 w:1) fn deposit() -> Weight { // Minimum execution time: 3_884_000 nanoseconds. From 4440e474db00afbf9448d63bcd39bbf251f53150 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Fri, 30 Jun 2023 00:51:34 +0800 Subject: [PATCH 18/26] more tests Signed-off-by: zqhxuyuan --- pallets/farming/src/tests.rs | 507 ++++++++++++++++++++++------------- 1 file changed, 314 insertions(+), 193 deletions(-) diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 7971a3e81..06c2703f2 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -93,6 +93,43 @@ fn init_gauge_1000() -> (PoolId, BalanceOf) { (pid, tokens) } +fn init_no_gauge() -> (PoolId, BalanceOf) { + let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; + let tokens = 1000; + let basic_rewards = vec![(KSM, 1000)]; + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + None, + 0, // min_deposit_to_start + 0, // after_block_to_start + 10, // withdraw_limit_time + 0, // claim_limit_time + 1 // withdraw_limit_count + )); + + let pid = 0; + let charge_rewards = vec![(KSM, 100000)]; + + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + None + )); + + let share_info = Farming::shares_and_withdrawn_rewards(pid, &ALICE).unwrap(); + assert_eq!(share_info.share, tokens); + (pid, tokens) +} + #[test] fn precondition_check_should_work() { ExtBuilder::default() @@ -677,227 +714,322 @@ fn gauge_farming_pool_should_work() { } #[test] -fn deposit_gauge_should_work() { +fn deposit_no_gauge_should_work() { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_eq!(Assets::balance(KSM, &ALICE), 3000); - let (pid, tokens) = init_gauge_1000(); - assert_eq!(Assets::balance(KSM, &ALICE), 2000); - - System::set_block_number(System::block_number() + 1); - assert_ok!(Farming::deposit( - RuntimeOrigin::signed(ALICE), - pid, - tokens, - Some((100, 100)) - )); - assert_eq!(Assets::balance(KSM, &ALICE), 900); - System::set_block_number(System::block_number() + 1); - assert_ok!(Farming::deposit( - RuntimeOrigin::signed(ALICE), - pid, - 0, - Some((100, 100)) - )); - assert_eq!(Assets::balance(KSM, &ALICE), 800); - - let keeper: AccountId = - ::Keeper::get().into_sub_account_truncating(pid); - let reward_issuer: AccountId = - ::RewardIssuer::get().into_sub_account_truncating(pid); - let mut gauge_basic_rewards = - BTreeMap::, BalanceOf>::new(); - gauge_basic_rewards.entry(KSM).or_insert(tokens); - let gauge_pool_info2 = GaugePoolInfo { - pid, - token: KSM, - keeper, - reward_issuer, - rewards: BTreeMap::< - CurrencyIdOf, - (BalanceOf, BalanceOf, BalanceOf), - >::new(), - gauge_basic_rewards, - max_block: 1000, - gauge_amount: 200, - total_time_factor: 39900, - gauge_last_block: System::block_number(), - gauge_state: GaugeState::Bonded, - }; - assert_eq!(Farming::gauge_pool_infos(0), Some(gauge_pool_info2)); - Farming::on_initialize(0); - assert_eq!(Farming::pool_infos(0).unwrap().state, PoolState::Ongoing); - assert!(Farming::pool_infos(0).unwrap().rewards.is_empty()); - assert_eq!( - Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), - Some(&(1000, 0, 0)) - ); - - Farming::on_initialize(0); - assert_eq!( - Farming::pool_infos(0).unwrap().rewards.get(&KSM), - Some(&(1000, 0)) - ); - assert_eq!( - Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), - Some(&(2000, 0, 0)) - ); - - System::set_block_number(System::block_number() + 1000); - Farming::on_initialize(0); - assert_eq!( - Farming::pool_infos(0).unwrap().rewards.get(&KSM), - Some(&(2000, 0)) - ); - assert_eq!( - Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), - Some(&(3000, 0, 0)) - ); + deposit_should_work(false); }) } #[test] -fn withdraw() { +fn deposit_gauge_should_work() { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, tokens) = init_gauge_1000(); - let pool = PoolInfos::::get(pid).unwrap(); - let reward_issuer = pool.reward_issuer; - let token_keeper = pool.keeper; - - assert_eq!(Assets::balance(KSM, &ALICE), 2_000); - assert_eq!(Assets::balance(KSM, &reward_issuer), 100_000); - assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); - - Farming::on_initialize(0); - Farming::on_initialize(0); - System::set_block_number(System::block_number() + 1); - - let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - assert!(reward.withdraw_list.is_empty()); - assert_eq!(pool.withdraw_limit_count, 1); - - // withdraw - assert_ok!(Farming::withdraw( - RuntimeOrigin::signed(ALICE), - pid, - Some(800) - )); - - // withdraw contains claim reward operation - // reward issuer transfer 1000 reward token to user - assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); - assert_eq!(Assets::balance(KSM, &ALICE), 3_000); - - let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - assert_eq!(reward.withdraw_list.len(), 1); - // user share info withdraw list size is not less than pool info `withdraw_limit_count` - assert_err!( - Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, Some(100)), - Error::::WithdrawLimitCountExceeded - ); - - // Alice claim reward manually, but due to no new block, so no reward - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 3_000); - assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); - assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); - - // Bob deposit - System::set_block_number(System::block_number() + 100); - assert_ok!(Farming::deposit( - RuntimeOrigin::signed(BOB), - pid, - tokens, - None - )); - // deposit operation transfer user staked token to pool keeper account - assert_eq!(Assets::balance(KSM, &token_keeper), 2_000); + deposit_should_work(true); + }) +} - // Alice claim again, because new block produces, so has reward now - Farming::on_initialize(0); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 3_966); - assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); +fn deposit_should_work(use_gauge: bool) { + assert_eq!(Assets::balance(KSM, &ALICE), 3000); + let (pid, tokens) = if use_gauge { + init_gauge_1000() + } else { + init_no_gauge() + }; + let keeper: AccountId = ::Keeper::get().into_sub_account_truncating(pid); + let reward_issuer: AccountId = + ::RewardIssuer::get().into_sub_account_truncating(pid); + + assert_eq!(Assets::balance(KSM, &ALICE), 2000); + assert_eq!(Assets::balance(KSM, &keeper), 1000); + + System::set_block_number(System::block_number() + 1); + if use_gauge { + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + Some((100, 100)) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 900); + assert_eq!(Assets::balance(KSM, &keeper), 2100); + + System::set_block_number(System::block_number() + 1); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + 0, + Some((100, 100)) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 800); + assert_eq!(Assets::balance(KSM, &keeper), 2200); + } else { + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + None + )); + assert_eq!(Assets::balance(KSM, &ALICE), 1000); + assert_eq!(Assets::balance(KSM, &keeper), 2000); + + System::set_block_number(System::block_number() + 1); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + 100, + None + )); + assert_eq!(Assets::balance(KSM, &ALICE), 900); + assert_eq!(Assets::balance(KSM, &keeper), 2100); + } + + if use_gauge { + let mut gauge_basic_rewards = BTreeMap::, BalanceOf>::new(); + gauge_basic_rewards.entry(KSM).or_insert(tokens); + let gauge_pool_info = GaugePoolInfo { + pid, + token: KSM, + keeper, + reward_issuer, + rewards: BTreeMap::< + CurrencyIdOf, + (BalanceOf, BalanceOf, BalanceOf), + >::new(), + gauge_basic_rewards, + max_block: 1000, + gauge_amount: 200, + total_time_factor: 39900, + gauge_last_block: System::block_number(), + gauge_state: GaugeState::Bonded, + }; + assert_eq!(Farming::gauge_pool_infos(0), Some(gauge_pool_info)); + } else { + assert_eq!(Farming::gauge_pool_infos(0), None); + } + + Farming::on_initialize(0); + assert_eq!(Farming::pool_infos(0).unwrap().state, PoolState::Ongoing); + assert!(Farming::pool_infos(0).unwrap().rewards.is_empty()); + if use_gauge { + assert_eq!( + Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(1000, 0, 0)) + ); + } + + Farming::on_initialize(0); + assert_eq!( + Farming::pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(1000, 0)) + ); + if use_gauge { + assert_eq!( + Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(2000, 0, 0)) + ); + } + + System::set_block_number(System::block_number() + 1000); + Farming::on_initialize(0); + assert_eq!( + Farming::pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(2000, 0)) + ); + if use_gauge { + assert_eq!( + Farming::gauge_pool_infos(0).unwrap().rewards.get(&KSM), + Some(&(3000, 0, 0)) + ); + } +} - // withdraw - assert_ok!(Farming::withdraw( - RuntimeOrigin::signed(ALICE), - pid, - Some(200) - )); - assert_eq!(Assets::balance(KSM, &ALICE), 3_966); - assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); - assert_eq!(Assets::balance(KSM, &token_keeper), 1_200); +#[test] +fn withdraw_gauge_should_work() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + withdraw_should_work(true); + }) +} - // `withdraw_claim` operation will transfer back user stake token - // User unStake 200 KSM, so keeper transfer back 200 KSM to user. - System::set_block_number(System::block_number() + 100); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 4_166); - assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); - assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); +#[test] +fn withdraw_no_gauge_should_work() { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| withdraw_should_work(false)) +} - // claim - let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - assert!(reward.withdraw_list.is_empty()); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 4_166); - assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); - assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); +fn withdraw_should_work(use_gauge: bool) { + let (pid, tokens) = if use_gauge { + init_gauge_1000() + } else { + init_no_gauge() + }; + let pool = PoolInfos::::get(pid).unwrap(); + let reward_issuer = pool.reward_issuer; + let token_keeper = pool.keeper; + + assert_eq!(Assets::balance(KSM, &ALICE), 2_000); + assert_eq!(Assets::balance(KSM, &reward_issuer), 100_000); + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + + Farming::on_initialize(0); + Farming::on_initialize(0); + System::set_block_number(System::block_number() + 1); + + let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert!(reward.withdraw_list.is_empty()); + assert_eq!(pool.withdraw_limit_count, 1); + + // withdraw + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(800) + )); - // `process_withdraw_list` remove the share info. - // due to withdraw_list of share info is empty, so there's no token transfer. - assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); - assert_eq!(Assets::balance(KSM, &TREASURY_ACCOUNT), 0); - }) + // withdraw contains claim reward operation + // reward issuer transfer 1000 reward token to user + assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); + assert_eq!(Assets::balance(KSM, &ALICE), 3_000); + + let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.withdraw_list.len(), 1); + // user share info withdraw list size is not less than pool info `withdraw_limit_count` + assert_err!( + Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, Some(100)), + Error::::WithdrawLimitCountExceeded + ); + + // Alice claim reward manually, but due to no new block, so no reward + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3_000); + assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + + // Bob deposit + System::set_block_number(System::block_number() + 100); + if use_gauge { + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(BOB), + pid, + tokens, + Some((100, 100)) + )); + } else { + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(BOB), + pid, + tokens, + None + )); + } + + // deposit operation transfer user staked token to pool keeper account + if use_gauge { + assert_eq!(Assets::balance(KSM, &token_keeper), 2_100); + } else { + assert_eq!(Assets::balance(KSM, &token_keeper), 2_000); + } + + // Alice claim again, because new block produces, so has reward now + Farming::on_initialize(0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 3_966); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + + // withdraw + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(200) + )); + assert_eq!(Assets::balance(KSM, &ALICE), 3_966); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + if use_gauge { + assert_eq!(Assets::balance(KSM, &token_keeper), 1_300); + } else { + assert_eq!(Assets::balance(KSM, &token_keeper), 1_200); + } + + // `withdraw_claim` operation will transfer back user stake token + // User unStake 200 KSM, so keeper transfer back 200 KSM to user. + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 4_166); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + if use_gauge { + assert_eq!(Assets::balance(KSM, &token_keeper), 1_100); + } else { + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + } + + // claim + let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert!(reward.withdraw_list.is_empty()); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Assets::balance(KSM, &ALICE), 4_166); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); + if use_gauge { + assert_eq!(Assets::balance(KSM, &token_keeper), 1_100); + } else { + assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); + } + + // `process_withdraw_list` remove the share info. + // due to withdraw_list of share info is empty, so there's no token transfer. + assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); + assert_eq!(Assets::balance(KSM, &TREASURY_ACCOUNT), 0); } #[test] fn claim() { - let keeper_account = FarmingKeeperPalletId::get().into_account_truncating(); - ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() .execute_with(|| { let (pid, _tokens) = init_gauge_1000(); + let keeper: AccountId = + ::Keeper::get().into_sub_account_truncating(pid); + let reward_issuer: AccountId = + ::RewardIssuer::get().into_sub_account_truncating(pid); + assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); assert_err!( Farming::claim(RuntimeOrigin::signed(ALICE), pid), Error::::InvalidPoolState ); + System::set_block_number(System::block_number() + 100); Farming::on_initialize(0); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 2000); + assert_eq!(Assets::balance(KSM, &keeper), 1000); + assert_eq!(Assets::balance(KSM, &reward_issuer), 100_000); + Farming::on_initialize(0); assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 2000); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_eq!(Assets::balance(KSM, &keeper), 1000); + assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); + Farming::on_initialize(0); assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); - // Fund token to keeper_account - assert_ok!(Assets::mint( - RuntimeOrigin::signed(ALICE), - KSM, - keeper_account, - 100 - )); - assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 5000); // 3000 + 1000 + 1000 - Farming::on_initialize(0); - assert_err!( - Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), - Error::::InvalidPoolState - ); + assert_eq!(Assets::balance(KSM, &keeper), 0); + assert_eq!(Assets::balance(KSM, &reward_issuer), 98_000); }); } @@ -910,19 +1042,14 @@ fn gauge() { let (pid, tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { - assert_eq!( - gauge_pool_infos.rewards, - BTreeMap::< - CurrencyIdOf, - (BalanceOf, BalanceOf, BalanceOf), - >::new() - ) + assert!(gauge_pool_infos.rewards.is_empty()) }; Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); Farming::on_initialize(0); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 2918); + Farming::on_initialize(0); System::set_block_number(System::block_number() + 10); assert_ok!(Farming::deposit( @@ -932,11 +1059,14 @@ fn gauge() { Some((100, 100)) )); assert_eq!(Assets::balance(KSM, &ALICE), 1818); + System::set_block_number(System::block_number() + 20); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 3163); + assert_ok!(Farming::deposit(RuntimeOrigin::signed(BOB), pid, 10, None)); assert_eq!(Assets::balance(KSM, &BOB), 9699990); + System::set_block_number(System::block_number() + 200); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); assert_eq!(Assets::balance(KSM, &ALICE), 5383); @@ -947,6 +1077,7 @@ fn gauge() { 0, Some((100, 100)) )); + System::set_block_number(System::block_number() + 200); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); assert_ok!(Farming::force_gauge_claim( @@ -984,8 +1115,6 @@ fn gauge_withdraw() { #[test] fn pool_admin_operation_should_work() { - let keeper_account = FarmingKeeperPalletId::get().into_account_truncating(); - ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() @@ -1039,14 +1168,6 @@ fn pool_admin_operation_should_work() { let pool: PoolInfoOf = Farming::pool_infos(pid).unwrap(); assert_eq!(pool.state, PoolState::Dead); - // Fund token to keeper_account - assert_ok!(Assets::mint( - RuntimeOrigin::signed(ALICE), - KSM, - keeper_account, - 100 - )); - assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); System::set_block_number(System::block_number() + 1000); From 00551cb47459a12c8cc52ff5bd9412c3160f9fd8 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Fri, 30 Jun 2023 17:42:42 +0800 Subject: [PATCH 19/26] gauge error Signed-off-by: zqhxuyuan --- pallets/farming/src/tests.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 06c2703f2..4035004c8 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -1042,7 +1042,7 @@ fn gauge() { let (pid, tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { - assert!(gauge_pool_infos.rewards.is_empty()) + assert!(gauge_pool_infos.rewards.is_empty()); }; Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); @@ -1052,6 +1052,10 @@ fn gauge() { Farming::on_initialize(0); System::set_block_number(System::block_number() + 10); + assert_noop!( + Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 2000))), + Error::::GaugeMaxBlockOverflow + ); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), pid, @@ -1085,6 +1089,18 @@ fn gauge() { pid )); assert_eq!(Assets::balance(KSM, &BOB), 9699991); + + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + tokens, + Some((100, 1)) + )); + System::set_block_number(System::block_number() + 200); + assert_noop!( + Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 1))), + Error::::LastGaugeNotClaim + ); }) } From 184438be5939835011bafb8435f148f1a8aa2c43 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Fri, 30 Jun 2023 20:33:03 +0800 Subject: [PATCH 20/26] native token allowdeath Signed-off-by: zqhxuyuan --- pallets/farming/src/lib.rs | 2 + pallets/farming/src/tests.rs | 133 +++++++++++++++++++---------- primitives/manta/src/currencies.rs | 4 +- 3 files changed, 92 insertions(+), 47 deletions(-) diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index f434eacb3..db8f14832 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -238,7 +238,9 @@ pub mod pallet { #[pallet::getter(fn gauge_pool_infos)] pub type GaugePoolInfos = StorageMap<_, Twox64Concat, PoolId, GaugePoolInfoOf>; + /// Record gauge info for specific `AccountId` under `PoolId`. /// + /// double_map (PoolId, AccountId) => GaugeInfo #[pallet::storage] #[pallet::getter(fn gauge_infos)] pub type GaugeInfos = diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 4035004c8..096f34de8 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -294,9 +294,9 @@ fn no_gauge_farming_pool_should_work() { // Stake KSM, get KSM reward let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; let deposit_amount = 1000; - let reward_amount: Balance = 1000; - let basic_rewards = vec![(KSM, 1000)]; - let total_rewards = 300000; + let reward_amount: Balance = 800; + let basic_rewards = vec![(KSM, reward_amount)]; + let total_rewards = 300_000; let alice_init_balance = 3000; assert_eq!(Assets::balance(KSM, &ALICE), alice_init_balance); @@ -359,7 +359,7 @@ fn no_gauge_farming_pool_should_work() { ); System::set_block_number(System::block_number() + 3); - // Deposit failed because Gauge pool is not exist + // Deposit failed because gauge pool is not exist assert_noop!( Farming::deposit( RuntimeOrigin::signed(ALICE), @@ -369,7 +369,7 @@ fn no_gauge_farming_pool_should_work() { ), Error::::GaugePoolNotExist ); - // Deposit success + // Deposit success without gauge info assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), pid, @@ -377,7 +377,7 @@ fn no_gauge_farming_pool_should_work() { None )); - // User staked token transfer to keeper account + // User staked token transfer to keeper account when deposit assert_eq!( Assets::balance(KSM, &ALICE), alice_init_balance - deposit_amount @@ -391,35 +391,35 @@ fn no_gauge_farming_pool_should_work() { assert!(reward.withdraw_list.is_empty()); assert_eq!(reward.claim_last_block, 3); - // The pool state is still on Charged until new block + // The pool state is still on `Charged` until new block produced pool1 = Farming::pool_infos(pid).unwrap(); assert_eq!(pool1.total_shares, deposit_amount); assert_eq!(pool1.state, PoolState::Charged); assert!(pool1.rewards.is_empty()); - // Claim failed because of pool state is still Charged + // Can't Claim if pool state is `Charged` assert_err!( Farming::claim(RuntimeOrigin::signed(ALICE), pid), Error::::InvalidPoolState ); - // OnInitialize hook change the pool state + // OnInitialize hook change the pool state and also pool rewards Farming::on_initialize(System::block_number() + 3); Farming::on_initialize(0); pool1 = Farming::pool_infos(pid).unwrap(); assert_eq!(pool1.total_shares, deposit_amount); assert_eq!(pool1.state, PoolState::Ongoing); assert_eq!(pool1.claim_limit_time, 6); - assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 0)); + assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(reward_amount, 0)); - // new block didn't change the reward info + // Produce new block didn't change the reward info reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); assert_eq!(reward.share, deposit_amount); assert!(reward.withdrawn_rewards.is_empty()); assert!(reward.withdraw_list.is_empty()); assert_eq!(reward.claim_last_block, 3); - // Claim failed because of share info not exist + // Claim failed because of user share info not exist assert_err!( Farming::claim(RuntimeOrigin::signed(BOB), pid), Error::::ShareInfoNotExists @@ -437,15 +437,21 @@ fn no_gauge_farming_pool_should_work() { // Claim success, user get reward. System::set_block_number(System::block_number() + 6); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_eq!( + Assets::balance(KSM, &ALICE), + alice_init_balance - deposit_amount + reward_amount + ); assert_eq!( Assets::balance(KSM, &pool1.reward_issuer), - total_rewards - 1000 + total_rewards - reward_amount ); // Claim operation update pool info's rewards and also share info's withdrawn_rewards pool1 = Farming::pool_infos(pid).unwrap(); - assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 1000)); + assert_eq!( + pool1.rewards.get(&KSM).unwrap(), + &(reward_amount, reward_amount) + ); reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &reward_amount); // The withdraw list of user share info is still empty. @@ -459,22 +465,31 @@ fn no_gauge_farming_pool_should_work() { reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &reward_amount); assert_eq!(reward.claim_last_block, 109 + i * 100); - assert_eq!(reward.share, 1000); + assert_eq!(reward.share, deposit_amount); assert!(reward.withdraw_list.is_empty()); pool1 = Farming::pool_infos(pid).unwrap(); - assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 1000)); - assert_eq!(pool1.total_shares, 1000); + assert_eq!( + pool1.rewards.get(&KSM).unwrap(), + &(reward_amount, reward_amount) + ); + assert_eq!(pool1.total_shares, deposit_amount); - assert_eq!(Assets::balance(KSM, &ALICE), 3000); + assert_eq!( + Assets::balance(KSM, &ALICE), + alice_init_balance - deposit_amount + reward_amount + ); assert_eq!( Assets::balance(KSM, &pool1.reward_issuer), - total_rewards - 1000 + total_rewards - reward_amount ); assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); } - assert_eq!(Assets::balance(KSM, &pool1.reward_issuer), 299000); - assert_eq!(Assets::balance(KSM, &pool1.keeper), 1000); + assert_eq!( + Assets::balance(KSM, &pool1.reward_issuer), + total_rewards - reward_amount + ); + assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); // Claim with new block for i in 1..5 { System::set_block_number(System::block_number() + 6); @@ -484,30 +499,43 @@ fn no_gauge_farming_pool_should_work() { reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); assert_eq!( reward.withdrawn_rewards.get(&KSM).unwrap(), - &(1000 * (i + 1)) + &(reward_amount * (i + 1)) ); assert_eq!(reward.claim_last_block as u128, 509 + i * 6); - assert_eq!(reward.share, 1000); + assert_eq!(reward.share, deposit_amount); assert!(reward.withdraw_list.is_empty()); pool1 = Farming::pool_infos(pid).unwrap(); assert_eq!( pool1.rewards.get(&KSM).unwrap(), - &(1000 * (i + 1), 1000 * (i + 1)) + &(reward_amount * (i + 1), reward_amount * (i + 1)) ); - assert_eq!(pool1.total_shares, 1000); + assert_eq!(pool1.total_shares, deposit_amount); - assert_eq!(Assets::balance(KSM, &ALICE), 3000 + 1000 * i); + assert_eq!( + Assets::balance(KSM, &ALICE), + alice_init_balance - deposit_amount + reward_amount * (i + 1) + ); assert_eq!( Assets::balance(KSM, &pool1.reward_issuer), - total_rewards - 1000 * (i + 1) + total_rewards - reward_amount * (i + 1) ); // Because withdraw_list of user share is empty, keeper not return token to user. assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); } - assert_eq!(Assets::balance(KSM, &pool1.reward_issuer), 295000); - assert_eq!(Assets::balance(KSM, &pool1.keeper), 1000); - assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(5000, 5000)); + assert_eq!( + Assets::balance(KSM, &ALICE), + alice_init_balance - deposit_amount + reward_amount * 5 + ); + assert_eq!( + Assets::balance(KSM, &pool1.reward_issuer), + total_rewards - reward_amount * 5 + ); + assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); + assert_eq!( + pool1.rewards.get(&KSM).unwrap(), + &(reward_amount * 5, reward_amount * 5) + ); // Withdraw failed because of share info not exist. assert_err!( @@ -521,11 +549,14 @@ fn no_gauge_farming_pool_should_work() { assert!(reward.withdraw_list.is_empty()); let share_reward = reward.withdrawn_rewards.get(&KSM).unwrap(); - assert_eq!(share_reward, &(5000)); + assert_eq!(share_reward, &(reward_amount * 5)); let (total_reward, total_withdrawn_reward) = pool1.rewards.get(&KSM).unwrap(); - assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(5000, 5000)); + assert_eq!( + pool1.rewards.get(&KSM).unwrap(), + &(reward_amount * 5, reward_amount * 5) + ); - let reward_amount = Farming::get_reward_amount( + let reward_amount1 = Farming::get_reward_amount( &reward, total_reward, total_withdrawn_reward, @@ -533,21 +564,24 @@ fn no_gauge_farming_pool_should_work() { &KSM, ) .unwrap(); - assert_eq!(reward_amount, (5000, 0)); + assert_eq!(reward_amount1, (reward_amount * 5, 0)); let reward_inflation = Farming::get_reward_inflation(reward.share, total_reward, pool1.total_shares); - assert_eq!(reward_inflation, 5000); + assert_eq!(reward_inflation, reward_amount * 5); let reward_inflation = Farming::get_reward_inflation(800, share_reward, reward.share); - assert_eq!(reward_inflation, 4000); + assert_eq!(reward_inflation, share_reward * 8 / 10); let reward_inflation = Farming::get_reward_inflation(200, share_reward, reward.share); - assert_eq!(reward_inflation, 1000); + assert_eq!(reward_inflation, share_reward * 2 / 10); let reward_inflation = Farming::get_reward_inflation(100, share_reward, reward.share); - assert_eq!(reward_inflation, 500); + assert_eq!(reward_inflation, share_reward / 10); // Withdraw partial tokens assert_eq!(System::block_number(), 533); - assert_eq!(Assets::balance(KSM, &ALICE), 7000); + assert_eq!( + Assets::balance(KSM, &ALICE), + alice_init_balance - deposit_amount + reward_amount * 5 + ); assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), pid, @@ -556,9 +590,15 @@ fn no_gauge_farming_pool_should_work() { // Although withdraw also has claim, but no new rewards due to no new block // So both user and reward issuer account balance not change. - assert_eq!(Assets::balance(KSM, &ALICE), 7000); - assert_eq!(Assets::balance(KSM, &pool1.reward_issuer), 295000); - assert_eq!(Assets::balance(KSM, &pool1.keeper), 1000); + assert_eq!( + Assets::balance(KSM, &ALICE), + alice_init_balance - deposit_amount + reward_amount * 5 + ); + assert_eq!( + Assets::balance(KSM, &pool1.reward_issuer), + total_rewards - reward_amount * 5 + ); + assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); // Withdraw operation has only one operation `remove_share`. // And `remove_share` will claim rewards and also update user share info. @@ -569,8 +609,11 @@ fn no_gauge_farming_pool_should_work() { assert_eq!(pool1.total_shares, 200); assert_eq!(reward.withdraw_list, vec![(533 + withdraw_limit_time, 800)]); assert_eq!(reward.share, 200); - assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &1000); - assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(1000, 1000)); + assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &reward_amount); + assert_eq!( + pool1.rewards.get(&KSM).unwrap(), + &(reward_amount, reward_amount) + ); System::set_block_number(System::block_number() + 6); Farming::on_initialize(System::block_number() + 3); diff --git a/primitives/manta/src/currencies.rs b/primitives/manta/src/currencies.rs index 8af0c8d4c..952a3120c 100644 --- a/primitives/manta/src/currencies.rs +++ b/primitives/manta/src/currencies.rs @@ -125,7 +125,7 @@ where amount: Self::Balance, ) -> DispatchResult { if currency_id == A::NativeAssetId::get() { - Native::transfer(from, to, amount, ExistenceRequirement::KeepAlive)?; + Native::transfer(from, to, amount, ExistenceRequirement::AllowDeath)?; } else { NonNative::transfer(currency_id, from, to, amount, false)?; } @@ -155,7 +155,7 @@ where who, amount, WithdrawReasons::empty(), - ExistenceRequirement::KeepAlive, + ExistenceRequirement::AllowDeath, )?; } else { NonNative::burn_from(currency_id, who, amount)?; From db1f76d24bf375e630eb65bbb0953547854e4731 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 3 Jul 2023 14:40:37 +0800 Subject: [PATCH 21/26] more tests Signed-off-by: zqhxuyuan --- pallets/farming/src/lib.rs | 7 +- pallets/farming/src/mock.rs | 7 +- pallets/farming/src/tests.rs | 485 ++++++++++++++++++++++++++++++++++- 3 files changed, 490 insertions(+), 9 deletions(-) diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index db8f14832..dc5b6e442 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -469,7 +469,8 @@ pub mod pallet { Ok(()) } - /// User can withdraw token from farming pool. This only remove share and get claim rewards. + /// `Withdraw` operation only remove share and get claim rewards, then update `withdraw_list` of user share info. + /// This operation don't withdrawn staked token. #[pallet::call_index(3)] #[pallet::weight(T::WeightInfo::withdraw())] pub fn withdraw( @@ -502,7 +503,7 @@ pub mod pallet { Ok(()) } - /// User can claim rewards and also unStake. + /// `claim` operation can claim rewards and also un-stake if user share info has `withdraw_list`. #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::claim())] pub fn claim(origin: OriginFor, pid: PoolId) -> DispatchResult { @@ -535,7 +536,7 @@ pub mod pallet { Ok(()) } - /// User can unStake token from farm pool. + /// `withdraw_claim` operation will un-stake user staked token on farming pool from keeper account to user account. #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::claim())] pub fn withdraw_claim(origin: OriginFor, pid: PoolId) -> DispatchResult { diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index 471041ee4..65fea7d26 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -53,6 +53,7 @@ pub type AccountId = AccountId32; pub type Balance = u128; pub const KSM: DolphinAssetId = 8; +pub const KMA: DolphinAssetId = 1; pub const ALICE: AccountId = AccountId32::new([0u8; 32]); pub const BOB: AccountId = AccountId32::new([1u8; 32]); @@ -309,11 +310,11 @@ impl ExtBuilder { pub fn one_hundred_for_alice_n_bob(self) -> Self { self.balances(vec![ - (ALICE, 1, 100), - (BOB, 1, 100), + (ALICE, 1, 3000), + (BOB, 1, 400_000), (CHARLIE, 1, 100), (ALICE, KSM, 3000), - (BOB, KSM, 10000000), + (BOB, KSM, 10_000_000), ]) } diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 096f34de8..8ccc92562 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -17,6 +17,7 @@ #![cfg(test)] use frame_support::{assert_err, assert_noop, assert_ok}; +use manta_primitives::types::DolphinAssetId; use sp_runtime::traits::AccountIdConversion; use crate::{mock::*, *}; @@ -431,9 +432,6 @@ fn no_gauge_farming_pool_should_work() { Error::::CanNotClaim ); - pool1 = Farming::pool_infos(pid).unwrap(); - assert_eq!(pool1.total_shares, deposit_amount); - // Claim success, user get reward. System::set_block_number(System::block_number() + 6); assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); @@ -634,6 +632,487 @@ fn no_gauge_farming_pool_should_work() { }) } +#[test] +fn no_gauge_staking_cases_should_work() { + staking_case(KSM, KMA); + staking_case(KMA, KSM); + staking_all_kma(KMA, KSM); +} + +fn staking_all_kma(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let tokens_proportion = vec![(stake_token, Perbill::from_percent(100))]; + // let deposit_amount = 1000; + let reward_amount: Balance = 800; + let basic_rewards = vec![(reward_token, reward_amount)]; + let total_rewards = 300_000; + let alice_init_kma = 3000; + assert_eq!(Balances::free_balance(&ALICE), alice_init_kma); + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + None, + 2, // min_deposit_to_start + 1, // after_block_to_start + 7, // withdraw_limit_time, + 6, // claim_limit_time + 5 // withdraw_limit_count + )); + + // Charge to the pool reward issuer + let pid = 0; + let charge_rewards = vec![(reward_token, total_rewards)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + + System::set_block_number(System::block_number() + 3); + // Deposit success without gauge info + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + alice_init_kma, + None + )); + + let pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(Balances::free_balance(&ALICE), 0); + assert_eq!(Balances::free_balance(&pool1.keeper), alice_init_kma); + + Farming::on_initialize(System::block_number() + 10); + System::set_block_number(System::block_number() + 10); + assert_eq!(Balances::free_balance(&ALICE), 0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Balances::free_balance(&ALICE), 0); + + System::set_block_number(System::block_number() + 10); + assert_ok!(Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, None)); + assert_eq!(Balances::free_balance(&ALICE), 0); + let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.withdraw_list, vec![(30, alice_init_kma)]); + + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Balances::free_balance(&ALICE), 0); + + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Balances::free_balance(&ALICE), alice_init_kma); + assert_eq!(Balances::free_balance(pool1.keeper), 0); + }); +} + +fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let tokens_proportion = vec![(stake_token, Perbill::from_percent(100))]; + let deposit_amount = 1000; + let reward_amount: Balance = 800; + let basic_rewards = vec![(reward_token, reward_amount)]; + let total_rewards = 300_000; + let alice_init_ksm = 3000; + let alice_init_kma = 3000; + assert_eq!(Balances::free_balance(&ALICE), alice_init_kma); + + let withdraw_limit_time = 7; + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + None, + 2, // min_deposit_to_start + 1, // after_block_to_start + withdraw_limit_time, + 6, // claim_limit_time + 5 // withdraw_limit_count + )); + + // Charge to the pool reward issuer + let pid = 0; + let charge_rewards = vec![(reward_token, total_rewards)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pid, + charge_rewards + )); + + let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 0); + assert_eq!(pool1.min_deposit_to_start, 2); + assert_eq!(pool1.state, PoolState::Charged); + assert!(pool1.rewards.is_empty()); + + System::set_block_number(System::block_number() + 3); + // Deposit success without gauge info + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(ALICE), + pid, + deposit_amount, + None + )); + + // User staked token transfer to keeper account when deposit + if stake_token == KSM { + // Stake KSM, reward KMA + assert_eq!( + Assets::balance(stake_token, &ALICE), + alice_init_ksm - deposit_amount + ); + assert_eq!(Assets::balance(stake_token, &pool1.keeper), deposit_amount); + assert_eq!(Balances::free_balance(&ALICE), alice_init_kma); + } else { + // Stake KMA, reward KSM + assert_eq!( + Balances::free_balance(&ALICE), + alice_init_kma - deposit_amount + ); + assert_eq!(Balances::free_balance(&pool1.keeper), deposit_amount); + } + if reward_token == KSM { + // Stake KMA, reward KSM + assert_eq!( + Assets::balance(reward_token, &pool1.reward_issuer), + total_rewards + ); + } else { + // Stake KSM, reward KMA + assert_eq!(Balances::free_balance(&pool1.reward_issuer), total_rewards); + } + + // reward info + let mut reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.share, deposit_amount); + assert!(reward.withdrawn_rewards.is_empty()); + assert!(reward.withdraw_list.is_empty()); + assert_eq!(reward.claim_last_block, 3); + + // The pool state is still on `Charged` until new block produced + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, deposit_amount); + assert_eq!(pool1.state, PoolState::Charged); + assert!(pool1.rewards.is_empty()); + + // OnInitialize hook change the pool state and also pool rewards + Farming::on_initialize(System::block_number() + 3); + Farming::on_initialize(0); + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, deposit_amount); + assert_eq!(pool1.state, PoolState::Ongoing); + assert_eq!(pool1.claim_limit_time, 6); + assert_eq!( + pool1.rewards.get(&reward_token).unwrap(), + &(reward_amount, 0) + ); + + // Produce new block didn't change the reward info + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!(reward.share, deposit_amount); + assert!(reward.withdrawn_rewards.is_empty()); + assert!(reward.withdraw_list.is_empty()); + assert_eq!(reward.claim_last_block, 3); + + // Claim success, user get reward. + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + if reward_token == KSM { + // Stake KMA, reward KSM + assert_eq!( + Assets::balance(reward_token, &ALICE), + alice_init_ksm + reward_amount + ); + assert_eq!( + Assets::balance(reward_token, &pool1.reward_issuer), + total_rewards - reward_amount + ); + } else { + // Stake KSM, reward KMA + assert_eq!( + Balances::free_balance(&ALICE), + alice_init_kma + reward_amount + ); + assert_eq!( + Balances::free_balance(&pool1.reward_issuer), + total_rewards - reward_amount + ); + } + + // Claim operation update pool info's rewards and also share info's withdrawn_rewards + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!( + pool1.rewards.get(&reward_token).unwrap(), + &(reward_amount, reward_amount) + ); + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!( + reward.withdrawn_rewards.get(&reward_token).unwrap(), + &reward_amount + ); + // The withdraw list of user share info is still empty. + assert!(reward.withdraw_list.is_empty()); + + // Claim without new block. + for i in 0..5 { + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!( + reward.withdrawn_rewards.get(&reward_token).unwrap(), + &reward_amount + ); + assert_eq!(reward.claim_last_block, 109 + i * 100); + assert_eq!(reward.share, deposit_amount); + assert!(reward.withdraw_list.is_empty()); + + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!( + pool1.rewards.get(&reward_token).unwrap(), + &(reward_amount, reward_amount) + ); + assert_eq!(pool1.total_shares, deposit_amount); + } + if reward_token == KSM { + // Stake KMA, reward KSM + assert_eq!( + Assets::balance(reward_token, &pool1.reward_issuer), + total_rewards - reward_amount + ); + } else { + // Stake KSM, reward KMA + assert_eq!( + Balances::free_balance(&pool1.reward_issuer), + total_rewards - reward_amount + ); + } + if stake_token == KSM { + assert_eq!(Assets::balance(stake_token, &pool1.keeper), deposit_amount); + } else { + assert_eq!(Balances::free_balance(&pool1.keeper), deposit_amount); + } + + // Claim with new block + for i in 1..5 { + System::set_block_number(System::block_number() + 6); + Farming::on_initialize(System::block_number() + 3); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + assert_eq!( + reward.withdrawn_rewards.get(&reward_token).unwrap(), + &(reward_amount * (i + 1)) + ); + assert_eq!(reward.claim_last_block as u128, 509 + i * 6); + assert_eq!(reward.share, deposit_amount); + assert!(reward.withdraw_list.is_empty()); + + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!( + pool1.rewards.get(&reward_token).unwrap(), + &(reward_amount * (i + 1), reward_amount * (i + 1)) + ); + assert_eq!(pool1.total_shares, deposit_amount); + } + if reward_token == KSM { + // Stake KMA, reward another 4 times KSM + assert_eq!( + Assets::balance(reward_token, &ALICE), + alice_init_ksm + reward_amount * 5 + ); + assert_eq!( + Assets::balance(reward_token, &pool1.reward_issuer), + total_rewards - reward_amount * 5 + ); + } else { + // Stake KSM, reward another 4 times KMA + assert_eq!( + Balances::free_balance(&ALICE), + alice_init_kma + reward_amount * 5 + ); + assert_eq!( + Balances::free_balance(&pool1.reward_issuer), + total_rewards - reward_amount * 5 + ); + } + if stake_token == KSM { + assert_eq!(Assets::balance(stake_token, &pool1.keeper), deposit_amount); + } else { + assert_eq!(Balances::free_balance(&pool1.keeper), deposit_amount); + } + assert_eq!( + pool1.rewards.get(&reward_token).unwrap(), + &(reward_amount * 5, reward_amount * 5) + ); + + // Withdraw failed because of share info not exist. + assert_err!( + Farming::withdraw(RuntimeOrigin::signed(BOB), pid, Some(800)), + Error::::ShareInfoNotExists + ); + + // Claim again without new blocks, no new rewards + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pid).unwrap(); + assert!(reward.withdraw_list.is_empty()); + + let share_reward = reward.withdrawn_rewards.get(&reward_token).unwrap(); + assert_eq!(share_reward, &(reward_amount * 5)); + let (total_reward, total_withdrawn_reward) = pool1.rewards.get(&reward_token).unwrap(); + assert_eq!( + pool1.rewards.get(&reward_token).unwrap(), + &(reward_amount * 5, reward_amount * 5) + ); + + let reward_amount1 = Farming::get_reward_amount( + &reward, + total_reward, + total_withdrawn_reward, + pool1.total_shares, + &reward_token, + ) + .unwrap(); + assert_eq!(reward_amount1, (reward_amount * 5, 0)); + let reward_inflation = + Farming::get_reward_inflation(reward.share, total_reward, pool1.total_shares); + assert_eq!(reward_inflation, reward_amount * 5); + + let reward_inflation = Farming::get_reward_inflation(800, share_reward, reward.share); + assert_eq!(reward_inflation, share_reward * 8 / 10); + let reward_inflation = Farming::get_reward_inflation(200, share_reward, reward.share); + assert_eq!(reward_inflation, share_reward * 2 / 10); + let reward_inflation = Farming::get_reward_inflation(100, share_reward, reward.share); + assert_eq!(reward_inflation, share_reward / 10); + + // Withdraw partial tokens + assert_eq!(System::block_number(), 533); + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(800) + )); + // Although withdraw also has claim, but no new rewards due to no new block + // So both user and reward issuer account balance not change. + if reward_token == KSM { + // Stake KMA, reward KSM + assert_eq!( + Assets::balance(reward_token, &ALICE), + alice_init_ksm + reward_amount * 5 + ); + assert_eq!( + Assets::balance(reward_token, &pool1.reward_issuer), + total_rewards - reward_amount * 5 + ); + } else { + // Stake KSM, reward KMA + assert_eq!( + Balances::free_balance(&ALICE), + alice_init_kma + reward_amount * 5 + ); + assert_eq!( + Balances::free_balance(&pool1.reward_issuer), + total_rewards - reward_amount * 5 + ); + } + if stake_token == KSM { + assert_eq!(Assets::balance(stake_token, &pool1.keeper), deposit_amount); + } else { + assert_eq!(Balances::free_balance(&pool1.keeper), deposit_amount); + } + + // Withdraw operation has only one operation `remove_share`. + // And `remove_share` will claim rewards and also update user share info. + // We already know that due to no new block, claim rewards actually has no reward. + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pid).unwrap(); + + assert_eq!(pool1.total_shares, 200); + assert_eq!(reward.withdraw_list, vec![(533 + withdraw_limit_time, 800)]); + assert_eq!(reward.share, 200); + assert_eq!( + reward.withdrawn_rewards.get(&reward_token).unwrap(), + &reward_amount + ); + assert_eq!( + pool1.rewards.get(&reward_token).unwrap(), + &(reward_amount, reward_amount) + ); + + System::set_block_number(System::block_number() + 6); + Farming::on_initialize(System::block_number() + 3); + + // Withdraw rest all of share + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pid, + Some(300) + )); + reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pid).unwrap(); + assert_eq!(pool1.total_shares, 0); + assert!(pool1.rewards.is_empty()); + assert_eq!(reward.share, 0); + assert_eq!(reward.withdraw_list, vec![(540, 800), (546, 200)]); + assert_eq!(reward.withdrawn_rewards.get(&reward_token).unwrap(), &0); + if reward_token == KSM { + // Stake KMA, reward KSM + assert_eq!( + Assets::balance(reward_token, &ALICE), + alice_init_ksm + reward_amount * 6 + ); + assert_eq!( + Assets::balance(reward_token, &pool1.reward_issuer), + total_rewards - reward_amount * 6 + ); + } else { + // Stake KSM, reward KMA + assert_eq!( + Balances::free_balance(&ALICE), + alice_init_kma + reward_amount * 6 + ); + assert_eq!( + Balances::free_balance(&pool1.reward_issuer), + total_rewards - reward_amount * 6 + ); + } + if stake_token == KSM { + // Stake KSM, reward KMA + assert_eq!(Assets::balance(stake_token, &pool1.keeper), deposit_amount); + } else { + // Stake KMA, reward KSM + assert_eq!(Balances::free_balance(&pool1.keeper), deposit_amount); + } + + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + if stake_token == KSM { + // Stake KSM, reward KMA + assert_eq!(Assets::balance(stake_token, &pool1.keeper), 200); + } else { + // Stake KMA, reward KSM + assert_eq!(Balances::free_balance(&pool1.keeper), 200); + } + + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + if stake_token == KSM { + // Stake KSM, reward KMA + assert_eq!(Assets::balance(stake_token, &pool1.keeper), 0); + } else { + // Stake KMA, reward KSM + assert_eq!(Balances::free_balance(&pool1.keeper), 0); + } + }) +} + #[test] fn gauge_farming_pool_should_work() { ExtBuilder::default() From 44cb6a5f2129d0d047c1e53b3f7a3a13f137ab56 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 3 Jul 2023 19:40:40 +0800 Subject: [PATCH 22/26] address comments Signed-off-by: zqhxuyuan --- Cargo.lock | 112 +++++++++--------- node/Cargo.toml | 4 +- node/src/rpc/calamari.rs | 4 +- node/src/rpc/manta.rs | 4 +- pallets/farming/Cargo.toml | 2 +- pallets/farming/rpc/Cargo.toml | 4 +- pallets/farming/rpc/runtime-api/Cargo.toml | 2 +- pallets/farming/rpc/src/lib.rs | 2 +- pallets/farming/src/gauge.rs | 33 ++++-- pallets/farming/src/lib.rs | 22 ++-- pallets/farming/src/mock.rs | 6 +- pallets/farming/src/tests.rs | 15 +++ pallets/farming/src/weights.rs | 8 +- runtime/calamari/Cargo.toml | 12 +- runtime/calamari/src/lib.rs | 10 +- runtime/calamari/src/weights/mod.rs | 2 +- .../{manta_farming.rs => pallet_farming.rs} | 12 +- runtime/manta/Cargo.toml | 12 +- runtime/manta/src/lib.rs | 10 +- runtime/manta/src/weights/mod.rs | 2 +- .../{manta_farming.rs => pallet_farming.rs} | 12 +- 21 files changed, 161 insertions(+), 129 deletions(-) rename runtime/calamari/src/weights/{manta_farming.rs => pallet_farming.rs} (95%) rename runtime/manta/src/weights/{manta_farming.rs => pallet_farming.rs} (95%) diff --git a/Cargo.lock b/Cargo.lock index 3799124c8..90c4bb410 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1118,8 +1118,6 @@ dependencies = [ "lazy_static", "log", "manta-collator-selection", - "manta-farming", - "manta-farming-rpc-runtime-api", "manta-primitives", "nimbus-primitives", "orml-traits", @@ -1133,6 +1131,8 @@ dependencies = [ "pallet-balances", "pallet-collective", "pallet-democracy", + "pallet-farming", + "pallet-farming-rpc-runtime-api", "pallet-manta-pay", "pallet-manta-sbt", "pallet-manta-support", @@ -5368,13 +5368,13 @@ dependencies = [ "hex-literal", "jsonrpsee", "log", - "manta-farming-rpc-api", - "manta-farming-rpc-runtime-api", "manta-primitives", "manta-runtime", "nimbus-consensus", "nimbus-primitives", "pallet-author-inherent", + "pallet-farming-rpc-api", + "pallet-farming-rpc-runtime-api", "pallet-manta-pay", "pallet-manta-sbt", "pallet-parachain-staking", @@ -5503,56 +5503,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "manta-farming" -version = "4.2.0" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "hex-literal", - "log", - "manta-primitives", - "orml-traits", - "pallet-asset-manager", - "pallet-assets", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", -] - -[[package]] -name = "manta-farming-rpc-api" -version = "4.2.0" -dependencies = [ - "jsonrpsee", - "manta-farming-rpc-runtime-api", - "manta-primitives", - "parity-scale-codec", - "serde", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-rpc", - "sp-runtime", -] - -[[package]] -name = "manta-farming-rpc-runtime-api" -version = "4.2.0" -dependencies = [ - "manta-primitives", - "parity-scale-codec", - "sp-api", - "sp-std", -] - [[package]] name = "manta-parameters" version = "0.5.15" @@ -5628,8 +5578,6 @@ dependencies = [ "hex-literal", "log", "manta-collator-selection", - "manta-farming", - "manta-farming-rpc-runtime-api", "manta-primitives", "nimbus-primitives", "orml-traits", @@ -5643,6 +5591,8 @@ dependencies = [ "pallet-balances", "pallet-collective", "pallet-democracy", + "pallet-farming", + "pallet-farming-rpc-runtime-api", "pallet-manta-pay", "pallet-manta-sbt", "pallet-manta-support", @@ -6942,6 +6892,56 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-farming" +version = "4.2.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "hex-literal", + "log", + "manta-primitives", + "orml-traits", + "pallet-asset-manager", + "pallet-assets", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", +] + +[[package]] +name = "pallet-farming-rpc-api" +version = "4.2.0" +dependencies = [ + "jsonrpsee", + "manta-primitives", + "pallet-farming-rpc-runtime-api", + "parity-scale-codec", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", +] + +[[package]] +name = "pallet-farming-rpc-runtime-api" +version = "4.2.0" +dependencies = [ + "manta-primitives", + "parity-scale-codec", + "sp-api", + "sp-std", +] + [[package]] name = "pallet-fast-unstake" version = "4.0.0-dev" diff --git a/node/Cargo.toml b/node/Cargo.toml index 8ddfcb084..72f24d705 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -36,8 +36,8 @@ jsonrpsee = { version = "0.16.2", features = ["server"] } pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" } -manta-farming-rpc-api = { path = "../pallets/farming/rpc" } -manta-farming-rpc-runtime-api = { path = "../pallets/farming/rpc/runtime-api" } +pallet-farming-rpc-api = { path = "../pallets/farming/rpc" } +pallet-farming-rpc-runtime-api = { path = "../pallets/farming/rpc/runtime-api" } zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" } zenlink-protocol-rpc = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" } zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" } diff --git a/node/src/rpc/calamari.rs b/node/src/rpc/calamari.rs index 8aa9bcf47..a9783902a 100644 --- a/node/src/rpc/calamari.rs +++ b/node/src/rpc/calamari.rs @@ -17,9 +17,9 @@ //! Calamari RPC Extensions use super::*; -use manta_farming_rpc_api::{FarmingRpc, FarmingRpcApiServer}; -use manta_farming_rpc_runtime_api::FarmingRuntimeApi; use manta_primitives::types::{CalamariAssetId, PoolId}; +use pallet_farming_rpc_api::{FarmingRpc, FarmingRpcApiServer}; +use pallet_farming_rpc_runtime_api::FarmingRuntimeApi; use pallet_manta_pay::{ rpc::{Pull, PullApiServer}, runtime::PullLedgerDiffApi, diff --git a/node/src/rpc/manta.rs b/node/src/rpc/manta.rs index 455fea364..accc6b925 100644 --- a/node/src/rpc/manta.rs +++ b/node/src/rpc/manta.rs @@ -17,9 +17,9 @@ //! Manta RPC Extensions use super::*; -use manta_farming_rpc_api::{FarmingRpc, FarmingRpcApiServer}; -use manta_farming_rpc_runtime_api::FarmingRuntimeApi; use manta_primitives::types::{MantaAssetId, PoolId}; +use pallet_farming_rpc_api::{FarmingRpc, FarmingRpcApiServer}; +use pallet_farming_rpc_runtime_api::FarmingRuntimeApi; use pallet_manta_pay::{ rpc::{Pull, PullApiServer}, runtime::PullLedgerDiffApi, diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 8d3bc337e..5be9998c3 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -4,7 +4,7 @@ description = 'Pallet implementing farming protocol.' edition = "2021" homepage = "https://manta.network" license = "GPL-3.0" -name = "manta-farming" +name = "pallet-farming" repository = 'https://github.com/Manta-Network/Manta/' version = "4.2.0" diff --git a/pallets/farming/rpc/Cargo.toml b/pallets/farming/rpc/Cargo.toml index 0cb5a08ab..b8d480a12 100644 --- a/pallets/farming/rpc/Cargo.toml +++ b/pallets/farming/rpc/Cargo.toml @@ -3,7 +3,7 @@ authors = ['Manta Network'] edition = "2021" homepage = "https://manta.network" license = "GPL-3.0" -name = "manta-farming-rpc-api" +name = "pallet-farming-rpc-api" repository = 'https://github.com/Manta-Network/Manta/' version = "4.2.0" @@ -18,5 +18,5 @@ sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot- sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" } -manta-farming-rpc-runtime-api = { path = "./runtime-api" } manta-primitives = { path = '../../../primitives/manta', default-features = false } +pallet-farming-rpc-runtime-api = { path = "./runtime-api" } diff --git a/pallets/farming/rpc/runtime-api/Cargo.toml b/pallets/farming/rpc/runtime-api/Cargo.toml index 49219a8a1..3eeaab175 100644 --- a/pallets/farming/rpc/runtime-api/Cargo.toml +++ b/pallets/farming/rpc/runtime-api/Cargo.toml @@ -3,7 +3,7 @@ authors = ['Manta Network'] edition = "2021" homepage = "https://manta.network" license = "GPL-3.0" -name = "manta-farming-rpc-runtime-api" +name = "pallet-farming-rpc-runtime-api" repository = 'https://github.com/Manta-Network/Manta/' version = "4.2.0" diff --git a/pallets/farming/rpc/src/lib.rs b/pallets/farming/rpc/src/lib.rs index 5aadff978..26a0f4da5 100644 --- a/pallets/farming/rpc/src/lib.rs +++ b/pallets/farming/rpc/src/lib.rs @@ -22,8 +22,8 @@ use jsonrpsee::{ proc_macros::rpc, types::error::{CallError, ErrorCode, ErrorObject}, }; -pub use manta_farming_rpc_runtime_api::{self as runtime_api, FarmingRuntimeApi}; use manta_primitives::types::Balance; +pub use pallet_farming_rpc_runtime_api::{self as runtime_api, FarmingRuntimeApi}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_rpc::number::NumberOrHex; diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 36f979890..71d4c3645 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -225,7 +225,12 @@ where .ok_or(ArithmeticError::Overflow)?; let time_factor_b = gauge_block .saturated_into::() - .checked_mul((gauge_value + gauge_info.gauge_amount).saturated_into::()) + .checked_mul( + (gauge_value + .checked_add(&gauge_info.gauge_amount) + .ok_or(ArithmeticError::Overflow)?) + .saturated_into::(), + ) .ok_or(ArithmeticError::Overflow)?; let increase_total_time_factor = time_factor_a + time_factor_b; gauge_info.total_time_factor = gauge_info @@ -293,7 +298,7 @@ where -> DispatchResult { let reward = reward_amount .checked_sub(total_gauged_reward) - .ok_or(ArithmeticError::Overflow)?; + .ok_or(ArithmeticError::Underflow)?; // gauge_reward = gauge rate * gauge rewards * existing rewards let gauge_reward = gauge_rate * reward; // reward_to_claim = farming rate * gauge_reward @@ -330,11 +335,11 @@ where gauge_pool_info.total_time_factor = gauge_pool_info .total_time_factor .checked_sub(gauge_info.total_time_factor) - .ok_or(ArithmeticError::Overflow)?; + .ok_or(ArithmeticError::Underflow)?; gauge_pool_info.gauge_amount = gauge_pool_info .gauge_amount .checked_sub(&gauge_info.gauge_amount) - .ok_or(ArithmeticError::Overflow)?; + .ok_or(ArithmeticError::Underflow)?; } else { *maybe_gauge_info = Some(gauge_info); }; @@ -371,7 +376,7 @@ where -> DispatchResult { let reward = reward_amount .checked_sub(total_gauged_reward) - .ok_or(ArithmeticError::Overflow)?; + .ok_or(ArithmeticError::Underflow)?; // gauge_reward = gauge rate * gauge rewards * existing rewards let gauge_reward = gauge_rate * reward; // reward_to_claim = farming rate * gauge_reward @@ -400,12 +405,18 @@ where current_block_number }; - let latest_claimed_time_factor = gauge_info.latest_time_factor - + gauge_info - .gauge_amount - .saturated_into::() - .checked_mul((start_block - gauge_info.gauge_last_block).saturated_into::()) - .ok_or(ArithmeticError::Overflow)?; + let latest_claimed_time_factor = gauge_info + .latest_time_factor + .checked_add( + gauge_info + .gauge_amount + .saturated_into::() + .checked_mul( + (start_block - gauge_info.gauge_last_block).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?, + ) + .ok_or(ArithmeticError::Overflow)?; let gauge_rate = Perbill::from_rational( latest_claimed_time_factor - gauge_info.claimed_time_factor, gauge_pool_info.total_time_factor, diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index dc5b6e442..647c540b9 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -187,6 +187,8 @@ pub mod pallet { #[pallet::error] pub enum Error { + /// Pool parameter is invalid + InvalidPoolParameter, /// Pool not exist PoolDoesNotExist, /// Gauge pool not exist @@ -331,6 +333,10 @@ pub mod pallet { let pid = Self::pool_next_id(); let keeper = T::Keeper::get().into_sub_account_truncating(pid); let reward_issuer = T::RewardIssuer::get().into_sub_account_truncating(pid); + ensure!( + !tokens_proportion.is_empty(), + Error::::InvalidPoolParameter + ); let basic_token = tokens_proportion[0]; let tokens_proportion_map: BTreeMap, Perbill> = tokens_proportion.into_iter().map(|(k, v)| (k, v)).collect(); @@ -553,7 +559,7 @@ pub mod pallet { } #[pallet::call_index(6)] - #[pallet::weight(0)] + #[pallet::weight(1000)] pub fn close_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -571,7 +577,7 @@ pub mod pallet { } #[pallet::call_index(7)] - #[pallet::weight(0)] + #[pallet::weight(1000)] pub fn set_retire_limit(origin: OriginFor, limit: u32) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -584,7 +590,7 @@ pub mod pallet { } #[pallet::call_index(8)] - #[pallet::weight(0)] + #[pallet::weight(1000)] pub fn retire_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -630,7 +636,7 @@ pub mod pallet { } #[pallet::call_index(9)] - #[pallet::weight(0)] + #[pallet::weight(1000)] pub fn reset_pool( origin: OriginFor, pid: PoolId, @@ -696,7 +702,7 @@ pub mod pallet { } #[pallet::call_index(10)] - #[pallet::weight(0)] + #[pallet::weight(1000)] pub fn kill_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -714,7 +720,7 @@ pub mod pallet { } #[pallet::call_index(11)] - #[pallet::weight(0)] + #[pallet::weight(1000)] pub fn edit_pool( origin: OriginFor, pid: PoolId, @@ -794,7 +800,7 @@ pub mod pallet { gauge_pool_info.total_time_factor = gauge_pool_info .total_time_factor .checked_sub(gauge_info.total_time_factor) - .ok_or(ArithmeticError::Overflow)?; + .ok_or(ArithmeticError::Underflow)?; GaugePoolInfos::::insert(gid, gauge_pool_info); } else { *maybe_gauge_info = Some(gauge_info); @@ -810,7 +816,7 @@ pub mod pallet { } #[pallet::call_index(13)] - #[pallet::weight(0)] + #[pallet::weight(1000)] pub fn force_gauge_claim(origin: OriginFor, gid: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index 65fea7d26..c04dffd06 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -47,7 +47,7 @@ use xcm::{ VersionedMultiLocation, }; -use crate as manta_farming; +use crate as pallet_farming; pub type AccountId = AccountId32; pub type Balance = u128; @@ -70,7 +70,7 @@ frame_support::construct_runtime!( Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Assets: pallet_assets::{Pallet, Storage, Config, Event}, AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event}, - Farming: manta_farming::{Pallet, Call, Storage, Event} + Farming: pallet_farming::{Pallet, Call, Storage, Event} } ); @@ -283,7 +283,7 @@ ord_parameter_types! { type MantaCurrencies = Currencies; -impl manta_farming::Config for Runtime { +impl pallet_farming::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CurrencyId = CalamariAssetId; type MultiCurrency = MantaCurrencies; diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 8ccc92562..84239f13b 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -141,6 +141,21 @@ fn precondition_check_should_work() { let pid = 1; let charge_rewards = vec![(KSM, 300000)]; + assert_noop!( + Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + vec![], + vec![(KSM, 1000)], + None, + 0, // min_deposit_to_start + 0, // after_block_to_start + 10, // withdraw_limit_time + 0, // claim_limit_time + 1 // withdraw_limit_count + ), + Error::::InvalidPoolParameter + ); + assert_noop!( Farming::charge(RuntimeOrigin::signed(BOB), pid, charge_rewards), Error::::PoolDoesNotExist diff --git a/pallets/farming/src/weights.rs b/pallets/farming/src/weights.rs index 7dfab7a0c..456781032 100644 --- a/pallets/farming/src/weights.rs +++ b/pallets/farming/src/weights.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Manta. If not, see . -//! Autogenerated weights for manta_farming +//! Autogenerated weights for pallet_farming //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-05-14, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -25,7 +25,7 @@ // benchmark // pallet // --chain=dolphin-dev -// --pallet=manta-farming +// --pallet=pallet-farming // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -44,7 +44,7 @@ use frame_support::{traits::Get, weights::Weight}; use sp_std::marker::PhantomData; use manta_primitives::constants::RocksDbWeight; -/// Weight functions needed for manta_farming. +/// Weight functions needed for pallet_farming. pub trait WeightInfo { fn on_initialize() -> Weight; fn create_farming_pool() -> Weight; @@ -55,7 +55,7 @@ pub trait WeightInfo { fn gauge_withdraw() -> Weight; } -/// Weights for manta_farming using the Substrate node and recommended hardware. +/// Weights for pallet_farming using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { // Storage: Farming PoolInfos (r:1 w:0) diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 4b4531d3a..59c82a957 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -87,11 +87,11 @@ xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', default-fea # Self dependencies calamari-vesting = { path = '../../pallets/vesting', default-features = false } manta-collator-selection = { path = '../../pallets/collator-selection', default-features = false } -manta-farming = { path = '../../pallets/farming', default-features = false } -manta-farming-rpc-runtime-api = { path = '../../pallets/farming/rpc/runtime-api', default-features = false } manta-primitives = { path = '../../primitives/manta', default-features = false } manta-support = { package = "pallet-manta-support", path = "../../pallets/manta-support", default-features = false } pallet-asset-manager = { path = '../../pallets/asset-manager', default-features = false } +pallet-farming = { path = '../../pallets/farming', default-features = false } +pallet-farming-rpc-runtime-api = { path = '../../pallets/farming/rpc/runtime-api', default-features = false } pallet-manta-pay = { path = '../../pallets/manta-pay', default-features = false, features = ["runtime"] } pallet-manta-sbt = { path = '../../pallets/manta-sbt', default-features = false, features = ["runtime"] } pallet-name-service = { path = '../../pallets/name-service', default-features = false } @@ -167,7 +167,7 @@ runtime-benchmarks = [ 'pallet-manta-sbt/runtime-benchmarks', 'pallet-name-service/runtime-benchmarks', "zenlink-protocol/runtime-benchmarks", - 'manta-farming/runtime-benchmarks', + 'pallet-farming/runtime-benchmarks', ] try-runtime = [ 'frame-try-runtime', @@ -208,7 +208,7 @@ try-runtime = [ 'pallet-manta-sbt/try-runtime', 'pallet-name-service/try-runtime', "zenlink-protocol/try-runtime", - "manta-farming/try-runtime", + "pallet-farming/try-runtime", ] # Set timing constants (e.g. session period) to faster versions to speed up testing. fast-runtime = [] @@ -282,8 +282,8 @@ std = [ 'manta-support/std', "zenlink-protocol/std", "zenlink-protocol-runtime-api/std", - "manta-farming/std", - "manta-farming-rpc-runtime-api/std", + "pallet-farming/std", + "pallet-farming-rpc-runtime-api/std", ] # A feature that should be enabled when the runtime should be build for on-chain # deployment. This will disable stuff that shouldn't be part of the on-chain wasm diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index 7c8edce24..688272c39 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -808,7 +808,7 @@ parameter_types! { /// Zenlink protocol Asset adaptor for orml_traits::MultiCurrency. type MantaCurrencies = Currencies; -impl manta_farming::Config for Runtime { +impl pallet_farming::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CurrencyId = CalamariAssetId; type MultiCurrency = MantaCurrencies; @@ -819,7 +819,7 @@ impl manta_farming::Config for Runtime { type TreasuryAccount = TreasuryAccount; type Keeper = FarmingKeeperPalletId; type RewardIssuer = FarmingRewardIssuerPalletId; - type WeightInfo = weights::manta_farming::SubstrateWeight; + type WeightInfo = weights::pallet_farming::SubstrateWeight; } parameter_types! { @@ -904,7 +904,7 @@ construct_runtime!( // Calamari stuff CalamariVesting: calamari_vesting::{Pallet, Call, Storage, Event} = 50, ZenlinkProtocol: zenlink_protocol::{Pallet, Call, Storage, Event} = 51, - Farming: manta_farming::{Pallet, Call, Storage, Event} = 54, + Farming: pallet_farming::{Pallet, Call, Storage, Event} = 54, } ); @@ -977,7 +977,7 @@ mod benches { [pallet_name_service, NameService] // Dex [zenlink_protocol, ZenlinkProtocol] - [manta_farming, Farming] + [pallet_farming, Farming] // XCM [cumulus_pallet_xcmp_queue, XcmpQueue] [pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::] @@ -1236,7 +1236,7 @@ impl_runtime_apis! { } } - impl manta_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { + impl pallet_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { fn get_farming_rewards(who: AccountId, pid: PoolId) -> Vec<(CalamariAssetId, Balance)> { Farming::get_farming_rewards(&who, pid).unwrap_or(Vec::new()) } diff --git a/runtime/calamari/src/weights/mod.rs b/runtime/calamari/src/weights/mod.rs index b4e579a6e..eeb78ff82 100644 --- a/runtime/calamari/src/weights/mod.rs +++ b/runtime/calamari/src/weights/mod.rs @@ -20,13 +20,13 @@ pub mod calamari_vesting; pub mod cumulus_pallet_xcmp_queue; pub mod frame_system; pub mod manta_collator_selection; -pub mod manta_farming; pub mod pallet_asset_manager; pub mod pallet_assets; pub mod pallet_author_inherent; pub mod pallet_balances; pub mod pallet_collective; pub mod pallet_democracy; +pub mod pallet_farming; pub mod pallet_manta_pay; pub mod pallet_manta_sbt; pub mod pallet_membership; diff --git a/runtime/calamari/src/weights/manta_farming.rs b/runtime/calamari/src/weights/pallet_farming.rs similarity index 95% rename from runtime/calamari/src/weights/manta_farming.rs rename to runtime/calamari/src/weights/pallet_farming.rs index aa02e995d..d74011ccf 100644 --- a/runtime/calamari/src/weights/manta_farming.rs +++ b/runtime/calamari/src/weights/pallet_farming.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Manta. If not, see . -//! Autogenerated weights for manta_farming +//! Autogenerated weights for pallet_farming //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-06-05, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -25,13 +25,13 @@ // benchmark // pallet // --chain=calamari-dev -// --pallet=manta_farming +// --pallet=pallet_farming // --extrinsic=* // --heap-pages=4096 // --repeat=1 // --steps=1 // --template=.github/resources/frame-weight-template.hbs -// --output=manta-farming.rs +// --output=pallet-farming.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -42,7 +42,7 @@ use frame_support::{traits::Get, weights::Weight}; use sp_std::marker::PhantomData; use manta_primitives::constants::RocksDbWeight; -/// Weight functions needed for manta_farming. +/// Weight functions needed for pallet_farming. pub trait WeightInfo { fn on_initialize() -> Weight; fn create_farming_pool() -> Weight; @@ -53,9 +53,9 @@ pub trait WeightInfo { fn gauge_withdraw() -> Weight; } -/// Weights for manta_farming using the Substrate node and recommended hardware. +/// Weights for pallet_farming using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl manta_farming::WeightInfo for SubstrateWeight { +impl pallet_farming::WeightInfo for SubstrateWeight { // Storage: Farming PoolInfos (r:1 w:0) // Storage: Farming GaugePoolInfos (r:1 w:0) fn on_initialize() -> Weight { diff --git a/runtime/manta/Cargo.toml b/runtime/manta/Cargo.toml index a33b1bf86..0aa90d3db 100644 --- a/runtime/manta/Cargo.toml +++ b/runtime/manta/Cargo.toml @@ -93,11 +93,11 @@ zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink # Self dependencies manta-collator-selection = { path = '../../pallets/collator-selection', default-features = false } -manta-farming = { path = '../../pallets/farming', default-features = false } -manta-farming-rpc-runtime-api = { path = '../../pallets/farming/rpc/runtime-api', default-features = false } manta-primitives = { path = '../../primitives/manta', default-features = false } manta-support = { package = "pallet-manta-support", path = "../../pallets/manta-support", default-features = false } pallet-asset-manager = { path = '../../pallets/asset-manager', default-features = false } +pallet-farming = { path = '../../pallets/farming', default-features = false } +pallet-farming-rpc-runtime-api = { path = '../../pallets/farming/rpc/runtime-api', default-features = false } pallet-manta-pay = { path = '../../pallets/manta-pay', default-features = false, features = ["runtime"] } pallet-manta-sbt = { path = '../../pallets/manta-sbt', default-features = false, features = ["runtime"] } pallet-parachain-staking = { path = '../../pallets/parachain-staking', default-features = false } @@ -154,7 +154,7 @@ runtime-benchmarks = [ 'pallet-xcm-benchmarks/runtime-benchmarks', 'pallet-manta-sbt/runtime-benchmarks', "zenlink-protocol/runtime-benchmarks", - 'manta-farming/runtime-benchmarks', + 'pallet-farming/runtime-benchmarks', ] try-runtime = [ 'frame-try-runtime', @@ -195,7 +195,7 @@ try-runtime = [ 'orml-xtokens/try-runtime', 'pallet-manta-sbt/try-runtime', "zenlink-protocol/try-runtime", - "manta-farming/try-runtime", + "pallet-farming/try-runtime", ] # Set timing constants (e.g. session period) to faster versions to speed up testing. fast-runtime = [] @@ -269,8 +269,8 @@ std = [ 'manta-support/std', "zenlink-protocol/std", "zenlink-protocol-runtime-api/std", - "manta-farming/std", - "manta-farming-rpc-runtime-api/std", + "pallet-farming/std", + "pallet-farming-rpc-runtime-api/std", ] # A feature that should be enabled when the runtime should be build for on-chain # deployment. This will disable stuff that shouldn't be part of the on-chain wasm diff --git a/runtime/manta/src/lib.rs b/runtime/manta/src/lib.rs index 3e258d3ab..d278872f5 100644 --- a/runtime/manta/src/lib.rs +++ b/runtime/manta/src/lib.rs @@ -769,7 +769,7 @@ parameter_types! { /// Zenlink protocol Asset adaptor for orml_traits::MultiCurrency. type MantaCurrencies = Currencies; -impl manta_farming::Config for Runtime { +impl pallet_farming::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CurrencyId = MantaAssetId; type MultiCurrency = MantaCurrencies; @@ -780,7 +780,7 @@ impl manta_farming::Config for Runtime { type TreasuryAccount = TreasuryAccount; type Keeper = FarmingKeeperPalletId; type RewardIssuer = FarmingRewardIssuerPalletId; - type WeightInfo = weights::manta_farming::SubstrateWeight; + type WeightInfo = weights::pallet_farming::SubstrateWeight; } // Create the runtime by composing the FRAME pallets that were previously configured. @@ -846,7 +846,7 @@ construct_runtime!( MantaSbt: pallet_manta_sbt::{Pallet, Call, Storage, Event} = 49, ZenlinkProtocol: zenlink_protocol::{Pallet, Call, Storage, Event} = 51, - Farming: manta_farming::{Pallet, Call, Storage, Event} = 54, + Farming: pallet_farming::{Pallet, Call, Storage, Event} = 54, } ); @@ -920,7 +920,7 @@ mod benches { [pallet_manta_pay, MantaPay] [pallet_manta_sbt, MantaSbt] [zenlink_protocol, ZenlinkProtocol] - [manta_farming, Farming] + [pallet_farming, Farming] // Nimbus pallets [pallet_author_inherent, AuthorInherent] ); @@ -1183,7 +1183,7 @@ impl_runtime_apis! { } } - impl manta_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { + impl pallet_farming_rpc_runtime_api::FarmingRuntimeApi for Runtime { fn get_farming_rewards(who: AccountId, pid: PoolId) -> Vec<(MantaAssetId, Balance)> { Farming::get_farming_rewards(&who, pid).unwrap_or(Vec::new()) } diff --git a/runtime/manta/src/weights/mod.rs b/runtime/manta/src/weights/mod.rs index 3be189619..27616a0fe 100644 --- a/runtime/manta/src/weights/mod.rs +++ b/runtime/manta/src/weights/mod.rs @@ -19,13 +19,13 @@ pub mod cumulus_pallet_xcmp_queue; pub mod frame_system; pub mod manta_collator_selection; -pub mod manta_farming; pub mod pallet_asset_manager; pub mod pallet_assets; pub mod pallet_author_inherent; pub mod pallet_balances; pub mod pallet_collective; pub mod pallet_democracy; +pub mod pallet_farming; pub mod pallet_manta_pay; pub mod pallet_manta_sbt; pub mod pallet_membership; diff --git a/runtime/manta/src/weights/manta_farming.rs b/runtime/manta/src/weights/pallet_farming.rs similarity index 95% rename from runtime/manta/src/weights/manta_farming.rs rename to runtime/manta/src/weights/pallet_farming.rs index aa02e995d..d74011ccf 100644 --- a/runtime/manta/src/weights/manta_farming.rs +++ b/runtime/manta/src/weights/pallet_farming.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Manta. If not, see . -//! Autogenerated weights for manta_farming +//! Autogenerated weights for pallet_farming //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-06-05, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -25,13 +25,13 @@ // benchmark // pallet // --chain=calamari-dev -// --pallet=manta_farming +// --pallet=pallet_farming // --extrinsic=* // --heap-pages=4096 // --repeat=1 // --steps=1 // --template=.github/resources/frame-weight-template.hbs -// --output=manta-farming.rs +// --output=pallet-farming.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -42,7 +42,7 @@ use frame_support::{traits::Get, weights::Weight}; use sp_std::marker::PhantomData; use manta_primitives::constants::RocksDbWeight; -/// Weight functions needed for manta_farming. +/// Weight functions needed for pallet_farming. pub trait WeightInfo { fn on_initialize() -> Weight; fn create_farming_pool() -> Weight; @@ -53,9 +53,9 @@ pub trait WeightInfo { fn gauge_withdraw() -> Weight; } -/// Weights for manta_farming using the Substrate node and recommended hardware. +/// Weights for pallet_farming using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl manta_farming::WeightInfo for SubstrateWeight { +impl pallet_farming::WeightInfo for SubstrateWeight { // Storage: Farming PoolInfos (r:1 w:0) // Storage: Farming GaugePoolInfos (r:1 w:0) fn on_initialize() -> Weight { From 23c4374fa17cf1020584864690a5dc7d498236b6 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 3 Jul 2023 20:19:45 +0800 Subject: [PATCH 23/26] pid to pool_id and add min deposit Signed-off-by: zqhxuyuan --- pallets/farming/src/gauge.rs | 20 +- pallets/farming/src/lib.rs | 159 +++++----- pallets/farming/src/mock.rs | 8 +- pallets/farming/src/rewards.rs | 8 +- pallets/farming/src/tests.rs | 543 ++++++++++++++++++++------------- 5 files changed, 435 insertions(+), 303 deletions(-) diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 71d4c3645..7bb07f2ce 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -61,7 +61,7 @@ where /// The Reward Pool Info. #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] pub struct GaugePoolInfo { - pub pid: PoolId, + pub pool_id: PoolId, pub token: CurrencyIdOf, pub keeper: AccountIdOf, pub reward_issuer: AccountIdOf, @@ -88,7 +88,7 @@ where BlockNumberFor: Clone, { pub fn new( - pid: PoolId, + pool_id: PoolId, token: CurrencyIdOf, keeper: AccountIdOf, reward_issuer: AccountIdOf, @@ -97,7 +97,7 @@ where current_block_number: BlockNumberFor, ) -> Self { Self { - pid, + pool_id, token, keeper, reward_issuer, @@ -118,7 +118,7 @@ where BalanceOf: AtLeast32BitUnsigned + Copy, { pub fn create_gauge_pool( - pid: PoolId, + pool_id: PoolId, pool_info: &mut PoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, gauge_token: CurrencyIdOf, gauge_basic_rewards: BTreeMap, BalanceOf>, @@ -128,7 +128,7 @@ where pool_info.gauge = Some(gid); let current_block_number = frame_system::Pallet::::block_number(); let gauge_pool_info = GaugePoolInfo::new( - pid, + pool_id, gauge_token, pool_info.keeper.clone(), pool_info.reward_issuer.clone(), @@ -278,7 +278,7 @@ where let mut gauge_pool_info = GaugePoolInfos::::get(gid).ok_or(Error::::GaugePoolNotExist)?; let pool_info = - PoolInfos::::get(gauge_pool_info.pid).ok_or(Error::::PoolDoesNotExist)?; + PoolInfos::::get(gauge_pool_info.pool_id).ok_or(Error::::PoolDoesNotExist)?; GaugeInfos::::mutate_exists(gid, who, |maybe_gauge_info| -> DispatchResult { if let Some(mut gauge_info) = maybe_gauge_info.take() { ensure!( @@ -288,7 +288,7 @@ where let (gauge_rate, latest_claimed_time_factor) = Self::get_gauge_rate(&gauge_pool_info, &gauge_info)?; let total_shares = pool_info.total_shares; - let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) + let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pool_id, who) .ok_or(Error::::ShareInfoNotExists)?; gauge_pool_info.rewards.iter_mut().try_for_each( |( @@ -352,9 +352,9 @@ where pub fn get_gauge_rewards( who: &T::AccountId, - pid: PoolId, + pool_id: PoolId, ) -> Result, DispatchError> { - let pool_info = PoolInfos::::get(pid).ok_or(Error::::PoolDoesNotExist)?; + let pool_info = PoolInfos::::get(pool_id).ok_or(Error::::PoolDoesNotExist)?; let mut result_vec = Vec::<(CurrencyIdOf, BalanceOf)>::new(); match pool_info.gauge { @@ -366,7 +366,7 @@ where GaugeInfos::::get(gid, who).ok_or(Error::::GaugeInfoNotExist)?; let (gauge_rate, _) = Self::get_gauge_rate(&gauge_pool_info, &gauge_info)?; let total_shares = pool_info.total_shares; - let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pid, who) + let share_info = SharesAndWithdrawnRewards::::get(gauge_pool_info.pool_id, who) .ok_or(Error::::ShareInfoNotExists)?; gauge_pool_info.rewards.iter().try_for_each( |( diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 647c540b9..b2fc644d4 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -126,43 +126,43 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { FarmingPoolCreated { - pid: PoolId, + pool_id: PoolId, }, FarmingPoolReset { - pid: PoolId, + pool_id: PoolId, }, FarmingPoolClosed { - pid: PoolId, + pool_id: PoolId, }, FarmingPoolKilled { - pid: PoolId, + pool_id: PoolId, }, FarmingPoolEdited { - pid: PoolId, + pool_id: PoolId, }, Charged { who: AccountIdOf, - pid: PoolId, + pool_id: PoolId, rewards: Vec<(CurrencyIdOf, BalanceOf)>, }, Deposited { who: AccountIdOf, - pid: PoolId, + pool_id: PoolId, add_value: BalanceOf, gauge_info: Option<(BalanceOf, BlockNumberFor)>, }, Withdrawn { who: AccountIdOf, - pid: PoolId, + pool_id: PoolId, remove_value: Option>, }, Claimed { who: AccountIdOf, - pid: PoolId, + pool_id: PoolId, }, WithdrawClaimed { who: AccountIdOf, - pid: PoolId, + pool_id: PoolId, }, GaugeWithdrawn { who: AccountIdOf, @@ -175,10 +175,10 @@ pub mod pallet { gid: PoolId, }, AllRetired { - pid: PoolId, + pool_id: PoolId, }, PartiallyRetired { - pid: PoolId, + pool_id: PoolId, }, RetireLimitSet { limit: u32, @@ -260,7 +260,7 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(n: BlockNumberFor) -> Weight { - PoolInfos::::iter().for_each(|(pid, mut pool_info)| match pool_info.state { + PoolInfos::::iter().for_each(|(pool_id, mut pool_info)| match pool_info.state { PoolState::Ongoing => { pool_info.basic_rewards.clone().iter().for_each( |(reward_currency_id, reward_amount)| { @@ -273,7 +273,7 @@ pub mod pallet { .or_insert((*reward_amount, Zero::zero())); }, ); - PoolInfos::::insert(pid, &pool_info); + PoolInfos::::insert(pool_id, &pool_info); } PoolState::Charged => { if n >= pool_info.after_block_to_start @@ -281,13 +281,13 @@ pub mod pallet { { pool_info.block_startup = Some(n); pool_info.state = PoolState::Ongoing; - PoolInfos::::insert(pid, &pool_info); + PoolInfos::::insert(pool_id, &pool_info); } } _ => (), }); - GaugePoolInfos::::iter().for_each(|(gid, mut gauge_pool_info)| { + GaugePoolInfos::::iter().for_each(|(pool_id, mut gauge_pool_info)| { if gauge_pool_info.gauge_state == GaugeState::Bonded { gauge_pool_info.gauge_basic_rewards.clone().iter().for_each( |(reward_currency_id, reward_amount)| { @@ -300,7 +300,7 @@ pub mod pallet { .or_insert((*reward_amount, Zero::zero(), Zero::zero())); }, ); - GaugePoolInfos::::insert(gid, &gauge_pool_info); + GaugePoolInfos::::insert(pool_id, &gauge_pool_info); } }); @@ -330,9 +330,9 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let pid = Self::pool_next_id(); - let keeper = T::Keeper::get().into_sub_account_truncating(pid); - let reward_issuer = T::RewardIssuer::get().into_sub_account_truncating(pid); + let pool_id = Self::pool_next_id(); + let keeper = T::Keeper::get().into_sub_account_truncating(pool_id); + let reward_issuer = T::RewardIssuer::get().into_sub_account_truncating(pool_id); ensure!( !tokens_proportion.is_empty(), Error::::InvalidPoolParameter @@ -365,7 +365,7 @@ pub mod pallet { .collect(); Self::create_gauge_pool( - pid, + pool_id, &mut pool_info, gauge_token, gauge_basic_rewards_map, @@ -373,7 +373,7 @@ pub mod pallet { )?; }; - PoolInfos::::insert(pid, &pool_info); + PoolInfos::::insert(pool_id, &pool_info); PoolNextId::::mutate(|id| -> DispatchResult { *id = id .checked_add(One::one()) @@ -381,7 +381,7 @@ pub mod pallet { Ok(()) })?; - Self::deposit_event(Event::FarmingPoolCreated { pid }); + Self::deposit_event(Event::FarmingPoolCreated { pool_id }); Ok(()) } @@ -390,12 +390,12 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::charge())] pub fn charge( origin: OriginFor, - pid: PoolId, + pool_id: PoolId, rewards: Vec<(CurrencyIdOf, BalanceOf)>, ) -> DispatchResult { let exchanger = ensure_signed(origin)?; - let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let mut pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; rewards .iter() .try_for_each(|(reward_currency, reward)| -> DispatchResult { @@ -407,11 +407,11 @@ pub mod pallet { ) })?; pool_info.state = PoolState::Charged; - PoolInfos::::insert(pid, pool_info); + PoolInfos::::insert(pool_id, pool_info); Self::deposit_event(Event::Charged { who: exchanger, - pid, + pool_id, rewards, }); Ok(()) @@ -422,13 +422,13 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::deposit())] pub fn deposit( origin: OriginFor, - pid: PoolId, + pool_id: PoolId, #[pallet::compact] add_value: BalanceOf, gauge_info: Option<(BalanceOf, BlockNumberFor)>, ) -> DispatchResult { let exchanger = ensure_signed(origin)?; - let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let mut pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::Deposit, pool_info.state), Error::::InvalidPoolState @@ -455,7 +455,7 @@ pub mod pallet { ) }, )?; - Self::add_share(&exchanger, pid, &mut pool_info, add_value); + Self::add_share(&exchanger, pool_id, &mut pool_info, add_value); if let Some((gauge_value, gauge_block)) = gauge_info { Self::gauge_add( @@ -468,7 +468,7 @@ pub mod pallet { Self::deposit_event(Event::Deposited { who: exchanger, - pid, + pool_id, add_value, gauge_info, }); @@ -481,29 +481,34 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::withdraw())] pub fn withdraw( origin: OriginFor, - pid: PoolId, + pool_id: PoolId, remove_value: Option>, ) -> DispatchResult { let exchanger = ensure_signed(origin)?; - let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::Withdraw, pool_info.state), Error::::InvalidPoolState ); - let share_info = Self::shares_and_withdrawn_rewards(pid, &exchanger) + let share_info = Self::shares_and_withdrawn_rewards(pool_id, &exchanger) .ok_or(Error::::ShareInfoNotExists)?; ensure!( share_info.withdraw_list.len() < pool_info.withdraw_limit_count.into(), Error::::WithdrawLimitCountExceeded ); - Self::remove_share(&exchanger, pid, remove_value, pool_info.withdraw_limit_time)?; + Self::remove_share( + &exchanger, + pool_id, + remove_value, + pool_info.withdraw_limit_time, + )?; Self::deposit_event(Event::Withdrawn { who: exchanger, - pid, + pool_id, remove_value, }); Ok(()) @@ -512,32 +517,32 @@ pub mod pallet { /// `claim` operation can claim rewards and also un-stake if user share info has `withdraw_list`. #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::claim())] - pub fn claim(origin: OriginFor, pid: PoolId) -> DispatchResult { + pub fn claim(origin: OriginFor, pool_id: PoolId) -> DispatchResult { let exchanger = ensure_signed(origin)?; - let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::Claim, pool_info.state), Error::::InvalidPoolState ); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); - let share_info = Self::shares_and_withdrawn_rewards(pid, &exchanger) + let share_info = Self::shares_and_withdrawn_rewards(pool_id, &exchanger) .ok_or(Error::::ShareInfoNotExists)?; ensure!( share_info.claim_last_block + pool_info.claim_limit_time <= current_block_number, Error::::CanNotClaim ); - Self::claim_rewards(&exchanger, pid)?; + Self::claim_rewards(&exchanger, pool_id)?; if let Some(ref gid) = pool_info.gauge { Self::gauge_claim_inner(&exchanger, *gid)?; } - Self::process_withdraw_list(&exchanger, pid, &pool_info, true)?; + Self::process_withdraw_list(&exchanger, pool_id, &pool_info, true)?; Self::deposit_event(Event::Claimed { who: exchanger, - pid, + pool_id, }); Ok(()) } @@ -545,34 +550,34 @@ pub mod pallet { /// `withdraw_claim` operation will un-stake user staked token on farming pool from keeper account to user account. #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::claim())] - pub fn withdraw_claim(origin: OriginFor, pid: PoolId) -> DispatchResult { + pub fn withdraw_claim(origin: OriginFor, pool_id: PoolId) -> DispatchResult { let exchanger = ensure_signed(origin)?; - let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; - Self::process_withdraw_list(&exchanger, pid, &pool_info, false)?; + let pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; + Self::process_withdraw_list(&exchanger, pool_id, &pool_info, false)?; Self::deposit_event(Event::WithdrawClaimed { who: exchanger, - pid, + pool_id, }); Ok(()) } #[pallet::call_index(6)] #[pallet::weight(1000)] - pub fn close_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + pub fn close_pool(origin: OriginFor, pool_id: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let mut pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::ClosePool, pool_info.state), Error::::InvalidPoolState ); pool_info.state = PoolState::Dead; - PoolInfos::::insert(pid, pool_info); + PoolInfos::::insert(pool_id, pool_info); - Self::deposit_event(Event::FarmingPoolClosed { pid }); + Self::deposit_event(Event::FarmingPoolClosed { pool_id }); Ok(()) } @@ -591,10 +596,10 @@ pub mod pallet { #[pallet::call_index(8)] #[pallet::weight(1000)] - pub fn retire_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + pub fn retire_pool(origin: OriginFor, pool_id: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let mut pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::RetirePool, pool_info.state), Error::::InvalidPoolState @@ -603,19 +608,19 @@ pub mod pallet { let withdraw_limit_time = BlockNumberFor::::default(); let retire_limit = RetireLimit::::get(); let mut all_retired = true; - let share_infos = SharesAndWithdrawnRewards::::iter_prefix_values(pid); + let share_infos = SharesAndWithdrawnRewards::::iter_prefix_values(pool_id); for (retire_count, share_info) in share_infos.enumerate() { if retire_count.saturated_into::() >= retire_limit { all_retired = false; break; } let who = share_info.who; - Self::remove_share(&who, pid, None, withdraw_limit_time)?; - Self::claim_rewards(&who, pid)?; + Self::remove_share(&who, pool_id, None, withdraw_limit_time)?; + Self::claim_rewards(&who, pool_id)?; if let Some(ref gid) = pool_info.gauge { Self::gauge_claim_inner(&who, *gid)?; } - Self::process_withdraw_list(&who, pid, &pool_info, true)?; + Self::process_withdraw_list(&who, pool_id, &pool_info, true)?; } if all_retired { @@ -627,10 +632,10 @@ pub mod pallet { } pool_info.state = PoolState::Retired; pool_info.gauge = None; - PoolInfos::::insert(pid, pool_info); - Self::deposit_event(Event::AllRetired { pid }); + PoolInfos::::insert(pool_id, pool_info); + Self::deposit_event(Event::AllRetired { pool_id }); } else { - Self::deposit_event(Event::PartiallyRetired { pid }); + Self::deposit_event(Event::PartiallyRetired { pool_id }); } Ok(()) } @@ -639,7 +644,7 @@ pub mod pallet { #[pallet::weight(1000)] pub fn reset_pool( origin: OriginFor, - pid: PoolId, + pool_id: PoolId, basic_rewards: Option, BalanceOf)>>, min_deposit_to_start: Option>, after_block_to_start: Option>, @@ -650,7 +655,7 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let mut pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::ResetPool, pool_info.state), Error::::InvalidPoolState @@ -684,7 +689,7 @@ pub mod pallet { .collect(); Self::create_gauge_pool( - pid, + pool_id, &mut pool_info, gauge_token, gauge_basic_rewards_map, @@ -695,27 +700,27 @@ pub mod pallet { pool_info.rewards = BTreeMap::new(); pool_info.state = PoolState::UnCharged; pool_info.block_startup = None; - PoolInfos::::insert(pid, &pool_info); + PoolInfos::::insert(pool_id, &pool_info); - Self::deposit_event(Event::FarmingPoolReset { pid }); + Self::deposit_event(Event::FarmingPoolReset { pool_id }); Ok(()) } #[pallet::call_index(10)] #[pallet::weight(1000)] - pub fn kill_pool(origin: OriginFor, pid: PoolId) -> DispatchResult { + pub fn kill_pool(origin: OriginFor, pool_id: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::KillPool, pool_info.state), Error::::InvalidPoolState ); #[allow(deprecated)] - SharesAndWithdrawnRewards::::remove_prefix(pid, None); - PoolInfos::::remove(pid); + SharesAndWithdrawnRewards::::remove_prefix(pool_id, None); + PoolInfos::::remove(pool_id); - Self::deposit_event(Event::FarmingPoolKilled { pid }); + Self::deposit_event(Event::FarmingPoolKilled { pool_id }); Ok(()) } @@ -723,7 +728,7 @@ pub mod pallet { #[pallet::weight(1000)] pub fn edit_pool( origin: OriginFor, - pid: PoolId, + pool_id: PoolId, basic_rewards: Option, BalanceOf)>>, withdraw_limit_time: Option>, claim_limit_time: Option>, @@ -732,7 +737,7 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let mut pool_info = Self::pool_infos(pid).ok_or(Error::::PoolDoesNotExist)?; + let mut pool_info = Self::pool_infos(pool_id).ok_or(Error::::PoolDoesNotExist)?; ensure!( PoolState::state_valid(Action::EditPool, pool_info.state), Error::::InvalidPoolState @@ -768,9 +773,9 @@ pub mod pallet { }, ); }; - PoolInfos::::insert(pid, &pool_info); + PoolInfos::::insert(pool_id, &pool_info); - Self::deposit_event(Event::FarmingPoolEdited { pid }); + Self::deposit_event(Event::FarmingPoolEdited { pool_id }); Ok(()) } @@ -867,11 +872,11 @@ impl Pallet { pub fn get_farming_rewards( who: &T::AccountId, - pid: PoolId, + pool_id: PoolId, ) -> Result, DispatchError> { - let share_info = - SharesAndWithdrawnRewards::::get(pid, who).ok_or(Error::::ShareInfoNotExists)?; - let pool_info = PoolInfos::::get(pid).ok_or(Error::::PoolDoesNotExist)?; + let share_info = SharesAndWithdrawnRewards::::get(pool_id, who) + .ok_or(Error::::ShareInfoNotExists)?; + let pool_info = PoolInfos::::get(pool_id).ok_or(Error::::PoolDoesNotExist)?; let total_shares = pool_info.total_shares; let mut result_vec = Vec::<(CurrencyIdOf, BalanceOf)>::new(); diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index c04dffd06..6eaf9e9a2 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -33,7 +33,7 @@ use manta_primitives::{ }, constants::ASSET_MANAGER_PALLET_ID, currencies::Currencies, - types::{CalamariAssetId, DolphinAssetId}, + types::CalamariAssetId, }; use sp_core::{ConstU32, H256}; use sp_runtime::{ @@ -52,8 +52,8 @@ use crate as pallet_farming; pub type AccountId = AccountId32; pub type Balance = u128; -pub const KSM: DolphinAssetId = 8; -pub const KMA: DolphinAssetId = 1; +pub const KSM: CalamariAssetId = 8; +pub const KMA: CalamariAssetId = 1; pub const ALICE: AccountId = AccountId32::new([0u8; 32]); pub const BOB: AccountId = AccountId32::new([1u8; 32]); @@ -312,7 +312,7 @@ impl ExtBuilder { self.balances(vec![ (ALICE, 1, 3000), (BOB, 1, 400_000), - (CHARLIE, 1, 100), + (CHARLIE, 1, 1), (ALICE, KSM, 3000), (BOB, KSM, 10_000_000), ]) diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs index 377540f20..0dd3a95ac 100644 --- a/pallets/farming/src/rewards.rs +++ b/pallets/farming/src/rewards.rs @@ -165,7 +165,7 @@ impl PoolState { impl Pallet { pub fn add_share( who: &T::AccountId, - pid: PoolId, + pool_id: PoolId, pool_info: &mut PoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, add_amount: BalanceOf, ) { @@ -179,7 +179,7 @@ impl Pallet { // update user share let n: BlockNumberFor = frame_system::Pallet::::block_number(); - let mut share_info = SharesAndWithdrawnRewards::::get(pid, who) + let mut share_info = SharesAndWithdrawnRewards::::get(pool_id, who) .unwrap_or_else(|| ShareInfo::new(who.clone(), n)); share_info.share = share_info.share.saturating_add(add_amount); @@ -213,8 +213,8 @@ impl Pallet { .or_insert(reward_inflation); }); - SharesAndWithdrawnRewards::::insert(pid, who, share_info); - PoolInfos::::insert(pid, pool_info); + SharesAndWithdrawnRewards::::insert(pool_id, who, share_info); + PoolInfos::::insert(pool_id, pool_info); } pub fn remove_share( diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 84239f13b..26eaacd21 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -17,7 +17,7 @@ #![cfg(test)] use frame_support::{assert_err, assert_noop, assert_ok}; -use manta_primitives::types::DolphinAssetId; +use manta_primitives::types::CalamariAssetId; use sp_runtime::traits::AccountIdConversion; use crate::{mock::*, *}; @@ -40,20 +40,20 @@ fn init_gauge_900() -> (PoolId, BalanceOf) { 5 // withdraw_limit_count )); - let pid = 0; + let pool_id = 0; let charge_rewards = vec![(KSM, 300000)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, Some((100, 100)) )); - (pid, tokens) + (pool_id, tokens) } fn init_gauge_1000() -> (PoolId, BalanceOf) { @@ -74,24 +74,24 @@ fn init_gauge_1000() -> (PoolId, BalanceOf) { 1 // withdraw_limit_count )); - let pid = 0; + let pool_id = 0; let charge_rewards = vec![(KSM, 100000)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, None )); - let share_info = Farming::shares_and_withdrawn_rewards(pid, &ALICE).unwrap(); + let share_info = Farming::shares_and_withdrawn_rewards(pool_id, &ALICE).unwrap(); assert_eq!(share_info.share, tokens); - (pid, tokens) + (pool_id, tokens) } fn init_no_gauge() -> (PoolId, BalanceOf) { @@ -111,24 +111,24 @@ fn init_no_gauge() -> (PoolId, BalanceOf) { 1 // withdraw_limit_count )); - let pid = 0; + let pool_id = 0; let charge_rewards = vec![(KSM, 100000)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, None )); - let share_info = Farming::shares_and_withdrawn_rewards(pid, &ALICE).unwrap(); + let share_info = Farming::shares_and_withdrawn_rewards(pool_id, &ALICE).unwrap(); assert_eq!(share_info.share, tokens); - (pid, tokens) + (pool_id, tokens) } #[test] @@ -137,8 +137,8 @@ fn precondition_check_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid0, tokens) = init_gauge_1000(); - let pid = 1; + let (pool_id0, tokens) = init_gauge_1000(); + let pool_id = 1; let charge_rewards = vec![(KSM, 300000)]; assert_noop!( @@ -157,37 +157,42 @@ fn precondition_check_should_work() { ); assert_noop!( - Farming::charge(RuntimeOrigin::signed(BOB), pid, charge_rewards), + Farming::charge(RuntimeOrigin::signed(BOB), pool_id, charge_rewards), Error::::PoolDoesNotExist ); assert_noop!( - Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 100))), + Farming::deposit( + RuntimeOrigin::signed(ALICE), + pool_id, + tokens, + Some((100, 100)) + ), Error::::PoolDoesNotExist ); assert_noop!( - Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, Some(200)), + Farming::withdraw(RuntimeOrigin::signed(ALICE), pool_id, Some(200)), Error::::PoolDoesNotExist ); assert_noop!( - Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid), + Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::PoolDoesNotExist ); assert_noop!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::PoolDoesNotExist ); assert_noop!( - Farming::close_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::PoolDoesNotExist ); assert_noop!( - Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::PoolDoesNotExist ); assert_noop!( Farming::reset_pool( RuntimeOrigin::signed(ALICE), - pid, + pool_id, None, None, None, @@ -199,17 +204,17 @@ fn precondition_check_should_work() { Error::::PoolDoesNotExist ); assert_noop!( - Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::PoolDoesNotExist ); assert_noop!( - Farming::gauge_withdraw(RuntimeOrigin::signed(ALICE), pid), + Farming::gauge_withdraw(RuntimeOrigin::signed(ALICE), pool_id), Error::::GaugePoolNotExist ); assert_noop!( Farming::edit_pool( RuntimeOrigin::signed(ALICE), - pid, + pool_id, None, None, None, @@ -220,33 +225,33 @@ fn precondition_check_should_work() { ); // Pool state is Charged - let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + let pool1: PoolInfoOf = Farming::pool_infos(pool_id0).unwrap(); assert_eq!(pool1.state, PoolState::Charged); // Charge again assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid0, + pool_id0, vec![(KSM, 1000)] )); - let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + let pool1: PoolInfoOf = Farming::pool_infos(pool_id0).unwrap(); assert_eq!(pool1.state, PoolState::Charged); assert_noop!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid0), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id0), Error::::InvalidPoolState ); assert_noop!( - Farming::close_pool(RuntimeOrigin::signed(ALICE), pid0), + Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id0), Error::::InvalidPoolState ); assert_noop!( - Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid0), + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id0), Error::::InvalidPoolState ); assert_noop!( Farming::reset_pool( RuntimeOrigin::signed(ALICE), - pid0, + pool_id0, None, None, None, @@ -258,23 +263,23 @@ fn precondition_check_should_work() { Error::::InvalidPoolState ); assert_noop!( - Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid0), + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pool_id0), Error::::InvalidPoolState ); // Pool state is Ongoing Farming::on_initialize(System::block_number() + 10); - let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + let pool1: PoolInfoOf = Farming::pool_infos(pool_id0).unwrap(); assert_eq!(pool1.state, PoolState::Ongoing); assert_noop!( - Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid0), + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id0), Error::::InvalidPoolState ); assert_noop!( Farming::reset_pool( RuntimeOrigin::signed(ALICE), - pid0, + pool_id0, None, None, None, @@ -286,17 +291,17 @@ fn precondition_check_should_work() { Error::::InvalidPoolState ); assert_noop!( - Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid0), + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pool_id0), Error::::InvalidPoolState ); // Charge again, change back state from Ongoing to Charged. assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid0, + pool_id0, vec![(KSM, 1000)] )); - let pool1: PoolInfoOf = Farming::pool_infos(pid0).unwrap(); + let pool1: PoolInfoOf = Farming::pool_infos(pool_id0).unwrap(); assert_eq!(pool1.state, PoolState::Charged); }) } @@ -349,14 +354,14 @@ fn no_gauge_farming_pool_should_work() { assert_eq!(Farming::pool_infos(0), None); // Charge to the pool reward issuer - let pid = 1; + let pool_id = 1; let charge_rewards = vec![(KSM, total_rewards)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); - let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + let mut pool1: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 0); assert_eq!(pool1.min_deposit_to_start, 2); assert_eq!(pool1.state, PoolState::Charged); @@ -367,7 +372,7 @@ fn no_gauge_farming_pool_should_work() { assert_noop!( Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, deposit_amount, Some((100, 100)) ), @@ -379,7 +384,7 @@ fn no_gauge_farming_pool_should_work() { assert_noop!( Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, deposit_amount, Some((100, 100)) ), @@ -388,7 +393,7 @@ fn no_gauge_farming_pool_should_work() { // Deposit success without gauge info assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, deposit_amount, None )); @@ -401,35 +406,35 @@ fn no_gauge_farming_pool_should_work() { assert_eq!(Assets::balance(KSM, &pool1.keeper), deposit_amount); // reward info - let mut reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + let mut reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.share, deposit_amount); assert!(reward.withdrawn_rewards.is_empty()); assert!(reward.withdraw_list.is_empty()); assert_eq!(reward.claim_last_block, 3); // The pool state is still on `Charged` until new block produced - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, deposit_amount); assert_eq!(pool1.state, PoolState::Charged); assert!(pool1.rewards.is_empty()); // Can't Claim if pool state is `Charged` assert_err!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); // OnInitialize hook change the pool state and also pool rewards Farming::on_initialize(System::block_number() + 3); Farming::on_initialize(0); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, deposit_amount); assert_eq!(pool1.state, PoolState::Ongoing); assert_eq!(pool1.claim_limit_time, 6); assert_eq!(pool1.rewards.get(&KSM).unwrap(), &(reward_amount, 0)); // Produce new block didn't change the reward info - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.share, deposit_amount); assert!(reward.withdrawn_rewards.is_empty()); assert!(reward.withdraw_list.is_empty()); @@ -437,19 +442,19 @@ fn no_gauge_farming_pool_should_work() { // Claim failed because of user share info not exist assert_err!( - Farming::claim(RuntimeOrigin::signed(BOB), pid), + Farming::claim(RuntimeOrigin::signed(BOB), pool_id), Error::::ShareInfoNotExists ); // Claim failed because of block not reached, at least 3+6=9 assert!(System::block_number() < reward.claim_last_block + pool1.claim_limit_time); assert_err!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::CanNotClaim ); // Claim success, user get reward. System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!( Assets::balance(KSM, &ALICE), alice_init_balance - deposit_amount + reward_amount @@ -460,12 +465,12 @@ fn no_gauge_farming_pool_should_work() { ); // Claim operation update pool info's rewards and also share info's withdrawn_rewards - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!( pool1.rewards.get(&KSM).unwrap(), &(reward_amount, reward_amount) ); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &reward_amount); // The withdraw list of user share info is still empty. assert!(reward.withdraw_list.is_empty()); @@ -473,15 +478,15 @@ fn no_gauge_farming_pool_should_work() { // Claim without new block. for i in 0..5 { System::set_block_number(System::block_number() + 100); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.withdrawn_rewards.get(&KSM).unwrap(), &reward_amount); assert_eq!(reward.claim_last_block, 109 + i * 100); assert_eq!(reward.share, deposit_amount); assert!(reward.withdraw_list.is_empty()); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!( pool1.rewards.get(&KSM).unwrap(), &(reward_amount, reward_amount) @@ -507,9 +512,9 @@ fn no_gauge_farming_pool_should_work() { for i in 1..5 { System::set_block_number(System::block_number() + 6); Farming::on_initialize(System::block_number() + 3); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!( reward.withdrawn_rewards.get(&KSM).unwrap(), &(reward_amount * (i + 1)) @@ -518,7 +523,7 @@ fn no_gauge_farming_pool_should_work() { assert_eq!(reward.share, deposit_amount); assert!(reward.withdraw_list.is_empty()); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!( pool1.rewards.get(&KSM).unwrap(), &(reward_amount * (i + 1), reward_amount * (i + 1)) @@ -552,13 +557,13 @@ fn no_gauge_farming_pool_should_work() { // Withdraw failed because of share info not exist. assert_err!( - Farming::withdraw(RuntimeOrigin::signed(BOB), pid, Some(800)), + Farming::withdraw(RuntimeOrigin::signed(BOB), pool_id, Some(800)), Error::::ShareInfoNotExists ); // Claim again without new blocks, no new rewards - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - pool1 = Farming::pool_infos(pid).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert!(reward.withdraw_list.is_empty()); let share_reward = reward.withdrawn_rewards.get(&KSM).unwrap(); @@ -597,7 +602,7 @@ fn no_gauge_farming_pool_should_work() { ); assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - pid, + pool_id, Some(800) )); @@ -616,8 +621,8 @@ fn no_gauge_farming_pool_should_work() { // Withdraw operation has only one operation `remove_share`. // And `remove_share` will claim rewards and also update user share info. // We already know that due to no new block, claim rewards actually has no reward. - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - pool1 = Farming::pool_infos(pid).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 200); assert_eq!(reward.withdraw_list, vec![(533 + withdraw_limit_time, 800)]); @@ -634,11 +639,11 @@ fn no_gauge_farming_pool_should_work() { // Withdraw rest all of share assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - pid, + pool_id, Some(300) )); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - pool1 = Farming::pool_infos(pid).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 0); assert!(pool1.rewards.is_empty()); assert_eq!(reward.share, 0); @@ -652,15 +657,94 @@ fn no_gauge_staking_cases_should_work() { staking_case(KSM, KMA); staking_case(KMA, KSM); staking_all_kma(KMA, KSM); + staking_minimum_kma(KMA, KSM); +} + +fn staking_minimum_kma(stake_token: CalamariAssetId, reward_token: CalamariAssetId) { + ExtBuilder::default() + .one_hundred_for_alice_n_bob() + .build() + .execute_with(|| { + let tokens_proportion = vec![(stake_token, Perbill::from_percent(100))]; + let reward_amount: Balance = 1; + let basic_rewards = vec![(reward_token, reward_amount)]; + let total_rewards = 300_000; + let charlie_init_kma = 1; + assert_eq!(Balances::free_balance(&CHARLIE), charlie_init_kma); + + assert_ok!(Farming::create_farming_pool( + RuntimeOrigin::signed(ALICE), + tokens_proportion, + basic_rewards, + None, + 1, // min_deposit_to_start + 1, // after_block_to_start + 7, // withdraw_limit_time, + 6, // claim_limit_time + 5 // withdraw_limit_count + )); + + // Charge to the pool reward issuer + let pool_id = 0; + let charge_rewards = vec![(reward_token, total_rewards)]; + assert_ok!(Farming::charge( + RuntimeOrigin::signed(BOB), + pool_id, + charge_rewards + )); + + System::set_block_number(System::block_number() + 3); + // Deposit success without gauge info + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(CHARLIE), + pool_id, + charlie_init_kma, + None + )); + + let pool1: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); + assert_eq!(Balances::free_balance(&CHARLIE), 0); + assert_eq!(Balances::free_balance(&pool1.keeper), charlie_init_kma); + + Farming::on_initialize(System::block_number() + 10); + System::set_block_number(System::block_number() + 10); + assert_eq!(Balances::free_balance(&CHARLIE), 0); + assert_ok!(Farming::claim(RuntimeOrigin::signed(CHARLIE), pool_id)); + assert_eq!(Balances::free_balance(&CHARLIE), 0); + + System::set_block_number(System::block_number() + 10); + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(CHARLIE), + pool_id, + None + )); + assert_eq!(Balances::free_balance(&CHARLIE), 0); + let reward = SharesAndWithdrawnRewards::::get(pool_id, &CHARLIE).unwrap(); + assert_eq!(reward.withdraw_list, vec![(30, charlie_init_kma)]); + + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(CHARLIE), + pool_id + )); + assert_eq!(Balances::free_balance(&CHARLIE), 0); + + System::set_block_number(System::block_number() + 6); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(CHARLIE), + pool_id + )); + assert_eq!(Balances::free_balance(&CHARLIE), charlie_init_kma); + assert_eq!(Balances::free_balance(pool1.keeper), 0); + }); } -fn staking_all_kma(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { +fn staking_all_kma(stake_token: CalamariAssetId, reward_token: CalamariAssetId) { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() .execute_with(|| { let tokens_proportion = vec![(stake_token, Perbill::from_percent(100))]; - // let deposit_amount = 1000; let reward_amount: Balance = 800; let basic_rewards = vec![(reward_token, reward_amount)]; let total_rewards = 300_000; @@ -680,11 +764,11 @@ fn staking_all_kma(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { )); // Charge to the pool reward issuer - let pid = 0; + let pool_id = 0; let charge_rewards = vec![(reward_token, total_rewards)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); @@ -692,39 +776,49 @@ fn staking_all_kma(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // Deposit success without gauge info assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, alice_init_kma, None )); - let pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + let pool1: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(Balances::free_balance(&ALICE), 0); assert_eq!(Balances::free_balance(&pool1.keeper), alice_init_kma); Farming::on_initialize(System::block_number() + 10); System::set_block_number(System::block_number() + 10); assert_eq!(Balances::free_balance(&ALICE), 0); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Balances::free_balance(&ALICE), 0); System::set_block_number(System::block_number() + 10); - assert_ok!(Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, None)); + assert_ok!(Farming::withdraw( + RuntimeOrigin::signed(ALICE), + pool_id, + None + )); assert_eq!(Balances::free_balance(&ALICE), 0); - let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + let reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.withdraw_list, vec![(30, alice_init_kma)]); System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(ALICE), + pool_id + )); assert_eq!(Balances::free_balance(&ALICE), 0); System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(ALICE), + pool_id + )); assert_eq!(Balances::free_balance(&ALICE), alice_init_kma); assert_eq!(Balances::free_balance(pool1.keeper), 0); }); } -fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { +fn staking_case(stake_token: CalamariAssetId, reward_token: CalamariAssetId) { ExtBuilder::default() .one_hundred_for_alice_n_bob() .build() @@ -753,15 +847,15 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { )); // Charge to the pool reward issuer - let pid = 0; + let pool_id = 0; let charge_rewards = vec![(reward_token, total_rewards)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); - let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + let mut pool1: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 0); assert_eq!(pool1.min_deposit_to_start, 2); assert_eq!(pool1.state, PoolState::Charged); @@ -771,7 +865,7 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // Deposit success without gauge info assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, deposit_amount, None )); @@ -805,14 +899,14 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { } // reward info - let mut reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + let mut reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.share, deposit_amount); assert!(reward.withdrawn_rewards.is_empty()); assert!(reward.withdraw_list.is_empty()); assert_eq!(reward.claim_last_block, 3); // The pool state is still on `Charged` until new block produced - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, deposit_amount); assert_eq!(pool1.state, PoolState::Charged); assert!(pool1.rewards.is_empty()); @@ -820,7 +914,7 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // OnInitialize hook change the pool state and also pool rewards Farming::on_initialize(System::block_number() + 3); Farming::on_initialize(0); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, deposit_amount); assert_eq!(pool1.state, PoolState::Ongoing); assert_eq!(pool1.claim_limit_time, 6); @@ -830,7 +924,7 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { ); // Produce new block didn't change the reward info - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.share, deposit_amount); assert!(reward.withdrawn_rewards.is_empty()); assert!(reward.withdraw_list.is_empty()); @@ -838,7 +932,7 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // Claim success, user get reward. System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); if reward_token == KSM { // Stake KMA, reward KSM assert_eq!( @@ -862,12 +956,12 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { } // Claim operation update pool info's rewards and also share info's withdrawn_rewards - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!( pool1.rewards.get(&reward_token).unwrap(), &(reward_amount, reward_amount) ); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!( reward.withdrawn_rewards.get(&reward_token).unwrap(), &reward_amount @@ -878,9 +972,9 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // Claim without new block. for i in 0..5 { System::set_block_number(System::block_number() + 100); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!( reward.withdrawn_rewards.get(&reward_token).unwrap(), &reward_amount @@ -889,7 +983,7 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { assert_eq!(reward.share, deposit_amount); assert!(reward.withdraw_list.is_empty()); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!( pool1.rewards.get(&reward_token).unwrap(), &(reward_amount, reward_amount) @@ -919,9 +1013,9 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { for i in 1..5 { System::set_block_number(System::block_number() + 6); Farming::on_initialize(System::block_number() + 3); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!( reward.withdrawn_rewards.get(&reward_token).unwrap(), &(reward_amount * (i + 1)) @@ -930,7 +1024,7 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { assert_eq!(reward.share, deposit_amount); assert!(reward.withdraw_list.is_empty()); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!( pool1.rewards.get(&reward_token).unwrap(), &(reward_amount * (i + 1), reward_amount * (i + 1)) @@ -970,13 +1064,13 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // Withdraw failed because of share info not exist. assert_err!( - Farming::withdraw(RuntimeOrigin::signed(BOB), pid, Some(800)), + Farming::withdraw(RuntimeOrigin::signed(BOB), pool_id, Some(800)), Error::::ShareInfoNotExists ); // Claim again without new blocks, no new rewards - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - pool1 = Farming::pool_infos(pid).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert!(reward.withdraw_list.is_empty()); let share_reward = reward.withdrawn_rewards.get(&reward_token).unwrap(); @@ -1011,7 +1105,7 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { assert_eq!(System::block_number(), 533); assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - pid, + pool_id, Some(800) )); // Although withdraw also has claim, but no new rewards due to no new block @@ -1046,8 +1140,8 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // Withdraw operation has only one operation `remove_share`. // And `remove_share` will claim rewards and also update user share info. // We already know that due to no new block, claim rewards actually has no reward. - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - pool1 = Farming::pool_infos(pid).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 200); assert_eq!(reward.withdraw_list, vec![(533 + withdraw_limit_time, 800)]); @@ -1067,11 +1161,11 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { // Withdraw rest all of share assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - pid, + pool_id, Some(300) )); - reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); - pool1 = Farming::pool_infos(pid).unwrap(); + reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 0); assert!(pool1.rewards.is_empty()); assert_eq!(reward.share, 0); @@ -1107,7 +1201,10 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { } System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(ALICE), + pool_id + )); if stake_token == KSM { // Stake KSM, reward KMA assert_eq!(Assets::balance(stake_token, &pool1.keeper), 200); @@ -1117,7 +1214,10 @@ fn staking_case(stake_token: DolphinAssetId, reward_token: DolphinAssetId) { } System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(ALICE), + pool_id + )); if stake_token == KSM { // Stake KSM, reward KMA assert_eq!(Assets::balance(stake_token, &pool1.keeper), 0); @@ -1171,14 +1271,14 @@ fn gauge_farming_pool_should_work() { assert_eq!(Farming::pool_infos(0), None); // Charge to the pool - let pid = 1; + let pool_id = 1; let charge_rewards = vec![(KSM, 300000)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); - let mut pool1: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + let mut pool1: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 0); assert_eq!(pool1.min_deposit_to_start, 2); assert_eq!(pool1.state, PoolState::Charged); @@ -1187,7 +1287,7 @@ fn gauge_farming_pool_should_work() { assert_err!( Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, deposit_amount, Some((100, 100)) ), @@ -1197,12 +1297,12 @@ fn gauge_farming_pool_should_work() { assert_eq!(Assets::balance(KSM, &ALICE), 3000); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, deposit_amount, Some((100, 100)) )); assert_eq!(Assets::balance(KSM, &ALICE), 1900); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 1000); assert_eq!(pool1.min_deposit_to_start, 2); assert_eq!(pool1.state, PoolState::Charged); @@ -1210,42 +1310,42 @@ fn gauge_farming_pool_should_work() { // OnInitialize hook change the pool state Farming::on_initialize(System::block_number() + 3); Farming::on_initialize(0); - pool1 = Farming::pool_infos(pid).unwrap(); + pool1 = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool1.total_shares, 1000); assert_eq!(pool1.min_deposit_to_start, 2); assert_eq!(pool1.state, PoolState::Ongoing); // Claim to get rewards assert_err!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::CanNotClaim ); System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 3008); System::set_block_number(System::block_number() + 100); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 4698); // Withdraw part tokens assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - pid, + pool_id, Some(800) )); assert_eq!(Assets::balance(KSM, &ALICE), 4698); // Claim again System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_err!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::CanNotClaim ); assert_eq!(Assets::balance(KSM, &ALICE), 4698); System::set_block_number(System::block_number() + 6); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 5498); }) } @@ -1272,14 +1372,14 @@ fn deposit_gauge_should_work() { fn deposit_should_work(use_gauge: bool) { assert_eq!(Assets::balance(KSM, &ALICE), 3000); - let (pid, tokens) = if use_gauge { + let (pool_id, tokens) = if use_gauge { init_gauge_1000() } else { init_no_gauge() }; - let keeper: AccountId = ::Keeper::get().into_sub_account_truncating(pid); + let keeper: AccountId = ::Keeper::get().into_sub_account_truncating(pool_id); let reward_issuer: AccountId = - ::RewardIssuer::get().into_sub_account_truncating(pid); + ::RewardIssuer::get().into_sub_account_truncating(pool_id); assert_eq!(Assets::balance(KSM, &ALICE), 2000); assert_eq!(Assets::balance(KSM, &keeper), 1000); @@ -1288,7 +1388,7 @@ fn deposit_should_work(use_gauge: bool) { if use_gauge { assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, Some((100, 100)) )); @@ -1298,7 +1398,7 @@ fn deposit_should_work(use_gauge: bool) { System::set_block_number(System::block_number() + 1); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, 0, Some((100, 100)) )); @@ -1307,7 +1407,7 @@ fn deposit_should_work(use_gauge: bool) { } else { assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, None )); @@ -1317,7 +1417,7 @@ fn deposit_should_work(use_gauge: bool) { System::set_block_number(System::block_number() + 1); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, 100, None )); @@ -1329,7 +1429,7 @@ fn deposit_should_work(use_gauge: bool) { let mut gauge_basic_rewards = BTreeMap::, BalanceOf>::new(); gauge_basic_rewards.entry(KSM).or_insert(tokens); let gauge_pool_info = GaugePoolInfo { - pid, + pool_id, token: KSM, keeper, reward_issuer, @@ -1404,12 +1504,12 @@ fn withdraw_no_gauge_should_work() { } fn withdraw_should_work(use_gauge: bool) { - let (pid, tokens) = if use_gauge { + let (pool_id, tokens) = if use_gauge { init_gauge_1000() } else { init_no_gauge() }; - let pool = PoolInfos::::get(pid).unwrap(); + let pool = PoolInfos::::get(pool_id).unwrap(); let reward_issuer = pool.reward_issuer; let token_keeper = pool.keeper; @@ -1421,14 +1521,14 @@ fn withdraw_should_work(use_gauge: bool) { Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); - let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + let reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert!(reward.withdraw_list.is_empty()); assert_eq!(pool.withdraw_limit_count, 1); // withdraw assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - pid, + pool_id, Some(800) )); @@ -1437,16 +1537,16 @@ fn withdraw_should_work(use_gauge: bool) { assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); assert_eq!(Assets::balance(KSM, &ALICE), 3_000); - let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + let reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert_eq!(reward.withdraw_list.len(), 1); // user share info withdraw list size is not less than pool info `withdraw_limit_count` assert_err!( - Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, Some(100)), + Farming::withdraw(RuntimeOrigin::signed(ALICE), pool_id, Some(100)), Error::::WithdrawLimitCountExceeded ); // Alice claim reward manually, but due to no new block, so no reward - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 3_000); assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); assert_eq!(Assets::balance(KSM, &token_keeper), 1_000); @@ -1456,14 +1556,14 @@ fn withdraw_should_work(use_gauge: bool) { if use_gauge { assert_ok!(Farming::deposit( RuntimeOrigin::signed(BOB), - pid, + pool_id, tokens, Some((100, 100)) )); } else { assert_ok!(Farming::deposit( RuntimeOrigin::signed(BOB), - pid, + pool_id, tokens, None )); @@ -1478,14 +1578,14 @@ fn withdraw_should_work(use_gauge: bool) { // Alice claim again, because new block produces, so has reward now Farming::on_initialize(0); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 3_966); assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); // withdraw assert_ok!(Farming::withdraw( RuntimeOrigin::signed(ALICE), - pid, + pool_id, Some(200) )); assert_eq!(Assets::balance(KSM, &ALICE), 3_966); @@ -1499,7 +1599,10 @@ fn withdraw_should_work(use_gauge: bool) { // `withdraw_claim` operation will transfer back user stake token // User unStake 200 KSM, so keeper transfer back 200 KSM to user. System::set_block_number(System::block_number() + 100); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(ALICE), + pool_id + )); assert_eq!(Assets::balance(KSM, &ALICE), 4_166); assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); if use_gauge { @@ -1509,9 +1612,9 @@ fn withdraw_should_work(use_gauge: bool) { } // claim - let reward = SharesAndWithdrawnRewards::::get(pid, &ALICE).unwrap(); + let reward = SharesAndWithdrawnRewards::::get(pool_id, &ALICE).unwrap(); assert!(reward.withdraw_list.is_empty()); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 4_166); assert_eq!(Assets::balance(KSM, &reward_issuer), 98_834); if use_gauge { @@ -1522,7 +1625,7 @@ fn withdraw_should_work(use_gauge: bool) { // `process_withdraw_list` remove the share info. // due to withdraw_list of share info is empty, so there's no token transfer. - assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); + assert_eq!(Farming::shares_and_withdrawn_rewards(pool_id, &ALICE), None); assert_eq!(Assets::balance(KSM, &TREASURY_ACCOUNT), 0); } @@ -1532,38 +1635,41 @@ fn claim() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, _tokens) = init_gauge_1000(); + let (pool_id, _tokens) = init_gauge_1000(); let keeper: AccountId = - ::Keeper::get().into_sub_account_truncating(pid); + ::Keeper::get().into_sub_account_truncating(pool_id); let reward_issuer: AccountId = - ::RewardIssuer::get().into_sub_account_truncating(pid); + ::RewardIssuer::get().into_sub_account_truncating(pool_id); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); assert_err!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); System::set_block_number(System::block_number() + 100); Farming::on_initialize(0); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 2000); assert_eq!(Assets::balance(KSM, &keeper), 1000); assert_eq!(Assets::balance(KSM, &reward_issuer), 100_000); Farming::on_initialize(0); - assert_ok!(Farming::withdraw_claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::withdraw_claim( + RuntimeOrigin::signed(ALICE), + pool_id + )); assert_eq!(Assets::balance(KSM, &ALICE), 2000); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 3000); assert_eq!(Assets::balance(KSM, &keeper), 1000); assert_eq!(Assets::balance(KSM, &reward_issuer), 99_000); Farming::on_initialize(0); - assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id)); - assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 5000); // 3000 + 1000 + 1000 assert_eq!(Assets::balance(KSM, &keeper), 0); assert_eq!(Assets::balance(KSM, &reward_issuer), 98_000); @@ -1576,7 +1682,7 @@ fn gauge() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, tokens) = init_gauge_900(); + let (pool_id, tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { assert!(gauge_pool_infos.rewards.is_empty()); @@ -1584,37 +1690,47 @@ fn gauge() { Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); Farming::on_initialize(0); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 2918); Farming::on_initialize(0); System::set_block_number(System::block_number() + 10); assert_noop!( - Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 2000))), + Farming::deposit( + RuntimeOrigin::signed(ALICE), + pool_id, + tokens, + Some((100, 2000)) + ), Error::::GaugeMaxBlockOverflow ); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, Some((100, 100)) )); assert_eq!(Assets::balance(KSM, &ALICE), 1818); System::set_block_number(System::block_number() + 20); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 3163); - assert_ok!(Farming::deposit(RuntimeOrigin::signed(BOB), pid, 10, None)); + assert_ok!(Farming::deposit( + RuntimeOrigin::signed(BOB), + pool_id, + 10, + None + )); assert_eq!(Assets::balance(KSM, &BOB), 9699990); System::set_block_number(System::block_number() + 200); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 5383); assert_eq!(Assets::balance(KSM, &BOB), 9699990); assert_ok!(Farming::deposit( RuntimeOrigin::signed(BOB), - pid, + pool_id, 0, Some((100, 100)) )); @@ -1623,19 +1739,24 @@ fn gauge() { assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); assert_ok!(Farming::force_gauge_claim( RuntimeOrigin::signed(ALICE), - pid + pool_id )); assert_eq!(Assets::balance(KSM, &BOB), 9699991); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, Some((100, 1)) )); System::set_block_number(System::block_number() + 200); assert_noop!( - Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 1))), + Farming::deposit( + RuntimeOrigin::signed(ALICE), + pool_id, + tokens, + Some((100, 1)) + ), Error::::LastGaugeNotClaim ); }) @@ -1647,7 +1768,7 @@ fn gauge_withdraw() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, _tokens) = init_gauge_900(); + let (pool_id, _tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { assert_eq!(gauge_pool_infos.gauge_amount, 100) @@ -1655,10 +1776,16 @@ fn gauge_withdraw() { Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); Farming::on_initialize(0); - assert_ok!(Farming::gauge_withdraw(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::gauge_withdraw( + RuntimeOrigin::signed(ALICE), + pool_id + )); assert_eq!(Assets::balance(KSM, &ALICE), 1918); System::set_block_number(System::block_number() + 1000); - assert_ok!(Farming::gauge_withdraw(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::gauge_withdraw( + RuntimeOrigin::signed(ALICE), + pool_id + )); assert_eq!(Assets::balance(KSM, &ALICE), 3782); if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { assert_eq!(gauge_pool_infos.gauge_amount, 0) @@ -1672,19 +1799,19 @@ fn pool_admin_operation_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, tokens) = init_gauge_1000(); + let (pool_id, tokens) = init_gauge_1000(); Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, tokens, Some((100, 100)) )); System::set_block_number(System::block_number() + 1); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, 0, Some((100, 100)) )); @@ -1692,17 +1819,17 @@ fn pool_admin_operation_should_work() { // Not allow retire or reset, kill pool if pool is not Dead assert_noop!( - Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); assert_noop!( - Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); assert_noop!( Farming::reset_pool( RuntimeOrigin::signed(ALICE), - pid, + pool_id, None, None, None, @@ -1715,10 +1842,10 @@ fn pool_admin_operation_should_work() { ); // Close the pool - let pool: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + let pool: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool.state, PoolState::Ongoing); - assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); - let pool: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id)); + let pool: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool.state, PoolState::Dead); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); @@ -1726,17 +1853,17 @@ fn pool_admin_operation_should_work() { // Pool is dead, not allow to close again, deposit, reset, kill or edit. assert_noop!( - Farming::close_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); assert_noop!( - Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::kill_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); assert_noop!( Farming::reset_pool( RuntimeOrigin::signed(ALICE), - pid, + pool_id, None, None, None, @@ -1750,7 +1877,7 @@ fn pool_admin_operation_should_work() { assert_noop!( Farming::edit_pool( RuntimeOrigin::signed(ALICE), - pid, + pool_id, None, None, None, @@ -1760,44 +1887,44 @@ fn pool_admin_operation_should_work() { Error::::InvalidPoolState ); assert_noop!( - Farming::deposit(RuntimeOrigin::signed(ALICE), pid, 0, Some((100, 100))), + Farming::deposit(RuntimeOrigin::signed(ALICE), pool_id, 0, Some((100, 100))), Error::::InvalidPoolState ); // Retire pool - assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); - let pool: PoolInfoOf = Farming::pool_infos(pid).unwrap(); + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id)); + let pool: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool.state, PoolState::Retired); // claim all rewards automatically to user assert_eq!(Assets::balance(KSM, &ALICE), 3000); - assert_eq!(Farming::shares_and_withdrawn_rewards(pid, &ALICE), None); + assert_eq!(Farming::shares_and_withdrawn_rewards(pool_id, &ALICE), None); // Pool is retired, not allow to retire again, deposit, withdraw, claim, close assert_noop!( - Farming::close_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); assert_noop!( - Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid), + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); assert_noop!( - Farming::deposit(RuntimeOrigin::signed(ALICE), pid, 0, Some((100, 100))), + Farming::deposit(RuntimeOrigin::signed(ALICE), pool_id, 0, Some((100, 100))), Error::::InvalidPoolState ); assert_noop!( - Farming::withdraw(RuntimeOrigin::signed(ALICE), pid, None), + Farming::withdraw(RuntimeOrigin::signed(ALICE), pool_id, None), Error::::InvalidPoolState ); assert_noop!( - Farming::claim(RuntimeOrigin::signed(ALICE), pid), + Farming::claim(RuntimeOrigin::signed(ALICE), pool_id), Error::::InvalidPoolState ); // Kill the pool - assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), pid)); - assert_eq!(Farming::pool_infos(pid), None); + assert_ok!(Farming::kill_pool(RuntimeOrigin::signed(ALICE), pool_id)); + assert_eq!(Farming::pool_infos(pool_id), None); }) } @@ -1807,20 +1934,20 @@ fn reset() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - let (pid, _tokens) = init_gauge_900(); + let (pool_id, _tokens) = init_gauge_900(); assert_eq!(Assets::balance(KSM, &ALICE), 1900); Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); Farming::on_initialize(0); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 2918); - assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id)); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); - assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id)); let basic_rewards = vec![(KSM, 1000)]; assert_ok!(Farming::reset_pool( RuntimeOrigin::signed(ALICE), - pid, + pool_id, None, None, None, @@ -1830,9 +1957,9 @@ fn reset() { Some((KSM, 1000, basic_rewards)), )); let keeper: AccountId = - ::Keeper::get().into_sub_account_truncating(pid); + ::Keeper::get().into_sub_account_truncating(pool_id); let reward_issuer: AccountId = - ::RewardIssuer::get().into_sub_account_truncating(pid); + ::RewardIssuer::get().into_sub_account_truncating(pool_id); let mut basic_rewards_map = BTreeMap::, BalanceOf>::new(); basic_rewards_map.entry(KSM).or_insert(1000); @@ -1859,7 +1986,7 @@ fn reset() { }; assert_eq!(Farming::pool_infos(0), Some(pool_infos)); let gauge_pool_info = GaugePoolInfo { - pid, + pool_id, token: KSM, keeper, reward_issuer, @@ -1879,19 +2006,19 @@ fn reset() { let charge_rewards = vec![(KSM, 300000)]; assert_ok!(Farming::charge( RuntimeOrigin::signed(BOB), - pid, + pool_id, charge_rewards )); assert_ok!(Farming::deposit( RuntimeOrigin::signed(ALICE), - pid, + pool_id, 1, Some((100, 100)) )); assert_eq!(Assets::balance(KSM, &ALICE), 3817); Farming::on_initialize(0); System::set_block_number(System::block_number() + 20); - assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pool_id)); assert_eq!(Assets::balance(KSM, &ALICE), 4017); }) } From 5d5153c2f6fbdc89871f80ef343b68ad82b1e585 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Mon, 3 Jul 2023 21:42:38 +0800 Subject: [PATCH 24/26] event use pid Signed-off-by: zqhxuyuan --- pallets/farming/src/lib.rs | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index b2fc644d4..a1447e771 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -126,43 +126,43 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { FarmingPoolCreated { - pool_id: PoolId, + pid: PoolId, }, FarmingPoolReset { - pool_id: PoolId, + pid: PoolId, }, FarmingPoolClosed { - pool_id: PoolId, + pid: PoolId, }, FarmingPoolKilled { - pool_id: PoolId, + pid: PoolId, }, FarmingPoolEdited { - pool_id: PoolId, + pid: PoolId, }, Charged { who: AccountIdOf, - pool_id: PoolId, + pid: PoolId, rewards: Vec<(CurrencyIdOf, BalanceOf)>, }, Deposited { who: AccountIdOf, - pool_id: PoolId, + pid: PoolId, add_value: BalanceOf, gauge_info: Option<(BalanceOf, BlockNumberFor)>, }, Withdrawn { who: AccountIdOf, - pool_id: PoolId, + pid: PoolId, remove_value: Option>, }, Claimed { who: AccountIdOf, - pool_id: PoolId, + pid: PoolId, }, WithdrawClaimed { who: AccountIdOf, - pool_id: PoolId, + pid: PoolId, }, GaugeWithdrawn { who: AccountIdOf, @@ -175,10 +175,10 @@ pub mod pallet { gid: PoolId, }, AllRetired { - pool_id: PoolId, + pid: PoolId, }, PartiallyRetired { - pool_id: PoolId, + pid: PoolId, }, RetireLimitSet { limit: u32, @@ -381,7 +381,7 @@ pub mod pallet { Ok(()) })?; - Self::deposit_event(Event::FarmingPoolCreated { pool_id }); + Self::deposit_event(Event::FarmingPoolCreated { pid: pool_id }); Ok(()) } @@ -411,7 +411,7 @@ pub mod pallet { Self::deposit_event(Event::Charged { who: exchanger, - pool_id, + pid: pool_id, rewards, }); Ok(()) @@ -468,7 +468,7 @@ pub mod pallet { Self::deposit_event(Event::Deposited { who: exchanger, - pool_id, + pid: pool_id, add_value, gauge_info, }); @@ -508,7 +508,7 @@ pub mod pallet { Self::deposit_event(Event::Withdrawn { who: exchanger, - pool_id, + pid: pool_id, remove_value, }); Ok(()) @@ -542,7 +542,7 @@ pub mod pallet { Self::deposit_event(Event::Claimed { who: exchanger, - pool_id, + pid: pool_id, }); Ok(()) } @@ -558,7 +558,7 @@ pub mod pallet { Self::deposit_event(Event::WithdrawClaimed { who: exchanger, - pool_id, + pid: pool_id, }); Ok(()) } @@ -577,7 +577,7 @@ pub mod pallet { pool_info.state = PoolState::Dead; PoolInfos::::insert(pool_id, pool_info); - Self::deposit_event(Event::FarmingPoolClosed { pool_id }); + Self::deposit_event(Event::FarmingPoolClosed { pid: pool_id }); Ok(()) } @@ -633,9 +633,9 @@ pub mod pallet { pool_info.state = PoolState::Retired; pool_info.gauge = None; PoolInfos::::insert(pool_id, pool_info); - Self::deposit_event(Event::AllRetired { pool_id }); + Self::deposit_event(Event::AllRetired { pid: pool_id }); } else { - Self::deposit_event(Event::PartiallyRetired { pool_id }); + Self::deposit_event(Event::PartiallyRetired { pid: pool_id }); } Ok(()) } @@ -702,7 +702,7 @@ pub mod pallet { pool_info.block_startup = None; PoolInfos::::insert(pool_id, &pool_info); - Self::deposit_event(Event::FarmingPoolReset { pool_id }); + Self::deposit_event(Event::FarmingPoolReset { pid: pool_id }); Ok(()) } @@ -720,7 +720,7 @@ pub mod pallet { SharesAndWithdrawnRewards::::remove_prefix(pool_id, None); PoolInfos::::remove(pool_id); - Self::deposit_event(Event::FarmingPoolKilled { pool_id }); + Self::deposit_event(Event::FarmingPoolKilled { pid: pool_id }); Ok(()) } @@ -775,7 +775,7 @@ pub mod pallet { }; PoolInfos::::insert(pool_id, &pool_info); - Self::deposit_event(Event::FarmingPoolEdited { pool_id }); + Self::deposit_event(Event::FarmingPoolEdited { pid: pool_id }); Ok(()) } From e6d5bc94f5bf71b17434de018e79899b2bf41219 Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 4 Jul 2023 22:39:08 +0800 Subject: [PATCH 25/26] ensure retire limit not zero Signed-off-by: zqhxuyuan --- pallets/farming/src/gauge.rs | 99 ++++++++++++++++++++---------------- pallets/farming/src/lib.rs | 4 ++ pallets/farming/src/tests.rs | 14 +++-- 3 files changed, 70 insertions(+), 47 deletions(-) diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 7bb07f2ce..e02ae3530 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -207,50 +207,8 @@ where Error::::GaugeMaxBlockOverflow ); - let increase_total_time_factor = if gauge_info.gauge_amount.is_zero() { - gauge_info.gauge_stop_block = current_block_number; - gauge_info.gauge_start_block = current_block_number; - gauge_info.last_claim_block = current_block_number; - gauge_info.total_time_factor = gauge_block - .saturated_into::() - .checked_mul(gauge_value.saturated_into::()) - .ok_or(ArithmeticError::Overflow)?; - gauge_info.total_time_factor - } else { - let time_factor_a = gauge_value - .saturated_into::() - .checked_mul( - (gauge_info.gauge_stop_block - current_block_number).saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - let time_factor_b = gauge_block - .saturated_into::() - .checked_mul( - (gauge_value - .checked_add(&gauge_info.gauge_amount) - .ok_or(ArithmeticError::Overflow)?) - .saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - let increase_total_time_factor = time_factor_a + time_factor_b; - gauge_info.total_time_factor = gauge_info - .total_time_factor - .checked_add(increase_total_time_factor) - .ok_or(ArithmeticError::Overflow)?; - // latest_time_factor only increases in not first gauge_deposit - let increase_latest_time_factor = gauge_info - .gauge_amount - .saturated_into::() - .checked_mul( - (current_block_number - gauge_info.gauge_last_block).saturated_into::(), - ) - .ok_or(ArithmeticError::Overflow)?; - gauge_info.latest_time_factor = gauge_info - .latest_time_factor - .checked_add(increase_latest_time_factor) - .ok_or(ArithmeticError::Overflow)?; - increase_total_time_factor - }; + let increase_total_time_factor = + Self::get_time_factor(gauge_info, current_block_number, gauge_value, gauge_block)?; gauge_info.gauge_last_block = current_block_number; gauge_info.gauge_amount = gauge_info @@ -423,4 +381,57 @@ where ); Ok((gauge_rate, latest_claimed_time_factor)) } + + fn get_time_factor( + gauge_info: &mut GaugeInfoOf, + current_block_number: BlockNumberFor, + gauge_value: BalanceOf, + gauge_block: BlockNumberFor, + ) -> Result { + let increase_total_time_factor = if gauge_info.gauge_amount.is_zero() { + gauge_info.gauge_stop_block = current_block_number; + gauge_info.gauge_start_block = current_block_number; + gauge_info.last_claim_block = current_block_number; + gauge_info.total_time_factor = gauge_block + .saturated_into::() + .checked_mul(gauge_value.saturated_into::()) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.total_time_factor + } else { + let time_factor_a = gauge_value + .saturated_into::() + .checked_mul( + (gauge_info.gauge_stop_block - current_block_number).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let time_factor_b = gauge_block + .saturated_into::() + .checked_mul( + (gauge_value + .checked_add(&gauge_info.gauge_amount) + .ok_or(ArithmeticError::Overflow)?) + .saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + let increase_total_time_factor = time_factor_a + time_factor_b; + gauge_info.total_time_factor = gauge_info + .total_time_factor + .checked_add(increase_total_time_factor) + .ok_or(ArithmeticError::Overflow)?; + // latest_time_factor only increases in not first gauge_deposit + let increase_latest_time_factor = gauge_info + .gauge_amount + .saturated_into::() + .checked_mul( + (current_block_number - gauge_info.gauge_last_block).saturated_into::(), + ) + .ok_or(ArithmeticError::Overflow)?; + gauge_info.latest_time_factor = gauge_info + .latest_time_factor + .checked_add(increase_latest_time_factor) + .ok_or(ArithmeticError::Overflow)?; + increase_total_time_factor + }; + Ok(increase_total_time_factor) + } } diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index a1447e771..20fbea6bc 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -209,6 +209,8 @@ pub mod pallet { WithdrawLimitCountExceeded, /// Can not deposit to pool yet CanNotDeposit, + /// The retire limit number is not set + RetireLimitNotSet, } /// The next farming pool id. @@ -607,6 +609,7 @@ pub mod pallet { let withdraw_limit_time = BlockNumberFor::::default(); let retire_limit = RetireLimit::::get(); + ensure!(retire_limit > 0, Error::::RetireLimitNotSet); let mut all_retired = true; let share_infos = SharesAndWithdrawnRewards::::iter_prefix_values(pool_id); for (retire_count, share_info) in share_infos.enumerate() { @@ -827,6 +830,7 @@ pub mod pallet { let gauge_infos = GaugeInfos::::iter_prefix_values(gid); let retire_limit = RetireLimit::::get(); + ensure!(retire_limit > 0, Error::::RetireLimitNotSet); let mut all_retired = true; for (retire_count, gauge_info) in gauge_infos.enumerate() { if retire_count.saturated_into::() >= retire_limit { diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 26eaacd21..de832cb09 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -1736,6 +1736,10 @@ fn gauge() { )); System::set_block_number(System::block_number() + 200); + assert_noop!( + Farming::force_gauge_claim(RuntimeOrigin::signed(ALICE), pool_id), + Error::::RetireLimitNotSet + ); assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); assert_ok!(Farming::force_gauge_claim( RuntimeOrigin::signed(ALICE), @@ -1848,9 +1852,6 @@ fn pool_admin_operation_should_work() { let pool: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool.state, PoolState::Dead); - assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); - System::set_block_number(System::block_number() + 1000); - // Pool is dead, not allow to close again, deposit, reset, kill or edit. assert_noop!( Farming::close_pool(RuntimeOrigin::signed(ALICE), pool_id), @@ -1892,6 +1893,13 @@ fn pool_admin_operation_should_work() { ); // Retire pool + assert_noop!( + Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id), + Error::::RetireLimitNotSet + ); + assert_ok!(Farming::set_retire_limit(RuntimeOrigin::signed(ALICE), 10)); + System::set_block_number(System::block_number() + 1000); + assert_ok!(Farming::retire_pool(RuntimeOrigin::signed(ALICE), pool_id)); let pool: PoolInfoOf = Farming::pool_infos(pool_id).unwrap(); assert_eq!(pool.state, PoolState::Retired); From 9e70eb02b92542b9783b4377128e78cfb278376f Mon Sep 17 00:00:00 2001 From: zqhxuyuan Date: Tue, 4 Jul 2023 22:49:39 +0800 Subject: [PATCH 26/26] retire limit Signed-off-by: zqhxuyuan --- pallets/farming/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 20fbea6bc..5ea4ee9ca 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -606,10 +606,10 @@ pub mod pallet { PoolState::state_valid(Action::RetirePool, pool_info.state), Error::::InvalidPoolState ); - - let withdraw_limit_time = BlockNumberFor::::default(); let retire_limit = RetireLimit::::get(); ensure!(retire_limit > 0, Error::::RetireLimitNotSet); + + let withdraw_limit_time = BlockNumberFor::::default(); let mut all_retired = true; let share_infos = SharesAndWithdrawnRewards::::iter_prefix_values(pool_id); for (retire_count, share_info) in share_infos.enumerate() { @@ -827,10 +827,10 @@ pub mod pallet { #[pallet::weight(1000)] pub fn force_gauge_claim(origin: OriginFor, gid: PoolId) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - - let gauge_infos = GaugeInfos::::iter_prefix_values(gid); let retire_limit = RetireLimit::::get(); ensure!(retire_limit > 0, Error::::RetireLimitNotSet); + + let gauge_infos = GaugeInfos::::iter_prefix_values(gid); let mut all_retired = true; for (retire_count, gauge_info) in gauge_infos.enumerate() { if retire_count.saturated_into::() >= retire_limit {