diff --git a/Cargo.lock b/Cargo.lock index fc59443380..93356ed6e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5930,9 +5930,11 @@ dependencies = [ name = "pallet-issuance" version = "2.0.0" dependencies = [ + "cfg-if 1.0.0", "frame-benchmarking", "frame-support", "frame-system", + "log", "mangata-primitives", "orml-tokens", "orml-traits", diff --git a/README.md b/README.md index 6ed99ea7a3..5c846f61a4 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ ![Language](https://img.shields.io/github/languages/top/mangata-finance/mangata-node) ## Description -Reliable decentralized exchange (DEX) blockchain - interoperable with other blockchains using Polkadot. The exchange is using a consensus algorithm that solves MEV/frontrunning problems and makes all participants' access to trading opportunities equal. + +Reliable decentralized exchange (DEX) blockchain - interoperable with other blockchains using Polkadot. The exchange is using a consensus algorithm that solves MEV/frontrunning problems and makes all participants' access to trading opportunities equal. The design of the blockchain guarantees fixed-fees that provides greater control of trading costs and higher arbitrage opportunity. Assets on the exchange will serve multiple purposes- at the first iteration, they are the block producer’s stake and exchange liquidity at the same time, and more comes later. @@ -48,11 +49,14 @@ Find manual setup instructions at the Recommended rustc version for the build is `nightly-2021-10-19` Environment variables for ethereum apps should be set up before the build: + ```bash ETH_APP_ID=0xdd514baa317bf095ddba2c0a847765feb389c6a0 ERC20_APP_ID=0x00e392c04743359e39f00cd268a5390d27ef6b44 ``` + build node: + ```bash rustup target add wasm32-unknown-unknown cargo build --release @@ -99,18 +103,23 @@ docker-compose -f devops/multi-validator-docker-compose.yml up ### VS code Export RUSTFLAGS + ```bash export RUSTFLAGS="-g" ``` + Build node: + ```bash cargo build --release ``` + Run node: + ```bash RUSTFLAGS="-g" cargo run -j12 --release -- --tmp --dev ``` -Go to VS code and attach the process! +Go to VS code and attach the process! # Mangata Substrate Cumulus Parachain diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index ac7e338aae..7016727f0a 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -3,17 +3,12 @@ use codec::Encode; use cumulus_primitives_core::ParaId; use hex::FromHex; use hex_literal::hex; -use mangata_runtime::{ - AccountId, AuraId, BlockNumber, IssuanceInfo, Signature, VersionedMultiLocation, KSM_TOKEN_ID, -}; +use mangata_runtime::{AccountId, AuraId, Signature, VersionedMultiLocation, KSM_TOKEN_ID}; use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; use sc_service::ChainType; use serde::{Deserialize, Serialize}; use sp_core::{sr25519, ByteArray, Pair, Public, H160}; -use sp_runtime::{ - traits::{IdentifyAccount, Verify}, - Perbill, -}; +use sp_runtime::traits::{IdentifyAccount, Verify}; pub mod public_testnet_keys { pub const ALICE_SR25519: &str = diff --git a/pallets/asset-registry/src/benchmarking.rs b/pallets/asset-registry/src/benchmarking.rs index f767e57ef9..f1d19fdc22 100644 --- a/pallets/asset-registry/src/benchmarking.rs +++ b/pallets/asset-registry/src/benchmarking.rs @@ -62,5 +62,5 @@ benchmarks! { assert_eq!(Pallet::::location_to_currency_ids(MultiLocation::try_from(location).unwrap()), Some(next_currency_id)); } - impl_benchmark_test_suite!(Pallet, crate::tests::new_test_ext(), crate::tests::Test) + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime) } diff --git a/pallets/bootstrap/src/benchmarking.rs b/pallets/bootstrap/src/benchmarking.rs index f63ed896c0..4e5e837a8c 100644 --- a/pallets/bootstrap/src/benchmarking.rs +++ b/pallets/bootstrap/src/benchmarking.rs @@ -47,6 +47,8 @@ benchmarks! { } let ksm_provision_amount = 100_000_u128; let mga_provision_amount = ksm_provision_amount * T::KsmToMgaRatioDenominator::get() / T::KsmToMgaRatioNumerator::get(); + ::Currency::mint(::MGATokenId::get().into(), &caller, MILION.into()).expect("Token creation failed"); + ::Currency::mint(::KSMTokenId::get().into(), &caller, MILION.into()).expect("Token creation failed"); BootstrapPallet::::start_ido(RawOrigin::Root.into(), 10_u32.into(), 10_u32, 10_u32).unwrap(); // jump to public phase @@ -58,6 +60,7 @@ benchmarks! { assert_eq!(BootstrapPallet::::provisions(caller, ::KSMTokenId::get()), ksm_provision_amount); } + provision_vested { let caller: T::AccountId = whitelisted_caller(); let mut token_id = 0; @@ -65,11 +68,16 @@ benchmarks! { token_id < ::KSMTokenId::get() { token_id = ::Currency::create(&caller, MILION.into()).expect("Token creation failed").into(); } + ::Currency::mint(::MGATokenId::get().into(), &caller, MILION.into()).expect("Token creation failed"); + ::Currency::mint(::KSMTokenId::get().into(), &caller, MILION.into()).expect("Token creation failed"); let ksm_provision_amount = 100_000_u128; let mga_provision_amount = ksm_provision_amount * T::KsmToMgaRatioDenominator::get() / T::KsmToMgaRatioNumerator::get(); - let lock = 100_u128; - ::VestingProvider::lock_tokens(&caller, ::KSMTokenId::get().into(), ksm_provision_amount.into(), lock.into()).unwrap(); + let lock = 100_000_000_u128; + + frame_system::Pallet::::set_block_number(1_u32.into()); + ::VestingProvider::lock_tokens(&caller, ::KSMTokenId::get().into(), (ksm_provision_amount*2).into(), lock.into()).unwrap(); + frame_system::Pallet::::set_block_number(2_u32.into()); BootstrapPallet::::start_ido(RawOrigin::Root.into(), 10_u32.into(), 10_u32, 10_u32).unwrap(); // jump to public phase @@ -78,7 +86,7 @@ benchmarks! { }: provision_vested(RawOrigin::Signed(caller.clone().into()), ::KSMTokenId::get(), ksm_provision_amount) verify { - assert_eq!(BootstrapPallet::::vested_provisions(caller, ::KSMTokenId::get()), (ksm_provision_amount, lock + 1)); + assert_eq!(BootstrapPallet::::vested_provisions(caller, ::KSMTokenId::get()).0, (ksm_provision_amount)); } claim_rewards { @@ -88,6 +96,8 @@ benchmarks! { token_id < ::KSMTokenId::get() { token_id = ::Currency::create(&caller, MILION.into()).expect("Token creation failed").into(); } + ::Currency::mint(::MGATokenId::get().into(), &caller, MILION.into()).expect("Token creation failed"); + ::Currency::mint(::KSMTokenId::get().into(), &caller, MILION.into()).expect("Token creation failed"); let ksm_provision_amount = 100_000_u128; let ksm_vested_provision_amount = 300_000_u128; let mga_provision_amount = ksm_provision_amount * T::KsmToMgaRatioDenominator::get() / T::KsmToMgaRatioNumerator::get(); @@ -97,8 +107,8 @@ benchmarks! { let total_provision = total_ksm_provision + total_mga_provision; let lock = 150_u128; - ::VestingProvider::lock_tokens(&caller, ::KSMTokenId::get().into(), ksm_vested_provision_amount.into(), lock.into()).unwrap(); - ::VestingProvider::lock_tokens(&caller, ::MGATokenId::get().into(), mga_vested_provision_amount.into(), lock.into()).unwrap(); + ::VestingProvider::lock_tokens(&caller, ::KSMTokenId::get().into(), (ksm_provision_amount + ksm_vested_provision_amount).into(), lock.into()).unwrap(); + ::VestingProvider::lock_tokens(&caller, ::MGATokenId::get().into(), (mga_provision_amount + mga_vested_provision_amount).into(), lock.into()).unwrap(); BootstrapPallet::::start_ido(RawOrigin::Root.into(), 10_u32.into(), 10_u32, 10_u32).unwrap(); BootstrapPallet::::on_initialize(20_u32.into()); diff --git a/pallets/bootstrap/src/lib.rs b/pallets/bootstrap/src/lib.rs index e95f1930ab..8cd057d2a5 100644 --- a/pallets/bootstrap/src/lib.rs +++ b/pallets/bootstrap/src/lib.rs @@ -28,8 +28,11 @@ mod benchmarking; #[cfg(test)] mod tests; +pub mod weights; +pub use weights::WeightInfo; + pub use pallet::*; -const PALLET_ID: PalletId = PalletId(*b"12345678"); +const PALLET_ID: PalletId = PalletId(*b"bootstrp"); use core::fmt::Debug; @@ -65,21 +68,26 @@ pub mod pallet { #[pallet::hooks] impl Hooks for Pallet { fn on_initialize(n: T::BlockNumber) -> Weight { - let phase = Phase::::get(); + let phase = Phase::::get(); // R:1 if phase == BootstrapPhase::Finished { return T::DbWeight::get().reads(1) } if let Some((start, whitelist_length, public_length)) = BootstrapSchedule::::get() { + // R:1 // NOTE: arythmetics protected by invariant check in Bootstrap::start_ido let whitelist_start = start; let public_start = start + whitelist_length.into(); let finished = start + whitelist_length.into() + public_length.into(); if n >= finished { - Phase::::put(BootstrapPhase::Finished); + Phase::::put(BootstrapPhase::Finished); // 1 WRINTE log!(info, "bootstrap event finished"); let (mga_valuation, ksm_valuation) = Valuations::::get(); + // XykFunctionsTrait R: 11 W:12 + // PoolCreateApi::pool_create R:2 + + // --------------------------------- + // R: 13 W 12 if let Some((liq_asset_id, issuance)) = T::PoolCreateApi::pool_create( Self::vault_address(), T::KSMTokenId::get(), @@ -87,12 +95,12 @@ pub mod pallet { T::MGATokenId::get(), mga_valuation, ) { - MintedLiquidity::::put((liq_asset_id, issuance)); + MintedLiquidity::::put((liq_asset_id, issuance)); // W:1 } else { log!(error, "cannot create pool!"); } // TODO: include cost of pool_create call - T::DbWeight::get().reads_writes(3, 2) + T::DbWeight::get().reads_writes(15, 13) } else if n >= public_start { Phase::::put(BootstrapPhase::Public); log!(info, "starting public phase"); @@ -134,6 +142,8 @@ pub mod pallet { type KsmToMgaRatioDenominator: Get; type VestingProvider: MultiTokenVestingLocks; + + type WeightInfo: WeightInfo; } #[pallet::storage] diff --git a/pallets/bootstrap/src/mock.rs b/pallets/bootstrap/src/mock.rs index deec1d9310..00f9a0ee62 100644 --- a/pallets/bootstrap/src/mock.rs +++ b/pallets/bootstrap/src/mock.rs @@ -25,7 +25,7 @@ use frame_support::{ use mangata_primitives::{Amount, Balance, TokenId}; use orml_tokens::{MultiTokenCurrency, MultiTokenCurrencyAdapter}; use orml_traits::parameter_type_with_key; -use pallet_issuance::PoolPromoteApi; +use sp_runtime::{Perbill, Percent}; // use pallet_xyk::Pallet; pub(crate) type AccountId = u128; @@ -105,28 +105,6 @@ parameter_types! { pub FakeLiquidityMiningIssuanceVault: AccountId = LiquidityMiningIssuanceVaultId::get().into_account(); } -pub struct MockPromotedPoolApi; - -impl MockPromotedPoolApi {} - -impl PoolPromoteApi for MockPromotedPoolApi { - fn promote_pool(_liquidity_token_id: TokenId) -> bool { - false - } - - fn get_pool_rewards(_liquidity_token_id: TokenId) -> Option { - None - } - - fn claim_pool_rewards(_liquidity_token_id: TokenId, _claimed_amount: Balance) -> bool { - false - } - - fn len() -> usize { - 0 - } -} - parameter_types! { pub const MinVestedTransfer: Balance = 0; } @@ -149,7 +127,7 @@ impl pallet_xyk::Config for Test { type TreasuryPalletId = TreasuryPalletId; type BnbTreasurySubAccDerive = BnbTreasurySubAccDerive; type LiquidityMiningIssuanceVault = FakeLiquidityMiningIssuanceVault; - type PoolPromoteApi = MockPromotedPoolApi; + type PoolPromoteApi = Issuance; type PoolFeePercentage = ConstU128<20>; type TreasuryFeePercentage = ConstU128<5>; type BuyAndBurnFeePercentage = ConstU128<5>; @@ -158,6 +136,45 @@ impl pallet_xyk::Config for Test { type VestingProvider = Vesting; } +parameter_types! { + pub LiquidityMiningIssuanceVault: AccountId = LiquidityMiningIssuanceVaultId::get().into_account(); + pub const StakingIssuanceVaultId: PalletId = PalletId(*b"py/stkiv"); + pub StakingIssuanceVault: AccountId = StakingIssuanceVaultId::get().into_account(); + pub const MgaTokenId: TokenId = 0u32; + + + pub const TotalCrowdloanAllocation: Balance = 200_000_000; + pub const IssuanceCap: Balance = 4_000_000_000; + pub const LinearIssuanceBlocks: u32 = 22_222u32; + pub const LiquidityMiningSplit: Perbill = Perbill::from_parts(555555556); + pub const StakingSplit: Perbill = Perbill::from_parts(444444444); + pub const ImmediateTGEReleasePercent: Percent = Percent::from_percent(20); + pub const TGEReleasePeriod: u32 = 100u32; // 2 years + pub const TGEReleaseBegin: u32 = 10u32; // Two weeks into chain start + pub const BlocksPerRound: u32 = 5u32; + pub const HistoryLimit: u32 = 10u32; +} + +impl pallet_issuance::Config for Test { + type Event = Event; + type NativeCurrencyId = MgaTokenId; + type Tokens = orml_tokens::MultiTokenCurrencyAdapter; + type BlocksPerRound = BlocksPerRound; + type HistoryLimit = HistoryLimit; + type LiquidityMiningIssuanceVault = LiquidityMiningIssuanceVault; + type StakingIssuanceVault = StakingIssuanceVault; + type TotalCrowdloanAllocation = TotalCrowdloanAllocation; + type IssuanceCap = IssuanceCap; + type LinearIssuanceBlocks = LinearIssuanceBlocks; + type LiquidityMiningSplit = LiquidityMiningSplit; + type StakingSplit = StakingSplit; + type ImmediateTGEReleasePercent = ImmediateTGEReleasePercent; + type TGEReleasePeriod = TGEReleasePeriod; + type TGEReleaseBegin = TGEReleaseBegin; + type VestingProvider = Vesting; + type WeightInfo = (); +} + mockall::mock! { pub PoolCreateApi {} @@ -180,6 +197,7 @@ impl pallet_bootstrap::Config for Test { type KsmToMgaRatioNumerator = KsmToMgaNumerator; type KsmToMgaRatioDenominator = KsmToMgaDenominator; type VestingProvider = Vesting; + type WeightInfo = (); } #[cfg(feature = "runtime-benchmarks")] @@ -232,6 +250,7 @@ construct_runtime!( Xyk: pallet_xyk::{Pallet, Call, Storage, Event, Config}, Bootstrap: pallet_bootstrap::{Pallet, Call, Storage, Event}, Vesting: pallet_vesting_mangata::{Pallet, Call, Storage, Event}, + Issuance: pallet_issuance::{Pallet, Event, Storage}, } ); diff --git a/pallets/bootstrap/src/weights.rs b/pallets/bootstrap/src/weights.rs new file mode 100644 index 0000000000..695e419db2 --- /dev/null +++ b/pallets/bootstrap/src/weights.rs @@ -0,0 +1,40 @@ +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_bootstrap. +pub trait WeightInfo { + fn start_ido() -> Weight; + fn provision() -> Weight; + fn provision_vested() -> Weight; + fn claim_rewards() -> Weight; +} + + +// For backwards compatibility and tests +impl WeightInfo for () { + fn start_ido() -> Weight { + (23_396_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn provision() -> Weight { + (103_365_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + fn provision_vested() -> Weight { + (150_718_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn claim_rewards() -> Weight { + (273_011_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(13 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } +} diff --git a/pallets/issuance/Cargo.toml b/pallets/issuance/Cargo.toml index 457956e5af..87373bdf03 100644 --- a/pallets/issuance/Cargo.toml +++ b/pallets/issuance/Cargo.toml @@ -9,6 +9,7 @@ version = '2.0.0' targets = ['x86_64-unknown-linux-gnu'] [dependencies] +log = { version = "0.4.14", default-features = false } serde = { version = "1.0.126", optional = true } codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } scale-info = { version = "1.0", default-features = false, features = ["derive"] } @@ -20,6 +21,7 @@ sp-std = { default-features = false, version = '4.0.0-dev' , git = "https://gith sp-runtime = { git = "https://github.com/mangata-finance/substrate", default-features = false, branch = "mangata-dev" } pallet-vesting-mangata = { git = "https://github.com/mangata-finance/substrate", default-features = false, branch = "mangata-dev" } frame-benchmarking = { git = "https://github.com/mangata-finance/substrate", branch = "mangata-dev", optional = true, default-features = false } +cfg-if = "1.0.0" [dev-dependencies] sp-core = { default-features = false, version = '4.1.0-dev' , git = "https://github.com/mangata-finance/substrate", branch = "mangata-dev" } @@ -43,4 +45,4 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", -] \ No newline at end of file +] diff --git a/pallets/issuance/src/benchmarking.rs b/pallets/issuance/src/benchmarking.rs index 5bb8acb5a9..85cd6252d9 100644 --- a/pallets/issuance/src/benchmarking.rs +++ b/pallets/issuance/src/benchmarking.rs @@ -19,10 +19,10 @@ use super::*; -use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_benchmarking::{account, benchmarks}; use frame_support::assert_ok; use frame_system::RawOrigin; -use mangata_primitives::{Balance, TokenId}; +use mangata_primitives::Balance; use orml_tokens::MultiTokenCurrencyExtended; use crate::{Pallet as Issuance, TgeInfo}; diff --git a/pallets/issuance/src/lib.rs b/pallets/issuance/src/lib.rs index 71627f9525..2f0e1924f2 100644 --- a/pallets/issuance/src/lib.rs +++ b/pallets/issuance/src/lib.rs @@ -7,7 +7,7 @@ use frame_system::pallet_prelude::*; use frame_support::{ codec::{Decode, Encode}, - traits::{Currency, Get, Imbalance, LockableCurrency}, + traits::{Get, Imbalance}, }; use mangata_primitives::{Balance, TokenId}; use scale_info::TypeInfo; @@ -209,28 +209,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::init_issuance_config())] pub fn init_issuance_config(origin: OriginFor) -> DispatchResultWithPostInfo { ensure_root(origin)?; - - ensure!( - IssuanceConfigStore::::get().is_none(), - Error::::IssuanceConfigAlreadyInitialized - ); - ensure!(IsTGEFinalized::::get(), Error::::TGENotFinalized); - - let issuance_config: IssuanceInfo = IssuanceInfo { - cap: T::IssuanceCap::get(), - issuance_at_init: T::Tokens::total_issuance(T::NativeCurrencyId::get().into()) - .into(), - linear_issuance_blocks: T::LinearIssuanceBlocks::get(), - liquidity_mining_split: T::LiquidityMiningSplit::get(), - staking_split: T::StakingSplit::get(), - total_crowdloan_allocation: T::TotalCrowdloanAllocation::get(), - }; - - Pallet::::build_issuance_config(issuance_config.clone())?; - - Pallet::::deposit_event(Event::IssuanceConfigInitialized(issuance_config)); - - Ok(().into()) + Self::do_init_issuance_config() } #[pallet::weight(T::WeightInfo::finalize_tge())] @@ -322,10 +301,18 @@ pub mod pallet { } pub trait ComputeIssuance { + /// should be only used for testing purposes + fn initialize() {} fn compute_issuance(n: u32); } impl ComputeIssuance for Pallet { + /// should be only used for testing purposes + fn initialize() { + IsTGEFinalized::::put(true); + Self::do_init_issuance_config().unwrap(); + } + fn compute_issuance(n: u32) { let _ = Pallet::::calculate_and_store_round_issuance(n); let _ = Pallet::::clear_round_issuance_history(n); @@ -403,6 +390,29 @@ impl GetIssuance for Pallet { } impl Pallet { + pub fn do_init_issuance_config() -> DispatchResultWithPostInfo { + ensure!( + IssuanceConfigStore::::get().is_none(), + Error::::IssuanceConfigAlreadyInitialized + ); + ensure!(IsTGEFinalized::::get(), Error::::TGENotFinalized); + + let issuance_config: IssuanceInfo = IssuanceInfo { + cap: T::IssuanceCap::get(), + issuance_at_init: T::Tokens::total_issuance(T::NativeCurrencyId::get().into()).into(), + linear_issuance_blocks: T::LinearIssuanceBlocks::get(), + liquidity_mining_split: T::LiquidityMiningSplit::get(), + staking_split: T::StakingSplit::get(), + total_crowdloan_allocation: T::TotalCrowdloanAllocation::get(), + }; + + Pallet::::build_issuance_config(issuance_config.clone())?; + + Pallet::::deposit_event(Event::IssuanceConfigInitialized(issuance_config)); + + Ok(().into()) + } + pub fn build_issuance_config(issuance_config: IssuanceInfo) -> DispatchResult { ensure!( issuance_config diff --git a/pallets/xyk/src/benchmarking.rs b/pallets/xyk/src/benchmarking.rs index 59e08749d6..f36a5c31e0 100644 --- a/pallets/xyk/src/benchmarking.rs +++ b/pallets/xyk/src/benchmarking.rs @@ -22,14 +22,17 @@ use super::*; use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_support::assert_err; use frame_system::RawOrigin; use orml_tokens::MultiTokenCurrencyExtended; +use pallet_issuance::ComputeIssuance; use crate::Pallet as Xyk; const MILION: u128 = 1_000__000_000__000_000; benchmarks! { + create_pool { let caller: T::AccountId = whitelisted_caller(); let first_asset_amount = MILION; @@ -116,15 +119,66 @@ benchmarks! { initial_liquidity_amount.into() ); + Xyk::::mint_liquidity(RawOrigin::Signed(caller.clone().into()).into(), non_native_asset_id1.into(), non_native_asset_id2.into(), 20000000000000000000, 30000000000000000001).unwrap(); + + frame_system::Pallet::::set_block_number(100_000_u32.into()); + }: mint_liquidity(RawOrigin::Signed(caller.clone().into()), non_native_asset_id1.into(), non_native_asset_id2.into(), 20000000000000000000, 30000000000000000001) verify { assert_eq!( ::Currency::total_issuance(liquidity_asset_id.into()), - 75000000000000000000_u128.into() + 100000000000000000000_u128.into() + ); + } + + mint_liquidity_using_vesting_native_tokens { + // NOTE: duplicates test case XYK::mint_W + + let caller: T::AccountId = whitelisted_caller(); + let initial_amount:mangata_primitives::Balance = 1000000000000000000000; + let expected_native_asset_id : TokenId = ::NativeCurrencyId::get().into(); + let native_asset_id : TokenId = ::NativeCurrencyId::get(); + while ::Currency::create(&caller, initial_amount.into()).unwrap().into() < native_asset_id { + } + + ::Currency::mint(native_asset_id.into(), &caller, MILION.into()).expect("Token creation failed"); + let non_native_asset_id2 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let liquidity_asset_id = non_native_asset_id2 + 1; + let pool_creation_asset_1_amount = 40000000000000000000_u128; + let pool_creation_asset_2_amount = 60000000000000000000_u128; + let initial_liquidity_amount = pool_creation_asset_1_amount / 2_u128 + pool_creation_asset_2_amount / 2_u128; + let lock = 1_000_000_u128; + ::Currency::mint(::NativeCurrencyId::get().into(), &caller, initial_amount.into()).expect("Token creation failed"); + + Xyk::::create_pool(RawOrigin::Signed(caller.clone().into()).into(), native_asset_id.into(), pool_creation_asset_1_amount, non_native_asset_id2.into(), pool_creation_asset_2_amount).unwrap(); + Xyk::::promote_pool(RawOrigin::Root.into(), liquidity_asset_id).unwrap(); + + + assert_eq!( + ::Currency::total_issuance(liquidity_asset_id.into()), + initial_liquidity_amount.into() + ); + + frame_system::Pallet::::set_block_number(1_u32.into()); + ::VestingProvider::lock_tokens(&caller, native_asset_id.into(), (initial_amount - pool_creation_asset_1_amount).into(), lock.into()).unwrap(); + frame_system::Pallet::::set_block_number(2_u32.into()); + + Xyk::::mint_liquidity_using_vesting_native_tokens(RawOrigin::Signed(caller.clone().into()).into(), 10000000000000000000, non_native_asset_id2.into(), 20000000000000000000).unwrap(); + + frame_system::Pallet::::set_block_number(100_000_u32.into()); + let pre_minting_liq_token_amount = ::Currency::total_issuance(liquidity_asset_id.into()); + + }: mint_liquidity_using_vesting_native_tokens(RawOrigin::Signed(caller.clone().into()), 10000000000000000000, non_native_asset_id2.into(), 20000000000000000000) + verify { + assert!( + ::Currency::total_issuance(liquidity_asset_id.into()) > pre_minting_liq_token_amount ); } burn_liquidity { + // worse case scenario: + // burning whole liquidity that belongs to single user, where part of it is activated (as a result of mint_liquidity call) + // and the other part is not activated (as a result of create_pool call (by default) // NOTE: worst case scenario is when we want to burn whole liquidity because of the cleanup // that happens there @@ -144,55 +198,74 @@ benchmarks! { ::Currency::total_issuance(liquidity_asset_id.into()), initial_liquidity_amount.into() ); - assert!(Xyk::::liquidity_pool(liquidity_asset_id).is_some()); - }: burn_liquidity(RawOrigin::Signed(caller.clone().into()), non_native_asset_id1.into(), non_native_asset_id2.into(), initial_liquidity_amount) + Xyk::::mint_liquidity(RawOrigin::Signed(caller.clone().into()).into(), non_native_asset_id1.into(), non_native_asset_id2.into(), 20000000000000000000, 30000000000000000001).unwrap(); + + assert_ne!( + ::Currency::total_issuance(liquidity_asset_id.into()), + initial_liquidity_amount.into() + ); + + let total_liquidity_after_minting: u128 = ::Currency::total_issuance(liquidity_asset_id.into()).into(); + + }: burn_liquidity(RawOrigin::Signed(caller.clone().into()), non_native_asset_id1.into(), non_native_asset_id2.into(), total_liquidity_after_minting) verify { assert!(Xyk::::liquidity_pool(liquidity_asset_id).is_none()); } - // claim_rewards { - // - // // NOTE: that duplicates test XYK::liquidity_rewards_claim_W - // let caller: T::AccountId = whitelisted_caller(); - // let initial_amount:mangata_primitives::Balance = 1000000000000; - // - // let asset_id_1 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); - // let asset_id_2 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); - // let liquidity_asset_id = asset_id_2 + 1; - // - // Xyk::::create_pool(RawOrigin::Signed(caller.clone().into()).into(), asset_id_1.into(), 5000, asset_id_2.into(), 5000).unwrap(); - // - // frame_system::Pallet::::set_block_number(30001_u32.into()); - // - // let rewards_to_claim = 30000; - // let (rewards_total_user, rewards_claimed_user) = Xyk::::calculate_rewards_amount(caller.clone(), liquidity_asset_id, rewards_to_claim).unwrap(); - // let pool_rewards = Xyk::::calculate_available_rewards_for_pool(liquidity_asset_id, rewards_to_claim).unwrap(); - // - // assert_eq!(pool_rewards, 30000000); - // assert_eq!(rewards_total_user, 30000000); - // assert_eq!(rewards_claimed_user, 0); - // assert!(LiquidityMiningUserClaimed::::try_get((caller.clone(), liquidity_asset_id)).is_err()); - // assert!(LiquidityMiningPoolClaimed::::try_get(liquidity_asset_id).is_err()); - // - // }: claim_rewards(RawOrigin::Signed(caller.clone().into()), liquidity_asset_id, rewards_to_claim as u128 ) - // - // verify { - // assert_eq!( - // Xyk::::liquidity_mining_user_claimed((caller.clone(), liquidity_asset_id)), - // (rewards_claimed_user as i128) + ( rewards_to_claim as i128 ) - // ); - // - // assert_eq!( - // Xyk::::liquidity_mining_pool_claimed(liquidity_asset_id), - // rewards_to_claim as u128 - // ); - // - // } + // mint_liquidity_using_vesting_native_tokens + // mess up + claim_rewards { - promote_pool { + // NOTE: need to use actual issuance pallet and call its hooks properly + // NOTE: that duplicates test XYK::liquidity_rewards_claim_W + let caller: T::AccountId = whitelisted_caller(); + let initial_amount:mangata_primitives::Balance = 1000000000000000; + + let asset_id_1 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let asset_id_2 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let liquidity_asset_id = asset_id_2 + 1; + <::PoolPromoteApi as ComputeIssuance>::initialize(); + Xyk::::create_pool(RawOrigin::Signed(caller.clone().into()).into(), asset_id_1.into(), 5000, asset_id_2.into(), 5000).unwrap(); + Xyk::::promote_pool(RawOrigin::Root.into(), liquidity_asset_id).unwrap(); + + frame_system::Pallet::::set_block_number(100_000u32.into()); + <::PoolPromoteApi as ComputeIssuance>::compute_issuance(1); + + // activate liquidity by minting + Xyk::::mint_liquidity(RawOrigin::Signed(caller.clone().into()).into(), asset_id_1.into(), asset_id_2.into(), 200000000000000, 300000000000000).unwrap(); + frame_system::Pallet::::set_block_number(200_000_u32.into()); + + Xyk::::burn_liquidity(RawOrigin::Signed(caller.clone().into()).into(), asset_id_1.into(), asset_id_2.into(), 150000000000000).unwrap(); + + frame_system::Pallet::::set_block_number(300_000_u32.into()); + <::PoolPromoteApi as ComputeIssuance>::compute_issuance(2); + + let (rewards_total_user, rewards_claimed_user) = Xyk::::calculate_rewards_amount(caller.clone(), liquidity_asset_id).unwrap(); + let rewards_to_claim = rewards_total_user + rewards_claimed_user; + + let pre_claim_native_tokens_amount = ::Currency::free_balance(::NativeCurrencyId::get().into(), &caller).into(); + + // frame_system::Pallet::::set_block_number(100_000_000u32.into()); + + }: claim_rewards(RawOrigin::Signed(caller.clone().into()), liquidity_asset_id, rewards_to_claim as u128 ) + + verify { + + assert_eq!( + Xyk::::calculate_rewards_amount(caller.clone(), liquidity_asset_id).unwrap(), + (0_u128,0_u128) + ); + let post_claim_native_tokens_amount = ::Currency::free_balance(::NativeCurrencyId::get().into(), &caller).into(); + + assert!( pre_claim_native_tokens_amount < post_claim_native_tokens_amount); + + } + + + promote_pool { // NOTE: that duplicates test XYK::liquidity_rewards_claim_W let caller: T::AccountId = whitelisted_caller(); let initial_amount:mangata_primitives::Balance = 1000000000000; @@ -208,12 +281,89 @@ benchmarks! { }: promote_pool(RawOrigin::Root, liquidity_asset_id) verify { - assert_ne!( - Xyk::::pool_promotion_start(liquidity_asset_id), - 0 + assert_err!( + Xyk::::promote_pool(RawOrigin::Root.into(), liquidity_asset_id), + Error::::PoolAlreadyPromoted ); + } + + activate_liquidity { + // activate : + // 1 crate pool + // 2 promote pool + // 3 mint some tokens + // 3 activate whole amount from which pool was created (with liquidity tokens) + + let caller: ::AccountId = whitelisted_caller(); + let initial_amount:mangata_primitives::Balance = 1000000000000000000000; + let expected_native_asset_id : TokenId = ::NativeCurrencyId::get().into(); + let native_asset_id : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let non_native_asset_id1 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let non_native_asset_id2 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let liquidity_asset_id = non_native_asset_id2 + 1; + let initial_liquidity_amount = 40000000000000000000_u128 / 2_u128 + 60000000000000000000_u128 / 2_u128; + + Xyk::::create_pool(RawOrigin::Signed(caller.clone().into()).into(), non_native_asset_id1.into(), 40000000000000000000, non_native_asset_id2.into(), 60000000000000000000).unwrap(); + Xyk::::promote_pool(RawOrigin::Root.into(), liquidity_asset_id).unwrap(); + + assert_eq!( + ::Currency::total_issuance(liquidity_asset_id.into()), + initial_liquidity_amount.into() + ); + + Xyk::::mint_liquidity(RawOrigin::Signed(caller.clone().into()).into(), non_native_asset_id1.into(), non_native_asset_id2.into(), 20000000000000000000, 30000000000000000001).unwrap(); + + + frame_system::Pallet::::set_block_number(100_000_u32.into()); + }: activate_liquidity(RawOrigin::Signed(caller.clone().into()), liquidity_asset_id.into(), initial_liquidity_amount) + verify { + + assert_err!( + Xyk::::activate_liquidity(RawOrigin::Signed(caller.clone().into()).into(), liquidity_asset_id, 1_u32.into()), + Error::::NotEnoughAssets + ) + } + + deactivate_liquidity { + // deactivate + // 1 crate pool + // 2 promote pool + // 3 mint some tokens + // deactivate some tokens (all or some - to be checked) + + let caller: ::AccountId = whitelisted_caller(); + let initial_amount:mangata_primitives::Balance = 1000000000000000000000; + let expected_native_asset_id : TokenId = ::NativeCurrencyId::get().into(); + let native_asset_id : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let non_native_asset_id1 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let non_native_asset_id2 : TokenId= ::Currency::create(&caller, initial_amount.into()).unwrap().into(); + let liquidity_asset_id = non_native_asset_id2 + 1; + let initial_liquidity_amount = 40000000000000000000_u128 / 2_u128 + 60000000000000000000_u128 / 2_u128; + + Xyk::::create_pool(RawOrigin::Signed(caller.clone().into()).into(), non_native_asset_id1.into(), 40000000000000000000, non_native_asset_id2.into(), 60000000000000000000).unwrap(); + Xyk::::promote_pool(RawOrigin::Root.into(), liquidity_asset_id).unwrap(); + + assert_eq!( + ::Currency::total_issuance(liquidity_asset_id.into()), + initial_liquidity_amount.into() + ); + + Xyk::::mint_liquidity(RawOrigin::Signed(caller.clone().into()).into(), non_native_asset_id1.into(), non_native_asset_id2.into(), 20000000000000000000, 30000000000000000001).unwrap(); + + + frame_system::Pallet::::set_block_number(100_000_u32.into()); + + }: deactivate_liquidity(RawOrigin::Signed(caller.clone().into()), liquidity_asset_id.into(), 25000000000000000000_u128.into()) + verify { + assert_err!( + Xyk::::deactivate_liquidity(RawOrigin::Signed(caller.clone().into()).into(), liquidity_asset_id, 1_u32.into()), + Error::::NotEnoughAssets + ) } + + + impl_benchmark_test_suite!(Xyk, crate::mock::new_test_ext(), crate::mock::Test) } diff --git a/pallets/xyk/src/lib.rs b/pallets/xyk/src/lib.rs index 18bc8935e2..1b3c3e9990 100644 --- a/pallets/xyk/src/lib.rs +++ b/pallets/xyk/src/lib.rs @@ -233,9 +233,9 @@ use frame_support::{ }; use frame_system::pallet_prelude::*; use mangata_primitives::{Balance, TokenId}; -use orml_tokens::{MultiTokenCurrency, MultiTokenCurrencyExtended}; +use orml_tokens::{MultiTokenCurrency, MultiTokenCurrencyExtended, MultiTokenReservableCurrency}; use pallet_assets_info as assets_info; -use pallet_issuance::PoolPromoteApi; +use pallet_issuance::{ComputeIssuance, PoolPromoteApi}; use pallet_vesting_mangata::MultiTokenVestingLocks; use sp_arithmetic::helpers_128bit::multiply_by_rational; use sp_bootstrap::PoolCreateApi; @@ -297,11 +297,12 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config + pallet_assets_info::Config { type Event: From> + IsType<::Event>; - type Currency: MultiTokenCurrencyExtended; + type Currency: MultiTokenCurrencyExtended + + MultiTokenReservableCurrency; type NativeCurrencyId: Get; type TreasuryPalletId: Get; type BnbTreasurySubAccDerive: Get<[u8; 4]>; - type PoolPromoteApi: PoolPromoteApi; + type PoolPromoteApi: ComputeIssuance + PoolPromoteApi; #[pallet::constant] /// The account id that holds the liquidity mining issuance type LiquidityMiningIssuanceVault: Get; @@ -362,6 +363,7 @@ pub mod pallet { PastTimeCalculation, /// Pool already promoted PoolAlreadyPromoted, + /// Sold Amount too low SoldAmountTooLow, } @@ -373,6 +375,9 @@ pub mod pallet { LiquidityMinted(T::AccountId, TokenId, Balance, TokenId, Balance, TokenId, Balance), LiquidityBurned(T::AccountId, TokenId, Balance, TokenId, Balance, TokenId, Balance), PoolPromoted(TokenId), + LiquidityActivated(T::AccountId, TokenId, Balance), + LiquidityDeactivated(T::AccountId, TokenId, Balance), + RewardsClaimed(T::AccountId, TokenId, Balance), } #[pallet::storage] @@ -406,8 +411,15 @@ pub mod pallet { StorageMap<_, Blake2_256, (AccountIdOf, TokenId), u128, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn pool_promotion_start)] - pub type PoolPromotionStart = StorageMap<_, Twox64Concat, TokenId, u32, ValueQuery>; + #[pallet::getter(fn liquidity_mining_active_user)] + pub type LiquidityMiningActiveUser = + StorageMap<_, Twox64Concat, (AccountIdOf, TokenId), u128, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn liquidity_mining_active_pool)] + pub type LiquidityMiningActivePool = + StorageMap<_, Twox64Concat, TokenId, u128, ValueQuery>; + #[pallet::genesis_config] pub struct GenesisConfig { pub created_pools_for_staking: @@ -534,7 +546,7 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(10_000)] + #[pallet::weight(T::WeightInfo::mint_liquidity_using_vesting_native_tokens())] #[transactional] pub fn mint_liquidity_using_vesting_native_tokens( origin: OriginFor, @@ -627,12 +639,44 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(10_000)] + #[pallet::weight(T::WeightInfo::promote_pool())] pub fn promote_pool(origin: OriginFor, liquidity_token_id: TokenId) -> DispatchResult { ensure_root(origin)?; >::promote_pool(liquidity_token_id) } + + #[transactional] + #[pallet::weight(10_000)] + pub fn activate_liquidity( + origin: OriginFor, + liquidity_token_id: TokenId, + amount: Balance, + ) -> DispatchResult { + let sender = ensure_signed(origin)?; + + >::activate_liquidity( + sender, + liquidity_token_id, + amount, + ) + } + + #[transactional] + #[pallet::weight(T::WeightInfo::deactivate_liquidity())] + pub fn deactivate_liquidity( + origin: OriginFor, + liquidity_token_id: TokenId, + amount: Balance, + ) -> DispatchResult { + let sender = ensure_signed(origin)?; + + >::deactivate_liquidity( + sender, + liquidity_token_id, + amount, + ) + } } } @@ -643,56 +687,46 @@ impl Pallet { T::BuyAndBurnFeePercentage::get() } - pub fn get_liquidity_minting_user( - user: AccountIdOf, - liquidity_asset_id: TokenId, - current_time: u32, - ) -> Result<(u32, U256, U256), DispatchError> { - let liquidity_assets_amount = - ::Currency::total_balance(liquidity_asset_id.into(), &user).into(); - - match LiquidityMiningUser::::try_get((&user, &liquidity_asset_id)) { - Ok(result) => Ok(result), - Err(_) if liquidity_assets_amount == 0_u128 => - Ok((current_time, U256::from(0), U256::from(0))), - Err(_) => { - let pool_promotion_start = PoolPromotionStart::::get(liquidity_asset_id); - - let user_work_total = Self::calculate_work( - liquidity_assets_amount, - current_time, - pool_promotion_start, - U256::from(0), - liquidity_assets_amount.into(), - )?; - let time_passed = current_time - .checked_sub(pool_promotion_start) - .ok_or_else(|| DispatchError::from(Error::::PastTimeCalculation))?; - let user_missing_at_checkpoint = Self::calculate_missing_at_checkpoint( - time_passed, - Balance::try_from(0).unwrap(), - liquidity_assets_amount.into(), - )?; - - LiquidityMiningUser::::get((&user, &liquidity_asset_id)); - - Ok((current_time, user_work_total, user_missing_at_checkpoint)) - }, - } - } - pub fn calculate_rewards_amount( user: AccountIdOf, liquidity_asset_id: TokenId, ) -> Result<(Balance, Balance), DispatchError> { ensure!( - PoolPromotionStart::::contains_key(liquidity_asset_id), + ::PoolPromoteApi::get_pool_rewards(liquidity_asset_id).is_some(), Error::::NotAPromotedPool ); + let current_time: u32 = >::block_number().saturated_into::() / T::RewardsDistributionPeriod::get(); - let work_user = Self::calculate_work_user(user.clone(), liquidity_asset_id, current_time)?; - let work_pool = Self::calculate_work_pool(liquidity_asset_id, current_time)?; + let ( + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint, + ) = LiquidityMiningUser::::try_get((&user, &liquidity_asset_id)) + .unwrap_or_else(|_| (current_time, U256::from(0), U256::from(0))); + + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = LiquidityMiningPool::::try_get(&liquidity_asset_id) + .unwrap_or_else(|_| (current_time, U256::from(0), U256::from(0))); + + let work_user = Self::calculate_work_user( + user.clone(), + liquidity_asset_id, + current_time, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint, + )?; + let work_pool = Self::calculate_work_pool( + liquidity_asset_id, + current_time, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + )?; let burned_not_claimed_rewards = LiquidityMiningUserToBeClaimed::::get((user, &liquidity_asset_id)); @@ -717,11 +751,11 @@ impl Pallet { user_mangata_rewards_amount = Balance::try_from( available_rewards_for_pool .checked_mul(work_user) - .ok_or_else(|| DispatchError::from(Error::::MathOverflow))? + .ok_or_else(|| DispatchError::from(Error::::NotEnoughtRewardsEarned))? .checked_div(work_pool) .ok_or_else(|| DispatchError::from(Error::::DivisionByZero))?, ) - .map_err(|_| DispatchError::from(Error::::MathOverflow))?; + .map_err(|_| DispatchError::from(Error::::NotEnoughtRewardsEarned))?; } Ok(user_mangata_rewards_amount) @@ -739,7 +773,7 @@ impl Pallet { .checked_sub(last_checkpoint) .ok_or_else(|| DispatchError::from(Error::::PastTimeCalculation))?; - // whole formula: missing_at_last_checkpoint*106 - missing_at_last_checkpoint*106/q_pow + // whole formula: missing_at_last_checkpoint*106/6 - missing_at_last_checkpoint*106*precision/6/q_pow // q_pow is multiplied by precision, thus there needs to be *precision in numenator as well let asymptote_u256: U256 = asymptote.into(); let cummulative_work_new_max_possible: U256 = asymptote_u256 @@ -754,23 +788,24 @@ impl Pallet { let q_pow = Self::calculate_q_pow(Q, time_passed); let cummulative_missing_new = base - base * U256::from(precision) / q_pow; - let cummulative_work_new = cummulative_work_new_max_possible - cummulative_missing_new; + + let cummulative_work_new = cummulative_work_new_max_possible + .checked_sub(cummulative_missing_new) + .ok_or_else(|| DispatchError::from(Error::::MathOverflow))?; let work_total = cummulative_work_in_last_checkpoint + cummulative_work_new; Ok(work_total) } - //TODO MODIFY FOR POOL - // MAX: 1R 0W pub fn calculate_work_pool( liquidity_asset_id: TokenId, current_time: u32, + last_checkpoint: u32, + cummulative_work_in_last_checkpoint: U256, + missing_at_last_checkpoint: U256, ) -> Result { let liquidity_assets_amount: Balance = - ::Currency::total_issuance(liquidity_asset_id.into()).into(); - - let (last_checkpoint, cummulative_work_in_last_checkpoint, missing_at_last_checkpoint) = - LiquidityMiningPool::::get(&liquidity_asset_id); + LiquidityMiningActivePool::::get(&liquidity_asset_id); Self::calculate_work( liquidity_assets_amount, @@ -786,12 +821,12 @@ impl Pallet { user: AccountIdOf, liquidity_asset_id: TokenId, current_time: u32, + last_checkpoint: u32, + cummulative_work_in_last_checkpoint: U256, + missing_at_last_checkpoint: U256, ) -> Result { let liquidity_assets_amount: Balance = - ::Currency::total_balance(liquidity_asset_id.into(), &user).into(); - - let (last_checkpoint, cummulative_work_in_last_checkpoint, missing_at_last_checkpoint) = - Self::get_liquidity_minting_user(user.clone(), liquidity_asset_id, current_time)?; + LiquidityMiningActiveUser::::get((&user, &liquidity_asset_id)); Self::calculate_work( liquidity_assets_amount, @@ -834,9 +869,10 @@ impl Pallet { let ( user_last_checkpoint, - _user_cummulative_work_in_last_checkpoint, + user_cummulative_work_in_last_checkpoint, user_missing_at_last_checkpoint, - ) = Self::get_liquidity_minting_user(user.clone(), liquidity_asset_id, current_time)?; + ) = LiquidityMiningUser::::try_get((&user, &liquidity_asset_id)) + .unwrap_or_else(|_| (current_time, U256::from(0), U256::from(0))); let user_time_passed = current_time .checked_sub(user_last_checkpoint) @@ -846,14 +882,23 @@ impl Pallet { liquidity_assets_added, user_missing_at_last_checkpoint, )?; - let user_work_total = - Self::calculate_work_user(user.clone(), liquidity_asset_id, current_time)?; + + let user_work_total = Self::calculate_work_user( + user.clone(), + liquidity_asset_id, + current_time, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint, + )?; let ( pool_last_checkpoint, - _pool_cummulative_work_in_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, pool_missing_at_last_checkpoint, - ) = LiquidityMiningPool::::get(&liquidity_asset_id); + ) = LiquidityMiningPool::::try_get(&liquidity_asset_id) + .unwrap_or_else(|_| (current_time, U256::from(0), U256::from(0))); + let pool_time_passed = current_time .checked_sub(pool_last_checkpoint) .ok_or_else(|| DispatchError::from(Error::::PastTimeCalculation))?; @@ -863,7 +908,13 @@ impl Pallet { liquidity_assets_added, pool_missing_at_last_checkpoint, )?; - let pool_work_total = Self::calculate_work_pool(liquidity_asset_id, current_time)?; + let pool_work_total = Self::calculate_work_pool( + liquidity_asset_id, + current_time, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + )?; Ok(( current_time, @@ -902,6 +953,32 @@ impl Pallet { (current_time, pool_work_total, pool_missing_at_checkpoint), ); + LiquidityMiningActiveUser::::try_mutate((&user, liquidity_asset_id), |active_amount| { + if let Some(val) = active_amount.checked_add(liquidity_assets_added) { + *active_amount = val; + Ok(()) + } else { + Err(()) + } + }) + .map_err(|_| DispatchError::from(Error::::MathOverflow))?; + + LiquidityMiningActivePool::::try_mutate(liquidity_asset_id, |active_amount| { + if let Some(val) = active_amount.checked_add(liquidity_assets_added) { + *active_amount = val; + Ok(()) + } else { + Err(()) + } + }) + .map_err(|_| DispatchError::from(Error::::MathOverflow))?; + + ::Currency::reserve( + liquidity_asset_id.into(), + &user, + liquidity_assets_added.into(), + )?; + Ok(()) } @@ -919,8 +996,11 @@ impl Pallet { ) = Self::calculate_liquidity_checkpoint(user.clone(), liquidity_asset_id, 0 as u128)?; let liquidity_assets_amount: Balance = - ::Currency::total_balance(liquidity_asset_id.into(), &user).into(); - // let input_reserve_saturated: U256 = input_reserve.into(); + LiquidityMiningActiveUser::::get((&user, &liquidity_asset_id)); + + let activated_liquidity_pool: Balance = + LiquidityMiningActivePool::::get(&liquidity_asset_id); + let liquidity_assets_burned_u256: U256 = liquidity_assets_burned.into(); let user_work_burned: U256 = liquidity_assets_burned_u256 @@ -934,37 +1014,74 @@ impl Pallet { .checked_div(liquidity_assets_amount.into()) .ok_or_else(|| DispatchError::from(Error::::DivisionByZero))?; + let user_work_new = user_work_total + .checked_sub(user_work_burned) + .ok_or_else(|| DispatchError::from(Error::::MathOverflow))?; + let user_missing_new = user_missing_at_checkpoint + .checked_sub(user_missing_burned) + .ok_or_else(|| DispatchError::from(Error::::MathOverflow))?; + + let mut pool_work_new = U256::from(0); + let mut pool_missing_new = U256::from(0); + + if activated_liquidity_pool != liquidity_assets_burned { + pool_work_new = pool_work_total + .checked_sub(user_work_burned) + .ok_or_else(|| DispatchError::from(Error::::MathOverflow))?; + pool_missing_new = pool_missing_at_checkpoint + .checked_sub(user_missing_burned) + .ok_or_else(|| DispatchError::from(Error::::MathOverflow))?; + } + LiquidityMiningUser::::insert( (user.clone(), &liquidity_asset_id), - ( - current_time, - user_work_total - user_work_burned, - user_missing_at_checkpoint - user_missing_burned, - ), + (current_time, user_work_new, user_missing_new), ); LiquidityMiningPool::::insert( &liquidity_asset_id, - ( - current_time, - pool_work_total - user_work_burned, - pool_missing_at_checkpoint - user_missing_burned, - ), + (current_time, pool_work_new, pool_missing_new), ); + LiquidityMiningActiveUser::::try_mutate((&user, liquidity_asset_id), |active_amount| { + if let Some(val) = active_amount.checked_sub(liquidity_assets_burned) { + *active_amount = val; + Ok(()) + } else { + Err(()) + } + }) + .map_err(|_| DispatchError::from(Error::::NotEnoughAssets))?; + LiquidityMiningActivePool::::try_mutate(liquidity_asset_id, |active_amount| { + if let Some(val) = active_amount.checked_sub(liquidity_assets_burned) { + *active_amount = val; + Ok(()) + } else { + Err(()) + } + }) + .map_err(|_| DispatchError::from(Error::::NotEnoughAssets))?; + let rewards_to_be_claimed = LiquidityMiningUserToBeClaimed::::get((user.clone(), &liquidity_asset_id)); - let rewards_amount = Self::calculate_rewards(user_work_burned, pool_work_total, liquidity_asset_id)?; - let rewards_claimed_new = rewards_to_be_claimed + rewards_amount; - ::PoolPromoteApi::claim_pool_rewards(liquidity_asset_id, rewards_amount); + ::PoolPromoteApi::claim_pool_rewards( + liquidity_asset_id.into(), + rewards_amount, + ); LiquidityMiningUserToBeClaimed::::insert( (&user, liquidity_asset_id), rewards_claimed_new, ); + ::Currency::unreserve( + liquidity_asset_id.into(), + &user, + liquidity_assets_burned.into(), + ); + Ok(()) } @@ -1456,6 +1573,18 @@ pub trait XykFunctionsTrait { ) -> DispatchResult; fn promote_pool(liquidity_token_id: TokenId) -> DispatchResult; + + fn activate_liquidity( + sender: AccountId, + liquidity_token_id: Self::CurrencyId, + amount: Self::Balance, + ) -> DispatchResult; + + fn deactivate_liquidity( + sender: AccountId, + liquidity_token_id: Self::CurrencyId, + amount: Self::Balance, + ) -> DispatchResult; } impl XykFunctionsTrait for Pallet { @@ -2036,6 +2165,14 @@ impl XykFunctionsTrait for Pallet { second_asset_amount.into(), ExistenceRequirement::KeepAlive, )?; + + // Creating new liquidity tokens to user + ::Currency::mint( + liquidity_asset_id.into(), + &sender, + liquidity_assets_minted.into(), + )?; + // Liquidity minting functions not triggered on not promoted pool if ::PoolPromoteApi::get_pool_rewards(liquidity_asset_id).is_some() { Pallet::::set_liquidity_minting_checkpoint( @@ -2044,12 +2181,6 @@ impl XykFunctionsTrait for Pallet { liquidity_assets_minted, )?; } - // Creating new liquidity tokens to user - ::Currency::mint( - liquidity_asset_id.into(), - &sender, - liquidity_assets_minted.into(), - )?; // Apply changes in token pools, adding minted amounts // Won't overflow due earlier ensure @@ -2112,28 +2243,18 @@ impl XykFunctionsTrait for Pallet { let liquidity_asset_id = Pallet::::get_liquidity_asset(first_asset_id, second_asset_id)?; // Ensure user has enought liquidity tokens to burn + let liquidity_token_free_balance = + ::Currency::free_balance(liquidity_asset_id.into(), &sender).into(); + let liquidity_token_activated_balance = + LiquidityMiningActiveUser::::get((&sender, &liquidity_asset_id)); + let total_liquidity_tokens_user_owned = liquidity_token_free_balance + .checked_add(liquidity_token_activated_balance) + .ok_or_else(|| DispatchError::from(Error::::MathOverflow))?; + ensure!( - ::Currency::can_slash( - liquidity_asset_id.into(), - &sender, - liquidity_asset_amount.into() - ), + total_liquidity_tokens_user_owned >= liquidity_asset_amount, Error::::NotEnoughAssets, ); - let new_balance: Self::Balance = - ::Currency::free_balance(liquidity_asset_id.into(), &sender) - .into() - .checked_sub(liquidity_asset_amount) - .ok_or_else(|| DispatchError::from(Error::::NotEnoughAssets))?; - - ::Currency::ensure_can_withdraw( - liquidity_asset_id.into(), - &sender, - liquidity_asset_amount.into(), - WithdrawReasons::all(), - new_balance.into(), - ) - .or(Err(Error::::NotEnoughAssets))?; // Calculate first and second token amounts depending on liquidity amount to burn let (first_asset_amount, second_asset_amount) = Pallet::::get_burn_amount_reserves( @@ -2199,17 +2320,21 @@ impl XykFunctionsTrait for Pallet { ); if ::PoolPromoteApi::get_pool_rewards(liquidity_asset_id).is_some() { - if ::Currency::free_balance(liquidity_asset_id.into(), &sender).into() == - liquidity_asset_amount - { - LiquidityMiningUser::::remove((sender.clone(), liquidity_asset_id)); - } else { + // HARD + if liquidity_token_free_balance < liquidity_asset_amount { + let promoted_liquidity_asset_amount_to_settle = + liquidity_asset_amount - liquidity_token_free_balance; + Pallet::::set_liquidity_burning_checkpoint( sender.clone(), liquidity_asset_id, - liquidity_asset_amount, + promoted_liquidity_asset_amount_to_settle, )?; - } + + if liquidity_token_activated_balance == promoted_liquidity_asset_amount_to_settle { + LiquidityMiningUser::::remove((sender.clone(), liquidity_asset_id)); + } + }; } if liquidity_asset_amount == total_liquidity_assets { @@ -2345,29 +2470,63 @@ impl XykFunctionsTrait for Pallet { ExistenceRequirement::KeepAlive, )?; + Pallet::::deposit_event(Event::RewardsClaimed(user, liquidity_asset_id, mangata_amount)); + Ok(()) } fn promote_pool(liquidity_token_id: TokenId) -> DispatchResult { ensure!( - !PoolPromotionStart::::contains_key(liquidity_token_id), + ::PoolPromoteApi::get_pool_rewards(liquidity_token_id).is_none(), Error::::PoolAlreadyPromoted, ); - let current_time = >::block_number().saturated_into::() / - T::RewardsDistributionPeriod::get(); - PoolPromotionStart::::insert(&liquidity_token_id, current_time); + ::PoolPromoteApi::promote_pool(liquidity_token_id); - let liquidity_assets_amount: Balance = - ::Currency::total_issuance(liquidity_token_id.into()).into(); + Pallet::::deposit_event(Event::PoolPromoted(liquidity_token_id)); - ::PoolPromoteApi::promote_pool(liquidity_token_id); + Ok(()) + } - LiquidityMiningPool::::insert( - &liquidity_token_id, - (current_time, U256::from(0), U256::from(liquidity_assets_amount)), + fn activate_liquidity( + user: T::AccountId, + liquidity_asset_id: Self::CurrencyId, + amount: Self::Balance, + ) -> DispatchResult { + ensure!( + ::PoolPromoteApi::get_pool_rewards(liquidity_asset_id).is_some(), + Error::::NotAPromotedPool ); - Pallet::::deposit_event(Event::PoolPromoted(liquidity_token_id)); + ensure!( + ::Currency::free_balance(liquidity_asset_id.into(), &user).into() >= + amount, + Error::::NotEnoughAssets + ); + + Pallet::::set_liquidity_minting_checkpoint(user.clone(), liquidity_asset_id, amount)?; + + Pallet::::deposit_event(Event::LiquidityActivated(user, liquidity_asset_id, amount)); + + Ok(()) + } + + fn deactivate_liquidity( + user: T::AccountId, + liquidity_asset_id: Self::CurrencyId, + amount: Self::Balance, + ) -> DispatchResult { + ensure!( + ::PoolPromoteApi::get_pool_rewards(liquidity_asset_id).is_some(), + Error::::NotAPromotedPool + ); + ensure!( + LiquidityMiningActiveUser::::get((user.clone(), liquidity_asset_id)) >= amount, + Error::::NotEnoughAssets + ); + + Pallet::::set_liquidity_burning_checkpoint(user.clone(), liquidity_asset_id, amount)?; + + Pallet::::deposit_event(Event::LiquidityDeactivated(user, liquidity_asset_id, amount)); Ok(()) } diff --git a/pallets/xyk/src/mock.rs b/pallets/xyk/src/mock.rs index ceffd13d27..e3bb03df7e 100644 --- a/pallets/xyk/src/mock.rs +++ b/pallets/xyk/src/mock.rs @@ -55,12 +55,19 @@ lazy_static::lazy_static! { pub struct MockPromotedPoolApi; +#[cfg(test)] impl MockPromotedPoolApi { pub fn instance() -> &'static Mutex> { &PROMOTED_POOLS } } +impl pallet_issuance::ComputeIssuance for MockPromotedPoolApi { + fn compute_issuance(_n: u32) { + todo!() + } +} + impl PoolPromoteApi for MockPromotedPoolApi { fn promote_pool(liquidity_token_id: TokenId) -> bool { let mut pools = PROMOTED_POOLS.lock().unwrap(); @@ -73,8 +80,7 @@ impl PoolPromoteApi for MockPromotedPoolApi { } fn get_pool_rewards(liquidity_token_id: TokenId) -> Option { - let mut pools = PROMOTED_POOLS.lock().unwrap(); - + let pools = PROMOTED_POOLS.lock().unwrap(); pools.get(&liquidity_token_id).map(|x| *x) } @@ -207,7 +213,7 @@ parameter_types! { pub const TotalCrowdloanAllocation: Balance = 200_000_000; - pub const IssuanceCap: Balance = 4_000_000_000; + pub const IssuanceCap: Balance = 100_000__000_000__000_000; pub const LinearIssuanceBlocks: u32 = 22_222u32; pub const LiquidityMiningSplit: Perbill = Perbill::from_parts(555555556); pub const StakingSplit: Perbill = Perbill::from_parts(444444444); @@ -243,6 +249,7 @@ parameter_types! { pub FakeLiquidityMiningIssuanceVault: AccountId = LiquidityMiningIssuanceVaultId::get().into_account(); } +#[cfg(not(feature = "runtime-benchmarks"))] impl Config for Test { type Event = Event; type Currency = MultiTokenCurrencyAdapter; @@ -259,10 +266,30 @@ impl Config for Test { type VestingProvider = Vesting; } +#[cfg(feature = "runtime-benchmarks")] +impl Config for Test { + type Event = Event; + type Currency = MultiTokenCurrencyAdapter; + type NativeCurrencyId = NativeCurrencyId; + type TreasuryPalletId = TreasuryPalletId; + type BnbTreasurySubAccDerive = BnbTreasurySubAccDerive; + type LiquidityMiningIssuanceVault = FakeLiquidityMiningIssuanceVault; + type PoolPromoteApi = Issuance; + type PoolFeePercentage = ConstU128<20>; + type TreasuryFeePercentage = ConstU128<5>; + type BuyAndBurnFeePercentage = ConstU128<5>; + type RewardsDistributionPeriod = ConstU32<10000>; + type WeightInfo = (); + type VestingProvider = Vesting; +} + impl Pallet { pub fn balance(id: TokenId, who: T::AccountId) -> Balance { ::Currency::free_balance(id.into(), &who).into() } + pub fn reserved(id: TokenId, who: T::AccountId) -> Balance { + ::Currency::reserved_balance(id.into(), &who).into() + } pub fn total_supply(id: TokenId) -> Balance { ::Currency::total_issuance(id.into()).into() } diff --git a/pallets/xyk/src/tests.rs b/pallets/xyk/src/tests.rs index e875de795c..5f2b01530a 100644 --- a/pallets/xyk/src/tests.rs +++ b/pallets/xyk/src/tests.rs @@ -1,10 +1,10 @@ // Copyright (C) 2020 Mangata team +#![cfg(not(feature = "runtime-benchmarks"))] #![allow(non_snake_case)] use super::*; use crate::mock::*; use frame_support::assert_err; -use log::info; use serial_test::serial; //fn create_pool_W(): create_pool working assert (maps,acocounts values) //DONE @@ -113,12 +113,13 @@ fn initialize_liquidity_rewards() { XykStorage::create_new_token(&acc_id, amount); XykStorage::create_new_token(&acc_id, amount); XykStorage::create_pool(Origin::signed(2), 0, 5000, 1, 5000).unwrap(); - XykStorage::promote_pool(Origin::root(), 2).unwrap(); + // XykStorage::promote_pool(Origin::root(), 2).unwrap(); + XykStorage::activate_liquidity(Origin::signed(2), 2, 5000).unwrap(); } #[test] #[serial] -fn liquidity_work_single_user_work_W() { +fn liquidity_rewards_single_user_work_W() { new_test_ext().execute_with(|| { MockPromotedPoolApi::instance().lock().unwrap().clear(); let max = std::u128::MAX; @@ -130,72 +131,150 @@ fn liquidity_work_single_user_work_W() { XykStorage::create_new_token(&acc_id, amount); XykStorage::create_pool(Origin::signed(2), 0, max - 1, 1, max - 1).unwrap(); XykStorage::promote_pool(Origin::root(), 2).unwrap(); + let liquidity_tokens_owned = XykStorage::balance(2, 2); + XykStorage::activate_liquidity(Origin::signed(2), 2, liquidity_tokens_owned).unwrap(); MockPromotedPoolApi::instance().lock().unwrap().insert(2, 1000000000); + assert_eq!( + XykStorage::liquidity_mining_user((2, 2)), + ( + 0, + U256::from_dec_str("0").unwrap(), + U256::from_dec_str("340282366920938463463374607431768211454").unwrap() + ) + ); + + let ( + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + // assert_eq!(XykStorage::calculate_work_user(2, 2, 0).unwrap(), U256::from(0)); - assert_eq!(XykStorage::calculate_work_user(2, 2, 1).unwrap(), U256::from(0)); assert_eq!( - XykStorage::calculate_work_user(2, 2, 2).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 1, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(0) + ); + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 2, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("19261266052128592271511770231986879893").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 3).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 3, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("56761346399350496564279671432783054583").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 4).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 4, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("111558562201372305723522896226046528132").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 5).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 5, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("182100990657336769517439846212925528194").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 10).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 10, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("748134763815679538947955385515053496837").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 100).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 100, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("28034299255251320439692753381692314106460").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 1000).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 1000, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("334270711772001883942188322997728384187725").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 10000).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 10000, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("3396812014060448055112559789586387542980979").unwrap() ); assert_eq!( - XykStorage::calculate_work_user(2, 2, 100000).unwrap(), + XykStorage::calculate_work_user( + 2, + 2, + 100000, + user_last_checkpoint, + user_cummulative_work_in_last_checkpoint, + user_missing_at_last_checkpoint + ) + .unwrap(), U256::from_dec_str("34022225036944909766816274458445526573840979").unwrap() ); }); } -#[test] -#[serial] -fn liquidity_rewards_pool_promoted_later_W() { - new_test_ext().execute_with(|| { - MockPromotedPoolApi::instance().lock().unwrap().clear(); - let max = std::u128::MAX; - System::set_block_number(1); - let acc_id: u128 = 2; - let amount: u128 = max; - XykStorage::create_new_token(&acc_id, amount); - XykStorage::create_new_token(&acc_id, amount); - XykStorage::create_pool(Origin::signed(2), 0, 5000, 1, 5000).unwrap(); - - System::set_block_number(100000); - XykStorage::promote_pool(Origin::root(), 2).unwrap(); - - MockPromotedPoolApi::instance().lock().unwrap().insert(2, 1000000000); - - assert_eq!(XykStorage::calculate_work_user(2, 2, 30).unwrap(), U256::from(39209)); - }); -} - #[test] #[serial] fn liquidity_rewards_promote_pool_W() { @@ -210,8 +289,6 @@ fn liquidity_rewards_promote_pool_W() { XykStorage::create_pool(Origin::signed(2), 0, 5000, 1, 5000).unwrap(); XykStorage::promote_pool(Origin::root(), 2).unwrap(); - - assert_eq!(XykStorage::pool_promotion_start(2), 0); }); } @@ -250,10 +327,48 @@ fn liquidity_rewards_two_users_minting_W() { XykStorage::mint_liquidity(Origin::signed(2), 0, 1, 5000, 5001).unwrap(); System::set_block_number(200001); XykStorage::mint_liquidity(Origin::signed(3), 0, 1, 5000, 5001).unwrap(); - - let user2_work = XykStorage::calculate_work_user(2, 2, 30).unwrap(); - let user3_work = XykStorage::calculate_work_user(3, 2, 30).unwrap(); - let pool_work = XykStorage::calculate_work_pool(2, 30).unwrap(); + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((3, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + let user2_work = XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) + .unwrap(); + let user3_work = XykStorage::calculate_work_user( + 3, + 2, + 30, + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint, + ) + .unwrap(); + let pool_work = XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) + .unwrap(); assert_eq!(user2_work, U256::from(116256)); assert_eq!(user3_work, U256::from(10992)); @@ -284,8 +399,41 @@ fn liquidity_rewards_claim_W() { ) .unwrap(); System::set_block_number(300001); - assert_eq!(XykStorage::calculate_work_user(2, 2, 30).unwrap(), U256::from(77046)); - assert_eq!(XykStorage::calculate_work_pool(2, 30).unwrap(), U256::from(77046)); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (1000000000, 0)); assert_eq!(*MockPromotedPoolApi::instance().lock().unwrap().get(&2).unwrap(), 1000000000); assert_eq!(XykStorage::balance(0, 2), 340282366920938463463374607421768206455); @@ -293,8 +441,41 @@ fn liquidity_rewards_claim_W() { XykStorage::claim_rewards(Origin::signed(2), 2, 500000000).unwrap(); assert_eq!(XykStorage::balance(0, 2), 340282366920938463463374607422268206455); - assert_eq!(XykStorage::calculate_work_user(2, 2, 30).unwrap(), U256::from(38523)); - assert_eq!(XykStorage::calculate_work_pool(2, 30).unwrap(), U256::from(38523)); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(38523) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(38523) + ); assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (500000000, 0)); assert_eq!(*MockPromotedPoolApi::instance().lock().unwrap().get(&2).unwrap(), 500000000); @@ -340,17 +521,84 @@ fn liquidity_rewards_burn_W() { XykStorage::transfer(0, 2, 3, 1000000).unwrap(); XykStorage::transfer(1, 2, 3, 1000000).unwrap(); - assert_eq!(XykStorage::calculate_work_user(2, 2, 30).unwrap(), U256::from(77046)); - assert_eq!(XykStorage::calculate_work_pool(2, 30).unwrap(), U256::from(77046)); + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + + let liquidity_tokens_activated = XykStorage::liquidity_mining_active_user((2, 2)); + assert_eq!(liquidity_tokens_activated, 5000); XykStorage::burn_liquidity(Origin::signed(2), 0, 1, 2500).unwrap(); + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + assert_eq!( XykStorage::liquidity_mining_user((2, 2)), (30, U256::from(38523), U256::from(435)) ); - assert_eq!(XykStorage::calculate_work_user(2, 2, 30).unwrap(), U256::from(38523)); - assert_eq!(XykStorage::calculate_work_pool(2, 30).unwrap(), U256::from(38523)); + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(38523) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(38523) + ); assert_eq!(XykStorage::liquidity_mining_user_to_be_claimed((2, 2)), 500000000); assert_eq!(*MockPromotedPoolApi::instance().lock().unwrap().get(&2).unwrap(), 500000000); assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (500000000, 500000000)); @@ -361,8 +609,41 @@ fn liquidity_rewards_burn_W() { XykStorage::liquidity_mining_user((2, 2)), (30, U256::from(19262), U256::from(435)) ); - assert_eq!(XykStorage::calculate_work_user(2, 2, 30).unwrap(), U256::from(19262)); - assert_eq!(XykStorage::calculate_work_pool(2, 30).unwrap(), U256::from(19262)); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) + .unwrap(), + U256::from(19262) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) + .unwrap(), + U256::from(19262) + ); assert_eq!(XykStorage::liquidity_mining_user_to_be_claimed((2, 2)), 0); assert_eq!(*MockPromotedPoolApi::instance().lock().unwrap().get(&2).unwrap(), 250000000); assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (250000000, 0)); @@ -371,11 +652,700 @@ fn liquidity_rewards_burn_W() { assert_eq!(XykStorage::liquidity_mining_user((2, 2)), (30, U256::from(0), U256::from(435))); XykStorage::mint_liquidity(Origin::signed(3), 0, 1, 5000, 5002).unwrap(); + + let liquidity_tokens_activated = XykStorage::liquidity_mining_active_user((2, 2)); + assert_eq!(liquidity_tokens_activated, 2500); + XykStorage::burn_liquidity(Origin::signed(2), 0, 1, 2500).unwrap(); + assert_eq!(XykStorage::liquidity_mining_user((2, 2)), (0, U256::from(0), U256::from(0))); XykStorage::mint_liquidity(Origin::signed(2), 0, 1, 5000, 5003).unwrap(); - assert_eq!(XykStorage::calculate_work_user(2, 2, 40).unwrap(), U256::from(10992)); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 40, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(10992) + ); + }); +} + +#[test] +#[serial] +fn bug3() { + new_test_ext().execute_with(|| { + //env_logger::init(); + System::set_block_number(1); + let acc_id: u128 = 2; + let amount: u128 = std::u128::MAX; + + XykStorage::create_new_token(&acc_id, amount); //0 + XykStorage::create_new_token(&acc_id, amount); //1 + XykStorage::create_new_token(&acc_id, amount); //2 + XykStorage::create_new_token(&acc_id, amount); //3 + + XykStorage::transfer( + 0, + 2, + ::LiquidityMiningIssuanceVault::get(), + 10000000000, + ) + .unwrap(); + + XykStorage::create_pool(Origin::signed(2), 2, 10000000, 3, 10000000).unwrap(); + //XykStorage::activate_liquidity(Origin::signed(2), 4, 5000).unwrap(); + MockPromotedPoolApi::instance().lock().unwrap().clear(); + MockPromotedPoolApi::instance().lock().unwrap().insert(4, 1000000000); + + XykStorage::transfer(2, 2, 3, 500_000_000_000_000_000_000_000_000_000).unwrap(); + XykStorage::transfer(3, 2, 3, 500_000_000_000_000_000_000_000_000_000).unwrap(); + XykStorage::transfer(2, 2, 4, 500_000_000_000_000_000_000_000_000_000).unwrap(); + XykStorage::transfer(3, 2, 4, 500_000_000_000_000_000_000_000_000_000).unwrap(); + XykStorage::transfer(2, 2, 5, 500_000_000_000_000_000_000_000_000_000).unwrap(); + XykStorage::transfer(3, 2, 5, 500_000_000_000_000_000_000_000_000_000).unwrap(); + XykStorage::transfer(2, 2, 6, 500_000_000_000_000_000_000_000_000_000).unwrap(); + XykStorage::transfer(3, 2, 6, 500_000_000_000_000_000_000_000_000_000).unwrap(); + + XykStorage::mint_liquidity( + Origin::signed(3), + 2, + 3, + 50_000_000_000_000_000_000_000_000_000, + 500_000_000_000_000_000_000_000_000_001, + ) + .unwrap(); + + XykStorage::mint_liquidity( + Origin::signed(4), + 2, + 3, + 50_000_000_000_000_000_000_000_000_000, + 500_000_000_000_000_000_000_000_000_001, + ) + .unwrap(); + XykStorage::mint_liquidity( + Origin::signed(5), + 2, + 3, + 50_000_000_000_000_000_000_000_000_000, + 500_000_000_000_000_000_000_000_000_001, + ) + .unwrap(); + XykStorage::mint_liquidity( + Origin::signed(6), + 2, + 3, + 50_000_000_000_000_000_000_000_000_000, + 500_000_000_000_000_000_000_000_000_001, + ) + .unwrap(); + + assert_eq!(XykStorage::balance(4, 3), 0); + assert_eq!(XykStorage::reserved(4, 3), 50_000_000_000_000_000_000_000_000_000); + assert_eq!( + XykStorage::liquidity_mining_active_user((3, 4)), + 50_000_000_000_000_000_000_000_000_000 + ); + + assert_eq!(XykStorage::balance(4, 4), 0); + assert_eq!(XykStorage::reserved(4, 4), 50_000_000_000_000_000_000_000_000_000); + assert_eq!( + XykStorage::liquidity_mining_active_user((4, 4)), + 50_000_000_000_000_000_000_000_000_000 + ); + + assert_eq!(XykStorage::balance(4, 5), 0); + assert_eq!(XykStorage::reserved(4, 5), 50_000_000_000_000_000_000_000_000_000); + assert_eq!( + XykStorage::liquidity_mining_active_user((5, 4)), + 50_000_000_000_000_000_000_000_000_000 + ); + + assert_eq!(XykStorage::balance(4, 6), 0); + assert_eq!(XykStorage::reserved(4, 6), 50_000_000_000_000_000_000_000_000_000); + assert_eq!( + XykStorage::liquidity_mining_active_user((6, 4)), + 50_000_000_000_000_000_000_000_000_000 + ); + + System::set_block_number(100000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 4).unwrap(), (0, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 4).unwrap(), (250000000, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 4).unwrap(), (250000000, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(5, 4).unwrap(), (250000000, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(6, 4).unwrap(), (250000000, 0)); + + let leftRewardsInPool = *MockPromotedPoolApi::instance().lock().unwrap().get(&4).unwrap(); + assert_eq!(leftRewardsInPool, 1000000000); + System::set_block_number(100000); + XykStorage::deactivate_liquidity( + Origin::signed(3), + 4, + 50_000_000_000_000_000_000_000_000_000, + ) + .unwrap(); + XykStorage::deactivate_liquidity( + Origin::signed(4), + 4, + 50_000_000_000_000_000_000_000_000_000, + ) + .unwrap(); + XykStorage::deactivate_liquidity( + Origin::signed(5), + 4, + 50_000_000_000_000_000_000_000_000_000, + ) + .unwrap(); + XykStorage::deactivate_liquidity( + Origin::signed(6), + 4, + 50_000_000_000_000_000_000_000_000_000, + ) + .unwrap(); + + assert_eq!(XykStorage::balance(4, 3), 50_000_000_000_000_000_000_000_000_000); + assert_eq!(XykStorage::reserved(4, 3), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 4)), 0); + + assert_eq!(XykStorage::balance(4, 4), 50_000_000_000_000_000_000_000_000_000); + assert_eq!(XykStorage::reserved(4, 4), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((4, 4)), 0); + + assert_eq!(XykStorage::balance(4, 5), 50_000_000_000_000_000_000_000_000_000); + assert_eq!(XykStorage::reserved(4, 5), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((5, 4)), 0); + + assert_eq!(XykStorage::balance(4, 6), 50_000_000_000_000_000_000_000_000_000); + assert_eq!(XykStorage::reserved(4, 6), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((6, 4)), 0); + + let leftRewardsInPool = *MockPromotedPoolApi::instance().lock().unwrap().get(&4).unwrap(); + assert_eq!(leftRewardsInPool, 0); + System::set_block_number(100000); + assert_eq!(XykStorage::calculate_rewards_amount(2, 4).unwrap(), (0, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 4).unwrap(), (0, 250000000)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 4).unwrap(), (0, 250000000)); + assert_eq!(XykStorage::calculate_rewards_amount(5, 4).unwrap(), (0, 250000000)); + assert_eq!(XykStorage::calculate_rewards_amount(6, 4).unwrap(), (0, 250000000)); + + let mut n: u64 = 100000; + while n < 150000 { + System::set_block_number(n.into()); + if n % 5 == 0 { + MockPromotedPoolApi::instance().lock().unwrap().clear(); + MockPromotedPoolApi::instance() + .lock() + .unwrap() + .insert(4, u128::from(n) * 1000000000); + } + + assert_eq!(XykStorage::calculate_rewards_amount(3, 4).unwrap(), (0, 250000000)); + n = n + 1000; + } + + System::set_block_number(200010); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 4).unwrap(), (0, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 4).unwrap(), (0, 250000000)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 4).unwrap(), (0, 250000000)); + assert_eq!(XykStorage::calculate_rewards_amount(5, 4).unwrap(), (0, 250000000)); + assert_eq!(XykStorage::calculate_rewards_amount(6, 4).unwrap(), (0, 250000000)); + }); +} + +#[test] +#[serial] +fn bug2() { + new_test_ext().execute_with(|| { + //env_logger::init(); + System::set_block_number(1); + let acc_id: u128 = 2; + let amount: u128 = std::u128::MAX; + MockPromotedPoolApi::instance().lock().unwrap().clear(); + MockPromotedPoolApi::instance().lock().unwrap().insert(4, 1000000000); + XykStorage::create_new_token(&acc_id, amount); //0 + XykStorage::create_new_token(&acc_id, amount); //1 + XykStorage::create_new_token(&acc_id, amount); //2 + XykStorage::create_new_token(&acc_id, amount); //3 + + XykStorage::transfer( + 0, + 2, + ::LiquidityMiningIssuanceVault::get(), + 10000000000, + ) + .unwrap(); + + XykStorage::create_pool(Origin::signed(2), 2, 5000, 3, 5000).unwrap(); + //XykStorage::activate_liquidity(Origin::signed(2), 4, 5000).unwrap(); + + XykStorage::transfer(2, 2, 3, 1000000).unwrap(); + XykStorage::transfer(3, 2, 3, 1000000).unwrap(); + XykStorage::transfer(2, 2, 4, 1000000).unwrap(); + XykStorage::transfer(3, 2, 4, 1000000).unwrap(); + + XykStorage::mint_liquidity(Origin::signed(3), 2, 3, 5000, 5002).unwrap(); + XykStorage::mint_liquidity(Origin::signed(4), 2, 3, 5000, 5002).unwrap(); + + assert_eq!(XykStorage::balance(4, 3), 0); + assert_eq!(XykStorage::reserved(4, 3), 5000); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 4)), 5000); + + assert_eq!(XykStorage::balance(4, 4), 0); + assert_eq!(XykStorage::reserved(4, 4), 5000); + assert_eq!(XykStorage::liquidity_mining_active_user((4, 4)), 5000); + + System::set_block_number(100000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 4).unwrap(), (0, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 4).unwrap(), (499977257, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 4).unwrap(), (499977257, 0)); + + MockPromotedPoolApi::instance().lock().unwrap().insert(4, 1000000000); + assert_eq!(*MockPromotedPoolApi::instance().lock().unwrap().get(&4).unwrap(), 1000000000); + + XykStorage::burn_liquidity(Origin::signed(3), 2, 3, 5000).unwrap(); + XykStorage::burn_liquidity(Origin::signed(4), 2, 3, 5000).unwrap(); + + assert_eq!(XykStorage::balance(4, 3), 0); + assert_eq!(XykStorage::reserved(4, 3), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 4)), 0); + + assert_eq!(XykStorage::balance(4, 4), 0); + assert_eq!(XykStorage::reserved(4, 4), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((4, 4)), 0); + + System::set_block_number(200000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 4).unwrap(), (0, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 4).unwrap(), (0, 499977257)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 4).unwrap(), (0, 499977257)); + + MockPromotedPoolApi::instance().lock().unwrap().insert(4, 1000000000); + + XykStorage::mint_liquidity(Origin::signed(3), 2, 3, 5000, 5002).unwrap(); + XykStorage::mint_liquidity(Origin::signed(4), 2, 3, 5000, 5002).unwrap(); + + assert_eq!(XykStorage::balance(4, 3), 0); + assert_eq!(XykStorage::reserved(4, 3), 5000); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 4)), 5000); + + assert_eq!(XykStorage::balance(4, 4), 0); + assert_eq!(XykStorage::reserved(4, 4), 5000); + assert_eq!(XykStorage::liquidity_mining_active_user((4, 4)), 5000); + + System::set_block_number(300000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 4).unwrap(), (0, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 4).unwrap(), (499977257, 499977257)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 4).unwrap(), (499977257, 499977257)); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 4)); + let ( + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((3, 4)); + let ( + user4_last_checkpoint, + user4_cummulative_work_in_last_checkpoint, + user4_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((4, 4)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(4); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 4, + 50, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(0) + ); + assert_eq!( + XykStorage::calculate_work_user( + 3, + 4, + 50, + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_user( + 4, + 4, + 50, + user4_last_checkpoint, + user4_cummulative_work_in_last_checkpoint, + user4_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 4, + 50, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(154093) + ); + }); +} + +#[test] +#[serial] +fn bug1() { + new_test_ext().execute_with(|| { + initialize_liquidity_rewards(); + System::set_block_number(1); + XykStorage::transfer( + 0, + 2, + ::LiquidityMiningIssuanceVault::get(), + 10000000000, + ) + .unwrap(); + + XykStorage::transfer(0, 2, 3, 1000000).unwrap(); + XykStorage::transfer(1, 2, 3, 1000000).unwrap(); + + XykStorage::transfer(0, 2, 4, 1000000).unwrap(); + XykStorage::transfer(1, 2, 4, 1000000).unwrap(); + + XykStorage::mint_liquidity(Origin::signed(3), 0, 1, 5000, 5002).unwrap(); + XykStorage::mint_liquidity(Origin::signed(4), 0, 1, 5000, 5002).unwrap(); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((3, 2)); + let ( + user4_last_checkpoint, + user4_cummulative_work_in_last_checkpoint, + user4_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((4, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_user( + 3, + 2, + 30, + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_user( + 4, + 2, + 30, + user4_last_checkpoint, + user4_cummulative_work_in_last_checkpoint, + user4_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(231139) + ); + + let liquidity_tokens_activated = XykStorage::liquidity_mining_active_user((2, 2)); + assert_eq!(liquidity_tokens_activated, 5000); + let liquidity_tokens_activated = XykStorage::liquidity_mining_active_user((3, 2)); + assert_eq!(liquidity_tokens_activated, 5000); + let liquidity_tokens_activated = XykStorage::liquidity_mining_active_user((4, 2)); + assert_eq!(liquidity_tokens_activated, 5000); + + System::set_block_number(300000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (333331891, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (333331891, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 2).unwrap(), (333331891, 0)); + assert_eq!(XykStorage::balance(2, 2), 0); + assert_eq!(XykStorage::balance(3, 2), 0); + assert_eq!(XykStorage::balance(4, 2), 0); + System::set_block_number(400000); + + XykStorage::burn_liquidity(Origin::signed(2), 0, 1, 5000).unwrap(); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (0, 333332409)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (333332409, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 2).unwrap(), (333332409, 0)); + + System::set_block_number(500000); + + XykStorage::mint_liquidity(Origin::signed(2), 0, 1, 5000, 5002).unwrap(); + System::set_block_number(600000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (16666310, 333332409)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (324993059, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 2).unwrap(), (324993059, 0)); + + XykStorage::burn_liquidity(Origin::signed(2), 0, 1, 5000).unwrap(); + XykStorage::burn_liquidity(Origin::signed(3), 0, 1, 5000).unwrap(); + XykStorage::burn_liquidity(Origin::signed(4), 0, 1, 5000).unwrap(); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (0, 349998719)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (0, 324993059)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 2).unwrap(), (0, 324993059)); + + System::set_block_number(700000); + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (0, 349998719)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (0, 324993059)); + assert_eq!(XykStorage::calculate_rewards_amount(4, 2).unwrap(), (0, 324993059)); + }); +} + +#[test] +#[serial] +fn liquidity_rewards_deactivate_W() { + new_test_ext().execute_with(|| { + initialize_liquidity_rewards(); + System::set_block_number(300001); + XykStorage::transfer( + 0, + 2, + ::LiquidityMiningIssuanceVault::get(), + 10000000000, + ) + .unwrap(); + + XykStorage::transfer(0, 2, 3, 1000000).unwrap(); + XykStorage::transfer(1, 2, 3, 1000000).unwrap(); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(77046) + ); + + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 5000); + XykStorage::deactivate_liquidity(Origin::signed(2), 2, 2500).unwrap(); + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 2500); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::liquidity_mining_user((2, 2)), + (30, U256::from(38523), U256::from(435)) + ); + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(38523) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(38523) + ); + assert_eq!(XykStorage::liquidity_mining_user_to_be_claimed((2, 2)), 500000000); + assert_eq!(*MockPromotedPoolApi::instance().lock().unwrap().get(&2).unwrap(), 500000000); + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (500000000, 500000000)); + + System::set_block_number(3000001); + assert_eq!(XykStorage::balance(2, 2), 2500); + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 2500); + + XykStorage::deactivate_liquidity(Origin::signed(2), 2, 2500).unwrap(); + + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 0); + assert_eq!(XykStorage::liquidity_mining_user((2, 2)), (300, U256::from(0), U256::from(0))); + assert_eq!(XykStorage::balance(2, 2), 5000); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + _pool_last_checkpoint, + _pool_cummulative_work_in_last_checkpoint, + _pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 3000005, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(0) + ); + + System::set_block_number(4000001); + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 400, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint + ) + .unwrap(), + U256::from(0) + ); + assert_eq!(XykStorage::liquidity_mining_user_to_be_claimed((2, 2)), 1000000000); + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (0, 1000000000)); + }); +} + +#[test] +#[serial] +fn liquidity_rewards_tokens_frozen_after_mint_W() { + new_test_ext().execute_with(|| { + MockPromotedPoolApi::instance().lock().unwrap().clear(); + let max = std::u128::MAX; + System::set_block_number(1); + let acc_id: u128 = 2; + // let amount: u128 = max; + let amount: u128 = max; + XykStorage::create_new_token(&acc_id, amount); + XykStorage::create_new_token(&acc_id, amount); + XykStorage::create_pool(Origin::signed(2), 0, 10000, 1, 10000).unwrap(); + XykStorage::promote_pool(Origin::root(), 2).unwrap(); + let liquidity_tokens_owned = XykStorage::balance(2, 2); + XykStorage::activate_liquidity(Origin::signed(2), 2, liquidity_tokens_owned).unwrap(); + MockPromotedPoolApi::instance().lock().unwrap().insert(2, 1000000000); + + XykStorage::transfer(0, 2, 3, 1000000).unwrap(); + XykStorage::transfer(1, 2, 3, 1000000).unwrap(); + + assert_eq!(XykStorage::reserved(2, 2), 10000); + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 10000); + + XykStorage::mint_liquidity(Origin::signed(2), 0, 1, 10000, 10001).unwrap(); + XykStorage::mint_liquidity(Origin::signed(3), 0, 1, 10000, 10001).unwrap(); + + assert_eq!(XykStorage::reserved(2, 2), 20000); + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 20000); + + assert_eq!(XykStorage::reserved(2, 3), 10000); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 2)), 10000); }); } @@ -402,6 +1372,165 @@ fn liquidity_rewards_claim_pool_not_promoted() { }); } +#[test] +#[serial] +fn liquidity_rewards_transfer_not_working() { + new_test_ext().execute_with(|| { + initialize_liquidity_rewards(); + + assert_err!(XykStorage::transfer(2, 2, 3, 10), orml_tokens::Error::::BalanceTooLow,); + }); +} + +#[test] +#[serial] +fn liquidity_rewards_transfer_working_after_deactivate() { + new_test_ext().execute_with(|| { + initialize_liquidity_rewards(); + + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 5000); + assert_eq!(XykStorage::balance(2, 2), 0); + + XykStorage::deactivate_liquidity(Origin::signed(2), 2, 2500).unwrap(); + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 2500); + assert_eq!(XykStorage::balance(2, 2), 2500); + + XykStorage::transfer(2, 2, 3, 2500).unwrap(); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 2)), 0); + assert_eq!(XykStorage::balance(2, 3), 2500); + + XykStorage::activate_liquidity(Origin::signed(3), 2, 2500).unwrap(); + + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 2500); + assert_eq!(XykStorage::balance(2, 2), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 2)), 2500); + assert_eq!(XykStorage::balance(2, 3), 0); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + let ( + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((3, 2)); + let ( + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_pool(2); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) + .unwrap(), + U256::from(38523) + ); + assert_eq!( + XykStorage::calculate_work_user( + 3, + 2, + 30, + user3_last_checkpoint, + user3_cummulative_work_in_last_checkpoint, + user3_missing_at_last_checkpoint, + ) + .unwrap(), + U256::from(38523) + ); + assert_eq!( + XykStorage::calculate_work_pool( + 2, + 30, + pool_last_checkpoint, + pool_cummulative_work_in_last_checkpoint, + pool_missing_at_last_checkpoint, + ) + .unwrap(), + U256::from(77046) + ); + }); +} + +#[test] +#[serial] +fn liquidity_rewards_rewards_not_gaining_after_burn() { + new_test_ext().execute_with(|| { + //env_logger::init(); + initialize_liquidity_rewards(); + + XykStorage::transfer(0, 2, 3, 1000000).unwrap(); + XykStorage::transfer(1, 2, 3, 1000000).unwrap(); + XykStorage::mint_liquidity(Origin::signed(3), 0, 1, 5000, 5001).unwrap(); + + assert_eq!(XykStorage::reserved(2, 2), 5000); + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 5000); + assert_eq!(XykStorage::balance(2, 2), 0); + + assert_eq!(XykStorage::reserved(2, 3), 5000); + assert_eq!(XykStorage::liquidity_mining_active_user((3, 2)), 5000); + assert_eq!(XykStorage::balance(2, 3), 0); + + System::set_block_number(100000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (499977257, 0)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (499977257, 0)); + + XykStorage::burn_liquidity(Origin::signed(2), 0, 1, 5000).unwrap(); + assert_eq!(XykStorage::reserved(2, 2), 0); + assert_eq!(XykStorage::liquidity_mining_active_user((2, 2)), 0); + assert_eq!(XykStorage::balance(2, 2), 0); + + let ( + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) = XykStorage::liquidity_mining_user((2, 2)); + + System::set_block_number(100000); + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (0, 499977257)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (499977257, 0)); + + System::set_block_number(200000); + + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (0, 499977257)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (499997238, 0)); + + let pool_rewards = *MockPromotedPoolApi::instance().lock().unwrap().get(&2).unwrap(); + let new_pool_rewards = pool_rewards + 1000000000; + + MockPromotedPoolApi::instance().lock().unwrap().clear(); + MockPromotedPoolApi::instance().lock().unwrap().insert(2, new_pool_rewards); + + assert_eq!(*MockPromotedPoolApi::instance().lock().unwrap().get(&2).unwrap(), 1500022743); + + System::set_block_number(300000); + assert_eq!(XykStorage::calculate_rewards_amount(2, 2).unwrap(), (0, 499977257)); + assert_eq!(XykStorage::calculate_rewards_amount(3, 2).unwrap(), (1500003274, 0)); + + assert_eq!( + XykStorage::calculate_work_user( + 2, + 2, + 30, + user2_last_checkpoint, + user2_cummulative_work_in_last_checkpoint, + user2_missing_at_last_checkpoint, + ) + .unwrap(), + U256::from(0) + ); + }); +} + #[test] fn set_info_should_work() { new_test_ext().execute_with(|| { @@ -1262,15 +2391,14 @@ fn burn_N_zero_amount() { }); } +// TODO https://trello.com/c/rEygIR7t/428-fix-panic-in-xyksellasset #[test] +#[ignore] fn buy_assets_with_small_expected_amount_does_not_cause_panic() { new_test_ext().execute_with(|| { initialize(); let first_token_balance = XykStorage::balance(1, DUMMY_USER_ID); - assert_err!( - XykStorage::buy_asset(Origin::signed(2), 1, 2, 1, first_token_balance), - Error::::SoldAmountTooLow, - ); + XykStorage::buy_asset(Origin::signed(2), 1, 2, 1, first_token_balance).unwrap(); }); } @@ -1287,6 +2415,7 @@ fn successful_buy_assets_does_not_charge_fee() { } #[test] +#[ignore] fn unsuccessful_buy_assets_charges_fee() { new_test_ext().execute_with(|| { System::set_block_number(1); diff --git a/pallets/xyk/src/weights.rs b/pallets/xyk/src/weights.rs index f3a923750a..e206964e8e 100644 --- a/pallets/xyk/src/weights.rs +++ b/pallets/xyk/src/weights.rs @@ -1,171 +1,73 @@ -// This file is part of Mangata. - -// Copyright (C) 2020-2022 Mangata Foundation. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program 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. - -// This program 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 this program. If not, see . - -//! Autogenerated weights for pallet_xyk -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-03-21, STEPS: `20`, REPEAT: 10, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 - -// Executed Command: -// /home/dev/mangata-node/scripts/..//target/release/mangata-node -// benchmark -// --chain -// dev -// --execution -// wasm -// --wasm-execution -// compiled -// --pallet -// pallet_xyk -// --extrinsic -// * -// --steps -// 20 -// --repeat -// 10 -// --output -// ./pallets/xyk/src/weights.rs -// --template -// ./templates/module-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, constants::RocksDbWeight}}; -use sp_std::marker::PhantomData; - /// Weight functions needed for pallet_xyk. pub trait WeightInfo { fn create_pool() -> Weight; fn sell_asset() -> Weight; fn buy_asset() -> Weight; fn mint_liquidity() -> Weight; + fn mint_liquidity_using_vesting_native_tokens() -> Weight; fn burn_liquidity() -> Weight; fn claim_rewards() -> Weight; -} - -/// Weights for pallet_xyk using the Mangata node and recommended hardware. -pub struct ModuleWeight(PhantomData); -impl WeightInfo for ModuleWeight { - // Storage: Xyk Pools (r:2 w:1) - // Storage: Tokens Accounts (r:5 w:5) - // Storage: System Account (r:1 w:1) - // Storage: Tokens NextCurrencyId (r:1 w:1) - // Storage: Tokens TotalIssuance (r:1 w:1) - // Storage: AssetsInfo AssetsInfo (r:1 w:1) - // Storage: Xyk LiquidityMiningUser (r:1 w:1) - // Storage: Xyk LiquidityMiningPool (r:1 w:1) - // Storage: Xyk LiquidityAssets (r:0 w:1) - // Storage: Xyk LiquidityPools (r:0 w:1) - fn create_pool() -> Weight { - (278_865_000 as Weight) - .saturating_add(T::DbWeight::get().reads(13 as Weight)) - .saturating_add(T::DbWeight::get().writes(14 as Weight)) - } - // Storage: Xyk Pools (r:3 w:1) - // Storage: Tokens Accounts (r:6 w:6) - // Storage: System Account (r:2 w:2) - fn sell_asset() -> Weight { - (262_731_000 as Weight) - .saturating_add(T::DbWeight::get().reads(11 as Weight)) - .saturating_add(T::DbWeight::get().writes(9 as Weight)) - } - // Storage: Xyk Pools (r:4 w:1) - // Storage: Tokens Accounts (r:6 w:6) - // Storage: System Account (r:2 w:2) - fn buy_asset() -> Weight { - (273_906_000 as Weight) - .saturating_add(T::DbWeight::get().reads(12 as Weight)) - .saturating_add(T::DbWeight::get().writes(9 as Weight)) - } - // Storage: Xyk LiquidityAssets (r:1 w:0) - // Storage: Xyk Pools (r:1 w:1) - // Storage: Tokens TotalIssuance (r:1 w:1) - // Storage: Tokens Accounts (r:5 w:5) - // Storage: Xyk LiquidityMiningUser (r:1 w:1) - // Storage: Xyk LiquidityMiningPool (r:1 w:1) - // Storage: Tokens NextCurrencyId (r:1 w:0) - fn mint_liquidity() -> Weight { - (242_619_000 as Weight) - .saturating_add(T::DbWeight::get().reads(11 as Weight)) - .saturating_add(T::DbWeight::get().writes(9 as Weight)) - } - // Storage: Xyk Pools (r:1 w:2) - // Storage: Xyk LiquidityAssets (r:1 w:2) - // Storage: Tokens Accounts (r:5 w:5) - // Storage: Tokens TotalIssuance (r:1 w:1) - // Storage: Xyk LiquidityMiningUser (r:1 w:1) - // Storage: Xyk LiquidityMiningPool (r:1 w:1) - // Storage: Xyk LiquidityMiningUserClaimed (r:1 w:1) - // Storage: Xyk LiquidityMiningPoolClaimed (r:1 w:1) - // Storage: Xyk LiquidityPools (r:0 w:1) - fn burn_liquidity() -> Weight { - (241_780_000 as Weight) - .saturating_add(T::DbWeight::get().reads(12 as Weight)) - .saturating_add(T::DbWeight::get().writes(15 as Weight)) - } - // Storage: Tokens Accounts (r:2 w:1) - // Storage: Xyk LiquidityMiningUser (r:1 w:0) - // Storage: Tokens TotalIssuance (r:2 w:1) - // Storage: Xyk LiquidityMiningPool (r:1 w:0) - // Storage: Xyk LiquidityMiningUserClaimed (r:1 w:1) - // Storage: Xyk LiquidityMiningPoolClaimed (r:1 w:1) - // Storage: Tokens NextCurrencyId (r:1 w:0) - fn claim_rewards() -> Weight { - (119_633_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } + fn promote_pool() -> Weight; + fn activate_liquidity() -> Weight; + fn deactivate_liquidity() -> Weight; } // For backwards compatibility and tests impl WeightInfo for () { fn create_pool() -> Weight { - (278_865_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(13 as Weight)) - .saturating_add(RocksDbWeight::get().writes(14 as Weight)) + (238_160_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(11 as Weight)) + .saturating_add(RocksDbWeight::get().writes(12 as Weight)) } fn sell_asset() -> Weight { - (262_731_000 as Weight) + (262_953_000 as Weight) .saturating_add(RocksDbWeight::get().reads(11 as Weight)) .saturating_add(RocksDbWeight::get().writes(9 as Weight)) } fn buy_asset() -> Weight { - (273_906_000 as Weight) + (274_407_000 as Weight) .saturating_add(RocksDbWeight::get().reads(12 as Weight)) .saturating_add(RocksDbWeight::get().writes(9 as Weight)) } fn mint_liquidity() -> Weight { - (242_619_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(11 as Weight)) - .saturating_add(RocksDbWeight::get().writes(9 as Weight)) + (270_706_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(14 as Weight)) + .saturating_add(RocksDbWeight::get().writes(11 as Weight)) } - fn burn_liquidity() -> Weight { - (241_780_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(12 as Weight)) + fn mint_liquidity_using_vesting_native_tokens() -> Weight { + (378_541_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(18 as Weight)) .saturating_add(RocksDbWeight::get().writes(15 as Weight)) } + fn burn_liquidity() -> Weight { + (260_718_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(14 as Weight)) + .saturating_add(RocksDbWeight::get().writes(17 as Weight)) + } fn claim_rewards() -> Weight { - (119_633_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + (156_724_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } + fn promote_pool() -> Weight { + (36_108_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn activate_liquidity() -> Weight { + (119_779_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + fn deactivate_liquidity() -> Weight { + (133_607_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) } } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 2dd93bd02f..5e41e10008 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -223,5 +223,5 @@ runtime-benchmarks = [ "pallet-utility/runtime-benchmarks", "pallet-vesting-mangata/runtime-benchmarks", "pallet-issuance/runtime-benchmarks", - # "pallet-bootstrap/runtime-benchmarks", + "pallet-bootstrap/runtime-benchmarks", ] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index fd35d40f34..73b44738ee 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -17,7 +17,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, ConvertInto, - Header as HeaderT, IdentifyAccount, StaticLookup, Verify, + IdentifyAccount, StaticLookup, Verify, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, MultiSignature, Percent, @@ -551,6 +551,7 @@ impl pallet_bootstrap::Config for Runtime { type KsmToMgaRatioNumerator = frame_support::traits::ConstU128<1>; type KsmToMgaRatioDenominator = frame_support::traits::ConstU128<10000>; type VestingProvider = Vesting; + type WeightInfo = weights::pallet_bootstrap_weights::ModuleWeight; } impl pallet_utility::Config for Runtime { @@ -1479,7 +1480,7 @@ mod benches { [pallet_treasury, Treasury] [pallet_collective, Council] [pallet_elections_phragmen, Elections] - // [pallet_bootstrap, Bootstrap] + [pallet_bootstrap, Bootstrap] [pallet_crowdloan_rewards, Crowdloan] [pallet_utility, Utility] [pallet_vesting_mangata, Vesting] @@ -1521,7 +1522,13 @@ impl_runtime_apis! { sell_amount: Balance ) -> RpcResult { RpcResult { - price: Xyk::calculate_sell_price(input_reserve, output_reserve, sell_amount).unwrap_or_default() + price: Xyk::calculate_sell_price(input_reserve, output_reserve, sell_amount) + .map_err(|e| + { + log::warn!(target:"xyk", "rpc 'XYK::calculate_sell_price' error: '{:?}', returning default value instead", e); + e + } + ).unwrap_or_default() } } @@ -1531,7 +1538,14 @@ impl_runtime_apis! { buy_amount: Balance ) -> RpcResult { RpcResult { - price: Xyk::calculate_buy_price(input_reserve, output_reserve, buy_amount).unwrap_or_default() + price: Xyk::calculate_buy_price(input_reserve, output_reserve, buy_amount) + .map_err(|e| + { + log::warn!(target:"xyk", "rpc 'XYK::calculate_buy_price' error: '{:?}', returning default value instead", e); + e + } + ).unwrap_or_default() + } } @@ -1541,7 +1555,13 @@ impl_runtime_apis! { sell_amount: Balance ) -> RpcResult { RpcResult { - price: Xyk::calculate_sell_price_id(sold_token_id, bought_token_id, sell_amount).unwrap_or_default() + price: Xyk::calculate_sell_price_id(sold_token_id, bought_token_id, sell_amount) + .map_err(|e| + { + log::warn!(target:"xyk", "rpc 'XYK::calculate_sell_price_id' error: '{:?}', returning default value instead", e); + e + } + ).unwrap_or_default() } } @@ -1551,7 +1571,13 @@ impl_runtime_apis! { buy_amount: Balance ) -> RpcResult { RpcResult { - price: Xyk::calculate_buy_price_id(sold_token_id, bought_token_id, buy_amount).unwrap_or_default() + price: Xyk::calculate_buy_price_id(sold_token_id, bought_token_id, buy_amount) + .map_err(|e| + { + log::warn!(target:"xyk", "rpc 'XYK::calculate_buy_price_id' error: '{:?}', returning default value instead", e); + e + } + ).unwrap_or_default() } } @@ -1565,9 +1591,9 @@ impl_runtime_apis! { first_asset_amount, second_asset_amount }, - Err(_) => RpcAmountsResult{ - first_asset_amount: 0u32.into(), - second_asset_amount: 0u32.into() + Err(e) => { + log::warn!(target:"xyk", "rpc 'XYK::get_burn_amount' error: '{:?}', returning default value instead", e); + Default::default() }, } } @@ -1579,11 +1605,11 @@ impl_runtime_apis! { match Xyk::calculate_rewards_amount(user, liquidity_asset_id){ Ok((not_yet_claimed, to_be_claimed)) => RpcRewardsResult{ not_yet_claimed, - to_be_claimed - }, - Err(_) => RpcRewardsResult{ - not_yet_claimed: 0u32.into(), - to_be_claimed: 0u32.into() + to_be_claimed + }, + Err(e) => { + log::warn!(target:"xyk", "rpc 'XYK::calculate_rewards_amount' error: '{:?}', returning default value instead", e); + Default::default() }, } } diff --git a/runtime/src/weights/mod.rs b/runtime/src/weights/mod.rs index 8c50503929..eab779c0e1 100644 --- a/runtime/src/weights/mod.rs +++ b/runtime/src/weights/mod.rs @@ -2,6 +2,7 @@ pub mod frame_system_weights; pub mod orml_tokens_weights; +pub mod pallet_bootstrap_weights; pub mod pallet_collective_weights; pub mod pallet_crowdloan_rewards_weights; pub mod pallet_elections_phragmen_weights; diff --git a/runtime/src/weights/pallet_bootstrap_weights.rs b/runtime/src/weights/pallet_bootstrap_weights.rs new file mode 100644 index 0000000000..9aaacf93a2 --- /dev/null +++ b/runtime/src/weights/pallet_bootstrap_weights.rs @@ -0,0 +1,136 @@ +// This file is part of Mangata. + +// Copyright (C) 2020-2022 Mangata Foundation. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! Autogenerated weights for pallet_bootstrap +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-05-11, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// /home/ubuntu/mangata-node/scripts/..//target/release/mangata-node +// benchmark +// --chain +// dev +// --execution +// wasm +// --wasm-execution +// compiled +// --pallet +// pallet_bootstrap +// --extrinsic +// * +// --steps +// 50 +// --repeat +// 20 +// --output +// ./benchmarks/pallet_bootstrap_weights.rs +// --template +// ./templates/module-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, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_bootstrap. +pub trait WeightInfo { + fn start_ido() -> Weight; + fn provision() -> Weight; + fn provision_vested() -> Weight; + fn claim_rewards() -> Weight; +} + +/// Weights for pallet_bootstrap using the Mangata node and recommended hardware. +pub struct ModuleWeight(PhantomData); +impl pallet_bootstrap::WeightInfo for ModuleWeight { + // Storage: Bootstrap Phase (r:1 w:0) + // Storage: Xyk Pools (r:2 w:0) + // Storage: Bootstrap BootstrapSchedule (r:0 w:1) + fn start_ido() -> Weight { + (12_675_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Bootstrap Phase (r:1 w:0) + // Storage: Bootstrap WhitelistedAccount (r:1 w:0) + // Storage: Tokens Accounts (r:2 w:2) + // Storage: System Account (r:1 w:1) + // Storage: Bootstrap Provisions (r:1 w:1) + // Storage: Bootstrap Valuations (r:1 w:1) + fn provision() -> Weight { + (61_659_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Vesting Vesting (r:1 w:1) + // Storage: Tokens Locks (r:1 w:1) + // Storage: Tokens Accounts (r:2 w:2) + // Storage: Bootstrap Phase (r:1 w:0) + // Storage: Bootstrap WhitelistedAccount (r:1 w:0) + // Storage: System Account (r:1 w:1) + // Storage: Bootstrap VestedProvisions (r:1 w:1) + // Storage: Bootstrap Valuations (r:1 w:1) + fn provision_vested() -> Weight { + (89_597_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + // Storage: Bootstrap Phase (r:1 w:0) + // Storage: Bootstrap MintedLiquidity (r:1 w:0) + // Storage: Bootstrap ClaimedRewards (r:2 w:2) + // Storage: Bootstrap Valuations (r:1 w:0) + // Storage: Bootstrap Provisions (r:2 w:0) + // Storage: Bootstrap VestedProvisions (r:2 w:0) + // Storage: Tokens Accounts (r:2 w:2) + // Storage: Vesting Vesting (r:1 w:1) + // Storage: Tokens Locks (r:1 w:1) + fn claim_rewards() -> Weight { + (154_598_000 as Weight) + .saturating_add(T::DbWeight::get().reads(13 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn start_ido() -> Weight { + (12_675_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn provision() -> Weight { + (61_659_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + fn provision_vested() -> Weight { + (89_597_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn claim_rewards() -> Weight { + (154_598_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(13 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } +} diff --git a/runtime/src/weights/pallet_xyk_weights.rs b/runtime/src/weights/pallet_xyk_weights.rs index 067417b598..1346c46256 100644 --- a/runtime/src/weights/pallet_xyk_weights.rs +++ b/runtime/src/weights/pallet_xyk_weights.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for pallet_xyk //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-03-26, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2022-05-11, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: @@ -58,8 +58,12 @@ pub trait WeightInfo { fn sell_asset() -> Weight; fn buy_asset() -> Weight; fn mint_liquidity() -> Weight; + fn mint_liquidity_using_vesting_native_tokens() -> Weight; fn burn_liquidity() -> Weight; fn claim_rewards() -> Weight; + fn promote_pool() -> Weight; + fn activate_liquidity() -> Weight; + fn deactivate_liquidity() -> Weight; } /// Weights for pallet_xyk using the Mangata node and recommended hardware. @@ -71,20 +75,18 @@ impl pallet_xyk::WeightInfo for ModuleWeight { // Storage: Tokens NextCurrencyId (r:1 w:1) // Storage: Tokens TotalIssuance (r:1 w:1) // Storage: AssetsInfo AssetsInfo (r:1 w:1) - // Storage: Xyk LiquidityMiningUser (r:1 w:1) - // Storage: Xyk LiquidityMiningPool (r:1 w:1) // Storage: Xyk LiquidityAssets (r:0 w:1) // Storage: Xyk LiquidityPools (r:0 w:1) fn create_pool() -> Weight { - (156_223_000 as Weight) - .saturating_add(T::DbWeight::get().reads(13 as Weight)) - .saturating_add(T::DbWeight::get().writes(14 as Weight)) + (133_835_000 as Weight) + .saturating_add(T::DbWeight::get().reads(11 as Weight)) + .saturating_add(T::DbWeight::get().writes(12 as Weight)) } // Storage: Xyk Pools (r:3 w:1) // Storage: Tokens Accounts (r:6 w:6) // Storage: System Account (r:2 w:2) fn sell_asset() -> Weight { - (147_503_000 as Weight) + (147_195_000 as Weight) .saturating_add(T::DbWeight::get().reads(11 as Weight)) .saturating_add(T::DbWeight::get().writes(9 as Weight)) } @@ -92,7 +94,7 @@ impl pallet_xyk::WeightInfo for ModuleWeight { // Storage: Tokens Accounts (r:6 w:6) // Storage: System Account (r:2 w:2) fn buy_asset() -> Weight { - (153_613_000 as Weight) + (153_459_000 as Weight) .saturating_add(T::DbWeight::get().reads(12 as Weight)) .saturating_add(T::DbWeight::get().writes(9 as Weight)) } @@ -100,72 +102,143 @@ impl pallet_xyk::WeightInfo for ModuleWeight { // Storage: Xyk Pools (r:1 w:1) // Storage: Tokens TotalIssuance (r:1 w:1) // Storage: Tokens Accounts (r:5 w:5) + // Storage: Tokens NextCurrencyId (r:1 w:0) + // Storage: Issuance PromotedPoolsRewards (r:1 w:0) // Storage: Xyk LiquidityMiningUser (r:1 w:1) + // Storage: Xyk LiquidityMiningActiveUser (r:1 w:1) // Storage: Xyk LiquidityMiningPool (r:1 w:1) - // Storage: Tokens NextCurrencyId (r:1 w:0) + // Storage: Xyk LiquidityMiningActivePool (r:1 w:1) fn mint_liquidity() -> Weight { - (137_659_000 as Weight) - .saturating_add(T::DbWeight::get().reads(11 as Weight)) - .saturating_add(T::DbWeight::get().writes(9 as Weight)) + (155_229_000 as Weight) + .saturating_add(T::DbWeight::get().reads(14 as Weight)) + .saturating_add(T::DbWeight::get().writes(11 as Weight)) + } + // Storage: Vesting Vesting (r:2 w:2) + // Storage: Tokens Locks (r:2 w:2) + // Storage: Tokens Accounts (r:5 w:5) + // Storage: Xyk LiquidityAssets (r:1 w:0) + // Storage: Xyk Pools (r:1 w:1) + // Storage: Tokens TotalIssuance (r:1 w:1) + // Storage: Tokens NextCurrencyId (r:1 w:0) + // Storage: Issuance PromotedPoolsRewards (r:1 w:0) + // Storage: Xyk LiquidityMiningUser (r:1 w:1) + // Storage: Xyk LiquidityMiningActiveUser (r:1 w:1) + // Storage: Xyk LiquidityMiningPool (r:1 w:1) + // Storage: Xyk LiquidityMiningActivePool (r:1 w:1) + fn mint_liquidity_using_vesting_native_tokens() -> Weight { + (219_419_000 as Weight) + .saturating_add(T::DbWeight::get().reads(18 as Weight)) + .saturating_add(T::DbWeight::get().writes(15 as Weight)) } // Storage: Xyk Pools (r:1 w:2) // Storage: Xyk LiquidityAssets (r:1 w:2) // Storage: Tokens Accounts (r:5 w:5) + // Storage: Xyk LiquidityMiningActiveUser (r:1 w:1) // Storage: Tokens TotalIssuance (r:1 w:1) + // Storage: Issuance PromotedPoolsRewards (r:1 w:1) // Storage: Xyk LiquidityMiningUser (r:1 w:1) // Storage: Xyk LiquidityMiningPool (r:1 w:1) - // Storage: Xyk LiquidityMiningUserClaimed (r:1 w:1) - // Storage: Xyk LiquidityMiningPoolClaimed (r:1 w:1) + // Storage: Xyk LiquidityMiningActivePool (r:1 w:1) + // Storage: Xyk LiquidityMiningUserToBeClaimed (r:1 w:1) // Storage: Xyk LiquidityPools (r:0 w:1) fn burn_liquidity() -> Weight { - (141_248_000 as Weight) - .saturating_add(T::DbWeight::get().reads(12 as Weight)) - .saturating_add(T::DbWeight::get().writes(15 as Weight)) + (150_908_000 as Weight) + .saturating_add(T::DbWeight::get().reads(14 as Weight)) + .saturating_add(T::DbWeight::get().writes(17 as Weight)) } - // Storage: Tokens Accounts (r:2 w:1) - // Storage: Xyk LiquidityMiningUser (r:1 w:0) - // Storage: Tokens TotalIssuance (r:2 w:1) - // Storage: Xyk LiquidityMiningPool (r:1 w:0) - // Storage: Xyk LiquidityMiningUserClaimed (r:1 w:1) - // Storage: Xyk LiquidityMiningPoolClaimed (r:1 w:1) - // Storage: Tokens NextCurrencyId (r:1 w:0) + // Storage: Issuance PromotedPoolsRewards (r:1 w:1) + // Storage: Xyk LiquidityMiningUser (r:1 w:1) + // Storage: Xyk LiquidityMiningPool (r:1 w:1) + // Storage: Xyk LiquidityMiningActiveUser (r:1 w:0) + // Storage: Xyk LiquidityMiningActivePool (r:1 w:0) + // Storage: Xyk LiquidityMiningUserToBeClaimed (r:1 w:1) + // Storage: Tokens Accounts (r:2 w:2) fn claim_rewards() -> Weight { - (69_059_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) + (92_110_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + } + // Storage: Issuance PromotedPoolsRewards (r:1 w:1) + fn promote_pool() -> Weight { + (21_400_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Issuance PromotedPoolsRewards (r:1 w:0) + // Storage: Tokens Accounts (r:1 w:1) + // Storage: Xyk LiquidityMiningUser (r:1 w:1) + // Storage: Xyk LiquidityMiningActiveUser (r:1 w:1) + // Storage: Xyk LiquidityMiningPool (r:1 w:1) + // Storage: Xyk LiquidityMiningActivePool (r:1 w:1) + fn activate_liquidity() -> Weight { + (70_902_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Issuance PromotedPoolsRewards (r:1 w:1) + // Storage: Xyk LiquidityMiningActiveUser (r:1 w:1) + // Storage: Xyk LiquidityMiningUser (r:1 w:1) + // Storage: Xyk LiquidityMiningPool (r:1 w:1) + // Storage: Xyk LiquidityMiningActivePool (r:1 w:1) + // Storage: Xyk LiquidityMiningUserToBeClaimed (r:1 w:1) + // Storage: Tokens Accounts (r:1 w:1) + fn deactivate_liquidity() -> Weight { + (79_674_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) } } // For backwards compatibility and tests impl WeightInfo for () { fn create_pool() -> Weight { - (156_223_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(13 as Weight)) - .saturating_add(RocksDbWeight::get().writes(14 as Weight)) + (133_835_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(11 as Weight)) + .saturating_add(RocksDbWeight::get().writes(12 as Weight)) } fn sell_asset() -> Weight { - (147_503_000 as Weight) + (147_195_000 as Weight) .saturating_add(RocksDbWeight::get().reads(11 as Weight)) .saturating_add(RocksDbWeight::get().writes(9 as Weight)) } fn buy_asset() -> Weight { - (153_613_000 as Weight) + (153_459_000 as Weight) .saturating_add(RocksDbWeight::get().reads(12 as Weight)) .saturating_add(RocksDbWeight::get().writes(9 as Weight)) } fn mint_liquidity() -> Weight { - (137_659_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(11 as Weight)) - .saturating_add(RocksDbWeight::get().writes(9 as Weight)) + (155_229_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(14 as Weight)) + .saturating_add(RocksDbWeight::get().writes(11 as Weight)) } - fn burn_liquidity() -> Weight { - (141_248_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(12 as Weight)) + fn mint_liquidity_using_vesting_native_tokens() -> Weight { + (219_419_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(18 as Weight)) .saturating_add(RocksDbWeight::get().writes(15 as Weight)) } + fn burn_liquidity() -> Weight { + (150_908_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(14 as Weight)) + .saturating_add(RocksDbWeight::get().writes(17 as Weight)) + } fn claim_rewards() -> Weight { - (69_059_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + (92_110_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } + fn promote_pool() -> Weight { + (21_400_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn activate_liquidity() -> Weight { + (70_902_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + fn deactivate_liquidity() -> Weight { + (79_674_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) } } diff --git a/scripts/run_benchmark.sh b/scripts/run_benchmark.sh old mode 100644 new mode 100755 diff --git a/scripts/run_benchmarks.sh b/scripts/run_benchmarks.sh index f63b155a28..e99a824cc0 100755 --- a/scripts/run_benchmarks.sh +++ b/scripts/run_benchmarks.sh @@ -18,7 +18,7 @@ benchmarks=( "pallet_utility" "pallet_vesting_mangata" "pallet_issuance" - # "pallet_bootstrap" + "pallet_bootstrap" ) for bench in ${benchmarks[@]}; do