diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index b914ce9a3..b26a9375a 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -227,143 +227,6 @@ benchmarks! { From<::MarketId>, } - admin_destroy_disputed_market { - // The number of assets. - let a in (T::MinCategories::get().into())..T::MaxCategories::get().into(); - // The number of market ids per open time frame. - let o in 0..63; - // The number of market ids per close time frame. - let c in 0..63; - // The number of market ids per dispute block. - let r in 0..63; - - let (caller, market_id) = setup_reported_categorical_market_with_pool::( - a, - OutcomeReport::Categorical(0u16), - )?; - - >::mutate_market(&market_id, |market| { - market.dispute_mechanism = Some(MarketDisputeMechanism::Authorized); - Ok(()) - })?; - - let pool_id = >::market_pool(&market_id)?; - - let disputor = account("disputor", 1, 0); - ::AssetManager::deposit( - Asset::Ztg, - &disputor, - u128::MAX.saturated_into(), - ).unwrap(); - let _ = Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id)?; - - let market = >::market(&market_id)?; - - let (range_start, range_end) = match market.period { - MarketPeriod::Timestamp(range) => (range.start, range.end), - _ => panic!("admin_destroy_reported_market: Unsupported market period"), - }; - - for i in 0..o { - // shift of 1 to avoid collisions with first market id 0 - MarketIdsPerOpenTimeFrame::::try_mutate( - Pallet::::calculate_time_frame_of_moment(range_start), - |ids| ids.try_push((i + 1).into()), - ).unwrap(); - } - - for i in 0..c { - // shift of 65 to avoid collisions with `o` - MarketIdsPerCloseTimeFrame::::try_mutate( - Pallet::::calculate_time_frame_of_moment(range_end), - |ids| ids.try_push((i + 65).into()), - ).unwrap(); - } - - AuthorizedPallet::::authorize_market_outcome( - T::AuthorizedDisputeResolutionOrigin::try_successful_origin().unwrap(), - market_id.into(), - OutcomeReport::Categorical(0u16), - )?; - - let now = >::block_number(); - let resolves_at = now.saturating_add(::CorrectionPeriod::get()); - for i in 0..r { - // shift of 129 to avoid collisions with `o` and `c` - MarketIdsPerDisputeBlock::::try_mutate( - resolves_at, - |ids| ids.try_push((i + 129).into()), - ).unwrap(); - } - - let destroy_origin = T::DestroyOrigin::try_successful_origin().unwrap(); - let call = Call::::admin_destroy_market { market_id }; - }: { - call.dispatch_bypass_filter(destroy_origin)? - } verify { - assert_last_event::(Event::MarketDestroyed::(market_id).into()); - } - - admin_destroy_reported_market { - // The number of assets. - let a in (T::MinCategories::get().into())..T::MaxCategories::get().into(); - // The number of market ids per open time frame. - let o in 0..63; - // The number of market ids per close time frame. - let c in 0..63; - // The number of market ids per dispute block. - let r in 0..63; - - let (caller, market_id) = setup_reported_categorical_market_with_pool::( - a, - OutcomeReport::Categorical(0u16), - )?; - - let pool_id = >::market_pool(&market_id)?; - - let market = >::market(&market_id)?; - - let (range_start, range_end) = match market.period { - MarketPeriod::Timestamp(range) => (range.start, range.end), - _ => panic!("admin_destroy_reported_market: Unsupported market period"), - }; - - for i in 0..o { - // shift of 1 to avoid collisions with first market id 0 - MarketIdsPerOpenTimeFrame::::try_mutate( - Pallet::::calculate_time_frame_of_moment(range_start), - |ids| ids.try_push((i + 1).into()), - ).unwrap(); - } - - for i in 0..c { - // shift of 65 to avoid collisions with `o` - MarketIdsPerCloseTimeFrame::::try_mutate( - Pallet::::calculate_time_frame_of_moment(range_end), - |ids| ids.try_push((i + 65).into()), - ).unwrap(); - } - - let report_at = market.report.unwrap().at; - let resolves_at = report_at.saturating_add(market.deadlines.dispute_duration); - for i in 0..r { - // shift of 129 to avoid collisions with `o` and `c` - MarketIdsPerReportBlock::::try_mutate( - resolves_at, - |ids| ids.try_push((i + 129).into()), - ).unwrap(); - } - - let destroy_origin = T::DestroyOrigin::try_successful_origin().unwrap(); - let call = Call::::admin_destroy_market { market_id }; - }: { - call.dispatch_bypass_filter(destroy_origin)? - } verify { - assert_last_event::(Event::MarketDestroyed::( - market_id, - ).into()); - } - admin_move_market_to_closed { let o in 0..63; let c in 0..63; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index d798345d9..603bcc2fc 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -271,6 +271,7 @@ mod pallet { /// in case the bond is not present or already settled. /// /// Return `true` if the bond is present and not settled, `false` otherwise. + #[allow(unused)] fn $fn_name( market_id: &MarketIdOf, market: &MarketOf, @@ -305,110 +306,6 @@ mod pallet { #[pallet::call] impl Pallet { - /// Destroy a market, including its outcome assets, market account and pool account. - /// - /// Must be called by `DestroyOrigin`. Bonds (unless already returned) are slashed without - /// exception. Can currently only be used for destroying CPMM markets. - #[pallet::call_index(0)] - #[pallet::weight(( - T::WeightInfo::admin_destroy_reported_market( - T::MaxCategories::get().into(), - CacheSize::get(), - CacheSize::get(), - CacheSize::get(), - ) - .max(T::WeightInfo::admin_destroy_disputed_market( - T::MaxCategories::get().into(), - CacheSize::get(), - CacheSize::get(), - CacheSize::get(), - )), - Pays::No, - ))] - #[transactional] - pub fn admin_destroy_market( - origin: OriginFor, - #[pallet::compact] market_id: MarketIdOf, - ) -> DispatchResultWithPostInfo { - // TODO(#618): Not implemented for Rikiddo! - T::DestroyOrigin::ensure_origin(origin)?; - - let market = >::market(&market_id)?; - ensure!( - matches!(market.scoring_rule, ScoringRule::CPMM | ScoringRule::Orderbook), - Error::::InvalidScoringRule - ); - let market_status = market.status; - let market_account = >::market_account(market_id); - - // Slash outstanding bonds; see - // https://github.com/zeitgeistpm/runtime-audit-1/issues/34#issuecomment-1120187097 for - // details. - Self::slash_pending_bonds(&market_id, &market)?; - - if market_status == MarketStatus::Proposed { - MarketIdsForEdit::::remove(market_id); - } - - if T::GlobalDisputes::is_active(&market_id) { - T::GlobalDisputes::destroy_global_dispute(&market_id)?; - } - - // NOTE: Currently we don't clean up outcome assets. - // TODO(#792): Remove outcome assets for accounts! Delete "resolved" assets of `orml_tokens` with storage migration. - T::AssetManager::slash( - market.base_asset, - &market_account, - T::AssetManager::free_balance(market.base_asset, &market_account), - ); - let mut category_count = 0u32; - if let Ok(pool_id) = >::market_pool(&market_id) { - let pool = T::Swaps::pool(pool_id)?; - category_count = pool.assets.len().saturated_into(); - let _ = T::Swaps::destroy_pool(pool_id)?; - >::remove_market_pool(&market_id)?; - } - - let open_ids_len = Self::clear_auto_open(&market_id)?; - let close_ids_len = Self::clear_auto_close(&market_id)?; - // Note: This is noop if the market is trusted. - let (ids_len, _) = Self::clear_auto_resolve(&market_id)?; - if market.dispute_mechanism.is_some() { - Self::clear_dispute_mechanism(&market_id)?; - } - >::remove_market(&market_id)?; - - Self::deposit_event(Event::MarketDestroyed(market_id)); - - // Weight correction - // The DestroyOrigin should not pay fees for providing this service - if market_status == MarketStatus::Reported { - Ok(( - Some(T::WeightInfo::admin_destroy_reported_market( - category_count, - open_ids_len, - close_ids_len, - ids_len, - )), - Pays::No, - ) - .into()) - } else if market_status == MarketStatus::Disputed { - Ok(( - Some(T::WeightInfo::admin_destroy_disputed_market( - category_count, - open_ids_len, - close_ids_len, - ids_len, - )), - Pays::No, - ) - .into()) - } else { - Ok((Option::::None, Pays::No).into()) - } - } - /// Allows the `CloseOrigin` to immediately move an open market to closed. /// /// # Weight @@ -2039,22 +1936,6 @@ mod pallet { impl_is_bond_pending!(is_outsider_bond_pending, outsider); impl_is_bond_pending!(is_dispute_bond_pending, dispute); - fn slash_pending_bonds(market_id: &MarketIdOf, market: &MarketOf) -> DispatchResult { - if Self::is_creation_bond_pending(market_id, market, false) { - Self::slash_creation_bond(market_id, None)?; - } - if Self::is_oracle_bond_pending(market_id, market, false) { - Self::slash_oracle_bond(market_id, None)?; - } - if Self::is_outsider_bond_pending(market_id, market, false) { - Self::slash_outsider_bond(market_id, None)?; - } - if Self::is_dispute_bond_pending(market_id, market, false) { - Self::slash_dispute_bond(market_id, None)?; - } - Ok(()) - } - #[require_transactional] fn do_create_market( who: T::AccountId, @@ -2272,23 +2153,6 @@ mod pallet { Ok((ids_len, mdm_len)) } - /// The dispute mechanism is intended to clear its own storage here. - fn clear_dispute_mechanism(market_id: &MarketIdOf) -> DispatchResult { - let market = >::market(market_id)?; - let dispute_mechanism = - market.dispute_mechanism.as_ref().ok_or(Error::::NoDisputeMechanism)?; - - // TODO(#782): use multiple benchmarks paths for different dispute mechanisms - match dispute_mechanism { - MarketDisputeMechanism::Authorized => T::Authorized::clear(market_id, &market)?, - MarketDisputeMechanism::Court => T::Court::clear(market_id, &market)?, - MarketDisputeMechanism::SimpleDisputes => { - T::SimpleDisputes::clear(market_id, &market)? - } - }; - Ok(()) - } - #[require_transactional] pub(crate) fn do_sell_complete_set( who: T::AccountId, diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 9dc7b9085..b6d1abd0f 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -530,611 +530,6 @@ fn create_market_with_foreign_assets() { }); } -#[test] -fn admin_destroy_market_correctly_slashes_permissionless_market_active() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - simple_create_categorical_market( - base_asset, - MarketCreation::Permissionless, - 0..2, - ScoringRule::CPMM, - ); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_permissionless_market_reported() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - let end = 2_u64; - simple_create_categorical_market( - base_asset, - MarketCreation::Permissionless, - 0..end, - ScoringRule::CPMM, - ); - let market = MarketCommons::market(&0).unwrap(); - run_to_block(end + market.deadlines.grace_period); - assert_ok!(PredictionMarkets::report( - RuntimeOrigin::signed(BOB), - 0, - OutcomeReport::Categorical(1) - )); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_permissionless_market_disputed() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - let end = 2; - simple_create_categorical_market( - base_asset, - MarketCreation::Permissionless, - 0..end, - ScoringRule::CPMM, - ); - let market = MarketCommons::market(&0).unwrap(); - let grace_period = end + market.deadlines.grace_period; - assert_ne!(grace_period, 0); - run_to_block(grace_period + 1); - assert_ok!(PredictionMarkets::report( - RuntimeOrigin::signed(BOB), - 0, - OutcomeReport::Categorical(1) - )); - run_to_block(grace_period + 2); - assert_ok!(PredictionMarkets::dispute(RuntimeOrigin::signed(CHARLIE), 0,)); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_dispute_bonds() { - ExtBuilder::default().build().execute_with(|| { - let end = 2; - simple_create_categorical_market( - Asset::Ztg, - MarketCreation::Permissionless, - 0..end, - ScoringRule::CPMM, - ); - let market_id = 0; - let market = MarketCommons::market(&market_id).unwrap(); - let grace_period = end + market.deadlines.grace_period; - assert_ne!(grace_period, 0); - run_to_block(grace_period + 1); - assert_ok!(PredictionMarkets::report( - RuntimeOrigin::signed(BOB), - 0, - OutcomeReport::Categorical(1) - )); - run_to_block(grace_period + 2); - assert_ok!(PredictionMarkets::dispute(RuntimeOrigin::signed(CHARLIE), 0,)); - assert_ok!(SimpleDisputes::suggest_outcome( - RuntimeOrigin::signed(CHARLIE), - 0, - OutcomeReport::Categorical(0) - )); - assert_ok!(SimpleDisputes::suggest_outcome( - RuntimeOrigin::signed(DAVE), - 0, - OutcomeReport::Categorical(1) - )); - let set_up_account = |account| { - assert_ok!(AssetManager::deposit(Asset::Ztg, account, SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - account, - SENTINEL_AMOUNT, - )); - }; - set_up_account(&CHARLIE); - set_up_account(&DAVE); - - let balance_free_before_charlie = Balances::free_balance(CHARLIE); - let balance_free_before_dave = Balances::free_balance(DAVE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), market_id)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &CHARLIE), - SENTINEL_AMOUNT, - ); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &DAVE), - SENTINEL_AMOUNT, - ); - assert_eq!( - Balances::free_balance(CHARLIE), - balance_free_before_charlie + zrml_simple_disputes::default_outcome_bond::(0) - ); - assert_eq!( - Balances::free_balance(DAVE), - balance_free_before_dave + zrml_simple_disputes::default_outcome_bond::(1), - ); - assert!(zrml_simple_disputes::Disputes::::get(market_id).is_empty()); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_permissionless_market_resolved() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - let end = 2; - simple_create_categorical_market( - base_asset, - MarketCreation::Permissionless, - 0..end, - ScoringRule::CPMM, - ); - let market = MarketCommons::market(&0).unwrap(); - let grace_period = end + market.deadlines.grace_period; - run_to_block(grace_period + 1); - assert_ok!(PredictionMarkets::report( - RuntimeOrigin::signed(BOB), - 0, - OutcomeReport::Categorical(1) - )); - run_blocks(market.deadlines.dispute_duration); - assert_eq!(Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), 0); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_advised_market_proposed() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - simple_create_categorical_market( - base_asset, - MarketCreation::Advised, - 0..1, - ScoringRule::CPMM, - ); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_advised_market_proposed_with_edit_request() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - simple_create_categorical_market( - base_asset, - MarketCreation::Advised, - 0..1, - ScoringRule::CPMM, - ); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - let market = MarketCommons::market(&0); - assert_eq!(market.unwrap().status, MarketStatus::Proposed); - - let edit_reason = vec![0_u8; ::MaxEditReasonLen::get() as usize]; - - assert_ok!(PredictionMarkets::request_edit(RuntimeOrigin::signed(SUDO), 0, edit_reason)); - assert!(MarketIdsForEdit::::contains_key(0)); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - assert!(!MarketIdsForEdit::::contains_key(0)); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_advised_market_active() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - simple_create_categorical_market( - base_asset, - MarketCreation::Advised, - 0..1, - ScoringRule::CPMM, - ); - assert_ok!(PredictionMarkets::approve_market(RuntimeOrigin::signed(SUDO), 0)); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_advised_market_reported() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - let end = 2; - simple_create_categorical_market( - base_asset, - MarketCreation::Advised, - 0..end, - ScoringRule::CPMM, - ); - assert_ok!(PredictionMarkets::approve_market(RuntimeOrigin::signed(SUDO), 0)); - let market = MarketCommons::market(&0).unwrap(); - let grace_period = end + market.deadlines.grace_period; - run_to_block(grace_period + 1); - assert_ok!(PredictionMarkets::report( - RuntimeOrigin::signed(BOB), - 0, - OutcomeReport::Categorical(1) - )); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_advised_market_disputed() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - let end = 2; - simple_create_categorical_market( - base_asset, - MarketCreation::Advised, - 0..end, - ScoringRule::CPMM, - ); - assert_ok!(PredictionMarkets::approve_market(RuntimeOrigin::signed(SUDO), 0)); - let market = MarketCommons::market(&0).unwrap(); - let grace_period = end + market.deadlines.grace_period; - run_to_block(grace_period + 1); - assert_ok!(PredictionMarkets::report( - RuntimeOrigin::signed(BOB), - 0, - OutcomeReport::Categorical(1) - )); - assert_ok!(PredictionMarkets::dispute(RuntimeOrigin::signed(CHARLIE), 0,)); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_slashes_advised_market_resolved() { - // NOTE: Bonds are always in ZTG, irrespective of base_asset. - let test = |base_asset: Asset| { - let end = 2; - simple_create_categorical_market( - base_asset, - MarketCreation::Advised, - 0..end, - ScoringRule::CPMM, - ); - assert_ok!(PredictionMarkets::approve_market(RuntimeOrigin::signed(SUDO), 0)); - let market = MarketCommons::market(&0).unwrap(); - let grace_period = end + market.deadlines.grace_period; - run_to_block(grace_period + 1); - assert_ok!(PredictionMarkets::report( - RuntimeOrigin::signed(BOB), - 0, - OutcomeReport::Categorical(1) - )); - run_blocks(market.deadlines.dispute_duration); - assert_eq!(Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), 0); - assert_ok!(AssetManager::deposit(Asset::Ztg, &ALICE, 2 * SENTINEL_AMOUNT)); - assert_ok!(Balances::reserve_named( - &PredictionMarkets::reserve_id(), - &ALICE, - SENTINEL_AMOUNT - )); - let balance_free_before_alice = Balances::free_balance(ALICE); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!( - Balances::reserved_balance_named(&PredictionMarkets::reserve_id(), &ALICE), - SENTINEL_AMOUNT - ); - let balance_free_after_alice = Balances::free_balance(ALICE); - assert_eq!(balance_free_before_alice, balance_free_after_alice); - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} -#[test] -fn admin_destroy_market_correctly_cleans_up_accounts() { - let test = |base_asset: Asset| { - let alice_ztg_before_market_creation = AssetManager::free_balance(Asset::Ztg, &ALICE); - let alice_base_asset_before_market_creation = - AssetManager::free_balance(base_asset, &ALICE); - let swap_fee = ::MaxSwapFee::get(); - assert_ok!(PredictionMarkets::create_cpmm_market_and_deploy_assets( - RuntimeOrigin::signed(ALICE), - base_asset, - Perbill::zero(), - ALICE, - MarketPeriod::Block(0..42), - get_deadlines(), - gen_metadata(50), - MarketType::Categorical(3), - Some(MarketDisputeMechanism::SimpleDisputes), - swap_fee, - LIQUIDITY, - vec![::MinWeight::get(); 3], - )); - // Buy some outcome tokens for Alice so that we can check that they get destroyed. - assert_ok!(PredictionMarkets::buy_complete_set(RuntimeOrigin::signed(ALICE), 0, BASE)); - let market_id = 0; - let pool_id = 0; - let pool_account = Swaps::pool_account_id(&pool_id); - let market_account = MarketCommons::market_account(market_id); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - assert_eq!(AssetManager::free_balance(Asset::CategoricalOutcome(0, 0), &pool_account), 0); - assert_eq!(AssetManager::free_balance(Asset::CategoricalOutcome(0, 1), &pool_account), 0); - assert_eq!(AssetManager::free_balance(Asset::CategoricalOutcome(0, 2), &pool_account), 0); - assert_eq!(AssetManager::free_balance(base_asset, &pool_account), 0); - assert_eq!(AssetManager::free_balance(Asset::CategoricalOutcome(0, 0), &market_account), 0); - assert_eq!(AssetManager::free_balance(Asset::CategoricalOutcome(0, 1), &market_account), 0); - assert_eq!(AssetManager::free_balance(Asset::CategoricalOutcome(0, 2), &market_account), 0); - assert_eq!(AssetManager::free_balance(base_asset, &market_account), 0); - // premissionless market so using ValidityBond - let creation_bond = ::ValidityBond::get(); - let oracle_bond = ::OracleBond::get(); - // substract LIQUIDITY twice, one for buy_complete_set() in - // create_cpmm_market_and_deploy_assets() and one in swaps::create_pool() - // then again substract BASE as buy_complete_set() above - let expected_base_asset_value = - alice_base_asset_before_market_creation - LIQUIDITY - LIQUIDITY - BASE; - if base_asset == Asset::Ztg { - let alice_base_asset_balance = AssetManager::free_balance(base_asset, &ALICE); - assert_eq!( - alice_base_asset_balance, - expected_base_asset_value - creation_bond - oracle_bond - ); - } else { - let alice_base_asset_balance = AssetManager::free_balance(base_asset, &ALICE); - assert_eq!(alice_base_asset_balance, expected_base_asset_value); - let alice_ztg_balance = AssetManager::free_balance(Asset::Ztg, &ALICE); - assert_eq!( - alice_ztg_balance, - alice_ztg_before_market_creation - creation_bond - oracle_bond - ); - } - }; - ExtBuilder::default().build().execute_with(|| { - test(Asset::Ztg); - }); - #[cfg(feature = "parachain")] - ExtBuilder::default().build().execute_with(|| { - test(Asset::ForeignAsset(100)); - }); -} - -#[test] -fn admin_destroy_market_correctly_clears_auto_open_and_close_blocks() { - ExtBuilder::default().build().execute_with(|| { - let category_count = 3; - assert_ok!(PredictionMarkets::create_cpmm_market_and_deploy_assets( - RuntimeOrigin::signed(ALICE), - Asset::Ztg, - Perbill::zero(), - ALICE, - MarketPeriod::Block(22..66), - get_deadlines(), - gen_metadata(50), - MarketType::Categorical(category_count), - Some(MarketDisputeMechanism::SimpleDisputes), - 0, - LIQUIDITY, - vec![::MinWeight::get(); category_count.into()], - )); - assert_ok!(PredictionMarkets::create_cpmm_market_and_deploy_assets( - RuntimeOrigin::signed(ALICE), - Asset::Ztg, - Perbill::zero(), - ALICE, - MarketPeriod::Block(33..66), - get_deadlines(), - gen_metadata(50), - MarketType::Categorical(category_count), - Some(MarketDisputeMechanism::SimpleDisputes), - 0, - LIQUIDITY, - vec![::MinWeight::get(); category_count.into()], - )); - assert_ok!(PredictionMarkets::create_cpmm_market_and_deploy_assets( - RuntimeOrigin::signed(ALICE), - Asset::Ztg, - Perbill::zero(), - ALICE, - MarketPeriod::Block(22..33), - get_deadlines(), - gen_metadata(50), - MarketType::Categorical(category_count), - Some(MarketDisputeMechanism::SimpleDisputes), - 0, - LIQUIDITY, - vec![::MinWeight::get(); category_count.into()], - )); - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - - let auto_close = MarketIdsPerCloseBlock::::get(66); - assert_eq!(auto_close.len(), 1); - assert_eq!(auto_close[0], 1); - - let auto_open = MarketIdsPerOpenBlock::::get(22); - assert_eq!(auto_open.len(), 1); - assert_eq!(auto_open[0], 2); - }); -} - #[test] fn admin_move_market_to_resolved_resolves_reported_market() { // NOTE: Bonds are always in ZTG, irrespective of base_asset. @@ -1343,27 +738,6 @@ fn it_does_not_create_market_with_too_many_categories() { }); } -#[test] -fn it_allows_sudo_to_destroy_markets() { - ExtBuilder::default().build().execute_with(|| { - // Creates an advised market. - simple_create_categorical_market( - Asset::Ztg, - MarketCreation::Advised, - 0..1, - ScoringRule::CPMM, - ); - - // destroy the market - assert_ok!(PredictionMarkets::admin_destroy_market(RuntimeOrigin::signed(SUDO), 0)); - - assert_noop!( - MarketCommons::market(&0), - zrml_market_commons::Error::::MarketDoesNotExist - ); - }); -} - #[test] fn it_allows_advisory_origin_to_approve_markets() { ExtBuilder::default().build().execute_with(|| { diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index a2ea80eed..ebf13cf19 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -49,8 +49,6 @@ use frame_support::{traits::Get, weights::Weight}; /// Trait containing the required functions for weight retrival within /// zrml_prediction_markets (automatically generated) pub trait WeightInfoZeitgeist { - fn admin_destroy_disputed_market(a: u32, o: u32, c: u32, r: u32) -> Weight; - fn admin_destroy_reported_market(a: u32, o: u32, c: u32, r: u32) -> Weight; fn admin_move_market_to_closed(o: u32, c: u32) -> Weight; fn admin_move_market_to_resolved_scalar_reported(r: u32) -> Weight; fn admin_move_market_to_resolved_categorical_reported(r: u32) -> Weight; @@ -88,78 +86,6 @@ pub trait WeightInfoZeitgeist { /// Weight functions for zrml_prediction_markets (automatically generated) pub struct WeightInfo(PhantomData); impl WeightInfoZeitgeist for WeightInfo { - /// Storage: MarketCommons Markets (r:1 w:1) - /// Proof: MarketCommons Markets (max_values: None, max_size: Some(541), added: 3016, mode: MaxEncodedLen) - /// Storage: Balances Reserves (r:2 w:2) - /// Proof: Balances Reserves (max_values: None, max_size: Some(1249), added: 3724, mode: MaxEncodedLen) - /// Storage: System Account (r:3 w:3) - /// Proof: System Account (max_values: None, max_size: Some(132), added: 2607, mode: MaxEncodedLen) - /// Storage: GlobalDisputes GlobalDisputesInfo (r:1 w:0) - /// Proof: GlobalDisputes GlobalDisputesInfo (max_values: None, max_size: Some(396), added: 2871, mode: MaxEncodedLen) - /// Storage: MarketCommons MarketPool (r:1 w:1) - /// Proof: MarketCommons MarketPool (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Swaps Pools (r:1 w:1) - /// Proof: Swaps Pools (max_values: None, max_size: Some(3651), added: 6126, mode: MaxEncodedLen) - /// Storage: Tokens Accounts (r:64 w:64) - /// Proof: Tokens Accounts (max_values: None, max_size: Some(123), added: 2598, mode: MaxEncodedLen) - /// Storage: Tokens TotalIssuance (r:64 w:64) - /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(43), added: 2518, mode: MaxEncodedLen) - /// Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) - /// Proof: Authorized AuthorizedOutcomeReports (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) - /// Proof: PredictionMarkets MarketIdsPerDisputeBlock (max_values: None, max_size: Some(1042), added: 3517, mode: MaxEncodedLen) - fn admin_destroy_disputed_market(a: u32, o: u32, c: u32, r: u32) -> Weight { - // Proof Size summary in bytes: - // Measured: `2060 + a * (215 ±0) + r * (16 ±0)` - // Estimated: `35846 + a * (5116 ±0)` - // Minimum execution time: 275_961 nanoseconds. - Weight::from_parts(223_802_648, 35846) - // Standard Error: 39_490 - .saturating_add(Weight::from_ref_time(29_860_680).saturating_mul(a.into())) - // Standard Error: 39_293 - .saturating_add(Weight::from_ref_time(133_295).saturating_mul(o.into())) - // Standard Error: 39_293 - .saturating_add(Weight::from_ref_time(199_113).saturating_mul(c.into())) - // Standard Error: 39_293 - .saturating_add(Weight::from_ref_time(205_263).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(11_u64)) - .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(a.into()))) - .saturating_add(T::DbWeight::get().writes(10_u64)) - .saturating_add(Weight::from_proof_size(5116).saturating_mul(a.into())) - } - /// Storage: MarketCommons Markets (r:1 w:1) - /// Proof: MarketCommons Markets (max_values: None, max_size: Some(541), added: 3016, mode: MaxEncodedLen) - /// Storage: Balances Reserves (r:1 w:1) - /// Proof: Balances Reserves (max_values: None, max_size: Some(1249), added: 3724, mode: MaxEncodedLen) - /// Storage: GlobalDisputes GlobalDisputesInfo (r:1 w:0) - /// Proof: GlobalDisputes GlobalDisputesInfo (max_values: None, max_size: Some(396), added: 2871, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(132), added: 2607, mode: MaxEncodedLen) - /// Storage: MarketCommons MarketPool (r:1 w:1) - /// Proof: MarketCommons MarketPool (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Swaps Pools (r:1 w:1) - /// Proof: Swaps Pools (max_values: None, max_size: Some(3651), added: 6126, mode: MaxEncodedLen) - /// Storage: Tokens Accounts (r:64 w:64) - /// Proof: Tokens Accounts (max_values: None, max_size: Some(123), added: 2598, mode: MaxEncodedLen) - /// Storage: Tokens TotalIssuance (r:64 w:64) - /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(43), added: 2518, mode: MaxEncodedLen) - /// Storage: PredictionMarkets MarketIdsPerReportBlock (r:1 w:1) - /// Proof: PredictionMarkets MarketIdsPerReportBlock (max_values: None, max_size: Some(1042), added: 3517, mode: MaxEncodedLen) - fn admin_destroy_reported_market(a: u32, _o: u32, _c: u32, r: u32) -> Weight { - // Proof Size summary in bytes: - // Measured: `1691 + a * (215 ±0) + r * (16 ±0)` - // Estimated: `26991 + a * (5116 ±0)` - // Minimum execution time: 241_041 nanoseconds. - Weight::from_parts(196_167_863, 26991) - // Standard Error: 42_480 - .saturating_add(Weight::from_ref_time(30_146_656).saturating_mul(a.into())) - // Standard Error: 42_269 - .saturating_add(Weight::from_ref_time(177_697).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) - .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(a.into()))) - .saturating_add(T::DbWeight::get().writes(7_u64)) - .saturating_add(Weight::from_proof_size(5116).saturating_mul(a.into())) - } /// Storage: MarketCommons Markets (r:1 w:1) /// Proof: MarketCommons Markets (max_values: None, max_size: Some(541), added: 3016, mode: MaxEncodedLen) /// Storage: PredictionMarkets MarketIdsPerOpenTimeFrame (r:1 w:1)