From 9966daa44cae413f662f5b49066f4ff902f31424 Mon Sep 17 00:00:00 2001 From: mrq Date: Fri, 1 May 2026 06:58:49 +0200 Subject: [PATCH 01/17] surface substrate transfers and swaps as evm logs --- Cargo.lock | 30 +- Cargo.toml | 4 +- integration-tests/src/evm.rs | 5 +- pallets/broadcast/Cargo.toml | 2 +- pallets/broadcast/src/lib.rs | 48 ++- pallets/broadcast/src/tests/mock.rs | 4 +- pallets/circuit-breaker/src/tests/mock.rs | 4 +- pallets/dca/src/tests/mock.rs | 4 +- pallets/hsm/src/tests/mock.rs | 4 +- pallets/lbp/src/mock.rs | 4 +- pallets/liquidation/src/tests/mock.rs | 4 +- .../src/tests/mock.rs | 4 +- pallets/omnipool/src/tests/mock.rs | 4 +- pallets/otc-settlements/src/mock.rs | 4 +- pallets/otc/src/tests/mock.rs | 4 +- pallets/route-executor/src/tests/mock.rs | 4 +- pallets/stableswap/src/tests/mock.rs | 4 +- pallets/synthetic-logs/Cargo.toml | 63 ++++ pallets/synthetic-logs/src/lib.rs | 306 ++++++++++++++++++ pallets/synthetic-logs/src/tests.rs | 73 +++++ pallets/xyk/src/tests/mock.rs | 4 +- runtime/adapters/src/tests/mock.rs | 4 +- runtime/hydradx/Cargo.toml | 6 +- runtime/hydradx/src/assets.rs | 13 +- runtime/hydradx/src/evm/erc20_logs.rs | 101 ++++++ runtime/hydradx/src/evm/mod.rs | 6 + .../src/evm/precompiles/multicurrency.rs | 58 +++- runtime/hydradx/src/evm/runner.rs | 154 +++++---- runtime/hydradx/src/evm/swap_logs.rs | 128 ++++++++ runtime/hydradx/src/lib.rs | 6 +- 30 files changed, 955 insertions(+), 104 deletions(-) create mode 100644 pallets/synthetic-logs/Cargo.toml create mode 100644 pallets/synthetic-logs/src/lib.rs create mode 100644 pallets/synthetic-logs/src/tests.rs create mode 100644 runtime/hydradx/src/evm/erc20_logs.rs create mode 100644 runtime/hydradx/src/evm/swap_logs.rs diff --git a/Cargo.lock b/Cargo.lock index 13136477e..7b142f606 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6379,7 +6379,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "412.0.0" +version = "413.0.0" dependencies = [ "alloy-primitives 0.7.7", "alloy-sol-types 0.7.7", @@ -6395,6 +6395,7 @@ dependencies = [ "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-timestamp", "cumulus-primitives-utility", + "environmental", "ethabi", "ethereum", "evm", @@ -6495,6 +6496,7 @@ dependencies = [ "pallet-stableswap", "pallet-staking 4.3.1", "pallet-state-trie-migration", + "pallet-synthetic-logs", "pallet-timestamp", "pallet-tips", "pallet-token-gateway", @@ -9769,7 +9771,7 @@ dependencies = [ [[package]] name = "pallet-broadcast" -version = "1.7.0" +version = "1.8.0" dependencies = [ "frame-support", "frame-support-procedural", @@ -12120,6 +12122,30 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "pallet-synthetic-logs" +version = "0.1.0" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm", + "fp-rpc", + "frame-support", + "frame-system", + "log", + "pallet-broadcast", + "pallet-ethereum", + "pallet-evm", + "parity-scale-codec", + "primitives", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-timestamp" version = "40.0.0" diff --git a/Cargo.toml b/Cargo.toml index aeea40df4..a691b5811 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,8 @@ members = [ 'liquidation-worker-support', 'pallets/hsm', "pallets/signet", - "pallets/dispenser" + "pallets/dispenser", + "pallets/synthetic-logs", ] resolver = "2" @@ -160,6 +161,7 @@ pallet-evm-accounts = { path = "pallets/evm-accounts", default-features = false pallet-evm-accounts-rpc-runtime-api = { path = "pallets/evm-accounts/rpc/runtime-api", default-features = false } pallet-liquidation = { path = "pallets/liquidation", default-features = false } pallet-broadcast = { path = "pallets/broadcast", default-features = false } +pallet-synthetic-logs = { path = "pallets/synthetic-logs", default-features = false } liquidation-worker-support = { path = "liquidation-worker-support", default-features = false } pallet-hsm = { path = "pallets/hsm", default-features = false } pallet-parameters = { path = "pallets/parameters", default-features = false } diff --git a/integration-tests/src/evm.rs b/integration-tests/src/evm.rs index fbc6968cf..f7bc36cb1 100644 --- a/integration-tests/src/evm.rs +++ b/integration-tests/src/evm.rs @@ -4738,7 +4738,10 @@ impl PrecompileHandle for MockHandle { } fn log(&mut self, _: H160, _: Vec, _: Vec) -> Result<(), ExitError> { - unimplemented!() + // no-op: tests using this mock handle don't inspect emitted logs; + // the precompile (e.g. multicurrency) calls `handle.log(...)` to emit + // the ERC-20 Transfer event inline, which we accept silently here. + Ok(()) } fn code_address(&self) -> H160 { diff --git a/pallets/broadcast/Cargo.toml b/pallets/broadcast/Cargo.toml index 2ee0b1366..32467be90 100644 --- a/pallets/broadcast/Cargo.toml +++ b/pallets/broadcast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-broadcast" -version = "1.7.0" +version = "1.8.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/pallets/broadcast/src/lib.rs b/pallets/broadcast/src/lib.rs index 44f059e60..13a8bb070 100644 --- a/pallets/broadcast/src/lib.rs +++ b/pallets/broadcast/src/lib.rs @@ -40,6 +40,36 @@ const LOG_TARGET: &str = "runtime::broadcast"; type ExecutionIdStack = BoundedVec>; +/// Hook fired after every `Swapped3` event is emitted from +/// [`Pallet::deposit_trade_event`]. Implementors translate the trade into +/// EVM-shaped logs (e.g. uniswap v2 `Swap`). Default is `()` — no-op. +pub trait OnTrade { + fn on_trade( + swapper: &AccountId, + filler: &AccountId, + filler_type: &types::Filler, + operation: &types::TradeOperation, + inputs: &[types::Asset], + outputs: &[types::Asset], + fees: &[types::Fee], + operation_stack: &[types::ExecutionType], + ); +} + +impl OnTrade for () { + fn on_trade( + _: &AccountId, + _: &AccountId, + _: &types::Filler, + _: &types::TradeOperation, + _: &[types::Asset], + _: &[types::Asset], + _: &[types::Fee], + _: &[types::ExecutionType], + ) { + } +} + #[frame_support::pallet] pub mod pallet { use super::*; @@ -53,7 +83,10 @@ pub mod pallet { pub struct Pallet(_); #[pallet::config] - pub trait Config: frame_system::Config {} + pub trait Config: frame_system::Config { + /// Hook called after every `Swapped3` emission. Default `()`. + type OnTrade: OnTrade; + } #[pallet::storage] /// Next available incremental ID @@ -126,6 +159,19 @@ impl Pallet { ) { let trade_swapper = Swapper::::get().unwrap_or(swapper); let operation_stack = Self::get_context(); + // Fire the OnTrade hook before depositing the substrate event so + // downstream consumers (e.g. evm log translator) can read the same + // data the event carries. + T::OnTrade::on_trade( + &trade_swapper, + &filler, + &filler_type, + &operation, + &inputs, + &outputs, + &fees, + &operation_stack, + ); Self::deposit_event(Event::::Swapped3 { swapper: trade_swapper, filler, diff --git a/pallets/broadcast/src/tests/mock.rs b/pallets/broadcast/src/tests/mock.rs index 95e61cfa2..fb236ded5 100644 --- a/pallets/broadcast/src/tests/mock.rs +++ b/pallets/broadcast/src/tests/mock.rs @@ -47,7 +47,9 @@ construct_runtime!( } ); -impl crate::Config for Test {} +impl crate::Config for Test { + type OnTrade = (); +} impl frame_system::Config for Test { type BaseCallFilter = Everything; diff --git a/pallets/circuit-breaker/src/tests/mock.rs b/pallets/circuit-breaker/src/tests/mock.rs index 09e0949b3..04316512d 100644 --- a/pallets/circuit-breaker/src/tests/mock.rs +++ b/pallets/circuit-breaker/src/tests/mock.rs @@ -318,7 +318,9 @@ impl pallet_omnipool::Config for Test { type BurnProtocolFee = BurnFee; } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} pub struct CircuitBreakerHooks(PhantomData); diff --git a/pallets/dca/src/tests/mock.rs b/pallets/dca/src/tests/mock.rs index c9ad9dbaf..05f55173b 100644 --- a/pallets/dca/src/tests/mock.rs +++ b/pallets/dca/src/tests/mock.rs @@ -363,7 +363,9 @@ parameter_types! { } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} type Pools = (OmniPool, Xyk); diff --git a/pallets/hsm/src/tests/mock.rs b/pallets/hsm/src/tests/mock.rs index bbeb7ddd2..9257a1fe7 100644 --- a/pallets/hsm/src/tests/mock.rs +++ b/pallets/hsm/src/tests/mock.rs @@ -138,7 +138,9 @@ impl frame_system::Config for Test { type ExtensionsWeightInfo = (); } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} parameter_type_with_key! { pub ExistentialDeposits: |_currency_id: AssetId| -> Balance { diff --git a/pallets/lbp/src/mock.rs b/pallets/lbp/src/mock.rs index 01ff7c609..86caf8ca4 100644 --- a/pallets/lbp/src/mock.rs +++ b/pallets/lbp/src/mock.rs @@ -171,7 +171,9 @@ impl LockedBalance for MultiLockedBalance { } } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} impl Config for Test { type MultiCurrency = Currency; diff --git a/pallets/liquidation/src/tests/mock.rs b/pallets/liquidation/src/tests/mock.rs index 430ba9e57..4978bebfc 100644 --- a/pallets/liquidation/src/tests/mock.rs +++ b/pallets/liquidation/src/tests/mock.rs @@ -279,7 +279,9 @@ impl pallet_route_executor::Config for Test { type WeightInfo = (); } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} parameter_types! { pub const BlockHashCount: u64 = 250; diff --git a/pallets/omnipool-liquidity-mining/src/tests/mock.rs b/pallets/omnipool-liquidity-mining/src/tests/mock.rs index 8c6f695d4..c9f3db173 100644 --- a/pallets/omnipool-liquidity-mining/src/tests/mock.rs +++ b/pallets/omnipool-liquidity-mining/src/tests/mock.rs @@ -350,7 +350,9 @@ impl pallet_omnipool::Config for Test { type BurnProtocolFee = BurnFee; } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} pub struct ExtBuilder { endowed_accounts: Vec<(AccountId, AssetId, Balance)>, diff --git a/pallets/omnipool/src/tests/mock.rs b/pallets/omnipool/src/tests/mock.rs index d448f7166..0ada932c1 100644 --- a/pallets/omnipool/src/tests/mock.rs +++ b/pallets/omnipool/src/tests/mock.rs @@ -186,7 +186,9 @@ parameter_types! { pub MinWithdrawFee: Permill = WITHDRAWAL_FEE.with(|v| *v.borrow()); } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} impl Config for Test { type AssetId = AssetId; diff --git a/pallets/otc-settlements/src/mock.rs b/pallets/otc-settlements/src/mock.rs index 1302bc910..c9ae9ee10 100644 --- a/pallets/otc-settlements/src/mock.rs +++ b/pallets/otc-settlements/src/mock.rs @@ -248,7 +248,9 @@ impl pallet_currencies::Config for Test { type WeightInfo = (); } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} parameter_types! { pub const MinTradingLimit: Balance = 1_000; diff --git a/pallets/otc/src/tests/mock.rs b/pallets/otc/src/tests/mock.rs index 06821e7f3..3fd044f71 100644 --- a/pallets/otc/src/tests/mock.rs +++ b/pallets/otc/src/tests/mock.rs @@ -144,7 +144,9 @@ impl orml_tokens::Config for Test { type CurrencyHooks = (); } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} pub struct DummyRegistry(sp_std::marker::PhantomData); diff --git a/pallets/route-executor/src/tests/mock.rs b/pallets/route-executor/src/tests/mock.rs index 2684a7ac0..e5ed6d908 100644 --- a/pallets/route-executor/src/tests/mock.rs +++ b/pallets/route-executor/src/tests/mock.rs @@ -149,7 +149,9 @@ impl pallet_currencies::Config for Test { type WeightInfo = (); } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} type Pools = (XYK, StableSwap, OmniPool, LBP); diff --git a/pallets/stableswap/src/tests/mock.rs b/pallets/stableswap/src/tests/mock.rs index 2f92858a9..7e7abf29b 100644 --- a/pallets/stableswap/src/tests/mock.rs +++ b/pallets/stableswap/src/tests/mock.rs @@ -197,7 +197,9 @@ impl DustRemovalAccountWhitelist for Whitelist { } } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} impl Config for Test { type AssetId = AssetId; diff --git a/pallets/synthetic-logs/Cargo.toml b/pallets/synthetic-logs/Cargo.toml new file mode 100644 index 000000000..eb80cf56f --- /dev/null +++ b/pallets/synthetic-logs/Cargo.toml @@ -0,0 +1,63 @@ +[package] +name = "pallet-synthetic-logs" +version = "0.1.0" +authors = ["GalacticCouncil"] +edition = "2021" +license = "Apache 2.0" +homepage = 'https://github.com/galacticcouncil/hydration-node' +repository = 'https://github.com/galacticcouncil/hydration-node' +description = "Buffer of synthetic ethereum logs from substrate-side events; flushes them as synthetic pallet_ethereum transactions on on_finalize so eth-rpc surfaces them." +readme = "README.md" + +[dependencies] +codec = { workspace = true } +scale-info = { workspace = true } +serde = { workspace = true, optional = true } +log = { workspace = true } + +# Substrate +sp-std = { workspace = true } +sp-io = { workspace = true } +sp-core = { workspace = true } +sp-runtime = { workspace = true } +frame-support = { workspace = true } +frame-system = { workspace = true } + +# Ethereum / Frontier +ethereum = { workspace = true } +ethereum-types = { workspace = true } +pallet-ethereum = { workspace = true } +fp-rpc = { workspace = true } +fp-evm = { workspace = true } +pallet-evm = { workspace = true } + +# HydraDX +pallet-broadcast = { workspace = true } +primitives = { workspace = true } + +[features] +default = ["std"] +std = [ + "codec/std", + "scale-info/std", + "serde", + "log/std", + "sp-std/std", + "sp-io/std", + "sp-core/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "ethereum/std", + "ethereum-types/std", + "pallet-ethereum/std", + "pallet-evm/std", + "fp-rpc/std", + "fp-evm/std", + "pallet-broadcast/std", + "primitives/std", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", +] diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs new file mode 100644 index 000000000..54ea2f016 --- /dev/null +++ b/pallets/synthetic-logs/src/lib.rs @@ -0,0 +1,306 @@ +// This file is part of hydration-node. +// +// Copyright (C) 2020-2026 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +//! # Synthetic Logs Pallet +//! +//! Buffers ethereum-shaped logs that originate from substrate-side hooks +//! (orml-tokens transfers, pallet-broadcast trades, etc.) and flushes them on +//! `on_finalize` as synthetic `pallet_ethereum::Transaction` records. This +//! makes substrate-origin events visible to eth json-rpc (`eth_getLogs`, +//! `eth_getTransactionReceipt`) and to standard EVM tooling — ethers.js, +//! etherscan-style explorers, the graph, dex aggregators. +//! +//! ## Bucket model +//! +//! Each pushed log is tagged with a `Bucket` derived from the current +//! `frame_system::Phase` plus `pallet_broadcast::ExecutionContext` (when in +//! a hook phase). One synthetic transaction is built per bucket, so: +//! - one synth tx per substrate extrinsic (containing all logs from that extrinsic) +//! - one synth tx per `(on_initialize/on_finalize, originating broadcast context)` +//! — e.g. each scheduled DCA execution gets its own tx attributed by `schedule_id` +//! +//! ## Pallet ordering +//! +//! Must be declared **before** `pallet_ethereum` in `construct_runtime!` so this +//! pallet's `on_finalize` runs first and writes into `pallet_ethereum::Pending` +//! before the ethereum pallet rolls Pending into the canonical block. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +mod tests; + +use codec::{Decode, Encode, MaxEncodedLen}; +use ethereum::EIP1559Transaction; +use ethereum_types::{Bloom, BloomInput, H160, H256, U256}; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; +use pallet_broadcast::types::ExecutionType; +use pallet_ethereum::{Receipt, Transaction, TransactionAction, TransactionStatus}; +use scale_info::TypeInfo; +use sp_std::prelude::*; + +pub use pallet::*; + +/// Sentinel address used as both `from` and (default) `to` for synthetic txs. +/// Indicates "non-real-tx origin"; logs inside still carry their own emitter +/// address (asset's erc20 contract for transfers, pool address for swaps). +pub const SENTINEL_ADDRESS: H160 = H160([ + 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, + 0xef, +]); + +/// Domain separator mixed into synthetic tx hashes so they can never collide +/// with real ethereum tx hashes computed from real signatures. +pub const SYNTH_DOMAIN: &[u8] = b"hydration-synth-v1"; + +/// Constant `r`/`s` value for synthetic signatures. Inside the valid ECDSA +/// range required by the ethereum crate, but clearly not a real signature. +pub const SYNTH_SIG_RS: H256 = H256([ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +]); + +/// Hard cap on number of buffered logs per block. On overflow we drop the +/// newest pushes and emit a `log::warn!` so operators notice. +pub const MAX_PENDING_LOGS: u32 = 4096; + +/// One synthetic-tx attribution bucket. All logs sharing a bucket end up in +/// the same synthetic transaction. +/// +/// `Hook` covers `on_initialize` / `on_idle` / `on_finalize` work — substrate +/// doesn't expose a stable public api to distinguish initialize from finalize +/// at hook-fire time, so we collapse them and rely on the broadcast +/// `ExecutionContext` for finer attribution (e.g. DCA schedule_id, xcm origin). +#[derive(Clone, Copy, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug, PartialEq, Eq)] +pub enum Bucket { + /// One synth tx per substrate extrinsic. + Extrinsic(u32), + /// One synth tx per (hook-phase + originating broadcast context). + Hook { origin: Option }, +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + pallet_ethereum::Config + pallet_broadcast::Config { + /// EVM chain id, mirrored from `pallet_evm::Config::ChainId`. + type ChainId: Get; + } + + /// Buffered `(bucket, emitter, log)` entries, drained on every `on_finalize`. + #[pallet::storage] + #[pallet::whitelist_storage] + #[pallet::unbounded] + pub type Pending = StorageValue<_, Vec<(Bucket, H160, ethereum::Log)>, ValueQuery>; + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_finalize(_n: BlockNumberFor) { + let drained = Pending::::take(); + if drained.is_empty() { + return; + } + Self::flush(drained); + } + } +} + +impl Pallet { + /// Buffer a log to be emitted as part of a synthetic tx at end of block. + /// Bucket is derived from current substrate phase and broadcast context. + pub fn push(emitter: H160, log: ethereum::Log) { + let bucket = Self::current_bucket(); + Pending::::mutate(|v| { + if v.len() as u32 >= MAX_PENDING_LOGS { + log::warn!( + target: "runtime::synthetic-logs", + "pending buffer full ({} entries); dropping log for {:?}", + v.len(), emitter, + ); + return; + } + v.push((bucket, emitter, log)); + }); + } + + /// Determine the bucket for the currently-executing substrate phase. + fn current_bucket() -> Bucket { + match frame_system::Pallet::::extrinsic_index() { + Some(i) => Bucket::Extrinsic(i), + None => Bucket::Hook { + origin: pallet_broadcast::Pallet::::get_context().first().copied(), + }, + } + } + + /// Drain buffer, group by bucket, and write one synthetic tx per bucket + /// into `pallet_ethereum::Pending`. Must run before `pallet_ethereum::on_finalize`. + fn flush(entries: Vec<(Bucket, H160, ethereum::Log)>) { + // sort entries by bucket while preserving in-bucket order + // (insertion order is preserved within each bucket because we iterate stably) + let mut groups: Vec<(Bucket, Vec)> = Vec::new(); + for (bucket, _emitter, log) in entries { + match groups.iter_mut().find(|(b, _)| *b == bucket) { + Some((_, logs)) => logs.push(log), + None => groups.push((bucket, vec![log])), + } + } + // stable bucket sort: Hook(Init,*) < Extrinsic(i) < Hook(Final,*) + groups.sort_by(|a, b| Self::bucket_sort_key(&a.0).cmp(&Self::bucket_sort_key(&b.0))); + + let block_number = frame_system::Pallet::::block_number(); + let parent_hash = frame_system::Pallet::::parent_hash(); + + for (idx, (bucket, logs)) in groups.into_iter().enumerate() { + Self::insert_synth_tx(bucket, logs, idx as u32, &parent_hash, block_number); + } + } + + fn bucket_sort_key(bucket: &Bucket) -> (u8, u64) { + match bucket { + Bucket::Hook { origin: None } => (0, 0), + Bucket::Hook { origin: Some(_) } => (0, Self::bucket_nonce(*bucket)), + Bucket::Extrinsic(i) => (1, *i as u64), + } + } + + /// Encodes the bucket as the synthetic tx's `nonce`, so indexers can + /// reverse the synth tx back to its substrate origin. + pub fn bucket_nonce(bucket: Bucket) -> u64 { + match bucket { + Bucket::Extrinsic(i) => i as u64, + Bucket::Hook { origin: None } => u64::MAX - 1, + Bucket::Hook { origin: Some(o) } => 0xDCA0_0000_0000_0000u64 | Self::origin_tag(&o), + } + } + + fn origin_tag(origin: &ExecutionType) -> u64 { + match origin { + ExecutionType::Router(id) => 0x01_00_0000_0000 | (*id as u64), + ExecutionType::DCA(schedule_id, _) => 0x02_00_0000_0000 | (*schedule_id as u64), + ExecutionType::Batch(id) => 0x03_00_0000_0000 | (*id as u64), + ExecutionType::Omnipool(id) => 0x04_00_0000_0000 | (*id as u64), + ExecutionType::XcmExchange(id) => 0x05_00_0000_0000 | (*id as u64), + ExecutionType::Xcm(_, id) => 0x06_00_0000_0000 | (*id as u64), + } + } + + fn insert_synth_tx( + bucket: Bucket, + logs: Vec, + group_index: u32, + parent_hash: &T::Hash, + block_number: BlockNumberFor, + ) { + let chain_id = ::ChainId::get(); + let nonce = Self::bucket_nonce(bucket); + + // Build a deterministic synthetic tx hash: + // keccak256(SYNTH_DOMAIN || parent_hash || block_number || nonce || group_index) + // `parent_hash` makes hashes unique across forks; nonce + group_index make them + // unique within a block. + let mut preimage: Vec = Vec::with_capacity(64); + preimage.extend_from_slice(SYNTH_DOMAIN); + preimage.extend_from_slice(parent_hash.as_ref()); + preimage.extend_from_slice(&block_number.encode()); + preimage.extend_from_slice(&nonce.to_be_bytes()); + preimage.extend_from_slice(&group_index.to_be_bytes()); + let transaction_hash = H256::from(sp_io::hashing::keccak_256(&preimage)); + + // Synthetic transaction. EIP-1559 envelope; fees and gas are zero. The + // signature is a constant fake (r=s=0x01..01) that satisfies the ECDSA + // range check imposed by the ethereum crate but obviously corresponds + // to no real signer. Synthetic txs are never recovered — `from` is + // sourced from `TransactionStatus.from`. + let signature = ethereum::eip2930::TransactionSignature::new(false, SYNTH_SIG_RS, SYNTH_SIG_RS) + .expect("synthetic signature constants are within valid ECDSA range; qed"); + let transaction = Transaction::EIP1559(EIP1559Transaction { + chain_id, + nonce: U256::from(nonce), + max_priority_fee_per_gas: U256::zero(), + max_fee_per_gas: U256::zero(), + gas_limit: U256::zero(), + action: TransactionAction::Call(SENTINEL_ADDRESS), + value: U256::zero(), + input: Vec::new(), + access_list: Vec::new(), + signature, + }); + + let mut bloom: Bloom = Bloom::default(); + Self::compute_logs_bloom(&logs, &mut bloom); + + let tx_index = pallet_ethereum::Pending::::count(); + + let status = TransactionStatus { + transaction_hash, + transaction_index: tx_index, + from: SENTINEL_ADDRESS, + to: Some(SENTINEL_ADDRESS), + contract_address: None, + logs: logs.clone(), + logs_bloom: bloom, + }; + + let receipt = Receipt::EIP1559(ethereum::EIP658ReceiptData { + status_code: 1, + used_gas: U256::zero(), + logs_bloom: bloom, + logs, + }); + + pallet_ethereum::Pending::::insert(tx_index, (transaction, status, receipt)); + } + + fn compute_logs_bloom(logs: &[ethereum::Log], bloom: &mut Bloom) { + for log in logs { + bloom.accrue(BloomInput::Raw(&log.address[..])); + for topic in log.topics.iter() { + bloom.accrue(BloomInput::Raw(&topic[..])); + } + } + } +} + +/// Helper: standard ERC-20 `Transfer(address,address,uint256)` topic0. +pub const TRANSFER_TOPIC: H256 = H256([ + 0xdd, 0xf2, 0x52, 0xad, 0x1b, 0xe2, 0xc8, 0x9b, 0x69, 0xc2, 0xb0, 0x68, 0xfc, 0x37, 0x8d, 0xaa, 0x95, 0x2b, 0xa7, + 0xf1, 0x63, 0xc4, 0xa1, 0x16, 0x28, 0xf5, 0x5a, 0x4d, 0xf5, 0x23, 0xb3, 0xef, +]); + +/// Helper: Uniswap V2 `Swap(address,uint256,uint256,uint256,uint256,address)` topic0. +pub const SWAP_TOPIC: H256 = H256([ + 0xd7, 0x8a, 0xd9, 0x5f, 0xa4, 0x6c, 0x99, 0x4b, 0x65, 0x51, 0xd0, 0xda, 0x85, 0xfc, 0x27, 0x5f, 0xe6, 0x13, 0xce, + 0x37, 0x65, 0x7f, 0xb8, 0xd5, 0xe3, 0xd1, 0x30, 0x84, 0x01, 0x59, 0xd8, 0x22, +]); + +/// Pad an `H160` to a 32-byte topic word (left-pad with 12 zero bytes). +pub fn h160_to_h256(addr: H160) -> H256 { + let mut bytes = [0u8; 32]; + bytes[12..].copy_from_slice(&addr.0); + H256(bytes) +} + +/// Encode a single u256 as a 32-byte big-endian word for log `data`. +pub fn encode_u256_be(value: U256) -> [u8; 32] { + value.to_big_endian() +} + +/// Encode four u256 values as 128 bytes (the ABI shape of the +/// uniswap v2 Swap event's non-indexed fields). +pub fn encode_uint256_quad(a: U256, b: U256, c: U256, d: U256) -> Vec { + let mut data = Vec::with_capacity(128); + data.extend_from_slice(&encode_u256_be(a)); + data.extend_from_slice(&encode_u256_be(b)); + data.extend_from_slice(&encode_u256_be(c)); + data.extend_from_slice(&encode_u256_be(d)); + data +} diff --git a/pallets/synthetic-logs/src/tests.rs b/pallets/synthetic-logs/src/tests.rs new file mode 100644 index 000000000..82b7cc58b --- /dev/null +++ b/pallets/synthetic-logs/src/tests.rs @@ -0,0 +1,73 @@ +// This file is part of hydration-node. +// +// Copyright (C) 2020-2026 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +//! Unit tests for the pure helpers exported by `pallet-synthetic-logs`. +//! +//! End-to-end tests (push -> on_finalize -> pallet_ethereum::Pending writes) +//! live in `integration-tests` because they require a runtime that wires +//! pallet_ethereum, pallet_evm, frame_system, and pallet_broadcast together. + +use super::*; +use ethereum_types::{H160, U256}; + +#[test] +fn h160_to_h256_left_pads_with_zeros() { + let addr = H160([ + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, + 0xbb, 0xcc, + ]); + let topic = h160_to_h256(addr); + // First 12 bytes zero, last 20 bytes are the address. + assert_eq!(&topic.0[..12], &[0u8; 12]); + assert_eq!(&topic.0[12..], &addr.0[..]); +} + +#[test] +fn encode_u256_be_round_trip() { + let value = U256::from(123_456_789u64); + let encoded = encode_u256_be(value); + assert_eq!(encoded.len(), 32); + assert_eq!(U256::from_big_endian(&encoded), value); +} + +#[test] +fn encode_uint256_quad_is_128_bytes() { + let data = encode_uint256_quad( + U256::from(1u64), + U256::from(2u64), + U256::from(3u64), + U256::from(4u64), + ); + assert_eq!(data.len(), 128); + assert_eq!(U256::from_big_endian(&data[0..32]), U256::from(1u64)); + assert_eq!(U256::from_big_endian(&data[32..64]), U256::from(2u64)); + assert_eq!(U256::from_big_endian(&data[64..96]), U256::from(3u64)); + assert_eq!(U256::from_big_endian(&data[96..128]), U256::from(4u64)); +} + +#[test] +fn synth_signature_is_in_valid_range() { + // Confirms our constant signature passes the ECDSA range check; the + // flusher panics with a message if this regresses. + let sig = ethereum::eip2930::TransactionSignature::new(false, SYNTH_SIG_RS, SYNTH_SIG_RS); + assert!(sig.is_some(), "synthetic signature constants must satisfy ECDSA range"); +} + +#[test] +fn known_topic_constants_match_expected_keccak256() { + // ERC-20 Transfer(address,address,uint256) + let expected_transfer = [ + 0xdd, 0xf2, 0x52, 0xad, 0x1b, 0xe2, 0xc8, 0x9b, 0x69, 0xc2, 0xb0, 0x68, 0xfc, 0x37, 0x8d, 0xaa, 0x95, 0x2b, + 0xa7, 0xf1, 0x63, 0xc4, 0xa1, 0x16, 0x28, 0xf5, 0x5a, 0x4d, 0xf5, 0x23, 0xb3, 0xef, + ]; + assert_eq!(TRANSFER_TOPIC.0, expected_transfer); + + // Uniswap V2 Swap(address,uint256,uint256,uint256,uint256,address) + let expected_swap = [ + 0xd7, 0x8a, 0xd9, 0x5f, 0xa4, 0x6c, 0x99, 0x4b, 0x65, 0x51, 0xd0, 0xda, 0x85, 0xfc, 0x27, 0x5f, 0xe6, 0x13, + 0xce, 0x37, 0x65, 0x7f, 0xb8, 0xd5, 0xe3, 0xd1, 0x30, 0x84, 0x01, 0x59, 0xd8, 0x22, + ]; + assert_eq!(SWAP_TOPIC.0, expected_swap); +} diff --git a/pallets/xyk/src/tests/mock.rs b/pallets/xyk/src/tests/mock.rs index da422fb44..5e4ef2947 100644 --- a/pallets/xyk/src/tests/mock.rs +++ b/pallets/xyk/src/tests/mock.rs @@ -192,7 +192,9 @@ impl CanCreatePool for Disallow10_10Pool { } } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} impl xyk::Config for Test { type AssetRegistry = AssetRegistry; diff --git a/runtime/adapters/src/tests/mock.rs b/runtime/adapters/src/tests/mock.rs index 1d6c454fb..bb7c8df32 100644 --- a/runtime/adapters/src/tests/mock.rs +++ b/runtime/adapters/src/tests/mock.rs @@ -292,7 +292,9 @@ impl pallet_xyk::Config for Test { type NonDustableWhitelistHandler = DummyDuster; } -impl pallet_broadcast::Config for Test {} +impl pallet_broadcast::Config for Test { + type OnTrade = (); +} pub struct CircuitBreakerWhitelist; diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 455c12e0c..9f03b6cb3 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "412.0.0" +version = "413.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" @@ -21,6 +21,7 @@ smallvec = { workspace = true } log = { workspace = true } num_enum = { workspace = true, default-features = false } evm = { workspace = true, features = ["with-codec"] } +environmental = { workspace = true } alloy-primitives = { workspace = true } alloy-sol-types = { workspace = true } @@ -43,6 +44,7 @@ pallet-lbp = { workspace = true } pallet-xyk = { workspace = true } pallet-referrals = { workspace = true } pallet-broadcast = { workspace = true } +pallet-synthetic-logs = { workspace = true } pallet-evm-accounts = { workspace = true } pallet-evm-accounts-rpc-runtime-api = { workspace = true } pallet-xyk-liquidity-mining = { workspace = true } @@ -274,6 +276,7 @@ std = [ "codec/std", "serde", "scale-info/std", + "environmental/std", "frame-executive/std", "frame-support/std", "frame-system/std", @@ -395,6 +398,7 @@ std = [ "pallet-referenda/std", "pallet-whitelist/std", "pallet-broadcast/std", + "pallet-synthetic-logs/std", "pallet-dispatcher/std", "pallet-signet/std", "pallet-dispenser/std", diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index e28cb16be..d1a5179b5 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -125,11 +125,14 @@ impl pallet_balances::Config for Runtime { pub struct CurrencyHooks; impl MutationHooks for CurrencyHooks { type OnDust = Duster; - type OnSlash = (); + type OnSlash = crate::evm::erc20_logs::EmitErc20TransferLog; type PreDeposit = SufficiencyCheck; - type PostDeposit = pallet_circuit_breaker::fuses::issuance::IssuanceIncreaseFuse; + type PostDeposit = crate::evm::erc20_logs::OnDepositTuple< + pallet_circuit_breaker::fuses::issuance::IssuanceIncreaseFuse, + crate::evm::erc20_logs::EmitErc20TransferLog, + >; type PreTransfer = SufficiencyCheck; - type PostTransfer = (); + type PostTransfer = crate::evm::erc20_logs::EmitErc20TransferLog; type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = (RemoveTxAssetOnKilled, OnKilledTokenAccount); } @@ -1799,7 +1802,9 @@ impl pallet_liquidation::Config for Runtime { type AuthorityOrigin = EitherOf, GeneralAdmin>; } -impl pallet_broadcast::Config for Runtime {} +impl pallet_broadcast::Config for Runtime { + type OnTrade = crate::evm::swap_logs::EmitUniswapV2SwapLog; +} parameter_types! { pub const HsmGasLimit: u64 = 400_000; diff --git a/runtime/hydradx/src/evm/erc20_logs.rs b/runtime/hydradx/src/evm/erc20_logs.rs new file mode 100644 index 000000000..f9bbf4287 --- /dev/null +++ b/runtime/hydradx/src/evm/erc20_logs.rs @@ -0,0 +1,101 @@ +// This file is part of hydration-node. +// +// Copyright (C) 2020-2026 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +//! ERC-20 `Transfer(address,address,uint256)` log emission for orml-tokens +//! mutation hooks. Each transfer/deposit/slash on a non-bound asset becomes a +//! log buffered in `pallet_synthetic_logs`, which flushes synthetic ethereum +//! transactions on `on_finalize` so eth-rpc surfaces them. +//! +//! Bound erc20 assets bypass orml-tokens entirely (they route through the +//! EVM runner via `pallet_currencies`), so this handler never fires for them +//! — there's no double-emission risk. + +use crate::evm::precompiles::erc20_mapping::HydraErc20Mapping; +use crate::Runtime; +use frame_support::sp_runtime::DispatchResult; +use hydradx_traits::evm::{Erc20Mapping, InspectEvmAccounts}; +use orml_traits::currency::{OnDeposit, OnSlash, OnTransfer}; +use pallet_synthetic_logs::{encode_u256_be, h160_to_h256, Pallet as SyntheticLogs, TRANSFER_TOPIC}; +use primitive_types::{H160, U256}; +use primitives::{AccountId, AssetId, Balance}; +use sp_std::{marker::PhantomData, vec::Vec}; + +/// `OnTransfer` / `OnDeposit` / `OnSlash` handler that emits ERC-20 +/// `Transfer(from, to, amount)` logs. `amount == 0` is skipped — orml allows +/// zero-amount calls but indexers usually filter them anyway. +pub struct EmitErc20TransferLog; + +fn evm_address_of(account: &AccountId) -> H160 { + pallet_evm_accounts::Pallet::::evm_address(account) +} + +fn build_transfer_log(asset: AssetId, from: H160, to: H160, amount: Balance) -> ethereum::Log { + let address = HydraErc20Mapping::asset_address(asset); + let mut data = Vec::with_capacity(32); + data.extend_from_slice(&encode_u256_be(U256::from(amount))); + ethereum::Log { + address, + topics: sp_std::vec![TRANSFER_TOPIC, h160_to_h256(from), h160_to_h256(to)], + data, + } +} + +fn push_transfer_log(asset: AssetId, from: H160, to: H160, amount: Balance) { + let log = build_transfer_log(asset, from, to, amount); + let address = HydraErc20Mapping::asset_address(asset); + SyntheticLogs::::push(address, log); +} + +impl OnTransfer for EmitErc20TransferLog { + fn on_transfer(asset: AssetId, from: &AccountId, to: &AccountId, amount: Balance) -> DispatchResult { + if amount == 0 || crate::evm::runner::is_in_evm() { + return Ok(()); + } + push_transfer_log(asset, evm_address_of(from), evm_address_of(to), amount); + Ok(()) + } +} + +impl OnDeposit for EmitErc20TransferLog { + fn on_deposit(asset: AssetId, who: &AccountId, amount: Balance) -> DispatchResult { + if amount == 0 || crate::evm::runner::is_in_evm() { + return Ok(()); + } + // Mint: Transfer(0x0, who, amount). + push_transfer_log(asset, H160::zero(), evm_address_of(who), amount); + Ok(()) + } +} + +impl OnSlash for EmitErc20TransferLog { + fn on_slash(asset: AssetId, who: &AccountId, amount: Balance) { + if amount == 0 || crate::evm::runner::is_in_evm() { + return; + } + // Burn-via-slash: Transfer(who, 0x0, amount). NOTE: orml's `OnSlash` + // is invoked with the requested slash amount, before clamping to the + // account's actual free balance. If the account holds less than + // `amount`, the emitted log slightly overstates the burn — accepted + // for v1; revisit if indexer fidelity demands it. + push_transfer_log(asset, evm_address_of(who), H160::zero(), amount); + } +} + +/// Generic 2-tuple combinator for `OnDeposit` — orml-traits doesn't provide +/// tuple impls. Used to chain the existing circuit-breaker issuance fuse with +/// our log emission. +pub struct OnDepositTuple(PhantomData<(A, B)>); + +impl OnDeposit for OnDepositTuple +where + A: OnDeposit, + B: OnDeposit, +{ + fn on_deposit(currency_id: AssetId, who: &AccountId, amount: Balance) -> DispatchResult { + A::on_deposit(currency_id, who, amount)?; + B::on_deposit(currency_id, who, amount)?; + Ok(()) + } +} diff --git a/runtime/hydradx/src/evm/mod.rs b/runtime/hydradx/src/evm/mod.rs index ba6d3607f..191ffc83f 100644 --- a/runtime/hydradx/src/evm/mod.rs +++ b/runtime/hydradx/src/evm/mod.rs @@ -55,6 +55,7 @@ use sp_core::{crypto::AccountId32, Get, U256}; pub mod aave_trade_executor; mod accounts_conversion; mod erc20_currency; +pub mod erc20_logs; pub mod evm_error_decoder; mod evm_fee; mod executor; @@ -62,6 +63,7 @@ mod gas_to_weight_mapping; pub mod permit; pub mod precompiles; mod runner; +pub mod swap_logs; use crate::circuit_breaker::IgnoreWithdrawFuse; pub use erc20_currency::Erc20Currency; @@ -225,6 +227,10 @@ impl pallet_ethereum::Config for Runtime { type ExtraDataLength = sp_core::ConstU32<1>; } +impl pallet_synthetic_logs::Config for Runtime { + type ChainId = ::ChainId; +} + pub struct EvmNonceProvider; impl pallet_evm_accounts::EvmNonceProvider for EvmNonceProvider { fn get_nonce(evm_address: sp_core::H160) -> U256 { diff --git a/runtime/hydradx/src/evm/precompiles/multicurrency.rs b/runtime/hydradx/src/evm/precompiles/multicurrency.rs index 06bfce14c..8e718f6b2 100644 --- a/runtime/hydradx/src/evm/precompiles/multicurrency.rs +++ b/runtime/hydradx/src/evm/precompiles/multicurrency.rs @@ -38,11 +38,12 @@ use frame_support::traits::{ExistenceRequirement, IsType, OriginTrait}; use hydradx_traits::evm::{Erc20Encoding, InspectEvmAccounts}; use hydradx_traits::registry::Inspect as InspectRegistry; use orml_traits::{MultiCurrency as MultiCurrencyT, MultiCurrency}; -use pallet_evm::{AddressMapping, ExitRevert, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; -use primitive_types::H160; +use pallet_evm::{AddressMapping, ExitRevert, Log, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; +use pallet_synthetic_logs::{encode_u256_be, h160_to_h256, TRANSFER_TOPIC}; +use primitive_types::{H160, U256}; use primitives::{AssetId, Balance}; use sp_runtime::traits::Dispatchable; -use sp_std::marker::PhantomData; +use sp_std::{marker::PhantomData, vec}; pub struct MultiCurrencyPrecompile(PhantomData); @@ -214,11 +215,12 @@ where let mut input = handle.read_input()?; input.expect_arguments(2)?; - let to: H160 = input.read::
()?.into(); + let to_h160: H160 = input.read::
()?.into(); + let from_h160: H160 = handle.context().caller; let amount = input.read::()?; - let origin = ExtendedAddressMapping::into_account_id(handle.context().caller); - let to = ExtendedAddressMapping::into_account_id(to); + let origin = ExtendedAddressMapping::into_account_id(from_h160); + let to = ExtendedAddressMapping::into_account_id(to_h160); log::debug!(target: "evm", "multicurrency: transfer from: {origin:?}, to: {to:?}, amount: {amount:?}"); @@ -234,6 +236,11 @@ where output: e.encode(), })?; + // Emit ERC-20 Transfer log inline so eth tooling sees the event in the + // real eth tx's logs. The substrate-side orml hooks are suppressed for + // in-evm context (`is_in_evm()` returns true) so we don't double-emit. + emit_erc20_transfer_log(handle, asset_id, from_h160, to_h160, amount)?; + Ok(succeed(EvmDataWriter::new().write(true).build())) } @@ -313,15 +320,15 @@ where } } - let from = ExtendedAddressMapping::into_account_id(from); - let to = ExtendedAddressMapping::into_account_id(to); + let from_acc = ExtendedAddressMapping::into_account_id(from); + let to_acc = ExtendedAddressMapping::into_account_id(to); - log::debug!(target: "evm", "multicurrency: transferFrom from: {from:?}, to: {to:?}, amount: {amount:?}"); + log::debug!(target: "evm", "multicurrency: transferFrom from: {from_acc:?}, to: {to_acc:?}, amount: {amount:?}"); as MultiCurrency>::transfer( asset_id, - &(>::into(from)), - &(>::into(to)), + &(>::into(from_acc)), + &(>::into(to_acc)), amount, ExistenceRequirement::AllowDeath, ) @@ -330,6 +337,35 @@ where output: e.encode(), })?; + emit_erc20_transfer_log(handle, asset_id, from, to, amount)?; + Ok(succeed(EvmDataWriter::new().write(true).build())) } } + +/// Emit an ERC-20 `Transfer(from, to, amount)` log inline on the precompile +/// handle so it lands in the calling eth transaction's logs. Address used is +/// the precompile's `code_address` (the asset's erc20 contract address). +fn emit_erc20_transfer_log( + handle: &mut impl PrecompileHandle, + asset_id: AssetId, + from: H160, + to: H160, + amount: Balance, +) -> Result<(), PrecompileFailure> { + let _ = asset_id; // contract address is `handle.code_address()`; asset_id reserved for future use + let topics = vec![TRANSFER_TOPIC, h160_to_h256(from), h160_to_h256(to)]; + let data = encode_u256_be(U256::from(amount)).to_vec(); + + // Charge the standard EVM log gas (3 topics, 32 bytes data). + let log_cost = + crate::evm::precompiles::costs::log_costs(topics.len(), data.len()).map_err(|_| PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::OutOfGas, + })?; + handle.record_cost(log_cost)?; + + let address = handle.code_address(); + let log = Log { address, topics, data }; + handle.log(log.address, log.topics, log.data)?; + Ok(()) +} diff --git a/runtime/hydradx/src/evm/runner.rs b/runtime/hydradx/src/evm/runner.rs index b982dbf06..9f3d7069a 100644 --- a/runtime/hydradx/src/evm/runner.rs +++ b/runtime/hydradx/src/evm/runner.rs @@ -37,6 +37,18 @@ use primitives::{AccountId, AssetId, Balance}; use sp_runtime::traits::UniqueSaturatedInto; use sp_std::vec::Vec; +// Process-local flag set while an EVM execution frame is on the stack. Read by +// substrate-side hooks (e.g. orml-tokens PostTransfer, pallet_broadcast OnTrade) +// to decide whether to buffer a synthetic log or skip — when in-evm, the log is +// expected to be emitted inline by the originating precompile so it lands in the +// real eth tx's logs. Nested frames inherit naturally via `using_once` semantics. +environmental::environmental!(EVM_CONTEXT: bool); + +/// Returns true if any EVM execution frame is currently on the call stack. +pub fn is_in_evm() -> bool { + EVM_CONTEXT::with(|in_evm| *in_evm).unwrap_or(false) +} + pub struct WrapRunner(sp_std::marker::PhantomData<(T, R, B)>); impl Runner for WrapRunner @@ -156,23 +168,25 @@ where let original_nonce = frame_system::Pallet::::account_nonce(source_account_id.clone()); // Validated, flag set to false - let result = R::call( - source, - target, - input, - value, - gas_limit, - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list, - authorization_list, - is_transactional, - false, - weight_limit, - proof_size_base_cost, - config, - )?; + let result = EVM_CONTEXT::using_once(&mut true, || { + R::call( + source, + target, + input, + value, + gas_limit, + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list, + authorization_list, + is_transactional, + false, + weight_limit, + proof_size_base_cost, + config, + ) + })?; if validate && is_transactional && nonce.is_none() && max_priority_fee_per_gas.is_none() { let current_nonce = frame_system::Pallet::::account_nonce(source_account_id.clone()); @@ -221,22 +235,24 @@ where )?; } // Validated, flag set to false - R::create( - source, - init, - value, - gas_limit, - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list, - authorization_list, - is_transactional, - false, - weight_limit, - proof_size_base_cost, - config, - ) + EVM_CONTEXT::using_once(&mut true, || { + R::create( + source, + init, + value, + gas_limit, + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list, + authorization_list, + is_transactional, + false, + weight_limit, + proof_size_base_cost, + config, + ) + }) } fn create2( @@ -275,23 +291,25 @@ where )?; } //Validated, flag set to false - R::create2( - source, - init, - salt, - value, - gas_limit, - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list, - authorization_list, - is_transactional, - false, - weight_limit, - proof_size_base_cost, - config, - ) + EVM_CONTEXT::using_once(&mut true, || { + R::create2( + source, + init, + salt, + value, + gas_limit, + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list, + authorization_list, + is_transactional, + false, + weight_limit, + proof_size_base_cost, + config, + ) + }) } fn create_force_address( @@ -330,23 +348,25 @@ where )?; } //Validated, flag set to false - R::create_force_address( - source, - init, - value, - gas_limit, - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list, - authorization_list, - is_transactional, - false, - weight_limit, - proof_size_base_cost, - config, - contract_address, - ) + EVM_CONTEXT::using_once(&mut true, || { + R::create_force_address( + source, + init, + value, + gas_limit, + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list, + authorization_list, + is_transactional, + false, + weight_limit, + proof_size_base_cost, + config, + contract_address, + ) + }) } } diff --git a/runtime/hydradx/src/evm/swap_logs.rs b/runtime/hydradx/src/evm/swap_logs.rs new file mode 100644 index 000000000..084853294 --- /dev/null +++ b/runtime/hydradx/src/evm/swap_logs.rs @@ -0,0 +1,128 @@ +// This file is part of hydration-node. +// +// Copyright (C) 2020-2026 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +//! Translates `pallet_broadcast::Event::Swapped3` trades into uniswap-v2-style +//! `Swap(address,uint256,uint256,uint256,uint256,address)` evm logs and +//! buffers them in `pallet_synthetic_logs`. Picked the uniswap v2 signature +//! because every defi aggregator (1inch, paraswap, defillama) and every dex +//! subgraph already indexes by it — emitting it from a stable per-pool +//! address gets us auto-discovery for free. +//! +//! v1 scope: bilateral 1-input / 1-output swaps (`ExactIn`/`ExactOut`). +//! Liquidity add/remove and multi-asset trades are skipped — they don't fit +//! the uniswap v2 mental model. Future extensions: `Mint`/`Burn` for +//! liquidity ops, custom `OTCFilled` for limit orders. + +use crate::evm::precompiles::erc20_mapping::is_asset_address; +use crate::Runtime; +use hydradx_traits::evm::InspectEvmAccounts; +use pallet_broadcast::types::{Asset, ExecutionType, Fee, Filler, TradeOperation}; +use pallet_broadcast::OnTrade; +use pallet_synthetic_logs::{encode_uint256_quad, h160_to_h256, Pallet as SyntheticLogs, SWAP_TOPIC}; +use primitive_types::{H160, U256}; +use primitives::AccountId; +use sp_std::vec; + +pub struct EmitUniswapV2SwapLog; + +fn evm_address_of(account: &AccountId) -> H160 { + pallet_evm_accounts::Pallet::::evm_address(account) +} + +/// Derive a stable evm address for a substrate-side pool (the trade `filler`). +/// +/// Each pool has a unique substrate `AccountId` (omnipool's pallet account, +/// each stableswap pool's account, each xyk pool's share-token account). The +/// h160 derivation from that accountId is stable across blocks and 1:1 with +/// the pool — exactly what indexers need. +fn derive_pool_address(filler: &AccountId, _filler_type: &Filler) -> H160 { + evm_address_of(filler) +} + +impl OnTrade for EmitUniswapV2SwapLog { + fn on_trade( + swapper: &AccountId, + filler: &AccountId, + filler_type: &Filler, + operation: &TradeOperation, + inputs: &[Asset], + outputs: &[Asset], + _fees: &[Fee], + _operation_stack: &[ExecutionType], + ) { + // v1: only swap-shaped trades. Liquidity ops, OTC limit fills, and + // multi-asset stableswap legs don't fit the uniswap v2 mental model. + if !matches!(operation, TradeOperation::ExactIn | TradeOperation::ExactOut) { + return; + } + if inputs.len() != 1 || outputs.len() != 1 { + return; + } + + // Today no swap precompile exists, so substrate-side trades never fire + // while inside an evm execution frame. Defensive guard: if a future + // swap precompile is added, it must emit the log inline itself; we + // skip here to avoid double-emission. + if crate::evm::runner::is_in_evm() { + return; + } + + let in_asset = inputs[0].asset; + let in_amount = inputs[0].amount; + let out_asset = outputs[0].asset; + let out_amount = outputs[0].amount; + + if in_amount == 0 && out_amount == 0 { + return; + } + + // Sort assets by id so token0 < token1 deterministically. Indexers + // assume this ordering when interpreting the four amount fields. + let token0_id = in_asset.min(out_asset); + let (a0_in, a1_in, a0_out, a1_out) = if in_asset == token0_id { + ( + U256::from(in_amount), + U256::zero(), + U256::zero(), + U256::from(out_amount), + ) + } else { + ( + U256::zero(), + U256::from(in_amount), + U256::from(out_amount), + U256::zero(), + ) + }; + + let pool_address = derive_pool_address(filler, filler_type); + // Defensive: pool address must not collide with the erc20 prefix range + // used by `HydraErc20Mapping::asset_address`. If a pool's accountId + // happened to derive to that range we'd emit logs from an asset + // contract address by mistake. Skip silently if it does — this is + // astronomically unlikely with any real pool accountId. + if is_asset_address(pool_address) { + log::warn!( + target: "runtime::synthetic-logs", + "pool address collides with erc20 prefix; skipping swap log for filler {:?}", + filler, + ); + return; + } + + let sender = evm_address_of(swapper); + // Hydration trades always credit the swapper. There's no separate + // recipient field on `Swapped3` to encode here. + let recipient = sender; + + let log = ethereum::Log { + address: pool_address, + topics: vec![SWAP_TOPIC, h160_to_h256(sender), h160_to_h256(recipient)], + data: encode_uint256_quad(a0_in, a1_in, a0_out, a1_out), + }; + + SyntheticLogs::::push(pool_address, log); + } +} diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 622b7dd08..547318a55 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: Cow::Borrowed("hydradx"), impl_name: Cow::Borrowed("hydradx"), authoring_version: 1, - spec_version: 412, + spec_version: 413, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -211,6 +211,10 @@ construct_runtime!( // Frontier and EVM pallets EVM: pallet_evm = 90, EVMChainId: pallet_evm_chain_id = 91, + // SyntheticLogs MUST come before Ethereum so its on_finalize runs first + // and writes synthetic txs into pallet_ethereum::Pending before the + // ethereum pallet rolls Pending into the canonical block. + SyntheticLogs: pallet_synthetic_logs = 86, Ethereum: pallet_ethereum = 92, EVMAccounts: pallet_evm_accounts = 93, DynamicEvmFee: pallet_dynamic_evm_fee = 94, From e781d15a198558da57fff4471668f6a91cae5df6 Mon Sep 17 00:00:00 2001 From: mrq Date: Mon, 4 May 2026 13:38:17 +0200 Subject: [PATCH 02/17] forked balances & tokens pallet --- Cargo.lock | 10 +- Cargo.toml | 20 +- pallets/balances/Cargo.toml | 57 + pallets/balances/README.md | 122 + pallets/balances/src/benchmarking.rs | 368 +++ pallets/balances/src/impl_currency.rs | 954 ++++++ pallets/balances/src/impl_fungible.rs | 387 +++ pallets/balances/src/lib.rs | 1315 +++++++++ pallets/balances/src/migration.rs | 103 + pallets/balances/src/tests/currency_tests.rs | 1445 +++++++++ .../balances/src/tests/dispatchable_tests.rs | 384 +++ .../src/tests/fungible_conformance_tests.rs | 141 + pallets/balances/src/tests/fungible_tests.rs | 670 +++++ pallets/balances/src/tests/general_tests.rs | 143 + pallets/balances/src/tests/mod.rs | 351 +++ .../balances/src/tests/reentrancy_tests.rs | 196 ++ pallets/balances/src/types.rs | 185 ++ pallets/balances/src/weights.rs | 321 ++ pallets/tokens/Cargo.toml | 54 + pallets/tokens/README.md | 13 + pallets/tokens/runtime-api/Cargo.toml | 23 + pallets/tokens/runtime-api/src/lib.rs | 18 + pallets/tokens/src/imbalances.rs | 197 ++ pallets/tokens/src/impls.rs | 352 +++ pallets/tokens/src/lib.rs | 2605 +++++++++++++++++ pallets/tokens/src/mock.rs | 445 +++ pallets/tokens/src/tests.rs | 1271 ++++++++ pallets/tokens/src/tests_currency_adapter.rs | 674 +++++ pallets/tokens/src/tests_events.rs | 469 +++ pallets/tokens/src/tests_fungibles.rs | 741 +++++ pallets/tokens/src/tests_multicurrency.rs | 808 +++++ pallets/tokens/src/weights.rs | 66 + 32 files changed, 14900 insertions(+), 8 deletions(-) create mode 100644 pallets/balances/Cargo.toml create mode 100644 pallets/balances/README.md create mode 100644 pallets/balances/src/benchmarking.rs create mode 100644 pallets/balances/src/impl_currency.rs create mode 100644 pallets/balances/src/impl_fungible.rs create mode 100644 pallets/balances/src/lib.rs create mode 100644 pallets/balances/src/migration.rs create mode 100644 pallets/balances/src/tests/currency_tests.rs create mode 100644 pallets/balances/src/tests/dispatchable_tests.rs create mode 100644 pallets/balances/src/tests/fungible_conformance_tests.rs create mode 100644 pallets/balances/src/tests/fungible_tests.rs create mode 100644 pallets/balances/src/tests/general_tests.rs create mode 100644 pallets/balances/src/tests/mod.rs create mode 100644 pallets/balances/src/tests/reentrancy_tests.rs create mode 100644 pallets/balances/src/types.rs create mode 100644 pallets/balances/src/weights.rs create mode 100644 pallets/tokens/Cargo.toml create mode 100644 pallets/tokens/README.md create mode 100644 pallets/tokens/runtime-api/Cargo.toml create mode 100644 pallets/tokens/runtime-api/src/lib.rs create mode 100644 pallets/tokens/src/imbalances.rs create mode 100644 pallets/tokens/src/impls.rs create mode 100644 pallets/tokens/src/lib.rs create mode 100644 pallets/tokens/src/mock.rs create mode 100644 pallets/tokens/src/tests.rs create mode 100644 pallets/tokens/src/tests_currency_adapter.rs create mode 100644 pallets/tokens/src/tests_events.rs create mode 100644 pallets/tokens/src/tests_fungibles.rs create mode 100644 pallets/tokens/src/tests_multicurrency.rs create mode 100644 pallets/tokens/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 7b142f606..6190bddd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9162,17 +9162,21 @@ dependencies = [ [[package]] name = "orml-tokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" dependencies = [ "frame-support", "frame-system", "log", "orml-traits", + "pallet-elections-phragmen", + "pallet-treasury", "parity-scale-codec", "scale-info", "serde", "sp-arithmetic", + "sp-core", + "sp-io", "sp-runtime", + "sp-staking", "sp-std", ] @@ -9590,16 +9594,18 @@ dependencies = [ [[package]] name = "pallet-balances" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" dependencies = [ "docify", "frame-benchmarking", "frame-support", "frame-system", "log", + "pallet-transaction-payment", "parity-scale-codec", + "paste", "scale-info", "sp-core", + "sp-io", "sp-runtime", ] diff --git a/Cargo.toml b/Cargo.toml index a691b5811..c4e9b46d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,8 @@ members = [ "pallets/signet", "pallets/dispenser", "pallets/synthetic-logs", + "pallets/balances", + "pallets/tokens", ] resolver = "2" @@ -252,7 +254,7 @@ sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = # Substrate Pallets pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } +pallet-balances = { path = "pallets/balances", default-features = false } pallet-bags-list = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } pallet-conviction-voting = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } @@ -290,7 +292,7 @@ substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil # ORML dependencies orml-benchmarking = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } orml-currencies = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } +orml-tokens = { path = "pallets/tokens", default-features = false } orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } orml-utilities = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } orml-vesting = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } @@ -411,7 +413,7 @@ ismp-parachain-inherent = { version = "2506.1.0" } [patch."https://github.com/moonbeam-foundation/open-runtime-module-library"] # ORML dependencies orml-benchmarking = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } +orml-tokens = { path = "pallets/tokens" } orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } orml-utilities = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } orml-vesting = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } @@ -494,7 +496,7 @@ sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", b # Substrate Pallets pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-balances = { path = "pallets/balances" } pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } @@ -653,7 +655,7 @@ sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", b # Substrate Pallets pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-balances = { path = "pallets/balances" } pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } @@ -813,7 +815,7 @@ sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", b # Substrate Pallets pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-balances = { path = "pallets/balances" } pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } @@ -900,3 +902,9 @@ cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/ [patch."https://github.com/bifrost-io/open-runtime-module-library"] orml-xcm-support = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } + +[patch."https://github.com/galacticcouncil/polkadot-sdk"] +pallet-balances = { path = "pallets/balances" } + +[patch."https://github.com/galacticcouncil/open-runtime-module-library"] +orml-tokens = { path = "pallets/tokens" } diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml new file mode 100644 index 000000000..6f407049f --- /dev/null +++ b/pallets/balances/Cargo.toml @@ -0,0 +1,57 @@ +[package] +name = "pallet-balances" +version = "42.0.0" +authors = ["Parity Technologies "] +edition = "2021" +license = "Apache-2.0" +homepage = "https://substrate.io" +repository = "https://github.com/galacticcouncil/hydration-node" +description = "FRAME pallet to manage balances" +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { features = ["derive", "max-encoded-len"], workspace = true } +docify = "0.2.8" +frame-benchmarking = { optional = true, workspace = true } +frame-support.workspace = true +frame-system.workspace = true +log = { workspace = true } +scale-info = { features = ["derive"], workspace = true } +sp-core.workspace = true +sp-runtime.workspace = true + +[dev-dependencies] +frame-support = { features = ["experimental"], default-features = true, workspace = true } +pallet-transaction-payment = { default-features = true, workspace = true } +paste = { workspace = true, default-features = true } +sp-io = { default-features = true, workspace = true } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "scale-info/std", + "sp-core/std", + "sp-runtime/std", +] +insecure_zero_ed = [] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-transaction-payment/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/pallets/balances/README.md b/pallets/balances/README.md new file mode 100644 index 000000000..1dc93a6bd --- /dev/null +++ b/pallets/balances/README.md @@ -0,0 +1,122 @@ +# Balances Module + +The Balances module provides functionality for handling accounts and balances. + +- [`Config`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/trait.Config.html) +- [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Call.html) +- [`Pallet`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.Pallet.html) + +## Overview + +The Balances module provides functions for: + +- Getting and setting free balances. +- Retrieving total, reserved and unreserved balances. +- Repatriating a reserved balance to a beneficiary account that exists. +- Transferring a balance between accounts (when not reserved). +- Slashing an account balance. +- Account creation and removal. +- Managing total issuance. +- Setting and managing locks. + +### Terminology + +- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents "dust accounts" +from filling storage. When the free plus the reserved balance (i.e. the total balance) fall below this, then the account + is said to be dead; and it loses its functionality as well as any prior history and all information on it is removed + from the chain's state. No account should ever have a total balance that is strictly between 0 and the existential + deposit (exclusive). If this ever happens, it indicates either a bug in this module or an erroneous raw mutation of + storage. + +- **Total Issuance:** The total number of units in existence in a system. + +- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its total balance has +become zero (or, strictly speaking, less than the Existential Deposit). + +- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only balance that matters for + most operations. + +- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. Reserved balance can + still be slashed, but only after all the free balance has been slashed. + +- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting (i.e. a +difference between total issuance and account balances). Functions that result in an imbalance will return an object of +the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is simply dropped, it should +automatically maintain any book-keeping such as total issuance.) + +- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple locks +always operate over the same funds, so they "overlay" rather than "stack". + +### Implementations + +The Balances module provides implementations for the following traits. If these traits provide the functionality that +you need, then you can avoid coupling with the Balances module. + +- [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Currency.html): Functions for dealing +with a fungible assets system. +- [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): +Functions for dealing with assets that can be reserved from an account. +- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions +for dealing with accounts that allow liquidity restrictions. +- [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling +imbalances between total issuance in the system and account balances. Must be used when a function creates new funds +(e.g. a reward) or destroys some funds (e.g. a system fee). +- [`IsDeadAccount`](https://docs.rs/frame-support/latest/frame_support/traits/trait.IsDeadAccount.html): Determiner to +say whether a given account is unused. + +## Interface + +### Dispatchable Functions + +- `transfer` - Transfer some liquid free balance to another account. +- `force_set_balance` - Set the balances of a given account. The origin of this call must be root. + +## Usage + +The following examples show how to use the Balances module in your custom module. + +### Examples from the FRAME + +The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: + +```rust +use frame_support::traits::Currency; + +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; + +``` + +The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: + +```rust +use frame_support::traits::{WithdrawReasons, LockableCurrency}; +use sp_runtime::traits::Bounded; +pub trait Config: frame_system::Config { + type Currency: LockableCurrency>; +} + +fn update_ledger( + controller: &T::AccountId, + ledger: &StakingLedger +) { + T::Currency::set_lock( + STAKING_ID, + &ledger.stash, + ledger.total, + WithdrawReasons::all() + ); + // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +} +``` + +## Genesis config + +The Balances module depends on the +[`GenesisConfig`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.GenesisConfig.html). + +## Assumptions + +- Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. + +License: Apache-2.0 diff --git a/pallets/balances/src/benchmarking.rs b/pallets/balances/src/benchmarking.rs new file mode 100644 index 000000000..d26660ac8 --- /dev/null +++ b/pallets/balances/src/benchmarking.rs @@ -0,0 +1,368 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Balances pallet benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use crate::Pallet as Balances; + +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; +use sp_runtime::traits::Bounded; +use types::ExtraFlags; + +const SEED: u32 = 0; +// existential deposit multiplier +const ED_MULTIPLIER: u32 = 10; + +fn minimum_balance, I: 'static>() -> T::Balance { + if cfg!(feature = "insecure_zero_ed") { + 100u32.into() + } else { + T::ExistentialDeposit::get() + } +} + +#[instance_benchmarks] +mod benchmarks { + use super::*; + + // Benchmark `transfer` extrinsic with the worst possible conditions: + // * Transfer will kill the sender account. + // * Transfer will create the recipient account. + #[benchmark] + fn transfer_allow_death() { + let existential_deposit: T::Balance = minimum_balance::(); + let caller = whitelisted_caller(); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()).max(1u32.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, + // and reap this user. + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + let transfer_amount = + existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); + + if cfg!(feature = "insecure_zero_ed") { + assert_eq!(Balances::::free_balance(&caller), balance - transfer_amount); + } else { + assert_eq!(Balances::::free_balance(&caller), Zero::zero()); + } + + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // Benchmark `transfer` with the best possible condition: + // * Both accounts exist and will continue to exist. + #[benchmark(extra)] + fn transfer_best_case() { + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + + // Give the sender account max funds for transfer (their account will never reasonably be + // killed). + let _ = + as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); + + // Give the recipient account existential deposit (thus their account already exists). + let existential_deposit: T::Balance = minimum_balance::(); + let _ = + as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); + let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + + #[extrinsic_call] + transfer_allow_death(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); + + assert!(!Balances::::free_balance(&caller).is_zero()); + assert!(!Balances::::free_balance(&recipient).is_zero()); + } + + // Benchmark `transfer_keep_alive` with the worst possible condition: + // * The recipient account is created. + #[benchmark] + fn transfer_keep_alive() { + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + + // Give the sender account max funds, thus a transfer will not kill account. + let _ = + as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); + let existential_deposit: T::Balance = minimum_balance::(); + let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); + + assert!(!Balances::::free_balance(&caller).is_zero()); + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // Benchmark `force_set_balance` coming from ROOT account. This always creates an account. + #[benchmark] + fn force_set_balance_creating() { + let user: T::AccountId = account("user", 0, SEED); + let user_lookup = T::Lookup::unlookup(user.clone()); + + let existential_deposit: T::Balance = minimum_balance::(); + let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + + #[extrinsic_call] + force_set_balance(RawOrigin::Root, user_lookup, balance_amount); + + assert_eq!(Balances::::free_balance(&user), balance_amount); + } + + // Benchmark `force_set_balance` coming from ROOT account. This always kills an account. + #[benchmark] + fn force_set_balance_killing() { + let user: T::AccountId = account("user", 0, SEED); + let user_lookup = T::Lookup::unlookup(user.clone()); + + // Give the user some initial balance. + let existential_deposit: T::Balance = minimum_balance::(); + let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); + + #[extrinsic_call] + force_set_balance(RawOrigin::Root, user_lookup, Zero::zero()); + + assert!(Balances::::free_balance(&user).is_zero()); + } + + // Benchmark `force_transfer` extrinsic with the worst possible conditions: + // * Transfer will kill the sender account. + // * Transfer will create the recipient account. + #[benchmark] + fn force_transfer() { + let existential_deposit: T::Balance = minimum_balance::(); + let source: T::AccountId = account("source", 0, SEED); + let source_lookup = T::Lookup::unlookup(source.clone()); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&source, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, + // and reap this user. + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + let transfer_amount = + existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + + #[extrinsic_call] + _(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount); + + if cfg!(feature = "insecure_zero_ed") { + assert_eq!(Balances::::free_balance(&source), balance - transfer_amount); + } else { + assert_eq!(Balances::::free_balance(&source), Zero::zero()); + } + + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // This benchmark performs the same operation as `transfer` in the worst case scenario, + // but additionally introduces many new users into the storage, increasing the the merkle + // trie and PoV size. + #[benchmark(extra)] + fn transfer_increasing_users(u: Linear<0, 1_000>) { + // 1_000 is not very much, but this upper bound can be controlled by the CLI. + let existential_deposit: T::Balance = minimum_balance::(); + let caller = whitelisted_caller(); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, + // and reap this user. + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + let transfer_amount = + existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); + + // Create a bunch of users in storage. + for i in 0..u { + // The `account` function uses `blake2_256` to generate unique accounts, so these + // should be quite random and evenly distributed in the trie. + let new_user: T::AccountId = account("new_user", i, SEED); + let _ = as Currency<_>>::make_free_balance_be(&new_user, balance); + } + + #[extrinsic_call] + transfer_allow_death(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); + + if cfg!(feature = "insecure_zero_ed") { + assert_eq!(Balances::::free_balance(&caller), balance - transfer_amount); + } else { + assert_eq!(Balances::::free_balance(&caller), Zero::zero()); + } + + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } + + // Benchmark `transfer_all` with the worst possible condition: + // * The recipient account is created + // * The sender is killed + #[benchmark] + fn transfer_all() { + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup = T::Lookup::unlookup(recipient.clone()); + + // Give some multiple of the existential deposit + let existential_deposit: T::Balance = minimum_balance::(); + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), recipient_lookup, false); + + assert!(Balances::::free_balance(&caller).is_zero()); + assert_eq!(Balances::::free_balance(&recipient), balance); + } + + #[benchmark] + fn force_unreserve() -> Result<(), BenchmarkError> { + let user: T::AccountId = account("user", 0, SEED); + let user_lookup = T::Lookup::unlookup(user.clone()); + + // Give some multiple of the existential deposit + let ed = minimum_balance::(); + let balance = ed + ed; + let _ = as Currency<_>>::make_free_balance_be(&user, balance); + + // Reserve the balance + as ReservableCurrency<_>>::reserve(&user, ed)?; + assert_eq!(Balances::::reserved_balance(&user), ed); + assert_eq!(Balances::::free_balance(&user), ed); + + #[extrinsic_call] + _(RawOrigin::Root, user_lookup, balance); + + assert!(Balances::::reserved_balance(&user).is_zero()); + assert_eq!(Balances::::free_balance(&user), ed + ed); + + Ok(()) + } + + #[benchmark] + fn upgrade_accounts(u: Linear<1, 1_000>) { + let caller: T::AccountId = whitelisted_caller(); + let who = (0..u) + .into_iter() + .map(|i| -> T::AccountId { + let user = account("old_user", i, SEED); + let account = AccountData { + free: minimum_balance::(), + reserved: minimum_balance::(), + frozen: Zero::zero(), + flags: ExtraFlags::old_logic(), + }; + frame_system::Pallet::::inc_providers(&user); + assert!(T::AccountStore::try_mutate_exists(&user, |a| -> DispatchResult { + *a = Some(account); + Ok(()) + }) + .is_ok()); + assert!(!Balances::::account(&user).flags.is_new_logic()); + assert_eq!(frame_system::Pallet::::providers(&user), 1); + assert_eq!(frame_system::Pallet::::consumers(&user), 0); + user + }) + .collect(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), who); + + for i in 0..u { + let user: T::AccountId = account("old_user", i, SEED); + assert!(Balances::::account(&user).flags.is_new_logic()); + assert_eq!(frame_system::Pallet::::providers(&user), 1); + assert_eq!(frame_system::Pallet::::consumers(&user), 1); + } + } + + #[benchmark] + fn force_adjust_total_issuance() { + let ti = TotalIssuance::::get(); + let delta = 123u32.into(); + + #[extrinsic_call] + _(RawOrigin::Root, AdjustmentDirection::Increase, delta); + + assert_eq!(TotalIssuance::::get(), ti + delta); + } + + /// Benchmark `burn` extrinsic with the worst possible condition - burn kills the account. + #[benchmark] + fn burn_allow_death() { + let existential_deposit: T::Balance = minimum_balance::(); + let caller = whitelisted_caller(); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + + // Burn enough to kill the account. + let burn_amount = balance - existential_deposit + 1u32.into(); + + #[extrinsic_call] + burn(RawOrigin::Signed(caller.clone()), burn_amount, false); + + if cfg!(feature = "insecure_zero_ed") { + assert_eq!(Balances::::free_balance(&caller), balance - burn_amount); + } else { + assert_eq!(Balances::::free_balance(&caller), Zero::zero()); + } + } + + // Benchmark `burn` extrinsic with the case where account is kept alive. + #[benchmark] + fn burn_keep_alive() { + let existential_deposit: T::Balance = minimum_balance::(); + let caller = whitelisted_caller(); + + // Give some multiple of the existential deposit + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + + // Burn minimum possible amount which should not kill the account. + let burn_amount = 1u32.into(); + + #[extrinsic_call] + burn(RawOrigin::Signed(caller.clone()), burn_amount, true); + + assert_eq!(Balances::::free_balance(&caller), balance - burn_amount); + } + + impl_benchmark_test_suite! { + Balances, + crate::tests::ExtBuilder::default().build(), + crate::tests::Test, + } +} diff --git a/pallets/balances/src/impl_currency.rs b/pallets/balances/src/impl_currency.rs new file mode 100644 index 000000000..f453b2342 --- /dev/null +++ b/pallets/balances/src/impl_currency.rs @@ -0,0 +1,954 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Implementations for the `Currency` family of traits. +//! +//! Note that `WithdrawReasons` are intentionally not used for anything in this implementation and +//! are expected to be removed in the near future, once migration to `fungible::*` traits is done. + +use super::*; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{ + tokens::{fungible, BalanceStatus as Status, Fortitude::Polite, Precision::BestEffort}, + Currency, DefensiveSaturating, ExistenceRequirement, + ExistenceRequirement::AllowDeath, + Get, Imbalance, InspectLockableCurrency, LockIdentifier, LockableCurrency, + NamedReservableCurrency, ReservableCurrency, SignedImbalance, TryDrop, WithdrawReasons, + }, +}; +use frame_system::pallet_prelude::BlockNumberFor; +pub use imbalances::{NegativeImbalance, PositiveImbalance}; +use sp_runtime::traits::Bounded; + +// wrapping these imbalances in a private module is necessary to ensure absolute privacy +// of the inner member. +mod imbalances { + use super::*; + use core::mem; + use frame_support::traits::{tokens::imbalance::TryMerge, SameOrOther}; + + /// Opaque, move-only struct with private fields that serves as a token denoting that + /// funds have been created without any equal and opposite accounting. + #[must_use] + #[derive(RuntimeDebug, PartialEq, Eq)] + pub struct PositiveImbalance, I: 'static = ()>(T::Balance); + + impl, I: 'static> PositiveImbalance { + /// Create a new positive imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + PositiveImbalance(amount) + } + } + + /// Opaque, move-only struct with private fields that serves as a token denoting that + /// funds have been destroyed without any equal and opposite accounting. + #[must_use] + #[derive(RuntimeDebug, PartialEq, Eq)] + pub struct NegativeImbalance, I: 'static = ()>(T::Balance); + + impl, I: 'static> NegativeImbalance { + /// Create a new negative imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + NegativeImbalance(amount) + } + } + + impl, I: 'static> TryDrop for PositiveImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } + } + + impl, I: 'static> Default for PositiveImbalance { + fn default() -> Self { + Self::zero() + } + } + + impl, I: 'static> Imbalance for PositiveImbalance { + type Opposite = NegativeImbalance; + + fn zero() -> Self { + Self(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0 - first; + + mem::forget(self); + (Self(first), Self(second)) + } + fn extract(&mut self, amount: T::Balance) -> Self { + let new = self.0.min(amount); + self.0 = self.0 - new; + Self(new) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self(a - b)) + } else if b > a { + SameOrOther::Other(NegativeImbalance::new(b - a)) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + } + + impl, I: 'static> TryMerge for PositiveImbalance { + fn try_merge(self, other: Self) -> Result { + Ok(self.merge(other)) + } + } + + impl, I: 'static> TryDrop for NegativeImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } + } + + impl, I: 'static> Default for NegativeImbalance { + fn default() -> Self { + Self::zero() + } + } + + impl, I: 'static> Imbalance for NegativeImbalance { + type Opposite = PositiveImbalance; + + fn zero() -> Self { + Self(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0 - first; + + mem::forget(self); + (Self(first), Self(second)) + } + fn extract(&mut self, amount: T::Balance) -> Self { + let new = self.0.min(amount); + self.0 = self.0 - new; + Self(new) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self(a - b)) + } else if b > a { + SameOrOther::Other(PositiveImbalance::new(b - a)) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + } + + impl, I: 'static> TryMerge for NegativeImbalance { + fn try_merge(self, other: Self) -> Result { + Ok(self.merge(other)) + } + } + + impl, I: 'static> Drop for PositiveImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + if !self.0.is_zero() { + >::mutate(|v| *v = v.saturating_add(self.0)); + Pallet::::deposit_event(Event::::Issued { amount: self.0 }); + } + } + } + + impl, I: 'static> Drop for NegativeImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + if !self.0.is_zero() { + >::mutate(|v| *v = v.saturating_sub(self.0)); + Pallet::::deposit_event(Event::::Rescinded { amount: self.0 }); + } + } + } +} + +impl, I: 'static> Currency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + type Balance = T::Balance; + type PositiveImbalance = PositiveImbalance; + type NegativeImbalance = NegativeImbalance; + + fn total_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).total() + } + + // Check if `value` amount of free balance can be slashed from `who`. + fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true + } + Self::free_balance(who) >= value + } + + fn total_issuance() -> Self::Balance { + TotalIssuance::::get() + } + + fn active_issuance() -> Self::Balance { + >::active_issuance() + } + + fn deactivate(amount: Self::Balance) { + >::deactivate(amount); + } + + fn reactivate(amount: Self::Balance) { + >::reactivate(amount); + } + + fn minimum_balance() -> Self::Balance { + T::ExistentialDeposit::get() + } + + // Burn funds from the total issuance, returning a positive imbalance for the amount burned. + // Is a no-op if amount to be burned is zero. + fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { + if amount.is_zero() { + return PositiveImbalance::zero() + } + >::mutate(|issued| { + *issued = issued.checked_sub(&amount).unwrap_or_else(|| { + amount = *issued; + Zero::zero() + }); + }); + + Pallet::::deposit_event(Event::::Rescinded { amount }); + PositiveImbalance::new(amount) + } + + // Create new funds into the total issuance, returning a negative imbalance + // for the amount issued. + // Is a no-op if amount to be issued it zero. + fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { + if amount.is_zero() { + return NegativeImbalance::zero() + } + >::mutate(|issued| { + *issued = issued.checked_add(&amount).unwrap_or_else(|| { + amount = Self::Balance::max_value() - *issued; + Self::Balance::max_value() + }) + }); + + Pallet::::deposit_event(Event::::Issued { amount }); + NegativeImbalance::new(amount) + } + + fn free_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).free + } + + // Ensure that an account can withdraw from their free balance given any existing withdrawal + // restrictions like locks and vesting balance. + // Is a no-op if amount to be withdrawn is zero. + fn ensure_can_withdraw( + who: &T::AccountId, + amount: T::Balance, + _reasons: WithdrawReasons, + new_balance: T::Balance, + ) -> DispatchResult { + if amount.is_zero() { + return Ok(()) + } + ensure!(new_balance >= Self::account(who).frozen, Error::::LiquidityRestrictions); + Ok(()) + } + + // Transfer some free balance from `transactor` to `dest`, respecting existence requirements. + // Is a no-op if value to be transferred is zero or the `transactor` is the same as `dest`. + fn transfer( + transactor: &T::AccountId, + dest: &T::AccountId, + value: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + if value.is_zero() || transactor == dest { + return Ok(()) + } + let keep_alive = match existence_requirement { + ExistenceRequirement::KeepAlive => Preserve, + ExistenceRequirement::AllowDeath => Expendable, + }; + >::transfer(transactor, dest, value, keep_alive)?; + Ok(()) + } + + /// Slash a target account `who`, returning the negative imbalance created and any left over + /// amount that could not be slashed. + /// + /// Is a no-op if `value` to be slashed is zero or the account does not exist. + /// + /// NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn + /// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid + /// having to draw from reserved funds, however we err on the side of punishment if things are + /// inconsistent or `can_slash` wasn't used appropriately. + fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()) + } + if Self::total_balance(who).is_zero() { + return (NegativeImbalance::zero(), value) + } + + let result = match Self::try_mutate_account_handling_dust( + who, + |account, _is_new| -> Result<(Self::NegativeImbalance, Self::Balance), DispatchError> { + // Best value is the most amount we can slash following liveness rules. + let ed = T::ExistentialDeposit::get(); + let actual = match system::Pallet::::can_dec_provider(who) { + true => value.min(account.free), + false => value.min(account.free.saturating_sub(ed)), + }; + account.free.saturating_reduce(actual); + let remaining = value.saturating_sub(actual); + Ok((NegativeImbalance::new(actual), remaining)) + }, + ) { + Ok((imbalance, remaining)) => { + Self::deposit_event(Event::Slashed { + who: who.clone(), + amount: value.saturating_sub(remaining), + }); + (imbalance, remaining) + }, + Err(_) => (Self::NegativeImbalance::zero(), value), + }; + result + } + + /// Deposit some `value` into the free balance of an existing target account `who`. + /// + /// Is a no-op if the `value` to be deposited is zero. + fn deposit_into_existing( + who: &T::AccountId, + value: Self::Balance, + ) -> Result { + if value.is_zero() { + return Ok(PositiveImbalance::zero()) + } + + Self::try_mutate_account_handling_dust( + who, + |account, is_new| -> Result { + ensure!(!is_new, Error::::DeadAccount); + account.free = account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?; + Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); + Ok(PositiveImbalance::new(value)) + }, + ) + } + + /// Deposit some `value` into the free balance of `who`, possibly creating a new account. + /// + /// This function is a no-op if: + /// - the `value` to be deposited is zero; or + /// - the `value` to be deposited is less than the required ED and the account does not yet + /// exist; or + /// - the deposit would necessitate the account to exist and there are no provider references; + /// or + /// - `value` is so large it would cause the balance of `who` to overflow. + fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { + if value.is_zero() { + return Self::PositiveImbalance::zero() + } + + Self::try_mutate_account_handling_dust( + who, + |account, is_new| -> Result { + let ed = T::ExistentialDeposit::get(); + ensure!(value >= ed || !is_new, Error::::ExistentialDeposit); + + // defensive only: overflow should never happen, however in case it does, then this + // operation is a no-op. + account.free = match account.free.checked_add(&value) { + Some(x) => x, + None => return Ok(Self::PositiveImbalance::zero()), + }; + + Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); + Ok(PositiveImbalance::new(value)) + }, + ) + .unwrap_or_else(|_| Self::PositiveImbalance::zero()) + } + + /// Withdraw some free balance from an account, respecting existence requirements. + /// + /// Is a no-op if value to be withdrawn is zero. + fn withdraw( + who: &T::AccountId, + value: Self::Balance, + reasons: WithdrawReasons, + liveness: ExistenceRequirement, + ) -> result::Result { + if value.is_zero() { + return Ok(NegativeImbalance::zero()) + } + + Self::try_mutate_account_handling_dust( + who, + |account, _| -> Result { + let new_free_account = + account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; + + // bail if we need to keep the account alive and this would kill it. + let ed = T::ExistentialDeposit::get(); + let would_be_dead = new_free_account < ed; + let would_kill = would_be_dead && account.free >= ed; + ensure!(liveness == AllowDeath || !would_kill, Error::::Expendability); + + Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; + + account.free = new_free_account; + + Self::deposit_event(Event::Withdraw { who: who.clone(), amount: value }); + Ok(NegativeImbalance::new(value)) + }, + ) + } + + /// Force the new free balance of a target account `who` to some new value `balance`. + fn make_free_balance_be( + who: &T::AccountId, + value: Self::Balance, + ) -> SignedImbalance { + Self::try_mutate_account_handling_dust( + who, + |account, + is_new| + -> Result, DispatchError> { + let ed = T::ExistentialDeposit::get(); + // If we're attempting to set an existing account to less than ED, then + // bypass the entire operation. It's a no-op if you follow it through, but + // since this is an instance where we might account for a negative imbalance + // (in the dust cleaner of set_account) before we account for its actual + // equal and opposite cause (returned as an Imbalance), then in the + // instance that there's no other accounts on the system at all, we might + // underflow the issuance and our arithmetic will be off. + ensure!(value >= ed || !is_new, Error::::ExistentialDeposit); + + let imbalance = if account.free <= value { + SignedImbalance::Positive(PositiveImbalance::new(value - account.free)) + } else { + SignedImbalance::Negative(NegativeImbalance::new(account.free - value)) + }; + account.free = value; + Self::deposit_event(Event::BalanceSet { who: who.clone(), free: account.free }); + Ok(imbalance) + }, + ) + .unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero())) + } +} + +impl, I: 'static> ReservableCurrency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + /// Check if `who` can reserve `value` from their free balance. + /// + /// Always `true` if value to be reserved is zero. + fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true + } + Self::account(who).free.checked_sub(&value).map_or(false, |new_balance| { + new_balance >= T::ExistentialDeposit::get() && + Self::ensure_can_withdraw(who, value, WithdrawReasons::RESERVE, new_balance) + .is_ok() + }) + } + + fn reserved_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).reserved + } + + /// Move `value` from the free balance from `who` to their reserved balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { + if value.is_zero() { + return Ok(()) + } + + Self::try_mutate_account_handling_dust(who, |account, _| -> DispatchResult { + account.free = + account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; + account.reserved = + account.reserved.checked_add(&value).ok_or(ArithmeticError::Overflow)?; + Self::ensure_can_withdraw(&who, value, WithdrawReasons::RESERVE, account.free) + })?; + + Self::deposit_event(Event::Reserved { who: who.clone(), amount: value }); + Ok(()) + } + + /// Unreserve some funds, returning any amount that was unable to be unreserved. + /// + /// Is a no-op if the value to be unreserved is zero or the account does not exist. + /// + /// NOTE: returns amount value which wasn't successfully unreserved. + fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { + if value.is_zero() { + return Zero::zero() + } + if Self::total_balance(who).is_zero() { + return value + } + + let actual = match Self::mutate_account_handling_dust(who, |account| { + let actual = cmp::min(account.reserved, value); + account.reserved -= actual; + // defensive only: this can never fail since total issuance which is at least + // free+reserved fits into the same data type. + account.free = account.free.defensive_saturating_add(actual); + actual + }) { + Ok(x) => x, + Err(_) => { + // This should never happen since we don't alter the total amount in the account. + // If it ever does, then we should fail gracefully though, indicating that nothing + // could be done. + return value + }, + }; + + Self::deposit_event(Event::Unreserved { who: who.clone(), amount: actual }); + value - actual + } + + /// Slash from reserved balance, returning the negative imbalance created, + /// and any amount that was unable to be slashed. + /// + /// Is a no-op if the value to be slashed is zero or the account does not exist. + fn slash_reserved( + who: &T::AccountId, + value: Self::Balance, + ) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()) + } + if Self::total_balance(who).is_zero() { + return (NegativeImbalance::zero(), value) + } + + // NOTE: `mutate_account` may fail if it attempts to reduce the balance to the point that an + // account is attempted to be illegally destroyed. + + match Self::mutate_account_handling_dust(who, |account| { + let actual = value.min(account.reserved); + account.reserved.saturating_reduce(actual); + + // underflow should never happen, but it if does, there's nothing to be done here. + (NegativeImbalance::new(actual), value.saturating_sub(actual)) + }) { + Ok((imbalance, not_slashed)) => { + Self::deposit_event(Event::Slashed { + who: who.clone(), + amount: value.saturating_sub(not_slashed), + }); + (imbalance, not_slashed) + }, + Err(_) => (Self::NegativeImbalance::zero(), value), + } + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + /// + /// This is `Polite` and thus will not repatriate any funds which would lead the total balance + /// to be less than the frozen amount. Returns `Ok` with the actual amount of funds moved, + /// which may be less than `value` since the operation is done on a `BestEffort` basis. + fn repatriate_reserved( + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> Result { + let actual = + Self::do_transfer_reserved(slashed, beneficiary, value, BestEffort, Polite, status)?; + Ok(value.saturating_sub(actual)) + } +} + +impl, I: 'static> NamedReservableCurrency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + type ReserveIdentifier = T::ReserveIdentifier; + + fn reserved_balance_named(id: &Self::ReserveIdentifier, who: &T::AccountId) -> Self::Balance { + let reserves = Self::reserves(who); + reserves + .binary_search_by_key(id, |data| data.id) + .map(|index| reserves[index].amount) + .unwrap_or_default() + } + + /// Move `value` from the free balance from `who` to a named reserve balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> DispatchResult { + if value.is_zero() { + return Ok(()) + } + + Reserves::::try_mutate(who, |reserves| -> DispatchResult { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + reserves[index].amount = reserves[index] + .amount + .checked_add(&value) + .ok_or(ArithmeticError::Overflow)?; + }, + Err(index) => { + reserves + .try_insert(index, ReserveData { id: *id, amount: value }) + .map_err(|_| Error::::TooManyReserves)?; + }, + }; + >::reserve(who, value)?; + Ok(()) + }) + } + + /// Unreserve some funds, returning any amount that was unable to be unreserved. + /// + /// Is a no-op if the value to be unreserved is zero. + fn unreserve_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> Self::Balance { + if value.is_zero() { + return Zero::zero() + } + + Reserves::::mutate_exists(who, |maybe_reserves| -> Self::Balance { + if let Some(reserves) = maybe_reserves.as_mut() { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let remain = >::unreserve(who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + if reserves[index].amount.is_zero() { + if reserves.len() == 1 { + // no more named reserves + *maybe_reserves = None; + } else { + // remove this named reserve + reserves.remove(index); + } + } + + value - actual + }, + Err(_) => value, + } + } else { + value + } + }) + } + + /// Slash from reserved balance, returning the negative imbalance created, + /// and any amount that was unable to be slashed. + /// + /// Is a no-op if the value to be slashed is zero. + fn slash_reserved_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (NegativeImbalance::zero(), Zero::zero()) + } + + Reserves::::mutate(who, |reserves| -> (Self::NegativeImbalance, Self::Balance) { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let (imb, remain) = + >::slash_reserved(who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + Self::deposit_event(Event::Slashed { who: who.clone(), amount: actual }); + (imb, value - actual) + }, + Err(_) => (NegativeImbalance::zero(), value), + } + }) + } + + /// Move the reserved balance of one account into the balance of another, according to `status`. + /// If `status` is `Reserved`, the balance will be reserved with given `id`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. + fn repatriate_reserved_named( + id: &Self::ReserveIdentifier, + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> Result { + if value.is_zero() { + return Ok(Zero::zero()) + } + + if slashed == beneficiary { + return match status { + Status::Free => Ok(Self::unreserve_named(id, slashed, value)), + Status::Reserved => + Ok(value.saturating_sub(Self::reserved_balance_named(id, slashed))), + } + } + + Reserves::::try_mutate(slashed, |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let actual = if status == Status::Reserved { + // make it the reserved under same identifier + Reserves::::try_mutate( + beneficiary, + |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let remain = + >::repatriate_reserved( + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive + // here. + let actual = to_change.defensive_saturating_sub(remain); + + // this add can't overflow but just to be defensive. + reserves[index].amount = + reserves[index].amount.defensive_saturating_add(actual); + + Ok(actual) + }, + Err(index) => { + let remain = + >::repatriate_reserved( + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive + // here + let actual = to_change.defensive_saturating_sub(remain); + + reserves + .try_insert( + index, + ReserveData { id: *id, amount: actual }, + ) + .map_err(|_| Error::::TooManyReserves)?; + + Ok(actual) + }, + } + }, + )? + } else { + let remain = >::repatriate_reserved( + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive here + to_change.defensive_saturating_sub(remain) + }; + + // `actual <= to_change` and `to_change <= amount`; qed; + reserves[index].amount -= actual; + + Ok(value - actual) + }, + Err(_) => Ok(value), + } + }) + } +} + +impl, I: 'static> LockableCurrency for Pallet +where + T::Balance: MaybeSerializeDeserialize + Debug, +{ + type Moment = BlockNumberFor; + + type MaxLocks = T::MaxLocks; + + // Set or alter a lock on the balance of `who`. + fn set_lock( + id: LockIdentifier, + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + ) { + if reasons.is_empty() || amount.is_zero() { + Self::remove_lock(id, who); + return + } + + let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); + let mut locks = Self::locks(who) + .into_iter() + .filter_map(|l| if l.id == id { new_lock.take() } else { Some(l) }) + .collect::>(); + if let Some(lock) = new_lock { + locks.push(lock) + } + Self::update_locks(who, &locks[..]); + } + + // Extend a lock on the balance of `who`. + // Is a no-op if lock amount is zero or `reasons` `is_none()`. + fn extend_lock( + id: LockIdentifier, + who: &T::AccountId, + amount: T::Balance, + reasons: WithdrawReasons, + ) { + if amount.is_zero() || reasons.is_empty() { + return + } + let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); + let mut locks = Self::locks(who) + .into_iter() + .filter_map(|l| { + if l.id == id { + new_lock.take().map(|nl| BalanceLock { + id: l.id, + amount: l.amount.max(nl.amount), + reasons: l.reasons | nl.reasons, + }) + } else { + Some(l) + } + }) + .collect::>(); + if let Some(lock) = new_lock { + locks.push(lock) + } + Self::update_locks(who, &locks[..]); + } + + fn remove_lock(id: LockIdentifier, who: &T::AccountId) { + let mut locks = Self::locks(who); + locks.retain(|l| l.id != id); + Self::update_locks(who, &locks[..]); + } +} + +impl, I: 'static> InspectLockableCurrency for Pallet { + fn balance_locked(id: LockIdentifier, who: &T::AccountId) -> Self::Balance { + Self::locks(who) + .into_iter() + .filter(|l| l.id == id) + .fold(Zero::zero(), |acc, l| acc + l.amount) + } +} diff --git a/pallets/balances/src/impl_fungible.rs b/pallets/balances/src/impl_fungible.rs new file mode 100644 index 000000000..4470c3cc9 --- /dev/null +++ b/pallets/balances/src/impl_fungible.rs @@ -0,0 +1,387 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Implementation of `fungible` traits for Balances pallet. +use super::*; +use frame_support::traits::{ + tokens::{ + Fortitude, + Preservation::{self, Preserve, Protect}, + Provenance::{self, Minted}, + }, + AccountTouch, +}; + +impl, I: 'static> fungible::Inspect for Pallet { + type Balance = T::Balance; + + fn total_issuance() -> Self::Balance { + TotalIssuance::::get() + } + fn active_issuance() -> Self::Balance { + TotalIssuance::::get().saturating_sub(InactiveIssuance::::get()) + } + fn minimum_balance() -> Self::Balance { + T::ExistentialDeposit::get() + } + fn total_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).total() + } + fn balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).free + } + fn reducible_balance( + who: &T::AccountId, + preservation: Preservation, + force: Fortitude, + ) -> Self::Balance { + let a = Self::account(who); + let mut untouchable = Zero::zero(); + if force == Polite { + // Frozen balance applies to total. Anything on hold therefore gets discounted from the + // limit given by the freezes. + untouchable = a.frozen.saturating_sub(a.reserved); + } + // If we want to keep our provider ref.. + if preservation == Preserve + // ..or we don't want the account to die and our provider ref is needed for it to live.. + || preservation == Protect && !a.free.is_zero() && + frame_system::Pallet::::providers(who) == 1 + // ..or we don't care about the account dying but our provider ref is required.. + || preservation == Expendable && !a.free.is_zero() && + !frame_system::Pallet::::can_dec_provider(who) + { + // ..then the ED needed.. + untouchable = untouchable.max(T::ExistentialDeposit::get()); + } + // Liquid balance is what is neither on hold nor frozen/required for provider. + a.free.saturating_sub(untouchable) + } + fn can_deposit( + who: &T::AccountId, + amount: Self::Balance, + provenance: Provenance, + ) -> DepositConsequence { + if amount.is_zero() { + return DepositConsequence::Success + } + + if provenance == Minted && TotalIssuance::::get().checked_add(&amount).is_none() { + return DepositConsequence::Overflow + } + + let account = Self::account(who); + let new_free = match account.free.checked_add(&amount) { + None => return DepositConsequence::Overflow, + Some(x) if x < T::ExistentialDeposit::get() => return DepositConsequence::BelowMinimum, + Some(x) => x, + }; + + match account.reserved.checked_add(&new_free) { + Some(_) => {}, + None => return DepositConsequence::Overflow, + }; + + // NOTE: We assume that we are a provider, so don't need to do any checks in the + // case of account creation. + + DepositConsequence::Success + } + fn can_withdraw( + who: &T::AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + if amount.is_zero() { + return WithdrawConsequence::Success + } + + if TotalIssuance::::get().checked_sub(&amount).is_none() { + return WithdrawConsequence::Underflow + } + + let account = Self::account(who); + let new_free_balance = match account.free.checked_sub(&amount) { + Some(x) => x, + None => return WithdrawConsequence::BalanceLow, + }; + + let liquid = Self::reducible_balance(who, Expendable, Polite); + if amount > liquid { + return WithdrawConsequence::Frozen + } + + // Provider restriction - total account balance cannot be reduced to zero if it cannot + // sustain the loss of a provider reference. + // NOTE: This assumes that the pallet is a provider (which is true). Is this ever changes, + // then this will need to adapt accordingly. + let ed = T::ExistentialDeposit::get(); + let success = if new_free_balance < ed { + if frame_system::Pallet::::can_dec_provider(who) { + WithdrawConsequence::ReducedToZero(new_free_balance) + } else { + return WithdrawConsequence::WouldDie + } + } else { + WithdrawConsequence::Success + }; + + let new_total_balance = new_free_balance.saturating_add(account.reserved); + + // Eventual free funds must be no less than the frozen balance. + if new_total_balance < account.frozen { + return WithdrawConsequence::Frozen + } + + success + } +} + +impl, I: 'static> fungible::Unbalanced for Pallet { + fn handle_dust(dust: fungible::Dust) { + T::DustRemoval::on_unbalanced(dust.into_credit()); + } + fn write_balance( + who: &T::AccountId, + amount: Self::Balance, + ) -> Result, DispatchError> { + let max_reduction = + >::reducible_balance(who, Expendable, Force); + let (result, maybe_dust) = Self::mutate_account(who, |account| -> DispatchResult { + // Make sure the reduction (if there is one) is no more than the maximum allowed. + let reduction = account.free.saturating_sub(amount); + ensure!(reduction <= max_reduction, Error::::InsufficientBalance); + + account.free = amount; + Ok(()) + })?; + result?; + Ok(maybe_dust) + } + + fn set_total_issuance(amount: Self::Balance) { + TotalIssuance::::mutate(|t| *t = amount); + } + + fn deactivate(amount: Self::Balance) { + InactiveIssuance::::mutate(|b| { + // InactiveIssuance cannot be greater than TotalIssuance. + *b = b.saturating_add(amount).min(TotalIssuance::::get()); + }); + } + + fn reactivate(amount: Self::Balance) { + InactiveIssuance::::mutate(|b| b.saturating_reduce(amount)); + } +} + +impl, I: 'static> fungible::Mutate for Pallet { + fn done_mint_into(who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::::Minted { who: who.clone(), amount }); + } + fn done_burn_from(who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::::Burned { who: who.clone(), amount }); + } + fn done_shelve(who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::::Suspended { who: who.clone(), amount }); + } + fn done_restore(who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::::Restored { who: who.clone(), amount }); + } + fn done_transfer(source: &T::AccountId, dest: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::::Transfer { + from: source.clone(), + to: dest.clone(), + amount, + }); + } +} + +impl, I: 'static> fungible::MutateHold for Pallet {} + +impl, I: 'static> fungible::InspectHold for Pallet { + type Reason = T::RuntimeHoldReason; + + fn total_balance_on_hold(who: &T::AccountId) -> T::Balance { + Self::account(who).reserved + } + fn reducible_total_balance_on_hold(who: &T::AccountId, force: Fortitude) -> Self::Balance { + // The total balance must never drop below the freeze requirements if we're not forcing: + let a = Self::account(who); + let unavailable = if force == Force { + Self::Balance::zero() + } else { + // The freeze lock applies to the total balance, so we can discount the free balance + // from the amount which the total reserved balance must provide to satisfy it. + a.frozen.saturating_sub(a.free) + }; + a.reserved.saturating_sub(unavailable) + } + fn balance_on_hold(reason: &Self::Reason, who: &T::AccountId) -> T::Balance { + Holds::::get(who) + .iter() + .find(|x| &x.id == reason) + .map_or_else(Zero::zero, |x| x.amount) + } + fn hold_available(reason: &Self::Reason, who: &T::AccountId) -> bool { + if frame_system::Pallet::::providers(who) == 0 { + return false + } + let holds = Holds::::get(who); + if holds.is_full() && !holds.iter().any(|x| &x.id == reason) { + return false + } + true + } +} + +impl, I: 'static> fungible::UnbalancedHold for Pallet { + fn set_balance_on_hold( + reason: &Self::Reason, + who: &T::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + let mut new_account = Self::account(who); + let mut holds = Holds::::get(who); + let mut increase = true; + let mut delta = amount; + + if let Some(item) = holds.iter_mut().find(|x| &x.id == reason) { + delta = item.amount.max(amount) - item.amount.min(amount); + increase = amount > item.amount; + item.amount = amount; + holds.retain(|x| !x.amount.is_zero()); + } else { + if !amount.is_zero() { + holds + .try_push(IdAmount { id: *reason, amount }) + .map_err(|_| Error::::TooManyHolds)?; + } + } + + new_account.reserved = if increase { + new_account.reserved.checked_add(&delta).ok_or(ArithmeticError::Overflow)? + } else { + new_account.reserved.checked_sub(&delta).ok_or(ArithmeticError::Underflow)? + }; + + let (result, maybe_dust) = Self::try_mutate_account(who, |a, _| -> DispatchResult { + *a = new_account; + Ok(()) + })?; + debug_assert!( + maybe_dust.is_none(), + "Does not alter main balance; dust only happens when it is altered; qed" + ); + Holds::::insert(who, holds); + Ok(result) + } +} + +impl, I: 'static> fungible::InspectFreeze for Pallet { + type Id = T::FreezeIdentifier; + + fn balance_frozen(id: &Self::Id, who: &T::AccountId) -> Self::Balance { + let locks = Freezes::::get(who); + locks.into_iter().find(|l| &l.id == id).map_or(Zero::zero(), |l| l.amount) + } + + fn can_freeze(id: &Self::Id, who: &T::AccountId) -> bool { + let l = Freezes::::get(who); + !l.is_full() || l.iter().any(|x| &x.id == id) + } +} + +impl, I: 'static> fungible::MutateFreeze for Pallet { + fn set_freeze(id: &Self::Id, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + if amount.is_zero() { + return Self::thaw(id, who) + } + let mut locks = Freezes::::get(who); + if let Some(i) = locks.iter_mut().find(|x| &x.id == id) { + i.amount = amount; + } else { + locks + .try_push(IdAmount { id: *id, amount }) + .map_err(|_| Error::::TooManyFreezes)?; + } + Self::update_freezes(who, locks.as_bounded_slice()) + } + + fn extend_freeze(id: &Self::Id, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + if amount.is_zero() { + return Ok(()) + } + let mut locks = Freezes::::get(who); + if let Some(i) = locks.iter_mut().find(|x| &x.id == id) { + i.amount = i.amount.max(amount); + } else { + locks + .try_push(IdAmount { id: *id, amount }) + .map_err(|_| Error::::TooManyFreezes)?; + } + Self::update_freezes(who, locks.as_bounded_slice()) + } + + fn thaw(id: &Self::Id, who: &T::AccountId) -> DispatchResult { + let mut locks = Freezes::::get(who); + locks.retain(|l| &l.id != id); + Self::update_freezes(who, locks.as_bounded_slice()) + } +} + +impl, I: 'static> fungible::Balanced for Pallet { + type OnDropCredit = fungible::DecreaseIssuance; + type OnDropDebt = fungible::IncreaseIssuance; + + fn done_deposit(who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::::Deposit { who: who.clone(), amount }); + } + fn done_withdraw(who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::::Withdraw { who: who.clone(), amount }); + } + fn done_issue(amount: Self::Balance) { + if !amount.is_zero() { + Self::deposit_event(Event::::Issued { amount }); + } + } + fn done_rescind(amount: Self::Balance) { + Self::deposit_event(Event::::Rescinded { amount }); + } +} + +impl, I: 'static> fungible::BalancedHold for Pallet {} + +impl, I: 'static> + fungible::hold::DoneSlash for Pallet +{ + fn done_slash(reason: &T::RuntimeHoldReason, who: &T::AccountId, amount: T::Balance) { + T::DoneSlashHandler::done_slash(reason, who, amount); + } +} + +impl, I: 'static> AccountTouch<(), T::AccountId> for Pallet { + type Balance = T::Balance; + fn deposit_required(_: ()) -> Self::Balance { + Self::Balance::zero() + } + fn should_touch(_: (), _: &T::AccountId) -> bool { + false + } + fn touch(_: (), _: &T::AccountId, _: &T::AccountId) -> DispatchResult { + Ok(()) + } +} diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs new file mode 100644 index 000000000..7c558bf6a --- /dev/null +++ b/pallets/balances/src/lib.rs @@ -0,0 +1,1315 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! # Balances Pallet +//! +//! The Balances pallet provides functionality for handling accounts and balances for a single +//! token. +//! +//! It makes heavy use of concepts such as Holds and Freezes from the +//! [`frame_support::traits::fungible`] traits, therefore you should read and understand those docs +//! as a prerequisite to understanding this pallet. +//! +//! Also see the [`frame_tokens`] reference docs for higher level information regarding the +//! place of this palet in FRAME. +//! +//! ## Overview +//! +//! The Balances pallet provides functions for: +//! +//! - Getting and setting free balances. +//! - Retrieving total, reserved and unreserved balances. +//! - Repatriating a reserved balance to a beneficiary account that exists. +//! - Transferring a balance between accounts (when not reserved). +//! - Slashing an account balance. +//! - Account creation and removal. +//! - Managing total issuance. +//! - Setting and managing locks. +//! +//! ### Terminology +//! +//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after +//! its total balance has become less than the Existential Deposit. +//! +//! ### Implementations +//! +//! The Balances pallet provides implementations for the following [`fungible`] traits. If these +//! traits provide the functionality that you need, then you should avoid tight coupling with the +//! Balances pallet. +//! +//! - [`fungible::Inspect`] +//! - [`fungible::Mutate`] +//! - [`fungible::Unbalanced`] +//! - [`fungible::Balanced`] +//! - [`fungible::BalancedHold`] +//! - [`fungible::InspectHold`] +//! - [`fungible::MutateHold`] +//! - [`fungible::InspectFreeze`] +//! - [`fungible::MutateFreeze`] +//! - [`fungible::Imbalance`] +//! +//! It also implements the following [`Currency`] related traits, however they are deprecated and +//! will eventually be removed. +//! +//! - [`Currency`]: Functions for dealing with a fungible assets system. +//! - [`ReservableCurrency`] +//! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency): +//! Functions for dealing with assets that can be reserved from an account. +//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for +//! dealing with accounts that allow liquidity restrictions. +//! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling +//! imbalances between total issuance in the system and account balances. Must be used when a +//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). +//! +//! ## Usage +//! +//! The following examples show how to use the Balances pallet in your custom pallet. +//! +//! ### Examples from the FRAME +//! +//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from +//! `Currency`: +//! +//! ``` +//! use frame_support::traits::Currency; +//! # pub trait Config: frame_system::Config { +//! # type Currency: Currency; +//! # } +//! +//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +//! +//! # fn main() {} +//! ``` +//! +//! The Staking pallet uses the `LockableCurrency` trait to lock a stash account's funds: +//! +//! ``` +//! use frame_support::traits::{WithdrawReasons, LockableCurrency}; +//! use sp_runtime::traits::Bounded; +//! pub trait Config: frame_system::Config { +//! type Currency: LockableCurrency>; +//! } +//! # struct StakingLedger { +//! # stash: ::AccountId, +//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, +//! # phantom: std::marker::PhantomData, +//! # } +//! # const STAKING_ID: [u8; 8] = *b"staking "; +//! +//! fn update_ledger( +//! controller: &T::AccountId, +//! ledger: &StakingLedger +//! ) { +//! T::Currency::set_lock( +//! STAKING_ID, +//! &ledger.stash, +//! ledger.total, +//! WithdrawReasons::all() +//! ); +//! // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +//! } +//! # fn main() {} +//! ``` +//! +//! ## Genesis config +//! +//! The Balances pallet depends on the [`GenesisConfig`]. +//! +//! ## Assumptions +//! +//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. +//! * Existential Deposit is set to a value greater than zero. +//! +//! Note, you may find the Balances pallet still functions with an ED of zero when the +//! `insecure_zero_ed` cargo feature is enabled. However this is not a configuration which is +//! generally supported, nor will it be. +//! +//! [`frame_tokens`]: ../polkadot_sdk_docs/reference_docs/frame_tokens/index.html + +#![cfg_attr(not(feature = "std"), no_std)] +mod benchmarking; +mod impl_currency; +mod impl_fungible; +pub mod migration; +mod tests; +mod types; +pub mod weights; + +extern crate alloc; + +use alloc::{ + format, + string::{String, ToString}, + vec::Vec, +}; +use codec::{Codec, MaxEncodedLen}; +use core::{cmp, fmt::Debug, mem, result}; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{ + tokens::{ + fungible, BalanceStatus as Status, DepositConsequence, + Fortitude::{self, Force, Polite}, + IdAmount, + Preservation::{Expendable, Preserve, Protect}, + WithdrawConsequence, + }, + Currency, Defensive, Get, OnUnbalanced, ReservableCurrency, StoredMap, + }, + BoundedSlice, WeakBoundedVec, +}; +use frame_system as system; +pub use impl_currency::{NegativeImbalance, PositiveImbalance}; +use scale_info::TypeInfo; +use sp_core::{sr25519::Pair as SrPair, Pair}; +use sp_runtime::{ + traits::{ + AtLeast32BitUnsigned, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Saturating, + StaticLookup, Zero, + }, + ArithmeticError, DispatchError, FixedPointOperand, Perbill, RuntimeDebug, TokenError, +}; + +pub use types::{ + AccountData, AdjustmentDirection, BalanceLock, DustCleaner, ExtraFlags, Reasons, ReserveData, +}; +pub use weights::WeightInfo; + +pub use pallet::*; + +const LOG_TARGET: &str = "runtime::balances"; + +// Default derivation(hard) for development accounts. +const DEFAULT_ADDRESS_URI: &str = "//Sender//{}"; + +type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use codec::HasCompact; + use frame_support::{ + pallet_prelude::*, + traits::{fungible::Credit, tokens::Precision, VariantCount, VariantCountOf}, + }; + use frame_system::pallet_prelude::*; + + pub type CreditOf = Credit<::AccountId, Pallet>; + + /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. + pub mod config_preludes { + use super::*; + use frame_support::derive_impl; + + pub struct TestDefaultConfig; + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig, no_aggregated_types)] + impl frame_system::DefaultConfig for TestDefaultConfig {} + + #[frame_support::register_default_impl(TestDefaultConfig)] + impl DefaultConfig for TestDefaultConfig { + #[inject_runtime_type] + type RuntimeEvent = (); + #[inject_runtime_type] + type RuntimeHoldReason = (); + #[inject_runtime_type] + type RuntimeFreezeReason = (); + + type Balance = u64; + type ExistentialDeposit = ConstUint<1>; + + type ReserveIdentifier = (); + type FreezeIdentifier = Self::RuntimeFreezeReason; + + type DustRemoval = (); + + type MaxLocks = ConstU32<100>; + type MaxReserves = ConstU32<100>; + type MaxFreezes = VariantCountOf; + + type WeightInfo = (); + type DoneSlashHandler = (); + } + } + + #[pallet::config(with_default)] + pub trait Config: frame_system::Config { + /// The overarching event type. + #[pallet::no_default_bounds] + #[allow(deprecated)] + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + + /// The overarching hold reason. + #[pallet::no_default_bounds] + type RuntimeHoldReason: Parameter + Member + MaxEncodedLen + Copy + VariantCount; + + /// The overarching freeze reason. + #[pallet::no_default_bounds] + type RuntimeFreezeReason: VariantCount; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + + /// The balance of an account. + type Balance: Parameter + + Member + + AtLeast32BitUnsigned + + Codec + + HasCompact + + Default + + Copy + + MaybeSerializeDeserialize + + Debug + + MaxEncodedLen + + TypeInfo + + FixedPointOperand; + + /// Handler for the unbalanced reduction when removing a dust account. + #[pallet::no_default_bounds] + type DustRemoval: OnUnbalanced>; + + /// The minimum amount required to keep an account open. MUST BE GREATER THAN ZERO! + /// + /// If you *really* need it to be zero, you can enable the feature `insecure_zero_ed` for + /// this pallet. However, you do so at your own risk: this will open up a major DoS vector. + /// In case you have multiple sources of provider references, you may also get unexpected + /// behaviour if you set this to zero. + /// + /// Bottom line: Do yourself a favour and make it at least one! + #[pallet::constant] + #[pallet::no_default_bounds] + type ExistentialDeposit: Get; + + /// The means of storing the balances of an account. + #[pallet::no_default] + type AccountStore: StoredMap>; + + /// The ID type for reserves. + /// + /// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/` + type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; + + /// The ID type for freezes. + type FreezeIdentifier: Parameter + Member + MaxEncodedLen + Copy; + + /// The maximum number of locks that should exist on an account. + /// Not strictly enforced, but used for weight estimation. + /// + /// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/` + #[pallet::constant] + type MaxLocks: Get; + + /// The maximum number of named reserves that can exist on an account. + /// + /// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/` + #[pallet::constant] + type MaxReserves: Get; + + /// The maximum number of individual freeze locks that can exist on an account at any time. + #[pallet::constant] + type MaxFreezes: Get; + + /// Allows callbacks to other pallets so they can update their bookkeeping when a slash + /// occurs. + type DoneSlashHandler: fungible::hold::DoneSlash< + Self::RuntimeHoldReason, + Self::AccountId, + Self::Balance, + >; + } + + /// The in-code storage version. + const STORAGE_VERSION: frame_support::traits::StorageVersion = + frame_support::traits::StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// An account was created with some free balance. + Endowed { account: T::AccountId, free_balance: T::Balance }, + /// An account was removed whose balance was non-zero but below ExistentialDeposit, + /// resulting in an outright loss. + DustLost { account: T::AccountId, amount: T::Balance }, + /// Transfer succeeded. + Transfer { from: T::AccountId, to: T::AccountId, amount: T::Balance }, + /// A balance was set by root. + BalanceSet { who: T::AccountId, free: T::Balance }, + /// Some balance was reserved (moved from free to reserved). + Reserved { who: T::AccountId, amount: T::Balance }, + /// Some balance was unreserved (moved from reserved to free). + Unreserved { who: T::AccountId, amount: T::Balance }, + /// Some balance was moved from the reserve of the first account to the second account. + /// Final argument indicates the destination balance type. + ReserveRepatriated { + from: T::AccountId, + to: T::AccountId, + amount: T::Balance, + destination_status: Status, + }, + /// Some amount was deposited (e.g. for transaction fees). + Deposit { who: T::AccountId, amount: T::Balance }, + /// Some amount was withdrawn from the account (e.g. for transaction fees). + Withdraw { who: T::AccountId, amount: T::Balance }, + /// Some amount was removed from the account (e.g. for misbehavior). + Slashed { who: T::AccountId, amount: T::Balance }, + /// Some amount was minted into an account. + Minted { who: T::AccountId, amount: T::Balance }, + /// Some amount was burned from an account. + Burned { who: T::AccountId, amount: T::Balance }, + /// Some amount was suspended from an account (it can be restored later). + Suspended { who: T::AccountId, amount: T::Balance }, + /// Some amount was restored into an account. + Restored { who: T::AccountId, amount: T::Balance }, + /// An account was upgraded. + Upgraded { who: T::AccountId }, + /// Total issuance was increased by `amount`, creating a credit to be balanced. + Issued { amount: T::Balance }, + /// Total issuance was decreased by `amount`, creating a debt to be balanced. + Rescinded { amount: T::Balance }, + /// Some balance was locked. + Locked { who: T::AccountId, amount: T::Balance }, + /// Some balance was unlocked. + Unlocked { who: T::AccountId, amount: T::Balance }, + /// Some balance was frozen. + Frozen { who: T::AccountId, amount: T::Balance }, + /// Some balance was thawed. + Thawed { who: T::AccountId, amount: T::Balance }, + /// The `TotalIssuance` was forcefully changed. + TotalIssuanceForced { old: T::Balance, new: T::Balance }, + } + + #[pallet::error] + pub enum Error { + /// Vesting balance too high to send value. + VestingBalance, + /// Account liquidity restrictions prevent withdrawal. + LiquidityRestrictions, + /// Balance too low to send value. + InsufficientBalance, + /// Value too low to create account due to existential deposit. + ExistentialDeposit, + /// Transfer/payment would kill account. + Expendability, + /// A vesting schedule already exists for this account. + ExistingVestingSchedule, + /// Beneficiary account must pre-exist. + DeadAccount, + /// Number of named reserves exceed `MaxReserves`. + TooManyReserves, + /// Number of holds exceed `VariantCountOf`. + TooManyHolds, + /// Number of freezes exceed `MaxFreezes`. + TooManyFreezes, + /// The issuance cannot be modified since it is already deactivated. + IssuanceDeactivated, + /// The delta cannot be zero. + DeltaZero, + } + + /// The total units issued in the system. + #[pallet::storage] + #[pallet::whitelist_storage] + pub type TotalIssuance, I: 'static = ()> = StorageValue<_, T::Balance, ValueQuery>; + + /// The total units of outstanding deactivated balance in the system. + #[pallet::storage] + #[pallet::whitelist_storage] + pub type InactiveIssuance, I: 'static = ()> = + StorageValue<_, T::Balance, ValueQuery>; + + /// The Balances pallet example of storing the balance of an account. + /// + /// # Example + /// + /// ```nocompile + /// impl pallet_balances::Config for Runtime { + /// type AccountStore = StorageMapShim, frame_system::Provider, AccountId, Self::AccountData> + /// } + /// ``` + /// + /// You can also store the balance of an account in the `System` pallet. + /// + /// # Example + /// + /// ```nocompile + /// impl pallet_balances::Config for Runtime { + /// type AccountStore = System + /// } + /// ``` + /// + /// But this comes with tradeoffs, storing account balances in the system pallet stores + /// `frame_system` data alongside the account data contrary to storing account balances in the + /// `Balances` pallet, which uses a `StorageMap` to store balances data only. + /// NOTE: This is only used in the case that this pallet is used to store balances. + #[pallet::storage] + pub type Account, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, AccountData, ValueQuery>; + + /// Any liquidity locks on some account balances. + /// NOTE: Should only be accessed when setting, changing and freeing a lock. + /// + /// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/` + #[pallet::storage] + pub type Locks, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + WeakBoundedVec, T::MaxLocks>, + ValueQuery, + >; + + /// Named reserves on some account balances. + /// + /// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/` + #[pallet::storage] + pub type Reserves, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedVec, T::MaxReserves>, + ValueQuery, + >; + + /// Holds on account balances. + #[pallet::storage] + pub type Holds, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedVec< + IdAmount, + VariantCountOf, + >, + ValueQuery, + >; + + /// Freeze locks on account balances. + #[pallet::storage] + pub type Freezes, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedVec, T::MaxFreezes>, + ValueQuery, + >; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + pub balances: Vec<(T::AccountId, T::Balance)>, + /// Derived development accounts(Optional): + /// - `u32`: The number of development accounts to generate. + /// - `T::Balance`: The initial balance assigned to each development account. + /// - `String`: An optional derivation(hard) string template. + /// - Must include `{}` as a placeholder for account indices. + /// - Defaults to `"//Sender//{}`" if `None`. + pub dev_accounts: Option<(u32, T::Balance, Option)>, + } + + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { balances: Default::default(), dev_accounts: None } + } + } + + #[pallet::genesis_build] + impl, I: 'static> BuildGenesisConfig for GenesisConfig { + fn build(&self) { + let total = self.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n); + + >::put(total); + + for (_, balance) in &self.balances { + assert!( + *balance >= >::ExistentialDeposit::get(), + "the balance of any account should always be at least the existential deposit.", + ) + } + + // ensure no duplicates exist. + let endowed_accounts = self + .balances + .iter() + .map(|(x, _)| x) + .cloned() + .collect::>(); + + assert!( + endowed_accounts.len() == self.balances.len(), + "duplicate balances in genesis." + ); + + // Generate additional dev accounts. + if let Some((num_accounts, balance, ref derivation)) = self.dev_accounts { + // Using the provided derivation string or default to `"//Sender//{}`". + Pallet::::derive_dev_account( + num_accounts, + balance, + derivation.as_deref().unwrap_or(DEFAULT_ADDRESS_URI), + ); + } + for &(ref who, free) in self.balances.iter() { + frame_system::Pallet::::inc_providers(who); + assert!(T::AccountStore::insert(who, AccountData { free, ..Default::default() }) + .is_ok()); + } + } + } + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn integrity_test() { + #[cfg(not(feature = "insecure_zero_ed"))] + assert!( + !>::ExistentialDeposit::get().is_zero(), + "The existential deposit must be greater than zero!" + ); + + assert!( + T::MaxFreezes::get() >= ::VARIANT_COUNT, + "MaxFreezes should be greater than or equal to the number of freeze reasons: {} < {}", + T::MaxFreezes::get(), ::VARIANT_COUNT, + ); + } + + #[cfg(feature = "try-runtime")] + fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { + Holds::::iter_keys().try_for_each(|k| { + if Holds::::decode_len(k).unwrap_or(0) > + T::RuntimeHoldReason::VARIANT_COUNT as usize + { + Err("Found `Hold` with too many elements") + } else { + Ok(()) + } + })?; + + Freezes::::iter_keys().try_for_each(|k| { + if Freezes::::decode_len(k).unwrap_or(0) > T::MaxFreezes::get() as usize { + Err("Found `Freeze` with too many elements") + } else { + Ok(()) + } + })?; + + Ok(()) + } + } + + #[pallet::call(weight(>::WeightInfo))] + impl, I: 'static> Pallet { + /// Transfer some liquid free balance to another account. + /// + /// `transfer_allow_death` will set the `FreeBalance` of the sender and receiver. + /// If the sender's account is below the existential deposit as a result + /// of the transfer, the account will be reaped. + /// + /// The dispatch origin for this call must be `Signed` by the transactor. + #[pallet::call_index(0)] + pub fn transfer_allow_death( + origin: OriginFor, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResult { + let source = ensure_signed(origin)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer(&source, &dest, value, Expendable)?; + Ok(()) + } + + /// Exactly as `transfer_allow_death`, except the origin must be root and the source account + /// may be specified. + #[pallet::call_index(2)] + pub fn force_transfer( + origin: OriginFor, + source: AccountIdLookupOf, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + let source = T::Lookup::lookup(source)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer(&source, &dest, value, Expendable)?; + Ok(()) + } + + /// Same as the [`transfer_allow_death`] call, but with a check that the transfer will not + /// kill the origin account. + /// + /// 99% of the time you want [`transfer_allow_death`] instead. + /// + /// [`transfer_allow_death`]: struct.Pallet.html#method.transfer + #[pallet::call_index(3)] + pub fn transfer_keep_alive( + origin: OriginFor, + dest: AccountIdLookupOf, + #[pallet::compact] value: T::Balance, + ) -> DispatchResult { + let source = ensure_signed(origin)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer(&source, &dest, value, Preserve)?; + Ok(()) + } + + /// Transfer the entire transferable balance from the caller account. + /// + /// NOTE: This function only attempts to transfer _transferable_ balances. This means that + /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be + /// transferred by this function. To ensure that this function results in a killed account, + /// you might need to prepare the account by removing any reference counters, storage + /// deposits, etc... + /// + /// The dispatch origin of this call must be Signed. + /// + /// - `dest`: The recipient of the transfer. + /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all + /// of the funds the account has, causing the sender account to be killed (false), or + /// transfer everything except at least the existential deposit, which will guarantee to + /// keep the sender account alive (true). + #[pallet::call_index(4)] + pub fn transfer_all( + origin: OriginFor, + dest: AccountIdLookupOf, + keep_alive: bool, + ) -> DispatchResult { + let transactor = ensure_signed(origin)?; + let keep_alive = if keep_alive { Preserve } else { Expendable }; + let reducible_balance = >::reducible_balance( + &transactor, + keep_alive, + Fortitude::Polite, + ); + let dest = T::Lookup::lookup(dest)?; + >::transfer( + &transactor, + &dest, + reducible_balance, + keep_alive, + )?; + Ok(()) + } + + /// Unreserve some balance from a user by force. + /// + /// Can only be called by ROOT. + #[pallet::call_index(5)] + pub fn force_unreserve( + origin: OriginFor, + who: AccountIdLookupOf, + amount: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + let _leftover = >::unreserve(&who, amount); + Ok(()) + } + + /// Upgrade a specified account. + /// + /// - `origin`: Must be `Signed`. + /// - `who`: The account to be upgraded. + /// + /// This will waive the transaction fee if at least all but 10% of the accounts needed to + /// be upgraded. (We let some not have to be upgraded just in order to allow for the + /// possibility of churn). + #[pallet::call_index(6)] + #[pallet::weight(T::WeightInfo::upgrade_accounts(who.len() as u32))] + pub fn upgrade_accounts( + origin: OriginFor, + who: Vec, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + if who.is_empty() { + return Ok(Pays::Yes.into()) + } + let mut upgrade_count = 0; + for i in &who { + let upgraded = Self::ensure_upgraded(i); + if upgraded { + upgrade_count.saturating_inc(); + } + } + let proportion_upgraded = Perbill::from_rational(upgrade_count, who.len() as u32); + if proportion_upgraded >= Perbill::from_percent(90) { + Ok(Pays::No.into()) + } else { + Ok(Pays::Yes.into()) + } + } + + /// Set the regular balance of a given account. + /// + /// The dispatch origin for this call is `root`. + #[pallet::call_index(8)] + #[pallet::weight( + T::WeightInfo::force_set_balance_creating() // Creates a new account. + .max(T::WeightInfo::force_set_balance_killing()) // Kills an existing account. + )] + pub fn force_set_balance( + origin: OriginFor, + who: AccountIdLookupOf, + #[pallet::compact] new_free: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + let existential_deposit = Self::ed(); + + let wipeout = new_free < existential_deposit; + let new_free = if wipeout { Zero::zero() } else { new_free }; + + // First we try to modify the account's balance to the forced balance. + let old_free = Self::mutate_account_handling_dust(&who, |account| { + let old_free = account.free; + account.free = new_free; + old_free + })?; + + // This will adjust the total issuance, which was not done by the `mutate_account` + // above. + if new_free > old_free { + mem::drop(PositiveImbalance::::new(new_free - old_free)); + } else if new_free < old_free { + mem::drop(NegativeImbalance::::new(old_free - new_free)); + } + + Self::deposit_event(Event::BalanceSet { who, free: new_free }); + Ok(()) + } + + /// Adjust the total issuance in a saturating way. + /// + /// Can only be called by root and always needs a positive `delta`. + /// + /// # Example + #[doc = docify::embed!("./src/tests/dispatchable_tests.rs", force_adjust_total_issuance_example)] + #[pallet::call_index(9)] + #[pallet::weight(T::WeightInfo::force_adjust_total_issuance())] + pub fn force_adjust_total_issuance( + origin: OriginFor, + direction: AdjustmentDirection, + #[pallet::compact] delta: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + + ensure!(delta > Zero::zero(), Error::::DeltaZero); + + let old = TotalIssuance::::get(); + let new = match direction { + AdjustmentDirection::Increase => old.saturating_add(delta), + AdjustmentDirection::Decrease => old.saturating_sub(delta), + }; + + ensure!(InactiveIssuance::::get() <= new, Error::::IssuanceDeactivated); + TotalIssuance::::set(new); + + Self::deposit_event(Event::::TotalIssuanceForced { old, new }); + + Ok(()) + } + + /// Burn the specified liquid free balance from the origin account. + /// + /// If the origin's account ends up below the existential deposit as a result + /// of the burn and `keep_alive` is false, the account will be reaped. + /// + /// Unlike sending funds to a _burn_ address, which merely makes the funds inaccessible, + /// this `burn` operation will reduce total issuance by the amount _burned_. + #[pallet::call_index(10)] + #[pallet::weight(if *keep_alive {T::WeightInfo::burn_allow_death() } else {T::WeightInfo::burn_keep_alive()})] + pub fn burn( + origin: OriginFor, + #[pallet::compact] value: T::Balance, + keep_alive: bool, + ) -> DispatchResult { + let source = ensure_signed(origin)?; + let preservation = if keep_alive { Preserve } else { Expendable }; + >::burn_from( + &source, + value, + preservation, + Precision::Exact, + Polite, + )?; + Ok(()) + } + } + + impl, I: 'static> Pallet { + /// Public function to get the total issuance. + pub fn total_issuance() -> T::Balance { + TotalIssuance::::get() + } + + /// Public function to get the inactive issuance. + pub fn inactive_issuance() -> T::Balance { + InactiveIssuance::::get() + } + + /// Public function to access the Locks storage. + pub fn locks(who: &T::AccountId) -> WeakBoundedVec, T::MaxLocks> { + Locks::::get(who) + } + + /// Public function to access the reserves storage. + pub fn reserves( + who: &T::AccountId, + ) -> BoundedVec, T::MaxReserves> { + Reserves::::get(who) + } + + fn ed() -> T::Balance { + T::ExistentialDeposit::get() + } + /// Ensure the account `who` is using the new logic. + /// + /// Returns `true` if the account did get upgraded, `false` if it didn't need upgrading. + pub fn ensure_upgraded(who: &T::AccountId) -> bool { + let mut a = T::AccountStore::get(who); + if a.flags.is_new_logic() { + return false + } + a.flags.set_new_logic(); + if !a.reserved.is_zero() && a.frozen.is_zero() { + if system::Pallet::::providers(who) == 0 { + // Gah!! We have no provider refs :( + // This shouldn't practically happen, but we need a failsafe anyway: let's give + // them enough for an ED. + log::warn!( + target: LOG_TARGET, + "account with a non-zero reserve balance has no provider refs, account_id: '{:?}'.", + who + ); + a.free = a.free.max(Self::ed()); + system::Pallet::::inc_providers(who); + } + let _ = system::Pallet::::inc_consumers_without_limit(who).defensive(); + } + // Should never fail - we're only setting a bit. + let _ = T::AccountStore::try_mutate_exists(who, |account| -> DispatchResult { + *account = Some(a); + Ok(()) + }); + Self::deposit_event(Event::Upgraded { who: who.clone() }); + return true + } + + /// Get the free balance of an account. + pub fn free_balance(who: impl core::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).free + } + + /// Get the balance of an account that can be used for transfers, reservations, or any other + /// non-locking, non-transaction-fee activity. Will be at most `free_balance`. + pub fn usable_balance(who: impl core::borrow::Borrow) -> T::Balance { + >::reducible_balance(who.borrow(), Expendable, Polite) + } + + /// Get the balance of an account that can be used for paying transaction fees (not tipping, + /// or any other kind of fees, though). Will be at most `free_balance`. + /// + /// This requires that the account stays alive. + pub fn usable_balance_for_fees(who: impl core::borrow::Borrow) -> T::Balance { + >::reducible_balance(who.borrow(), Protect, Polite) + } + + /// Get the reserved balance of an account. + pub fn reserved_balance(who: impl core::borrow::Borrow) -> T::Balance { + Self::account(who.borrow()).reserved + } + + /// Get both the free and reserved balances of an account. + pub(crate) fn account(who: &T::AccountId) -> AccountData { + T::AccountStore::get(who) + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. + /// + /// It returns the result from the closure. Any dust is handled through the low-level + /// `fungible::Unbalanced` trap-door for legacy dust management. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + pub(crate) fn mutate_account_handling_dust( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData) -> R, + ) -> Result { + let (r, maybe_dust) = Self::mutate_account(who, f)?; + if let Some(dust) = maybe_dust { + >::handle_raw_dust(dust); + } + Ok(r) + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. + /// + /// It returns the result from the closure. Any dust is handled through the low-level + /// `fungible::Unbalanced` trap-door for legacy dust management. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + pub(crate) fn try_mutate_account_handling_dust>( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData, bool) -> Result, + ) -> Result { + let (r, maybe_dust) = Self::try_mutate_account(who, f)?; + if let Some(dust) = maybe_dust { + >::handle_raw_dust(dust); + } + Ok(r) + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. + /// + /// It returns both the result from the closure, and an optional amount of dust + /// which should be handled once it is known that all nested mutates that could affect + /// storage items what the dust handler touches have completed. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + pub(crate) fn mutate_account( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData) -> R, + ) -> Result<(R, Option), DispatchError> { + Self::try_mutate_account(who, |a, _| -> Result { Ok(f(a)) }) + } + + /// Returns `true` when `who` has some providers or `insecure_zero_ed` feature is disabled. + /// Returns `false` otherwise. + #[cfg(not(feature = "insecure_zero_ed"))] + fn have_providers_or_no_zero_ed(_: &T::AccountId) -> bool { + true + } + + /// Returns `true` when `who` has some providers or `insecure_zero_ed` feature is disabled. + /// Returns `false` otherwise. + #[cfg(feature = "insecure_zero_ed")] + fn have_providers_or_no_zero_ed(who: &T::AccountId) -> bool { + frame_system::Pallet::::providers(who) > 0 + } + + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the + /// result of `f` is an `Err`. + /// + /// It returns both the result from the closure, and an optional amount of dust + /// which should be handled once it is known that all nested mutates that could affect + /// storage items what the dust handler touches have completed. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + pub(crate) fn try_mutate_account>( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData, bool) -> Result, + ) -> Result<(R, Option), E> { + Self::ensure_upgraded(who); + let result = T::AccountStore::try_mutate_exists(who, |maybe_account| { + let is_new = maybe_account.is_none(); + let mut account = maybe_account.take().unwrap_or_default(); + let did_provide = + account.free >= Self::ed() && Self::have_providers_or_no_zero_ed(who); + let did_consume = + !is_new && (!account.reserved.is_zero() || !account.frozen.is_zero()); + + let result = f(&mut account, is_new)?; + + let does_provide = account.free >= Self::ed(); + let does_consume = !account.reserved.is_zero() || !account.frozen.is_zero(); + + if !did_provide && does_provide { + frame_system::Pallet::::inc_providers(who); + } + if did_consume && !does_consume { + frame_system::Pallet::::dec_consumers(who); + } + if !did_consume && does_consume { + frame_system::Pallet::::inc_consumers(who)?; + } + if does_consume && frame_system::Pallet::::consumers(who) == 0 { + // NOTE: This is a failsafe and should not happen for normal accounts. A normal + // account should have gotten a consumer ref in `!did_consume && does_consume` + // at some point. + log::error!(target: LOG_TARGET, "Defensively bumping a consumer ref."); + frame_system::Pallet::::inc_consumers(who)?; + } + if did_provide && !does_provide { + // This could reap the account so must go last. + frame_system::Pallet::::dec_providers(who).inspect_err(|_| { + // best-effort revert consumer change. + if did_consume && !does_consume { + let _ = frame_system::Pallet::::inc_consumers(who).defensive(); + } + if !did_consume && does_consume { + let _ = frame_system::Pallet::::dec_consumers(who); + } + })?; + } + + let maybe_endowed = if is_new { Some(account.free) } else { None }; + + // Handle any steps needed after mutating an account. + // + // This includes DustRemoval unbalancing, in the case than the `new` account's total + // balance is non-zero but below ED. + // + // Updates `maybe_account` to `Some` iff the account has sufficient balance. + // Evaluates `maybe_dust`, which is `Some` containing the dust to be dropped, iff + // some dust should be dropped. + // + // We should never be dropping if reserved is non-zero. Reserved being non-zero + // should imply that we have a consumer ref, so this is economically safe. + let ed = Self::ed(); + let maybe_dust = if account.free < ed && account.reserved.is_zero() { + if account.free.is_zero() { + None + } else { + Some(account.free) + } + } else { + assert!( + account.free.is_zero() || account.free >= ed || !account.reserved.is_zero() + ); + *maybe_account = Some(account); + None + }; + Ok((maybe_endowed, maybe_dust, result)) + }); + result.map(|(maybe_endowed, maybe_dust, result)| { + if let Some(endowed) = maybe_endowed { + Self::deposit_event(Event::Endowed { + account: who.clone(), + free_balance: endowed, + }); + } + if let Some(amount) = maybe_dust { + Pallet::::deposit_event(Event::DustLost { account: who.clone(), amount }); + } + (result, maybe_dust) + }) + } + + /// Update the account entry for `who`, given the locks. + pub(crate) fn update_locks(who: &T::AccountId, locks: &[BalanceLock]) { + let bounded_locks = WeakBoundedVec::<_, T::MaxLocks>::force_from( + locks.to_vec(), + Some("Balances Update Locks"), + ); + + if locks.len() as u32 > T::MaxLocks::get() { + log::warn!( + target: LOG_TARGET, + "Warning: A user has more currency locks than expected. \ + A runtime configuration adjustment may be needed." + ); + } + let freezes = Freezes::::get(who); + let mut prev_frozen = Zero::zero(); + let mut after_frozen = Zero::zero(); + // No way this can fail since we do not alter the existential balances. + // TODO: Revisit this assumption. + let res = Self::mutate_account(who, |b| { + prev_frozen = b.frozen; + b.frozen = Zero::zero(); + for l in locks.iter() { + b.frozen = b.frozen.max(l.amount); + } + for l in freezes.iter() { + b.frozen = b.frozen.max(l.amount); + } + after_frozen = b.frozen; + }); + debug_assert!(res.is_ok()); + if let Ok((_, maybe_dust)) = res { + debug_assert!(maybe_dust.is_none(), "Not altering main balance; qed"); + } + + match locks.is_empty() { + true => Locks::::remove(who), + false => Locks::::insert(who, bounded_locks), + } + + if prev_frozen > after_frozen { + let amount = prev_frozen.saturating_sub(after_frozen); + Self::deposit_event(Event::Unlocked { who: who.clone(), amount }); + } else if after_frozen > prev_frozen { + let amount = after_frozen.saturating_sub(prev_frozen); + Self::deposit_event(Event::Locked { who: who.clone(), amount }); + } + } + + /// Update the account entry for `who`, given the locks. + pub(crate) fn update_freezes( + who: &T::AccountId, + freezes: BoundedSlice, T::MaxFreezes>, + ) -> DispatchResult { + let mut prev_frozen = Zero::zero(); + let mut after_frozen = Zero::zero(); + let (_, maybe_dust) = Self::mutate_account(who, |b| { + prev_frozen = b.frozen; + b.frozen = Zero::zero(); + for l in Locks::::get(who).iter() { + b.frozen = b.frozen.max(l.amount); + } + for l in freezes.iter() { + b.frozen = b.frozen.max(l.amount); + } + after_frozen = b.frozen; + })?; + debug_assert!(maybe_dust.is_none(), "Not altering main balance; qed"); + if freezes.is_empty() { + Freezes::::remove(who); + } else { + Freezes::::insert(who, freezes); + } + if prev_frozen > after_frozen { + let amount = prev_frozen.saturating_sub(after_frozen); + Self::deposit_event(Event::Thawed { who: who.clone(), amount }); + } else if after_frozen > prev_frozen { + let amount = after_frozen.saturating_sub(prev_frozen); + Self::deposit_event(Event::Frozen { who: who.clone(), amount }); + } + Ok(()) + } + + /// Move the reserved balance of one account into the balance of another, according to + /// `status`. This will respect freezes/locks only if `fortitude` is `Polite`. + /// + /// Is a no-op if the value to be moved is zero. + /// + /// NOTE: returns actual amount of transferred value in `Ok` case. + pub(crate) fn do_transfer_reserved( + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: T::Balance, + precision: Precision, + fortitude: Fortitude, + status: Status, + ) -> Result { + if value.is_zero() { + return Ok(Zero::zero()) + } + + let max = >::reducible_total_balance_on_hold( + slashed, fortitude, + ); + let actual = match precision { + Precision::BestEffort => value.min(max), + Precision::Exact => value, + }; + ensure!(actual <= max, TokenError::FundsUnavailable); + if slashed == beneficiary { + return match status { + Status::Free => Ok(actual.saturating_sub(Self::unreserve(slashed, actual))), + Status::Reserved => Ok(actual), + } + } + + let ((_, maybe_dust_1), maybe_dust_2) = Self::try_mutate_account( + beneficiary, + |to_account, is_new| -> Result<((), Option), DispatchError> { + ensure!(!is_new, Error::::DeadAccount); + Self::try_mutate_account(slashed, |from_account, _| -> DispatchResult { + match status { + Status::Free => + to_account.free = to_account + .free + .checked_add(&actual) + .ok_or(ArithmeticError::Overflow)?, + Status::Reserved => + to_account.reserved = to_account + .reserved + .checked_add(&actual) + .ok_or(ArithmeticError::Overflow)?, + } + from_account.reserved.saturating_reduce(actual); + Ok(()) + }) + }, + )?; + + if let Some(dust) = maybe_dust_1 { + >::handle_raw_dust(dust); + } + if let Some(dust) = maybe_dust_2 { + >::handle_raw_dust(dust); + } + + Self::deposit_event(Event::ReserveRepatriated { + from: slashed.clone(), + to: beneficiary.clone(), + amount: actual, + destination_status: status, + }); + Ok(actual) + } + + /// Generate dev account from derivation(hard) string. + pub fn derive_dev_account(num_accounts: u32, balance: T::Balance, derivation: &str) { + // Ensure that the number of accounts is not zero. + assert!(num_accounts > 0, "num_accounts must be greater than zero"); + + assert!( + balance >= >::ExistentialDeposit::get(), + "the balance of any account should always be at least the existential deposit.", + ); + + assert!( + derivation.contains("{}"), + "Invalid derivation, expected `{{}}` as part of the derivation" + ); + + for index in 0..num_accounts { + // Replace "{}" in the derivation string with the index. + let derivation_string = derivation.replace("{}", &index.to_string()); + + // Generate the key pair from the derivation string using sr25519. + let pair: SrPair = Pair::from_string(&derivation_string, None) + .expect(&format!("Failed to parse derivation string: {derivation_string}")); + + // Convert the public key to AccountId. + let who = T::AccountId::decode(&mut &pair.public().encode()[..]) + .expect(&format!("Failed to decode public key from pair: {:?}", pair.public())); + + // Set the balance for the generated account. + Self::mutate_account_handling_dust(&who, |account| { + account.free = balance; + }) + .expect(&format!("Failed to add account to keystore: {:?}", who)); + } + } + } +} diff --git a/pallets/balances/src/migration.rs b/pallets/balances/src/migration.rs new file mode 100644 index 000000000..836deb325 --- /dev/null +++ b/pallets/balances/src/migration.rs @@ -0,0 +1,103 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Substrate. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::*; +use frame_support::{ + pallet_prelude::*, + traits::{OnRuntimeUpgrade, PalletInfoAccess}, + weights::Weight, +}; + +fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { + let on_chain_version = Pallet::::on_chain_storage_version(); + + if on_chain_version == 0 { + let total = accounts + .iter() + .map(|a| Pallet::::total_balance(a)) + .fold(T::Balance::zero(), |a, e| a.saturating_add(e)); + Pallet::::deactivate(total); + + // Remove the old `StorageVersion` type. + frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( + Pallet::::name().as_bytes(), + "StorageVersion".as_bytes(), + )); + + // Set storage version to `1`. + StorageVersion::new(1).put::>(); + + log::info!(target: LOG_TARGET, "Storage to version 1"); + T::DbWeight::get().reads_writes(2 + accounts.len() as u64, 3) + } else { + log::info!( + target: LOG_TARGET, + "Migration did not execute. This probably should be removed" + ); + T::DbWeight::get().reads(1) + } +} + +// NOTE: This must be used alongside the account whose balance is expected to be inactive. +// Generally this will be used for the XCM teleport checking account. +pub struct MigrateToTrackInactive(PhantomData<(T, A, I)>); +impl, A: Get, I: 'static> OnRuntimeUpgrade + for MigrateToTrackInactive +{ + fn on_runtime_upgrade() -> Weight { + migrate_v0_to_v1::(&[A::get()]) + } +} + +// NOTE: This must be used alongside the accounts whose balance is expected to be inactive. +// Generally this will be used for the XCM teleport checking accounts. +pub struct MigrateManyToTrackInactive(PhantomData<(T, A, I)>); +impl, A: Get>, I: 'static> OnRuntimeUpgrade + for MigrateManyToTrackInactive +{ + fn on_runtime_upgrade() -> Weight { + migrate_v0_to_v1::(&A::get()) + } +} + +pub struct ResetInactive(PhantomData<(T, I)>); +impl, I: 'static> OnRuntimeUpgrade for ResetInactive { + fn on_runtime_upgrade() -> Weight { + let on_chain_version = Pallet::::on_chain_storage_version(); + + if on_chain_version == 1 { + // Remove the old `StorageVersion` type. + frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( + Pallet::::name().as_bytes(), + "StorageVersion".as_bytes(), + )); + + InactiveIssuance::::kill(); + + // Set storage version to `0`. + StorageVersion::new(0).put::>(); + + log::info!(target: LOG_TARGET, "Storage to version 0"); + T::DbWeight::get().reads_writes(1, 3) + } else { + log::info!( + target: LOG_TARGET, + "Migration did not execute. This probably should be removed" + ); + T::DbWeight::get().reads(1) + } + } +} diff --git a/pallets/balances/src/tests/currency_tests.rs b/pallets/balances/src/tests/currency_tests.rs new file mode 100644 index 000000000..0e5d7ccb4 --- /dev/null +++ b/pallets/balances/src/tests/currency_tests.rs @@ -0,0 +1,1445 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests regarding the functionality of the `Currency` trait set implementations. + +use super::*; +use crate::{Event, NegativeImbalance}; +use frame_support::{ + traits::{ + BalanceStatus::{Free, Reserved}, + Currency, + ExistenceRequirement::{self, AllowDeath, KeepAlive}, + InspectLockableCurrency, LockIdentifier, LockableCurrency, NamedReservableCurrency, + ReservableCurrency, WithdrawReasons, + }, + StorageNoopGuard, +}; +use frame_system::Event as SysEvent; +use sp_runtime::traits::DispatchTransaction; + +const ID_1: LockIdentifier = *b"1 "; +const ID_2: LockIdentifier = *b"2 "; + +pub const CALL: &::RuntimeCall = + &RuntimeCall::Balances(crate::Call::transfer_allow_death { dest: 0, value: 0 }); + +#[test] +fn ed_should_work() { + ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 1000)); + assert_noop!( + >::transfer(&1, &10, 1000, KeepAlive), + TokenError::NotExpendable + ); + assert_ok!(>::transfer(&1, &10, 1000, AllowDeath)); + }); +} + +#[test] +fn set_lock_with_amount_zero_removes_lock() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 0, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); +} + +#[test] +fn set_lock_with_withdraw_reasons_empty_removes_lock() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); +} + +#[test] +fn basic_locking_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 5, AllowDeath), + TokenError::Frozen + ); + }); +} + +#[test] +fn inspect_lock_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); + Balances::set_lock(ID_2, &1, 10, WithdrawReasons::all()); + Balances::set_lock(ID_1, &2, 20, WithdrawReasons::all()); + + assert_eq!(>::balance_locked(ID_1, &1), 10); + assert_eq!(>::balance_locked(ID_2, &1), 10); + assert_eq!(>::balance_locked(ID_1, &2), 20); + assert_eq!(>::balance_locked(ID_2, &2), 0); + assert_eq!(>::balance_locked(ID_1, &3), 0); + }) +} + +#[test] +fn account_should_be_reaped() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); + assert_eq!(System::providers(&1), 0); + assert_eq!(System::consumers(&1), 0); + // Check that the account is dead. + assert!(!frame_system::Account::::contains_key(&1)); + }); +} + +#[test] +fn reap_failed_due_to_provider_and_consumer() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + // SCENARIO: only one provider and there are remaining consumers. + assert_ok!(System::inc_consumers(&1)); + assert!(!System::can_dec_provider(&1)); + assert_noop!( + >::transfer(&1, &2, 10, AllowDeath), + TokenError::Frozen + ); + assert!(System::account_exists(&1)); + assert_eq!(Balances::free_balance(1), 10); + + // SCENARIO: more than one provider, but will not kill account due to other provider. + assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed); + assert_eq!(System::providers(&1), 2); + assert!(System::can_dec_provider(&1)); + assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); + assert_eq!(System::providers(&1), 1); + assert!(System::account_exists(&1)); + assert_eq!(Balances::free_balance(1), 0); + }); +} + +#[test] +fn partial_locking_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); +} + +#[test] +fn lock_removal_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + Balances::remove_lock(ID_1, &1); + assert_eq!(System::consumers(&1), 0); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); +} + +#[test] +fn lock_replacement_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); +} + +#[test] +fn double_locking_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); +} + +#[test] +fn combination_locking_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_eq!(System::consumers(&1), 0); + Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); + assert_eq!(System::consumers(&1), 0); + Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 0); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); +} + +#[test] +fn lock_value_extension_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + TokenError::Frozen + ); + Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + TokenError::Frozen + ); + Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + assert_noop!( + >::transfer(&1, &2, 3, AllowDeath), + TokenError::Frozen + ); + }); +} + +#[test] +fn lock_should_work_reserve() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::::put( + Multiplier::saturating_from_integer(1), + ); + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); + assert_noop!( + >::transfer(&1, &2, 1, AllowDeath), + TokenError::Frozen + ); + assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); + assert!(ChargeTransactionPayment::::validate_and_prepare( + ChargeTransactionPayment::from(1), + Some(1).into(), + CALL, + &info_from_weight(Weight::from_parts(1, 0)), + 1, + 0, + ) + .is_err()); + assert!(ChargeTransactionPayment::::validate_and_prepare( + ChargeTransactionPayment::from(0), + Some(1).into(), + CALL, + &info_from_weight(Weight::from_parts(1, 0)), + 1, + 0, + ) + .is_err()); + }); +} + +#[test] +fn lock_should_work_tx_fee() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); + assert_noop!( + >::transfer(&1, &2, 1, AllowDeath), + TokenError::Frozen + ); + assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); + assert!(ChargeTransactionPayment::::validate_and_prepare( + ChargeTransactionPayment::from(1), + Some(1).into(), + CALL, + &info_from_weight(Weight::from_parts(1, 0)), + 1, + 0, + ) + .is_err()); + assert!(ChargeTransactionPayment::::validate_and_prepare( + ChargeTransactionPayment::from(0), + Some(1).into(), + CALL, + &info_from_weight(Weight::from_parts(1, 0)), + 1, + 0, + ) + .is_err()); + }); +} + +#[test] +fn lock_block_number_extension_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + TokenError::Frozen + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + TokenError::Frozen + ); + System::set_block_number(2); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 3, AllowDeath), + TokenError::Frozen + ); + }); +} + +#[test] +fn lock_reasons_extension_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSFER); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + TokenError::Frozen + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::empty()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + TokenError::Frozen + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + TokenError::Frozen + ); + }); +} + +#[test] +fn reserved_balance_should_prevent_reclaim_count() { + ExtBuilder::default() + .existential_deposit(256 * 1) + .monied(true) + .build_and_execute_with(|| { + System::inc_account_nonce(&2); + assert_eq!(Balances::total_balance(&2), 256 * 20); + assert_eq!(System::providers(&2), 1); + System::inc_providers(&2); + assert_eq!(System::providers(&2), 2); + + assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved + assert_eq!(System::providers(&2), 1); + assert_eq!(Balances::free_balance(2), 255); // "free" account would be deleted. + assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. + assert_eq!(System::account_nonce(&2), 1); + + // account 4 tries to take index 1 for account 5. + assert_ok!(Balances::transfer_allow_death(Some(4).into(), 5, 256 * 1 + 0x69)); + assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); + + assert!(Balances::slash_reserved(&2, 256 * 19 + 1).1.is_zero()); // account 2 gets slashed + + // "reserve" account reduced to 255 (below ED) so account no longer consuming + assert_ok!(System::dec_providers(&2)); + assert_eq!(System::providers(&2), 0); + // account deleted + assert_eq!(System::account_nonce(&2), 0); // nonce zero + assert_eq!(Balances::total_balance(&2), 0); + + // account 4 tries to take index 1 again for account 6. + assert_ok!(Balances::transfer_allow_death(Some(4).into(), 6, 256 * 1 + 0x69)); + assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); + }); +} + +#[test] +fn reward_should_work() { + ExtBuilder::default().monied(true).build_and_execute_with(|| { + assert_eq!(Balances::total_balance(&1), 10); + assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); + assert_eq!( + events(), + [ + RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 10 }), + RuntimeEvent::Balances(crate::Event::Issued { amount: 10 }), + ] + ); + assert_eq!(Balances::total_balance(&1), 20); + assert_eq!(pallet_balances::TotalIssuance::::get(), 120); + }); +} + +#[test] +fn balance_works() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { + who: 1, + amount: 42, + })); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::total_balance(&2), 0); + }); +} + +#[test] +fn reserving_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_ok!(Balances::reserve(&1, 69)); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 69); + }); +} + +#[test] +fn deducting_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 69)); + assert_eq!(Balances::free_balance(1), 42); + }); +} + +#[test] +fn refunding_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + assert_ok!(Balances::mutate_account(&1, |a| a.reserved = 69)); + Balances::unreserve(&1, 69); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn slashing_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 112); + assert_ok!(Balances::reserve(&1, 69)); + assert!(Balances::slash(&1, 42).1.is_zero()); + assert_eq!(Balances::free_balance(1), 1); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(pallet_balances::TotalIssuance::::get(), 70); + }); +} + +#[test] +fn withdrawing_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&2, 111); + let _ = + Balances::withdraw(&2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Withdraw { + who: 2, + amount: 11, + })); + assert_eq!(Balances::free_balance(2), 100); + assert_eq!(pallet_balances::TotalIssuance::::get(), 100); + }); +} + +#[test] +fn withdrawing_balance_should_fail_when_not_expendable() { + ExtBuilder::default().build_and_execute_with(|| { + ExistentialDeposit::set(10); + let _ = Balances::deposit_creating(&2, 20); + assert_ok!(Balances::reserve(&2, 5)); + assert_noop!( + Balances::withdraw(&2, 6, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive), + Error::::Expendability, + ); + assert_ok!(Balances::withdraw( + &2, + 5, + WithdrawReasons::TRANSFER, + ExistenceRequirement::KeepAlive + ),); + }); +} + +#[test] +fn slashing_incomplete_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + assert_ok!(Balances::reserve(&1, 21)); + assert_eq!(Balances::slash(&1, 69).1, 49); + assert_eq!(Balances::free_balance(1), 1); + assert_eq!(Balances::reserved_balance(1), 21); + assert_eq!(pallet_balances::TotalIssuance::::get(), 22); + }); +} + +#[test] +fn unreserving_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 110)); + Balances::unreserve(&1, 41); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 42); + }); +} + +#[test] +fn slashing_reserved_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 112); + assert_ok!(Balances::reserve(&1, 111)); + assert_eq!(Balances::slash_reserved(&1, 42).1, 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 1); + assert_eq!(pallet_balances::TotalIssuance::::get(), 70); + }); +} + +#[test] +fn slashing_incomplete_reserved_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 42)); + assert_eq!(Balances::slash_reserved(&1, 69).1, 27); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(pallet_balances::TotalIssuance::::get(), 69); + }); +} + +#[test] +fn repatriating_reserved_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 110)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Free), 0); + System::assert_last_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { + from: 1, + to: 2, + amount: 41, + destination_status: Free, + })); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 1); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); + }); +} + +#[test] +fn transferring_reserved_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 110)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Reserved), 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 1); + assert_eq!(Balances::reserved_balance(2), 41); + assert_eq!(Balances::free_balance(2), 1); + }); +} + +#[test] +fn transferring_reserved_balance_to_yourself_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + assert_ok!(Balances::reserve(&1, 50)); + assert_ok!(Balances::repatriate_reserved(&1, &1, 50, Free), 0); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_ok!(Balances::reserve(&1, 50)); + assert_ok!(Balances::repatriate_reserved(&1, &1, 60, Free), 10); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn transferring_reserved_balance_to_nonexistent_should_fail() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 110)); + assert_noop!( + Balances::repatriate_reserved(&1, &2, 42, Free), + Error::::DeadAccount + ); + }); +} + +#[test] +fn transferring_incomplete_reserved_balance_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 41)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Free), 28); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); + }); +} + +#[test] +fn transferring_too_high_value_should_not_panic() { + ExtBuilder::default().build_and_execute_with(|| { + Balances::make_free_balance_be(&1, u64::MAX); + Balances::make_free_balance_be(&2, 1); + + assert_err!( + >::transfer(&1, &2, u64::MAX, AllowDeath), + ArithmeticError::Overflow, + ); + + assert_eq!(Balances::free_balance(1), u64::MAX); + assert_eq!(Balances::free_balance(2), 1); + }); +} + +#[test] +fn account_create_on_free_too_low_with_other() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + assert_eq!(pallet_balances::TotalIssuance::::get(), 100); + + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(pallet_balances::TotalIssuance::::get(), 100); + }) +} + +#[test] +fn account_create_on_free_too_low() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(pallet_balances::TotalIssuance::::get(), 0); + }) +} + +#[test] +fn account_removal_on_free_too_low() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + assert_eq!(pallet_balances::TotalIssuance::::get(), 0); + + // Setup two accounts with free balance above the existential threshold. + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 110); + + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::free_balance(2), 110); + assert_eq!(pallet_balances::TotalIssuance::::get(), 220); + + // Transfer funds from account 1 of such amount that after this transfer + // the balance of account 1 will be below the existential threshold. + // This should lead to the removal of all balance of this account. + assert_ok!(Balances::transfer_allow_death(Some(1).into(), 2, 20)); + + // Verify free balance removal of account 1. + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 130); + + // Verify that TotalIssuance tracks balance removal when free balance is too low. + assert_eq!(pallet_balances::TotalIssuance::::get(), 130); + }); +} + +#[test] +fn burn_must_work() { + ExtBuilder::default().monied(true).build_and_execute_with(|| { + let init_total_issuance = pallet_balances::TotalIssuance::::get(); + let imbalance = >::burn(10); + assert_eq!(pallet_balances::TotalIssuance::::get(), init_total_issuance - 10); + drop(imbalance); + assert_eq!(pallet_balances::TotalIssuance::::get(), init_total_issuance); + }); +} + +#[test] +#[should_panic = "the balance of any account should always be at least the existential deposit."] +fn cannot_set_genesis_value_below_ed() { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = 11); + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let _ = crate::GenesisConfig:: { balances: vec![(1, 10)], ..Default::default() } + .assimilate_storage(&mut t) + .unwrap(); +} + +#[test] +#[should_panic = "duplicate balances in genesis."] +fn cannot_set_genesis_value_twice() { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let _ = crate::GenesisConfig:: { + balances: vec![(1, 10), (2, 20), (1, 15)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); +} + +#[test] +fn existential_deposit_respected_when_reserving() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + // Set balance to free and reserved at the existential deposit + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 101)); + // Check balance + assert_eq!(Balances::free_balance(1), 101); + assert_eq!(Balances::reserved_balance(1), 0); + + // Reserve some free balance + assert_ok!(Balances::reserve(&1, 1)); + // Check balance, the account should be ok. + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 1); + + // Cannot reserve any more of the free balance. + assert_noop!(Balances::reserve(&1, 1), DispatchError::ConsumerRemaining); + }); +} + +#[test] +fn slash_fails_when_account_needed() { + ExtBuilder::default().existential_deposit(50).build_and_execute_with(|| { + // Set balance to free and reserved at the existential deposit + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 52)); + assert_ok!(Balances::reserve(&1, 1)); + // Check balance + assert_eq!(Balances::free_balance(1), 51); + assert_eq!(Balances::reserved_balance(1), 1); + + // Slash a small amount + let res = Balances::slash(&1, 1); + assert_eq!(res, (NegativeImbalance::new(1), 0)); + + // The account should be dead. + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 1); + + // Slashing again doesn't work since we require the ED + let res = Balances::slash(&1, 1); + assert_eq!(res, (NegativeImbalance::new(0), 1)); + + // The account should be dead. + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 1); + }); +} + +#[test] +fn account_deleted_when_just_dust() { + ExtBuilder::default().existential_deposit(50).build_and_execute_with(|| { + // Set balance to free and reserved at the existential deposit + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 50)); + // Check balance + assert_eq!(Balances::free_balance(1), 50); + + // Slash a small amount + let res = Balances::slash(&1, 1); + assert_eq!(res, (NegativeImbalance::new(1), 0)); + + // The account should be dead. + assert_eq!(Balances::free_balance(1), 0); + }); +} + +#[test] +fn emit_events_with_reserve_and_unreserve() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + + System::set_block_number(2); + assert_ok!(Balances::reserve(&1, 10)); + + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Reserved { + who: 1, + amount: 10, + })); + + System::set_block_number(3); + assert!(Balances::unreserve(&1, 5).is_zero()); + + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { + who: 1, + amount: 5, + })); + + System::set_block_number(4); + assert_eq!(Balances::unreserve(&1, 6), 1); + + // should only unreserve 5 + System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { + who: 1, + amount: 5, + })); + }); +} + +#[test] +fn emit_events_with_changing_locks() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + System::reset_events(); + + // Locks = [] --> [10] + Balances::set_lock(*b"LOCK_000", &1, 10, WithdrawReasons::TRANSFER); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 10 })]); + + // Locks = [10] --> [15] + Balances::set_lock(*b"LOCK_000", &1, 15, WithdrawReasons::TRANSFER); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 5 })]); + + // Locks = [15] --> [15, 20] + Balances::set_lock(*b"LOCK_001", &1, 20, WithdrawReasons::TRANSACTION_PAYMENT); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 5 })]); + + // Locks = [15, 20] --> [17, 20] + Balances::set_lock(*b"LOCK_000", &1, 17, WithdrawReasons::TRANSACTION_PAYMENT); + for event in events() { + match event { + RuntimeEvent::Balances(crate::Event::Locked { .. }) => { + assert!(false, "unexpected lock event") + }, + RuntimeEvent::Balances(crate::Event::Unlocked { .. }) => { + assert!(false, "unexpected unlock event") + }, + _ => continue, + } + } + + // Locks = [17, 20] --> [17, 15] + Balances::set_lock(*b"LOCK_001", &1, 15, WithdrawReasons::TRANSFER); + assert_eq!( + events(), + [RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 3 })] + ); + + // Locks = [17, 15] --> [15] + Balances::remove_lock(*b"LOCK_000", &1); + assert_eq!( + events(), + [RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 2 })] + ); + + // Locks = [15] --> [] + Balances::remove_lock(*b"LOCK_001", &1); + assert_eq!( + events(), + [RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 15 })] + ); + }); +} + +#[test] +fn emit_events_with_existential_deposit() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 100)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::NewAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), + RuntimeEvent::Balances(crate::Event::Issued { amount: 100 }), + RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100 }), + ] + ); + + let res = Balances::slash(&1, 1); + assert_eq!(res, (NegativeImbalance::new(1), 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 99 }), + RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }), + RuntimeEvent::Balances(crate::Event::Rescinded { amount: 1 }), + ] + ); + }); +} + +#[test] +fn emit_events_with_no_existential_deposit_suicide() { + ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 100); + + assert_eq!( + events(), + [ + RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100 }), + RuntimeEvent::System(system::Event::NewAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), + RuntimeEvent::Balances(crate::Event::Issued { amount: 100 }), + ] + ); + + let res = Balances::slash(&1, 100); + assert_eq!(res, (NegativeImbalance::new(100), 0)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 100 }), + RuntimeEvent::Balances(crate::Event::Rescinded { amount: 100 }), + ] + ); + }); +} + +#[test] +fn slash_over_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + // SCENARIO: Over-slash will kill account, and report missing slash amount. + Balances::make_free_balance_be(&1, 1_000); + // Slashed full free_balance, and reports 300 not slashed + assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1000), 300)); + // Account is dead + assert!(!System::account_exists(&1)); + }); +} + +#[test] +fn slash_full_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + // Slashed completed in full + assert_eq!(Balances::slash(&1, 1_000), (NegativeImbalance::new(1000), 0)); + // Account is still alive + assert!(!System::account_exists(&1)); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { + who: 1, + amount: 1000, + })); + }); +} + +#[test] +fn slash_partial_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + // Slashed completed in full + assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { + who: 1, + amount: 900, + })); + }); +} + +#[test] +fn slash_dusting_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + // Slashed completed in full + assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(950), 0)); + assert!(!System::account_exists(&1)); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { + who: 1, + amount: 950, + })); + }); +} + +#[test] +fn slash_does_not_take_from_reserve() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + assert_ok!(Balances::reserve(&1, 100)); + // Slashed completed in full + assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(800), 100)); + assert_eq!(Balances::reserved_balance(&1), 100); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { + who: 1, + amount: 800, + })); + }); +} + +#[test] +fn slash_consumed_slash_full_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests + // Slashed completed in full + assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + }); +} + +#[test] +fn slash_consumed_slash_over_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests + // Slashed completed in full + assert_eq!(Balances::slash(&1, 1_000), (NegativeImbalance::new(900), 100)); + // Account is still alive + assert!(System::account_exists(&1)); + }); +} + +#[test] +fn slash_consumed_slash_partial_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests + // Slashed completed in full + assert_eq!(Balances::slash(&1, 800), (NegativeImbalance::new(800), 0)); + // Account is still alive + assert!(System::account_exists(&1)); + }); +} + +#[test] +fn slash_on_non_existent_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + // Slash on non-existent account is okay. + assert_eq!(Balances::slash(&12345, 1_300), (NegativeImbalance::new(0), 1300)); + }); +} + +#[test] +fn slash_reserved_slash_partial_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + assert_ok!(Balances::reserve(&1, 900)); + // Slashed completed in full + assert_eq!(Balances::slash_reserved(&1, 800), (NegativeImbalance::new(800), 0)); + assert_eq!(System::consumers(&1), 1); + assert_eq!(Balances::reserved_balance(&1), 100); + assert_eq!(Balances::free_balance(&1), 100); + }); +} + +#[test] +fn slash_reserved_slash_everything_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + Balances::make_free_balance_be(&1, 1_000); + assert_ok!(Balances::reserve(&1, 900)); + assert_eq!(System::consumers(&1), 1); + // Slashed completed in full + assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); + assert_eq!(System::consumers(&1), 0); + // Account is still alive + assert!(System::account_exists(&1)); + }); +} + +#[test] +fn slash_reserved_overslash_does_not_touch_free_balance() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + // SCENARIO: Over-slash doesn't touch free balance. + Balances::make_free_balance_be(&1, 1_000); + assert_ok!(Balances::reserve(&1, 800)); + // Slashed done + assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(800), 100)); + assert_eq!(Balances::free_balance(&1), 200); + }); +} + +#[test] +fn slash_reserved_on_non_existent_works() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + // Slash on non-existent account is okay. + assert_eq!(Balances::slash_reserved(&12345, 1_300), (NegativeImbalance::new(0), 1300)); + }); +} + +#[test] +fn operations_on_dead_account_should_not_change_state() { + // These functions all use `mutate_account` which may introduce a storage change when + // the account never existed to begin with, and shouldn't exist in the end. + ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { + assert!(!frame_system::Account::::contains_key(&1337)); + + // Unreserve + assert_storage_noop!(assert_eq!(Balances::unreserve(&1337, 42), 42)); + // Reserve + assert_noop!(Balances::reserve(&1337, 42), Error::::InsufficientBalance); + // Slash Reserve + assert_storage_noop!(assert_eq!(Balances::slash_reserved(&1337, 42).1, 42)); + // Repatriate Reserve + assert_noop!( + Balances::repatriate_reserved(&1337, &1338, 42, Free), + Error::::DeadAccount + ); + // Slash + assert_storage_noop!(assert_eq!(Balances::slash(&1337, 42).1, 42)); + }); +} + +#[test] +#[should_panic = "The existential deposit must be greater than zero!"] +#[cfg(not(feature = "insecure_zero_ed"))] +fn zero_ed_is_prohibited() { + use frame_support::traits::Hooks; + // These functions all use `mutate_account` which may introduce a storage change when + // the account never existed to begin with, and shouldn't exist in the end. + ExtBuilder::default().existential_deposit(0).build_and_execute_with(|| { + Balances::integrity_test(); + }); +} + +#[test] +fn named_reserve_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + let id_1 = TestId::Foo; + let id_2 = TestId::Bar; + let id_3 = TestId::Baz; + + // reserve + + assert_noop!( + Balances::reserve_named(&id_1, &1, 112), + Error::::InsufficientBalance + ); + + assert_ok!(Balances::reserve_named(&id_1, &1, 12)); + + assert_eq!(Balances::reserved_balance(1), 12); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 12); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + + assert_ok!(Balances::reserve_named(&id_1, &1, 2)); + + assert_eq!(Balances::reserved_balance(1), 14); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + + assert_ok!(Balances::reserve_named(&id_2, &1, 23)); + + assert_eq!(Balances::reserved_balance(1), 37); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + + assert_ok!(Balances::reserve(&1, 34)); + + assert_eq!(Balances::reserved_balance(1), 71); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 40); + + assert_noop!(Balances::reserve_named(&id_3, &1, 2), Error::::TooManyReserves); + + // unreserve + + assert_eq!(Balances::unreserve_named(&id_1, &1, 10), 0); + + assert_eq!(Balances::reserved_balance(1), 61); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 4); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + + assert_eq!(Balances::unreserve_named(&id_1, &1, 5), 1); + + assert_eq!(Balances::reserved_balance(1), 57); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); + + assert_eq!(Balances::unreserve_named(&id_2, &1, 3), 0); + + assert_eq!(Balances::reserved_balance(1), 54); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 57); + + // slash_reserved_named + + assert_ok!(Balances::reserve_named(&id_1, &1, 10)); + + assert_eq!(Balances::slash_reserved_named(&id_1, &1, 25).1, 15); + + assert_eq!(Balances::reserved_balance(1), 54); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); + assert_eq!(Balances::total_balance(&1), 101); + + assert_eq!(Balances::slash_reserved_named(&id_2, &1, 5).1, 0); + + assert_eq!(Balances::reserved_balance(1), 49); + assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); + assert_eq!(Balances::total_balance(&1), 96); + + // repatriate_reserved_named + + let _ = Balances::deposit_creating(&2, 100); + + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Reserved).unwrap(), 0); + + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + assert_eq!(Balances::reserved_balance_named(&id_2, &2), 10); + assert_eq!(Balances::reserved_balance(&2), 10); + + assert_eq!(Balances::repatriate_reserved_named(&id_2, &2, &1, 11, Reserved).unwrap(), 1); + + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); + assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); + assert_eq!(Balances::reserved_balance(&2), 0); + + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Free).unwrap(), 0); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); + assert_eq!(Balances::free_balance(&2), 110); + + // repatriate_reserved_named to self + + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 10, Reserved).unwrap(), 5); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); + + assert_eq!(Balances::free_balance(&1), 47); + + assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 15, Free).unwrap(), 10); + assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); + + assert_eq!(Balances::free_balance(&1), 52); + }); +} + +#[test] +fn reserve_must_succeed_if_can_reserve_does() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 1); + let _ = Balances::deposit_creating(&2, 2); + assert!(Balances::can_reserve(&1, 1) == Balances::reserve(&1, 1).is_ok()); + assert!(Balances::can_reserve(&2, 1) == Balances::reserve(&2, 1).is_ok()); + }); +} + +#[test] +fn reserved_named_to_yourself_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + + let id = TestId::Foo; + + assert_ok!(Balances::reserve_named(&id, &1, 50)); + assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 50, Free), 0); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + + assert_ok!(Balances::reserve_named(&id, &1, 50)); + assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 60, Free), 10); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + }); +} + +#[test] +fn ensure_reserved_named_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + let id = TestId::Foo; + + assert_ok!(Balances::ensure_reserved_named(&id, &1, 15)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 15); + + assert_ok!(Balances::ensure_reserved_named(&id, &1, 10)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 10); + + assert_ok!(Balances::ensure_reserved_named(&id, &1, 20)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 20); + }); +} + +#[test] +fn unreserve_all_named_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + let id = TestId::Foo; + + assert_ok!(Balances::reserve_named(&id, &1, 15)); + + assert_eq!(Balances::unreserve_all_named(&id, &1), 15); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + assert_eq!(Balances::free_balance(&1), 111); + + assert_eq!(Balances::unreserve_all_named(&id, &1), 0); + }); +} + +#[test] +fn slash_all_reserved_named_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + let id = TestId::Foo; + + assert_ok!(Balances::reserve_named(&id, &1, 15)); + + assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 15); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + assert_eq!(Balances::free_balance(&1), 96); + + assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 0); + }); +} + +#[test] +fn repatriate_all_reserved_named_should_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + let _ = Balances::deposit_creating(&2, 10); + let _ = Balances::deposit_creating(&3, 10); + + let id = TestId::Foo; + + assert_ok!(Balances::reserve_named(&id, &1, 15)); + + assert_ok!(Balances::repatriate_all_reserved_named(&id, &1, &2, Reserved)); + assert_eq!(Balances::reserved_balance_named(&id, &1), 0); + assert_eq!(Balances::reserved_balance_named(&id, &2), 15); + + assert_ok!(Balances::repatriate_all_reserved_named(&id, &2, &3, Free)); + assert_eq!(Balances::reserved_balance_named(&id, &2), 0); + assert_eq!(Balances::free_balance(&3), 25); + }); +} + +#[test] +fn freezing_and_locking_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + // Consumer is shared between freezing and locking. + assert_eq!(System::consumers(&1), 0); + assert_ok!(>::set_freeze(&TestId::Foo, &1, 4)); + assert_eq!(System::consumers(&1), 1); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_eq!(System::consumers(&1), 1); + + // Frozen and locked balances update correctly. + assert_eq!(Balances::account(&1).frozen, 5); + assert_ok!(>::set_freeze(&TestId::Foo, &1, 6)); + assert_eq!(Balances::account(&1).frozen, 6); + assert_ok!(>::set_freeze(&TestId::Foo, &1, 4)); + assert_eq!(Balances::account(&1).frozen, 5); + Balances::set_lock(ID_1, &1, 3, WithdrawReasons::all()); + assert_eq!(Balances::account(&1).frozen, 4); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_eq!(Balances::account(&1).frozen, 5); + + // Locks update correctly. + Balances::remove_lock(ID_1, &1); + assert_eq!(Balances::account(&1).frozen, 4); + assert_eq!(System::consumers(&1), 1); + assert_ok!(>::set_freeze(&TestId::Foo, &1, 0)); + assert_eq!(Balances::account(&1).frozen, 0); + assert_eq!(System::consumers(&1), 0); + }); +} + +#[test] +fn self_transfer_noop() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + assert_eq!(pallet_balances::TotalIssuance::::get(), 0); + let _ = Balances::deposit_creating(&1, 100); + + // The account is set up properly: + assert_eq!( + events(), + [ + Event::Deposit { who: 1, amount: 100 }.into(), + SysEvent::NewAccount { account: 1 }.into(), + Event::Endowed { account: 1, free_balance: 100 }.into(), + Event::Issued { amount: 100 }.into(), + ] + ); + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(pallet_balances::TotalIssuance::::get(), 100); + + // Transfers to self are No-OPs: + let _g = StorageNoopGuard::new(); + for i in 0..200 { + let r = Balances::transfer_allow_death(Some(1).into(), 1, i); + + if i <= 100 { + assert_ok!(r); + } else { + assert!(r.is_err()); + } + + assert!(events().is_empty()); + assert_eq!(Balances::free_balance(1), 100, "Balance unchanged by self transfer"); + assert_eq!( + pallet_balances::TotalIssuance::::get(), + 100, + "TI unchanged by self transfers" + ); + } + }); +} diff --git a/pallets/balances/src/tests/dispatchable_tests.rs b/pallets/balances/src/tests/dispatchable_tests.rs new file mode 100644 index 000000000..77e44202e --- /dev/null +++ b/pallets/balances/src/tests/dispatchable_tests.rs @@ -0,0 +1,384 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests regarding the functionality of the dispatchables/extrinsics. + +use super::*; +use crate::{ + AdjustmentDirection::{Decrease as Dec, Increase as Inc}, + Event, +}; +use frame_support::traits::{fungible::Unbalanced, tokens::Preservation::Expendable}; +use fungible::{hold::Mutate as HoldMutate, Inspect, Mutate}; + +/// Alice account ID for more readable tests. +const ALICE: u64 = 1; + +#[test] +fn default_indexing_on_new_accounts_should_not_work2() { + ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .build_and_execute_with(|| { + // account 5 should not exist + // ext_deposit is 10, value is 9, not satisfies for ext_deposit + assert_noop!( + Balances::transfer_allow_death(Some(1).into(), 5, 9), + TokenError::BelowMinimum, + ); + assert_eq!(Balances::free_balance(1), 100); + }); +} + +#[test] +fn dust_account_removal_should_work() { + ExtBuilder::default() + .existential_deposit(100) + .monied(true) + .build_and_execute_with(|| { + System::inc_account_nonce(&2); + assert_eq!(System::account_nonce(&2), 1); + assert_eq!(Balances::total_balance(&2), 2000); + // index 1 (account 2) becomes zombie + assert_ok!(Balances::transfer_allow_death(Some(2).into(), 5, 1901)); + assert_eq!(Balances::total_balance(&2), 0); + assert_eq!(Balances::total_balance(&5), 1901); + assert_eq!(System::account_nonce(&2), 0); + }); +} + +#[test] +fn balance_transfer_works() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::mint_into(&1, 111); + assert_ok!(Balances::transfer_allow_death(Some(1).into(), 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); +} + +#[test] +fn force_transfer_works() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::mint_into(&1, 111); + assert_noop!(Balances::force_transfer(Some(2).into(), 1, 2, 69), BadOrigin,); + assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); +} + +#[test] +fn balance_transfer_when_on_hold_should_not_work() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::mint_into(&1, 111); + assert_ok!(Balances::hold(&TestId::Foo, &1, 69)); + assert_noop!( + Balances::transfer_allow_death(Some(1).into(), 2, 69), + TokenError::FundsUnavailable, + ); + }); +} + +#[test] +fn transfer_keep_alive_works() { + ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { + let _ = Balances::mint_into(&1, 100); + assert_noop!( + Balances::transfer_keep_alive(Some(1).into(), 2, 100), + TokenError::NotExpendable + ); + assert_eq!(Balances::total_balance(&1), 100); + assert_eq!(Balances::total_balance(&2), 0); + }); +} + +#[test] +fn transfer_keep_alive_all_free_succeed() { + ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 300)); + assert_ok!(Balances::hold(&TestId::Foo, &1, 100)); + assert_ok!(Balances::transfer_keep_alive(Some(1).into(), 2, 100)); + assert_eq!(Balances::total_balance(&1), 200); + assert_eq!(Balances::total_balance(&2), 100); + }); +} + +#[test] +fn transfer_all_works_1() { + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + // setup + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 200)); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); + // transfer all and allow death + assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); + assert_eq!(Balances::total_balance(&1), 0); + assert_eq!(Balances::total_balance(&2), 200); + }); +} + +#[test] +fn transfer_all_works_2() { + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + // setup + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 200)); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); + // transfer all and keep alive + assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); + assert_eq!(Balances::total_balance(&1), 100); + assert_eq!(Balances::total_balance(&2), 100); + }); +} + +#[test] +fn transfer_all_works_3() { + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + // setup + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 210)); + assert_ok!(Balances::hold(&TestId::Foo, &1, 10)); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); + // transfer all and allow death w/ reserved + assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); + assert_eq!(Balances::total_balance(&1), 110); + assert_eq!(Balances::total_balance(&2), 100); + }); +} + +#[test] +fn transfer_all_works_4() { + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + // setup + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 210)); + assert_ok!(Balances::hold(&TestId::Foo, &1, 10)); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); + // transfer all and keep alive w/ reserved + assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); + assert_eq!(Balances::total_balance(&1), 110); + assert_eq!(Balances::total_balance(&2), 100); + }); +} + +#[test] +fn set_balance_handles_killing_account() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::mint_into(&1, 111); + assert_ok!(frame_system::Pallet::::inc_consumers(&1)); + assert_noop!( + Balances::force_set_balance(RuntimeOrigin::root(), 1, 0), + DispatchError::ConsumerRemaining, + ); + }); +} + +#[test] +fn set_balance_handles_total_issuance() { + ExtBuilder::default().build_and_execute_with(|| { + let old_total_issuance = pallet_balances::TotalIssuance::::get(); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 69)); + assert_eq!(pallet_balances::TotalIssuance::::get(), old_total_issuance + 69); + assert_eq!(Balances::total_balance(&1337), 69); + assert_eq!(Balances::free_balance(&1337), 69); + }); +} + +#[test] +fn upgrade_accounts_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + System::inc_providers(&7); + assert_ok!(::AccountStore::try_mutate_exists( + &7, + |a| -> DispatchResult { + *a = Some(AccountData { + free: 5, + reserved: 5, + frozen: Zero::zero(), + flags: crate::types::ExtraFlags::old_logic(), + }); + Ok(()) + } + )); + assert!(!Balances::account(&7).flags.is_new_logic()); + assert_eq!(System::providers(&7), 1); + assert_eq!(System::consumers(&7), 0); + assert_ok!(Balances::upgrade_accounts(Some(1).into(), vec![7])); + assert!(Balances::account(&7).flags.is_new_logic()); + assert_eq!(System::providers(&7), 1); + assert_eq!(System::consumers(&7), 1); + + >::unreserve(&7, 5); + assert_ok!(>::transfer(&7, &1, 10, Expendable)); + assert_eq!(Balances::total_balance(&7), 0); + assert_eq!(System::providers(&7), 0); + assert_eq!(System::consumers(&7), 0); + }); +} + +#[test] +#[docify::export] +fn force_adjust_total_issuance_example() { + ExtBuilder::default().build_and_execute_with(|| { + // First we set the TotalIssuance to 64 by giving Alice a balance of 64. + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), ALICE, 64)); + let old_ti = pallet_balances::TotalIssuance::::get(); + assert_eq!(old_ti, 64, "TI should be 64"); + + // Now test the increase: + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 32)); + let new_ti = pallet_balances::TotalIssuance::::get(); + assert_eq!(old_ti + 32, new_ti, "Should increase by 32"); + + // If Alice tries to call it, it errors: + assert_noop!( + Balances::force_adjust_total_issuance(RawOrigin::Signed(ALICE).into(), Inc, 32), + BadOrigin, + ); + }); +} + +#[test] +fn force_adjust_total_issuance_works() { + ExtBuilder::default().build_and_execute_with(|| { + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 64)); + let ti = pallet_balances::TotalIssuance::::get(); + + // Increase works: + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 32)); + assert_eq!(pallet_balances::TotalIssuance::::get(), ti + 32); + System::assert_last_event(RuntimeEvent::Balances(Event::TotalIssuanceForced { + old: 64, + new: 96, + })); + + // Decrease works: + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 64)); + assert_eq!(pallet_balances::TotalIssuance::::get(), ti - 32); + System::assert_last_event(RuntimeEvent::Balances(Event::TotalIssuanceForced { + old: 96, + new: 32, + })); + }); +} + +#[test] +fn force_adjust_total_issuance_saturates() { + ExtBuilder::default().build_and_execute_with(|| { + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 64)); + let ti = pallet_balances::TotalIssuance::::get(); + let max = ::Balance::max_value(); + assert_eq!(ti, 64); + + // Increment saturates: + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, max)); + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 123)); + assert_eq!(pallet_balances::TotalIssuance::::get(), max); + + // Decrement saturates: + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, max)); + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 123)); + assert_eq!(pallet_balances::TotalIssuance::::get(), 0); + }); +} + +#[test] +fn force_adjust_total_issuance_rejects_zero_delta() { + ExtBuilder::default().build_and_execute_with(|| { + assert_noop!( + Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 0), + Error::::DeltaZero, + ); + assert_noop!( + Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 0), + Error::::DeltaZero, + ); + }); +} + +#[test] +fn force_adjust_total_issuance_rejects_more_than_inactive() { + ExtBuilder::default().build_and_execute_with(|| { + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 64)); + Balances::deactivate(16u32.into()); + + assert_eq!(pallet_balances::TotalIssuance::::get(), 64); + assert_eq!(Balances::active_issuance(), 48); + + // Works with up to 48: + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 40),); + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 8),); + assert_eq!(pallet_balances::TotalIssuance::::get(), 16); + assert_eq!(Balances::active_issuance(), 0); + // Errors with more than 48: + assert_noop!( + Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 1), + Error::::IssuanceDeactivated, + ); + // Increasing again increases the inactive issuance: + assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 10),); + assert_eq!(pallet_balances::TotalIssuance::::get(), 26); + assert_eq!(Balances::active_issuance(), 10); + }); +} + +#[test] +fn burn_works() { + ExtBuilder::default().build().execute_with(|| { + // Prepare account with initial balance + let (account, init_balance) = (1, 37); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), account, init_balance)); + let init_issuance = pallet_balances::TotalIssuance::::get(); + let (keep_alive, allow_death) = (true, false); + + // 1. Cannot burn more than what's available + assert_noop!( + Balances::burn(Some(account).into(), init_balance + 1, allow_death), + TokenError::FundsUnavailable, + ); + + // 2. Burn some funds, without reaping the account + let burn_amount_1 = 1; + assert_ok!(Balances::burn(Some(account).into(), burn_amount_1, allow_death)); + System::assert_last_event(RuntimeEvent::Balances(Event::Burned { + who: account, + amount: burn_amount_1, + })); + assert_eq!(pallet_balances::TotalIssuance::::get(), init_issuance - burn_amount_1); + assert_eq!(Balances::total_balance(&account), init_balance - burn_amount_1); + + // 3. Cannot burn funds below existential deposit if `keep_alive` is `true` + let burn_amount_2 = + init_balance - burn_amount_1 - ::ExistentialDeposit::get() + 1; + assert_noop!( + Balances::burn(Some(account).into(), init_balance + 1, keep_alive), + TokenError::FundsUnavailable, + ); + + // 4. Burn some more funds, this time reaping the account + assert_ok!(Balances::burn(Some(account).into(), burn_amount_2, allow_death)); + System::assert_last_event(RuntimeEvent::Balances(Event::Burned { + who: account, + amount: burn_amount_2, + })); + assert_eq!( + pallet_balances::TotalIssuance::::get(), + init_issuance - burn_amount_1 - burn_amount_2 + ); + assert!(Balances::total_balance(&account).is_zero()); + }); +} diff --git a/pallets/balances/src/tests/fungible_conformance_tests.rs b/pallets/balances/src/tests/fungible_conformance_tests.rs new file mode 100644 index 000000000..5c0c19a55 --- /dev/null +++ b/pallets/balances/src/tests/fungible_conformance_tests.rs @@ -0,0 +1,141 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::*; +use frame_support::traits::fungible::{conformance_tests, Inspect, Mutate}; +use paste::paste; + +macro_rules! generate_tests { + // Handle a conformance test that requires special testing with and without a dust trap. + (dust_trap_variation, $base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { + $( + paste! { + #[test] + fn [<$trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_on >]() { + // Some random trap account. + let trap_account = ::AccountId::from(65174286u64); + let builder = ExtBuilder::default().existential_deposit($ext_deposit).dust_trap(trap_account); + builder.build_and_execute_with(|| { + Balances::set_balance(&trap_account, Balances::minimum_balance()); + $base_path::$scope::$trait::$test_name::< + Balances, + ::AccountId, + >(Some(trap_account)); + }); + } + + #[test] + fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_off >]() { + let builder = ExtBuilder::default().existential_deposit($ext_deposit); + builder.build_and_execute_with(|| { + $base_path::$scope::$trait::$test_name::< + Balances, + ::AccountId, + >(None); + }); + } + } + )* + }; + // Regular conformance test + ($base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { + $( + paste! { + #[test] + fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit>]() { + let builder = ExtBuilder::default().existential_deposit($ext_deposit); + builder.build_and_execute_with(|| { + $base_path::$scope::$trait::$test_name::< + Balances, + ::AccountId, + >(); + }); + } + } + )* + }; + ($base_path:path, $ext_deposit:expr) => { + // regular::mutate + generate_tests!( + dust_trap_variation, + $base_path, + regular, + mutate, + $ext_deposit, + transfer_expendable_dust + ); + generate_tests!( + $base_path, + regular, + mutate, + $ext_deposit, + mint_into_success, + mint_into_overflow, + mint_into_below_minimum, + burn_from_exact_success, + burn_from_best_effort_success, + burn_from_exact_insufficient_funds, + restore_success, + restore_overflow, + restore_below_minimum, + shelve_success, + shelve_insufficient_funds, + transfer_success, + transfer_expendable_all, + transfer_protect_preserve, + set_balance_mint_success, + set_balance_burn_success, + can_deposit_success, + can_deposit_below_minimum, + can_deposit_overflow, + can_withdraw_success, + can_withdraw_reduced_to_zero, + can_withdraw_balance_low, + reducible_balance_expendable, + reducible_balance_protect_preserve + ); + // regular::unbalanced + generate_tests!( + $base_path, + regular, + unbalanced, + $ext_deposit, + write_balance, + decrease_balance_expendable, + decrease_balance_preserve, + increase_balance, + set_total_issuance, + deactivate_and_reactivate + ); + // regular::balanced + generate_tests!( + $base_path, + regular, + balanced, + $ext_deposit, + issue_and_resolve_credit, + rescind_and_settle_debt, + deposit, + withdraw, + pair + ); + }; +} + +generate_tests!(conformance_tests, 1); +generate_tests!(conformance_tests, 5); +generate_tests!(conformance_tests, 1000); diff --git a/pallets/balances/src/tests/fungible_tests.rs b/pallets/balances/src/tests/fungible_tests.rs new file mode 100644 index 000000000..4a8b213c6 --- /dev/null +++ b/pallets/balances/src/tests/fungible_tests.rs @@ -0,0 +1,670 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests regarding the functionality of the `fungible` trait set implementations. + +use super::*; +use frame_support::traits::{ + tokens::{ + Fortitude::{Force, Polite}, + Precision::{BestEffort, Exact}, + Preservation::{Expendable, Preserve, Protect}, + Restriction::Free, + }, + Consideration, Footprint, LinearStoragePrice, MaybeConsideration, +}; +use fungible::{ + FreezeConsideration, HoldConsideration, Inspect, InspectFreeze, InspectHold, + LoneFreezeConsideration, LoneHoldConsideration, Mutate, MutateFreeze, MutateHold, Unbalanced, +}; +use sp_core::ConstU64; + +#[test] +fn inspect_trait_reducible_balance_basic_works() { + ExtBuilder::default().existential_deposit(10).build_and_execute_with(|| { + Balances::set_balance(&1, 100); + assert_eq!(Balances::reducible_balance(&1, Expendable, Polite), 100); + assert_eq!(Balances::reducible_balance(&1, Protect, Polite), 90); + assert_eq!(Balances::reducible_balance(&1, Preserve, Polite), 90); + assert_eq!(Balances::reducible_balance(&1, Expendable, Force), 100); + assert_eq!(Balances::reducible_balance(&1, Protect, Force), 90); + assert_eq!(Balances::reducible_balance(&1, Preserve, Force), 90); + }); +} + +#[test] +fn inspect_trait_reducible_balance_other_provide_works() { + ExtBuilder::default().existential_deposit(10).build_and_execute_with(|| { + Balances::set_balance(&1, 100); + System::inc_providers(&1); + assert_eq!(Balances::reducible_balance(&1, Expendable, Polite), 100); + assert_eq!(Balances::reducible_balance(&1, Protect, Polite), 100); + assert_eq!(Balances::reducible_balance(&1, Preserve, Polite), 90); + assert_eq!(Balances::reducible_balance(&1, Expendable, Force), 100); + assert_eq!(Balances::reducible_balance(&1, Protect, Force), 100); + assert_eq!(Balances::reducible_balance(&1, Preserve, Force), 90); + }); +} + +#[test] +fn inspect_trait_reducible_balance_frozen_works() { + ExtBuilder::default().existential_deposit(10).build_and_execute_with(|| { + Balances::set_balance(&1, 100); + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 50)); + assert_eq!(Balances::reducible_balance(&1, Expendable, Polite), 50); + assert_eq!(Balances::reducible_balance(&1, Protect, Polite), 50); + assert_eq!(Balances::reducible_balance(&1, Preserve, Polite), 50); + assert_eq!(Balances::reducible_balance(&1, Expendable, Force), 90); + assert_eq!(Balances::reducible_balance(&1, Protect, Force), 90); + assert_eq!(Balances::reducible_balance(&1, Preserve, Force), 90); + }); +} + +#[test] +fn unbalanced_trait_set_balance_works() { + ExtBuilder::default().build_and_execute_with(|| { + assert_eq!(>::balance(&1337), 0); + assert_ok!(Balances::write_balance(&1337, 100)); + assert_eq!(>::balance(&1337), 100); + + assert_ok!(>::hold(&TestId::Foo, &1337, 60)); + assert_eq!(>::balance(&1337), 40); + assert_eq!(>::total_balance_on_hold(&1337), 60); + assert_eq!( + >::balance_on_hold(&TestId::Foo, &1337), + 60 + ); + + assert_noop!(Balances::write_balance(&1337, 0), Error::::InsufficientBalance); + + assert_ok!(Balances::write_balance(&1337, 1)); + assert_eq!(>::balance(&1337), 1); + assert_eq!( + >::balance_on_hold(&TestId::Foo, &1337), + 60 + ); + + assert_ok!(>::release(&TestId::Foo, &1337, 60, Exact)); + assert_eq!(>::balance_on_hold(&TestId::Foo, &1337), 0); + assert_eq!(>::total_balance_on_hold(&1337), 0); + }); +} + +#[test] +fn unbalanced_trait_set_total_issuance_works() { + ExtBuilder::default().build_and_execute_with(|| { + assert_eq!(>::total_issuance(), 0); + Balances::set_total_issuance(100); + assert_eq!(>::total_issuance(), 100); + }); +} + +#[test] +fn unbalanced_trait_decrease_balance_simple_works() { + ExtBuilder::default().build_and_execute_with(|| { + // An Account that starts at 100 + assert_ok!(Balances::write_balance(&1337, 100)); + assert_eq!(>::balance(&1337), 100); + // and reserves 50 + assert_ok!(>::hold(&TestId::Foo, &1337, 50)); + assert_eq!(>::balance(&1337), 50); + // and is decreased by 20 + assert_ok!(Balances::decrease_balance(&1337, 20, Exact, Expendable, Polite)); + assert_eq!(>::balance(&1337), 30); + }); +} + +#[test] +fn unbalanced_trait_decrease_balance_works_1() { + ExtBuilder::default().build_and_execute_with(|| { + assert_ok!(Balances::write_balance(&1337, 100)); + assert_eq!(>::balance(&1337), 100); + + assert_noop!( + Balances::decrease_balance(&1337, 101, Exact, Expendable, Polite), + TokenError::FundsUnavailable + ); + assert_eq!(Balances::decrease_balance(&1337, 100, Exact, Expendable, Polite), Ok(100)); + assert_eq!(>::balance(&1337), 0); + }); +} + +#[test] +fn unbalanced_trait_decrease_balance_works_2() { + ExtBuilder::default().build_and_execute_with(|| { + // free: 40, reserved: 60 + assert_ok!(Balances::write_balance(&1337, 100)); + assert_ok!(Balances::hold(&TestId::Foo, &1337, 60)); + assert_eq!(>::balance(&1337), 40); + assert_eq!(Balances::total_balance_on_hold(&1337), 60); + assert_noop!( + Balances::decrease_balance(&1337, 40, Exact, Expendable, Polite), + TokenError::FundsUnavailable + ); + assert_eq!(Balances::decrease_balance(&1337, 39, Exact, Expendable, Polite), Ok(39)); + assert_eq!(>::balance(&1337), 1); + assert_eq!(Balances::total_balance_on_hold(&1337), 60); + }); +} + +#[test] +fn unbalanced_trait_decrease_balance_at_most_works_1() { + ExtBuilder::default().build_and_execute_with(|| { + assert_ok!(Balances::write_balance(&1337, 100)); + assert_eq!(>::balance(&1337), 100); + + assert_eq!(Balances::decrease_balance(&1337, 101, BestEffort, Expendable, Polite), Ok(100)); + assert_eq!(>::balance(&1337), 0); + }); +} + +#[test] +fn unbalanced_trait_decrease_balance_at_most_works_2() { + ExtBuilder::default().build_and_execute_with(|| { + assert_ok!(Balances::write_balance(&1337, 99)); + assert_eq!(Balances::decrease_balance(&1337, 99, BestEffort, Expendable, Polite), Ok(99)); + assert_eq!(>::balance(&1337), 0); + }); +} + +#[test] +fn unbalanced_trait_decrease_balance_at_most_works_3() { + ExtBuilder::default().build_and_execute_with(|| { + // free: 40, reserved: 60 + assert_ok!(Balances::write_balance(&1337, 100)); + assert_ok!(Balances::hold(&TestId::Foo, &1337, 60)); + assert_eq!(Balances::free_balance(1337), 40); + assert_eq!(Balances::total_balance_on_hold(&1337), 60); + assert_eq!(Balances::decrease_balance(&1337, 0, BestEffort, Expendable, Polite), Ok(0)); + assert_eq!(Balances::free_balance(1337), 40); + assert_eq!(Balances::total_balance_on_hold(&1337), 60); + assert_eq!(Balances::decrease_balance(&1337, 10, BestEffort, Expendable, Polite), Ok(10)); + assert_eq!(Balances::free_balance(1337), 30); + assert_eq!(Balances::decrease_balance(&1337, 200, BestEffort, Expendable, Polite), Ok(29)); + assert_eq!(>::balance(&1337), 1); + assert_eq!(Balances::free_balance(1337), 1); + assert_eq!(Balances::total_balance_on_hold(&1337), 60); + }); +} + +#[test] +fn unbalanced_trait_increase_balance_works() { + ExtBuilder::default().build_and_execute_with(|| { + assert_noop!(Balances::increase_balance(&1337, 0, Exact), TokenError::BelowMinimum); + assert_eq!(Balances::increase_balance(&1337, 1, Exact), Ok(1)); + assert_noop!(Balances::increase_balance(&1337, u64::MAX, Exact), ArithmeticError::Overflow); + }); +} + +#[test] +fn unbalanced_trait_increase_balance_at_most_works() { + ExtBuilder::default().build_and_execute_with(|| { + assert_eq!(Balances::increase_balance(&1337, 0, BestEffort), Ok(0)); + assert_eq!(Balances::increase_balance(&1337, 1, BestEffort), Ok(1)); + assert_eq!(Balances::increase_balance(&1337, u64::MAX, BestEffort), Ok(u64::MAX - 1)); + }); +} + +#[test] +fn freezing_and_holds_should_overlap() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); + assert_ok!(Balances::hold(&TestId::Foo, &1, 9)); + assert_eq!(Balances::account(&1).free, 1); + assert_eq!(System::consumers(&1), 1); + assert_eq!(Balances::account(&1).free, 1); + assert_eq!(Balances::account(&1).frozen, 10); + assert_eq!(Balances::account(&1).reserved, 9); + assert_eq!(Balances::total_balance_on_hold(&1), 9); + }); +} + +#[test] +fn frozen_hold_balance_cannot_be_moved_without_force() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); + assert_ok!(Balances::hold(&TestId::Foo, &1, 9)); + assert_eq!(Balances::reducible_total_balance_on_hold(&1, Force), 9); + assert_eq!(Balances::reducible_total_balance_on_hold(&1, Polite), 0); + let e = TokenError::Frozen; + assert_noop!( + Balances::transfer_on_hold(&TestId::Foo, &1, &2, 1, Exact, Free, Polite), + e + ); + assert_ok!(Balances::transfer_on_hold(&TestId::Foo, &1, &2, 1, Exact, Free, Force)); + }); +} + +#[test] +fn frozen_hold_balance_best_effort_transfer_works() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); + assert_ok!(Balances::hold(&TestId::Foo, &1, 9)); + assert_eq!(Balances::reducible_total_balance_on_hold(&1, Force), 9); + assert_eq!(Balances::reducible_total_balance_on_hold(&1, Polite), 5); + assert_ok!(Balances::transfer_on_hold( + &TestId::Foo, + &1, + &2, + 10, + BestEffort, + Free, + Polite + )); + assert_eq!(Balances::total_balance(&1), 5); + assert_eq!(Balances::total_balance(&2), 25); + }); +} + +#[test] +fn partial_freezing_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); + assert_eq!(System::consumers(&1), 1); + assert_ok!(>::transfer(&1, &2, 5, Expendable)); + assert_noop!( + >::transfer(&1, &2, 1, Expendable), + TokenError::Frozen + ); + }); +} + +#[test] +fn thaw_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, u64::MAX)); + assert_ok!(Balances::thaw(&TestId::Foo, &1)); + assert_eq!(System::consumers(&1), 0); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &1), 0); + assert_eq!(Balances::account(&1).frozen, 0); + assert_ok!(>::transfer(&1, &2, 10, Expendable)); + }); +} + +#[test] +fn set_freeze_zero_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, u64::MAX)); + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 0)); + assert_eq!(System::consumers(&1), 0); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &1), 0); + assert_eq!(Balances::account(&1).frozen, 0); + assert_ok!(>::transfer(&1, &2, 10, Expendable)); + }); +} + +#[test] +fn set_freeze_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, u64::MAX)); + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); + assert_ok!(>::transfer(&1, &2, 5, Expendable)); + assert_noop!( + >::transfer(&1, &2, 1, Expendable), + TokenError::Frozen + ); + }); +} + +#[test] +fn extend_freeze_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); + assert_ok!(Balances::extend_freeze(&TestId::Foo, &1, 10)); + assert_eq!(Balances::account(&1).frozen, 10); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &1), 10); + assert_noop!( + >::transfer(&1, &2, 1, Expendable), + TokenError::Frozen + ); + }); +} + +#[test] +fn double_freezing_should_work() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); + assert_ok!(Balances::set_freeze(&TestId::Bar, &1, 5)); + assert_eq!(System::consumers(&1), 1); + assert_ok!(>::transfer(&1, &2, 5, Expendable)); + assert_noop!( + >::transfer(&1, &2, 1, Expendable), + TokenError::Frozen + ); + }); +} + +#[test] +fn can_hold_entire_balance_when_second_provider() { + ExtBuilder::default() + .existential_deposit(1) + .monied(false) + .build_and_execute_with(|| { + >::set_balance(&1, 100); + assert_noop!(Balances::hold(&TestId::Foo, &1, 100), TokenError::FundsUnavailable); + System::inc_providers(&1); + assert_eq!(System::providers(&1), 2); + assert_ok!(Balances::hold(&TestId::Foo, &1, 100)); + assert_eq!(System::providers(&1), 1); + assert_noop!(System::dec_providers(&1), DispatchError::ConsumerRemaining); + }); +} + +#[test] +fn unholding_frees_hold_slot() { + ExtBuilder::default() + .existential_deposit(1) + .monied(false) + .build_and_execute_with(|| { + >::set_balance(&1, 100); + assert_ok!(Balances::hold(&TestId::Foo, &1, 10)); + assert_ok!(Balances::hold(&TestId::Bar, &1, 10)); + assert_ok!(Balances::release(&TestId::Foo, &1, 10, Exact)); + assert_ok!(Balances::hold(&TestId::Baz, &1, 10)); + }); +} + +#[test] +fn sufficients_work_properly_with_reference_counting() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + // Only run PoC when the system pallet is enabled, since the underlying bug is in the + // system pallet it won't work with BalancesAccountStore + if UseSystem::get() { + // Start with a balance of 100 + >::set_balance(&1, 100); + // Emulate a sufficient, in reality this could be reached by transferring a + // sufficient asset to the account + System::inc_sufficients(&1); + // Spend the same balance multiple times + assert_ok!(>::transfer(&1, &1337, 100, Expendable)); + assert_eq!(Balances::free_balance(&1), 0); + assert_noop!( + >::transfer(&1, &1337, 100, Expendable), + TokenError::FundsUnavailable + ); + } + }); +} + +#[test] +fn emit_events_with_changing_freezes() { + ExtBuilder::default().build_and_execute_with(|| { + let _ = Balances::set_balance(&1, 100); + System::reset_events(); + + // Freeze = [] --> [10] + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Frozen { who: 1, amount: 10 })]); + + // Freeze = [10] --> [15] + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 15)); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Frozen { who: 1, amount: 5 })]); + + // Freeze = [15] --> [15, 20] + assert_ok!(Balances::set_freeze(&TestId::Bar, &1, 20)); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Frozen { who: 1, amount: 5 })]); + + // Freeze = [15, 20] --> [17, 20] + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 17)); + for event in events() { + match event { + RuntimeEvent::Balances(crate::Event::Frozen { .. }) => { + assert!(false, "unexpected freeze event") + }, + RuntimeEvent::Balances(crate::Event::Thawed { .. }) => { + assert!(false, "unexpected thaw event") + }, + _ => continue, + } + } + + // Freeze = [17, 20] --> [17, 15] + assert_ok!(Balances::set_freeze(&TestId::Bar, &1, 15)); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Thawed { who: 1, amount: 3 })]); + + // Freeze = [17, 15] --> [15] + assert_ok!(Balances::thaw(&TestId::Foo, &1)); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Thawed { who: 1, amount: 2 })]); + + // Freeze = [15] --> [] + assert_ok!(Balances::thaw(&TestId::Bar, &1)); + assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Thawed { who: 1, amount: 15 })]); + }); +} + +#[test] +fn withdraw_precision_exact_works() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); + assert_eq!(Balances::account(&1).free, 10); + assert_eq!(Balances::account(&1).frozen, 10); + + // `BestEffort` will not reduce anything + assert_ok!(>::withdraw( + &1, 5, BestEffort, Preserve, Polite + )); + + assert_eq!(Balances::account(&1).free, 10); + assert_eq!(Balances::account(&1).frozen, 10); + + assert_noop!( + >::withdraw(&1, 5, Exact, Preserve, Polite), + TokenError::FundsUnavailable + ); + }); +} + +#[test] +fn freeze_consideration_works() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + type Consideration = FreezeConsideration< + u64, + Balances, + FooReason, + LinearStoragePrice, ConstU64<1>, u64>, + Footprint, + >; + + let who = 4; + // freeze amount taken somewhere outside of our (Consideration) scope. + let extend_freeze = 15; + + let ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); + assert!(ticket.is_none()); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); + + let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10); + + let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 4); + + assert_ok!(Balances::increase_frozen(&TestId::Foo, &who, extend_freeze)); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 4 + extend_freeze); + + let ticket = ticket.update(&who, Footprint::from_parts(8, 1)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 8 + extend_freeze); + + let ticket = ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(); + assert!(ticket.is_none()); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0 + extend_freeze); + + let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10 + extend_freeze); + + let _ = ticket.drop(&who).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0 + extend_freeze); + }); +} + +#[test] +fn hold_consideration_works() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + type Consideration = HoldConsideration< + u64, + Balances, + FooReason, + LinearStoragePrice, ConstU64<1>, u64>, + Footprint, + >; + + let who = 4; + // hold amount taken somewhere outside of our (Consideration) scope. + let extend_hold = 15; + + let ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); + assert!(ticket.is_none()); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); + + let ticket = ticket.update(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10); + + let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 4); + + assert_ok!(Balances::hold(&TestId::Foo, &who, extend_hold)); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 4 + extend_hold); + + let ticket = ticket.update(&who, Footprint::from_parts(8, 1)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 8 + extend_hold); + + let ticket = ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(); + assert!(ticket.is_none()); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0 + extend_hold); + + let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10 + extend_hold); + + let _ = ticket.drop(&who).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0 + extend_hold); + }); +} + +#[test] +fn lone_freeze_consideration_works() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + type Consideration = LoneFreezeConsideration< + u64, + Balances, + FooReason, + LinearStoragePrice, ConstU64<1>, u64>, + Footprint, + >; + + let who = 4; + let zero_ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); + + let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10); + + assert_ok!(Balances::increase_frozen(&TestId::Foo, &who, 5)); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 15); + + let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 4); + + assert_eq!(ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(), zero_ticket); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); + + let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10); + + let _ = ticket.drop(&who).unwrap(); + assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); + }); +} + +#[test] +fn lone_hold_consideration_works() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + type Consideration = LoneHoldConsideration< + u64, + Balances, + FooReason, + LinearStoragePrice, ConstU64<1>, u64>, + Footprint, + >; + + let who = 4; + let zero_ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); + + let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10); + + assert_ok!(Balances::hold(&TestId::Foo, &who, 5)); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 15); + + let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 4); + + assert_eq!(ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(), zero_ticket); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); + + let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10); + + let _ = ticket.drop(&who).unwrap(); + assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); + }); +} diff --git a/pallets/balances/src/tests/general_tests.rs b/pallets/balances/src/tests/general_tests.rs new file mode 100644 index 000000000..a855fae56 --- /dev/null +++ b/pallets/balances/src/tests/general_tests.rs @@ -0,0 +1,143 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +use crate::{ + system::AccountInfo, + tests::{ensure_ti_valid, Balances, ExtBuilder, System, Test, TestId, UseSystem}, + AccountData, ExtraFlags, TotalIssuance, +}; +use frame_support::{ + assert_noop, assert_ok, hypothetically, + traits::{ + fungible::{Mutate, MutateHold}, + tokens::Precision, + }, +}; +use sp_runtime::DispatchError; + +/// There are some accounts that have one consumer ref too few. These accounts are at risk of losing +/// their held (reserved) balance. They do not just lose it - it is also not accounted for in the +/// Total Issuance. Here we test the case that the account does not reap in such a case, but gets +/// one consumer ref for its reserved balance. +#[test] +fn regression_historic_acc_does_not_evaporate_reserve() { + ExtBuilder::default().build_and_execute_with(|| { + UseSystem::set(true); + let (alice, bob) = (0, 1); + // Alice is in a bad state with consumer == 0 && reserved > 0: + Balances::set_balance(&alice, 100); + TotalIssuance::::put(100); + ensure_ti_valid(); + + assert_ok!(Balances::hold(&TestId::Foo, &alice, 10)); + // This is the issue of the account: + System::dec_consumers(&alice); + + assert_eq!( + System::account(&alice), + AccountInfo { + data: AccountData { + free: 90, + reserved: 10, + frozen: 0, + flags: ExtraFlags(1u128 << 127), + }, + nonce: 0, + consumers: 0, // should be 1 on a good acc + providers: 1, + sufficients: 0, + } + ); + + ensure_ti_valid(); + + // Reaping the account is prevented by the new logic: + assert_noop!( + Balances::transfer_allow_death(Some(alice).into(), bob, 90), + DispatchError::ConsumerRemaining + ); + assert_noop!( + Balances::transfer_all(Some(alice).into(), bob, false), + DispatchError::ConsumerRemaining + ); + + // normal transfers still work: + hypothetically!({ + assert_ok!(Balances::transfer_keep_alive(Some(alice).into(), bob, 40)); + // Alice got back her consumer ref: + assert_eq!(System::consumers(&alice), 1); + ensure_ti_valid(); + }); + hypothetically!({ + assert_ok!(Balances::transfer_all(Some(alice).into(), bob, true)); + // Alice got back her consumer ref: + assert_eq!(System::consumers(&alice), 1); + ensure_ti_valid(); + }); + + // un-reserving all does not add a consumer ref: + hypothetically!({ + assert_ok!(Balances::release(&TestId::Foo, &alice, 10, Precision::Exact)); + assert_eq!(System::consumers(&alice), 0); + assert_ok!(Balances::transfer_keep_alive(Some(alice).into(), bob, 40)); + assert_eq!(System::consumers(&alice), 0); + ensure_ti_valid(); + }); + // un-reserving some does add a consumer ref: + hypothetically!({ + assert_ok!(Balances::release(&TestId::Foo, &alice, 5, Precision::Exact)); + assert_eq!(System::consumers(&alice), 1); + assert_ok!(Balances::transfer_keep_alive(Some(alice).into(), bob, 40)); + assert_eq!(System::consumers(&alice), 1); + ensure_ti_valid(); + }); + }); +} + +#[cfg(feature = "try-runtime")] +#[test] +fn try_state_works() { + use crate::{Config, Freezes, Holds}; + use frame_support::{ + storage, + traits::{Get, Hooks, VariantCount}, + }; + + ExtBuilder::default().build_and_execute_with(|| { + storage::unhashed::put( + &Holds::::hashed_key_for(1), + &vec![0u8; ::RuntimeHoldReason::VARIANT_COUNT as usize + 1], + ); + + assert!(format!("{:?}", Balances::try_state(0).unwrap_err()) + .contains("Found `Hold` with too many elements")); + }); + + ExtBuilder::default().build_and_execute_with(|| { + let max_freezes: u32 = ::MaxFreezes::get(); + + storage::unhashed::put( + &Freezes::::hashed_key_for(1), + &vec![0u8; max_freezes as usize + 1], + ); + + assert!(format!("{:?}", Balances::try_state(0).unwrap_err()) + .contains("Found `Freeze` with too many elements")); + }); +} diff --git a/pallets/balances/src/tests/mod.rs b/pallets/balances/src/tests/mod.rs new file mode 100644 index 000000000..d27d99758 --- /dev/null +++ b/pallets/balances/src/tests/mod.rs @@ -0,0 +1,351 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests. + +#![cfg(test)] + +use crate::{ + self as pallet_balances, AccountData, Config, CreditOf, Error, Pallet, TotalIssuance, + DEFAULT_ADDRESS_URI, +}; +use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen}; +use frame_support::{ + assert_err, assert_noop, assert_ok, assert_storage_noop, derive_impl, + dispatch::{DispatchInfo, GetDispatchInfo}, + parameter_types, + traits::{ + fungible, ConstU32, ConstU8, Imbalance as ImbalanceT, OnUnbalanced, StorageMapShim, + StoredMap, VariantCount, VariantCountOf, WhitelistedStorageKeys, + }, + weights::{IdentityFee, Weight}, +}; +use frame_system::{self as system, RawOrigin}; +use pallet_transaction_payment::{ChargeTransactionPayment, FungibleAdapter, Multiplier}; +use scale_info::TypeInfo; +use sp_core::{hexdisplay::HexDisplay, sr25519::Pair as SrPair, Pair}; +use sp_io; +use sp_runtime::{ + traits::{BadOrigin, Zero}, + ArithmeticError, BuildStorage, DispatchError, DispatchResult, FixedPointNumber, RuntimeDebug, + TokenError, +}; +use std::collections::BTreeSet; + +mod currency_tests; +mod dispatchable_tests; +mod fungible_conformance_tests; +mod fungible_tests; +mod general_tests; +mod reentrancy_tests; + +type Block = frame_system::mocking::MockBlock; + +#[derive( + Encode, + Decode, + DecodeWithMemTracking, + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + MaxEncodedLen, + TypeInfo, + RuntimeDebug, +)] +pub enum TestId { + Foo, + Bar, + Baz, +} + +impl VariantCount for TestId { + const VARIANT_COUNT: u32 = 3; +} + +frame_support::construct_runtime!( + pub enum Test { + System: frame_system, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, + } +); + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max( + frame_support::weights::Weight::from_parts(1024, u64::MAX), + ); + pub static ExistentialDeposit: u64 = 1; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; + type AccountData = super::AccountData; +} + +#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig)] +impl pallet_transaction_payment::Config for Test { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = FungibleAdapter, ()>; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = IdentityFee; +} + +parameter_types! { + pub FooReason: TestId = TestId::Foo; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl Config for Test { + type DustRemoval = DustTrap; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = TestAccountStore; + type MaxReserves = ConstU32<2>; + type ReserveIdentifier = TestId; + type RuntimeHoldReason = TestId; + type RuntimeFreezeReason = TestId; + type FreezeIdentifier = TestId; + type MaxFreezes = VariantCountOf; +} + +#[derive(Clone)] +pub struct ExtBuilder { + existential_deposit: u64, + monied: bool, + dust_trap: Option, +} +impl Default for ExtBuilder { + fn default() -> Self { + Self { existential_deposit: 1, monied: false, dust_trap: None } + } +} +impl ExtBuilder { + pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { + self.existential_deposit = existential_deposit; + self + } + pub fn monied(mut self, monied: bool) -> Self { + self.monied = monied; + if self.existential_deposit == 0 { + self.existential_deposit = 1; + } + self + } + pub fn dust_trap(mut self, account: u64) -> Self { + self.dust_trap = Some(account); + self + } + pub fn set_associated_consts(&self) { + DUST_TRAP_TARGET.with(|v| v.replace(self.dust_trap)); + EXISTENTIAL_DEPOSIT.with(|v| v.replace(self.existential_deposit)); + } + pub fn build(self) -> sp_io::TestExternalities { + self.set_associated_consts(); + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: if self.monied { + vec![ + (1, 10 * self.existential_deposit), + (2, 20 * self.existential_deposit), + (3, 30 * self.existential_deposit), + (4, 40 * self.existential_deposit), + (12, 10 * self.existential_deposit), + ] + } else { + vec![] + }, + dev_accounts: Some(( + 1000, + self.existential_deposit, + Some(DEFAULT_ADDRESS_URI.to_string()), + )), + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } + pub fn build_and_execute_with(self, f: impl Fn()) { + let other = self.clone(); + UseSystem::set(false); + other.build().execute_with(|| f()); + UseSystem::set(true); + self.build().execute_with(|| f()); + } +} + +parameter_types! { + static DustTrapTarget: Option = None; +} + +pub struct DustTrap; + +impl OnUnbalanced> for DustTrap { + fn on_nonzero_unbalanced(amount: CreditOf) { + match DustTrapTarget::get() { + None => drop(amount), + Some(a) => { + let result = >::resolve(&a, amount); + debug_assert!(result.is_ok()); + }, + } + } +} + +parameter_types! { + pub static UseSystem: bool = false; +} + +type BalancesAccountStore = StorageMapShim, u64, super::AccountData>; +type SystemAccountStore = frame_system::Pallet; + +pub struct TestAccountStore; +impl StoredMap> for TestAccountStore { + fn get(k: &u64) -> super::AccountData { + if UseSystem::get() { + >::get(k) + } else { + >::get(k) + } + } + fn try_mutate_exists>( + k: &u64, + f: impl FnOnce(&mut Option>) -> Result, + ) -> Result { + if UseSystem::get() { + >::try_mutate_exists(k, f) + } else { + >::try_mutate_exists(k, f) + } + } + fn mutate( + k: &u64, + f: impl FnOnce(&mut super::AccountData) -> R, + ) -> Result { + if UseSystem::get() { + >::mutate(k, f) + } else { + >::mutate(k, f) + } + } + fn mutate_exists( + k: &u64, + f: impl FnOnce(&mut Option>) -> R, + ) -> Result { + if UseSystem::get() { + >::mutate_exists(k, f) + } else { + >::mutate_exists(k, f) + } + } + fn insert(k: &u64, t: super::AccountData) -> Result<(), DispatchError> { + if UseSystem::get() { + >::insert(k, t) + } else { + >::insert(k, t) + } + } + fn remove(k: &u64) -> Result<(), DispatchError> { + if UseSystem::get() { + >::remove(k) + } else { + >::remove(k) + } + } +} + +pub fn events() -> Vec { + let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + System::reset_events(); + evt +} + +/// create a transaction info struct from weight. Handy to avoid building the whole struct. +pub fn info_from_weight(w: Weight) -> DispatchInfo { + DispatchInfo { call_weight: w, ..Default::default() } +} + +/// Check that the total-issuance matches the sum of all accounts' total balances. +pub fn ensure_ti_valid() { + let mut sum = 0; + + // Fetch the dev accounts from Account Storage. + let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, DEFAULT_ADDRESS_URI.to_string()); + let (num_accounts, _balance, ref derivation) = dev_accounts; + + // Generate the dev account public keys. + let dev_account_ids: Vec<_> = (0..num_accounts) + .map(|index| { + let derivation_string = derivation.replace("{}", &index.to_string()); + let pair: SrPair = + Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); + ::AccountId::decode( + &mut &pair.public().encode()[..], + ) + .unwrap() + }) + .collect(); + + // Iterate over all account keys (i.e., the account IDs). + for acc in frame_system::Account::::iter_keys() { + // Skip dev accounts by checking if the account is in the dev_account_ids list. + // This also proves dev_accounts exists in storage. + if dev_account_ids.contains(&acc) { + continue; + } + + // Check if we are using the system pallet or some other custom storage for accounts. + if UseSystem::get() { + let data = frame_system::Pallet::::account(acc); + sum += data.data.total(); + } else { + let data = crate::Account::::get(acc); + sum += data.total(); + } + } + + // Ensure the total issuance matches the sum of the account balances + assert_eq!(TotalIssuance::::get(), sum, "Total Issuance is incorrect"); +} + +#[test] +fn weights_sane() { + let info = crate::Call::::transfer_allow_death { dest: 10, value: 4 }.get_dispatch_info(); + assert_eq!(<() as crate::WeightInfo>::transfer_allow_death(), info.call_weight); + + let info = crate::Call::::force_unreserve { who: 10, amount: 4 }.get_dispatch_info(); + assert_eq!(<() as crate::WeightInfo>::force_unreserve(), info.call_weight); +} + +#[test] +fn check_whitelist() { + let whitelist: BTreeSet = AllPalletsWithSystem::whitelisted_storage_keys() + .iter() + .map(|s| HexDisplay::from(&s.key).to_string()) + .collect(); + // Inactive Issuance + assert!(whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f1ccde6872881f893a21de93dfe970cd5")); + // Total Issuance + assert!(whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")); +} diff --git a/pallets/balances/src/tests/reentrancy_tests.rs b/pallets/balances/src/tests/reentrancy_tests.rs new file mode 100644 index 000000000..0b66f2c93 --- /dev/null +++ b/pallets/balances/src/tests/reentrancy_tests.rs @@ -0,0 +1,196 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests regarding the reentrancy functionality. + +use super::*; +use frame_support::traits::tokens::{ + Fortitude::Force, + Precision::BestEffort, + Preservation::{Expendable, Protect}, +}; +use fungible::Balanced; + +#[test] +fn transfer_dust_removal_tst1_should_work() { + ExtBuilder::default() + .existential_deposit(100) + .dust_trap(1) + .build_and_execute_with(|| { + // Verification of reentrancy in dust removal + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 1000)); + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 2, 500)); + + // In this transaction, account 2 free balance + // drops below existential balance + // and dust balance is removed from account 2 + assert_ok!(Balances::transfer_allow_death(RawOrigin::Signed(2).into(), 3, 450)); + + // As expected dust balance is removed. + assert_eq!(Balances::free_balance(&2), 0); + + // As expected beneficiary account 3 + // received the transferred fund. + assert_eq!(Balances::free_balance(&3), 450); + + // Dust balance is deposited to account 1 + // during the process of dust removal. + assert_eq!(Balances::free_balance(&1), 1050); + + // Verify the events + assert_eq!(System::events().len(), 14); + + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { + from: 2, + to: 3, + amount: 450, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { + account: 2, + amount: 50, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { + who: 1, + amount: 50, + })); + }); +} + +#[test] +fn transfer_dust_removal_tst2_should_work() { + ExtBuilder::default() + .existential_deposit(100) + .dust_trap(1) + .build_and_execute_with(|| { + // Verification of reentrancy in dust removal + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 1000)); + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 2, 500)); + + // In this transaction, account 2 free balance + // drops below existential balance + // and dust balance is removed from account 2 + assert_ok!(Balances::transfer_allow_death(RawOrigin::Signed(2).into(), 1, 450)); + + // As expected dust balance is removed. + assert_eq!(Balances::free_balance(&2), 0); + + // Dust balance is deposited to account 1 + // during the process of dust removal. + assert_eq!(Balances::free_balance(&1), 1500); + + // Verify the events + assert_eq!(System::events().len(), 12); + + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { + from: 2, + to: 1, + amount: 450, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { + account: 2, + amount: 50, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { + who: 1, + amount: 50, + })); + }); +} + +#[test] +fn repatriating_reserved_balance_dust_removal_should_work() { + ExtBuilder::default() + .existential_deposit(100) + .dust_trap(1) + .build_and_execute_with(|| { + // Verification of reentrancy in dust removal + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 1000)); + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 2, 500)); + + // Reserve a value on account 2, + // Such that free balance is lower than + // Existential deposit. + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), 1, 450)); + + // Since free balance of account 2 is lower than + // existential deposit, dust amount is + // removed from the account 2 + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 0); + + // account 1 is credited with reserved amount + // together with dust balance during dust + // removal. + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 1500); + + // Verify the events + assert_eq!(System::events().len(), 12); + + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { + from: 2, + to: 1, + amount: 450, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { + account: 2, + amount: 50, + })); + System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { + who: 1, + amount: 50, + })); + }); +} + +#[test] +fn emit_events_with_no_existential_deposit_suicide_with_dust() { + ExtBuilder::default().existential_deposit(2).build_and_execute_with(|| { + assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 100)); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::NewAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), + RuntimeEvent::Balances(crate::Event::Issued { amount: 100 }), + RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100 }), + ] + ); + + let res = Balances::withdraw(&1, 98, BestEffort, Protect, Force); + assert_eq!(res.unwrap().peek(), 98); + + // no events + assert_eq!( + events(), + [RuntimeEvent::Balances(crate::Event::Withdraw { who: 1, amount: 98 })] + ); + + let res = Balances::withdraw(&1, 1, BestEffort, Expendable, Force); + assert_eq!(res.unwrap().peek(), 1); + + assert_eq!( + events(), + [ + RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), + RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 1 }), + RuntimeEvent::Balances(crate::Event::Withdraw { who: 1, amount: 1 }) + ] + ); + }); +} diff --git a/pallets/balances/src/types.rs b/pallets/balances/src/types.rs new file mode 100644 index 000000000..2ec496a66 --- /dev/null +++ b/pallets/balances/src/types.rs @@ -0,0 +1,185 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Types used in the pallet. + +use crate::{Config, CreditOf, Event, Pallet}; +use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen}; +use core::ops::BitOr; +use frame_support::traits::{Imbalance, LockIdentifier, OnUnbalanced, WithdrawReasons}; +use scale_info::TypeInfo; +use sp_runtime::{RuntimeDebug, Saturating}; + +/// Simplified reasons for withdrawing balance. +#[derive( + Encode, + Decode, + DecodeWithMemTracking, + Clone, + Copy, + PartialEq, + Eq, + RuntimeDebug, + MaxEncodedLen, + TypeInfo, +)] +pub enum Reasons { + /// Paying system transaction fees. + Fee = 0, + /// Any reason other than paying system transaction fees. + Misc = 1, + /// Any reason at all. + All = 2, +} + +impl From for Reasons { + fn from(r: WithdrawReasons) -> Reasons { + if r == WithdrawReasons::TRANSACTION_PAYMENT { + Reasons::Fee + } else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) { + Reasons::All + } else { + Reasons::Misc + } + } +} + +impl BitOr for Reasons { + type Output = Reasons; + fn bitor(self, other: Reasons) -> Reasons { + if self == other { + return self + } + Reasons::All + } +} + +/// A single lock on a balance. There can be many of these on an account and they "overlap", so the +/// same balance is frozen by multiple locks. +#[derive( + Encode, + Decode, + DecodeWithMemTracking, + Clone, + PartialEq, + Eq, + RuntimeDebug, + MaxEncodedLen, + TypeInfo, +)] +pub struct BalanceLock { + /// An identifier for this lock. Only one lock may be in existence for each identifier. + pub id: LockIdentifier, + /// The amount which the free balance may not drop below when this lock is in effect. + pub amount: Balance, + /// If true, then the lock remains in effect even for payment of transaction fees. + pub reasons: Reasons, +} + +/// Store named reserved balance. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct ReserveData { + /// The identifier for the named reserve. + pub id: ReserveIdentifier, + /// The amount of the named reserve. + pub amount: Balance, +} + +/// All balance information for an account. +#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct AccountData { + /// Non-reserved part of the balance which the account holder may be able to control. + /// + /// This is the only balance that matters in terms of most operations on tokens. + pub free: Balance, + /// Balance which is has active holds on it and may not be used at all. + /// + /// This is the sum of all individual holds together with any sums still under the (deprecated) + /// reserves API. + pub reserved: Balance, + /// The amount that `free + reserved` may not drop below when reducing the balance, except for + /// actions where the account owner cannot reasonably benefit from the balance reduction, such + /// as slashing. + pub frozen: Balance, + /// Extra information about this account. The MSB is a flag indicating whether the new ref- + /// counting logic is in place for this account. + pub flags: ExtraFlags, +} + +const IS_NEW_LOGIC: u128 = 0x80000000_00000000_00000000_00000000u128; + +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct ExtraFlags(pub(crate) u128); +impl Default for ExtraFlags { + fn default() -> Self { + Self(IS_NEW_LOGIC) + } +} +impl ExtraFlags { + pub fn old_logic() -> Self { + Self(0) + } + pub fn set_new_logic(&mut self) { + self.0 = self.0 | IS_NEW_LOGIC + } + pub fn is_new_logic(&self) -> bool { + (self.0 & IS_NEW_LOGIC) == IS_NEW_LOGIC + } +} + +impl AccountData { + pub fn usable(&self) -> Balance { + self.free.saturating_sub(self.frozen) + } + + /// The total balance in this account including any that is reserved and ignoring any frozen. + pub fn total(&self) -> Balance { + self.free.saturating_add(self.reserved) + } +} + +pub struct DustCleaner, I: 'static = ()>( + pub(crate) Option<(T::AccountId, CreditOf)>, +); + +impl, I: 'static> Drop for DustCleaner { + fn drop(&mut self) { + if let Some((who, dust)) = self.0.take() { + Pallet::::deposit_event(Event::DustLost { account: who, amount: dust.peek() }); + T::DustRemoval::on_unbalanced(dust); + } + } +} + +/// Whether something should be interpreted as an increase or a decrease. +#[derive( + Encode, + Decode, + DecodeWithMemTracking, + Clone, + PartialEq, + Eq, + RuntimeDebug, + MaxEncodedLen, + TypeInfo, +)] +pub enum AdjustmentDirection { + /// Increase the amount. + Increase, + /// Decrease the amount. + Decrease, +} diff --git a/pallets/balances/src/weights.rs b/pallets/balances/src/weights.rs new file mode 100644 index 000000000..d5e55460f --- /dev/null +++ b/pallets/balances/src/weights.rs @@ -0,0 +1,321 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for `pallet_balances` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `4563561839a5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --extrinsic=* +// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm +// --pallet=pallet_balances +// --header=/__w/polkadot-sdk/polkadot-sdk/substrate/HEADER-APACHE2 +// --output=/__w/polkadot-sdk/polkadot-sdk/substrate/frame/balances/src/weights.rs +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --template=substrate/.maintain/frame-weight-template.hbs +// --no-storage-info +// --no-min-squares +// --no-median-slopes +// --genesis-builder-policy=none +// --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic,pallet_nomination_pools,pallet_remark,pallet_transaction_storage,pallet_election_provider_multi_block,pallet_election_provider_multi_block::signed,pallet_election_provider_multi_block::unsigned,pallet_election_provider_multi_block::verifier + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] +#![allow(dead_code)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet_balances`. +pub trait WeightInfo { + fn transfer_allow_death() -> Weight; + fn transfer_keep_alive() -> Weight; + fn force_set_balance_creating() -> Weight; + fn force_set_balance_killing() -> Weight; + fn force_transfer() -> Weight; + fn transfer_all() -> Weight; + fn force_unreserve() -> Weight; + fn upgrade_accounts(u: u32, ) -> Weight; + fn force_adjust_total_issuance() -> Weight; + fn burn_allow_death() -> Weight; + fn burn_keep_alive() -> Weight; +} + +/// Weights for `pallet_balances` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 48_203_000 picoseconds. + Weight::from_parts(48_834_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 38_647_000 picoseconds. + Weight::from_parts(39_051_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_set_balance_creating() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `3593` + // Minimum execution time: 12_191_000 picoseconds. + Weight::from_parts(12_547_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_set_balance_killing() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `3593` + // Minimum execution time: 18_636_000 picoseconds. + Weight::from_parts(19_206_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `6196` + // Minimum execution time: 49_073_000 picoseconds. + Weight::from_parts(49_519_000, 6196) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_all() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 47_572_000 picoseconds. + Weight::from_parts(48_209_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_unreserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `3593` + // Minimum execution time: 15_290_000 picoseconds. + Weight::from_parts(15_515_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:999 w:999) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `u` is `[1, 1000]`. + fn upgrade_accounts(u: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + u * (135 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 14_546_000 picoseconds. + Weight::from_parts(14_674_000, 990) + // Standard Error: 11_734 + .saturating_add(Weight::from_parts(14_648_188, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) + } + fn force_adjust_total_issuance() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_096_000 picoseconds. + Weight::from_parts(5_351_000, 0) + } + fn burn_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 29_641_000 picoseconds. + Weight::from_parts(30_219_000, 0) + } + fn burn_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 20_462_000 picoseconds. + Weight::from_parts(20_720_000, 0) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 48_203_000 picoseconds. + Weight::from_parts(48_834_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 38_647_000 picoseconds. + Weight::from_parts(39_051_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_set_balance_creating() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `3593` + // Minimum execution time: 12_191_000 picoseconds. + Weight::from_parts(12_547_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_set_balance_killing() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `3593` + // Minimum execution time: 18_636_000 picoseconds. + Weight::from_parts(19_206_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `6196` + // Minimum execution time: 49_073_000 picoseconds. + Weight::from_parts(49_519_000, 6196) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_all() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 47_572_000 picoseconds. + Weight::from_parts(48_209_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_unreserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `52` + // Estimated: `3593` + // Minimum execution time: 15_290_000 picoseconds. + Weight::from_parts(15_515_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `System::Account` (r:999 w:999) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `u` is `[1, 1000]`. + fn upgrade_accounts(u: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + u * (135 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 14_546_000 picoseconds. + Weight::from_parts(14_674_000, 990) + // Standard Error: 11_734 + .saturating_add(Weight::from_parts(14_648_188, 0).saturating_mul(u.into())) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(u.into()))) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) + } + fn force_adjust_total_issuance() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_096_000 picoseconds. + Weight::from_parts(5_351_000, 0) + } + fn burn_allow_death() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 29_641_000 picoseconds. + Weight::from_parts(30_219_000, 0) + } + fn burn_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 20_462_000 picoseconds. + Weight::from_parts(20_720_000, 0) + } +} diff --git a/pallets/tokens/Cargo.toml b/pallets/tokens/Cargo.toml new file mode 100644 index 000000000..b43b611cb --- /dev/null +++ b/pallets/tokens/Cargo.toml @@ -0,0 +1,54 @@ +[package] +name = "orml-tokens" +description = "Fungible tokens module that implements `MultiCurrency` trait." +repository = "https://github.com/galacticcouncil/hydration-node" +license = "Apache-2.0" +version = "1.4.0" +authors = ["Laminar Developers "] +edition = "2021" + +[dependencies] +parity-scale-codec = { version = "3.7", default-features = false, features = ["derive", "max-encoded-len"] } +log = { workspace = true } +scale-info = { workspace = true } +serde = { workspace = true, optional = true } + +frame-support = { workspace = true } +frame-system = { workspace = true } +sp-arithmetic = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +orml-traits = { workspace = true } + +[dev-dependencies] +pallet-elections-phragmen = { workspace = true, features = ["std"] } +pallet-treasury = { workspace = true, features = ["std"] } +sp-core = { workspace = true, features = ["std"] } +sp-io = { workspace = true, features = ["std"] } +sp-staking = { workspace = true, features = ["std"] } + +[features] +default = ["std"] +std = [ + "frame-support/std", + "frame-system/std", + "log/std", + "orml-traits/std", + "parity-scale-codec/std", + "scale-info/std", + "serde", + "sp-arithmetic/std", + "sp-runtime/std", + "sp-std/std", +] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/pallets/tokens/README.md b/pallets/tokens/README.md new file mode 100644 index 000000000..20e9e816e --- /dev/null +++ b/pallets/tokens/README.md @@ -0,0 +1,13 @@ +# Tokens Module + +## Overview + +The tokens module provides fungible multi-currencies functionality that implements `MultiCurrency` trait. + +The tokens module provides functions for: + +- Querying and setting the balance of a given account. +- Getting and managing total issuance. +- Balance transfer between accounts. +- Depositing and withdrawing balance. +- Slashing an account balance. diff --git a/pallets/tokens/runtime-api/Cargo.toml b/pallets/tokens/runtime-api/Cargo.toml new file mode 100644 index 000000000..b70a6b0d1 --- /dev/null +++ b/pallets/tokens/runtime-api/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "orml-tokens-runtime-api" +version = "1.4.0" +authors = ["Laminar Developers "] +edition = "2021" +license = "Apache-2.0" +description = "Runtime API module for orml-tokens." +repository = "https://github.com/open-web3-stack/open-runtime-module-library" + +[dependencies] +parity-scale-codec = { workspace = true, default-features = false, features = ["derive"] } +frame-support = { workspace = true } +sp-api = { workspace = true } +sp-runtime = { workspace = true } + +[features] +default = [ "std" ] +std = [ + "frame-support/std", + "parity-scale-codec/std", + "sp-api/std", + "sp-runtime/std", +] diff --git a/pallets/tokens/runtime-api/src/lib.rs b/pallets/tokens/runtime-api/src/lib.rs new file mode 100644 index 000000000..a54962c0c --- /dev/null +++ b/pallets/tokens/runtime-api/src/lib.rs @@ -0,0 +1,18 @@ +//! Runtime API definition for orml tokens pallet. + +#![cfg_attr(not(feature = "std"), no_std)] +// The `too_many_arguments` warning originates from `decl_runtime_apis` macro. +#![allow(clippy::too_many_arguments)] +// The `unnecessary_mut_passed` warning originates from `decl_runtime_apis` macro. +#![allow(clippy::unnecessary_mut_passed)] + +use parity_scale_codec::Codec; + +sp_api::decl_runtime_apis! { + pub trait TokensApi where + Balance: Codec, + CurrencyId: Codec + { + fn query_existential_deposit(currency_id: CurrencyId) -> Balance; + } +} diff --git a/pallets/tokens/src/imbalances.rs b/pallets/tokens/src/imbalances.rs new file mode 100644 index 000000000..858641130 --- /dev/null +++ b/pallets/tokens/src/imbalances.rs @@ -0,0 +1,197 @@ +// wrapping these imbalances in a private module is necessary to ensure absolute +// privacy of the inner member. +use crate::{Config, TotalIssuance}; +use frame_support::traits::{tokens::imbalance::TryMerge, Get, Imbalance, SameOrOther, TryDrop}; +use sp_runtime::traits::{Saturating, Zero}; +use sp_std::{marker, mem, result}; + +/// Opaque, move-only struct with private fields that serves as a token +/// denoting that funds have been created without any equal and opposite +/// accounting. +#[must_use] +pub struct PositiveImbalance>( + T::Balance, + marker::PhantomData, +); + +impl> PositiveImbalance { + /// Create a new positive imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + PositiveImbalance(amount, marker::PhantomData::) + } +} + +impl> Default for PositiveImbalance { + fn default() -> Self { + Self::zero() + } +} + +/// Opaque, move-only struct with private fields that serves as a token +/// denoting that funds have been destroyed without any equal and opposite +/// accounting. +#[must_use] +pub struct NegativeImbalance>( + T::Balance, + marker::PhantomData, +); + +impl> NegativeImbalance { + /// Create a new negative imbalance from a balance. + pub fn new(amount: T::Balance) -> Self { + NegativeImbalance(amount, marker::PhantomData::) + } +} + +impl> Default for NegativeImbalance { + fn default() -> Self { + Self::zero() + } +} + +impl> TryDrop for PositiveImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } +} + +impl> Imbalance for PositiveImbalance { + type Opposite = NegativeImbalance; + + fn zero() -> Self { + Self::new(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0.saturating_sub(first); + + mem::forget(self); + (Self::new(first), Self::new(second)) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + // allow to make the impl same with `pallet-balances` + #[allow(clippy::comparison_chain)] + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self::new(a.saturating_sub(b))) + } else if b > a { + SameOrOther::Other(NegativeImbalance::new(b.saturating_sub(a))) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + + fn extract(&mut self, amount: T::Balance) -> Self { + let new: T::Balance = self.0.min(amount); + self.0 -= new; + Self::new(new) + } +} + +impl> TryDrop for NegativeImbalance { + fn try_drop(self) -> result::Result<(), Self> { + self.drop_zero() + } +} + +impl> Imbalance for NegativeImbalance { + type Opposite = PositiveImbalance; + + fn zero() -> Self { + Self::new(Zero::zero()) + } + fn drop_zero(self) -> result::Result<(), Self> { + if self.0.is_zero() { + Ok(()) + } else { + Err(self) + } + } + fn split(self, amount: T::Balance) -> (Self, Self) { + let first = self.0.min(amount); + let second = self.0.saturating_sub(first); + + mem::forget(self); + (Self::new(first), Self::new(second)) + } + fn merge(mut self, other: Self) -> Self { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + + self + } + fn subsume(&mut self, other: Self) { + self.0 = self.0.saturating_add(other.0); + mem::forget(other); + } + // allow to make the impl same with `pallet-balances` + #[allow(clippy::comparison_chain)] + fn offset(self, other: Self::Opposite) -> SameOrOther { + let (a, b) = (self.0, other.0); + mem::forget((self, other)); + + if a > b { + SameOrOther::Same(Self::new(a.saturating_sub(b))) + } else if b > a { + SameOrOther::Other(PositiveImbalance::new(b.saturating_sub(a))) + } else { + SameOrOther::None + } + } + fn peek(&self) -> T::Balance { + self.0 + } + + fn extract(&mut self, amount: T::Balance) -> Self { + let new: T::Balance = self.0.min(amount); + self.0 -= new; + Self::new(new) + } +} + +impl> Drop for PositiveImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + TotalIssuance::::mutate(GetCurrencyId::get(), |v| *v = v.saturating_add(self.0)); + } +} + +impl> Drop for NegativeImbalance { + /// Basic drop handler will just square up the total issuance. + fn drop(&mut self) { + TotalIssuance::::mutate(GetCurrencyId::get(), |v| *v = v.saturating_sub(self.0)); + } +} + +impl> TryMerge for PositiveImbalance { + fn try_merge(self, other: Self) -> Result { + Ok(self.merge(other)) + } +} +impl> TryMerge for NegativeImbalance { + fn try_merge(self, other: Self) -> Result { + Ok(self.merge(other)) + } +} diff --git a/pallets/tokens/src/impls.rs b/pallets/tokens/src/impls.rs new file mode 100644 index 000000000..83a65ad60 --- /dev/null +++ b/pallets/tokens/src/impls.rs @@ -0,0 +1,352 @@ +use frame_support::traits::tokens::{Fortitude, Precision, Preservation, Provenance}; +use frame_support::traits::{ + fungible, fungibles, + tokens::{Balance as BalanceT, DepositConsequence, WithdrawConsequence}, + Contains, Get, +}; +use sp_arithmetic::{traits::Bounded, ArithmeticError}; +use sp_runtime::DispatchError; + +pub struct Combiner(sp_std::marker::PhantomData<(AccountId, TestKey, A, B)>); + +impl fungibles::Inspect for Combiner +where + TestKey: Contains<>::AssetId>, + A: fungible::Inspect>::Balance>, + B: fungibles::Inspect, +{ + type AssetId = >::AssetId; + type Balance = >::Balance; + + fn total_issuance(asset: Self::AssetId) -> Self::Balance { + if TestKey::contains(&asset) { + A::total_issuance() + } else { + B::total_issuance(asset) + } + } + + fn minimum_balance(asset: Self::AssetId) -> Self::Balance { + if TestKey::contains(&asset) { + A::minimum_balance() + } else { + B::minimum_balance(asset) + } + } + + fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + if TestKey::contains(&asset) { + A::balance(who) + } else { + B::balance(asset, who) + } + } + + fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + if TestKey::contains(&asset) { + A::total_balance(who) + } else { + B::total_balance(asset, who) + } + } + + fn reducible_balance( + asset: Self::AssetId, + who: &AccountId, + preservation: Preservation, + fortitude: Fortitude, + ) -> Self::Balance { + if TestKey::contains(&asset) { + A::reducible_balance(who, preservation, fortitude) + } else { + B::reducible_balance(asset, who, preservation, fortitude) + } + } + + fn can_deposit( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + provenance: Provenance, + ) -> DepositConsequence { + if TestKey::contains(&asset) { + A::can_deposit(who, amount, provenance) + } else { + B::can_deposit(asset, who, amount, provenance) + } + } + + fn can_withdraw( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + if TestKey::contains(&asset) { + A::can_withdraw(who, amount) + } else { + B::can_withdraw(asset, who, amount) + } + } + + fn asset_exists(asset: Self::AssetId) -> bool { + if TestKey::contains(&asset) { + true + } else { + B::asset_exists(asset) + } + } +} + +impl fungibles::Mutate for Combiner +where + TestKey: Contains<>::AssetId>, + A: fungible::Mutate>::Balance>, + B: fungibles::Mutate, + AccountId: Eq, +{ + fn mint_into( + asset: Self::AssetId, + dest: &AccountId, + amount: Self::Balance, + ) -> Result { + if TestKey::contains(&asset) { + A::mint_into(dest, amount) + } else { + B::mint_into(asset, dest, amount) + } + } + + fn burn_from( + asset: Self::AssetId, + dest: &AccountId, + amount: Self::Balance, + preservation: Preservation, + precision: Precision, + fortitude: Fortitude, + ) -> Result { + if TestKey::contains(&asset) { + A::burn_from(dest, amount, preservation, precision, fortitude) + } else { + B::burn_from(asset, dest, amount, preservation, precision, fortitude) + } + } + + fn transfer( + asset: Self::AssetId, + source: &AccountId, + dest: &AccountId, + amount: Self::Balance, + preservation: Preservation, + ) -> Result { + if TestKey::contains(&asset) { + A::transfer(source, dest, amount, preservation) + } else { + B::transfer(asset, source, dest, amount, preservation) + } + } +} + +impl fungibles::Unbalanced for Combiner +where + TestKey: Contains<>::AssetId>, + A: fungible::Mutate>::Balance>, + B: fungibles::Mutate, + AccountId: Eq, +{ + fn handle_dust(_dust: fungibles::Dust) { + // FIXME: only way to access internals of Dust is into_credit, but T is + // not balanced + } + + fn write_balance( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + ) -> Result, DispatchError> { + if TestKey::contains(&asset) { + A::write_balance(who, amount) + } else { + B::write_balance(asset, who, amount) + } + } + + fn set_total_issuance(asset: Self::AssetId, amount: Self::Balance) { + if TestKey::contains(&asset) { + A::set_total_issuance(amount) + } else { + B::set_total_issuance(asset, amount) + } + } +} + +pub trait ConvertBalance { + type AssetId; + fn convert_balance(amount: A, asset_id: Self::AssetId) -> Result; + fn convert_balance_back(amount: B, asset_id: Self::AssetId) -> Result; + + fn convert_balance_saturated(amount: A, asset_id: Self::AssetId) -> B { + Self::convert_balance(amount, asset_id).unwrap_or_else(|e| match e { + ArithmeticError::Overflow => B::max_value(), + ArithmeticError::Underflow => B::min_value(), + ArithmeticError::DivisionByZero => B::max_value(), + }) + } + fn convert_balance_back_saturated(amount: B, asset_id: Self::AssetId) -> A { + Self::convert_balance_back(amount, asset_id).unwrap_or_else(|e| match e { + ArithmeticError::Overflow => A::max_value(), + ArithmeticError::Underflow => A::min_value(), + ArithmeticError::DivisionByZero => A::max_value(), + }) + } +} + +pub struct Mapper(sp_std::marker::PhantomData<(AccountId, T, C, B, GetCurrencyId)>); +impl fungible::Inspect for Mapper +where + T: fungibles::Inspect, + C: ConvertBalance< + >::Balance, + B, + AssetId = >::AssetId, + >, + B: BalanceT, + GetCurrencyId: Get<>::AssetId>, +{ + type Balance = B; + + fn total_issuance() -> Self::Balance { + C::convert_balance_saturated(T::total_issuance(GetCurrencyId::get()), GetCurrencyId::get()) + } + + fn minimum_balance() -> Self::Balance { + C::convert_balance_saturated(T::minimum_balance(GetCurrencyId::get()), GetCurrencyId::get()) + } + + fn balance(who: &AccountId) -> Self::Balance { + C::convert_balance_saturated(T::balance(GetCurrencyId::get(), who), GetCurrencyId::get()) + } + + fn total_balance(who: &AccountId) -> Self::Balance { + C::convert_balance_saturated(T::total_balance(GetCurrencyId::get(), who), GetCurrencyId::get()) + } + + fn reducible_balance(who: &AccountId, preservation: Preservation, fortitude: Fortitude) -> Self::Balance { + C::convert_balance_saturated( + T::reducible_balance(GetCurrencyId::get(), who, preservation, fortitude), + GetCurrencyId::get(), + ) + } + + fn can_deposit(who: &AccountId, amount: Self::Balance, provenance: Provenance) -> DepositConsequence { + let amount = C::convert_balance_back(amount, GetCurrencyId::get()); + let amount = match amount { + Ok(amount) => amount, + Err(_) => return DepositConsequence::Overflow, + }; + T::can_deposit(GetCurrencyId::get(), who, amount, provenance) + } + + fn can_withdraw(who: &AccountId, amount: Self::Balance) -> WithdrawConsequence { + use WithdrawConsequence::*; + + let amount = C::convert_balance_back(amount, GetCurrencyId::get()); + let amount = match amount { + Ok(amount) => amount, + Err(ArithmeticError::Overflow) => return Overflow, + Err(ArithmeticError::Underflow) => return Underflow, + Err(ArithmeticError::DivisionByZero) => return Overflow, + }; + + let res = T::can_withdraw(GetCurrencyId::get(), who, amount); + match res { + WithdrawConsequence::ReducedToZero(b) => { + WithdrawConsequence::ReducedToZero(C::convert_balance_saturated(b, GetCurrencyId::get())) + } + BalanceLow => BalanceLow, + WouldDie => WouldDie, + UnknownAsset => UnknownAsset, + Underflow => Underflow, + Overflow => Overflow, + Frozen => Frozen, + Success => Success, + } + } +} + +impl fungible::Mutate for Mapper +where + T: fungibles::Mutate, + C: ConvertBalance< + >::Balance, + B, + AssetId = >::AssetId, + >, + B: BalanceT, + GetCurrencyId: Get<>::AssetId>, + AccountId: Eq, +{ + fn mint_into(dest: &AccountId, amount: Self::Balance) -> Result { + T::mint_into( + GetCurrencyId::get(), + dest, + C::convert_balance_back(amount, GetCurrencyId::get())?, + ) + } + + fn burn_from( + dest: &AccountId, + amount: Self::Balance, + preservation: Preservation, + precision: Precision, + fortitude: Fortitude, + ) -> Result { + T::burn_from( + GetCurrencyId::get(), + dest, + C::convert_balance_back(amount, GetCurrencyId::get())?, + preservation, + precision, + fortitude, + ) + } + + fn transfer( + source: &AccountId, + dest: &AccountId, + amount: B, + preservation: Preservation, + ) -> Result { + T::transfer( + GetCurrencyId::get(), + source, + dest, + C::convert_balance_back(amount, GetCurrencyId::get())?, + preservation, + ) + } +} + +impl fungible::Unbalanced for Mapper +where + T: fungibles::Unbalanced, + C: ConvertBalance< + >::Balance, + B, + AssetId = >::AssetId, + >, + B: BalanceT, + GetCurrencyId: Get<>::AssetId>, +{ + fn handle_dust(_dust: fungible::Dust) { + // FIXME: only way to access internals of Dust is into_credit, but T is + // not balanced + } + + fn write_balance(who: &AccountId, amount: Self::Balance) -> Result, DispatchError> { + T::write_balance(GetCurrencyId::get(), who, amount) + } + + fn set_total_issuance(amount: Self::Balance) { + T::set_total_issuance(GetCurrencyId::get(), amount) + } +} diff --git a/pallets/tokens/src/lib.rs b/pallets/tokens/src/lib.rs new file mode 100644 index 000000000..9f6a03ee3 --- /dev/null +++ b/pallets/tokens/src/lib.rs @@ -0,0 +1,2605 @@ +//! # Tokens Module +//! +//! ## Overview +//! +//! The tokens module provides fungible multi-currency functionality that +//! implements `MultiCurrency` trait. +//! +//! The tokens module provides functions for: +//! +//! - Querying and setting the balance of a given account. +//! - Getting and managing total issuance. +//! - Balance transfer between accounts. +//! - Depositing and withdrawing balance. +//! - Slashing an account balance. +//! +//! ### Implementations +//! +//! The tokens module provides implementations for following traits. +//! +//! - `MultiCurrency` - Abstraction over a fungible multi-currency system. +//! - `MultiCurrencyExtended` - Extended `MultiCurrency` with additional helper +//! types and methods, like updating balance by a given signed integer amount. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! - `transfer` - Transfer some balance to another account. +//! - `transfer_all` - Transfer all balance to another account. +//! +//! ### Genesis Config +//! +//! The tokens module depends on the `GenesisConfig`. Endowed accounts could be +//! configured in genesis configs. + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] +#![allow(clippy::comparison_chain)] +#![allow(clippy::useless_conversion)] + +pub use crate::imbalances::{NegativeImbalance, PositiveImbalance}; + +use frame_support::{ + ensure, + pallet_prelude::*, + traits::{ + tokens::{ + fungible, fungibles, DepositConsequence, Fortitude, Precision, Preservation, Provenance, Restriction, + WithdrawConsequence, + }, + BalanceStatus as Status, Contains, Currency as PalletCurrency, DefensiveSaturating, ExistenceRequirement, Get, + Imbalance, LockableCurrency as PalletLockableCurrency, + NamedReservableCurrency as PalletNamedReservableCurrency, ReservableCurrency as PalletReservableCurrency, + SignedImbalance, WithdrawReasons, + }, + transactional, BoundedVec, +}; +use frame_system::{ensure_signed, pallet_prelude::*}; +use parity_scale_codec::MaxEncodedLen; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, Saturating, StaticLookup, Zero}, + ArithmeticError, DispatchError, DispatchResult, RuntimeDebug, TokenError, +}; +use sp_std::{cmp, convert::Infallible, marker, prelude::*, vec::Vec}; + +use orml_traits::{ + arithmetic::{self, Signed}, + currency::{MutationHooks, OnDeposit, OnDust, OnSlash, OnTransfer, TransferAll}, + BalanceStatus, GetByKey, Happened, LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency, + MultiReservableCurrency, NamedMultiReservableCurrency, +}; + +mod imbalances; +mod impls; +mod mock; +mod tests; +mod tests_currency_adapter; +mod tests_events; +mod tests_fungibles; +mod tests_multicurrency; + +mod weights; + +pub use impls::*; +pub use weights::WeightInfo; + +pub struct TransferDust(marker::PhantomData<(T, GetAccountId)>); +impl OnDust for TransferDust +where + T: Config, + GetAccountId: Get, +{ + fn on_dust(who: &T::AccountId, currency_id: T::CurrencyId, amount: T::Balance) { + // transfer the dust to treasury account, ignore the result, + // if failed will leave some dust which still could be recycled. + let _ = Pallet::::do_transfer( + currency_id, + who, + &GetAccountId::get(), + amount, + ExistenceRequirement::AllowDeath, + ); + } +} + +pub struct BurnDust(marker::PhantomData); +impl OnDust for BurnDust { + fn on_dust(who: &T::AccountId, currency_id: T::CurrencyId, amount: T::Balance) { + // burn the dust, ignore the result, + // if failed will leave some dust which still could be recycled. + let _ = Pallet::::do_withdraw(currency_id, who, amount, ExistenceRequirement::AllowDeath, true); + } +} + +/// A single lock on a balance. There can be many of these on an account and +/// they "overlap", so the same balance is frozen by multiple locks. +#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, MaxEncodedLen, RuntimeDebug, TypeInfo)] +pub struct BalanceLock { + /// An identifier for this lock. Only one lock may be in existence for + /// each identifier. + pub id: LockIdentifier, + /// The amount which the free balance may not drop below when this lock + /// is in effect. + pub amount: Balance, +} + +/// Store named reserved balance. +#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct ReserveData { + /// The identifier for the named reserve. + pub id: ReserveIdentifier, + /// The amount of the named reserve. + pub amount: Balance, +} + +/// balance information for an account. +#[derive( + Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Default, MaxEncodedLen, RuntimeDebug, TypeInfo, +)] +pub struct AccountData { + /// Non-reserved part of the balance. There may still be restrictions on + /// this, but it is the total pool what may in principle be transferred, + /// reserved. + /// + /// This is the only balance that matters in terms of most operations on + /// tokens. + pub free: Balance, + /// Balance which is reserved and may not be used at all. + /// + /// This can still get slashed, but gets slashed last of all. + /// + /// This balance is a 'reserve' balance that other subsystems use in + /// order to set aside tokens that are still 'owned' by the account + /// holder, but which are suspendable. + pub reserved: Balance, + /// The amount that `free` may not drop below when withdrawing. + pub frozen: Balance, +} + +impl AccountData { + /// The amount that this account's free balance may not be reduced + /// beyond. + pub(crate) fn frozen(&self) -> Balance { + self.frozen + } + /// The total balance in this account including any that is reserved and + /// ignoring any frozen. + fn total(&self) -> Balance { + self.free.saturating_add(self.reserved) + } +} + +pub use module::*; + +#[frame_support::pallet] +pub mod module { + use orml_traits::currency::MutationHooks; + + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The balance type + type Balance: frame_support::traits::tokens::Balance; + + /// The amount type, should be signed version of `Balance` + type Amount: Signed + + TryInto + + TryFrom + + Parameter + + Member + + arithmetic::SimpleArithmetic + + Default + + Copy + + MaybeSerializeDeserialize + + MaxEncodedLen; + + /// The currency ID type + type CurrencyId: Parameter + Member + Copy + MaybeSerializeDeserialize + Ord + TypeInfo + MaxEncodedLen; + + /// Weight information for extrinsics in this module. + type WeightInfo: WeightInfo; + + /// The minimum amount required to keep an account. + /// It's deprecated to config 0 as ED for any currency_id, + /// zero ED will retain account even if its total is zero. + /// Since accounts of orml_tokens are also used as providers of + /// System::AccountInfo, zero ED may cause some problems. + type ExistentialDeposits: GetByKey; + + /// Hooks are actions that are executed on certain events. + /// For example: OnDust, OnNewTokenAccount + type CurrencyHooks: MutationHooks; + + #[pallet::constant] + type MaxLocks: Get; + + /// The maximum number of named reserves that can exist on an account. + #[pallet::constant] + type MaxReserves: Get; + + /// The id type for named reserves. + type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; + + // The whitelist of accounts that will not be reaped even if its total + // is zero or below ED. + type DustRemovalWhitelist: Contains; + } + + #[pallet::error] + pub enum Error { + /// The balance is too low + BalanceTooLow, + /// Cannot convert Amount into Balance type + AmountIntoBalanceFailed, + /// Failed because liquidity restrictions due to locking + LiquidityRestrictions, + /// Failed because the maximum locks was exceeded + MaxLocksExceeded, + /// Transfer/payment would kill account + KeepAlive, + /// Value too low to create account due to existential deposit + ExistentialDeposit, + /// Beneficiary account must pre-exist + DeadAccount, + // Number of named reserves exceed `T::MaxReserves` + TooManyReserves, + } + + #[pallet::event] + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event { + /// An account was created with some free balance. + Endowed { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// An account was removed whose balance was non-zero but below + /// ExistentialDeposit, resulting in an outright loss. + DustLost { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Transfer succeeded. + Transfer { + currency_id: T::CurrencyId, + from: T::AccountId, + to: T::AccountId, + amount: T::Balance, + }, + /// Some balance was reserved (moved from free to reserved). + Reserved { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Some balance was unreserved (moved from reserved to free). + Unreserved { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Some reserved balance was repatriated (moved from reserved to + /// another account). + ReserveRepatriated { + currency_id: T::CurrencyId, + from: T::AccountId, + to: T::AccountId, + amount: T::Balance, + status: BalanceStatus, + }, + /// A balance was set by root. + BalanceSet { + currency_id: T::CurrencyId, + who: T::AccountId, + free: T::Balance, + reserved: T::Balance, + }, + /// The total issuance of an currency has been set + TotalIssuanceSet { + currency_id: T::CurrencyId, + amount: T::Balance, + }, + /// Some balances were withdrawn (e.g. pay for transaction fee) + Withdrawn { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Some balances were slashed (e.g. due to mis-behavior) + Slashed { + currency_id: T::CurrencyId, + who: T::AccountId, + free_amount: T::Balance, + reserved_amount: T::Balance, + }, + /// Deposited some balance into an account + Deposited { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Some funds are locked + LockSet { + lock_id: LockIdentifier, + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Some locked funds were unlocked + LockRemoved { + lock_id: LockIdentifier, + currency_id: T::CurrencyId, + who: T::AccountId, + }, + /// Some free balance was locked. + Locked { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + /// Some locked balance was freed. + Unlocked { + currency_id: T::CurrencyId, + who: T::AccountId, + amount: T::Balance, + }, + Issued { + currency_id: T::CurrencyId, + amount: T::Balance, + }, + Rescinded { + currency_id: T::CurrencyId, + amount: T::Balance, + }, + } + + /// The total issuance of a token type. + #[pallet::storage] + #[pallet::getter(fn total_issuance)] + pub type TotalIssuance = StorageMap<_, Twox64Concat, T::CurrencyId, T::Balance, ValueQuery>; + + /// Any liquidity locks of a token type under an account. + /// NOTE: Should only be accessed when setting, changing and freeing a lock. + #[pallet::storage] + #[pallet::getter(fn locks)] + pub type Locks = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Twox64Concat, + T::CurrencyId, + BoundedVec, T::MaxLocks>, + ValueQuery, + >; + + /// The balance of a token type under an account. + /// + /// NOTE: If the total is ever zero, decrease account ref account. + /// + /// NOTE: This is only used in the case that this module is used to store + /// balances. + #[pallet::storage] + #[pallet::getter(fn accounts)] + pub type Accounts = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Twox64Concat, + T::CurrencyId, + AccountData, + ValueQuery, + >; + + /// Named reserves on some account balances. + #[pallet::storage] + #[pallet::getter(fn reserves)] + pub type Reserves = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Twox64Concat, + T::CurrencyId, + BoundedVec, T::MaxReserves>, + ValueQuery, + >; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub balances: Vec<(T::AccountId, T::CurrencyId, T::Balance)>, + } + + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + balances: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + // ensure no duplicates exist. + let unique_endowed_accounts = self + .balances + .iter() + .map(|(account_id, currency_id, _)| (account_id, currency_id)) + .collect::>(); + assert!( + unique_endowed_accounts.len() == self.balances.len(), + "duplicate endowed accounts in genesis." + ); + + self.balances + .iter() + .for_each(|(account_id, currency_id, initial_balance)| { + assert!( + *initial_balance >= T::ExistentialDeposits::get(currency_id), + "the balance of any account should always be more than existential deposit.", + ); + Pallet::::mutate_account(account_id, *currency_id, |account_data, _| { + account_data.free = *initial_balance + }); + TotalIssuance::::mutate(*currency_id, |total_issuance| { + *total_issuance = total_issuance + .checked_add(initial_balance) + .expect("total issuance cannot overflow when building genesis") + }); + }); + } + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + /// Transfer some liquid free balance to another account. + /// + /// `transfer` will set the `FreeBalance` of the sender and receiver. + /// It will decrease the total issuance of the system by the + /// `TransferFee`. If the sender's account is below the existential + /// deposit as a result of the transfer, the account will be reaped. + /// + /// The dispatch origin for this call must be `Signed` by the + /// transactor. + /// + /// - `dest`: The recipient of the transfer. + /// - `currency_id`: currency type. + /// - `amount`: free balance amount to transfer. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::transfer())] + pub fn transfer( + origin: OriginFor, + dest: ::Source, + currency_id: T::CurrencyId, + #[pallet::compact] amount: T::Balance, + ) -> DispatchResult { + let from = ensure_signed(origin)?; + let to = T::Lookup::lookup(dest)?; + Self::do_transfer(currency_id, &from, &to, amount, ExistenceRequirement::AllowDeath) + } + + /// Transfer all remaining balance to the given account. + /// + /// NOTE: This function only attempts to transfer _transferable_ + /// balances. This means that any locked, reserved, or existential + /// deposits (when `keep_alive` is `true`), will not be transferred by + /// this function. To ensure that this function results in a killed + /// account, you might need to prepare the account by removing any + /// reference counters, storage deposits, etc... + /// + /// The dispatch origin for this call must be `Signed` by the + /// transactor. + /// + /// - `dest`: The recipient of the transfer. + /// - `currency_id`: currency type. + /// - `keep_alive`: A boolean to determine if the `transfer_all` + /// operation should send all of the funds the account has, causing + /// the sender account to be killed (false), or transfer everything + /// except at least the existential deposit, which will guarantee to + /// keep the sender account alive (true). + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::transfer_all())] + pub fn transfer_all( + origin: OriginFor, + dest: ::Source, + currency_id: T::CurrencyId, + keep_alive: bool, + ) -> DispatchResult { + let from = ensure_signed(origin)?; + let to = T::Lookup::lookup(dest)?; + let preservation = if keep_alive { + Preservation::Protect + } else { + Preservation::Expendable + }; + let reducible_balance = >::reducible_balance( + currency_id, + &from, + preservation, + Fortitude::Polite, + ); + >::transfer(currency_id, &from, &to, reducible_balance, preservation) + .map(|_| ()) + } + + /// Same as the [`transfer`] call, but with a check that the transfer + /// will not kill the origin account. + /// + /// 99% of the time you want [`transfer`] instead. + /// + /// The dispatch origin for this call must be `Signed` by the + /// transactor. + /// + /// - `dest`: The recipient of the transfer. + /// - `currency_id`: currency type. + /// - `amount`: free balance amount to transfer. + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::transfer_keep_alive())] + pub fn transfer_keep_alive( + origin: OriginFor, + dest: ::Source, + currency_id: T::CurrencyId, + #[pallet::compact] amount: T::Balance, + ) -> DispatchResultWithPostInfo { + let from = ensure_signed(origin)?; + let to = T::Lookup::lookup(dest)?; + Self::do_transfer(currency_id, &from, &to, amount, ExistenceRequirement::KeepAlive)?; + Ok(().into()) + } + + /// Exactly as `transfer`, except the origin must be root and the source + /// account may be specified. + /// + /// The dispatch origin for this call must be _Root_. + /// + /// - `source`: The sender of the transfer. + /// - `dest`: The recipient of the transfer. + /// - `currency_id`: currency type. + /// - `amount`: free balance amount to transfer. + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::force_transfer())] + pub fn force_transfer( + origin: OriginFor, + source: ::Source, + dest: ::Source, + currency_id: T::CurrencyId, + #[pallet::compact] amount: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + let from = T::Lookup::lookup(source)?; + let to = T::Lookup::lookup(dest)?; + Self::do_transfer(currency_id, &from, &to, amount, ExistenceRequirement::AllowDeath) + } + + /// Set the balances of a given account. + /// + /// This will alter `FreeBalance` and `ReservedBalance` in storage. it + /// will also decrease the total issuance of the system + /// (`TotalIssuance`). If the new free or reserved balance is below the + /// existential deposit, it will reap the `AccountInfo`. + /// + /// The dispatch origin for this call is `root`. + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::set_balance())] + pub fn set_balance( + origin: OriginFor, + who: ::Source, + currency_id: T::CurrencyId, + #[pallet::compact] new_free: T::Balance, + #[pallet::compact] new_reserved: T::Balance, + ) -> DispatchResult { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + + Self::try_mutate_account(&who, currency_id, |account, _| -> DispatchResult { + let mut new_total = new_free.checked_add(&new_reserved).ok_or(ArithmeticError::Overflow)?; + let (new_free, new_reserved) = if new_total < T::ExistentialDeposits::get(¤cy_id) { + new_total = Zero::zero(); + (Zero::zero(), Zero::zero()) + } else { + (new_free, new_reserved) + }; + let old_total = account.total(); + + account.free = new_free; + account.reserved = new_reserved; + + if new_total > old_total { + TotalIssuance::::try_mutate(currency_id, |t| -> DispatchResult { + *t = t + .checked_add(&(new_total.defensive_saturating_sub(old_total))) + .ok_or(ArithmeticError::Overflow)?; + Ok(()) + })?; + } else if new_total < old_total { + TotalIssuance::::try_mutate(currency_id, |t| -> DispatchResult { + *t = t + .checked_sub(&(old_total.defensive_saturating_sub(new_total))) + .ok_or(ArithmeticError::Underflow)?; + Ok(()) + })?; + } + + Self::deposit_event(Event::BalanceSet { + currency_id, + who: who.clone(), + free: new_free, + reserved: new_reserved, + }); + Ok(()) + })?; + + Ok(()) + } + } +} + +impl Pallet { + pub(crate) fn deposit_consequence( + _who: &T::AccountId, + currency_id: T::CurrencyId, + amount: T::Balance, + account: &AccountData, + ) -> DepositConsequence { + if amount.is_zero() { + return DepositConsequence::Success; + } + + if TotalIssuance::::get(currency_id).checked_add(&amount).is_none() { + return DepositConsequence::Overflow; + } + + let new_total_balance = match account.total().checked_add(&amount) { + Some(x) => x, + None => return DepositConsequence::Overflow, + }; + + if new_total_balance < T::ExistentialDeposits::get(¤cy_id) { + return DepositConsequence::BelowMinimum; + } + + // NOTE: We assume that we are a provider, so don't need to do any checks in the + // case of account creation. + + DepositConsequence::Success + } + + pub(crate) fn withdraw_consequence( + who: &T::AccountId, + currency_id: T::CurrencyId, + amount: T::Balance, + account: &AccountData, + ) -> WithdrawConsequence { + if amount.is_zero() { + return WithdrawConsequence::Success; + } + + if TotalIssuance::::get(currency_id).checked_sub(&amount).is_none() { + return WithdrawConsequence::Underflow; + } + + let new_total_balance = match account.total().checked_sub(&amount) { + Some(x) => x, + None => return WithdrawConsequence::BalanceLow, + }; + + // Provider restriction - total account balance cannot be reduced to zero if it + // cannot sustain the loss of a provider reference. + // NOTE: This assumes that the pallet is a provider (which is true). Is this + // ever changes, then this will need to adapt accordingly. + let ed = T::ExistentialDeposits::get(¤cy_id); + let success = if new_total_balance < ed { + if frame_system::Pallet::::can_dec_provider(who) { + WithdrawConsequence::ReducedToZero(new_total_balance) + } else { + return WithdrawConsequence::WouldDie; + } + } else { + WithdrawConsequence::Success + }; + + // Enough free funds to have them be reduced. + let new_free_balance = match account.free.checked_sub(&amount) { + Some(b) => b, + None => return WithdrawConsequence::BalanceLow, + }; + + // Eventual free funds must be no less than the frozen balance. + if new_free_balance < account.frozen() { + return WithdrawConsequence::Frozen; + } + + success + } + + // Ensure that an account can withdraw from their free balance given any + // existing withdrawal restrictions like locks and vesting balance. + // Is a no-op if amount to be withdrawn is zero. + pub(crate) fn ensure_can_withdraw( + currency_id: T::CurrencyId, + who: &T::AccountId, + amount: T::Balance, + ) -> DispatchResult { + if amount.is_zero() { + return Ok(()); + } + + let new_balance = Self::free_balance(currency_id, who) + .checked_sub(&amount) + .ok_or(Error::::BalanceTooLow)?; + ensure!( + new_balance >= Self::accounts(who, currency_id).frozen(), + Error::::LiquidityRestrictions + ); + Ok(()) + } + + pub(crate) fn try_mutate_account( + who: &T::AccountId, + currency_id: T::CurrencyId, + f: impl FnOnce(&mut AccountData, bool) -> sp_std::result::Result, + ) -> sp_std::result::Result<(R, Option), E> { + Accounts::::try_mutate_exists(who, currency_id, |maybe_account| { + let existed = maybe_account.is_some(); + let mut account = maybe_account.take().unwrap_or_default(); + f(&mut account, existed).map(move |result| { + let maybe_endowed = if !existed { Some(account.free) } else { None }; + let mut maybe_dust: Option = None; + let total = account.total(); + *maybe_account = if total < T::ExistentialDeposits::get(¤cy_id) { + // if ED is not zero, but account total is zero, account will be reaped + if total.is_zero() { + None + } else { + if !T::DustRemovalWhitelist::contains(who) { + maybe_dust = Some(total); + } + Some(account) + } + } else { + // Note: if ED is zero, account will never be reaped + Some(account) + }; + + (maybe_endowed, existed, maybe_account.is_some(), maybe_dust, result) + }) + }) + .map(|(maybe_endowed, existed, exists, maybe_dust, result)| { + if existed && !exists { + // If existed before, decrease account provider. + // Ignore the result, because if it failed then there are remaining consumers, + // and the account storage in frame_system shouldn't be reaped. + let _ = frame_system::Pallet::::dec_providers(who); + >::OnKilledTokenAccount::happened(&(who.clone(), currency_id)); + } else if !existed && exists { + // if new, increase account provider + frame_system::Pallet::::inc_providers(who); + >::OnNewTokenAccount::happened(&(who.clone(), currency_id)); + } + + if let Some(endowed) = maybe_endowed { + Self::deposit_event(Event::Endowed { + currency_id, + who: who.clone(), + amount: endowed, + }); + } + + if let Some(dust_amount) = maybe_dust { + // `OnDust` maybe get/set storage `Accounts` of `who`, trigger handler here + // to avoid some unexpected errors. + >::OnDust::on_dust(who, currency_id, dust_amount); + + Self::deposit_event(Event::DustLost { + currency_id, + who: who.clone(), + amount: dust_amount, + }); + } + + (result, maybe_dust) + }) + } + + pub(crate) fn mutate_account( + who: &T::AccountId, + currency_id: T::CurrencyId, + f: impl FnOnce(&mut AccountData, bool) -> R, + ) -> (R, Option) { + Self::try_mutate_account(who, currency_id, |account, existed| -> Result { + Ok(f(account, existed)) + }) + .expect("Error is infallible; qed") + } + + /// Set free balance of `who` to a new value. + /// + /// Note: this will not maintain total issuance, and the caller is expected + /// to do it. If it will cause the account to be removed dust, shouldn't use + /// it, because maybe the account that should be reaped to remain due to + /// failed transfer/withdraw dust. + pub(crate) fn set_free_balance(currency_id: T::CurrencyId, who: &T::AccountId, amount: T::Balance) { + Self::mutate_account(who, currency_id, |account, _| { + account.free = amount; + + Self::deposit_event(Event::BalanceSet { + currency_id, + who: who.clone(), + free: account.free, + reserved: account.reserved, + }); + }); + } + + /// Set reserved balance of `who` to a new value. + /// + /// Note: this will not maintain total issuance, and the caller is expected + /// to do it. If it will cause the account to be removed dust, shouldn't use + /// it, because maybe the account that should be reaped to remain due to + /// failed transfer/withdraw dust. + pub(crate) fn set_reserved_balance(currency_id: T::CurrencyId, who: &T::AccountId, amount: T::Balance) { + Self::mutate_account(who, currency_id, |account, _| { + account.reserved = amount; + + Self::deposit_event(Event::BalanceSet { + currency_id, + who: who.clone(), + free: account.free, + reserved: account.reserved, + }); + }); + } + + /// Update the account entry for `who` under `currency_id`, given the + /// locks. + pub(crate) fn update_locks( + currency_id: T::CurrencyId, + who: &T::AccountId, + locks: &[BalanceLock], + ) -> DispatchResult { + // track lock delta + let mut total_frozen_prev = Zero::zero(); + let mut total_frozen_after = Zero::zero(); + + // update account data + Self::mutate_account(who, currency_id, |account, _| { + total_frozen_prev = account.frozen; + account.frozen = Zero::zero(); + for lock in locks.iter() { + account.frozen = account.frozen.max(lock.amount); + } + total_frozen_after = account.frozen; + }); + + // update locks + let existed = Locks::::contains_key(who, currency_id); + if locks.is_empty() { + Locks::::remove(who, currency_id); + if existed { + // decrease account ref count when destruct lock + frame_system::Pallet::::dec_consumers(who); + } + } else { + let bounded_locks: BoundedVec, T::MaxLocks> = + locks.to_vec().try_into().map_err(|_| Error::::MaxLocksExceeded)?; + Locks::::insert(who, currency_id, bounded_locks); + if !existed { + // increase account ref count when initialize lock + if frame_system::Pallet::::inc_consumers(who).is_err() { + // No providers for the locks. This is impossible under normal circumstances + // since the funds that are under the lock will themselves be stored in the + // account and therefore will need a reference. + log::warn!( + "Warning: Attempt to introduce lock consumer reference, yet no providers. \ + This is unexpected but should be safe." + ); + } + } + } + + if total_frozen_prev < total_frozen_after { + let amount = total_frozen_after.saturating_sub(total_frozen_prev); + Self::deposit_event(Event::Locked { + currency_id, + who: who.clone(), + amount, + }); + } else if total_frozen_prev > total_frozen_after { + let amount = total_frozen_prev.saturating_sub(total_frozen_after); + Self::deposit_event(Event::Unlocked { + currency_id, + who: who.clone(), + amount, + }); + } + + Ok(()) + } + + /// Transfer some free balance from `from` to `to`. Ensure from_account + /// allow death or new balance will not be reaped, and ensure + /// to_account will not be removed dust. + /// + /// Is a no-op if value to be transferred is zero or the `from` is the same + /// as `to`. + pub(crate) fn do_transfer( + currency_id: T::CurrencyId, + from: &T::AccountId, + to: &T::AccountId, + amount: T::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + if amount.is_zero() || from == to { + return Ok(()); + } + + >::PreTransfer::on_transfer( + currency_id, + from, + to, + amount, + )?; + Self::try_mutate_account(to, currency_id, |to_account, _existed| -> DispatchResult { + Self::try_mutate_account(from, currency_id, |from_account, _existed| -> DispatchResult { + from_account.free = from_account + .free + .checked_sub(&amount) + .ok_or(Error::::BalanceTooLow)?; + to_account.free = to_account.free.checked_add(&amount).ok_or(ArithmeticError::Overflow)?; + + let ed = T::ExistentialDeposits::get(¤cy_id); + // if the total of `to_account` is below existential deposit, would return an + // error. + // Note: if `to_account` is in `T::DustRemovalWhitelist`, can bypass this check. + ensure!( + to_account.total() >= ed || T::DustRemovalWhitelist::contains(to), + Error::::ExistentialDeposit + ); + + Self::ensure_can_withdraw(currency_id, from, amount)?; + + let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; + let allow_death = allow_death && frame_system::Pallet::::can_dec_provider(from); + let would_be_dead = if from_account.total() < ed { + if from_account.total().is_zero() { + true + } else { + // Note: if account is not in `T::DustRemovalWhitelist`, account will eventually + // be reaped due to the dust removal. + !T::DustRemovalWhitelist::contains(from) + } + } else { + false + }; + + ensure!(allow_death || !would_be_dead, Error::::KeepAlive); + Ok(()) + })?; + Ok(()) + })?; + + >::PostTransfer::on_transfer( + currency_id, + from, + to, + amount, + )?; + Self::deposit_event(Event::Transfer { + currency_id, + from: from.clone(), + to: to.clone(), + amount, + }); + Ok(()) + } + + /// Withdraw some free balance from an account, respecting existence + /// requirements. + /// + /// `change_total_issuance`: + /// - true, decrease the total issuance by burned amount. + /// - false, do not update the total issuance. + /// + /// Is a no-op if value to be withdrawn is zero. + pub(crate) fn do_withdraw( + currency_id: T::CurrencyId, + who: &T::AccountId, + amount: T::Balance, + existence_requirement: ExistenceRequirement, + change_total_issuance: bool, + ) -> DispatchResult { + if amount.is_zero() { + return Ok(()); + } + + Self::try_mutate_account(who, currency_id, |account, _existed| -> DispatchResult { + Self::ensure_can_withdraw(currency_id, who, amount)?; + let previous_total = account.total(); + account.free = account.free.defensive_saturating_sub(amount); + + let ed = T::ExistentialDeposits::get(¤cy_id); + let would_be_dead = if account.total() < ed { + if account.total().is_zero() { + true + } else { + // Note: if account is not in `T::DustRemovalWhitelist`, account will eventually + // be reaped due to the dust removal. + !T::DustRemovalWhitelist::contains(who) + } + } else { + false + }; + let would_kill = would_be_dead && (previous_total >= ed || !previous_total.is_zero()); + ensure!( + existence_requirement == ExistenceRequirement::AllowDeath || !would_kill, + Error::::KeepAlive + ); + + if change_total_issuance { + TotalIssuance::::mutate(currency_id, |v| *v = v.defensive_saturating_sub(amount)); + } + + Self::deposit_event(Event::Withdrawn { + currency_id, + who: who.clone(), + amount, + }); + Ok(()) + })?; + + Ok(()) + } + + /// Deposit some `value` into the free balance of `who`. + /// + /// `require_existed`: + /// - true, the account must already exist, do not require ED. + /// - false, possibly creating a new account, require ED if the account does + /// not yet exist, but except this account is in the dust removal + /// whitelist. + /// + /// `change_total_issuance`: + /// - true, increase the issued amount to total issuance. + /// - false, do not update the total issuance. + pub(crate) fn do_deposit( + currency_id: T::CurrencyId, + who: &T::AccountId, + amount: T::Balance, + require_existed: bool, + change_total_issuance: bool, + ) -> Result { + if amount.is_zero() { + return Ok(amount); + } + + >::PreDeposit::on_deposit( + currency_id, + who, + amount, + )?; + Self::try_mutate_account(who, currency_id, |account, existed| -> DispatchResult { + if require_existed { + ensure!(existed, Error::::DeadAccount); + } else { + let ed = T::ExistentialDeposits::get(¤cy_id); + // Note: if who is in dust removal whitelist, allow to deposit the amount that + // below ED to it. + ensure!( + amount >= ed || existed || T::DustRemovalWhitelist::contains(who), + Error::::ExistentialDeposit + ); + } + + let new_total_issuance = Self::total_issuance(currency_id) + .checked_add(&amount) + .ok_or(ArithmeticError::Overflow)?; + if change_total_issuance { + TotalIssuance::::mutate(currency_id, |v| *v = new_total_issuance); + } + account.free = account.free.defensive_saturating_add(amount); + Ok(()) + })?; + >::PostDeposit::on_deposit( + currency_id, + who, + amount, + )?; + Self::deposit_event(Event::Deposited { + currency_id, + who: who.clone(), + amount, + }); + Ok(amount) + } +} + +impl MultiCurrency for Pallet { + type CurrencyId = T::CurrencyId; + type Balance = T::Balance; + + fn minimum_balance(currency_id: Self::CurrencyId) -> Self::Balance { + T::ExistentialDeposits::get(¤cy_id) + } + + fn total_issuance(currency_id: Self::CurrencyId) -> Self::Balance { + Self::total_issuance(currency_id) + } + + fn total_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { + Self::accounts(who, currency_id).total() + } + + fn free_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { + Self::accounts(who, currency_id).free + } + + fn ensure_can_withdraw(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + Self::ensure_can_withdraw(currency_id, who, amount) + } + + fn transfer( + currency_id: Self::CurrencyId, + from: &T::AccountId, + to: &T::AccountId, + amount: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + // allow death + Self::do_transfer(currency_id, from, to, amount, existence_requirement) + } + + fn deposit(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + // do not require existing + Self::do_deposit(currency_id, who, amount, false, true)?; + Ok(()) + } + + fn withdraw( + currency_id: Self::CurrencyId, + who: &T::AccountId, + amount: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + // allow death + Self::do_withdraw(currency_id, who, amount, existence_requirement, true) + } + + // Check if `value` amount of free balance can be slashed from `who`. + fn can_slash(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true; + } + Self::free_balance(currency_id, who) >= value + } + + /// Is a no-op if `value` to be slashed is zero. + /// + /// NOTE: `slash()` prefers free balance, but assumes that reserve + /// balance can be drawn from in extreme circumstances. `can_slash()` + /// should be used prior to `slash()` to avoid having to draw from + /// reserved funds, however we err on the side of punishment if things + /// are inconsistent or `can_slash` wasn't used appropriately. + fn slash(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> Self::Balance { + if amount.is_zero() { + return amount; + } + + >::OnSlash::on_slash( + currency_id, + who, + amount, + ); + let account = Self::accounts(who, currency_id); + let free_slashed_amount = account.free.min(amount); + // Cannot underflow because free_slashed_amount can never be greater than amount + // but just to be defensive here. + let mut remaining_slash = amount.defensive_saturating_sub(free_slashed_amount); + + // slash free balance + if !free_slashed_amount.is_zero() { + // Cannot underflow because free_slashed_amount can never be greater than + // account.free but just to be defensive here. + Self::set_free_balance( + currency_id, + who, + account.free.defensive_saturating_sub(free_slashed_amount), + ); + } + + // slash reserved balance + let reserved_slashed_amount = account.reserved.min(remaining_slash); + + if !reserved_slashed_amount.is_zero() { + // Cannot underflow due to above line but just to be defensive here. + remaining_slash = remaining_slash.defensive_saturating_sub(reserved_slashed_amount); + Self::set_reserved_balance( + currency_id, + who, + account.reserved.defensive_saturating_sub(reserved_slashed_amount), + ); + } + + // Cannot underflow because the slashed value cannot be greater than total + // issuance but just to be defensive here. + TotalIssuance::::mutate(currency_id, |v| { + *v = v.defensive_saturating_sub(amount.defensive_saturating_sub(remaining_slash)) + }); + + Self::deposit_event(Event::Slashed { + currency_id, + who: who.clone(), + free_amount: free_slashed_amount, + reserved_amount: reserved_slashed_amount, + }); + remaining_slash + } +} + +impl MultiCurrencyExtended for Pallet { + type Amount = T::Amount; + + fn update_balance(currency_id: Self::CurrencyId, who: &T::AccountId, by_amount: Self::Amount) -> DispatchResult { + if by_amount.is_zero() { + return Ok(()); + } + + // Ensure this doesn't overflow. There isn't any traits that exposes + // `saturating_abs` so we need to do it manually. + let by_amount_abs = if by_amount == Self::Amount::min_value() { + Self::Amount::max_value() + } else { + by_amount.abs() + }; + + let by_balance = + TryInto::::try_into(by_amount_abs).map_err(|_| Error::::AmountIntoBalanceFailed)?; + if by_amount.is_positive() { + Self::deposit(currency_id, who, by_balance) + } else { + Self::withdraw(currency_id, who, by_balance, ExistenceRequirement::AllowDeath).map(|_| ()) + } + } +} + +impl MultiLockableCurrency for Pallet { + type Moment = BlockNumberFor; + + // Set a lock on the balance of `who` under `currency_id`. + // Is a no-op if lock amount is zero. + fn set_lock( + lock_id: LockIdentifier, + currency_id: Self::CurrencyId, + who: &T::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + if amount.is_zero() { + return Ok(()); + } + let mut new_lock = Some(BalanceLock { id: lock_id, amount }); + let mut locks = Self::locks(who, currency_id) + .into_iter() + .filter_map(|lock| { + if lock.id == lock_id { + new_lock.take() + } else { + Some(lock) + } + }) + .collect::>(); + if let Some(lock) = new_lock { + locks.push(lock) + } + Self::update_locks(currency_id, who, &locks[..])?; + + Self::deposit_event(Event::LockSet { + lock_id, + currency_id, + who: who.clone(), + amount, + }); + Ok(()) + } + + // Extend a lock on the balance of `who` under `currency_id`. + // Is a no-op if lock amount is zero + fn extend_lock( + lock_id: LockIdentifier, + currency_id: Self::CurrencyId, + who: &T::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + if amount.is_zero() { + return Ok(()); + } + let mut new_lock = Some(BalanceLock { id: lock_id, amount }); + let mut locks = Self::locks(who, currency_id) + .into_iter() + .filter_map(|lock| { + if lock.id == lock_id { + new_lock.take().map(|nl| { + let new_amount = lock.amount.max(nl.amount); + Self::deposit_event(Event::LockSet { + lock_id, + currency_id, + who: who.clone(), + amount: new_amount, + }); + BalanceLock { + id: lock.id, + amount: new_amount, + } + }) + } else { + Some(lock) + } + }) + .collect::>(); + if let Some(lock) = new_lock { + Self::deposit_event(Event::LockSet { + lock_id, + currency_id, + who: who.clone(), + amount: lock.amount, + }); + locks.push(lock) + } + Self::update_locks(currency_id, who, &locks[..]) + } + + fn remove_lock(lock_id: LockIdentifier, currency_id: Self::CurrencyId, who: &T::AccountId) -> DispatchResult { + let mut locks = Self::locks(who, currency_id); + locks.retain(|lock| lock.id != lock_id); + let locks_vec = locks.to_vec(); + Self::update_locks(currency_id, who, &locks_vec[..])?; + + Self::deposit_event(Event::LockRemoved { + lock_id, + currency_id, + who: who.clone(), + }); + Ok(()) + } +} + +impl MultiReservableCurrency for Pallet { + /// Check if `who` can reserve `value` from their free balance. + /// + /// Always `true` if value to be reserved is zero. + fn can_reserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> bool { + if value.is_zero() { + return true; + } + Self::ensure_can_withdraw(currency_id, who, value).is_ok() + } + + /// Slash from reserved balance, returning any amount that was unable to + /// be slashed. + /// + /// Is a no-op if the value to be slashed is zero. + fn slash_reserved(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> Self::Balance { + if value.is_zero() { + return value; + } + + >::OnSlash::on_slash( + currency_id, + who, + value, + ); + let reserved_balance = Self::reserved_balance(currency_id, who); + let actual = reserved_balance.min(value); + Self::mutate_account(who, currency_id, |account, _| { + // ensured reserved_balance >= actual but just to be defensive here. + account.reserved = reserved_balance.defensive_saturating_sub(actual); + }); + TotalIssuance::::mutate(currency_id, |v| *v = v.defensive_saturating_sub(actual)); + + Self::deposit_event(Event::Slashed { + currency_id, + who: who.clone(), + free_amount: Zero::zero(), + reserved_amount: actual, + }); + value.defensive_saturating_sub(actual) + } + + fn reserved_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { + Self::accounts(who, currency_id).reserved + } + + /// Move `value` from the free balance from `who` to their reserved + /// balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> DispatchResult { + if value.is_zero() { + return Ok(()); + } + Self::ensure_can_withdraw(currency_id, who, value)?; + + Self::mutate_account(who, currency_id, |account, _| { + account.free = account.free.defensive_saturating_sub(value); + account.reserved = account.reserved.defensive_saturating_add(value); + + Self::deposit_event(Event::Reserved { + currency_id, + who: who.clone(), + amount: value, + }); + }); + + Ok(()) + } + + /// Unreserve some funds, returning any amount that was unable to be + /// unreserved. + /// + /// Is a no-op if the value to be unreserved is zero. + fn unreserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> Self::Balance { + if value.is_zero() { + return value; + } + + let (remaining, _) = Self::mutate_account(who, currency_id, |account, _| { + let actual = account.reserved.min(value); + account.reserved = account.reserved.defensive_saturating_sub(actual); + account.free = account.free.defensive_saturating_add(actual); + + Self::deposit_event(Event::Unreserved { + currency_id, + who: who.clone(), + amount: actual, + }); + value.defensive_saturating_sub(actual) + }); + + remaining + } + + /// Move the reserved balance of one account into the balance of + /// another, according to `status`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is + /// `Reserved`. + fn repatriate_reserved( + currency_id: Self::CurrencyId, + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: BalanceStatus, + ) -> sp_std::result::Result { + if value.is_zero() { + return Ok(value); + } + + if slashed == beneficiary { + return match status { + BalanceStatus::Free => Ok(Self::unreserve(currency_id, slashed, value)), + BalanceStatus::Reserved => Ok(value.saturating_sub(Self::reserved_balance(currency_id, slashed))), + }; + } + + let from_account = Self::accounts(slashed, currency_id); + let to_account = Self::accounts(beneficiary, currency_id); + let actual = from_account.reserved.min(value); + match status { + BalanceStatus::Free => { + Self::set_free_balance( + currency_id, + beneficiary, + to_account.free.defensive_saturating_add(actual), + ); + } + BalanceStatus::Reserved => { + Self::set_reserved_balance( + currency_id, + beneficiary, + to_account.reserved.defensive_saturating_add(actual), + ); + } + } + Self::set_reserved_balance( + currency_id, + slashed, + from_account.reserved.defensive_saturating_sub(actual), + ); + + Self::deposit_event(Event::::ReserveRepatriated { + currency_id, + from: slashed.clone(), + to: beneficiary.clone(), + amount: actual, + status, + }); + Ok(value.defensive_saturating_sub(actual)) + } +} + +impl NamedMultiReservableCurrency for Pallet { + type ReserveIdentifier = T::ReserveIdentifier; + + fn reserved_balance_named( + id: &Self::ReserveIdentifier, + currency_id: Self::CurrencyId, + who: &T::AccountId, + ) -> Self::Balance { + let reserves = Self::reserves(who, currency_id); + reserves + .binary_search_by_key(id, |data| data.id) + .map(|index| reserves[index].amount) + .unwrap_or_default() + } + + /// Move `value` from the free balance from `who` to a named reserve + /// balance. + /// + /// Is a no-op if value to be reserved is zero. + fn reserve_named( + id: &Self::ReserveIdentifier, + currency_id: Self::CurrencyId, + who: &T::AccountId, + value: Self::Balance, + ) -> DispatchResult { + if value.is_zero() { + return Ok(()); + } + + Reserves::::try_mutate(who, currency_id, |reserves| -> DispatchResult { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + // this add can't overflow but just to be defensive. + reserves[index].amount = reserves[index].amount.defensive_saturating_add(value); + } + Err(index) => { + reserves + .try_insert(index, ReserveData { id: *id, amount: value }) + .map_err(|_| Error::::TooManyReserves)?; + } + }; + >::reserve(currency_id, who, value) + }) + } + + /// Unreserve some funds, returning any amount that was unable to be + /// unreserved. + /// + /// Is a no-op if the value to be unreserved is zero. + fn unreserve_named( + id: &Self::ReserveIdentifier, + currency_id: Self::CurrencyId, + who: &T::AccountId, + value: Self::Balance, + ) -> Self::Balance { + if value.is_zero() { + return Zero::zero(); + } + + Reserves::::mutate_exists(who, currency_id, |maybe_reserves| -> Self::Balance { + if let Some(reserves) = maybe_reserves.as_mut() { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let remain = >::unreserve(currency_id, who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount`, but just to be defensive + // here. + reserves[index].amount = reserves[index].amount.defensive_saturating_sub(actual); + + if reserves[index].amount.is_zero() { + if reserves.len() == 1 { + // no more named reserves + *maybe_reserves = None; + } else { + // remove this named reserve + reserves.remove(index); + } + } + value.defensive_saturating_sub(actual) + } + Err(_) => value, + } + } else { + value + } + }) + } + + /// Slash from reserved balance, returning the amount that was unable to be + /// slashed. + /// + /// Is a no-op if the value to be slashed is zero. + fn slash_reserved_named( + id: &Self::ReserveIdentifier, + currency_id: Self::CurrencyId, + who: &T::AccountId, + value: Self::Balance, + ) -> Self::Balance { + if value.is_zero() { + return Zero::zero(); + } + + Reserves::::mutate(who, currency_id, |reserves| -> Self::Balance { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let remain = >::slash_reserved(currency_id, who, to_change); + + // remain should always be zero but just to be defensive here. + let actual = to_change.defensive_saturating_sub(remain); + + // `actual <= to_change` and `to_change <= amount` but just to be defensive + // here. + reserves[index].amount = reserves[index].amount.defensive_saturating_sub(actual); + + Self::deposit_event(Event::Slashed { + who: who.clone(), + currency_id, + free_amount: Zero::zero(), + reserved_amount: actual, + }); + value.defensive_saturating_sub(actual) + } + Err(_) => value, + } + }) + } + + /// Move the reserved balance of one account into the balance of another, + /// according to `status`. If `status` is `Reserved`, the balance will be + /// reserved with given `id`. + /// + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is + /// `Reserved`. + fn repatriate_reserved_named( + id: &Self::ReserveIdentifier, + currency_id: Self::CurrencyId, + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> Result { + if value.is_zero() { + return Ok(Zero::zero()); + } + + if slashed == beneficiary { + return match status { + Status::Free => Ok(Self::unreserve_named(id, currency_id, slashed, value)), + Status::Reserved => Ok(value.saturating_sub(Self::reserved_balance_named(id, currency_id, slashed))), + }; + } + + Reserves::::try_mutate( + slashed, + currency_id, + |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let to_change = cmp::min(reserves[index].amount, value); + + let actual = if status == Status::Reserved { + // make it the reserved under same identifier + Reserves::::try_mutate( + beneficiary, + currency_id, + |reserves| -> Result { + match reserves.binary_search_by_key(id, |data| data.id) { + Ok(index) => { + let remain = >::repatriate_reserved( + currency_id, + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive + // here. + let actual = to_change.defensive_saturating_sub(remain); + + // this add can't overflow but just to be defensive. + reserves[index].amount = + reserves[index].amount.defensive_saturating_add(actual); + + Ok(actual) + } + Err(index) => { + let remain = >::repatriate_reserved( + currency_id, + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive + // here + let actual = to_change.defensive_saturating_sub(remain); + + reserves + .try_insert( + index, + ReserveData { + id: *id, + amount: actual, + }, + ) + .map_err(|_| Error::::TooManyReserves)?; + + Ok(actual) + } + } + }, + )? + } else { + let remain = >::repatriate_reserved( + currency_id, + slashed, + beneficiary, + to_change, + status, + )?; + + // remain should always be zero but just to be defensive here + to_change.defensive_saturating_sub(remain) + }; + + // `actual <= to_change` and `to_change <= amount` but just to be defensive + // here. + reserves[index].amount = reserves[index].amount.defensive_saturating_sub(actual); + Ok(value.defensive_saturating_sub(actual)) + } + Err(_) => Ok(value), + } + }, + ) + } +} + +impl fungibles::Inspect for Pallet { + type AssetId = T::CurrencyId; + type Balance = T::Balance; + + fn total_issuance(asset_id: Self::AssetId) -> Self::Balance { + Self::total_issuance(asset_id) + } + + fn minimum_balance(asset_id: Self::AssetId) -> Self::Balance { + T::ExistentialDeposits::get(&asset_id) + } + + fn balance(asset_id: Self::AssetId, who: &T::AccountId) -> Self::Balance { + Self::accounts(who, asset_id).free + } + + fn total_balance(asset_id: Self::AssetId, who: &T::AccountId) -> Self::Balance { + Self::accounts(who, asset_id).total() + } + + fn reducible_balance( + asset_id: Self::AssetId, + who: &T::AccountId, + preservation: Preservation, + _force: Fortitude, + ) -> Self::Balance { + let a = Self::accounts(who, asset_id); + // Liquid balance is what is neither reserved nor locked/frozen. + let liquid = a.free.saturating_sub(a.frozen); + if frame_system::Pallet::::can_dec_provider(who) + && !matches!(preservation, Preservation::Protect | Preservation::Preserve) + { + liquid + } else { + // `must_remain_to_exist` is the part of liquid balance which must remain to + // keep total over ED. + let must_remain_to_exist = + T::ExistentialDeposits::get(&asset_id).saturating_sub(a.total().saturating_sub(liquid)); + liquid.saturating_sub(must_remain_to_exist) + } + } + + fn can_deposit( + asset_id: Self::AssetId, + who: &T::AccountId, + amount: Self::Balance, + _provenance: Provenance, + ) -> DepositConsequence { + Self::deposit_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)) + } + + fn can_withdraw( + asset_id: Self::AssetId, + who: &T::AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + Self::withdraw_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)) + } + + fn asset_exists(asset: Self::AssetId) -> bool { + TotalIssuance::::contains_key(asset) + } +} + +impl fungibles::Mutate for Pallet { + fn mint_into( + asset_id: Self::AssetId, + who: &T::AccountId, + amount: Self::Balance, + ) -> Result { + Self::deposit_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)).into_result()?; + // do not require existing + Self::do_deposit(asset_id, who, amount, false, true) + } + + fn burn_from( + asset_id: Self::AssetId, + who: &T::AccountId, + amount: Self::Balance, + // TODO: Respect preservation + _preservation: Preservation, + // TODO: Respect precision + _precision: Precision, + // TODO: Respect fortitude + _fortitude: Fortitude, + ) -> Result { + let extra = + Self::withdraw_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)).into_result(false)?; + let actual = amount.defensive_saturating_add(extra); + // allow death + Self::do_withdraw(asset_id, who, actual, ExistenceRequirement::AllowDeath, true).map(|_| actual) + } + + fn transfer( + asset_id: Self::AssetId, + source: &T::AccountId, + dest: &T::AccountId, + amount: T::Balance, + preservation: Preservation, + ) -> Result { + let existence_requirement = match preservation { + Preservation::Expendable => ExistenceRequirement::AllowDeath, + Preservation::Protect | Preservation::Preserve => ExistenceRequirement::KeepAlive, + }; + Self::do_transfer(asset_id, source, dest, amount, existence_requirement).map(|_| amount) + } +} + +impl fungibles::Unbalanced for Pallet { + fn handle_dust(_dust: fungibles::Dust) { + // Dust is handled in account mutate method + } + + fn write_balance( + asset_id: Self::AssetId, + who: &T::AccountId, + amount: Self::Balance, + ) -> Result, DispatchError> { + let max_reduction = >::reducible_balance( + asset_id, + who, + Preservation::Expendable, + Fortitude::Force, + ); + + // Balance is the same type and will not overflow + let (_, dust_amount) = Self::try_mutate_account(who, asset_id, |account, _| -> Result<(), DispatchError> { + // Make sure the reduction (if there is one) is no more than the maximum + // allowed. + let reduction = account.free.saturating_sub(amount); + ensure!(reduction <= max_reduction, Error::::BalanceTooLow); + + account.free = amount; + Self::deposit_event(Event::BalanceSet { + currency_id: asset_id, + who: who.clone(), + free: account.free, + reserved: account.reserved, + }); + + Ok(()) + })?; + + Ok(dust_amount) + } + + fn set_total_issuance(asset_id: Self::AssetId, amount: Self::Balance) { + // Balance is the same type and will not overflow + TotalIssuance::::mutate(asset_id, |t| *t = amount); + + Self::deposit_event(Event::TotalIssuanceSet { + currency_id: asset_id, + amount, + }); + } + + fn decrease_balance( + asset: Self::AssetId, + who: &T::AccountId, + mut amount: Self::Balance, + precision: Precision, + preservation: Preservation, + force: Fortitude, + ) -> Result { + let old_balance = as fungibles::Inspect>::balance(asset, who); + let free = as fungibles::Inspect>::reducible_balance(asset, who, preservation, force); + if let Precision::BestEffort = precision { + amount = amount.min(free); + } + let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?; + let _dust_amount = Self::write_balance(asset, who, new_balance)?.unwrap_or_default(); + + // here just return decrease amount, shouldn't count the dust_amount + Ok(old_balance.saturating_sub(new_balance)) + } +} + +impl fungibles::Balanced for Pallet { + type OnDropDebt = fungibles::IncreaseIssuance; + type OnDropCredit = fungibles::DecreaseIssuance; + + fn done_deposit(currency_id: Self::AssetId, who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::Deposited { + currency_id, + who: who.clone(), + amount, + }); + } + fn done_withdraw(currency_id: Self::AssetId, who: &T::AccountId, amount: Self::Balance) { + Self::deposit_event(Event::Withdrawn { + currency_id, + who: who.clone(), + amount, + }); + } + fn done_issue(currency_id: Self::AssetId, amount: Self::Balance) { + Self::deposit_event(Event::Issued { currency_id, amount }); + } + fn done_rescind(currency_id: Self::AssetId, amount: Self::Balance) { + Self::deposit_event(Event::Rescinded { currency_id, amount }); + } +} + +type ReasonOf =

::AccountId>>::Reason; +impl fungibles::InspectHold for Pallet { + type Reason = (); + + fn balance_on_hold(asset_id: Self::AssetId, _reason: &Self::Reason, who: &T::AccountId) -> T::Balance { + Self::accounts(who, asset_id).reserved + } + + fn total_balance_on_hold(asset: Self::AssetId, who: &T::AccountId) -> Self::Balance { + Self::accounts(who, asset).reserved + } + + fn reducible_total_balance_on_hold(_asset: Self::AssetId, _who: &T::AccountId, _force: Fortitude) -> Self::Balance { + 0u32.into() + } + + fn hold_available(_asset: Self::AssetId, _reason: &Self::Reason, _who: &T::AccountId) -> bool { + true + } + + fn can_hold(asset_id: Self::AssetId, _reason: &Self::Reason, who: &T::AccountId, amount: T::Balance) -> bool { + let a = Self::accounts(who, asset_id); + let min_balance = T::ExistentialDeposits::get(&asset_id).max(a.frozen); + if a.reserved.checked_add(&amount).is_none() { + return false; + } + // We require it to be min_balance + amount to ensure that the full reserved + // funds may be slashed without compromising locked funds or destroying the + // account. + let required_free = match min_balance.checked_add(&amount) { + Some(x) => x, + None => return false, + }; + a.free >= required_free + } +} + +impl fungibles::MutateHold for Pallet { + fn hold( + asset_id: Self::AssetId, + _reason: &ReasonOf, + who: &T::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + as MultiReservableCurrency<_>>::reserve(asset_id, who, amount) + } + + fn release( + asset_id: Self::AssetId, + _reason: &ReasonOf, + who: &T::AccountId, + amount: Self::Balance, + precision: Precision, + ) -> Result { + if amount.is_zero() { + return Ok(amount); + } + + // Done on a best-effort basis. + let (released, _) = + Self::try_mutate_account(who, asset_id, |a, _existed| -> Result { + let new_free = a.free.saturating_add(amount.min(a.reserved)); + let actual = new_free.defensive_saturating_sub(a.free); + // Guaranteed to be <= amount and <= a.reserved + ensure!( + matches!(precision, Precision::BestEffort) || actual == amount, + Error::::BalanceTooLow + ); + a.free = new_free; + a.reserved = a.reserved.saturating_sub(actual); + + Self::deposit_event(Event::Unreserved { + currency_id: asset_id, + who: who.clone(), + amount, + }); + Ok(actual) + })?; + + Ok(released) + } + + fn transfer_on_hold( + asset_id: Self::AssetId, + reason: &ReasonOf, + source: &T::AccountId, + dest: &T::AccountId, + amount: Self::Balance, + precision: Precision, + restriction: Restriction, + _fortitude: Fortitude, + ) -> Result { + let status = if restriction == Restriction::OnHold { + Status::Reserved + } else { + Status::Free + }; + ensure!( + amount <= >::balance_on_hold(asset_id, reason, source) + || precision == Precision::BestEffort, + Error::::BalanceTooLow + ); + let gap = Self::repatriate_reserved(asset_id, source, dest, amount, status)?; + // return actual transferred amount + Ok(amount.saturating_sub(gap)) + } +} + +impl fungibles::UnbalancedHold for Pallet { + fn set_balance_on_hold( + asset: Self::AssetId, + _reason: &Self::Reason, + who: &T::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + // Balance is the same type and will not overflow + Self::try_mutate_account(who, asset, |account, _| -> Result<(), DispatchError> { + let old_reserved = account.reserved; + account.reserved = amount; + // free = free + old - new + account.free = account + .free + .checked_add(&old_reserved) + .ok_or(ArithmeticError::Overflow)? + .checked_sub(&account.reserved) + .ok_or(TokenError::BelowMinimum)?; + + Self::deposit_event(Event::BalanceSet { + currency_id: asset, + who: who.clone(), + free: account.free, + reserved: account.reserved, + }); + + Ok(()) + }) + .map(|_| ()) + } +} + +pub struct CurrencyAdapter(marker::PhantomData<(T, GetCurrencyId)>); + +impl PalletCurrency for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + type Balance = T::Balance; + type PositiveImbalance = PositiveImbalance; + type NegativeImbalance = NegativeImbalance; + + fn total_balance(who: &T::AccountId) -> Self::Balance { + as MultiCurrency<_>>::total_balance(GetCurrencyId::get(), who) + } + + fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { + as MultiCurrency<_>>::can_slash(GetCurrencyId::get(), who, value) + } + + fn total_issuance() -> Self::Balance { + as MultiCurrency<_>>::total_issuance(GetCurrencyId::get()) + } + + fn minimum_balance() -> Self::Balance { + as MultiCurrency<_>>::minimum_balance(GetCurrencyId::get()) + } + + fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { + if amount.is_zero() { + return PositiveImbalance::zero(); + } + let currency_id = GetCurrencyId::get(); + TotalIssuance::::mutate(currency_id, |issued| { + *issued = issued.checked_sub(&amount).unwrap_or_else(|| { + amount = *issued; + Zero::zero() + }) + }); + + Pallet::::deposit_event(Event::TotalIssuanceSet { + currency_id, + amount: Self::total_issuance(), + }); + PositiveImbalance::new(amount) + } + + fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { + if amount.is_zero() { + return NegativeImbalance::zero(); + } + TotalIssuance::::mutate(GetCurrencyId::get(), |issued| { + *issued = issued.checked_add(&amount).unwrap_or_else(|| { + amount = Self::Balance::max_value().defensive_saturating_sub(*issued); + Self::Balance::max_value() + }) + }); + + Pallet::::deposit_event(Event::TotalIssuanceSet { + currency_id: GetCurrencyId::get(), + amount: Self::total_issuance(), + }); + NegativeImbalance::new(amount) + } + + fn free_balance(who: &T::AccountId) -> Self::Balance { + as MultiCurrency<_>>::free_balance(GetCurrencyId::get(), who) + } + + fn ensure_can_withdraw( + who: &T::AccountId, + amount: Self::Balance, + _reasons: WithdrawReasons, + _new_balance: Self::Balance, + ) -> DispatchResult { + as MultiCurrency<_>>::ensure_can_withdraw(GetCurrencyId::get(), who, amount) + } + + fn transfer( + source: &T::AccountId, + dest: &T::AccountId, + value: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + Pallet::::do_transfer(GetCurrencyId::get(), source, dest, value, existence_requirement) + } + + fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { + if value.is_zero() { + return (Self::NegativeImbalance::zero(), value); + } + + let currency_id = GetCurrencyId::get(); + let account = Pallet::::accounts(who, currency_id); + let free_slashed_amount = account.free.min(value); + let mut remaining_slash = value.defensive_saturating_sub(free_slashed_amount); + + // slash free balance + if !free_slashed_amount.is_zero() { + Pallet::::set_free_balance( + currency_id, + who, + account.free.defensive_saturating_sub(free_slashed_amount), + ); + } + + // slash reserved balance + if !remaining_slash.is_zero() { + let reserved_slashed_amount = account.reserved.min(remaining_slash); + remaining_slash = remaining_slash.defensive_saturating_sub(reserved_slashed_amount); + Pallet::::set_reserved_balance( + currency_id, + who, + account.reserved.defensive_saturating_sub(reserved_slashed_amount), + ); + + Pallet::::deposit_event(Event::Slashed { + currency_id, + who: who.clone(), + free_amount: free_slashed_amount, + reserved_amount: reserved_slashed_amount, + }); + ( + Self::NegativeImbalance::new(free_slashed_amount.saturating_add(reserved_slashed_amount)), + remaining_slash, + ) + } else { + Pallet::::deposit_event(Event::Slashed { + currency_id, + who: who.clone(), + free_amount: value, + reserved_amount: Zero::zero(), + }); + (Self::NegativeImbalance::new(value), remaining_slash) + } + } + + /// Deposit some `value` into the free balance of an existing target account + /// `who`. + fn deposit_into_existing( + who: &T::AccountId, + value: Self::Balance, + ) -> sp_std::result::Result { + // do not change total issuance + Pallet::::do_deposit(GetCurrencyId::get(), who, value, true, false).map(|_| PositiveImbalance::new(value)) + } + + /// Deposit some `value` into the free balance of `who`, possibly creating a + /// new account. + fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { + // do not change total issuance + Pallet::::do_deposit(GetCurrencyId::get(), who, value, false, false) + .map_or_else(|_| Self::PositiveImbalance::zero(), |_| PositiveImbalance::new(value)) + } + + fn withdraw( + who: &T::AccountId, + value: Self::Balance, + _reasons: WithdrawReasons, + liveness: ExistenceRequirement, + ) -> sp_std::result::Result { + // do not change total issuance + Pallet::::do_withdraw(GetCurrencyId::get(), who, value, liveness, false) + .map(|_| Self::NegativeImbalance::new(value)) + } + + fn make_free_balance_be( + who: &T::AccountId, + value: Self::Balance, + ) -> SignedImbalance { + let currency_id = GetCurrencyId::get(); + Pallet::::try_mutate_account( + who, + currency_id, + |account, existed| -> Result, ()> { + // If we're attempting to set an existing account to less than ED, then + // bypass the entire operation. It's a no-op if you follow it through, but + // since this is an instance where we might account for a negative imbalance + // (in the dust cleaner of set_account) before we account for its actual + // equal and opposite cause (returned as an Imbalance), then in the + // instance that there's no other accounts on the system at all, we might + // underflow the issuance and our arithmetic will be off. + let ed = T::ExistentialDeposits::get(¤cy_id); + ensure!(value.saturating_add(account.reserved) >= ed || existed, ()); + + let imbalance = if account.free <= value { + SignedImbalance::Positive(PositiveImbalance::new(value.saturating_sub(account.free))) + } else { + SignedImbalance::Negative(NegativeImbalance::new(account.free.saturating_sub(value))) + }; + account.free = value; + + Pallet::::deposit_event(Event::BalanceSet { + currency_id, + who: who.clone(), + free: value, + reserved: account.reserved, + }); + Ok(imbalance) + }, + ) + .map(|(imbalance, _)| imbalance) + .unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero())) + } +} + +impl PalletReservableCurrency for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { + as MultiReservableCurrency<_>>::can_reserve(GetCurrencyId::get(), who, value) + } + + fn slash_reserved(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { + let actual = as MultiReservableCurrency<_>>::slash_reserved(GetCurrencyId::get(), who, value); + (Self::NegativeImbalance::zero(), actual) + } + + fn reserved_balance(who: &T::AccountId) -> Self::Balance { + as MultiReservableCurrency<_>>::reserved_balance(GetCurrencyId::get(), who) + } + + fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { + as MultiReservableCurrency<_>>::reserve(GetCurrencyId::get(), who, value) + } + + fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { + as MultiReservableCurrency<_>>::unreserve(GetCurrencyId::get(), who, value) + } + + fn repatriate_reserved( + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> sp_std::result::Result { + as MultiReservableCurrency<_>>::repatriate_reserved( + GetCurrencyId::get(), + slashed, + beneficiary, + value, + status, + ) + } +} + +impl PalletNamedReservableCurrency for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + type ReserveIdentifier = T::ReserveIdentifier; + + fn reserved_balance_named(id: &Self::ReserveIdentifier, who: &T::AccountId) -> Self::Balance { + as NamedMultiReservableCurrency<_>>::reserved_balance_named(id, GetCurrencyId::get(), who) + } + + fn reserve_named(id: &Self::ReserveIdentifier, who: &T::AccountId, value: Self::Balance) -> DispatchResult { + as NamedMultiReservableCurrency<_>>::reserve_named(id, GetCurrencyId::get(), who, value) + } + + fn unreserve_named(id: &Self::ReserveIdentifier, who: &T::AccountId, value: Self::Balance) -> Self::Balance { + as NamedMultiReservableCurrency<_>>::unreserve_named(id, GetCurrencyId::get(), who, value) + } + + fn slash_reserved_named( + id: &Self::ReserveIdentifier, + who: &T::AccountId, + value: Self::Balance, + ) -> (Self::NegativeImbalance, Self::Balance) { + let actual = + as NamedMultiReservableCurrency<_>>::slash_reserved_named(id, GetCurrencyId::get(), who, value); + (Self::NegativeImbalance::zero(), actual) + } + + fn repatriate_reserved_named( + id: &Self::ReserveIdentifier, + slashed: &T::AccountId, + beneficiary: &T::AccountId, + value: Self::Balance, + status: Status, + ) -> sp_std::result::Result { + as NamedMultiReservableCurrency<_>>::repatriate_reserved_named( + id, + GetCurrencyId::get(), + slashed, + beneficiary, + value, + status, + ) + } +} + +impl PalletLockableCurrency for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + type Moment = BlockNumberFor; + type MaxLocks = (); + + fn set_lock(id: LockIdentifier, who: &T::AccountId, amount: Self::Balance, _reasons: WithdrawReasons) { + let _ = as MultiLockableCurrency<_>>::set_lock(id, GetCurrencyId::get(), who, amount); + } + + fn extend_lock(id: LockIdentifier, who: &T::AccountId, amount: Self::Balance, _reasons: WithdrawReasons) { + let _ = as MultiLockableCurrency<_>>::extend_lock(id, GetCurrencyId::get(), who, amount); + } + + fn remove_lock(id: LockIdentifier, who: &T::AccountId) { + let _ = as MultiLockableCurrency<_>>::remove_lock(id, GetCurrencyId::get(), who); + } +} + +impl TransferAll for Pallet { + #[transactional] + fn transfer_all(source: &T::AccountId, dest: &T::AccountId) -> DispatchResult { + Accounts::::iter_prefix(source).try_for_each(|(currency_id, account_data)| -> DispatchResult { + // allow death + Self::do_transfer( + currency_id, + source, + dest, + account_data.free, + ExistenceRequirement::AllowDeath, + ) + }) + } +} + +impl fungible::Inspect for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + type Balance = T::Balance; + + fn total_issuance() -> Self::Balance { + as fungibles::Inspect<_>>::total_issuance(GetCurrencyId::get()) + } + fn minimum_balance() -> Self::Balance { + as fungibles::Inspect<_>>::minimum_balance(GetCurrencyId::get()) + } + fn balance(who: &T::AccountId) -> Self::Balance { + as fungibles::Inspect<_>>::balance(GetCurrencyId::get(), who) + } + fn total_balance(who: &T::AccountId) -> Self::Balance { + as fungibles::Inspect<_>>::total_balance(GetCurrencyId::get(), who) + } + fn reducible_balance(who: &T::AccountId, preservation: Preservation, fortitude: Fortitude) -> Self::Balance { + as fungibles::Inspect<_>>::reducible_balance(GetCurrencyId::get(), who, preservation, fortitude) + } + fn can_deposit(who: &T::AccountId, amount: Self::Balance, provenance: Provenance) -> DepositConsequence { + as fungibles::Inspect<_>>::can_deposit(GetCurrencyId::get(), who, amount, provenance) + } + fn can_withdraw(who: &T::AccountId, amount: Self::Balance) -> WithdrawConsequence { + as fungibles::Inspect<_>>::can_withdraw(GetCurrencyId::get(), who, amount) + } +} + +impl fungible::Mutate for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + fn mint_into(who: &T::AccountId, amount: Self::Balance) -> Result { + as fungibles::Mutate<_>>::mint_into(GetCurrencyId::get(), who, amount) + } + fn burn_from( + who: &T::AccountId, + amount: Self::Balance, + preservation: Preservation, + precision: Precision, + fortitude: Fortitude, + ) -> Result { + as fungibles::Mutate<_>>::burn_from( + GetCurrencyId::get(), + who, + amount, + preservation, + precision, + fortitude, + ) + } + + fn transfer( + source: &T::AccountId, + dest: &T::AccountId, + amount: T::Balance, + preservation: Preservation, + ) -> Result { + as fungibles::Mutate<_>>::transfer(GetCurrencyId::get(), source, dest, amount, preservation) + } +} + +impl fungible::Unbalanced for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + fn handle_dust(_dust: fungible::Dust) { + // Dust is handled in account mutate method + } + + fn write_balance(who: &T::AccountId, amount: Self::Balance) -> Result, DispatchError> { + as fungibles::Unbalanced<_>>::write_balance(GetCurrencyId::get(), who, amount) + } + fn set_total_issuance(amount: Self::Balance) { + as fungibles::Unbalanced<_>>::set_total_issuance(GetCurrencyId::get(), amount) + } +} + +type ReasonOfFungible =

::AccountId>>::Reason; +impl fungible::InspectHold for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + type Reason = as fungibles::InspectHold>::Reason; + + fn balance_on_hold(reason: &Self::Reason, who: &T::AccountId) -> T::Balance { + as fungibles::InspectHold<_>>::balance_on_hold(GetCurrencyId::get(), reason, who) + } + fn total_balance_on_hold(who: &T::AccountId) -> Self::Balance { + as fungibles::InspectHold<_>>::total_balance_on_hold(GetCurrencyId::get(), who) + } + fn reducible_total_balance_on_hold(who: &T::AccountId, force: Fortitude) -> Self::Balance { + as fungibles::InspectHold<_>>::reducible_total_balance_on_hold(GetCurrencyId::get(), who, force) + } + fn hold_available(reason: &Self::Reason, who: &T::AccountId) -> bool { + as fungibles::InspectHold<_>>::hold_available(GetCurrencyId::get(), reason, who) + } + fn can_hold(reason: &Self::Reason, who: &T::AccountId, amount: T::Balance) -> bool { + as fungibles::InspectHold<_>>::can_hold(GetCurrencyId::get(), reason, who, amount) + } +} + +impl fungible::MutateHold for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + fn hold(reason: &ReasonOfFungible, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + as fungibles::MutateHold<_>>::hold(GetCurrencyId::get(), reason, who, amount) + } + fn release( + reason: &ReasonOfFungible, + who: &T::AccountId, + amount: Self::Balance, + precision: Precision, + ) -> Result { + as fungibles::MutateHold<_>>::release(GetCurrencyId::get(), reason, who, amount, precision) + } + fn transfer_on_hold( + reason: &ReasonOfFungible, + source: &T::AccountId, + dest: &T::AccountId, + amount: Self::Balance, + precision: Precision, + restriction: Restriction, + fortitude: Fortitude, + ) -> Result { + as fungibles::MutateHold<_>>::transfer_on_hold( + GetCurrencyId::get(), + reason, + source, + dest, + amount, + precision, + restriction, + fortitude, + ) + } +} + +impl fungible::UnbalancedHold for CurrencyAdapter +where + T: Config, + GetCurrencyId: Get, +{ + fn set_balance_on_hold(reason: &Self::Reason, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + as fungibles::UnbalancedHold<_>>::set_balance_on_hold(GetCurrencyId::get(), reason, who, amount) + } +} diff --git a/pallets/tokens/src/mock.rs b/pallets/tokens/src/mock.rs new file mode 100644 index 000000000..5e1c62392 --- /dev/null +++ b/pallets/tokens/src/mock.rs @@ -0,0 +1,445 @@ +//! Mocks for the tokens module. + +#![cfg(test)] + +use super::*; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + traits::{ + tokens::{PayFromAccount, UnityAssetBalanceConversion}, + ChangeMembers, ConstU32, ConstU64, + }, + PalletId, +}; +use orml_traits::parameter_type_with_key; +use sp_runtime::{ + traits::{AccountIdConversion, BlockNumberProvider, IdentityLookup}, + AccountId32, BuildStorage, Permill, +}; +use sp_std::cell::RefCell; + +pub type AccountId = AccountId32; +pub type CurrencyId = u32; +pub type Balance = u64; +pub type ReserveIdentifier = [u8; 8]; + +pub const DOT: CurrencyId = 1; +pub const BTC: CurrencyId = 2; +pub const ETH: CurrencyId = 3; +pub const ALICE: AccountId = AccountId32::new([0u8; 32]); +pub const BOB: AccountId = AccountId32::new([1u8; 32]); +pub const CHARLIE: AccountId = AccountId32::new([2u8; 32]); +pub const DAVE: AccountId = AccountId32::new([3u8; 32]); +pub const TREASURY_ACCOUNT: AccountId = AccountId32::new([4u8; 32]); +pub const ID_1: LockIdentifier = *b"1 "; +pub const ID_2: LockIdentifier = *b"2 "; +pub const ID_3: LockIdentifier = *b"3 "; +pub const RID_1: ReserveIdentifier = [1u8; 8]; +pub const RID_2: ReserveIdentifier = [2u8; 8]; + +use crate as tokens; + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; +} + +thread_local! { + static TEN_TO_FOURTEEN: RefCell> = RefCell::new(vec![ + AccountId32::new([10u8; 32]), + AccountId32::new([11u8; 32]), + AccountId32::new([12u8; 32]), + AccountId32::new([13u8; 32]), + AccountId32::new([14u8; 32]), + ]); +} + +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const Burn: Permill = Permill::from_percent(50); + pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); + pub const GetTokenId: CurrencyId = DOT; + pub TreasuryAccount: AccountId = Treasury::account_id(); +} + +pub type MockCurrencyAdapter = CurrencyAdapter; + +parameter_types! { + pub static MockBlockNumberProvider: u64 = 0; +} + +impl BlockNumberProvider for MockBlockNumberProvider { + type BlockNumber = u64; + + fn current_block_number() -> BlockNumberFor { + Self::get() + } +} + +impl pallet_treasury::Config for Runtime { + type PalletId = TreasuryPalletId; + type Currency = MockCurrencyAdapter; + type RejectOrigin = frame_system::EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type SpendPeriod = ConstU64<2>; + type Burn = Burn; + type BurnDestination = (); // Just gets burned. + type WeightInfo = (); + type SpendFunds = (); + type MaxApprovals = ConstU32<100>; + type SpendOrigin = frame_support::traits::NeverEnsureOrigin; + type AssetKind = (); + type Beneficiary = Self::AccountId; + type BeneficiaryLookup = IdentityLookup; + type Paymaster = PayFromAccount; + type BalanceConverter = UnityAssetBalanceConversion; + type PayoutPeriod = ConstU64<10>; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + type BlockNumberProvider = MockBlockNumberProvider; +} + +thread_local! { + pub static MEMBERS: RefCell> = RefCell::new(vec![]); + pub static PRIME: RefCell> = RefCell::new(None); +} + +pub struct TestChangeMembers; +impl ChangeMembers for TestChangeMembers { + fn change_members_sorted(incoming: &[AccountId], outgoing: &[AccountId], new: &[AccountId]) { + // new, incoming, outgoing must be sorted. + let mut new_sorted = new.to_vec(); + new_sorted.sort(); + assert_eq!(new, &new_sorted[..]); + + let mut incoming_sorted = incoming.to_vec(); + incoming_sorted.sort(); + assert_eq!(incoming, &incoming_sorted[..]); + + let mut outgoing_sorted = outgoing.to_vec(); + outgoing_sorted.sort(); + assert_eq!(outgoing, &outgoing_sorted[..]); + + // incoming and outgoing must be disjoint + for x in incoming.iter() { + assert!(outgoing.binary_search(x).is_err()); + } + + let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); + old_plus_incoming.extend_from_slice(incoming); + old_plus_incoming.sort(); + + let mut new_plus_outgoing = new.to_vec(); + new_plus_outgoing.extend_from_slice(outgoing); + new_plus_outgoing.sort(); + + assert_eq!( + old_plus_incoming, new_plus_outgoing, + "change members call is incorrect!" + ); + + MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); + PRIME.with(|p| *p.borrow_mut() = None); + } + + fn set_prime(who: Option) { + PRIME.with(|p| *p.borrow_mut() = who); + } +} + +parameter_types! { + pub const ElectionsPhragmenPalletId: LockIdentifier = *b"phrelect"; +} + +impl pallet_elections_phragmen::Config for Runtime { + type PalletId = ElectionsPhragmenPalletId; + type RuntimeEvent = RuntimeEvent; + type Currency = MockCurrencyAdapter; + type CurrencyToVote = sp_staking::currency_to_vote::SaturatingCurrencyToVote; + type ChangeMembers = TestChangeMembers; + type InitializeMembers = (); + type CandidacyBond = ConstU64<3>; + type VotingBondBase = ConstU64<2>; + type VotingBondFactor = ConstU64<0>; + type TermDuration = ConstU64<5>; + type DesiredMembers = ConstU32<2>; + type DesiredRunnersUp = ConstU32<2>; + type MaxCandidates = ConstU32<5>; + type MaxVoters = ConstU32<5>; + type MaxVotesPerVoter = (); + type LoserCandidate = (); + type KickedMember = (); + type WeightInfo = (); +} + +pub struct MockDustRemovalWhitelist; +impl Contains for MockDustRemovalWhitelist { + fn contains(a: &AccountId) -> bool { + *a == DAVE || *a == DustReceiver::get() + } +} + +parameter_type_with_key! { + pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance { + #[allow(clippy::match_ref_pats)] // false positive + match currency_id { + &BTC => 1, + &DOT => 2, + _ => 0, + } + }; +} + +thread_local! { + pub static CREATED: RefCell> = RefCell::new(vec![]); + pub static KILLED: RefCell> = RefCell::new(vec![]); +} + +pub struct TrackCreatedAccounts(marker::PhantomData); +impl TrackCreatedAccounts +where + T::AccountId: From + Into, + T::CurrencyId: From + Into, +{ + pub fn accounts() -> Vec<(T::AccountId, T::CurrencyId)> { + CREATED + .with(|accounts| accounts.borrow().clone()) + .iter() + .map(|account| (account.0.clone().into(), account.1.clone().into())) + .collect() + } + + pub fn reset() { + CREATED.with(|accounts| { + accounts.replace(vec![]); + }); + } +} +impl Happened<(T::AccountId, T::CurrencyId)> for TrackCreatedAccounts +where + T::AccountId: From + Into, + T::CurrencyId: From + Into, +{ + fn happened((who, currency): &(T::AccountId, T::CurrencyId)) { + CREATED.with(|accounts| { + accounts.borrow_mut().push((who.clone().into(), (*currency).into())); + }); + } +} + +pub struct TrackKilledAccounts(marker::PhantomData); +impl TrackKilledAccounts +where + T::AccountId: From + Into, + T::CurrencyId: From + Into, +{ + pub fn accounts() -> Vec<(T::AccountId, T::CurrencyId)> { + KILLED + .with(|accounts| accounts.borrow().clone()) + .iter() + .map(|account| (account.0.clone().into(), account.1.clone().into())) + .collect() + } + + pub fn reset() { + KILLED.with(|accounts| { + accounts.replace(vec![]); + }); + } +} +impl Happened<(T::AccountId, T::CurrencyId)> for TrackKilledAccounts +where + T::AccountId: From + Into, + T::CurrencyId: From + Into, +{ + fn happened((who, currency): &(T::AccountId, T::CurrencyId)) { + KILLED.with(|accounts| { + accounts.borrow_mut().push((who.clone().into(), (*currency).into())); + }); + } +} + +thread_local! { + pub static ON_SLASH_CALLS: RefCell = RefCell::new(0); + pub static ON_DEPOSIT_PREHOOK_CALLS: RefCell = RefCell::new(0); + pub static ON_DEPOSIT_POSTHOOK_CALLS: RefCell = RefCell::new(0); + pub static ON_TRANSFER_PREHOOK_CALLS: RefCell = RefCell::new(0); + pub static ON_TRANSFER_POSTHOOK_CALLS: RefCell = RefCell::new(0); +} + +pub struct OnSlashHook(marker::PhantomData); +impl OnSlash for OnSlashHook { + fn on_slash(_currency_id: T::CurrencyId, _account_id: &T::AccountId, _amount: T::Balance) { + ON_SLASH_CALLS.with(|cell| *cell.borrow_mut() += 1); + } +} +impl OnSlashHook { + pub fn calls() -> u32 { + ON_SLASH_CALLS.with(|accounts| *accounts.borrow()) + } +} + +pub struct PreDeposit(marker::PhantomData); +impl OnDeposit for PreDeposit { + fn on_deposit(_currency_id: T::CurrencyId, _account_id: &T::AccountId, _amount: T::Balance) -> DispatchResult { + ON_DEPOSIT_PREHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); + Ok(()) + } +} +impl PreDeposit { + pub fn calls() -> u32 { + ON_DEPOSIT_PREHOOK_CALLS.with(|accounts| accounts.borrow().clone()) + } +} + +pub struct PostDeposit(marker::PhantomData); +impl OnDeposit for PostDeposit { + fn on_deposit(currency_id: T::CurrencyId, account_id: &T::AccountId, amount: T::Balance) -> DispatchResult { + ON_DEPOSIT_POSTHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); + let account_balance: AccountData = + tokens::Pallet::::accounts::(account_id.clone(), currency_id); + assert!( + account_balance.free.ge(&amount), + "Posthook must run after the account balance is updated." + ); + Ok(()) + } +} +impl PostDeposit { + pub fn calls() -> u32 { + ON_DEPOSIT_POSTHOOK_CALLS.with(|accounts| accounts.borrow().clone()) + } +} + +pub struct PreTransfer(marker::PhantomData); +impl OnTransfer for PreTransfer { + fn on_transfer( + _currency_id: T::CurrencyId, + _from: &T::AccountId, + _to: &T::AccountId, + _amount: T::Balance, + ) -> DispatchResult { + ON_TRANSFER_PREHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); + Ok(()) + } +} +impl PreTransfer { + pub fn calls() -> u32 { + ON_TRANSFER_PREHOOK_CALLS.with(|accounts| accounts.borrow().clone()) + } +} + +pub struct PostTransfer(marker::PhantomData); +impl OnTransfer for PostTransfer { + fn on_transfer( + currency_id: T::CurrencyId, + _from: &T::AccountId, + to: &T::AccountId, + amount: T::Balance, + ) -> DispatchResult { + ON_TRANSFER_POSTHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); + let account_balance: AccountData = + tokens::Pallet::::accounts::(to.clone(), currency_id); + assert!( + account_balance.free.ge(&amount), + "Posthook must run after the account balance is updated." + ); + Ok(()) + } +} +impl PostTransfer { + pub fn calls() -> u32 { + ON_TRANSFER_POSTHOOK_CALLS.with(|accounts| accounts.borrow().clone()) + } +} + +parameter_types! { + pub DustReceiver: AccountId = PalletId(*b"orml/dst").into_account_truncating(); +} + +pub struct CurrencyHooks(marker::PhantomData); +impl MutationHooks for CurrencyHooks +where + T::AccountId: From + Into, + T::CurrencyId: From + Into, +{ + type OnDust = TransferDust; + type OnSlash = OnSlashHook; + type PreDeposit = PreDeposit; + type PostDeposit = PostDeposit; + type PreTransfer = PreTransfer; + type PostTransfer = PostTransfer; + type OnNewTokenAccount = TrackCreatedAccounts; + type OnKilledTokenAccount = TrackKilledAccounts; +} + +impl Config for Runtime { + type Balance = Balance; + type Amount = i64; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type CurrencyHooks = CurrencyHooks; + type MaxLocks = ConstU32<2>; + type MaxReserves = ConstU32<2>; + type ReserveIdentifier = ReserveIdentifier; + type DustRemovalWhitelist = MockDustRemovalWhitelist; +} +pub type TreasuryCurrencyAdapter = ::Currency; + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime { + System: frame_system, + Tokens: tokens, + Treasury: pallet_treasury, + ElectionsPhragmen: pallet_elections_phragmen, + } +); + +#[derive(Default)] +pub struct ExtBuilder { + balances: Vec<(AccountId, CurrencyId, Balance)>, + treasury_genesis: bool, +} + +impl ExtBuilder { + pub fn balances(mut self, mut balances: Vec<(AccountId, CurrencyId, Balance)>) -> Self { + self.balances.append(&mut balances); + self + } + + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap(); + + tokens::GenesisConfig:: { + balances: self.balances, + } + .assimilate_storage(&mut t) + .unwrap(); + + if self.treasury_genesis { + pallet_treasury::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + + pallet_elections_phragmen::GenesisConfig:: { + members: vec![(TREASURY_ACCOUNT, 10)], + } + .assimilate_storage(&mut t) + .unwrap(); + } + + TrackCreatedAccounts::::reset(); + TrackKilledAccounts::::reset(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} diff --git a/pallets/tokens/src/tests.rs b/pallets/tokens/src/tests.rs new file mode 100644 index 000000000..f042cf361 --- /dev/null +++ b/pallets/tokens/src/tests.rs @@ -0,0 +1,1271 @@ +//! Unit tests for the tokens module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use frame_system::RawOrigin; +use mock::*; +use sp_runtime::{traits::BadOrigin, TokenError}; + +// ************************************************* +// tests for genesis +// ************************************************* + +#[test] +fn genesis_issuance_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); + assert_eq!(Tokens::total_issuance(DOT), 200); + }); +} + +// ************************************************* +// tests for call +// ************************************************* + +#[test] +fn transfer_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::transfer(Some(ALICE).into(), BOB, DOT, 50)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 50, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::free_balance(DOT, &BOB), 150); + assert_eq!(Tokens::total_issuance(DOT), 200); + + assert_noop!( + Tokens::transfer(Some(ALICE).into(), BOB, DOT, 60), + Error::::BalanceTooLow, + ); + assert_noop!( + Tokens::transfer(Some(ALICE).into(), CHARLIE, DOT, 1), + Error::::ExistentialDeposit, + ); + assert_ok!(Tokens::transfer(Some(ALICE).into(), CHARLIE, DOT, 2)); + assert_eq!(TrackCreatedAccounts::::accounts(), vec![(CHARLIE, DOT)]); + + // imply AllowDeath + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_ok!(Tokens::transfer(Some(ALICE).into(), BOB, DOT, 48)); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &BOB), 198); + assert_eq!(Tokens::total_issuance(DOT), 200); + }); +} + +#[test] +fn transfer_keep_alive_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + + // imply KeepAlive + assert_noop!( + Tokens::transfer_keep_alive(Some(ALICE).into(), BOB, DOT, 99), + Error::::KeepAlive, + ); + + assert_ok!(Tokens::transfer_keep_alive(Some(ALICE).into(), BOB, DOT, 98)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 98, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 2); + assert_eq!(Tokens::free_balance(DOT, &BOB), 198); + }); +} + +#[test] +fn transfer_all_keep_alive_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, DOT, true)); + System::assert_has_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: CHARLIE, + amount: 98, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 2); + + assert_ok!(Tokens::set_lock(ID_1, DOT, &BOB, 50)); + assert_eq!(Tokens::accounts(&BOB, DOT).frozen, 50); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_ok!(Tokens::transfer_all(Some(BOB).into(), CHARLIE, DOT, true)); + System::assert_has_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: BOB, + to: CHARLIE, + amount: 50, + })); + }); +} + +#[test] +fn transfer_all_allow_death_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, DOT, false)); + assert_eq!(TrackCreatedAccounts::::accounts(), vec![(CHARLIE, DOT)]); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: CHARLIE, + amount: 100, + })); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(TrackKilledAccounts::::accounts(), vec![(ALICE, DOT)]); + + assert_ok!(Tokens::set_lock(ID_1, DOT, &BOB, 50)); + assert_eq!(Tokens::accounts(&BOB, DOT).frozen, 50); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_ok!(Tokens::transfer_all(Some(BOB).into(), CHARLIE, DOT, false)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: BOB, + to: CHARLIE, + amount: 50, + })); + }); +} + +#[test] +fn force_transfer_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_noop!( + Tokens::force_transfer(Some(ALICE).into(), ALICE, BOB, DOT, 100), + BadOrigin + ); + + // imply AllowDeath + assert_ok!(Tokens::force_transfer(RawOrigin::Root.into(), ALICE, BOB, DOT, 100)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 100, + })); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(TrackKilledAccounts::::accounts(), vec![(ALICE, DOT)]); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &BOB), 200); + }); +} + +#[test] +fn set_balance_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + // bad origin + assert_noop!(Tokens::set_balance(Some(ALICE).into(), ALICE, DOT, 200, 100), BadOrigin); + + // total balance overflow + assert_noop!( + Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, Balance::max_value(), 1), + ArithmeticError::Overflow + ); + + // total issurance overflow + assert_noop!( + Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, Balance::max_value(), 0), + ArithmeticError::Overflow + ); + + // total issurance overflow + assert_noop!( + Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, Balance::max_value(), 0), + ArithmeticError::Overflow + ); + + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 200); + + assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, 200, 100)); + System::assert_has_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { + currency_id: DOT, + who: ALICE, + free: 200, + reserved: 100, + })); + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 200); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::total_issuance(DOT), 400); + + assert!(Accounts::::contains_key(BOB, DOT)); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); + + assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), BOB, DOT, 0, 0)); + System::assert_has_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { + currency_id: DOT, + who: BOB, + free: 0, + reserved: 0, + })); + assert!(!Accounts::::contains_key(BOB, DOT)); + assert_eq!(Tokens::free_balance(DOT, &BOB), 0); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); + assert_eq!(Tokens::total_issuance(DOT), 300); + + assert!(!Accounts::::contains_key(CHARLIE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); + assert_eq!(Tokens::reserved_balance(DOT, &CHARLIE), 0); + + // below ED, + assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), CHARLIE, DOT, 1, 0)); + System::assert_has_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { + currency_id: DOT, + who: CHARLIE, + free: 0, + reserved: 0, + })); + assert!(!Accounts::::contains_key(CHARLIE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); + assert_eq!(Tokens::reserved_balance(DOT, &CHARLIE), 0); + assert_eq!(Tokens::total_issuance(DOT), 300); + }); +} + +// ************************************************* +// tests for inline impl +// ************************************************* + +#[test] +fn deposit_consequence_should_work() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + Tokens::deposit_consequence( + &CHARLIE, + DOT, + 0, + &AccountData { + free: 1, + reserved: 0, + frozen: 0 + } + ) + .into_result(), + Ok(()) + ); + + // total issuance overflow + assert_eq!( + Tokens::deposit_consequence( + &CHARLIE, + DOT, + Balance::max_value(), + &AccountData { + free: 1, + reserved: 0, + frozen: 0 + } + ) + .into_result(), + Err(ArithmeticError::Overflow.into()) + ); + + // total balance overflow + assert_eq!( + Tokens::deposit_consequence( + &CHARLIE, + DOT, + 1, + &AccountData { + free: Balance::max_value(), + reserved: 0, + frozen: 0 + } + ) + .into_result(), + Err(ArithmeticError::Overflow.into()) + ); + + // below ed + assert_eq!( + Tokens::deposit_consequence( + &CHARLIE, + DOT, + 1, + &AccountData { + free: 0, + reserved: 0, + frozen: 0 + } + ) + .into_result(), + Err(TokenError::BelowMinimum.into()) + ); + + assert_eq!( + Tokens::deposit_consequence( + &CHARLIE, + DOT, + 1, + &AccountData { + free: 1, + reserved: 0, + frozen: 0 + } + ) + .into_result(), + Ok(()) + ); + }); +} + +#[test] +fn withdraw_consequence_should_work() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + Tokens::withdraw_consequence( + &ALICE, + DOT, + 0, + &AccountData { + free: 1, + reserved: 0, + frozen: 0 + } + ) + .into_result(true), + Ok(Zero::zero()) + ); + + // total issuance underflow + assert_ok!(Tokens::update_balance(DOT, &ALICE, 2)); + assert_eq!(Tokens::total_issuance(DOT), 2); + assert_eq!( + Tokens::withdraw_consequence( + &ALICE, + DOT, + 3, + &AccountData { + free: 1, + reserved: 0, + frozen: 0 + } + ) + .into_result(true), + Err(ArithmeticError::Underflow.into()) + ); + + // total issuance is not enough + assert_eq!( + Tokens::withdraw_consequence( + &ALICE, + DOT, + 2, + &AccountData { + free: 1, + reserved: 0, + frozen: 0 + } + ) + .into_result(true), + Err(TokenError::FundsUnavailable.into()) + ); + + // below ED and cannot dec provider + assert_ok!(Tokens::update_balance(DOT, &ALICE, 2)); + assert_eq!(System::providers(&ALICE), 1); + assert_ok!(System::inc_consumers(&ALICE)); + assert!(!System::can_dec_provider(&ALICE)); + assert_eq!( + Tokens::withdraw_consequence( + &ALICE, + DOT, + 1, + &AccountData { + free: 2, + reserved: 0, + frozen: 0 + } + ) + .into_result(true), + Err(TokenError::OnlyProvider.into()) + ); + + // below ED and can dec provider + let _ = System::inc_providers(&ALICE); + assert!(System::can_dec_provider(&ALICE)); + assert_eq!( + Tokens::withdraw_consequence( + &ALICE, + DOT, + 1, + &AccountData { + free: 2, + reserved: 0, + frozen: 0 + } + ) + .into_result(false), + Ok(1) + ); + + // free balance is not enough + assert_eq!( + Tokens::withdraw_consequence( + &ALICE, + DOT, + 2, + &AccountData { + free: 1, + reserved: 1, + frozen: 0 + } + ) + .into_result(true), + Err(TokenError::FundsUnavailable.into()) + ); + + // less to frozen balance + assert_eq!( + Tokens::withdraw_consequence( + &ALICE, + DOT, + 2, + &AccountData { + free: 2, + reserved: 0, + frozen: 2 + } + ) + .into_result(true), + Err(TokenError::Frozen.into()) + ); + }); +} + +#[test] +fn ensure_can_withdraw_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + + assert_noop!( + Tokens::ensure_can_withdraw(DOT, &ALICE, 101), + Error::::BalanceTooLow + ); + + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 50)); + assert_noop!( + Tokens::ensure_can_withdraw(DOT, &ALICE, 51), + Error::::LiquidityRestrictions + ); + + assert_ok!(Tokens::ensure_can_withdraw(DOT, &ALICE, 50)); + }); +} + +#[test] +fn set_free_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + /* Scenarios: ED is not zero, account is not in dust removal whitelist */ + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); + assert_eq!(Tokens::total_issuance(DOT), 0); + + // when total is below ED, account will be reaped. + Tokens::set_free_balance(DOT, &ALICE, 1); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); + // set_free_balance do not change total issuance. + assert_eq!(Tokens::total_issuance(DOT), 0); + + Tokens::set_free_balance(DOT, &ALICE, 2); + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 2); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); + + /* Scenarios: ED is not zero, account is in dust removal whitelist */ + assert!(!Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); + + // set zero will not create account + Tokens::set_free_balance(DOT, &DAVE, 0); + assert!(!Accounts::::contains_key(DAVE, DOT)); + + // when total is below ED, account will not be reaped. + Tokens::set_free_balance(DOT, &DAVE, 1); + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); + + /* Scenarios: ED is zero */ + assert!(!Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &ALICE), 0); + assert_eq!(Tokens::free_balance(ETH, &DustReceiver::get()), 0); + + // set zero will create account + Tokens::set_free_balance(ETH, &ALICE, 0); + assert!(Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &ALICE), 0); + assert_eq!(Tokens::free_balance(ETH, &DustReceiver::get()), 0); + }); +} + +#[test] +fn set_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + /* Scenarios: ED is not zero, account is not in dust removal whitelist */ + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 0); + + // when total is below ED, account should be reaped. + Tokens::set_reserved_balance(DOT, &ALICE, 1); + // but reap it failed because failed to transfer/withdraw dust removal!!! + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 1); + // set_reserved_balance do not change total issuance. + assert_eq!(Tokens::total_issuance(DOT), 0); + + Tokens::set_reserved_balance(DOT, &ALICE, 2); + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 2); + + /* Scenarios: ED is not zero, account is in dust removal whitelist */ + assert!(!Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); + + // set zero will not create account + Tokens::set_reserved_balance(DOT, &DAVE, 0); + assert!(!Accounts::::contains_key(DAVE, DOT)); + + // when total is below ED, account shouldn't be reaped. + Tokens::set_reserved_balance(DOT, &DAVE, 1); + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::reserved_balance(DOT, &DAVE), 1); + + /* Scenarios: ED is zero */ + assert!(!Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::reserved_balance(ETH, &ALICE), 0); + + // set zero will create account + Tokens::set_reserved_balance(ETH, &ALICE, 0); + assert!(Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::reserved_balance(ETH, &ALICE), 0); + }); +} + +#[test] +fn do_transfer_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + // always ok when from == to + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &ALICE, + 101, + ExistenceRequirement::KeepAlive + )); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); + + assert_noop!( + Tokens::do_transfer(DOT, &ALICE, &BOB, 101, ExistenceRequirement::KeepAlive), + Error::::BalanceTooLow + ); + assert_noop!( + Tokens::do_transfer(DOT, &ALICE, &CHARLIE, 1, ExistenceRequirement::KeepAlive), + Error::::ExistentialDeposit + ); + + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &BOB, + 100, + ExistenceRequirement::AllowDeath + )); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &BOB), 200); + }); +} + +#[test] +fn do_transfer_dust_removal_when_allow_death() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); + + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &BOB, + 99, + ExistenceRequirement::AllowDeath + )); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &BOB), 199); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); + }); +} + +#[test] +fn do_transfer_report_keep_alive_error_when_ed_is_not_zero() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (DAVE, DOT, 100)]) + .build() + .execute_with(|| { + // total of alice will below ED, account will be reaped. + assert_noop!( + Tokens::do_transfer(DOT, &ALICE, &BOB, 99, ExistenceRequirement::KeepAlive), + Error::::KeepAlive + ); + + // even if dave is in dust removal whitelist, but account drain will still cause + // account be reaped. + assert_noop!( + Tokens::do_transfer(DOT, &DAVE, &BOB, 100, ExistenceRequirement::KeepAlive), + Error::::KeepAlive + ); + + // as long as do not transfer all balance, even if the total is below ED, the + // account will not be reaped. + assert_eq!(Tokens::free_balance(DOT, &DAVE), 100); + assert_eq!(Tokens::free_balance(DOT, &BOB), 0); + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_ok!(Tokens::do_transfer( + DOT, + &DAVE, + &BOB, + 99, + ExistenceRequirement::KeepAlive + )); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); + assert_eq!(Tokens::free_balance(DOT, &BOB), 99); + assert!(Accounts::::contains_key(DAVE, DOT)); + }); +} + +#[test] +fn do_transfer_will_not_report_keep_alive_error_when_ed_is_zero() { + ExtBuilder::default() + .balances(vec![(ALICE, ETH, 100), (DAVE, ETH, 100)]) + .build() + .execute_with(|| { + assert!(Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &ALICE), 100); + assert_eq!(Tokens::free_balance(ETH, &BOB), 0); + assert_ok!(Tokens::do_transfer( + ETH, + &ALICE, + &BOB, + 99, + ExistenceRequirement::KeepAlive + )); + assert!(Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &ALICE), 1); + assert_eq!(Tokens::free_balance(ETH, &BOB), 99); + + // account that total is zero will not be reaped because ED is zero + assert!(Accounts::::contains_key(DAVE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &DAVE), 100); + assert_ok!(Tokens::do_transfer( + ETH, + &DAVE, + &BOB, + 100, + ExistenceRequirement::KeepAlive + )); + assert!(Accounts::::contains_key(DAVE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &DAVE), 0); + assert_eq!(Tokens::free_balance(ETH, &BOB), 199); + }); +} + +#[test] +fn do_transfer_report_keep_alive_error_due_to_cannot_dec_provider_when_allow_death() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (DAVE, DOT, 100)]) + .build() + .execute_with(|| { + assert!(System::can_dec_provider(&ALICE)); + assert_ok!(System::inc_consumers(&ALICE)); + assert!(!System::can_dec_provider(&ALICE)); + assert_noop!( + Tokens::do_transfer(DOT, &ALICE, &BOB, 99, ExistenceRequirement::AllowDeath), + Error::::KeepAlive + ); + + assert_ok!(Tokens::deposit(BTC, &ALICE, 100)); + assert!(System::can_dec_provider(&ALICE)); + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &BOB, + 99, + ExistenceRequirement::AllowDeath + )); + }); +} + +#[test] +fn do_transfer_report_existential_deposit_error_when_ed_is_not_zero() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_noop!( + Tokens::do_transfer(DOT, &ALICE, &BOB, 1, ExistenceRequirement::KeepAlive), + Error::::ExistentialDeposit + ); + + // if receiver is in dust removal whitelist, will not be reaped. + assert!(!Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &DAVE, + 1, + ExistenceRequirement::KeepAlive + )); + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); + }); +} + +#[test] +fn do_withdraw_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + // always ok if amount is zero + assert!(!Accounts::::contains_key(BOB, DOT)); + assert_ok!(Tokens::do_withdraw(DOT, &BOB, 0, ExistenceRequirement::KeepAlive, true)); + assert!(!Accounts::::contains_key(BOB, DOT)); + + assert_noop!( + Tokens::do_withdraw(DOT, &ALICE, 101, ExistenceRequirement::KeepAlive, true), + Error::::BalanceTooLow + ); + + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert_noop!( + Tokens::do_withdraw(DOT, &ALICE, 91, ExistenceRequirement::KeepAlive, true), + Error::::LiquidityRestrictions + ); + + // change issuance + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_ok!(Tokens::do_withdraw( + DOT, + &ALICE, + 10, + ExistenceRequirement::KeepAlive, + true + )); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 90); + assert_eq!(Tokens::total_issuance(DOT), 90); + + // do not change issuance + assert_ok!(Tokens::do_withdraw( + DOT, + &ALICE, + 10, + ExistenceRequirement::KeepAlive, + false + )); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 80); + assert_eq!(Tokens::total_issuance(DOT), 90); + }); +} + +#[test] +fn do_withdraw_dust_removal_when_allow_death() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::total_issuance(DOT), 100); + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); + + assert_ok!(Tokens::do_withdraw( + DOT, + &ALICE, + 99, + ExistenceRequirement::AllowDeath, + true + )); + assert_eq!(Tokens::total_issuance(DOT), 1); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); + }); +} + +#[test] +fn do_withdraw_report_keep_alive_error_when_ed_is_not_zero() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (DAVE, DOT, 100)]) + .build() + .execute_with(|| { + assert_noop!( + Tokens::do_withdraw(DOT, &ALICE, 99, ExistenceRequirement::KeepAlive, true), + Error::::KeepAlive + ); + + // dave is in dust removal whitelist, still can withdraw if remainder is not + // zero but below ED. + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 100); + assert_eq!(Tokens::total_issuance(DOT), 200); + assert_ok!(Tokens::do_withdraw( + DOT, + &DAVE, + 99, + ExistenceRequirement::KeepAlive, + true + )); + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); + assert_eq!(Tokens::total_issuance(DOT), 101); + + // even if dave is in dust removal whitelist, but if withdraw all total of it + // will still cause account reaped. + assert_noop!( + Tokens::do_withdraw(DOT, &DAVE, 1, ExistenceRequirement::KeepAlive, true), + Error::::KeepAlive + ); + }); +} + +#[test] +fn do_withdraw_will_not_report_keep_alive_error_when_ed_is_zero() { + ExtBuilder::default() + .balances(vec![(ALICE, ETH, 100), (DAVE, ETH, 100)]) + .build() + .execute_with(|| { + assert!(Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &ALICE), 100); + assert_eq!(Tokens::total_issuance(ETH), 200); + assert_ok!(Tokens::do_withdraw( + ETH, + &ALICE, + 100, + ExistenceRequirement::KeepAlive, + true + )); + assert!(Accounts::::contains_key(ALICE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &ALICE), 0); + assert_eq!(Tokens::total_issuance(ETH), 100); + + assert!(Accounts::::contains_key(DAVE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &DAVE), 100); + assert_ok!(Tokens::do_withdraw( + ETH, + &DAVE, + 100, + ExistenceRequirement::KeepAlive, + true + )); + assert!(Accounts::::contains_key(DAVE, ETH)); + assert_eq!(Tokens::free_balance(ETH, &DAVE), 0); + assert_eq!(Tokens::total_issuance(ETH), 0); + }); +} + +#[test] +fn do_deposit_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + // always ok if deposit amount is zero + assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 0, true, true)); + assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 0, false, true)); + + assert!(!Accounts::::contains_key(CHARLIE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 10, false, true)); + assert!(Accounts::::contains_key(CHARLIE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 10); + assert_eq!(Tokens::total_issuance(DOT), 110); + + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_ok!(Tokens::do_deposit(DOT, &ALICE, 10, true, true)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 110); + assert_eq!(Tokens::total_issuance(DOT), 120); + + assert_noop!( + Tokens::do_deposit(DOT, &ALICE, Balance::max_value(), false, true), + ArithmeticError::Overflow + ); + + // do not change issuance + assert_ok!(Tokens::do_deposit(DOT, &ALICE, 100, true, false)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 210); + assert_eq!(Tokens::total_issuance(DOT), 120); + }); +} + +#[test] +fn do_deposit_report_dead_account_error() { + ExtBuilder::default().build().execute_with(|| { + assert!(!Accounts::::contains_key(CHARLIE, DOT)); + assert_noop!( + Tokens::do_deposit(DOT, &CHARLIE, 10, true, true), + Error::::DeadAccount + ); + }); +} + +#[test] +fn do_deposit_report_existential_deposit_error() { + ExtBuilder::default().build().execute_with(|| { + assert!(!Accounts::::contains_key(CHARLIE, DOT)); + assert_noop!( + Tokens::do_deposit(DOT, &CHARLIE, 1, false, true), + Error::::ExistentialDeposit + ); + + assert!(!Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); + assert_eq!(Tokens::total_issuance(DOT), 0); + assert_ok!(Tokens::do_deposit(DOT, &DAVE, 1, false, true)); + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); + assert_eq!(Tokens::total_issuance(DOT), 1); + }); +} + +// ************************************************* +// tests for endowed account and remove account +// ************************************************* + +#[test] +fn endowed_account_work() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(System::providers(&ALICE), 0); + assert!(!Accounts::::contains_key(ALICE, DOT)); + Tokens::set_free_balance(DOT, &ALICE, 100); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Endowed { + currency_id: DOT, + who: ALICE, + amount: 100, + })); + assert_eq!(System::providers(&ALICE), 1); + assert!(Accounts::::contains_key(ALICE, DOT)); + }); +} + +#[test] +fn remove_account_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(System::providers(&ALICE), 1); + assert!(Accounts::::contains_key(ALICE, DOT)); + Tokens::set_free_balance(DOT, &ALICE, 0); + assert_eq!(System::providers(&ALICE), 0); + assert!(!Accounts::::contains_key(ALICE, DOT)); + }); +} + +#[test] +fn reap_account_will_dec_providers_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (ALICE, ETH, 100), (ALICE, BTC, 100)]) + .build() + .execute_with(|| { + assert_eq!(System::providers(&ALICE), 3); + assert!(System::account_exists(&ALICE)); + assert!(Accounts::::contains_key(ALICE, DOT)); + + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &BOB, + 100, + ExistenceRequirement::AllowDeath + )); + assert_eq!(System::providers(&ALICE), 2); + assert!(System::account_exists(&ALICE)); + assert!(!Accounts::::contains_key(ALICE, DOT)); + + // ED of ETH is zero, the account will retain even if the total is zero, + // will not dec_providers + assert!(Accounts::::contains_key(ALICE, ETH)); + assert_ok!(Tokens::do_transfer( + ETH, + &ALICE, + &BOB, + 100, + ExistenceRequirement::AllowDeath + )); + assert_eq!(System::providers(&ALICE), 2); + assert!(System::account_exists(&ALICE)); + assert!(Accounts::::contains_key(ALICE, ETH)); + + assert!(Accounts::::contains_key(ALICE, BTC)); + assert_ok!(Tokens::do_transfer( + BTC, + &ALICE, + &BOB, + 100, + ExistenceRequirement::AllowDeath + )); + assert_eq!(System::providers(&ALICE), 1); + assert!(System::account_exists(&ALICE)); + assert!(!Accounts::::contains_key(ALICE, BTC)); + }); +} + +#[test] +fn dust_removal_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(System::providers(&ALICE), 1); + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); + Tokens::set_free_balance(DOT, &ALICE, 1); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::DustLost { + currency_id: DOT, + who: ALICE, + amount: 1, + })); + assert_eq!(System::providers(&ALICE), 0); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); + + // dave is in dust removal whitelist, will not remove its dust even if its total + // below ED + assert!(!Accounts::::contains_key(DAVE, DOT)); + assert_eq!(System::providers(&DAVE), 0); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); + Tokens::set_free_balance(DOT, &DAVE, 1); + assert!(Accounts::::contains_key(DAVE, DOT)); + assert_eq!(System::providers(&DAVE), 1); + assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Endowed { + currency_id: DOT, + who: DAVE, + amount: 1, + })); + }); +} + +#[test] +fn account_survive_due_to_dust_transfer_failure() { + ExtBuilder::default().build().execute_with(|| { + let dust_account = DustReceiver::get(); + Tokens::set_free_balance(DOT, &dust_account, 0); + assert_eq!(Tokens::free_balance(DOT, &dust_account), 0); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 0); + assert_eq!(System::providers(&ALICE), 0); + assert!(!Accounts::::contains_key(ALICE, DOT)); + + Tokens::set_reserved_balance(DOT, &ALICE, 1); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::DustLost { + currency_id: DOT, + who: ALICE, + amount: 1, + })); + assert_eq!(Tokens::free_balance(DOT, &dust_account), 0); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 1); + assert_eq!(System::providers(&ALICE), 1); + assert!(Accounts::::contains_key(ALICE, DOT)); + }); +} + +#[test] +fn exceeding_max_reserves_should_fail() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let id_3 = [3u8; 8]; + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 10)); + assert_ok!(Tokens::reserve_named(&RID_2, DOT, &ALICE, 10)); + assert_noop!( + Tokens::reserve_named(&id_3, DOT, &ALICE, 10), + Error::::TooManyReserves + ); + }); +} + +#[test] +fn lifecycle_callbacks_are_activated() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, 200, 0)); + assert_eq!(TrackCreatedAccounts::::accounts(), vec![(ALICE, DOT)]); + + assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, BTC, 200, 0)); + assert_eq!( + TrackCreatedAccounts::::accounts(), + vec![(ALICE, DOT), (ALICE, BTC)] + ); + + assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, BTC, false)); + assert_eq!( + TrackCreatedAccounts::::accounts(), + vec![(ALICE, DOT), (ALICE, BTC), (CHARLIE, BTC)] + ); + assert_eq!(TrackKilledAccounts::::accounts(), vec![(ALICE, BTC)]); + }) +} + +// ************************************************* +// tests for mutation hooks (OnDeposit, OnTransfer) +// (tests for the OnSlash hook can be found in `./tests_multicurrency.rs`) +// ************************************************* + +#[test] +fn deposit_hooks_work() { + ExtBuilder::default().build().execute_with(|| { + let initial_prehook_calls = PreDeposit::::calls(); + let initial_posthook_calls = PostDeposit::::calls(); + assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 0, false, true),); + assert_eq!(PreDeposit::::calls(), initial_prehook_calls); + assert_eq!(PostDeposit::::calls(), initial_posthook_calls); + + assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 100, false, true),); + assert_eq!(PreDeposit::::calls(), initial_prehook_calls + 1); + assert_eq!(PostDeposit::::calls(), initial_posthook_calls + 1); + + assert_noop!( + Tokens::do_deposit(DOT, &BOB, 1, false, true), + Error::::ExistentialDeposit + ); + // The prehook is called + assert_eq!(PreDeposit::::calls(), initial_prehook_calls + 2); + // The posthook is not called + assert_eq!(PostDeposit::::calls(), initial_posthook_calls + 1); + }); +} + +#[test] +fn post_deposit_can_use_new_balance() { + ExtBuilder::default().build().execute_with(|| { + let initial_balance = Tokens::free_balance(DOT, &CHARLIE); + // The following will fail unless Charlie's new balance can be used by the hook, + // because `initial_balance + 100` is higher than Charlie's initial balance. + // If this fails, the posthook is called too soon. + assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, initial_balance + 100, false, true),); + }); +} + +#[test] +fn transfer_hooks_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let initial_prehook_calls = PreTransfer::::calls(); + let initial_posthook_calls = PostTransfer::::calls(); + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &CHARLIE, + 0, + ExistenceRequirement::AllowDeath + ),); + assert_eq!(PreTransfer::::calls(), initial_prehook_calls); + assert_eq!(PostTransfer::::calls(), initial_posthook_calls); + + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &CHARLIE, + 10, + ExistenceRequirement::AllowDeath + )); + assert_eq!(PreTransfer::::calls(), initial_prehook_calls + 1); + assert_eq!(PostTransfer::::calls(), initial_posthook_calls + 1); + + assert_noop!( + Tokens::do_transfer(DOT, &ALICE, &BOB, 1, ExistenceRequirement::AllowDeath), + Error::::ExistentialDeposit + ); + // The prehook is called + assert_eq!(PreTransfer::::calls(), initial_prehook_calls + 2); + // The posthook is not called + assert_eq!(PostTransfer::::calls(), initial_posthook_calls + 1); + }); +} + +#[test] +fn post_transfer_can_use_new_balance() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let initial_balance = Tokens::free_balance(DOT, &CHARLIE); + // The following will fail unless Charlie's new balance can be used by the hook, + // because `initial_balance + 100` is higher than Charlie's initial balance. + // If this fails, the posthook is called too soon. + assert_ok!(Tokens::do_transfer( + DOT, + &ALICE, + &CHARLIE, + initial_balance + 100, + ExistenceRequirement::AllowDeath + )); + }); +} diff --git a/pallets/tokens/src/tests_currency_adapter.rs b/pallets/tokens/src/tests_currency_adapter.rs new file mode 100644 index 000000000..20929baf2 --- /dev/null +++ b/pallets/tokens/src/tests_currency_adapter.rs @@ -0,0 +1,674 @@ +//! Unit tests for the tokens module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::*; + +#[test] +fn currency_adapter_ensure_currency_adapter_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_eq!(Tokens::total_balance(DOT, &TREASURY_ACCOUNT), 100); + assert_eq!(Tokens::reserved_balance(DOT, &TREASURY_ACCOUNT), 0); + assert_eq!(Tokens::free_balance(DOT, &TREASURY_ACCOUNT), 100); + assert_eq!( + ::Currency::total_balance(&TREASURY_ACCOUNT), + 100 + ); + assert!(::Currency::can_slash( + &TREASURY_ACCOUNT, + 10 + )); + assert_eq!( + ::Currency::total_issuance(), + 100 + ); + assert_eq!( + ::Currency::minimum_balance(), + 2 + ); + assert!(::Currency::can_reserve( + &TREASURY_ACCOUNT, + 5 + )); + + // burn + let imbalance = ::Currency::burn(10); + assert_eq!( + ::Currency::total_issuance(), + 90 + ); + drop(imbalance); + assert_eq!( + ::Currency::total_issuance(), + 100 + ); + + // issue + let imbalance = ::Currency::issue(20); + assert_eq!( + ::Currency::total_issuance(), + 120 + ); + drop(imbalance); + assert_eq!( + ::Currency::total_issuance(), + 100 + ); + + // transfer + assert_eq!( + ::Currency::free_balance(&TREASURY_ACCOUNT), + 100 + ); + assert_ok!( + ::Currency::ensure_can_withdraw( + &TREASURY_ACCOUNT, + 10, + WithdrawReasons::TRANSFER, + 0 + ) + ); + assert_ok!(::Currency::transfer( + &TREASURY_ACCOUNT, + &ALICE, + 11, + ExistenceRequirement::KeepAlive + )); + assert_eq!( + ::Currency::free_balance(&TREASURY_ACCOUNT), + 89 + ); + + // deposit + assert_eq!( + ::Currency::total_issuance(), + 100 + ); + let imbalance = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 11); + assert_eq!( + ::Currency::free_balance(&TREASURY_ACCOUNT), + 100 + ); + assert_eq!( + ::Currency::total_issuance(), + 100 + ); + drop(imbalance); + assert_eq!( + ::Currency::free_balance(&TREASURY_ACCOUNT), + 100 + ); + assert_eq!( + ::Currency::total_issuance(), + 111 + ); + + // withdraw + let imbalance = ::Currency::withdraw( + &TREASURY_ACCOUNT, + 10, + WithdrawReasons::TRANSFER, + ExistenceRequirement::KeepAlive, + ); + assert_eq!( + ::Currency::free_balance(&TREASURY_ACCOUNT), + 90 + ); + assert_eq!( + ::Currency::total_issuance(), + 111 + ); + drop(imbalance); + assert_eq!( + ::Currency::free_balance(&TREASURY_ACCOUNT), + 90 + ); + assert_eq!( + ::Currency::total_issuance(), + 101 + ); + }); +} + +#[test] +fn currency_adapter_imbalances_extract_works() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + let init_total_issuance = TreasuryCurrencyAdapter::total_issuance(); + + let mut imbalance = TreasuryCurrencyAdapter::burn(10); + + let imbalance2 = imbalance.extract(3); + + drop(imbalance); + + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance - 3); + + drop(imbalance2); + + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance); + + let mut imbalance = TreasuryCurrencyAdapter::issue(10); + + let imbalance2 = imbalance.extract(3); + + drop(imbalance); + + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance + 3); + + drop(imbalance2); + + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance); + }); +} + +#[test] +fn currency_adapter_burn_must_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + let init_total_issuance = TreasuryCurrencyAdapter::total_issuance(); + let imbalance = TreasuryCurrencyAdapter::burn(10); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance - 10); + drop(imbalance); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance); + }); +} + +#[test] +fn currency_adapter_reserving_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + + assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 111); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 111); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); + + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); + + assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 111); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 42); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); + }); +} + +#[test] +fn currency_adapter_balance_transfer_when_reserved_should_not_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 69, ExistenceRequirement::AllowDeath), + Error::::BalanceTooLow, + ); + }); +} + +#[test] +fn currency_adapter_deducting_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 42); + }); +} + +#[test] +fn currency_adapter_refunding_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 42); + Tokens::set_reserved_balance(DOT, &TREASURY_ACCOUNT, 69); + TreasuryCurrencyAdapter::unreserve(&TREASURY_ACCOUNT, 69); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 111); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); + }); +} + +#[test] +fn currency_adapter_slashing_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); + assert!(TreasuryCurrencyAdapter::slash(&TREASURY_ACCOUNT, 69).1.is_zero()); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 42); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 42); + }); +} + +#[test] +fn currency_adapter_slashing_incomplete_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 42); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 42); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 21)); + assert_eq!(TreasuryCurrencyAdapter::slash(&TREASURY_ACCOUNT, 69).1, 27); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 0); + }); +} + +#[test] +fn currency_adapter_basic_locking_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 100); + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 91, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 10, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + }); +} + +#[test] +fn currency_adapter_partial_locking_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 5, WithdrawReasons::all()); + assert_ok!(TreasuryCurrencyAdapter::transfer( + &TREASURY_ACCOUNT, + &ALICE, + 2, + ExistenceRequirement::AllowDeath + )); + }); +} + +#[test] +fn currency_adapter_lock_removal_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, u64::max_value(), WithdrawReasons::all()); + TreasuryCurrencyAdapter::remove_lock(ID_1, &TREASURY_ACCOUNT); + assert_ok!(TreasuryCurrencyAdapter::transfer( + &TREASURY_ACCOUNT, + &ALICE, + 2, + ExistenceRequirement::AllowDeath + )); + }); +} + +#[test] +fn currency_adapter_lock_replacement_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, u64::max_value(), WithdrawReasons::all()); + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 5, WithdrawReasons::all()); + assert_ok!(TreasuryCurrencyAdapter::transfer( + &TREASURY_ACCOUNT, + &ALICE, + 2, + ExistenceRequirement::AllowDeath + )); + }); +} + +#[test] +fn currency_adapter_double_locking_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 5, WithdrawReasons::empty()); + TreasuryCurrencyAdapter::set_lock(ID_2, &TREASURY_ACCOUNT, 5, WithdrawReasons::all()); + assert_ok!(TreasuryCurrencyAdapter::transfer( + &TREASURY_ACCOUNT, + &ALICE, + 2, + ExistenceRequirement::AllowDeath + )); + }); +} + +#[test] +fn currency_adapter_combination_locking_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + // withdrawReasons not work + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, u64::max_value(), WithdrawReasons::empty()); + TreasuryCurrencyAdapter::set_lock(ID_2, &TREASURY_ACCOUNT, 0, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 2, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + }); +} + +#[test] +fn currency_adapter_lock_value_extension_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 100, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 2, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 8, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 3, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + }); +} + +#[test] +fn currency_adapter_lock_block_number_extension_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 200, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + System::set_block_number(2); + TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::all()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 3, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + }); +} + +#[test] +fn currency_adapter_lock_reasons_extension_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::TRANSFER); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 11, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::empty()); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 11, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::RESERVE); + assert_noop!( + TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 11, ExistenceRequirement::AllowDeath), + Error::::LiquidityRestrictions + ); + }); +} + +#[test] +fn currency_adapter_deposit_creating_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 100); + assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 0); + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 2); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 102); + assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 2); + + assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 100); + let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 1); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 103); + assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 101); + }); +} + +#[test] +fn currency_adapter_deposit_into_existing_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 0); + assert_noop!( + TreasuryCurrencyAdapter::deposit_into_existing(&TREASURY_ACCOUNT, 10).map(drop), + Error::::DeadAccount, + ); + + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 100); + assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 100); + assert_ok!(TreasuryCurrencyAdapter::deposit_into_existing(&ALICE, 10).map(drop)); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 110); + assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 110); + }); +} + +#[test] +fn currency_adapter_reward_should_work() { + ExtBuilder::default() + .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 100); + assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 100); + assert_ok!(TreasuryCurrencyAdapter::deposit_into_existing(&TREASURY_ACCOUNT, 10).map(drop)); + assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 110); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 110); + }); +} + +#[test] +fn currency_adapter_slashing_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 111)); + assert_eq!(TreasuryCurrencyAdapter::slash_reserved(&TREASURY_ACCOUNT, 42).1, 0); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); + }); +} + +#[test] +fn currency_adapter_slashing_incomplete_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 42)); + assert_eq!(TreasuryCurrencyAdapter::slash_reserved(&TREASURY_ACCOUNT, 69).1, 27); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 69); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); + }); +} + +#[test] +fn currency_adapter_repatriating_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); + let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 110)); + assert_ok!( + TreasuryCurrencyAdapter::repatriate_reserved(&TREASURY_ACCOUNT, &ALICE, 41, Status::Free), + 0 + ); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&ALICE), 0); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 43); + }); +} + +#[test] +fn currency_adapter_transferring_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); + let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 110)); + assert_ok!( + TreasuryCurrencyAdapter::repatriate_reserved(&TREASURY_ACCOUNT, &ALICE, 41, Status::Reserved), + 0 + ); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&ALICE), 41); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 2); + }); +} + +#[test] +fn currency_adapter_transferring_reserved_balance_to_nonexistent_should_fail() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 111)); + assert_ok!(TreasuryCurrencyAdapter::repatriate_reserved( + &TREASURY_ACCOUNT, + &ALICE, + 42, + Status::Free + )); + }); +} + +#[test] +fn currency_adapter_transferring_incomplete_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); + let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); + assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 41)); + assert_ok!( + TreasuryCurrencyAdapter::repatriate_reserved(&TREASURY_ACCOUNT, &ALICE, 69, Status::Free), + 28 + ); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 69); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&ALICE), 0); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 43); + }); +} + +#[test] +fn currency_adapter_transferring_too_high_value_should_not_panic() { + ExtBuilder::default().build().execute_with(|| { + TreasuryCurrencyAdapter::make_free_balance_be(&TREASURY_ACCOUNT, u64::max_value()); + TreasuryCurrencyAdapter::make_free_balance_be(&ALICE, 2); + + assert_noop!( + TreasuryCurrencyAdapter::transfer( + &TREASURY_ACCOUNT, + &ALICE, + u64::max_value(), + ExistenceRequirement::AllowDeath + ), + ArithmeticError::Overflow, + ); + + assert_eq!( + TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), + u64::max_value() + ); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 2); + }); +} + +#[test] +fn exceeding_max_locks_should_fail() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); + assert_noop!( + Tokens::set_lock(ID_3, DOT, &ALICE, 10), + Error::::MaxLocksExceeded + ); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); + }); +} + +#[test] +fn currency_adapter_slashing_named_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); + assert_ok!(TreasuryCurrencyAdapter::reserve_named(&RID_1, &TREASURY_ACCOUNT, 111)); + assert_eq!( + TreasuryCurrencyAdapter::slash_reserved_named(&RID_1, &TREASURY_ACCOUNT, 42).1, + 0 + ); + assert_eq!( + TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &TREASURY_ACCOUNT), + 69 + ); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); + }); +} + +#[test] +fn currency_adapter_named_slashing_incomplete_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); + assert_ok!(TreasuryCurrencyAdapter::reserve_named(&RID_1, &TREASURY_ACCOUNT, 42)); + assert_eq!( + TreasuryCurrencyAdapter::slash_reserved_named(&RID_1, &TREASURY_ACCOUNT, 69).1, + 27 + ); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 69); + assert_eq!( + TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &TREASURY_ACCOUNT), + 0 + ); + assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); + }); +} + +#[test] +fn currency_adapter_repatriating_named_reserved_balance_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); + let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); + assert_ok!(TreasuryCurrencyAdapter::reserve_named(&RID_1, &TREASURY_ACCOUNT, 110)); + assert_ok!( + TreasuryCurrencyAdapter::repatriate_reserved_named(&RID_1, &TREASURY_ACCOUNT, &ALICE, 41, Status::Free), + 0 + ); + assert_eq!( + TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &TREASURY_ACCOUNT), + 69 + ); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); + assert_eq!(TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &ALICE), 0); + assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 43); + }); +} diff --git a/pallets/tokens/src/tests_events.rs b/pallets/tokens/src/tests_events.rs new file mode 100644 index 000000000..a81284e8f --- /dev/null +++ b/pallets/tokens/src/tests_events.rs @@ -0,0 +1,469 @@ +//! Unit tests for the tokens module. + +#![cfg(test)] + +use super::*; +use frame_support::assert_ok; +use mock::*; + +const REASON: &() = &(); + +fn events() -> Vec { + let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + System::reset_events(); + evt +} + +#[test] +fn pallet_multicurrency_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(>::transfer( + DOT, + &ALICE, + &BOB, + 10, + ExistenceRequirement::AllowDeath + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 10, + })); + + assert_ok!(>::deposit(DOT, &ALICE, 10)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { + currency_id: DOT, + who: ALICE, + amount: 10, + })); + + assert_ok!(>::withdraw( + DOT, + &ALICE, + 10, + ExistenceRequirement::AllowDeath + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { + currency_id: DOT, + who: ALICE, + amount: 10, + })); + + assert_ok!(>::reserve(DOT, &ALICE, 50)); + assert_eq!(>::slash(DOT, &ALICE, 60), 0); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Slashed { + currency_id: DOT, + who: ALICE, + free_amount: 40, + reserved_amount: 20, + })); + }); +} + +#[test] +fn pallet_multicurrency_extended_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(>::update_balance( + DOT, &ALICE, 500 + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { + currency_id: DOT, + who: ALICE, + amount: 500, + })); + assert_ok!(>::update_balance( + DOT, &ALICE, -500 + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { + currency_id: DOT, + who: ALICE, + amount: 500, + })); + }); +} + +#[test] +fn pallet_multi_lockable_currency_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(>::set_lock( + [0u8; 8], DOT, &ALICE, 10 + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::LockSet { + lock_id: [0u8; 8], + currency_id: DOT, + who: ALICE, + amount: 10, + })); + + assert_ok!(>::remove_lock( + [0u8; 8], DOT, &ALICE + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::LockRemoved { + lock_id: [0u8; 8], + currency_id: DOT, + who: ALICE, + })); + }); +} + +#[test] +fn pallet_multi_reservable_currency_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 1000), (BOB, DOT, 1000)]) + .build() + .execute_with(|| { + assert_ok!(>::reserve( + DOT, &ALICE, 500 + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 500, + })); + + assert_eq!( + >::slash_reserved(DOT, &ALICE, 300), + 0 + ); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Slashed { + currency_id: DOT, + who: ALICE, + free_amount: 0, + reserved_amount: 300, + })); + + assert_eq!( + >::unreserve(DOT, &ALICE, 100), + 0 + ); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: ALICE, + amount: 100, + })); + + assert_ok!(>::repatriate_reserved( + DOT, + &ALICE, + &BOB, + 100, + BalanceStatus::Free + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 100, + status: BalanceStatus::Free, + })); + }); +} + +#[test] +fn pallet_fungibles_mutate_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(>::mint_into(DOT, &ALICE, 500)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { + currency_id: DOT, + who: ALICE, + amount: 500, + })); + assert_ok!(>::burn_from( + DOT, + &ALICE, + 500, + Preservation::Expendable, + Precision::Exact, + Fortitude::Polite + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { + currency_id: DOT, + who: ALICE, + amount: 500, + })); + }); +} + +#[test] +fn pallet_fungibles_transfer_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(>::transfer( + DOT, + &ALICE, + &BOB, + 50, + Preservation::Protect + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 50, + })); + }); +} + +#[test] +fn pallet_fungibles_unbalanced_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(>::reserve(DOT, &ALICE, 50)); + assert_ok!(>::write_balance( + DOT, &ALICE, 500 + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { + currency_id: DOT, + who: ALICE, + free: 500, + reserved: 50, + })); + + >::set_total_issuance(DOT, 1000); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::TotalIssuanceSet { + currency_id: DOT, + amount: 1000, + })); + }); +} + +#[test] +fn pallet_fungibles_mutate_hold_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(>::hold( + DOT, REASON, &ALICE, 50 + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 50, + })); + + assert_ok!(>::transfer_on_hold( + DOT, + REASON, + &ALICE, + &BOB, + 50, + Precision::Exact, + Restriction::OnHold, + Fortitude::Polite + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 50, + status: BalanceStatus::Reserved, + })); + System::reset_events(); + assert_eq!( + >::release(DOT, REASON, &BOB, 50, Precision::Exact), + Ok(50) + ); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: BOB, + amount: 50, + })); + }); +} + +#[test] +fn currency_adapter_pallet_currency_deposit_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + // Use std::mem::forget to get rid the returned imbalance. + std::mem::forget(>::burn(500)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::TotalIssuanceSet { + currency_id: DOT, + amount: 0, + })); + + std::mem::forget(>::issue(200)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::TotalIssuanceSet { + currency_id: DOT, + amount: 200, + })); + + assert_ok!(>::transfer( + &ALICE, + &BOB, + 50, + ExistenceRequirement::AllowDeath + )); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 50, + })); + + assert_ok!(>::reserve(DOT, &BOB, 50)); + std::mem::forget(>::slash(&BOB, 110)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Slashed { + currency_id: DOT, + who: BOB, + free_amount: 100, + reserved_amount: 10, + })); + + std::mem::forget(>::make_free_balance_be(&BOB, 200)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { + currency_id: DOT, + who: BOB, + free: 200, + reserved: 40, + })); + }); +} + +#[test] +fn pallet_change_locks_events() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Tokens::do_deposit(DOT, &ALICE, 100, false, false)); + assert_ok!(Tokens::do_deposit(BTC, &ALICE, 100, false, false)); + System::reset_events(); + + // Locks: [10/DOT] + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 10 + }))); + + // Locks: [15/DOT] + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 15)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 5 + }))); + + // Locks: [15/DOT, 20/BTC] + assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 20)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { + currency_id: BTC, + who: ALICE, + amount: 20 + }))); + + // Locks: [15/DOT, 20/BTC, 10/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); + for event in events() { + match event { + RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 12/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 12)); + for event in events() { + match event { + RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 10/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); + for event in events() { + match event { + RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), + RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), + _ => continue, + } + } + + // Locks: [15/DOT, 20/BTC, 20/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { + currency_id: DOT, + who: ALICE, + amount: 5 + }))); + + // Locks: [15/DOT, 20/BTC, 16/DOT] + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 16)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { + currency_id: DOT, + who: ALICE, + amount: 4 + }))); + + // Locks: [15/DOT, 12/BTC, 16/DOT] + assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 12)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { + currency_id: BTC, + who: ALICE, + amount: 8 + }))); + + // Locks: [15/DOT, 12/BTC] + assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { + currency_id: DOT, + who: ALICE, + amount: 1 + }))); + }); +} + +#[test] +fn pallet_multi_lockable_currency_extend_lock_events() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + // lock already exists + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert_ok!(Tokens::extend_lock(ID_1, DOT, &ALICE, 20)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::LockSet { + lock_id: ID_1, + currency_id: DOT, + who: ALICE, + amount: 20, + }))); + // lock doesn't exist + assert_ok!(Tokens::extend_lock(ID_2, DOT, &ALICE, 10)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::LockSet { + lock_id: ID_2, + currency_id: DOT, + who: ALICE, + amount: 10, + }))); + assert_ok!(Tokens::extend_lock(ID_2, DOT, &ALICE, 20)); + assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::LockSet { + lock_id: ID_2, + currency_id: DOT, + who: ALICE, + amount: 20, + }))); + }); +} diff --git a/pallets/tokens/src/tests_fungibles.rs b/pallets/tokens/src/tests_fungibles.rs new file mode 100644 index 000000000..13c56c33a --- /dev/null +++ b/pallets/tokens/src/tests_fungibles.rs @@ -0,0 +1,741 @@ +//! Unit tests for the tokens module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::*; +use sp_runtime::{ArithmeticError, TokenError}; + +const REASON: &() = &(); + +#[test] +fn fungibles_inspect_trait_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(>::total_issuance(DOT), 100); + assert_eq!(>::minimum_balance(DOT), 2); + assert_eq!(>::balance(DOT, &ALICE), 100); + assert_eq!( + >::reducible_balance( + DOT, + &ALICE, + Preservation::Protect, + Fortitude::Polite + ), + 98 + ); + assert_eq!( + >::reducible_balance( + DOT, + &ALICE, + Preservation::Preserve, + Fortitude::Polite + ), + 98 + ); + assert_ok!( + >::can_deposit(DOT, &ALICE, 1, Provenance::Extant).into_result() + ); + assert_ok!(>::can_withdraw(DOT, &ALICE, 1).into_result(true)); + + assert!(>::asset_exists(DOT)); + assert!(!>::asset_exists(BTC)); + }); +} + +#[test] +fn fungibles_mutate_trait_should_work() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(>::mint_into(DOT, &ALICE, 10)); + assert_eq!( + >::burn_from( + DOT, + &ALICE, + 8, + Preservation::Expendable, + Precision::Exact, + Fortitude::Polite + ), + Ok(8) + ); + }); +} + +#[test] +fn fungibles_transfer_trait_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(>::balance(DOT, &ALICE), 100); + assert_eq!(>::balance(DOT, &BOB), 100); + assert_ok!(>::transfer( + DOT, + &ALICE, + &BOB, + 10, + Preservation::Protect + )); + assert_eq!(>::balance(DOT, &ALICE), 90); + assert_eq!(>::balance(DOT, &BOB), 110); + }); +} + +#[test] +fn fungibles_unbalanced_trait_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + // set_balance + assert_eq!(>::balance(DOT, &ALICE), 100); + assert_ok!(>::write_balance(DOT, &ALICE, 10)); + assert_eq!(>::balance(DOT, &ALICE), 10); + + // set_total_issuance + assert_eq!(>::total_issuance(DOT), 100); + >::set_total_issuance(DOT, 10); + assert_eq!(>::total_issuance(DOT), 10); + + // decrease_balance + assert_eq!(>::balance(DOT, &ALICE), 10); + assert_noop!( + >::decrease_balance( + DOT, + &ALICE, + 20, + Precision::Exact, + Preservation::Protect, + Fortitude::Polite + ), + TokenError::FundsUnavailable + ); + assert_eq!( + >::decrease_balance( + DOT, + &ALICE, + 5, + Precision::Exact, + Preservation::Protect, + Fortitude::Polite + ), + Ok(5) + ); + assert_eq!(>::balance(DOT, &ALICE), 5); + // new balance < ExistentialDeposits, clean dust + assert_eq!( + >::decrease_balance( + DOT, + &ALICE, + 4, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite + ), + Ok(4) + ); + assert_eq!(>::balance(DOT, &ALICE), 0); + assert_eq!(>::total_balance(DOT, &ALICE), 0); + // set reserved + assert_ok!(>::write_balance(DOT, &ALICE, 100)); + assert_ok!(>::reserve(DOT, &ALICE, 50)); + assert_eq!(>::balance(DOT, &ALICE), 50); + assert_eq!(>::total_balance(DOT, &ALICE), 100); + assert_eq!( + >::reducible_balance( + DOT, + &ALICE, + Preservation::Protect, + Fortitude::Polite + ), + 50 + ); + assert_noop!( + >::decrease_balance( + DOT, + &ALICE, + 60, + Precision::Exact, + Preservation::Protect, + Fortitude::Polite + ), + TokenError::FundsUnavailable + ); + assert_eq!( + >::decrease_balance( + DOT, + &ALICE, + 50, + Precision::Exact, + Preservation::Protect, + Fortitude::Polite + ), + Ok(50) + ); + assert_eq!(>::balance(DOT, &ALICE), 0); + assert_eq!(>::total_balance(DOT, &ALICE), 50); + assert_eq!( + >::unreserve(DOT, &ALICE, 50), + 0 + ); + assert_eq!(>::balance(DOT, &ALICE), 50); + assert_eq!(>::total_balance(DOT, &ALICE), 50); + + // decrease_balance_at_most + assert_ok!(>::write_balance(DOT, &ALICE, 10)); + assert_eq!(>::balance(DOT, &ALICE), 10); + assert_eq!(>::total_balance(DOT, &ALICE), 10); + assert_eq!( + >::decrease_balance( + DOT, + &ALICE, + 20, + Precision::BestEffort, + Preservation::Expendable, + Fortitude::Polite + ), + Ok(10) + ); + assert_eq!(>::balance(DOT, &ALICE), 0); + assert_eq!(>::total_balance(DOT, &ALICE), 0); + assert_ok!(>::write_balance(DOT, &ALICE, 10)); + assert_eq!( + >::decrease_balance( + DOT, + &ALICE, + 5, + Precision::BestEffort, + Preservation::Protect, + Fortitude::Polite + ), + Ok(5) + ); + assert_eq!(>::balance(DOT, &ALICE), 5); + assert_eq!(>::total_balance(DOT, &ALICE), 5); + + // new balance < ExistentialDeposits, clean dust + assert_eq!( + >::decrease_balance( + DOT, + &ALICE, + 4, + Precision::BestEffort, + Preservation::Expendable, + Fortitude::Polite + ), + Ok(4) + ); + assert_eq!(>::balance(DOT, &ALICE), 0); + assert_eq!(>::total_balance(DOT, &ALICE), 0); + // set reserved + assert_ok!(>::write_balance(DOT, &ALICE, 100)); + assert_ok!(>::reserve(DOT, &ALICE, 50)); + assert_eq!(>::balance(DOT, &ALICE), 50); + assert_eq!(>::total_balance(DOT, &ALICE), 100); + assert_eq!( + >::reducible_balance( + DOT, + &ALICE, + Preservation::Protect, + Fortitude::Polite + ), + 50 + ); + assert_eq!( + >::decrease_balance( + DOT, + &ALICE, + 60, + Precision::BestEffort, + Preservation::Protect, + Fortitude::Polite + ), + Ok(50), + ); + assert_eq!(>::balance(DOT, &ALICE), 0); + assert_eq!(>::total_balance(DOT, &ALICE), 50); + assert_eq!( + >::unreserve(DOT, &ALICE, 50), + 0 + ); + assert_eq!(>::balance(DOT, &ALICE), 50); + assert_eq!(>::total_balance(DOT, &ALICE), 50); + + // increase_balance + assert_ok!(>::write_balance(DOT, &ALICE, 0)); + assert_noop!( + >::increase_balance(DOT, &ALICE, 1, Precision::Exact), + TokenError::BelowMinimum + ); + assert_eq!( + >::increase_balance(DOT, &ALICE, 2, Precision::Exact), + Ok(2) + ); + assert_eq!(>::balance(DOT, &ALICE), 2); + assert_noop!( + >::increase_balance(DOT, &ALICE, Balance::MAX, Precision::Exact), + ArithmeticError::Overflow + ); + + // increase_balance_at_most + assert_ok!(>::write_balance(DOT, &ALICE, 0)); + assert_eq!( + >::increase_balance(DOT, &ALICE, 1, Precision::BestEffort), + Ok(0) + ); + assert_eq!( + >::increase_balance(DOT, &ALICE, 2, Precision::BestEffort), + Ok(2) + ); + assert_eq!(>::balance(DOT, &ALICE), 2); + assert_eq!( + >::increase_balance( + DOT, + &ALICE, + Balance::MAX, + Precision::BestEffort + ), + Ok(Balance::MAX - 2) + ); + }); +} + +#[test] +fn fungibles_balanced_deposit_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let amount = 42; + let alice_old_balance = >::balance(DOT, &ALICE); + let debt = >::deposit(DOT, &ALICE, amount, Precision::Exact).unwrap(); + assert_eq!(debt.asset(), DOT); + assert_eq!(debt.peek(), amount); + let alice_new_balance = >::balance(DOT, &ALICE); + assert_eq!(alice_old_balance + amount, alice_new_balance); + + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { + currency_id: DOT, + who: ALICE, + amount, + })); + }); +} + +#[test] +fn fungibles_balanced_withdraw_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let amount = 42; + let alice_old_balance = >::balance(DOT, &ALICE); + let credit = >::withdraw( + DOT, + &ALICE, + amount, + Precision::Exact, + Preservation::Protect, + Fortitude::Polite, + ) + .unwrap(); + assert_eq!(credit.asset(), DOT); + assert_eq!(credit.peek(), amount); + let alice_new_balance = >::balance(DOT, &ALICE); + assert_eq!(alice_old_balance - amount, alice_new_balance); + + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { + currency_id: DOT, + who: ALICE, + amount, + })); + }); +} + +#[test] +fn fungibles_balanced_issue_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let amount = 42; + + let old_total_issuance = >::total_issuance(DOT); + let credit = >::issue(DOT, amount); + assert_eq!(credit.asset(), DOT); + assert_eq!(credit.peek(), amount); + let new_total_issuance = >::total_issuance(DOT); + assert_eq!(old_total_issuance + amount, new_total_issuance); + + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Issued { + currency_id: DOT, + amount, + })); + }); +} + +#[test] +fn fungibles_balanced_rescind_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let amount = 42; + + let old_total_issuance = >::total_issuance(DOT); + let debt = >::rescind(DOT, amount); + assert_eq!(debt.asset(), DOT); + assert_eq!(debt.peek(), amount); + let new_total_issuance = >::total_issuance(DOT); + assert_eq!(old_total_issuance - amount, new_total_issuance); + + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Rescinded { + currency_id: DOT, + amount, + })); + }); +} + +#[test] +fn fungibles_inspect_hold_trait_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 0 + ); + assert!(>::can_hold(DOT, REASON, &ALICE, 50)); + assert!(!>::can_hold( + DOT, REASON, &ALICE, 100 + )); + }); +} + +#[test] +fn fungibles_mutate_hold_trait_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_noop!( + >::hold(DOT, REASON, &ALICE, 200), + Error::::BalanceTooLow + ); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 0 + ); + assert_eq!(>::balance(DOT, &ALICE), 100); + + assert_ok!(>::hold(DOT, REASON, &ALICE, 100)); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 100 + ); + assert_eq!(>::balance(DOT, &ALICE), 0); + + assert_eq!( + >::release(DOT, REASON, &ALICE, 40, Precision::Exact), + Ok(40) + ); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 60 + ); + assert_eq!(>::balance(DOT, &ALICE), 40); + + // exceed hold amount when not in best_effort + assert_noop!( + >::release(DOT, REASON, &ALICE, 61, Precision::Exact), + Error::::BalanceTooLow + ); + + // exceed hold amount when in best_effort + assert_eq!( + >::release(DOT, REASON, &ALICE, 61, Precision::BestEffort), + Ok(60) + ); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 0 + ); + assert_eq!(>::balance(DOT, &ALICE), 100); + + assert_ok!(>::hold(DOT, REASON, &ALICE, 70)); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 70 + ); + assert_eq!(>::balance(DOT, &ALICE), 30); + + assert_eq!( + >::balance_on_hold(DOT, REASON, &BOB), + 0 + ); + assert_eq!(>::balance(DOT, &BOB), 100); + assert_eq!( + >::transfer_on_hold( + DOT, + REASON, + &ALICE, + &BOB, + 5, + Precision::Exact, + Restriction::Free, + Fortitude::Polite + ), + Ok(5) + ); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 65 + ); + assert_eq!(>::balance(DOT, &ALICE), 30); + assert_eq!( + >::balance_on_hold(DOT, REASON, &BOB), + 0 + ); + assert_eq!(>::balance(DOT, &BOB), 105); + + assert_eq!( + >::transfer_on_hold( + DOT, + REASON, + &ALICE, + &BOB, + 5, + Precision::Exact, + Restriction::OnHold, + Fortitude::Polite + ), + Ok(5) + ); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 60 + ); + assert_eq!(>::balance(DOT, &ALICE), 30); + assert_eq!( + >::balance_on_hold(DOT, REASON, &BOB), + 5 + ); + assert_eq!(>::balance(DOT, &BOB), 105); + + // exceed hold amount when not in best_effort + assert_noop!( + >::transfer_on_hold( + DOT, + REASON, + &ALICE, + &BOB, + 61, + Precision::Exact, + Restriction::OnHold, + Fortitude::Polite + ), + Error::::BalanceTooLow + ); + + // exceed hold amount when in best_effort + assert_eq!( + >::transfer_on_hold( + DOT, + REASON, + &ALICE, + &BOB, + 61, + Precision::BestEffort, + Restriction::OnHold, + Fortitude::Polite + ), + Ok(60) + ); + assert_eq!( + >::balance_on_hold(DOT, REASON, &ALICE), + 0 + ); + assert_eq!(>::balance(DOT, &ALICE), 30); + assert_eq!( + >::balance_on_hold(DOT, REASON, &BOB), + 65 + ); + assert_eq!(>::balance(DOT, &BOB), 105); + }); +} + +#[test] +fn fungibles_inspect_convert_should_work() { + pub struct ConvertBalanceTest; + impl ConvertBalance for ConvertBalanceTest { + type AssetId = CurrencyId; + fn convert_balance(balance: Balance, _asset_id: CurrencyId) -> Result { + Ok(balance * 100) + } + + fn convert_balance_back(balance: Balance, _asset_id: CurrencyId) -> Result { + Ok(balance / 100) + } + } + + pub struct IsLiquidToken; + impl Contains for IsLiquidToken { + fn contains(currency_id: &CurrencyId) -> bool { + matches!(currency_id, &DOT) + } + } + + pub struct GetCurrencyId; + impl Get for GetCurrencyId { + fn get() -> CurrencyId { + DOT + } + } + + type RebaseTokens = Combiner< + AccountId, + IsLiquidToken, + Mapper, + Tokens, + >; + + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100), (BOB, BTC, 100)]) + .build() + .execute_with(|| { + assert_eq!( + >::balance(DOT, &ALICE), + 10000 + ); + assert_eq!( + >::total_issuance(DOT), + 20000 + ); + + assert!(>::asset_exists(DOT)); + assert!(>::asset_exists(BTC)); + assert!(!>::asset_exists(ETH)); + }); +} + +#[test] +fn fungibles_transfers_convert_should_work() { + pub struct ConvertBalanceTest; + impl ConvertBalance for ConvertBalanceTest { + type AssetId = CurrencyId; + fn convert_balance(balance: Balance, _asset_id: CurrencyId) -> Result { + Ok(balance * 100) + } + + fn convert_balance_back(balance: Balance, _asset_id: CurrencyId) -> Result { + Ok(balance / 100) + } + } + + pub struct IsLiquidToken; + impl Contains for IsLiquidToken { + fn contains(currency_id: &CurrencyId) -> bool { + matches!(currency_id, &DOT) + } + } + + pub struct GetCurrencyId; + impl Get for GetCurrencyId { + fn get() -> CurrencyId { + DOT + } + } + + type RebaseTokens = Combiner< + AccountId, + IsLiquidToken, + Mapper, + Tokens, + >; + + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 300), (BOB, DOT, 200)]) + .build() + .execute_with(|| { + assert_ok!(>::transfer( + DOT, + &ALICE, + &BOB, + 10000, + Preservation::Protect + )); + assert_eq!( + >::balance(DOT, &ALICE), + 20000 + ); + assert_eq!( + >::balance(DOT, &BOB), + 30000 + ); + }); +} + +#[test] +fn fungibles_mutate_convert_should_work() { + pub struct ConvertBalanceTest; + impl ConvertBalance for ConvertBalanceTest { + type AssetId = CurrencyId; + fn convert_balance(balance: Balance, _asset_id: CurrencyId) -> Result { + Ok(balance * 100) + } + + fn convert_balance_back(balance: Balance, _asset_id: CurrencyId) -> Result { + Ok(balance / 100) + } + } + + pub struct IsLiquidToken; + impl Contains for IsLiquidToken { + fn contains(currency_id: &CurrencyId) -> bool { + matches!(currency_id, &DOT) + } + } + + pub struct GetCurrencyId; + impl Get for GetCurrencyId { + fn get() -> CurrencyId { + DOT + } + } + + type RebaseTokens = Combiner< + AccountId, + IsLiquidToken, + Mapper, + Tokens, + >; + + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 300), (BOB, DOT, 200)]) + .build() + .execute_with(|| { + assert_ok!(>::mint_into( + DOT, &ALICE, 10000 + )); + assert_ok!(>::burn_from( + DOT, + &BOB, + 10000, + Preservation::Expendable, + Precision::Exact, + Fortitude::Polite + )); + assert_eq!( + >::balance(DOT, &ALICE), + 40000 + ); + assert_eq!( + >::balance(DOT, &BOB), + 10000 + ); + }); +} diff --git a/pallets/tokens/src/tests_multicurrency.rs b/pallets/tokens/src/tests_multicurrency.rs new file mode 100644 index 000000000..f1a5684a1 --- /dev/null +++ b/pallets/tokens/src/tests_multicurrency.rs @@ -0,0 +1,808 @@ +//! Unit tests for the tokens module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::*; + +#[test] +fn multicurrency_deposit_work() { + ExtBuilder::default().build().execute_with(|| { + assert!(!Accounts::::contains_key(CHARLIE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); + assert_eq!(Tokens::total_issuance(DOT), 0); + assert_ok!(Tokens::deposit(DOT, &CHARLIE, 10)); + assert!(Accounts::::contains_key(CHARLIE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 10); + assert_eq!(Tokens::total_issuance(DOT), 10); + }); +} + +#[test] +fn multicurrency_withdraw_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_ok!(Tokens::withdraw(DOT, &ALICE, 99, ExistenceRequirement::AllowDeath)); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 1); + }); +} + +#[test] +fn multicurrency_transfer_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert!(Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_ok!(>::transfer( + DOT, + &ALICE, + &BOB, + 99, + ExistenceRequirement::AllowDeath + )); + assert!(!Accounts::::contains_key(ALICE, DOT)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &BOB), 199); + }); +} + +#[test] +fn multicurrency_can_slash_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert!(!Tokens::can_slash(DOT, &ALICE, 101)); + assert!(Tokens::can_slash(DOT, &ALICE, 100)); + }); +} + +#[test] +fn multicurrency_slash_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + // slashed_amount < amount + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_eq!(Tokens::slash(DOT, &ALICE, 50), 0); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 50); + + // slashed_amount == amount + assert_eq!(Tokens::slash(DOT, &ALICE, 51), 1); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 0); + }); +} + +#[test] +fn multicurrency_extended_update_balance_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::update_balance(DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 150); + assert_eq!(Tokens::total_issuance(DOT), 250); + + assert_ok!(Tokens::update_balance(DOT, &BOB, -50)); + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::total_issuance(DOT), 200); + + assert_noop!(Tokens::update_balance(DOT, &BOB, -60), Error::::BalanceTooLow); + }); +} + +#[test] +fn multi_lockable_currency_set_lock_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 10); + assert_eq!(Tokens::accounts(&ALICE, DOT).frozen(), 10); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 50)); + assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 50); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 60)); + assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 60); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); + }); +} + +#[test] +fn multi_lockable_currency_extend_lock_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); + assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 10); + assert_ok!(Tokens::extend_lock(ID_1, DOT, &ALICE, 20)); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); + assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 20); + assert_ok!(Tokens::extend_lock(ID_2, DOT, &ALICE, 10)); + assert_ok!(Tokens::extend_lock(ID_1, DOT, &ALICE, 20)); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); + }); +} + +#[test] +fn multi_lockable_currency_remove_lock_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); + assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); + assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); + assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); + }); +} + +#[test] +fn multi_reservable_currency_can_reserve_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert!(Tokens::can_reserve(DOT, &ALICE, 0)); + assert!(!Tokens::can_reserve(DOT, &ALICE, 101)); + assert!(Tokens::can_reserve(DOT, &ALICE, 100)); + }); +} + +#[test] +fn multi_reservable_currency_slash_reserved_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 0), 0); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 100), 50); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 50); + }); +} + +#[test] +fn multi_reservable_currency_reserve_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_noop!(Tokens::reserve(DOT, &ALICE, 101), Error::::BalanceTooLow); + assert_ok!(Tokens::reserve(DOT, &ALICE, 0)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); + assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 50, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); + + assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); + // ensure will not trigger Endowed event + assert!(System::events().iter().all(|record| !matches!( + record.event, + RuntimeEvent::Tokens(crate::Event::Endowed { + currency_id: DOT, + who: ALICE, + amount: _ + }) + ))); + }); +} + +#[test] +fn multi_reservable_currency_unreserve_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::unreserve(DOT, &ALICE, 0), 0); + assert_eq!(Tokens::unreserve(DOT, &ALICE, 50), 50); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: ALICE, + amount: 0, + })); + assert_ok!(Tokens::reserve(DOT, &ALICE, 30)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 30, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 70); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::unreserve(DOT, &ALICE, 15), 0); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: ALICE, + amount: 15, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 85); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 15); + assert_eq!(Tokens::unreserve(DOT, &ALICE, 30), 15); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: ALICE, + amount: 15, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + // ensure will not trigger Endowed event + assert!(System::events().iter().all(|record| !matches!( + record.event, + RuntimeEvent::Tokens(crate::Event::Endowed { + currency_id: DOT, + who: ALICE, + amount: _ + }) + ))); + }); +} + +#[test] +fn multi_reservable_currency_repatriate_reserved_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!( + Tokens::repatriate_reserved(DOT, &ALICE, &ALICE, 0, BalanceStatus::Free), + Ok(0) + ); + assert_eq!( + Tokens::repatriate_reserved(DOT, &ALICE, &ALICE, 50, BalanceStatus::Free), + Ok(50) + ); + // Repatriating from and to the same account, fund is `unreserved`. + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: ALICE, + amount: 0, + })); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); + assert_ok!(Tokens::reserve(DOT, &BOB, 50)); + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 50); + assert_eq!( + Tokens::repatriate_reserved(DOT, &BOB, &BOB, 60, BalanceStatus::Reserved), + Ok(10) + ); + + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 50); + + assert_eq!( + Tokens::repatriate_reserved(DOT, &BOB, &ALICE, 30, BalanceStatus::Reserved), + Ok(0) + ); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { + currency_id: DOT, + from: BOB, + to: ALICE, + amount: 30, + status: BalanceStatus::Reserved, + })); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 20); + + assert_eq!( + Tokens::repatriate_reserved(DOT, &BOB, &ALICE, 30, BalanceStatus::Free), + Ok(10) + ); + + // Actual amount repatriated is 20. + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { + currency_id: DOT, + from: BOB, + to: ALICE, + amount: 20, + status: BalanceStatus::Free, + })); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 120); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); + }); +} + +#[test] +fn slash_draw_reserved_correct() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 100); + + assert_eq!(Tokens::slash(DOT, &ALICE, 80), 0); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 20); + assert_eq!(Tokens::total_issuance(DOT), 20); + + assert_eq!(Tokens::slash(DOT, &ALICE, 50), 30); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 0); + }); +} + +#[test] +fn no_op_if_amount_is_zero() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Tokens::ensure_can_withdraw(DOT, &ALICE, 0)); + assert_ok!(Tokens::transfer(Some(ALICE).into(), BOB, DOT, 0)); + assert_ok!(Tokens::transfer(Some(ALICE).into(), ALICE, DOT, 0)); + assert_ok!(Tokens::deposit(DOT, &ALICE, 0)); + assert_ok!(Tokens::withdraw(DOT, &ALICE, 0, ExistenceRequirement::AllowDeath)); + assert_eq!(Tokens::slash(DOT, &ALICE, 0), 0); + assert_eq!(Tokens::slash(DOT, &ALICE, 1), 1); + assert_ok!(Tokens::update_balance(DOT, &ALICE, 0)); + }); +} + +#[test] +fn transfer_all_trait_should_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (ALICE, BTC, 200)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::free_balance(BTC, &ALICE), 200); + assert_eq!(Tokens::free_balance(DOT, &BOB), 0); + + assert_ok!(>::transfer_all(&ALICE, &BOB)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::free_balance(BTC, &ALICE), 0); + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::free_balance(BTC, &BOB), 200); + + assert_ok!(Tokens::reserve(DOT, &BOB, 1)); + assert_ok!(>::transfer_all(&BOB, &ALICE)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 99); + assert_eq!(Tokens::free_balance(BTC, &ALICE), 200); + assert_eq!(Tokens::free_balance(DOT, &BOB), 0); + assert_eq!(Tokens::free_balance(BTC, &BOB), 0); + }); +} + +#[test] +fn named_multi_reservable_currency_slash_reserved_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 0), 0); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 100); + assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 100), 50); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 50); + }); +} + +#[test] +fn named_multi_reservable_currency_reserve_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_noop!( + Tokens::reserve_named(&RID_1, DOT, &ALICE, 101), + Error::::BalanceTooLow + ); + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 0)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 50, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); + + assert_ok!(Tokens::reserve_named(&RID_2, DOT, &ALICE, 50)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 50, + })); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 50); + assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); + + // ensure will not trigger Endowed event + assert!(System::events().iter().all(|record| !matches!( + record.event, + RuntimeEvent::Tokens(crate::Event::Endowed { + currency_id: DOT, + who: ALICE, + amount: _ + }) + ))); + }); +} + +#[test] +fn named_multi_reservable_currency_unreserve_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + assert_eq!(Tokens::unreserve_named(&RID_1, DOT, &ALICE, 0), 0); + + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 30)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 30, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 70); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); + + assert_ok!(Tokens::reserve_named(&RID_2, DOT, &ALICE, 30)); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { + currency_id: DOT, + who: ALICE, + amount: 30, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 40); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 60); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); + assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 30); + + assert_eq!(Tokens::unreserve_named(&RID_1, DOT, &ALICE, 30), 0); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: ALICE, + amount: 30, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 70); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 30); + + assert_eq!(Tokens::unreserve_named(&RID_2, DOT, &ALICE, 30), 0); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { + currency_id: DOT, + who: ALICE, + amount: 30, + })); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 0); + // ensure will not trigger Endowed event + assert!(System::events().iter().all(|record| !matches!( + record.event, + RuntimeEvent::Tokens(crate::Event::Endowed { + currency_id: DOT, + who: ALICE, + amount: _ + }) + ))); + }); +} + +#[test] +fn named_multi_reservable_currency_repatriate_reserved_work() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!( + Tokens::repatriate_reserved_named(&RID_1, DOT, &ALICE, &ALICE, 0, BalanceStatus::Free), + Ok(0) + ); + assert_eq!( + Tokens::repatriate_reserved_named(&RID_1, DOT, &ALICE, &ALICE, 50, BalanceStatus::Free), + Ok(50) + ); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 0); + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &BOB, 50)); + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 50); + assert_eq!( + Tokens::repatriate_reserved_named(&RID_1, DOT, &BOB, &BOB, 60, BalanceStatus::Reserved), + Ok(10) + ); + + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 50); + + assert_eq!( + Tokens::repatriate_reserved_named(&RID_1, DOT, &BOB, &ALICE, 30, BalanceStatus::Reserved), + Ok(0) + ); + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { + currency_id: DOT, + from: BOB, + to: ALICE, + amount: 30, + status: BalanceStatus::Reserved, + })); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 20); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 20); + + assert_eq!( + Tokens::repatriate_reserved_named(&RID_1, DOT, &BOB, &ALICE, 30, BalanceStatus::Free), + Ok(10) + ); + + // Actual amount repatriated is 20. + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { + currency_id: DOT, + from: BOB, + to: ALICE, + amount: 20, + status: BalanceStatus::Free, + })); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 120); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); + assert_eq!(Tokens::free_balance(DOT, &BOB), 50); + assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 0); + }); +} + +#[test] +fn slashed_reserved_named_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 100); + + assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 20), 0); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); + assert_eq!(Tokens::total_issuance(DOT), 80); + + assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 40), 10); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); + assert_eq!(Tokens::total_issuance(DOT), 50); + }); +} + +#[test] +fn named_multi_reservable_ensure_named_reserved_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); + assert_eq!(Tokens::total_issuance(DOT), 100); + + assert_ok!(Tokens::ensure_reserved_named(&RID_1, DOT, &ALICE, 20)); + assert_ok!(Tokens::ensure_reserved_named(&RID_1, DOT, &ALICE, 70)); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 70); + }); +} + +#[test] +fn named_multi_reservable_unreserve_all_named() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 20)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 30); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 70); + + let value = Tokens::unreserve_all_named(&RID_1, DOT, &ALICE); + assert!(value == 70); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + }); +} + +#[test] +fn named_multi_reservable_slash_all_reserved_named() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); + + let value = Tokens::slash_all_reserved_named(&RID_1, DOT, &ALICE); + assert!(value == 0); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + }); +} + +#[test] +fn named_multi_reservable_repatriate_all_reserved_named_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) + .build() + .execute_with(|| { + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 0); + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); + + assert_ok!(Tokens::repatriate_all_reserved_named( + &RID_1, + DOT, + &ALICE, + &BOB, + BalanceStatus::Reserved + )); + + assert_eq!(Tokens::free_balance(DOT, &BOB), 100); + assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 50); + + System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { + currency_id: DOT, + from: ALICE, + to: BOB, + amount: 50, + status: BalanceStatus::Reserved, + })); + }); +} + +#[test] +fn slash_hook_works() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let initial_hook_calls = OnSlashHook::::calls(); + + // slashing zero tokens is a no-op + assert_eq!(Tokens::slash(DOT, &ALICE, 0), 0); + assert_eq!(OnSlashHook::::calls(), initial_hook_calls); + + assert_eq!(Tokens::slash(DOT, &ALICE, 50), 0); + assert_eq!(OnSlashHook::::calls(), initial_hook_calls + 1); + + // `slash` calls the hook even if no amount was slashed + assert_eq!(Tokens::slash(DOT, &ALICE, 100), 50); + assert_eq!(OnSlashHook::::calls(), initial_hook_calls + 2); + }); +} + +#[test] +fn slash_hook_works_for_reserved() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let initial_slash_hook_calls = OnSlashHook::::calls(); + + assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); + // slashing zero tokens is a no-op + assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 0), 0); + assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls); + + assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 50), 0); + assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 1); + + // `slash_reserved` calls the hook even if no amount was slashed + assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 50), 50); + assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 2); + }); +} + +#[test] +fn slash_hook_works_for_reserved_named() { + ExtBuilder::default() + .balances(vec![(ALICE, DOT, 100)]) + .build() + .execute_with(|| { + let initial_slash_hook_calls = OnSlashHook::::calls(); + + assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 10)); + // slashing zero tokens is a no-op + assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 0), 0); + assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls); + + assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 10), 0); + assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 1); + + // `slash_reserved_named` calls `slash_reserved` under-the-hood with a + // value to slash based on the account's balance. Because the account's + // balance is currently zero, `slash_reserved` will be a no-op and + // the OnSlash hook will not be called. + assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 50), 50); + // Same value as previously because of the no-op + assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 1); + }); +} diff --git a/pallets/tokens/src/weights.rs b/pallets/tokens/src/weights.rs new file mode 100644 index 000000000..8f5637160 --- /dev/null +++ b/pallets/tokens/src/weights.rs @@ -0,0 +1,66 @@ +//! Autogenerated weights for orml_tokens +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-09-14, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// /Users/ermal/Acala/target/release/acala +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=orml_tokens +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --template=../templates/orml-weight-template.hbs +// --output=./tokens/src/weights.rs + + +#![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 orml_tokens. +pub trait WeightInfo { + fn transfer() -> Weight; + fn transfer_all() -> Weight; + fn transfer_keep_alive() -> Weight; + fn force_transfer() -> Weight; + fn set_balance() -> Weight; +} + +/// Default weights. +impl WeightInfo for () { + fn transfer() -> Weight { + Weight::from_parts(69_000_000, 0) + .saturating_add(RocksDbWeight::get().reads(5 as u64)) + .saturating_add(RocksDbWeight::get().writes(4 as u64)) + } + fn transfer_all() -> Weight { + Weight::from_parts(69_000_000, 0) + .saturating_add(RocksDbWeight::get().reads(5 as u64)) + .saturating_add(RocksDbWeight::get().writes(4 as u64)) + } + fn transfer_keep_alive() -> Weight { + Weight::from_parts(38_000_000, 0) + .saturating_add(RocksDbWeight::get().reads(3 as u64)) + .saturating_add(RocksDbWeight::get().writes(3 as u64)) + } + fn force_transfer() -> Weight { + Weight::from_parts(45_000_000, 0) + .saturating_add(RocksDbWeight::get().reads(4 as u64)) + .saturating_add(RocksDbWeight::get().writes(3 as u64)) + } + fn set_balance() -> Weight { + Weight::from_parts(34_000_000, 0) + .saturating_add(RocksDbWeight::get().reads(3 as u64)) + .saturating_add(RocksDbWeight::get().writes(3 as u64)) + } +} From b115483cd475bd0cafc9a3e66281358cbbc0920a Mon Sep 17 00:00:00 2001 From: mrq Date: Mon, 4 May 2026 14:01:15 +0200 Subject: [PATCH 03/17] integration test prep --- Cargo.lock | 2 + integration-tests/Cargo.toml | 2 + .../src/balances_tokens_hooks.rs | 287 ++++++++++++++++++ integration-tests/src/lib.rs | 1 + 4 files changed, 292 insertions(+) create mode 100644 integration-tests/src/balances_tokens_hooks.rs diff --git a/Cargo.lock b/Cargo.lock index 7b142f606..84db21a89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15702,6 +15702,7 @@ dependencies = [ "cumulus-test-relay-sproof-builder", "ethabi", "ethereum", + "ethereum-types", "fp-evm", "fp-rpc", "fp-self-contained", @@ -15773,6 +15774,7 @@ dependencies = [ "pallet-session", "pallet-stableswap", "pallet-staking 4.3.1", + "pallet-synthetic-logs", "pallet-timestamp", "pallet-transaction-multi-payment", "pallet-transaction-pause", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index d786a1345..73ab32e99 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -49,6 +49,8 @@ pallet-transaction-pause = { workspace = true } pallet-liquidation = { workspace = true } liquidation-worker-support = { workspace = true } pallet-broadcast = { workspace = true } +pallet-synthetic-logs = { workspace = true } +ethereum-types = { workspace = true } pallet-duster = { workspace = true } pallet-duster-rpc-runtime-api = { workspace = true } diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs new file mode 100644 index 000000000..8b8438883 --- /dev/null +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -0,0 +1,287 @@ +#![cfg(test)] + +use crate::polkadot_test_net::*; +use frame_support::assert_ok; +use hydradx_runtime::evm::precompiles::erc20_mapping::HydraErc20Mapping; +use hydradx_runtime::{Balances, Currencies, Runtime, RuntimeOrigin, Tokens}; +use hydradx_traits::evm::Erc20Mapping; +use orml_traits::MultiCurrency; +use pallet_synthetic_logs::{h160_to_h256, Pending as SyntheticLogsPending, TRANSFER_TOPIC}; +use ethereum_types::{H160, U256}; +use xcm_emulator::TestExt; + +fn buffered_logs() -> Vec<(pallet_synthetic_logs::Bucket, H160, ethereum::Log)> { + SyntheticLogsPending::::get() +} + +fn alice_h160() -> H160 { + hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)) +} + +fn bob_h160() -> H160 { + hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(BOB)) +} + +#[test] +fn currencies_transfer_routes_native_via_balances() { + TestNet::reset(); + Hydra::execute_with(|| { + assert_ok!(Currencies::transfer( + RuntimeOrigin::signed(ALICE.into()), + BOB.into(), + HDX, + UNITS, + )); + + expect_hydra_events(vec![pallet_balances::Event::Transfer { + from: ALICE.into(), + to: BOB.into(), + amount: UNITS, + } + .into()]); + }); +} + +#[test] +fn currencies_transfer_routes_non_native_via_orml_tokens() { + TestNet::reset(); + Hydra::execute_with(|| { + assert_ok!(Currencies::transfer( + RuntimeOrigin::signed(ALICE.into()), + BOB.into(), + DAI, + UNITS, + )); + + expect_hydra_events(vec![orml_tokens::Event::Transfer { + currency_id: DAI, + from: ALICE.into(), + to: BOB.into(), + amount: UNITS, + } + .into()]); + }); +} + +#[test] +fn orml_tokens_post_transfer_buffers_synth_log() { + TestNet::reset(); + Hydra::execute_with(|| { + assert_ok!(Currencies::transfer( + RuntimeOrigin::signed(ALICE.into()), + BOB.into(), + DAI, + UNITS, + )); + + let logs = buffered_logs(); + let asset_addr = HydraErc20Mapping::asset_address(DAI); + + let entry = logs + .iter() + .find(|(_, emitter, log)| *emitter == asset_addr && log.address == asset_addr) + .expect("synth log for DAI transfer"); + + let (_, _, log) = entry; + assert_eq!(log.topics[0], TRANSFER_TOPIC); + assert_eq!(log.topics[1], h160_to_h256(alice_h160())); + assert_eq!(log.topics[2], h160_to_h256(bob_h160())); + + let data = U256::from(UNITS).to_big_endian(); + assert_eq!(log.data.as_slice(), &data[..]); + }); +} + +#[test] +fn orml_tokens_post_deposit_buffers_mint_log() { + TestNet::reset(); + Hydra::execute_with(|| { + assert_ok!(Currencies::update_balance( + RuntimeOrigin::root(), + BOB.into(), + DAI, + UNITS as i128, + )); + + let logs = buffered_logs(); + let asset_addr = HydraErc20Mapping::asset_address(DAI); + let entry = logs + .iter() + .find(|(_, emitter, log)| { + *emitter == asset_addr && log.topics.first() == Some(&TRANSFER_TOPIC) && log.topics[1] == h160_to_h256(H160::zero()) + }) + .expect("synth log for DAI mint"); + + let (_, _, log) = entry; + assert_eq!(log.topics[1], h160_to_h256(H160::zero())); + assert_eq!(log.topics[2], h160_to_h256(bob_h160())); + }); +} + +#[test] +fn orml_tokens_on_slash_buffers_burn_log() { + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + >::deposit(DAI, &ALICE.into(), amount).unwrap(); + SyntheticLogsPending::::kill(); + + >::slash(DAI, &ALICE.into(), amount); + + let logs = buffered_logs(); + let asset_addr = HydraErc20Mapping::asset_address(DAI); + let entry = logs + .iter() + .find(|(_, emitter, log)| *emitter == asset_addr && log.topics[2] == h160_to_h256(H160::zero())) + .expect("synth log for DAI slash"); + + let (_, _, log) = entry; + assert_eq!(log.topics[0], TRANSFER_TOPIC); + assert_eq!(log.topics[1], h160_to_h256(alice_h160())); + assert_eq!(log.topics[2], h160_to_h256(H160::zero())); + }); +} + +#[test] +fn orml_tokens_zero_amount_transfer_does_not_buffer() { + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + assert_ok!(Currencies::transfer( + RuntimeOrigin::signed(ALICE.into()), + BOB.into(), + DAI, + 0, + )); + + let logs = buffered_logs(); + let asset_addr = HydraErc20Mapping::asset_address(DAI); + assert!( + logs.iter().all(|(_, emitter, _)| *emitter != asset_addr), + "zero-amount transfer must not buffer a log" + ); + }); +} + +#[test] +#[ignore] +fn balances_transfer_buffers_synth_log() { + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + assert_ok!(Balances::transfer_keep_alive( + RuntimeOrigin::signed(ALICE.into()), + BOB.into(), + UNITS, + )); + + let logs = buffered_logs(); + let asset_addr = HydraErc20Mapping::asset_address(HDX); + let entry = logs + .iter() + .find(|(_, emitter, _)| *emitter == asset_addr) + .expect("synth log for HDX balances transfer"); + + let (_, _, log) = entry; + assert_eq!(log.topics[0], TRANSFER_TOPIC); + assert_eq!(log.topics[1], h160_to_h256(alice_h160())); + assert_eq!(log.topics[2], h160_to_h256(bob_h160())); + }); +} + +#[test] +#[ignore] +fn balances_force_transfer_buffers_synth_log() { + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + assert_ok!(Balances::force_transfer( + RuntimeOrigin::root(), + ALICE.into(), + BOB.into(), + UNITS, + )); + + let asset_addr = HydraErc20Mapping::asset_address(HDX); + let entry = buffered_logs() + .into_iter() + .find(|(_, emitter, _)| *emitter == asset_addr) + .expect("synth log for HDX force_transfer"); + + let (_, _, log) = entry; + assert_eq!(log.topics[1], h160_to_h256(alice_h160())); + assert_eq!(log.topics[2], h160_to_h256(bob_h160())); + }); +} + +#[test] +#[ignore] +fn currencies_transfer_native_buffers_synth_log() { + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + assert_ok!(Currencies::transfer( + RuntimeOrigin::signed(ALICE.into()), + BOB.into(), + HDX, + UNITS, + )); + + let asset_addr = HydraErc20Mapping::asset_address(HDX); + assert!( + buffered_logs().iter().any(|(_, emitter, _)| *emitter == asset_addr), + "Currencies::transfer of native HDX must buffer a synth log" + ); + }); +} + +#[test] +#[ignore] +fn balances_dust_loss_buffers_burn_log() { + TestNet::reset(); + Hydra::execute_with(|| { + let hdx_ed = ::ExistentialDeposit::get(); + assert!(hdx_ed > 0); + + assert_ok!(Balances::force_set_balance( + RuntimeOrigin::root(), + ALICE.into(), + hdx_ed, + )); + SyntheticLogsPending::::kill(); + assert_ok!(Balances::transfer_allow_death( + RuntimeOrigin::signed(ALICE.into()), + BOB.into(), + hdx_ed - 1, + )); + + let asset_addr = HydraErc20Mapping::asset_address(HDX); + let burn_to_zero = buffered_logs() + .into_iter() + .find(|(_, emitter, log)| *emitter == asset_addr && log.topics[2] == h160_to_h256(H160::zero())); + assert!(burn_to_zero.is_some(), "dust loss must buffer Transfer(from, 0x0, amount)"); + }); +} + +#[test] +#[ignore] +fn currencies_withdraw_orml_buffers_burn_log() { + TestNet::reset(); + Hydra::execute_with(|| { + >::deposit(DAI, &ALICE.into(), UNITS).unwrap(); + SyntheticLogsPending::::kill(); + >::withdraw( + DAI, + &ALICE.into(), + UNITS, + frame_support::traits::ExistenceRequirement::AllowDeath, + ) + .unwrap(); + + let asset_addr = HydraErc20Mapping::asset_address(DAI); + let burn = buffered_logs() + .into_iter() + .find(|(_, emitter, log)| *emitter == asset_addr && log.topics[2] == h160_to_h256(H160::zero())); + assert!(burn.is_some(), "Currencies::withdraw must buffer Transfer(from, 0x0, amount)"); + }); +} diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 089926089..df942de6e 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -3,6 +3,7 @@ #![cfg(not(feature = "runtime-benchmarks"))] mod aave_router; mod asset_registry; +mod balances_tokens_hooks; mod bonds; mod call_filter; mod circuit_breaker; From 3f9e91b8e6fe4af2b9610561ea8ee42bbd4ecaa5 Mon Sep 17 00:00:00 2001 From: mrq Date: Mon, 4 May 2026 17:26:17 +0200 Subject: [PATCH 04/17] hooks --- Cargo.lock | 768 +++-- Cargo.toml | 1273 ++++---- .../src/balances_tokens_hooks.rs | 27 +- pallets/balances/Cargo.toml | 57 - pallets/balances/README.md | 122 - pallets/balances/src/benchmarking.rs | 368 --- pallets/balances/src/impl_currency.rs | 954 ------ pallets/balances/src/impl_fungible.rs | 387 --- pallets/balances/src/lib.rs | 1315 --------- pallets/balances/src/migration.rs | 103 - pallets/balances/src/tests/currency_tests.rs | 1445 --------- .../balances/src/tests/dispatchable_tests.rs | 384 --- .../src/tests/fungible_conformance_tests.rs | 141 - pallets/balances/src/tests/fungible_tests.rs | 670 ----- pallets/balances/src/tests/general_tests.rs | 143 - pallets/balances/src/tests/mod.rs | 351 --- .../balances/src/tests/reentrancy_tests.rs | 196 -- pallets/balances/src/types.rs | 185 -- pallets/balances/src/weights.rs | 321 -- pallets/circuit-breaker/src/tests/mock.rs | 3 + pallets/claims/src/mock.rs | 1 + pallets/collator-rewards/src/mock.rs | 1 + pallets/currencies/src/mock.rs | 1 + pallets/dca/src/tests/mock.rs | 1 + pallets/democracy/src/tests.rs | 1 + pallets/dispenser/src/tests/mod.rs | 1 + pallets/duster/src/mock.rs | 1 + pallets/dynamic-evm-fee/src/tests/mock.rs | 1 + pallets/evm-accounts/src/mock.rs | 1 + pallets/liquidation/src/tests/mock.rs | 1 + pallets/liquidity-mining/src/tests/mock.rs | 1 + pallets/nft/src/mock.rs | 1 + .../src/tests/mock.rs | 1 + pallets/omnipool/src/tests/mock.rs | 1 + pallets/otc-settlements/src/mock.rs | 1 + pallets/route-executor/src/tests/mock.rs | 1 + pallets/signet/src/tests/mod.rs | 1 + pallets/stableswap/src/tests/mock.rs | 2 + pallets/staking/src/tests/mock.rs | 1 + pallets/synthetic-logs/src/tests.rs | 7 +- pallets/tokens/Cargo.toml | 54 - pallets/tokens/README.md | 13 - pallets/tokens/runtime-api/Cargo.toml | 23 - pallets/tokens/runtime-api/src/lib.rs | 18 - pallets/tokens/src/imbalances.rs | 197 -- pallets/tokens/src/impls.rs | 352 --- pallets/tokens/src/lib.rs | 2605 ----------------- pallets/tokens/src/mock.rs | 445 --- pallets/tokens/src/tests.rs | 1271 -------- pallets/tokens/src/tests_currency_adapter.rs | 674 ----- pallets/tokens/src/tests_events.rs | 469 --- pallets/tokens/src/tests_fungibles.rs | 741 ----- pallets/tokens/src/tests_multicurrency.rs | 808 ----- pallets/tokens/src/weights.rs | 66 - pallets/transaction-multi-payment/src/mock.rs | 3 + pallets/transaction-pause/src/mock.rs | 1 + .../xyk-liquidity-mining/src/tests/mock.rs | 1 + precompiles/call-permit/src/mock.rs | 1 + runtime/adapters/src/tests/mock.rs | 1 + runtime/hydradx/src/assets.rs | 3 + runtime/hydradx/src/evm/erc20_logs.rs | 83 +- 61 files changed, 1112 insertions(+), 15957 deletions(-) delete mode 100644 pallets/balances/Cargo.toml delete mode 100644 pallets/balances/README.md delete mode 100644 pallets/balances/src/benchmarking.rs delete mode 100644 pallets/balances/src/impl_currency.rs delete mode 100644 pallets/balances/src/impl_fungible.rs delete mode 100644 pallets/balances/src/lib.rs delete mode 100644 pallets/balances/src/migration.rs delete mode 100644 pallets/balances/src/tests/currency_tests.rs delete mode 100644 pallets/balances/src/tests/dispatchable_tests.rs delete mode 100644 pallets/balances/src/tests/fungible_conformance_tests.rs delete mode 100644 pallets/balances/src/tests/fungible_tests.rs delete mode 100644 pallets/balances/src/tests/general_tests.rs delete mode 100644 pallets/balances/src/tests/mod.rs delete mode 100644 pallets/balances/src/tests/reentrancy_tests.rs delete mode 100644 pallets/balances/src/types.rs delete mode 100644 pallets/balances/src/weights.rs delete mode 100644 pallets/tokens/Cargo.toml delete mode 100644 pallets/tokens/README.md delete mode 100644 pallets/tokens/runtime-api/Cargo.toml delete mode 100644 pallets/tokens/runtime-api/src/lib.rs delete mode 100644 pallets/tokens/src/imbalances.rs delete mode 100644 pallets/tokens/src/impls.rs delete mode 100644 pallets/tokens/src/lib.rs delete mode 100644 pallets/tokens/src/mock.rs delete mode 100644 pallets/tokens/src/tests.rs delete mode 100644 pallets/tokens/src/tests_currency_adapter.rs delete mode 100644 pallets/tokens/src/tests_events.rs delete mode 100644 pallets/tokens/src/tests_fungibles.rs delete mode 100644 pallets/tokens/src/tests_multicurrency.rs delete mode 100644 pallets/tokens/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index fb7c6b60f..de2ae1ba6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1086,7 +1086,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "asset-test-utils" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -1116,7 +1116,7 @@ dependencies = [ [[package]] name = "assets-common" version = "0.22.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "ethereum-standards", @@ -1482,7 +1482,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "binary-merkle-tree" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "hash-db", "log", @@ -1779,7 +1779,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1796,7 +1796,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-runtime", @@ -1812,7 +1812,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -1829,7 +1829,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-messages", "bp-runtime", @@ -1846,7 +1846,7 @@ dependencies = [ [[package]] name = "bp-relayers" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-messages", @@ -1864,7 +1864,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -1887,7 +1887,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-parachains", @@ -1907,7 +1907,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-messages", "bp-runtime", @@ -1924,7 +1924,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub-router" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -1936,7 +1936,7 @@ dependencies = [ [[package]] name = "bridge-hub-common" version = "0.14.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1955,7 +1955,7 @@ dependencies = [ [[package]] name = "bridge-hub-test-utils" version = "0.23.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "asset-test-utils", "bp-header-chain", @@ -1997,7 +1997,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.22.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-messages", @@ -2928,7 +2928,7 @@ dependencies = [ [[package]] name = "cumulus-client-bootnodes" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -2954,7 +2954,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "clap", "parity-scale-codec", @@ -2971,7 +2971,7 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -2994,7 +2994,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" version = "0.24.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-client-collator", @@ -3041,7 +3041,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -3073,7 +3073,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-proposer" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "anyhow", "async-trait", @@ -3088,7 +3088,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-relay-chain" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-client-consensus-common", @@ -3111,7 +3111,7 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -3138,7 +3138,7 @@ dependencies = [ [[package]] name = "cumulus-client-parachain-inherent" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3159,7 +3159,7 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3187,7 +3187,7 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.25.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-channel 1.9.0", "cumulus-client-cli", @@ -3228,7 +3228,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-aura-ext" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3245,7 +3245,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system" version = "0.21.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "bytes", @@ -3300,7 +3300,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.6.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -3311,7 +3311,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-session-benchmarking" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-solo-to-para" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-weight-reclaim" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-storage-weight-reclaim", "derive-where", @@ -3358,7 +3358,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3373,7 +3373,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.21.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "approx", "bounded-collections 0.2.4", @@ -3399,7 +3399,7 @@ dependencies = [ [[package]] name = "cumulus-ping" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-pallet-xcm", "cumulus-primitives-core", @@ -3414,7 +3414,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-aura" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "sp-api", "sp-consensus-aura", @@ -3423,7 +3423,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -3440,7 +3440,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3454,7 +3454,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-proof-size-hostfunction" version = "0.13.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "sp-externalities", "sp-runtime-interface", @@ -3464,7 +3464,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-storage-weight-reclaim" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-proof-size-hostfunction", @@ -3481,7 +3481,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-timestamp" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "sp-inherents", @@ -3491,7 +3491,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-utility" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3508,7 +3508,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -3536,7 +3536,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3556,7 +3556,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-minimal-node" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -3592,7 +3592,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-streams" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-relay-chain-interface", "futures", @@ -3647,7 +3647,7 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -4417,7 +4417,7 @@ dependencies = [ [[package]] name = "ethereum-standards" version = "0.1.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "alloy-core", ] @@ -4922,7 +4922,7 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fork-tree" version = "13.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", ] @@ -5060,7 +5060,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-support-procedural", @@ -5084,7 +5084,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "49.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "Inflector", "array-bytes 6.2.2", @@ -5149,7 +5149,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-pallet-pov" version = "31.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -5177,7 +5177,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "16.1.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -5188,7 +5188,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -5205,7 +5205,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "aquamarine", "frame-support", @@ -5247,7 +5247,7 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" version = "0.9.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "const-hex", @@ -5263,7 +5263,7 @@ dependencies = [ [[package]] name = "frame-remote-externalities" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "indicatif", @@ -5285,7 +5285,7 @@ dependencies = [ [[package]] name = "frame-storage-access-test-runtime" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-pallet-parachain-system", "parity-scale-codec", @@ -5299,7 +5299,7 @@ dependencies = [ [[package]] name = "frame-support" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "aquamarine", "array-bytes 6.2.2", @@ -5340,7 +5340,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "34.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "Inflector", "cfg-expr", @@ -5360,7 +5360,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "13.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.1.0", @@ -5372,7 +5372,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro2", "quote", @@ -5382,7 +5382,7 @@ dependencies = [ [[package]] name = "frame-system" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cfg-if", "docify", @@ -5401,7 +5401,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -5415,7 +5415,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "parity-scale-codec", @@ -5425,7 +5425,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.47.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "parity-scale-codec", @@ -8456,7 +8456,7 @@ dependencies = [ [[package]] name = "mmr-gadget" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "log", @@ -8475,7 +8475,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -9141,7 +9141,7 @@ dependencies = [ [[package]] name = "orml-benchmarking" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-benchmarking", "frame-support", @@ -9162,28 +9162,24 @@ dependencies = [ [[package]] name = "orml-tokens" version = "1.4.0" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "frame-system", "log", "orml-traits", - "pallet-elections-phragmen", - "pallet-treasury", "parity-scale-codec", "scale-info", "serde", "sp-arithmetic", - "sp-core", - "sp-io", "sp-runtime", - "sp-staking", "sp-std", ] [[package]] name = "orml-traits" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -9203,7 +9199,7 @@ dependencies = [ [[package]] name = "orml-unknown-tokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "frame-system", @@ -9218,7 +9214,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "parity-scale-codec", @@ -9233,7 +9229,7 @@ dependencies = [ [[package]] name = "orml-vesting" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "frame-system", @@ -9248,7 +9244,7 @@ dependencies = [ [[package]] name = "orml-xcm" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "frame-system", @@ -9262,7 +9258,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "orml-traits", @@ -9276,7 +9272,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506#d20eee81b61c385918869e1633b91cfed49ed60b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" dependencies = [ "frame-support", "frame-system", @@ -9303,7 +9299,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pallet-alliance" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "frame-benchmarking", @@ -9323,7 +9319,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9341,7 +9337,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-ops" version = "0.9.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9359,7 +9355,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-tx-payment" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9374,7 +9370,7 @@ dependencies = [ [[package]] name = "pallet-asset-rate" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9417,7 +9413,7 @@ dependencies = [ [[package]] name = "pallet-asset-rewards" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9435,7 +9431,7 @@ dependencies = [ [[package]] name = "pallet-asset-tx-payment" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9451,7 +9447,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "43.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "ethereum-standards", "frame-benchmarking", @@ -9469,7 +9465,7 @@ dependencies = [ [[package]] name = "pallet-assets-freezer" version = "0.8.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "pallet-assets", @@ -9481,7 +9477,7 @@ dependencies = [ [[package]] name = "pallet-assets-holder" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9496,7 +9492,7 @@ dependencies = [ [[package]] name = "pallet-atomic-swap" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -9506,7 +9502,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -9522,7 +9518,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -9537,7 +9533,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -9550,7 +9546,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9573,7 +9569,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "aquamarine", "docify", @@ -9594,25 +9590,23 @@ dependencies = [ [[package]] name = "pallet-balances" version = "42.0.0" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", "frame-support", "frame-system", "log", - "pallet-transaction-payment", "parity-scale-codec", - "paste", "scale-info", "sp-core", - "sp-io", "sp-runtime", ] [[package]] name = "pallet-beefy" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -9631,7 +9625,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "binary-merkle-tree", @@ -9680,7 +9674,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9697,7 +9691,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-runtime", @@ -9716,7 +9710,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-messages", @@ -9735,7 +9729,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-parachains", @@ -9755,7 +9749,7 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-header-chain", "bp-messages", @@ -9798,7 +9792,7 @@ dependencies = [ [[package]] name = "pallet-broker" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "frame-benchmarking", @@ -9816,7 +9810,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9925,7 +9919,7 @@ dependencies = [ [[package]] name = "pallet-collator-selection" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9944,7 +9938,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -9961,7 +9955,7 @@ dependencies = [ [[package]] name = "pallet-collective-content" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -9975,7 +9969,7 @@ dependencies = [ [[package]] name = "pallet-contracts" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "environmental", "frame-benchmarking", @@ -10006,7 +10000,7 @@ dependencies = [ [[package]] name = "pallet-contracts-mock-network" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -10037,7 +10031,7 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "23.0.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro2", "quote", @@ -10047,7 +10041,7 @@ dependencies = [ [[package]] name = "pallet-contracts-uapi" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -10058,7 +10052,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "assert_matches", "frame-benchmarking", @@ -10074,7 +10068,7 @@ dependencies = [ [[package]] name = "pallet-core-fellowship" version = "25.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -10166,7 +10160,7 @@ dependencies = [ [[package]] name = "pallet-delegated-staking" version = "8.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -10201,7 +10195,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -10218,7 +10212,7 @@ dependencies = [ [[package]] name = "pallet-dev-mode" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -10286,7 +10280,7 @@ dependencies = [ [[package]] name = "pallet-dummy-dim" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -10385,7 +10379,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-block" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10406,7 +10400,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10427,7 +10421,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10440,7 +10434,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -10680,7 +10674,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -10716,7 +10710,7 @@ dependencies = [ [[package]] name = "pallet-glutton" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "blake2 0.10.6", "frame-benchmarking", @@ -10734,7 +10728,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -10807,7 +10801,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "enumflags2", "frame-benchmarking", @@ -10823,7 +10817,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -10842,7 +10836,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -10857,7 +10851,7 @@ dependencies = [ [[package]] name = "pallet-insecure-randomness-collective-flip" version = "29.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11022,7 +11016,7 @@ dependencies = [ [[package]] name = "pallet-lottery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11035,7 +11029,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11051,7 +11045,7 @@ dependencies = [ [[package]] name = "pallet-message-queue" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "environmental", "frame-benchmarking", @@ -11070,7 +11064,7 @@ dependencies = [ [[package]] name = "pallet-meta-tx" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -11088,7 +11082,7 @@ dependencies = [ [[package]] name = "pallet-migrations" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -11107,7 +11101,7 @@ dependencies = [ [[package]] name = "pallet-mixnet" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "parity-scale-codec", @@ -11121,7 +11115,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "parity-scale-codec", @@ -11133,7 +11127,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "parity-scale-codec", @@ -11164,7 +11158,7 @@ dependencies = [ [[package]] name = "pallet-nft-fractionalization" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "pallet-assets", @@ -11177,7 +11171,7 @@ dependencies = [ [[package]] name = "pallet-nfts" version = "35.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "enumflags2", "frame-benchmarking", @@ -11194,7 +11188,7 @@ dependencies = [ [[package]] name = "pallet-nfts-runtime-api" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "sp-api", @@ -11203,7 +11197,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11213,7 +11207,7 @@ dependencies = [ [[package]] name = "pallet-node-authorization" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "parity-scale-codec", @@ -11224,7 +11218,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -11242,7 +11236,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11262,7 +11256,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -11272,7 +11266,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -11287,7 +11281,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11370,7 +11364,7 @@ dependencies = [ [[package]] name = "pallet-origin-restriction" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11442,7 +11436,7 @@ dependencies = [ [[package]] name = "pallet-paged-list" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "parity-scale-codec", @@ -11454,7 +11448,7 @@ dependencies = [ [[package]] name = "pallet-parameters" version = "0.12.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -11485,7 +11479,7 @@ dependencies = [ [[package]] name = "pallet-people" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11503,7 +11497,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11519,7 +11513,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11529,7 +11523,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11547,7 +11541,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11557,7 +11551,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "assert_matches", "frame-benchmarking", @@ -11611,7 +11605,7 @@ dependencies = [ [[package]] name = "pallet-remark" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11627,7 +11621,7 @@ dependencies = [ [[package]] name = "pallet-revive" version = "0.7.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "alloy-core", "derive_more 0.99.20", @@ -11673,7 +11667,7 @@ dependencies = [ [[package]] name = "pallet-revive-fixtures" version = "0.4.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "anyhow", "cargo_metadata", @@ -11687,7 +11681,7 @@ dependencies = [ [[package]] name = "pallet-revive-proc-macro" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro2", "quote", @@ -11697,7 +11691,7 @@ dependencies = [ [[package]] name = "pallet-revive-uapi" version = "0.5.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitflags 1.3.2", "pallet-revive-proc-macro", @@ -11709,7 +11703,7 @@ dependencies = [ [[package]] name = "pallet-root-offences" version = "38.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -11725,7 +11719,7 @@ dependencies = [ [[package]] name = "pallet-root-testing" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -11765,7 +11759,7 @@ dependencies = [ [[package]] name = "pallet-safe-mode" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "pallet-balances", @@ -11779,7 +11773,7 @@ dependencies = [ [[package]] name = "pallet-salary" version = "26.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "pallet-ranked-collective", @@ -11791,7 +11785,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -11808,7 +11802,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -11821,7 +11815,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -11842,7 +11836,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11876,7 +11870,7 @@ dependencies = [ [[package]] name = "pallet-skip-feeless-payment" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -11888,7 +11882,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -11964,7 +11958,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11986,7 +11980,7 @@ dependencies = [ [[package]] name = "pallet-staking-async" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -12009,7 +12003,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-ah-client" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -12028,7 +12022,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-rc-client" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -12045,7 +12039,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-reward-fn" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "sp-arithmetic", @@ -12054,7 +12048,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-runtime-api" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "sp-api", @@ -12064,7 +12058,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "sp-arithmetic", @@ -12073,7 +12067,7 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "sp-api", @@ -12083,7 +12077,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12099,7 +12093,7 @@ dependencies = [ [[package]] name = "pallet-statement" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", @@ -12116,7 +12110,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -12155,7 +12149,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -12173,7 +12167,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12261,7 +12255,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12276,7 +12270,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -12292,7 +12286,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -12304,7 +12298,7 @@ dependencies = [ [[package]] name = "pallet-transaction-storage" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "frame-benchmarking", @@ -12324,7 +12318,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -12343,7 +12337,7 @@ dependencies = [ [[package]] name = "pallet-tx-pause" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "parity-scale-codec", @@ -12354,7 +12348,7 @@ dependencies = [ [[package]] name = "pallet-uniques" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12368,7 +12362,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12384,7 +12378,7 @@ dependencies = [ [[package]] name = "pallet-verify-signature" version = "0.4.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12399,7 +12393,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12413,7 +12407,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -12423,7 +12417,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "20.1.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bounded-collections 0.2.4", "frame-benchmarking", @@ -12449,7 +12443,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-benchmarking", "frame-support", @@ -12466,7 +12460,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-messages", "bp-runtime", @@ -12488,7 +12482,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub-router" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-xcm-bridge-hub-router", "frame-benchmarking", @@ -12561,7 +12555,7 @@ dependencies = [ [[package]] name = "parachains-common" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -12590,7 +12584,7 @@ dependencies = [ [[package]] name = "parachains-runtimes-test-utils" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -12948,7 +12942,7 @@ dependencies = [ [[package]] name = "polkadot-approval-distribution" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "futures-timer", @@ -12966,7 +12960,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "futures-timer", @@ -12981,7 +12975,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "fatality", "futures", @@ -13004,7 +12998,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "fatality", @@ -13037,7 +13031,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "clap", "frame-benchmarking-cli", @@ -13061,7 +13055,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "24.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "fatality", @@ -13084,7 +13078,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -13095,7 +13089,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "fatality", "futures", @@ -13117,7 +13111,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -13131,7 +13125,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "futures-timer", @@ -13152,7 +13146,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "always-assert", "async-trait", @@ -13175,7 +13169,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "parity-scale-codec", @@ -13193,7 +13187,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "bitvec", @@ -13225,7 +13219,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting-parallel" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -13249,7 +13243,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "futures", @@ -13268,7 +13262,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "fatality", @@ -13289,7 +13283,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "polkadot-node-subsystem", @@ -13304,7 +13298,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -13326,7 +13320,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "polkadot-node-metrics", @@ -13340,7 +13334,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "futures-timer", @@ -13356,7 +13350,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "fatality", "futures", @@ -13374,7 +13368,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -13391,7 +13385,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-prospective-parachains" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "fatality", "futures", @@ -13405,7 +13399,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "fatality", @@ -13422,7 +13416,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "always-assert", "array-bytes 6.2.2", @@ -13450,7 +13444,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "polkadot-node-subsystem", @@ -13463,7 +13457,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-common" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cpu-time", "futures", @@ -13489,7 +13483,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "polkadot-node-metrics", @@ -13504,7 +13498,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bs58", "futures", @@ -13521,7 +13515,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -13546,7 +13540,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "20.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "bounded-vec", @@ -13570,7 +13564,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "polkadot-node-subsystem-types", "polkadot-overseer", @@ -13579,7 +13573,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "derive_more 0.99.20", @@ -13607,7 +13601,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "fatality", "futures", @@ -13638,7 +13632,7 @@ dependencies = [ [[package]] name = "polkadot-omni-node-lib" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "clap", @@ -13724,7 +13718,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -13744,7 +13738,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-primitives" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bounded-collections 0.2.4", "derive_more 0.99.20", @@ -13760,7 +13754,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "bounded-collections 0.2.4", @@ -13789,7 +13783,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "jsonrpsee", "mmr-rpc", @@ -13822,7 +13816,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "frame-benchmarking", @@ -13872,7 +13866,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bs58", "frame-benchmarking", @@ -13884,7 +13878,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "20.0.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -13932,7 +13926,7 @@ dependencies = [ [[package]] name = "polkadot-sdk" version = "2506.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "asset-test-utils", "assets-common", @@ -14171,7 +14165,7 @@ dependencies = [ [[package]] name = "polkadot-sdk-frame" version = "0.10.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-benchmarking", @@ -14206,7 +14200,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "frame-benchmarking", @@ -14314,7 +14308,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitvec", "fatality", @@ -14334,7 +14328,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -15495,7 +15489,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "binary-merkle-tree", "bitvec", @@ -15593,7 +15587,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "polkadot-primitives", @@ -16162,7 +16156,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "32.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "sp-core", @@ -16173,7 +16167,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.51.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -16204,7 +16198,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "log", @@ -16225,7 +16219,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.45.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "sp-api", @@ -16240,7 +16234,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "clap", @@ -16267,7 +16261,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -16278,7 +16272,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.53.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "chrono", @@ -16320,7 +16314,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "fnv", "futures", @@ -16346,7 +16340,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.47.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "hash-db", "kvdb", @@ -16374,7 +16368,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -16397,7 +16391,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -16426,7 +16420,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "fork-tree", @@ -16462,7 +16456,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "jsonrpsee", @@ -16484,7 +16478,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16518,7 +16512,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "jsonrpsee", @@ -16538,7 +16532,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "fork-tree", "parity-scale-codec", @@ -16551,7 +16545,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "ahash", "array-bytes 6.2.2", @@ -16595,7 +16589,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "finality-grandpa", "futures", @@ -16615,7 +16609,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "assert_matches", "async-trait", @@ -16650,7 +16644,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -16673,7 +16667,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -16696,7 +16690,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "polkavm 0.24.0", "sc-allocator", @@ -16709,7 +16703,7 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "polkavm 0.24.0", @@ -16720,7 +16714,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "anyhow", "log", @@ -16736,7 +16730,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "console", "futures", @@ -16752,7 +16746,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "36.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "parking_lot 0.12.3", @@ -16766,7 +16760,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "arrayvec 0.7.4", @@ -16794,7 +16788,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.51.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16844,7 +16838,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.49.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -16854,7 +16848,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "ahash", "futures", @@ -16873,7 +16867,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16894,7 +16888,7 @@ dependencies = [ [[package]] name = "sc-network-statement" version = "0.33.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16915,7 +16909,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16950,7 +16944,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "futures", @@ -16969,7 +16963,7 @@ dependencies = [ [[package]] name = "sc-network-types" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bs58", "bytes", @@ -16990,7 +16984,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bytes", "fnv", @@ -17024,7 +17018,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -17033,7 +17027,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "jsonrpsee", @@ -17065,7 +17059,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17085,7 +17079,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "dyn-clone", "forwarded-header-value", @@ -17109,7 +17103,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "futures", @@ -17142,7 +17136,7 @@ dependencies = [ [[package]] name = "sc-runtime-utilities" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "sc-executor", @@ -17157,7 +17151,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "directories", @@ -17221,7 +17215,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "parity-scale-codec", @@ -17232,7 +17226,7 @@ dependencies = [ [[package]] name = "sc-statement-store" version = "22.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "parity-db", @@ -17252,7 +17246,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "clap", "fs4", @@ -17265,7 +17259,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17284,7 +17278,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "43.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "derive_more 0.99.20", "futures", @@ -17304,7 +17298,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "29.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "chrono", "futures", @@ -17323,7 +17317,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "40.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "chrono", "console", @@ -17353,7 +17347,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -17364,7 +17358,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "40.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -17395,7 +17389,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -17412,7 +17406,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-channel 1.9.0", "futures", @@ -18167,7 +18161,7 @@ dependencies = [ [[package]] name = "slot-range-helper" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "enumn", "parity-scale-codec", @@ -18430,7 +18424,7 @@ dependencies = [ [[package]] name = "snowbridge-core" version = "0.14.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bp-relayers", "frame-support", @@ -18515,7 +18509,7 @@ dependencies = [ [[package]] name = "sp-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "hash-db", @@ -18537,7 +18531,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "Inflector", "blake2 0.10.6", @@ -18551,7 +18545,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -18563,7 +18557,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "integer-sqrt", @@ -18577,7 +18571,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -18589,7 +18583,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "sp-api", "sp-inherents", @@ -18599,7 +18593,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "futures", "parity-scale-codec", @@ -18620,7 +18614,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "futures", @@ -18634,7 +18628,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "parity-scale-codec", @@ -18650,7 +18644,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "parity-scale-codec", @@ -18668,7 +18662,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -18688,7 +18682,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "finality-grandpa", "log", @@ -18705,7 +18699,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "sp-api", @@ -18716,7 +18710,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -18727,7 +18721,7 @@ dependencies = [ [[package]] name = "sp-core" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "ark-vrf", "array-bytes 6.2.2", @@ -18775,7 +18769,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "sp-crypto-hashing", ] @@ -18783,7 +18777,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.16.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -18803,7 +18797,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "blake2b_simd", "byteorder", @@ -18816,7 +18810,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "quote", "sp-crypto-hashing", @@ -18826,7 +18820,7 @@ dependencies = [ [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "kvdb", "parking_lot 0.12.3", @@ -18835,7 +18829,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "proc-macro2", "quote", @@ -18845,7 +18839,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.30.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "environmental", "parity-scale-codec", @@ -18855,7 +18849,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -18867,7 +18861,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -18880,7 +18874,7 @@ dependencies = [ [[package]] name = "sp-io" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bytes", "docify", @@ -18906,7 +18900,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "sp-core", "sp-runtime", @@ -18916,7 +18910,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -18927,7 +18921,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "thiserror 1.0.69", "zstd 0.12.4", @@ -18936,7 +18930,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.11.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-metadata 23.0.1", "parity-scale-codec", @@ -18946,7 +18940,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.15.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -18957,7 +18951,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "log", "parity-scale-codec", @@ -18974,7 +18968,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -18987,7 +18981,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "sp-api", "sp-core", @@ -18997,7 +18991,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "backtrace", "regex", @@ -19006,7 +19000,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "35.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "rustc-hash 1.1.0", "serde", @@ -19016,7 +19010,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "binary-merkle-tree", "docify", @@ -19045,7 +19039,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -19064,7 +19058,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "Inflector", "expander", @@ -19077,7 +19071,7 @@ dependencies = [ [[package]] name = "sp-session" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "scale-info", @@ -19091,7 +19085,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -19104,7 +19098,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.46.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "hash-db", "log", @@ -19124,7 +19118,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "21.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "aes-gcm", "curve25519-dalek", @@ -19148,12 +19142,12 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" [[package]] name = "sp-storage" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "impl-serde", "parity-scale-codec", @@ -19165,7 +19159,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "parity-scale-codec", @@ -19177,7 +19171,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "17.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "tracing", @@ -19188,7 +19182,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "sp-api", "sp-runtime", @@ -19197,7 +19191,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "parity-scale-codec", @@ -19211,7 +19205,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "40.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "ahash", "foldhash 0.1.5", @@ -19236,7 +19230,7 @@ dependencies = [ [[package]] name = "sp-version" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "impl-serde", "parity-scale-codec", @@ -19253,7 +19247,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "15.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "parity-scale-codec", "proc-macro-warning", @@ -19265,7 +19259,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -19277,7 +19271,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "32.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "bounded-collections 0.2.4", "parity-scale-codec", @@ -19354,7 +19348,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-chain-spec-builder" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "clap", "docify", @@ -19367,7 +19361,7 @@ dependencies = [ [[package]] name = "staging-node-inspect" version = "0.29.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "clap", "parity-scale-codec", @@ -19385,7 +19379,7 @@ dependencies = [ [[package]] name = "staging-parachain-info" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -19398,7 +19392,7 @@ dependencies = [ [[package]] name = "staging-xcm" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "bounded-collections 0.2.4", @@ -19419,7 +19413,7 @@ dependencies = [ [[package]] name = "staging-xcm-builder" version = "21.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "environmental", "frame-support", @@ -19443,7 +19437,7 @@ dependencies = [ [[package]] name = "staging-xcm-executor" version = "20.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "environmental", "frame-benchmarking", @@ -19558,7 +19552,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.6.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -19583,12 +19577,12 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" [[package]] name = "substrate-frame-rpc-system" version = "45.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "docify", "frame-system-rpc-runtime-api", @@ -19608,7 +19602,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.6" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "http-body-util", "hyper 1.5.1", @@ -19622,7 +19616,7 @@ dependencies = [ [[package]] name = "substrate-rpc-client" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "async-trait", "jsonrpsee", @@ -19652,7 +19646,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -19669,7 +19663,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "27.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "build-helper", @@ -20107,7 +20101,7 @@ dependencies = [ [[package]] name = "testnet-parachains-constants" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -20620,7 +20614,7 @@ dependencies = [ [[package]] name = "tracing-gum" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "coarsetime", "polkadot-primitives", @@ -20631,7 +20625,7 @@ dependencies = [ [[package]] name = "tracing-gum-proc-macro" version = "5.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "expander", "proc-macro-crate 3.1.0", @@ -21545,7 +21539,7 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "westend-runtime" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "binary-merkle-tree", "bitvec", @@ -21652,7 +21646,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "polkadot-primitives", @@ -22259,7 +22253,7 @@ dependencies = [ [[package]] name = "xcm-emulator" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "array-bytes 6.2.2", "cumulus-pallet-parachain-system", @@ -22293,7 +22287,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "11.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "Inflector", "proc-macro2", @@ -22304,7 +22298,7 @@ dependencies = [ [[package]] name = "xcm-runtime-apis" version = "0.8.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "parity-scale-codec", @@ -22318,7 +22312,7 @@ dependencies = [ [[package]] name = "xcm-simulator" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch#478f0c6d701cd4371203f357a8144136b763b6b9" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" dependencies = [ "frame-support", "frame-system", diff --git a/Cargo.toml b/Cargo.toml index c4e9b46d6..80e60a625 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,8 +53,6 @@ members = [ "pallets/signet", "pallets/dispenser", "pallets/synthetic-logs", - "pallets/balances", - "pallets/tokens", ] resolver = "2" @@ -181,156 +179,156 @@ pallet-evm-precompile-flash-loan = { path = "precompiles/flash-loan", default-fe precompile-utils = { path = "precompiles/utils", default-features = false } # Frame -frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false, features = ["tuples-96"] } -frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false, features = ["tuples-96"] } -frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-consensus-beefy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-crypto-ec-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } - -sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } +frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false, features = ["tuples-96"] } +frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false, features = ["tuples-96"] } +frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-consensus-beefy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-crypto-ec-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } + +sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } # Substrate Pallets -pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-balances = { path = "pallets/balances", default-features = false } -pallet-bags-list = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-conviction-voting = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-migrations = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-referenda = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-whitelist = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } - -substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } +pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-bags-list = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-conviction-voting = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-migrations = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-referenda = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-whitelist = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } + +substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } #TODO: We use our custom ORML as it contains the fix of bug for reducible_balance check, for Preserve mode. Once the official ORML pushes a new version with the fix, we can use that again # ORML dependencies -orml-benchmarking = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-currencies = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-tokens = { path = "pallets/tokens", default-features = false } -orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-utilities = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-vesting = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } +orml-benchmarking = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-currencies = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-utilities = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-vesting = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } # orml XCM support -orml-unknown-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-xcm = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-xcm-support = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } -orml-xtokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506", default-features = false } +orml-unknown-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-xcm = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-xcm-support = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } +orml-xtokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks", default-features = false } # Cumulus dependencies -cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-pallet-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-primitives-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } +cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-pallet-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-primitives-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } # Frontier fc-consensus = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-stable2506", default-features = false } @@ -365,36 +363,36 @@ ethereum = { version = "0.18.2", default-features = false, features = [ ethereum-types = { version = "0.15.1", default-features = false } # Polkadot dependencies -pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false, features = [ +pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false, features = [ "wasm-api", ] } -polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -polkadot-xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } - -polkadot-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch", default-features = false } -polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +polkadot-xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } + +polkadot-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks", default-features = false } +polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Hyperbridge pallet-hyperbridge = { version = "2506.1.1", default-features = false } @@ -412,499 +410,494 @@ ismp-parachain-inherent = { version = "2506.1.0" } [patch."https://github.com/moonbeam-foundation/open-runtime-module-library"] # ORML dependencies -orml-benchmarking = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-tokens = { path = "pallets/tokens" } -orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-utilities = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-vesting = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-unknown-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-xcm = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-xcm-support = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-xtokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } +orml-benchmarking = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-utilities = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-vesting = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-unknown-tokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-xcm = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-xcm-support = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-xtokens = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } [patch."https://github.com/moonbeam-foundation/polkadot-sdk"] -frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-panic-handler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-database = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-panic-handler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-database = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Substrate Pallets -pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-balances = { path = "pallets/balances" } -pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Cumulus dependencies -cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Polkadot dependencies -pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } [patch."https://github.com/paritytech/polkadot-sdk"] -polkadot-sdk = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-panic-handler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-database = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +polkadot-sdk = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-panic-handler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-database = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Substrate Pallets -pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-balances = { path = "pallets/balances" } -pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Cumulus dependencies -cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Polkadot dependencies -pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } [patch.crates-io] -polkadot-sdk = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus-epochs = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-panic-handler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-database = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sc-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +polkadot-sdk = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus-epochs = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-benchmarking-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-executive = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-remote-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-support = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-support-procedural = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system-benchmarking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-system-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-try-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +frame-metadata-hash-extension = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-authority-discovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-block-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-genesis-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-blockchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-consensus-babe = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-externalities = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-inherents = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-io = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-npos-elections = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-offchain = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-runtime-interface-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-wasm-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-panic-handler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-database = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-staking = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-std = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-storage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-trie = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-version = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-basic-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-chain-spec = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-client-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-client-db = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-consensus-grandpa = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-executor = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-keystore = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network-sync = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-network-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-rpc-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-telemetry = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-tracing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-transaction-pool = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-transaction-pool-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-sysinfo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sc-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-state-machine = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-weights = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +sp-crypto-hashing = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Substrate Pallets -pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-balances = { path = "pallets/balances" } -pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-authorship = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-balances = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-collective = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-elections-phragmen = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-identity = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-multisig = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-preimage = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-proxy = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-scheduler = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-session = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-sudo = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-tips = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-treasury = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-uniques = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-im-online = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-message-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-state-trie-migration = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +substrate-build-script-utils = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-frame-rpc-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-prometheus-endpoint = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-rpc-client = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-wasm-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +substrate-state-trie-migration-rpc = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Cumulus dependencies -cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +cumulus-client-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-collator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-consensus-proposer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-network = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-client-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-core = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-collator-selection = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +staging-parachain-info = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-emulator = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +parachains-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-runtime-apis = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } # Polkadot dependencies -pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } - -cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } -cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch" } +pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +pallet-xcm-benchmarks = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-parachain = { package = "polkadot-parachain-primitives", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-service = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm = { package = "staging-xcm", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +westend-runtime = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } + +cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } +cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "polkadot-stable2506-10-patch-hooks" } [patch."https://github.com/bifrost-io/open-runtime-module-library"] -orml-xcm-support = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } -orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506" } +orml-xcm-support = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } +orml-traits = { git = "https://github.com/galacticcouncil/open-runtime-module-library", branch = "polkadot-stable2506-patch-hooks" } -[patch."https://github.com/galacticcouncil/polkadot-sdk"] -pallet-balances = { path = "pallets/balances" } - -[patch."https://github.com/galacticcouncil/open-runtime-module-library"] -orml-tokens = { path = "pallets/tokens" } diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index 8b8438883..696476fb0 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -1,13 +1,13 @@ #![cfg(test)] use crate::polkadot_test_net::*; +use ethereum_types::{H160, U256}; use frame_support::assert_ok; use hydradx_runtime::evm::precompiles::erc20_mapping::HydraErc20Mapping; use hydradx_runtime::{Balances, Currencies, Runtime, RuntimeOrigin, Tokens}; use hydradx_traits::evm::Erc20Mapping; use orml_traits::MultiCurrency; use pallet_synthetic_logs::{h160_to_h256, Pending as SyntheticLogsPending, TRANSFER_TOPIC}; -use ethereum_types::{H160, U256}; use xcm_emulator::TestExt; fn buffered_logs() -> Vec<(pallet_synthetic_logs::Bucket, H160, ethereum::Log)> { @@ -108,7 +108,9 @@ fn orml_tokens_post_deposit_buffers_mint_log() { let entry = logs .iter() .find(|(_, emitter, log)| { - *emitter == asset_addr && log.topics.first() == Some(&TRANSFER_TOPIC) && log.topics[1] == h160_to_h256(H160::zero()) + *emitter == asset_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics[1] == h160_to_h256(H160::zero()) }) .expect("synth log for DAI mint"); @@ -164,7 +166,6 @@ fn orml_tokens_zero_amount_transfer_does_not_buffer() { } #[test] -#[ignore] fn balances_transfer_buffers_synth_log() { TestNet::reset(); Hydra::execute_with(|| { @@ -190,7 +191,6 @@ fn balances_transfer_buffers_synth_log() { } #[test] -#[ignore] fn balances_force_transfer_buffers_synth_log() { TestNet::reset(); Hydra::execute_with(|| { @@ -215,7 +215,6 @@ fn balances_force_transfer_buffers_synth_log() { } #[test] -#[ignore] fn currencies_transfer_native_buffers_synth_log() { TestNet::reset(); Hydra::execute_with(|| { @@ -236,18 +235,13 @@ fn currencies_transfer_native_buffers_synth_log() { } #[test] -#[ignore] fn balances_dust_loss_buffers_burn_log() { TestNet::reset(); Hydra::execute_with(|| { let hdx_ed = ::ExistentialDeposit::get(); assert!(hdx_ed > 0); - assert_ok!(Balances::force_set_balance( - RuntimeOrigin::root(), - ALICE.into(), - hdx_ed, - )); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), ALICE.into(), hdx_ed,)); SyntheticLogsPending::::kill(); assert_ok!(Balances::transfer_allow_death( RuntimeOrigin::signed(ALICE.into()), @@ -259,12 +253,14 @@ fn balances_dust_loss_buffers_burn_log() { let burn_to_zero = buffered_logs() .into_iter() .find(|(_, emitter, log)| *emitter == asset_addr && log.topics[2] == h160_to_h256(H160::zero())); - assert!(burn_to_zero.is_some(), "dust loss must buffer Transfer(from, 0x0, amount)"); + assert!( + burn_to_zero.is_some(), + "dust loss must buffer Transfer(from, 0x0, amount)" + ); }); } #[test] -#[ignore] fn currencies_withdraw_orml_buffers_burn_log() { TestNet::reset(); Hydra::execute_with(|| { @@ -282,6 +278,9 @@ fn currencies_withdraw_orml_buffers_burn_log() { let burn = buffered_logs() .into_iter() .find(|(_, emitter, log)| *emitter == asset_addr && log.topics[2] == h160_to_h256(H160::zero())); - assert!(burn.is_some(), "Currencies::withdraw must buffer Transfer(from, 0x0, amount)"); + assert!( + burn.is_some(), + "Currencies::withdraw must buffer Transfer(from, 0x0, amount)" + ); }); } diff --git a/pallets/balances/Cargo.toml b/pallets/balances/Cargo.toml deleted file mode 100644 index 6f407049f..000000000 --- a/pallets/balances/Cargo.toml +++ /dev/null @@ -1,57 +0,0 @@ -[package] -name = "pallet-balances" -version = "42.0.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://substrate.io" -repository = "https://github.com/galacticcouncil/hydration-node" -description = "FRAME pallet to manage balances" -readme = "README.md" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { features = ["derive", "max-encoded-len"], workspace = true } -docify = "0.2.8" -frame-benchmarking = { optional = true, workspace = true } -frame-support.workspace = true -frame-system.workspace = true -log = { workspace = true } -scale-info = { features = ["derive"], workspace = true } -sp-core.workspace = true -sp-runtime.workspace = true - -[dev-dependencies] -frame-support = { features = ["experimental"], default-features = true, workspace = true } -pallet-transaction-payment = { default-features = true, workspace = true } -paste = { workspace = true, default-features = true } -sp-io = { default-features = true, workspace = true } - -[features] -default = ["std"] -std = [ - "codec/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", - "log/std", - "scale-info/std", - "sp-core/std", - "sp-runtime/std", -] -insecure_zero_ed = [] -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] -try-runtime = [ - "frame-support/try-runtime", - "frame-system/try-runtime", - "pallet-transaction-payment/try-runtime", - "sp-runtime/try-runtime", -] diff --git a/pallets/balances/README.md b/pallets/balances/README.md deleted file mode 100644 index 1dc93a6bd..000000000 --- a/pallets/balances/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Balances Module - -The Balances module provides functionality for handling accounts and balances. - -- [`Config`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/trait.Config.html) -- [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/enum.Call.html) -- [`Pallet`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.Pallet.html) - -## Overview - -The Balances module provides functions for: - -- Getting and setting free balances. -- Retrieving total, reserved and unreserved balances. -- Repatriating a reserved balance to a beneficiary account that exists. -- Transferring a balance between accounts (when not reserved). -- Slashing an account balance. -- Account creation and removal. -- Managing total issuance. -- Setting and managing locks. - -### Terminology - -- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents "dust accounts" -from filling storage. When the free plus the reserved balance (i.e. the total balance) fall below this, then the account - is said to be dead; and it loses its functionality as well as any prior history and all information on it is removed - from the chain's state. No account should ever have a total balance that is strictly between 0 and the existential - deposit (exclusive). If this ever happens, it indicates either a bug in this module or an erroneous raw mutation of - storage. - -- **Total Issuance:** The total number of units in existence in a system. - -- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its total balance has -become zero (or, strictly speaking, less than the Existential Deposit). - -- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only balance that matters for - most operations. - -- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. Reserved balance can - still be slashed, but only after all the free balance has been slashed. - -- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting (i.e. a -difference between total issuance and account balances). Functions that result in an imbalance will return an object of -the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is simply dropped, it should -automatically maintain any book-keeping such as total issuance.) - -- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple locks -always operate over the same funds, so they "overlay" rather than "stack". - -### Implementations - -The Balances module provides implementations for the following traits. If these traits provide the functionality that -you need, then you can avoid coupling with the Balances module. - -- [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Currency.html): Functions for dealing -with a fungible assets system. -- [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): -Functions for dealing with assets that can be reserved from an account. -- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions -for dealing with accounts that allow liquidity restrictions. -- [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling -imbalances between total issuance in the system and account balances. Must be used when a function creates new funds -(e.g. a reward) or destroys some funds (e.g. a system fee). -- [`IsDeadAccount`](https://docs.rs/frame-support/latest/frame_support/traits/trait.IsDeadAccount.html): Determiner to -say whether a given account is unused. - -## Interface - -### Dispatchable Functions - -- `transfer` - Transfer some liquid free balance to another account. -- `force_set_balance` - Set the balances of a given account. The origin of this call must be root. - -## Usage - -The following examples show how to use the Balances module in your custom module. - -### Examples from the FRAME - -The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: - -```rust -use frame_support::traits::Currency; - -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; - -``` - -The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: - -```rust -use frame_support::traits::{WithdrawReasons, LockableCurrency}; -use sp_runtime::traits::Bounded; -pub trait Config: frame_system::Config { - type Currency: LockableCurrency>; -} - -fn update_ledger( - controller: &T::AccountId, - ledger: &StakingLedger -) { - T::Currency::set_lock( - STAKING_ID, - &ledger.stash, - ledger.total, - WithdrawReasons::all() - ); - // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. -} -``` - -## Genesis config - -The Balances module depends on the -[`GenesisConfig`](https://docs.rs/pallet-balances/latest/pallet_balances/pallet/struct.GenesisConfig.html). - -## Assumptions - -- Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. - -License: Apache-2.0 diff --git a/pallets/balances/src/benchmarking.rs b/pallets/balances/src/benchmarking.rs deleted file mode 100644 index d26660ac8..000000000 --- a/pallets/balances/src/benchmarking.rs +++ /dev/null @@ -1,368 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Balances pallet benchmarking. - -#![cfg(feature = "runtime-benchmarks")] - -use super::*; -use crate::Pallet as Balances; - -use frame_benchmarking::v2::*; -use frame_system::RawOrigin; -use sp_runtime::traits::Bounded; -use types::ExtraFlags; - -const SEED: u32 = 0; -// existential deposit multiplier -const ED_MULTIPLIER: u32 = 10; - -fn minimum_balance, I: 'static>() -> T::Balance { - if cfg!(feature = "insecure_zero_ed") { - 100u32.into() - } else { - T::ExistentialDeposit::get() - } -} - -#[instance_benchmarks] -mod benchmarks { - use super::*; - - // Benchmark `transfer` extrinsic with the worst possible conditions: - // * Transfer will kill the sender account. - // * Transfer will create the recipient account. - #[benchmark] - fn transfer_allow_death() { - let existential_deposit: T::Balance = minimum_balance::(); - let caller = whitelisted_caller(); - - // Give some multiple of the existential deposit - let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()).max(1u32.into()); - let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - - // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, - // and reap this user. - let recipient: T::AccountId = account("recipient", 0, SEED); - let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - let transfer_amount = - existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); - - if cfg!(feature = "insecure_zero_ed") { - assert_eq!(Balances::::free_balance(&caller), balance - transfer_amount); - } else { - assert_eq!(Balances::::free_balance(&caller), Zero::zero()); - } - - assert_eq!(Balances::::free_balance(&recipient), transfer_amount); - } - - // Benchmark `transfer` with the best possible condition: - // * Both accounts exist and will continue to exist. - #[benchmark(extra)] - fn transfer_best_case() { - let caller = whitelisted_caller(); - let recipient: T::AccountId = account("recipient", 0, SEED); - let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - - // Give the sender account max funds for transfer (their account will never reasonably be - // killed). - let _ = - as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); - - // Give the recipient account existential deposit (thus their account already exists). - let existential_deposit: T::Balance = minimum_balance::(); - let _ = - as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); - let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - - #[extrinsic_call] - transfer_allow_death(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); - - assert!(!Balances::::free_balance(&caller).is_zero()); - assert!(!Balances::::free_balance(&recipient).is_zero()); - } - - // Benchmark `transfer_keep_alive` with the worst possible condition: - // * The recipient account is created. - #[benchmark] - fn transfer_keep_alive() { - let caller = whitelisted_caller(); - let recipient: T::AccountId = account("recipient", 0, SEED); - let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - - // Give the sender account max funds, thus a transfer will not kill account. - let _ = - as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); - let existential_deposit: T::Balance = minimum_balance::(); - let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); - - assert!(!Balances::::free_balance(&caller).is_zero()); - assert_eq!(Balances::::free_balance(&recipient), transfer_amount); - } - - // Benchmark `force_set_balance` coming from ROOT account. This always creates an account. - #[benchmark] - fn force_set_balance_creating() { - let user: T::AccountId = account("user", 0, SEED); - let user_lookup = T::Lookup::unlookup(user.clone()); - - let existential_deposit: T::Balance = minimum_balance::(); - let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - - #[extrinsic_call] - force_set_balance(RawOrigin::Root, user_lookup, balance_amount); - - assert_eq!(Balances::::free_balance(&user), balance_amount); - } - - // Benchmark `force_set_balance` coming from ROOT account. This always kills an account. - #[benchmark] - fn force_set_balance_killing() { - let user: T::AccountId = account("user", 0, SEED); - let user_lookup = T::Lookup::unlookup(user.clone()); - - // Give the user some initial balance. - let existential_deposit: T::Balance = minimum_balance::(); - let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); - - #[extrinsic_call] - force_set_balance(RawOrigin::Root, user_lookup, Zero::zero()); - - assert!(Balances::::free_balance(&user).is_zero()); - } - - // Benchmark `force_transfer` extrinsic with the worst possible conditions: - // * Transfer will kill the sender account. - // * Transfer will create the recipient account. - #[benchmark] - fn force_transfer() { - let existential_deposit: T::Balance = minimum_balance::(); - let source: T::AccountId = account("source", 0, SEED); - let source_lookup = T::Lookup::unlookup(source.clone()); - - // Give some multiple of the existential deposit - let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - let _ = as Currency<_>>::make_free_balance_be(&source, balance); - - // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, - // and reap this user. - let recipient: T::AccountId = account("recipient", 0, SEED); - let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - let transfer_amount = - existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); - - #[extrinsic_call] - _(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount); - - if cfg!(feature = "insecure_zero_ed") { - assert_eq!(Balances::::free_balance(&source), balance - transfer_amount); - } else { - assert_eq!(Balances::::free_balance(&source), Zero::zero()); - } - - assert_eq!(Balances::::free_balance(&recipient), transfer_amount); - } - - // This benchmark performs the same operation as `transfer` in the worst case scenario, - // but additionally introduces many new users into the storage, increasing the the merkle - // trie and PoV size. - #[benchmark(extra)] - fn transfer_increasing_users(u: Linear<0, 1_000>) { - // 1_000 is not very much, but this upper bound can be controlled by the CLI. - let existential_deposit: T::Balance = minimum_balance::(); - let caller = whitelisted_caller(); - - // Give some multiple of the existential deposit - let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - - // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, - // and reap this user. - let recipient: T::AccountId = account("recipient", 0, SEED); - let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - let transfer_amount = - existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into(); - - // Create a bunch of users in storage. - for i in 0..u { - // The `account` function uses `blake2_256` to generate unique accounts, so these - // should be quite random and evenly distributed in the trie. - let new_user: T::AccountId = account("new_user", i, SEED); - let _ = as Currency<_>>::make_free_balance_be(&new_user, balance); - } - - #[extrinsic_call] - transfer_allow_death(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount); - - if cfg!(feature = "insecure_zero_ed") { - assert_eq!(Balances::::free_balance(&caller), balance - transfer_amount); - } else { - assert_eq!(Balances::::free_balance(&caller), Zero::zero()); - } - - assert_eq!(Balances::::free_balance(&recipient), transfer_amount); - } - - // Benchmark `transfer_all` with the worst possible condition: - // * The recipient account is created - // * The sender is killed - #[benchmark] - fn transfer_all() { - let caller = whitelisted_caller(); - let recipient: T::AccountId = account("recipient", 0, SEED); - let recipient_lookup = T::Lookup::unlookup(recipient.clone()); - - // Give some multiple of the existential deposit - let existential_deposit: T::Balance = minimum_balance::(); - let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone()), recipient_lookup, false); - - assert!(Balances::::free_balance(&caller).is_zero()); - assert_eq!(Balances::::free_balance(&recipient), balance); - } - - #[benchmark] - fn force_unreserve() -> Result<(), BenchmarkError> { - let user: T::AccountId = account("user", 0, SEED); - let user_lookup = T::Lookup::unlookup(user.clone()); - - // Give some multiple of the existential deposit - let ed = minimum_balance::(); - let balance = ed + ed; - let _ = as Currency<_>>::make_free_balance_be(&user, balance); - - // Reserve the balance - as ReservableCurrency<_>>::reserve(&user, ed)?; - assert_eq!(Balances::::reserved_balance(&user), ed); - assert_eq!(Balances::::free_balance(&user), ed); - - #[extrinsic_call] - _(RawOrigin::Root, user_lookup, balance); - - assert!(Balances::::reserved_balance(&user).is_zero()); - assert_eq!(Balances::::free_balance(&user), ed + ed); - - Ok(()) - } - - #[benchmark] - fn upgrade_accounts(u: Linear<1, 1_000>) { - let caller: T::AccountId = whitelisted_caller(); - let who = (0..u) - .into_iter() - .map(|i| -> T::AccountId { - let user = account("old_user", i, SEED); - let account = AccountData { - free: minimum_balance::(), - reserved: minimum_balance::(), - frozen: Zero::zero(), - flags: ExtraFlags::old_logic(), - }; - frame_system::Pallet::::inc_providers(&user); - assert!(T::AccountStore::try_mutate_exists(&user, |a| -> DispatchResult { - *a = Some(account); - Ok(()) - }) - .is_ok()); - assert!(!Balances::::account(&user).flags.is_new_logic()); - assert_eq!(frame_system::Pallet::::providers(&user), 1); - assert_eq!(frame_system::Pallet::::consumers(&user), 0); - user - }) - .collect(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone()), who); - - for i in 0..u { - let user: T::AccountId = account("old_user", i, SEED); - assert!(Balances::::account(&user).flags.is_new_logic()); - assert_eq!(frame_system::Pallet::::providers(&user), 1); - assert_eq!(frame_system::Pallet::::consumers(&user), 1); - } - } - - #[benchmark] - fn force_adjust_total_issuance() { - let ti = TotalIssuance::::get(); - let delta = 123u32.into(); - - #[extrinsic_call] - _(RawOrigin::Root, AdjustmentDirection::Increase, delta); - - assert_eq!(TotalIssuance::::get(), ti + delta); - } - - /// Benchmark `burn` extrinsic with the worst possible condition - burn kills the account. - #[benchmark] - fn burn_allow_death() { - let existential_deposit: T::Balance = minimum_balance::(); - let caller = whitelisted_caller(); - - // Give some multiple of the existential deposit - let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - - // Burn enough to kill the account. - let burn_amount = balance - existential_deposit + 1u32.into(); - - #[extrinsic_call] - burn(RawOrigin::Signed(caller.clone()), burn_amount, false); - - if cfg!(feature = "insecure_zero_ed") { - assert_eq!(Balances::::free_balance(&caller), balance - burn_amount); - } else { - assert_eq!(Balances::::free_balance(&caller), Zero::zero()); - } - } - - // Benchmark `burn` extrinsic with the case where account is kept alive. - #[benchmark] - fn burn_keep_alive() { - let existential_deposit: T::Balance = minimum_balance::(); - let caller = whitelisted_caller(); - - // Give some multiple of the existential deposit - let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - let _ = as Currency<_>>::make_free_balance_be(&caller, balance); - - // Burn minimum possible amount which should not kill the account. - let burn_amount = 1u32.into(); - - #[extrinsic_call] - burn(RawOrigin::Signed(caller.clone()), burn_amount, true); - - assert_eq!(Balances::::free_balance(&caller), balance - burn_amount); - } - - impl_benchmark_test_suite! { - Balances, - crate::tests::ExtBuilder::default().build(), - crate::tests::Test, - } -} diff --git a/pallets/balances/src/impl_currency.rs b/pallets/balances/src/impl_currency.rs deleted file mode 100644 index f453b2342..000000000 --- a/pallets/balances/src/impl_currency.rs +++ /dev/null @@ -1,954 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Implementations for the `Currency` family of traits. -//! -//! Note that `WithdrawReasons` are intentionally not used for anything in this implementation and -//! are expected to be removed in the near future, once migration to `fungible::*` traits is done. - -use super::*; -use frame_support::{ - ensure, - pallet_prelude::DispatchResult, - traits::{ - tokens::{fungible, BalanceStatus as Status, Fortitude::Polite, Precision::BestEffort}, - Currency, DefensiveSaturating, ExistenceRequirement, - ExistenceRequirement::AllowDeath, - Get, Imbalance, InspectLockableCurrency, LockIdentifier, LockableCurrency, - NamedReservableCurrency, ReservableCurrency, SignedImbalance, TryDrop, WithdrawReasons, - }, -}; -use frame_system::pallet_prelude::BlockNumberFor; -pub use imbalances::{NegativeImbalance, PositiveImbalance}; -use sp_runtime::traits::Bounded; - -// wrapping these imbalances in a private module is necessary to ensure absolute privacy -// of the inner member. -mod imbalances { - use super::*; - use core::mem; - use frame_support::traits::{tokens::imbalance::TryMerge, SameOrOther}; - - /// Opaque, move-only struct with private fields that serves as a token denoting that - /// funds have been created without any equal and opposite accounting. - #[must_use] - #[derive(RuntimeDebug, PartialEq, Eq)] - pub struct PositiveImbalance, I: 'static = ()>(T::Balance); - - impl, I: 'static> PositiveImbalance { - /// Create a new positive imbalance from a balance. - pub fn new(amount: T::Balance) -> Self { - PositiveImbalance(amount) - } - } - - /// Opaque, move-only struct with private fields that serves as a token denoting that - /// funds have been destroyed without any equal and opposite accounting. - #[must_use] - #[derive(RuntimeDebug, PartialEq, Eq)] - pub struct NegativeImbalance, I: 'static = ()>(T::Balance); - - impl, I: 'static> NegativeImbalance { - /// Create a new negative imbalance from a balance. - pub fn new(amount: T::Balance) -> Self { - NegativeImbalance(amount) - } - } - - impl, I: 'static> TryDrop for PositiveImbalance { - fn try_drop(self) -> result::Result<(), Self> { - self.drop_zero() - } - } - - impl, I: 'static> Default for PositiveImbalance { - fn default() -> Self { - Self::zero() - } - } - - impl, I: 'static> Imbalance for PositiveImbalance { - type Opposite = NegativeImbalance; - - fn zero() -> Self { - Self(Zero::zero()) - } - fn drop_zero(self) -> result::Result<(), Self> { - if self.0.is_zero() { - Ok(()) - } else { - Err(self) - } - } - fn split(self, amount: T::Balance) -> (Self, Self) { - let first = self.0.min(amount); - let second = self.0 - first; - - mem::forget(self); - (Self(first), Self(second)) - } - fn extract(&mut self, amount: T::Balance) -> Self { - let new = self.0.min(amount); - self.0 = self.0 - new; - Self(new) - } - fn merge(mut self, other: Self) -> Self { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - - self - } - fn subsume(&mut self, other: Self) { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - } - fn offset(self, other: Self::Opposite) -> SameOrOther { - let (a, b) = (self.0, other.0); - mem::forget((self, other)); - - if a > b { - SameOrOther::Same(Self(a - b)) - } else if b > a { - SameOrOther::Other(NegativeImbalance::new(b - a)) - } else { - SameOrOther::None - } - } - fn peek(&self) -> T::Balance { - self.0 - } - } - - impl, I: 'static> TryMerge for PositiveImbalance { - fn try_merge(self, other: Self) -> Result { - Ok(self.merge(other)) - } - } - - impl, I: 'static> TryDrop for NegativeImbalance { - fn try_drop(self) -> result::Result<(), Self> { - self.drop_zero() - } - } - - impl, I: 'static> Default for NegativeImbalance { - fn default() -> Self { - Self::zero() - } - } - - impl, I: 'static> Imbalance for NegativeImbalance { - type Opposite = PositiveImbalance; - - fn zero() -> Self { - Self(Zero::zero()) - } - fn drop_zero(self) -> result::Result<(), Self> { - if self.0.is_zero() { - Ok(()) - } else { - Err(self) - } - } - fn split(self, amount: T::Balance) -> (Self, Self) { - let first = self.0.min(amount); - let second = self.0 - first; - - mem::forget(self); - (Self(first), Self(second)) - } - fn extract(&mut self, amount: T::Balance) -> Self { - let new = self.0.min(amount); - self.0 = self.0 - new; - Self(new) - } - fn merge(mut self, other: Self) -> Self { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - - self - } - fn subsume(&mut self, other: Self) { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - } - fn offset(self, other: Self::Opposite) -> SameOrOther { - let (a, b) = (self.0, other.0); - mem::forget((self, other)); - - if a > b { - SameOrOther::Same(Self(a - b)) - } else if b > a { - SameOrOther::Other(PositiveImbalance::new(b - a)) - } else { - SameOrOther::None - } - } - fn peek(&self) -> T::Balance { - self.0 - } - } - - impl, I: 'static> TryMerge for NegativeImbalance { - fn try_merge(self, other: Self) -> Result { - Ok(self.merge(other)) - } - } - - impl, I: 'static> Drop for PositiveImbalance { - /// Basic drop handler will just square up the total issuance. - fn drop(&mut self) { - if !self.0.is_zero() { - >::mutate(|v| *v = v.saturating_add(self.0)); - Pallet::::deposit_event(Event::::Issued { amount: self.0 }); - } - } - } - - impl, I: 'static> Drop for NegativeImbalance { - /// Basic drop handler will just square up the total issuance. - fn drop(&mut self) { - if !self.0.is_zero() { - >::mutate(|v| *v = v.saturating_sub(self.0)); - Pallet::::deposit_event(Event::::Rescinded { amount: self.0 }); - } - } - } -} - -impl, I: 'static> Currency for Pallet -where - T::Balance: MaybeSerializeDeserialize + Debug, -{ - type Balance = T::Balance; - type PositiveImbalance = PositiveImbalance; - type NegativeImbalance = NegativeImbalance; - - fn total_balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).total() - } - - // Check if `value` amount of free balance can be slashed from `who`. - fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { - if value.is_zero() { - return true - } - Self::free_balance(who) >= value - } - - fn total_issuance() -> Self::Balance { - TotalIssuance::::get() - } - - fn active_issuance() -> Self::Balance { - >::active_issuance() - } - - fn deactivate(amount: Self::Balance) { - >::deactivate(amount); - } - - fn reactivate(amount: Self::Balance) { - >::reactivate(amount); - } - - fn minimum_balance() -> Self::Balance { - T::ExistentialDeposit::get() - } - - // Burn funds from the total issuance, returning a positive imbalance for the amount burned. - // Is a no-op if amount to be burned is zero. - fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { - if amount.is_zero() { - return PositiveImbalance::zero() - } - >::mutate(|issued| { - *issued = issued.checked_sub(&amount).unwrap_or_else(|| { - amount = *issued; - Zero::zero() - }); - }); - - Pallet::::deposit_event(Event::::Rescinded { amount }); - PositiveImbalance::new(amount) - } - - // Create new funds into the total issuance, returning a negative imbalance - // for the amount issued. - // Is a no-op if amount to be issued it zero. - fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { - if amount.is_zero() { - return NegativeImbalance::zero() - } - >::mutate(|issued| { - *issued = issued.checked_add(&amount).unwrap_or_else(|| { - amount = Self::Balance::max_value() - *issued; - Self::Balance::max_value() - }) - }); - - Pallet::::deposit_event(Event::::Issued { amount }); - NegativeImbalance::new(amount) - } - - fn free_balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).free - } - - // Ensure that an account can withdraw from their free balance given any existing withdrawal - // restrictions like locks and vesting balance. - // Is a no-op if amount to be withdrawn is zero. - fn ensure_can_withdraw( - who: &T::AccountId, - amount: T::Balance, - _reasons: WithdrawReasons, - new_balance: T::Balance, - ) -> DispatchResult { - if amount.is_zero() { - return Ok(()) - } - ensure!(new_balance >= Self::account(who).frozen, Error::::LiquidityRestrictions); - Ok(()) - } - - // Transfer some free balance from `transactor` to `dest`, respecting existence requirements. - // Is a no-op if value to be transferred is zero or the `transactor` is the same as `dest`. - fn transfer( - transactor: &T::AccountId, - dest: &T::AccountId, - value: Self::Balance, - existence_requirement: ExistenceRequirement, - ) -> DispatchResult { - if value.is_zero() || transactor == dest { - return Ok(()) - } - let keep_alive = match existence_requirement { - ExistenceRequirement::KeepAlive => Preserve, - ExistenceRequirement::AllowDeath => Expendable, - }; - >::transfer(transactor, dest, value, keep_alive)?; - Ok(()) - } - - /// Slash a target account `who`, returning the negative imbalance created and any left over - /// amount that could not be slashed. - /// - /// Is a no-op if `value` to be slashed is zero or the account does not exist. - /// - /// NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn - /// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid - /// having to draw from reserved funds, however we err on the side of punishment if things are - /// inconsistent or `can_slash` wasn't used appropriately. - fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { - if value.is_zero() { - return (NegativeImbalance::zero(), Zero::zero()) - } - if Self::total_balance(who).is_zero() { - return (NegativeImbalance::zero(), value) - } - - let result = match Self::try_mutate_account_handling_dust( - who, - |account, _is_new| -> Result<(Self::NegativeImbalance, Self::Balance), DispatchError> { - // Best value is the most amount we can slash following liveness rules. - let ed = T::ExistentialDeposit::get(); - let actual = match system::Pallet::::can_dec_provider(who) { - true => value.min(account.free), - false => value.min(account.free.saturating_sub(ed)), - }; - account.free.saturating_reduce(actual); - let remaining = value.saturating_sub(actual); - Ok((NegativeImbalance::new(actual), remaining)) - }, - ) { - Ok((imbalance, remaining)) => { - Self::deposit_event(Event::Slashed { - who: who.clone(), - amount: value.saturating_sub(remaining), - }); - (imbalance, remaining) - }, - Err(_) => (Self::NegativeImbalance::zero(), value), - }; - result - } - - /// Deposit some `value` into the free balance of an existing target account `who`. - /// - /// Is a no-op if the `value` to be deposited is zero. - fn deposit_into_existing( - who: &T::AccountId, - value: Self::Balance, - ) -> Result { - if value.is_zero() { - return Ok(PositiveImbalance::zero()) - } - - Self::try_mutate_account_handling_dust( - who, - |account, is_new| -> Result { - ensure!(!is_new, Error::::DeadAccount); - account.free = account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?; - Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); - Ok(PositiveImbalance::new(value)) - }, - ) - } - - /// Deposit some `value` into the free balance of `who`, possibly creating a new account. - /// - /// This function is a no-op if: - /// - the `value` to be deposited is zero; or - /// - the `value` to be deposited is less than the required ED and the account does not yet - /// exist; or - /// - the deposit would necessitate the account to exist and there are no provider references; - /// or - /// - `value` is so large it would cause the balance of `who` to overflow. - fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { - if value.is_zero() { - return Self::PositiveImbalance::zero() - } - - Self::try_mutate_account_handling_dust( - who, - |account, is_new| -> Result { - let ed = T::ExistentialDeposit::get(); - ensure!(value >= ed || !is_new, Error::::ExistentialDeposit); - - // defensive only: overflow should never happen, however in case it does, then this - // operation is a no-op. - account.free = match account.free.checked_add(&value) { - Some(x) => x, - None => return Ok(Self::PositiveImbalance::zero()), - }; - - Self::deposit_event(Event::Deposit { who: who.clone(), amount: value }); - Ok(PositiveImbalance::new(value)) - }, - ) - .unwrap_or_else(|_| Self::PositiveImbalance::zero()) - } - - /// Withdraw some free balance from an account, respecting existence requirements. - /// - /// Is a no-op if value to be withdrawn is zero. - fn withdraw( - who: &T::AccountId, - value: Self::Balance, - reasons: WithdrawReasons, - liveness: ExistenceRequirement, - ) -> result::Result { - if value.is_zero() { - return Ok(NegativeImbalance::zero()) - } - - Self::try_mutate_account_handling_dust( - who, - |account, _| -> Result { - let new_free_account = - account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; - - // bail if we need to keep the account alive and this would kill it. - let ed = T::ExistentialDeposit::get(); - let would_be_dead = new_free_account < ed; - let would_kill = would_be_dead && account.free >= ed; - ensure!(liveness == AllowDeath || !would_kill, Error::::Expendability); - - Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; - - account.free = new_free_account; - - Self::deposit_event(Event::Withdraw { who: who.clone(), amount: value }); - Ok(NegativeImbalance::new(value)) - }, - ) - } - - /// Force the new free balance of a target account `who` to some new value `balance`. - fn make_free_balance_be( - who: &T::AccountId, - value: Self::Balance, - ) -> SignedImbalance { - Self::try_mutate_account_handling_dust( - who, - |account, - is_new| - -> Result, DispatchError> { - let ed = T::ExistentialDeposit::get(); - // If we're attempting to set an existing account to less than ED, then - // bypass the entire operation. It's a no-op if you follow it through, but - // since this is an instance where we might account for a negative imbalance - // (in the dust cleaner of set_account) before we account for its actual - // equal and opposite cause (returned as an Imbalance), then in the - // instance that there's no other accounts on the system at all, we might - // underflow the issuance and our arithmetic will be off. - ensure!(value >= ed || !is_new, Error::::ExistentialDeposit); - - let imbalance = if account.free <= value { - SignedImbalance::Positive(PositiveImbalance::new(value - account.free)) - } else { - SignedImbalance::Negative(NegativeImbalance::new(account.free - value)) - }; - account.free = value; - Self::deposit_event(Event::BalanceSet { who: who.clone(), free: account.free }); - Ok(imbalance) - }, - ) - .unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero())) - } -} - -impl, I: 'static> ReservableCurrency for Pallet -where - T::Balance: MaybeSerializeDeserialize + Debug, -{ - /// Check if `who` can reserve `value` from their free balance. - /// - /// Always `true` if value to be reserved is zero. - fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { - if value.is_zero() { - return true - } - Self::account(who).free.checked_sub(&value).map_or(false, |new_balance| { - new_balance >= T::ExistentialDeposit::get() && - Self::ensure_can_withdraw(who, value, WithdrawReasons::RESERVE, new_balance) - .is_ok() - }) - } - - fn reserved_balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).reserved - } - - /// Move `value` from the free balance from `who` to their reserved balance. - /// - /// Is a no-op if value to be reserved is zero. - fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { - if value.is_zero() { - return Ok(()) - } - - Self::try_mutate_account_handling_dust(who, |account, _| -> DispatchResult { - account.free = - account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; - account.reserved = - account.reserved.checked_add(&value).ok_or(ArithmeticError::Overflow)?; - Self::ensure_can_withdraw(&who, value, WithdrawReasons::RESERVE, account.free) - })?; - - Self::deposit_event(Event::Reserved { who: who.clone(), amount: value }); - Ok(()) - } - - /// Unreserve some funds, returning any amount that was unable to be unreserved. - /// - /// Is a no-op if the value to be unreserved is zero or the account does not exist. - /// - /// NOTE: returns amount value which wasn't successfully unreserved. - fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { - if value.is_zero() { - return Zero::zero() - } - if Self::total_balance(who).is_zero() { - return value - } - - let actual = match Self::mutate_account_handling_dust(who, |account| { - let actual = cmp::min(account.reserved, value); - account.reserved -= actual; - // defensive only: this can never fail since total issuance which is at least - // free+reserved fits into the same data type. - account.free = account.free.defensive_saturating_add(actual); - actual - }) { - Ok(x) => x, - Err(_) => { - // This should never happen since we don't alter the total amount in the account. - // If it ever does, then we should fail gracefully though, indicating that nothing - // could be done. - return value - }, - }; - - Self::deposit_event(Event::Unreserved { who: who.clone(), amount: actual }); - value - actual - } - - /// Slash from reserved balance, returning the negative imbalance created, - /// and any amount that was unable to be slashed. - /// - /// Is a no-op if the value to be slashed is zero or the account does not exist. - fn slash_reserved( - who: &T::AccountId, - value: Self::Balance, - ) -> (Self::NegativeImbalance, Self::Balance) { - if value.is_zero() { - return (NegativeImbalance::zero(), Zero::zero()) - } - if Self::total_balance(who).is_zero() { - return (NegativeImbalance::zero(), value) - } - - // NOTE: `mutate_account` may fail if it attempts to reduce the balance to the point that an - // account is attempted to be illegally destroyed. - - match Self::mutate_account_handling_dust(who, |account| { - let actual = value.min(account.reserved); - account.reserved.saturating_reduce(actual); - - // underflow should never happen, but it if does, there's nothing to be done here. - (NegativeImbalance::new(actual), value.saturating_sub(actual)) - }) { - Ok((imbalance, not_slashed)) => { - Self::deposit_event(Event::Slashed { - who: who.clone(), - amount: value.saturating_sub(not_slashed), - }); - (imbalance, not_slashed) - }, - Err(_) => (Self::NegativeImbalance::zero(), value), - } - } - - /// Move the reserved balance of one account into the balance of another, according to `status`. - /// - /// Is a no-op if: - /// - the value to be moved is zero; or - /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. - /// - /// This is `Polite` and thus will not repatriate any funds which would lead the total balance - /// to be less than the frozen amount. Returns `Ok` with the actual amount of funds moved, - /// which may be less than `value` since the operation is done on a `BestEffort` basis. - fn repatriate_reserved( - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: Status, - ) -> Result { - let actual = - Self::do_transfer_reserved(slashed, beneficiary, value, BestEffort, Polite, status)?; - Ok(value.saturating_sub(actual)) - } -} - -impl, I: 'static> NamedReservableCurrency for Pallet -where - T::Balance: MaybeSerializeDeserialize + Debug, -{ - type ReserveIdentifier = T::ReserveIdentifier; - - fn reserved_balance_named(id: &Self::ReserveIdentifier, who: &T::AccountId) -> Self::Balance { - let reserves = Self::reserves(who); - reserves - .binary_search_by_key(id, |data| data.id) - .map(|index| reserves[index].amount) - .unwrap_or_default() - } - - /// Move `value` from the free balance from `who` to a named reserve balance. - /// - /// Is a no-op if value to be reserved is zero. - fn reserve_named( - id: &Self::ReserveIdentifier, - who: &T::AccountId, - value: Self::Balance, - ) -> DispatchResult { - if value.is_zero() { - return Ok(()) - } - - Reserves::::try_mutate(who, |reserves| -> DispatchResult { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - reserves[index].amount = reserves[index] - .amount - .checked_add(&value) - .ok_or(ArithmeticError::Overflow)?; - }, - Err(index) => { - reserves - .try_insert(index, ReserveData { id: *id, amount: value }) - .map_err(|_| Error::::TooManyReserves)?; - }, - }; - >::reserve(who, value)?; - Ok(()) - }) - } - - /// Unreserve some funds, returning any amount that was unable to be unreserved. - /// - /// Is a no-op if the value to be unreserved is zero. - fn unreserve_named( - id: &Self::ReserveIdentifier, - who: &T::AccountId, - value: Self::Balance, - ) -> Self::Balance { - if value.is_zero() { - return Zero::zero() - } - - Reserves::::mutate_exists(who, |maybe_reserves| -> Self::Balance { - if let Some(reserves) = maybe_reserves.as_mut() { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let remain = >::unreserve(who, to_change); - - // remain should always be zero but just to be defensive here. - let actual = to_change.defensive_saturating_sub(remain); - - // `actual <= to_change` and `to_change <= amount`; qed; - reserves[index].amount -= actual; - - if reserves[index].amount.is_zero() { - if reserves.len() == 1 { - // no more named reserves - *maybe_reserves = None; - } else { - // remove this named reserve - reserves.remove(index); - } - } - - value - actual - }, - Err(_) => value, - } - } else { - value - } - }) - } - - /// Slash from reserved balance, returning the negative imbalance created, - /// and any amount that was unable to be slashed. - /// - /// Is a no-op if the value to be slashed is zero. - fn slash_reserved_named( - id: &Self::ReserveIdentifier, - who: &T::AccountId, - value: Self::Balance, - ) -> (Self::NegativeImbalance, Self::Balance) { - if value.is_zero() { - return (NegativeImbalance::zero(), Zero::zero()) - } - - Reserves::::mutate(who, |reserves| -> (Self::NegativeImbalance, Self::Balance) { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let (imb, remain) = - >::slash_reserved(who, to_change); - - // remain should always be zero but just to be defensive here. - let actual = to_change.defensive_saturating_sub(remain); - - // `actual <= to_change` and `to_change <= amount`; qed; - reserves[index].amount -= actual; - - Self::deposit_event(Event::Slashed { who: who.clone(), amount: actual }); - (imb, value - actual) - }, - Err(_) => (NegativeImbalance::zero(), value), - } - }) - } - - /// Move the reserved balance of one account into the balance of another, according to `status`. - /// If `status` is `Reserved`, the balance will be reserved with given `id`. - /// - /// Is a no-op if: - /// - the value to be moved is zero; or - /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. - fn repatriate_reserved_named( - id: &Self::ReserveIdentifier, - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: Status, - ) -> Result { - if value.is_zero() { - return Ok(Zero::zero()) - } - - if slashed == beneficiary { - return match status { - Status::Free => Ok(Self::unreserve_named(id, slashed, value)), - Status::Reserved => - Ok(value.saturating_sub(Self::reserved_balance_named(id, slashed))), - } - } - - Reserves::::try_mutate(slashed, |reserves| -> Result { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let actual = if status == Status::Reserved { - // make it the reserved under same identifier - Reserves::::try_mutate( - beneficiary, - |reserves| -> Result { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let remain = - >::repatriate_reserved( - slashed, - beneficiary, - to_change, - status, - )?; - - // remain should always be zero but just to be defensive - // here. - let actual = to_change.defensive_saturating_sub(remain); - - // this add can't overflow but just to be defensive. - reserves[index].amount = - reserves[index].amount.defensive_saturating_add(actual); - - Ok(actual) - }, - Err(index) => { - let remain = - >::repatriate_reserved( - slashed, - beneficiary, - to_change, - status, - )?; - - // remain should always be zero but just to be defensive - // here - let actual = to_change.defensive_saturating_sub(remain); - - reserves - .try_insert( - index, - ReserveData { id: *id, amount: actual }, - ) - .map_err(|_| Error::::TooManyReserves)?; - - Ok(actual) - }, - } - }, - )? - } else { - let remain = >::repatriate_reserved( - slashed, - beneficiary, - to_change, - status, - )?; - - // remain should always be zero but just to be defensive here - to_change.defensive_saturating_sub(remain) - }; - - // `actual <= to_change` and `to_change <= amount`; qed; - reserves[index].amount -= actual; - - Ok(value - actual) - }, - Err(_) => Ok(value), - } - }) - } -} - -impl, I: 'static> LockableCurrency for Pallet -where - T::Balance: MaybeSerializeDeserialize + Debug, -{ - type Moment = BlockNumberFor; - - type MaxLocks = T::MaxLocks; - - // Set or alter a lock on the balance of `who`. - fn set_lock( - id: LockIdentifier, - who: &T::AccountId, - amount: T::Balance, - reasons: WithdrawReasons, - ) { - if reasons.is_empty() || amount.is_zero() { - Self::remove_lock(id, who); - return - } - - let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); - let mut locks = Self::locks(who) - .into_iter() - .filter_map(|l| if l.id == id { new_lock.take() } else { Some(l) }) - .collect::>(); - if let Some(lock) = new_lock { - locks.push(lock) - } - Self::update_locks(who, &locks[..]); - } - - // Extend a lock on the balance of `who`. - // Is a no-op if lock amount is zero or `reasons` `is_none()`. - fn extend_lock( - id: LockIdentifier, - who: &T::AccountId, - amount: T::Balance, - reasons: WithdrawReasons, - ) { - if amount.is_zero() || reasons.is_empty() { - return - } - let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); - let mut locks = Self::locks(who) - .into_iter() - .filter_map(|l| { - if l.id == id { - new_lock.take().map(|nl| BalanceLock { - id: l.id, - amount: l.amount.max(nl.amount), - reasons: l.reasons | nl.reasons, - }) - } else { - Some(l) - } - }) - .collect::>(); - if let Some(lock) = new_lock { - locks.push(lock) - } - Self::update_locks(who, &locks[..]); - } - - fn remove_lock(id: LockIdentifier, who: &T::AccountId) { - let mut locks = Self::locks(who); - locks.retain(|l| l.id != id); - Self::update_locks(who, &locks[..]); - } -} - -impl, I: 'static> InspectLockableCurrency for Pallet { - fn balance_locked(id: LockIdentifier, who: &T::AccountId) -> Self::Balance { - Self::locks(who) - .into_iter() - .filter(|l| l.id == id) - .fold(Zero::zero(), |acc, l| acc + l.amount) - } -} diff --git a/pallets/balances/src/impl_fungible.rs b/pallets/balances/src/impl_fungible.rs deleted file mode 100644 index 4470c3cc9..000000000 --- a/pallets/balances/src/impl_fungible.rs +++ /dev/null @@ -1,387 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Implementation of `fungible` traits for Balances pallet. -use super::*; -use frame_support::traits::{ - tokens::{ - Fortitude, - Preservation::{self, Preserve, Protect}, - Provenance::{self, Minted}, - }, - AccountTouch, -}; - -impl, I: 'static> fungible::Inspect for Pallet { - type Balance = T::Balance; - - fn total_issuance() -> Self::Balance { - TotalIssuance::::get() - } - fn active_issuance() -> Self::Balance { - TotalIssuance::::get().saturating_sub(InactiveIssuance::::get()) - } - fn minimum_balance() -> Self::Balance { - T::ExistentialDeposit::get() - } - fn total_balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).total() - } - fn balance(who: &T::AccountId) -> Self::Balance { - Self::account(who).free - } - fn reducible_balance( - who: &T::AccountId, - preservation: Preservation, - force: Fortitude, - ) -> Self::Balance { - let a = Self::account(who); - let mut untouchable = Zero::zero(); - if force == Polite { - // Frozen balance applies to total. Anything on hold therefore gets discounted from the - // limit given by the freezes. - untouchable = a.frozen.saturating_sub(a.reserved); - } - // If we want to keep our provider ref.. - if preservation == Preserve - // ..or we don't want the account to die and our provider ref is needed for it to live.. - || preservation == Protect && !a.free.is_zero() && - frame_system::Pallet::::providers(who) == 1 - // ..or we don't care about the account dying but our provider ref is required.. - || preservation == Expendable && !a.free.is_zero() && - !frame_system::Pallet::::can_dec_provider(who) - { - // ..then the ED needed.. - untouchable = untouchable.max(T::ExistentialDeposit::get()); - } - // Liquid balance is what is neither on hold nor frozen/required for provider. - a.free.saturating_sub(untouchable) - } - fn can_deposit( - who: &T::AccountId, - amount: Self::Balance, - provenance: Provenance, - ) -> DepositConsequence { - if amount.is_zero() { - return DepositConsequence::Success - } - - if provenance == Minted && TotalIssuance::::get().checked_add(&amount).is_none() { - return DepositConsequence::Overflow - } - - let account = Self::account(who); - let new_free = match account.free.checked_add(&amount) { - None => return DepositConsequence::Overflow, - Some(x) if x < T::ExistentialDeposit::get() => return DepositConsequence::BelowMinimum, - Some(x) => x, - }; - - match account.reserved.checked_add(&new_free) { - Some(_) => {}, - None => return DepositConsequence::Overflow, - }; - - // NOTE: We assume that we are a provider, so don't need to do any checks in the - // case of account creation. - - DepositConsequence::Success - } - fn can_withdraw( - who: &T::AccountId, - amount: Self::Balance, - ) -> WithdrawConsequence { - if amount.is_zero() { - return WithdrawConsequence::Success - } - - if TotalIssuance::::get().checked_sub(&amount).is_none() { - return WithdrawConsequence::Underflow - } - - let account = Self::account(who); - let new_free_balance = match account.free.checked_sub(&amount) { - Some(x) => x, - None => return WithdrawConsequence::BalanceLow, - }; - - let liquid = Self::reducible_balance(who, Expendable, Polite); - if amount > liquid { - return WithdrawConsequence::Frozen - } - - // Provider restriction - total account balance cannot be reduced to zero if it cannot - // sustain the loss of a provider reference. - // NOTE: This assumes that the pallet is a provider (which is true). Is this ever changes, - // then this will need to adapt accordingly. - let ed = T::ExistentialDeposit::get(); - let success = if new_free_balance < ed { - if frame_system::Pallet::::can_dec_provider(who) { - WithdrawConsequence::ReducedToZero(new_free_balance) - } else { - return WithdrawConsequence::WouldDie - } - } else { - WithdrawConsequence::Success - }; - - let new_total_balance = new_free_balance.saturating_add(account.reserved); - - // Eventual free funds must be no less than the frozen balance. - if new_total_balance < account.frozen { - return WithdrawConsequence::Frozen - } - - success - } -} - -impl, I: 'static> fungible::Unbalanced for Pallet { - fn handle_dust(dust: fungible::Dust) { - T::DustRemoval::on_unbalanced(dust.into_credit()); - } - fn write_balance( - who: &T::AccountId, - amount: Self::Balance, - ) -> Result, DispatchError> { - let max_reduction = - >::reducible_balance(who, Expendable, Force); - let (result, maybe_dust) = Self::mutate_account(who, |account| -> DispatchResult { - // Make sure the reduction (if there is one) is no more than the maximum allowed. - let reduction = account.free.saturating_sub(amount); - ensure!(reduction <= max_reduction, Error::::InsufficientBalance); - - account.free = amount; - Ok(()) - })?; - result?; - Ok(maybe_dust) - } - - fn set_total_issuance(amount: Self::Balance) { - TotalIssuance::::mutate(|t| *t = amount); - } - - fn deactivate(amount: Self::Balance) { - InactiveIssuance::::mutate(|b| { - // InactiveIssuance cannot be greater than TotalIssuance. - *b = b.saturating_add(amount).min(TotalIssuance::::get()); - }); - } - - fn reactivate(amount: Self::Balance) { - InactiveIssuance::::mutate(|b| b.saturating_reduce(amount)); - } -} - -impl, I: 'static> fungible::Mutate for Pallet { - fn done_mint_into(who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::::Minted { who: who.clone(), amount }); - } - fn done_burn_from(who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::::Burned { who: who.clone(), amount }); - } - fn done_shelve(who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::::Suspended { who: who.clone(), amount }); - } - fn done_restore(who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::::Restored { who: who.clone(), amount }); - } - fn done_transfer(source: &T::AccountId, dest: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::::Transfer { - from: source.clone(), - to: dest.clone(), - amount, - }); - } -} - -impl, I: 'static> fungible::MutateHold for Pallet {} - -impl, I: 'static> fungible::InspectHold for Pallet { - type Reason = T::RuntimeHoldReason; - - fn total_balance_on_hold(who: &T::AccountId) -> T::Balance { - Self::account(who).reserved - } - fn reducible_total_balance_on_hold(who: &T::AccountId, force: Fortitude) -> Self::Balance { - // The total balance must never drop below the freeze requirements if we're not forcing: - let a = Self::account(who); - let unavailable = if force == Force { - Self::Balance::zero() - } else { - // The freeze lock applies to the total balance, so we can discount the free balance - // from the amount which the total reserved balance must provide to satisfy it. - a.frozen.saturating_sub(a.free) - }; - a.reserved.saturating_sub(unavailable) - } - fn balance_on_hold(reason: &Self::Reason, who: &T::AccountId) -> T::Balance { - Holds::::get(who) - .iter() - .find(|x| &x.id == reason) - .map_or_else(Zero::zero, |x| x.amount) - } - fn hold_available(reason: &Self::Reason, who: &T::AccountId) -> bool { - if frame_system::Pallet::::providers(who) == 0 { - return false - } - let holds = Holds::::get(who); - if holds.is_full() && !holds.iter().any(|x| &x.id == reason) { - return false - } - true - } -} - -impl, I: 'static> fungible::UnbalancedHold for Pallet { - fn set_balance_on_hold( - reason: &Self::Reason, - who: &T::AccountId, - amount: Self::Balance, - ) -> DispatchResult { - let mut new_account = Self::account(who); - let mut holds = Holds::::get(who); - let mut increase = true; - let mut delta = amount; - - if let Some(item) = holds.iter_mut().find(|x| &x.id == reason) { - delta = item.amount.max(amount) - item.amount.min(amount); - increase = amount > item.amount; - item.amount = amount; - holds.retain(|x| !x.amount.is_zero()); - } else { - if !amount.is_zero() { - holds - .try_push(IdAmount { id: *reason, amount }) - .map_err(|_| Error::::TooManyHolds)?; - } - } - - new_account.reserved = if increase { - new_account.reserved.checked_add(&delta).ok_or(ArithmeticError::Overflow)? - } else { - new_account.reserved.checked_sub(&delta).ok_or(ArithmeticError::Underflow)? - }; - - let (result, maybe_dust) = Self::try_mutate_account(who, |a, _| -> DispatchResult { - *a = new_account; - Ok(()) - })?; - debug_assert!( - maybe_dust.is_none(), - "Does not alter main balance; dust only happens when it is altered; qed" - ); - Holds::::insert(who, holds); - Ok(result) - } -} - -impl, I: 'static> fungible::InspectFreeze for Pallet { - type Id = T::FreezeIdentifier; - - fn balance_frozen(id: &Self::Id, who: &T::AccountId) -> Self::Balance { - let locks = Freezes::::get(who); - locks.into_iter().find(|l| &l.id == id).map_or(Zero::zero(), |l| l.amount) - } - - fn can_freeze(id: &Self::Id, who: &T::AccountId) -> bool { - let l = Freezes::::get(who); - !l.is_full() || l.iter().any(|x| &x.id == id) - } -} - -impl, I: 'static> fungible::MutateFreeze for Pallet { - fn set_freeze(id: &Self::Id, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - if amount.is_zero() { - return Self::thaw(id, who) - } - let mut locks = Freezes::::get(who); - if let Some(i) = locks.iter_mut().find(|x| &x.id == id) { - i.amount = amount; - } else { - locks - .try_push(IdAmount { id: *id, amount }) - .map_err(|_| Error::::TooManyFreezes)?; - } - Self::update_freezes(who, locks.as_bounded_slice()) - } - - fn extend_freeze(id: &Self::Id, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - if amount.is_zero() { - return Ok(()) - } - let mut locks = Freezes::::get(who); - if let Some(i) = locks.iter_mut().find(|x| &x.id == id) { - i.amount = i.amount.max(amount); - } else { - locks - .try_push(IdAmount { id: *id, amount }) - .map_err(|_| Error::::TooManyFreezes)?; - } - Self::update_freezes(who, locks.as_bounded_slice()) - } - - fn thaw(id: &Self::Id, who: &T::AccountId) -> DispatchResult { - let mut locks = Freezes::::get(who); - locks.retain(|l| &l.id != id); - Self::update_freezes(who, locks.as_bounded_slice()) - } -} - -impl, I: 'static> fungible::Balanced for Pallet { - type OnDropCredit = fungible::DecreaseIssuance; - type OnDropDebt = fungible::IncreaseIssuance; - - fn done_deposit(who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::::Deposit { who: who.clone(), amount }); - } - fn done_withdraw(who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::::Withdraw { who: who.clone(), amount }); - } - fn done_issue(amount: Self::Balance) { - if !amount.is_zero() { - Self::deposit_event(Event::::Issued { amount }); - } - } - fn done_rescind(amount: Self::Balance) { - Self::deposit_event(Event::::Rescinded { amount }); - } -} - -impl, I: 'static> fungible::BalancedHold for Pallet {} - -impl, I: 'static> - fungible::hold::DoneSlash for Pallet -{ - fn done_slash(reason: &T::RuntimeHoldReason, who: &T::AccountId, amount: T::Balance) { - T::DoneSlashHandler::done_slash(reason, who, amount); - } -} - -impl, I: 'static> AccountTouch<(), T::AccountId> for Pallet { - type Balance = T::Balance; - fn deposit_required(_: ()) -> Self::Balance { - Self::Balance::zero() - } - fn should_touch(_: (), _: &T::AccountId) -> bool { - false - } - fn touch(_: (), _: &T::AccountId, _: &T::AccountId) -> DispatchResult { - Ok(()) - } -} diff --git a/pallets/balances/src/lib.rs b/pallets/balances/src/lib.rs deleted file mode 100644 index 7c558bf6a..000000000 --- a/pallets/balances/src/lib.rs +++ /dev/null @@ -1,1315 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! # Balances Pallet -//! -//! The Balances pallet provides functionality for handling accounts and balances for a single -//! token. -//! -//! It makes heavy use of concepts such as Holds and Freezes from the -//! [`frame_support::traits::fungible`] traits, therefore you should read and understand those docs -//! as a prerequisite to understanding this pallet. -//! -//! Also see the [`frame_tokens`] reference docs for higher level information regarding the -//! place of this palet in FRAME. -//! -//! ## Overview -//! -//! The Balances pallet provides functions for: -//! -//! - Getting and setting free balances. -//! - Retrieving total, reserved and unreserved balances. -//! - Repatriating a reserved balance to a beneficiary account that exists. -//! - Transferring a balance between accounts (when not reserved). -//! - Slashing an account balance. -//! - Account creation and removal. -//! - Managing total issuance. -//! - Setting and managing locks. -//! -//! ### Terminology -//! -//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after -//! its total balance has become less than the Existential Deposit. -//! -//! ### Implementations -//! -//! The Balances pallet provides implementations for the following [`fungible`] traits. If these -//! traits provide the functionality that you need, then you should avoid tight coupling with the -//! Balances pallet. -//! -//! - [`fungible::Inspect`] -//! - [`fungible::Mutate`] -//! - [`fungible::Unbalanced`] -//! - [`fungible::Balanced`] -//! - [`fungible::BalancedHold`] -//! - [`fungible::InspectHold`] -//! - [`fungible::MutateHold`] -//! - [`fungible::InspectFreeze`] -//! - [`fungible::MutateFreeze`] -//! - [`fungible::Imbalance`] -//! -//! It also implements the following [`Currency`] related traits, however they are deprecated and -//! will eventually be removed. -//! -//! - [`Currency`]: Functions for dealing with a fungible assets system. -//! - [`ReservableCurrency`] -//! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency): -//! Functions for dealing with assets that can be reserved from an account. -//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for -//! dealing with accounts that allow liquidity restrictions. -//! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling -//! imbalances between total issuance in the system and account balances. Must be used when a -//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). -//! -//! ## Usage -//! -//! The following examples show how to use the Balances pallet in your custom pallet. -//! -//! ### Examples from the FRAME -//! -//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from -//! `Currency`: -//! -//! ``` -//! use frame_support::traits::Currency; -//! # pub trait Config: frame_system::Config { -//! # type Currency: Currency; -//! # } -//! -//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -//! -//! # fn main() {} -//! ``` -//! -//! The Staking pallet uses the `LockableCurrency` trait to lock a stash account's funds: -//! -//! ``` -//! use frame_support::traits::{WithdrawReasons, LockableCurrency}; -//! use sp_runtime::traits::Bounded; -//! pub trait Config: frame_system::Config { -//! type Currency: LockableCurrency>; -//! } -//! # struct StakingLedger { -//! # stash: ::AccountId, -//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, -//! # phantom: std::marker::PhantomData, -//! # } -//! # const STAKING_ID: [u8; 8] = *b"staking "; -//! -//! fn update_ledger( -//! controller: &T::AccountId, -//! ledger: &StakingLedger -//! ) { -//! T::Currency::set_lock( -//! STAKING_ID, -//! &ledger.stash, -//! ledger.total, -//! WithdrawReasons::all() -//! ); -//! // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. -//! } -//! # fn main() {} -//! ``` -//! -//! ## Genesis config -//! -//! The Balances pallet depends on the [`GenesisConfig`]. -//! -//! ## Assumptions -//! -//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. -//! * Existential Deposit is set to a value greater than zero. -//! -//! Note, you may find the Balances pallet still functions with an ED of zero when the -//! `insecure_zero_ed` cargo feature is enabled. However this is not a configuration which is -//! generally supported, nor will it be. -//! -//! [`frame_tokens`]: ../polkadot_sdk_docs/reference_docs/frame_tokens/index.html - -#![cfg_attr(not(feature = "std"), no_std)] -mod benchmarking; -mod impl_currency; -mod impl_fungible; -pub mod migration; -mod tests; -mod types; -pub mod weights; - -extern crate alloc; - -use alloc::{ - format, - string::{String, ToString}, - vec::Vec, -}; -use codec::{Codec, MaxEncodedLen}; -use core::{cmp, fmt::Debug, mem, result}; -use frame_support::{ - ensure, - pallet_prelude::DispatchResult, - traits::{ - tokens::{ - fungible, BalanceStatus as Status, DepositConsequence, - Fortitude::{self, Force, Polite}, - IdAmount, - Preservation::{Expendable, Preserve, Protect}, - WithdrawConsequence, - }, - Currency, Defensive, Get, OnUnbalanced, ReservableCurrency, StoredMap, - }, - BoundedSlice, WeakBoundedVec, -}; -use frame_system as system; -pub use impl_currency::{NegativeImbalance, PositiveImbalance}; -use scale_info::TypeInfo; -use sp_core::{sr25519::Pair as SrPair, Pair}; -use sp_runtime::{ - traits::{ - AtLeast32BitUnsigned, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Saturating, - StaticLookup, Zero, - }, - ArithmeticError, DispatchError, FixedPointOperand, Perbill, RuntimeDebug, TokenError, -}; - -pub use types::{ - AccountData, AdjustmentDirection, BalanceLock, DustCleaner, ExtraFlags, Reasons, ReserveData, -}; -pub use weights::WeightInfo; - -pub use pallet::*; - -const LOG_TARGET: &str = "runtime::balances"; - -// Default derivation(hard) for development accounts. -const DEFAULT_ADDRESS_URI: &str = "//Sender//{}"; - -type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; - -#[frame_support::pallet] -pub mod pallet { - use super::*; - use codec::HasCompact; - use frame_support::{ - pallet_prelude::*, - traits::{fungible::Credit, tokens::Precision, VariantCount, VariantCountOf}, - }; - use frame_system::pallet_prelude::*; - - pub type CreditOf = Credit<::AccountId, Pallet>; - - /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. - pub mod config_preludes { - use super::*; - use frame_support::derive_impl; - - pub struct TestDefaultConfig; - - #[derive_impl(frame_system::config_preludes::TestDefaultConfig, no_aggregated_types)] - impl frame_system::DefaultConfig for TestDefaultConfig {} - - #[frame_support::register_default_impl(TestDefaultConfig)] - impl DefaultConfig for TestDefaultConfig { - #[inject_runtime_type] - type RuntimeEvent = (); - #[inject_runtime_type] - type RuntimeHoldReason = (); - #[inject_runtime_type] - type RuntimeFreezeReason = (); - - type Balance = u64; - type ExistentialDeposit = ConstUint<1>; - - type ReserveIdentifier = (); - type FreezeIdentifier = Self::RuntimeFreezeReason; - - type DustRemoval = (); - - type MaxLocks = ConstU32<100>; - type MaxReserves = ConstU32<100>; - type MaxFreezes = VariantCountOf; - - type WeightInfo = (); - type DoneSlashHandler = (); - } - } - - #[pallet::config(with_default)] - pub trait Config: frame_system::Config { - /// The overarching event type. - #[pallet::no_default_bounds] - #[allow(deprecated)] - type RuntimeEvent: From> - + IsType<::RuntimeEvent>; - - /// The overarching hold reason. - #[pallet::no_default_bounds] - type RuntimeHoldReason: Parameter + Member + MaxEncodedLen + Copy + VariantCount; - - /// The overarching freeze reason. - #[pallet::no_default_bounds] - type RuntimeFreezeReason: VariantCount; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; - - /// The balance of an account. - type Balance: Parameter - + Member - + AtLeast32BitUnsigned - + Codec - + HasCompact - + Default - + Copy - + MaybeSerializeDeserialize - + Debug - + MaxEncodedLen - + TypeInfo - + FixedPointOperand; - - /// Handler for the unbalanced reduction when removing a dust account. - #[pallet::no_default_bounds] - type DustRemoval: OnUnbalanced>; - - /// The minimum amount required to keep an account open. MUST BE GREATER THAN ZERO! - /// - /// If you *really* need it to be zero, you can enable the feature `insecure_zero_ed` for - /// this pallet. However, you do so at your own risk: this will open up a major DoS vector. - /// In case you have multiple sources of provider references, you may also get unexpected - /// behaviour if you set this to zero. - /// - /// Bottom line: Do yourself a favour and make it at least one! - #[pallet::constant] - #[pallet::no_default_bounds] - type ExistentialDeposit: Get; - - /// The means of storing the balances of an account. - #[pallet::no_default] - type AccountStore: StoredMap>; - - /// The ID type for reserves. - /// - /// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/` - type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; - - /// The ID type for freezes. - type FreezeIdentifier: Parameter + Member + MaxEncodedLen + Copy; - - /// The maximum number of locks that should exist on an account. - /// Not strictly enforced, but used for weight estimation. - /// - /// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/` - #[pallet::constant] - type MaxLocks: Get; - - /// The maximum number of named reserves that can exist on an account. - /// - /// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/` - #[pallet::constant] - type MaxReserves: Get; - - /// The maximum number of individual freeze locks that can exist on an account at any time. - #[pallet::constant] - type MaxFreezes: Get; - - /// Allows callbacks to other pallets so they can update their bookkeeping when a slash - /// occurs. - type DoneSlashHandler: fungible::hold::DoneSlash< - Self::RuntimeHoldReason, - Self::AccountId, - Self::Balance, - >; - } - - /// The in-code storage version. - const STORAGE_VERSION: frame_support::traits::StorageVersion = - frame_support::traits::StorageVersion::new(1); - - #[pallet::pallet] - #[pallet::storage_version(STORAGE_VERSION)] - pub struct Pallet(PhantomData<(T, I)>); - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event, I: 'static = ()> { - /// An account was created with some free balance. - Endowed { account: T::AccountId, free_balance: T::Balance }, - /// An account was removed whose balance was non-zero but below ExistentialDeposit, - /// resulting in an outright loss. - DustLost { account: T::AccountId, amount: T::Balance }, - /// Transfer succeeded. - Transfer { from: T::AccountId, to: T::AccountId, amount: T::Balance }, - /// A balance was set by root. - BalanceSet { who: T::AccountId, free: T::Balance }, - /// Some balance was reserved (moved from free to reserved). - Reserved { who: T::AccountId, amount: T::Balance }, - /// Some balance was unreserved (moved from reserved to free). - Unreserved { who: T::AccountId, amount: T::Balance }, - /// Some balance was moved from the reserve of the first account to the second account. - /// Final argument indicates the destination balance type. - ReserveRepatriated { - from: T::AccountId, - to: T::AccountId, - amount: T::Balance, - destination_status: Status, - }, - /// Some amount was deposited (e.g. for transaction fees). - Deposit { who: T::AccountId, amount: T::Balance }, - /// Some amount was withdrawn from the account (e.g. for transaction fees). - Withdraw { who: T::AccountId, amount: T::Balance }, - /// Some amount was removed from the account (e.g. for misbehavior). - Slashed { who: T::AccountId, amount: T::Balance }, - /// Some amount was minted into an account. - Minted { who: T::AccountId, amount: T::Balance }, - /// Some amount was burned from an account. - Burned { who: T::AccountId, amount: T::Balance }, - /// Some amount was suspended from an account (it can be restored later). - Suspended { who: T::AccountId, amount: T::Balance }, - /// Some amount was restored into an account. - Restored { who: T::AccountId, amount: T::Balance }, - /// An account was upgraded. - Upgraded { who: T::AccountId }, - /// Total issuance was increased by `amount`, creating a credit to be balanced. - Issued { amount: T::Balance }, - /// Total issuance was decreased by `amount`, creating a debt to be balanced. - Rescinded { amount: T::Balance }, - /// Some balance was locked. - Locked { who: T::AccountId, amount: T::Balance }, - /// Some balance was unlocked. - Unlocked { who: T::AccountId, amount: T::Balance }, - /// Some balance was frozen. - Frozen { who: T::AccountId, amount: T::Balance }, - /// Some balance was thawed. - Thawed { who: T::AccountId, amount: T::Balance }, - /// The `TotalIssuance` was forcefully changed. - TotalIssuanceForced { old: T::Balance, new: T::Balance }, - } - - #[pallet::error] - pub enum Error { - /// Vesting balance too high to send value. - VestingBalance, - /// Account liquidity restrictions prevent withdrawal. - LiquidityRestrictions, - /// Balance too low to send value. - InsufficientBalance, - /// Value too low to create account due to existential deposit. - ExistentialDeposit, - /// Transfer/payment would kill account. - Expendability, - /// A vesting schedule already exists for this account. - ExistingVestingSchedule, - /// Beneficiary account must pre-exist. - DeadAccount, - /// Number of named reserves exceed `MaxReserves`. - TooManyReserves, - /// Number of holds exceed `VariantCountOf`. - TooManyHolds, - /// Number of freezes exceed `MaxFreezes`. - TooManyFreezes, - /// The issuance cannot be modified since it is already deactivated. - IssuanceDeactivated, - /// The delta cannot be zero. - DeltaZero, - } - - /// The total units issued in the system. - #[pallet::storage] - #[pallet::whitelist_storage] - pub type TotalIssuance, I: 'static = ()> = StorageValue<_, T::Balance, ValueQuery>; - - /// The total units of outstanding deactivated balance in the system. - #[pallet::storage] - #[pallet::whitelist_storage] - pub type InactiveIssuance, I: 'static = ()> = - StorageValue<_, T::Balance, ValueQuery>; - - /// The Balances pallet example of storing the balance of an account. - /// - /// # Example - /// - /// ```nocompile - /// impl pallet_balances::Config for Runtime { - /// type AccountStore = StorageMapShim, frame_system::Provider, AccountId, Self::AccountData> - /// } - /// ``` - /// - /// You can also store the balance of an account in the `System` pallet. - /// - /// # Example - /// - /// ```nocompile - /// impl pallet_balances::Config for Runtime { - /// type AccountStore = System - /// } - /// ``` - /// - /// But this comes with tradeoffs, storing account balances in the system pallet stores - /// `frame_system` data alongside the account data contrary to storing account balances in the - /// `Balances` pallet, which uses a `StorageMap` to store balances data only. - /// NOTE: This is only used in the case that this pallet is used to store balances. - #[pallet::storage] - pub type Account, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, T::AccountId, AccountData, ValueQuery>; - - /// Any liquidity locks on some account balances. - /// NOTE: Should only be accessed when setting, changing and freeing a lock. - /// - /// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/` - #[pallet::storage] - pub type Locks, I: 'static = ()> = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - WeakBoundedVec, T::MaxLocks>, - ValueQuery, - >; - - /// Named reserves on some account balances. - /// - /// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/` - #[pallet::storage] - pub type Reserves, I: 'static = ()> = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - BoundedVec, T::MaxReserves>, - ValueQuery, - >; - - /// Holds on account balances. - #[pallet::storage] - pub type Holds, I: 'static = ()> = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - BoundedVec< - IdAmount, - VariantCountOf, - >, - ValueQuery, - >; - - /// Freeze locks on account balances. - #[pallet::storage] - pub type Freezes, I: 'static = ()> = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - BoundedVec, T::MaxFreezes>, - ValueQuery, - >; - - #[pallet::genesis_config] - pub struct GenesisConfig, I: 'static = ()> { - pub balances: Vec<(T::AccountId, T::Balance)>, - /// Derived development accounts(Optional): - /// - `u32`: The number of development accounts to generate. - /// - `T::Balance`: The initial balance assigned to each development account. - /// - `String`: An optional derivation(hard) string template. - /// - Must include `{}` as a placeholder for account indices. - /// - Defaults to `"//Sender//{}`" if `None`. - pub dev_accounts: Option<(u32, T::Balance, Option)>, - } - - impl, I: 'static> Default for GenesisConfig { - fn default() -> Self { - Self { balances: Default::default(), dev_accounts: None } - } - } - - #[pallet::genesis_build] - impl, I: 'static> BuildGenesisConfig for GenesisConfig { - fn build(&self) { - let total = self.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n); - - >::put(total); - - for (_, balance) in &self.balances { - assert!( - *balance >= >::ExistentialDeposit::get(), - "the balance of any account should always be at least the existential deposit.", - ) - } - - // ensure no duplicates exist. - let endowed_accounts = self - .balances - .iter() - .map(|(x, _)| x) - .cloned() - .collect::>(); - - assert!( - endowed_accounts.len() == self.balances.len(), - "duplicate balances in genesis." - ); - - // Generate additional dev accounts. - if let Some((num_accounts, balance, ref derivation)) = self.dev_accounts { - // Using the provided derivation string or default to `"//Sender//{}`". - Pallet::::derive_dev_account( - num_accounts, - balance, - derivation.as_deref().unwrap_or(DEFAULT_ADDRESS_URI), - ); - } - for &(ref who, free) in self.balances.iter() { - frame_system::Pallet::::inc_providers(who); - assert!(T::AccountStore::insert(who, AccountData { free, ..Default::default() }) - .is_ok()); - } - } - } - - #[pallet::hooks] - impl, I: 'static> Hooks> for Pallet { - fn integrity_test() { - #[cfg(not(feature = "insecure_zero_ed"))] - assert!( - !>::ExistentialDeposit::get().is_zero(), - "The existential deposit must be greater than zero!" - ); - - assert!( - T::MaxFreezes::get() >= ::VARIANT_COUNT, - "MaxFreezes should be greater than or equal to the number of freeze reasons: {} < {}", - T::MaxFreezes::get(), ::VARIANT_COUNT, - ); - } - - #[cfg(feature = "try-runtime")] - fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { - Holds::::iter_keys().try_for_each(|k| { - if Holds::::decode_len(k).unwrap_or(0) > - T::RuntimeHoldReason::VARIANT_COUNT as usize - { - Err("Found `Hold` with too many elements") - } else { - Ok(()) - } - })?; - - Freezes::::iter_keys().try_for_each(|k| { - if Freezes::::decode_len(k).unwrap_or(0) > T::MaxFreezes::get() as usize { - Err("Found `Freeze` with too many elements") - } else { - Ok(()) - } - })?; - - Ok(()) - } - } - - #[pallet::call(weight(>::WeightInfo))] - impl, I: 'static> Pallet { - /// Transfer some liquid free balance to another account. - /// - /// `transfer_allow_death` will set the `FreeBalance` of the sender and receiver. - /// If the sender's account is below the existential deposit as a result - /// of the transfer, the account will be reaped. - /// - /// The dispatch origin for this call must be `Signed` by the transactor. - #[pallet::call_index(0)] - pub fn transfer_allow_death( - origin: OriginFor, - dest: AccountIdLookupOf, - #[pallet::compact] value: T::Balance, - ) -> DispatchResult { - let source = ensure_signed(origin)?; - let dest = T::Lookup::lookup(dest)?; - >::transfer(&source, &dest, value, Expendable)?; - Ok(()) - } - - /// Exactly as `transfer_allow_death`, except the origin must be root and the source account - /// may be specified. - #[pallet::call_index(2)] - pub fn force_transfer( - origin: OriginFor, - source: AccountIdLookupOf, - dest: AccountIdLookupOf, - #[pallet::compact] value: T::Balance, - ) -> DispatchResult { - ensure_root(origin)?; - let source = T::Lookup::lookup(source)?; - let dest = T::Lookup::lookup(dest)?; - >::transfer(&source, &dest, value, Expendable)?; - Ok(()) - } - - /// Same as the [`transfer_allow_death`] call, but with a check that the transfer will not - /// kill the origin account. - /// - /// 99% of the time you want [`transfer_allow_death`] instead. - /// - /// [`transfer_allow_death`]: struct.Pallet.html#method.transfer - #[pallet::call_index(3)] - pub fn transfer_keep_alive( - origin: OriginFor, - dest: AccountIdLookupOf, - #[pallet::compact] value: T::Balance, - ) -> DispatchResult { - let source = ensure_signed(origin)?; - let dest = T::Lookup::lookup(dest)?; - >::transfer(&source, &dest, value, Preserve)?; - Ok(()) - } - - /// Transfer the entire transferable balance from the caller account. - /// - /// NOTE: This function only attempts to transfer _transferable_ balances. This means that - /// any locked, reserved, or existential deposits (when `keep_alive` is `true`), will not be - /// transferred by this function. To ensure that this function results in a killed account, - /// you might need to prepare the account by removing any reference counters, storage - /// deposits, etc... - /// - /// The dispatch origin of this call must be Signed. - /// - /// - `dest`: The recipient of the transfer. - /// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all - /// of the funds the account has, causing the sender account to be killed (false), or - /// transfer everything except at least the existential deposit, which will guarantee to - /// keep the sender account alive (true). - #[pallet::call_index(4)] - pub fn transfer_all( - origin: OriginFor, - dest: AccountIdLookupOf, - keep_alive: bool, - ) -> DispatchResult { - let transactor = ensure_signed(origin)?; - let keep_alive = if keep_alive { Preserve } else { Expendable }; - let reducible_balance = >::reducible_balance( - &transactor, - keep_alive, - Fortitude::Polite, - ); - let dest = T::Lookup::lookup(dest)?; - >::transfer( - &transactor, - &dest, - reducible_balance, - keep_alive, - )?; - Ok(()) - } - - /// Unreserve some balance from a user by force. - /// - /// Can only be called by ROOT. - #[pallet::call_index(5)] - pub fn force_unreserve( - origin: OriginFor, - who: AccountIdLookupOf, - amount: T::Balance, - ) -> DispatchResult { - ensure_root(origin)?; - let who = T::Lookup::lookup(who)?; - let _leftover = >::unreserve(&who, amount); - Ok(()) - } - - /// Upgrade a specified account. - /// - /// - `origin`: Must be `Signed`. - /// - `who`: The account to be upgraded. - /// - /// This will waive the transaction fee if at least all but 10% of the accounts needed to - /// be upgraded. (We let some not have to be upgraded just in order to allow for the - /// possibility of churn). - #[pallet::call_index(6)] - #[pallet::weight(T::WeightInfo::upgrade_accounts(who.len() as u32))] - pub fn upgrade_accounts( - origin: OriginFor, - who: Vec, - ) -> DispatchResultWithPostInfo { - ensure_signed(origin)?; - if who.is_empty() { - return Ok(Pays::Yes.into()) - } - let mut upgrade_count = 0; - for i in &who { - let upgraded = Self::ensure_upgraded(i); - if upgraded { - upgrade_count.saturating_inc(); - } - } - let proportion_upgraded = Perbill::from_rational(upgrade_count, who.len() as u32); - if proportion_upgraded >= Perbill::from_percent(90) { - Ok(Pays::No.into()) - } else { - Ok(Pays::Yes.into()) - } - } - - /// Set the regular balance of a given account. - /// - /// The dispatch origin for this call is `root`. - #[pallet::call_index(8)] - #[pallet::weight( - T::WeightInfo::force_set_balance_creating() // Creates a new account. - .max(T::WeightInfo::force_set_balance_killing()) // Kills an existing account. - )] - pub fn force_set_balance( - origin: OriginFor, - who: AccountIdLookupOf, - #[pallet::compact] new_free: T::Balance, - ) -> DispatchResult { - ensure_root(origin)?; - let who = T::Lookup::lookup(who)?; - let existential_deposit = Self::ed(); - - let wipeout = new_free < existential_deposit; - let new_free = if wipeout { Zero::zero() } else { new_free }; - - // First we try to modify the account's balance to the forced balance. - let old_free = Self::mutate_account_handling_dust(&who, |account| { - let old_free = account.free; - account.free = new_free; - old_free - })?; - - // This will adjust the total issuance, which was not done by the `mutate_account` - // above. - if new_free > old_free { - mem::drop(PositiveImbalance::::new(new_free - old_free)); - } else if new_free < old_free { - mem::drop(NegativeImbalance::::new(old_free - new_free)); - } - - Self::deposit_event(Event::BalanceSet { who, free: new_free }); - Ok(()) - } - - /// Adjust the total issuance in a saturating way. - /// - /// Can only be called by root and always needs a positive `delta`. - /// - /// # Example - #[doc = docify::embed!("./src/tests/dispatchable_tests.rs", force_adjust_total_issuance_example)] - #[pallet::call_index(9)] - #[pallet::weight(T::WeightInfo::force_adjust_total_issuance())] - pub fn force_adjust_total_issuance( - origin: OriginFor, - direction: AdjustmentDirection, - #[pallet::compact] delta: T::Balance, - ) -> DispatchResult { - ensure_root(origin)?; - - ensure!(delta > Zero::zero(), Error::::DeltaZero); - - let old = TotalIssuance::::get(); - let new = match direction { - AdjustmentDirection::Increase => old.saturating_add(delta), - AdjustmentDirection::Decrease => old.saturating_sub(delta), - }; - - ensure!(InactiveIssuance::::get() <= new, Error::::IssuanceDeactivated); - TotalIssuance::::set(new); - - Self::deposit_event(Event::::TotalIssuanceForced { old, new }); - - Ok(()) - } - - /// Burn the specified liquid free balance from the origin account. - /// - /// If the origin's account ends up below the existential deposit as a result - /// of the burn and `keep_alive` is false, the account will be reaped. - /// - /// Unlike sending funds to a _burn_ address, which merely makes the funds inaccessible, - /// this `burn` operation will reduce total issuance by the amount _burned_. - #[pallet::call_index(10)] - #[pallet::weight(if *keep_alive {T::WeightInfo::burn_allow_death() } else {T::WeightInfo::burn_keep_alive()})] - pub fn burn( - origin: OriginFor, - #[pallet::compact] value: T::Balance, - keep_alive: bool, - ) -> DispatchResult { - let source = ensure_signed(origin)?; - let preservation = if keep_alive { Preserve } else { Expendable }; - >::burn_from( - &source, - value, - preservation, - Precision::Exact, - Polite, - )?; - Ok(()) - } - } - - impl, I: 'static> Pallet { - /// Public function to get the total issuance. - pub fn total_issuance() -> T::Balance { - TotalIssuance::::get() - } - - /// Public function to get the inactive issuance. - pub fn inactive_issuance() -> T::Balance { - InactiveIssuance::::get() - } - - /// Public function to access the Locks storage. - pub fn locks(who: &T::AccountId) -> WeakBoundedVec, T::MaxLocks> { - Locks::::get(who) - } - - /// Public function to access the reserves storage. - pub fn reserves( - who: &T::AccountId, - ) -> BoundedVec, T::MaxReserves> { - Reserves::::get(who) - } - - fn ed() -> T::Balance { - T::ExistentialDeposit::get() - } - /// Ensure the account `who` is using the new logic. - /// - /// Returns `true` if the account did get upgraded, `false` if it didn't need upgrading. - pub fn ensure_upgraded(who: &T::AccountId) -> bool { - let mut a = T::AccountStore::get(who); - if a.flags.is_new_logic() { - return false - } - a.flags.set_new_logic(); - if !a.reserved.is_zero() && a.frozen.is_zero() { - if system::Pallet::::providers(who) == 0 { - // Gah!! We have no provider refs :( - // This shouldn't practically happen, but we need a failsafe anyway: let's give - // them enough for an ED. - log::warn!( - target: LOG_TARGET, - "account with a non-zero reserve balance has no provider refs, account_id: '{:?}'.", - who - ); - a.free = a.free.max(Self::ed()); - system::Pallet::::inc_providers(who); - } - let _ = system::Pallet::::inc_consumers_without_limit(who).defensive(); - } - // Should never fail - we're only setting a bit. - let _ = T::AccountStore::try_mutate_exists(who, |account| -> DispatchResult { - *account = Some(a); - Ok(()) - }); - Self::deposit_event(Event::Upgraded { who: who.clone() }); - return true - } - - /// Get the free balance of an account. - pub fn free_balance(who: impl core::borrow::Borrow) -> T::Balance { - Self::account(who.borrow()).free - } - - /// Get the balance of an account that can be used for transfers, reservations, or any other - /// non-locking, non-transaction-fee activity. Will be at most `free_balance`. - pub fn usable_balance(who: impl core::borrow::Borrow) -> T::Balance { - >::reducible_balance(who.borrow(), Expendable, Polite) - } - - /// Get the balance of an account that can be used for paying transaction fees (not tipping, - /// or any other kind of fees, though). Will be at most `free_balance`. - /// - /// This requires that the account stays alive. - pub fn usable_balance_for_fees(who: impl core::borrow::Borrow) -> T::Balance { - >::reducible_balance(who.borrow(), Protect, Polite) - } - - /// Get the reserved balance of an account. - pub fn reserved_balance(who: impl core::borrow::Borrow) -> T::Balance { - Self::account(who.borrow()).reserved - } - - /// Get both the free and reserved balances of an account. - pub(crate) fn account(who: &T::AccountId) -> AccountData { - T::AccountStore::get(who) - } - - /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. - /// - /// It returns the result from the closure. Any dust is handled through the low-level - /// `fungible::Unbalanced` trap-door for legacy dust management. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - pub(crate) fn mutate_account_handling_dust( - who: &T::AccountId, - f: impl FnOnce(&mut AccountData) -> R, - ) -> Result { - let (r, maybe_dust) = Self::mutate_account(who, f)?; - if let Some(dust) = maybe_dust { - >::handle_raw_dust(dust); - } - Ok(r) - } - - /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. - /// - /// It returns the result from the closure. Any dust is handled through the low-level - /// `fungible::Unbalanced` trap-door for legacy dust management. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - pub(crate) fn try_mutate_account_handling_dust>( - who: &T::AccountId, - f: impl FnOnce(&mut AccountData, bool) -> Result, - ) -> Result { - let (r, maybe_dust) = Self::try_mutate_account(who, f)?; - if let Some(dust) = maybe_dust { - >::handle_raw_dust(dust); - } - Ok(r) - } - - /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. - /// - /// It returns both the result from the closure, and an optional amount of dust - /// which should be handled once it is known that all nested mutates that could affect - /// storage items what the dust handler touches have completed. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - pub(crate) fn mutate_account( - who: &T::AccountId, - f: impl FnOnce(&mut AccountData) -> R, - ) -> Result<(R, Option), DispatchError> { - Self::try_mutate_account(who, |a, _| -> Result { Ok(f(a)) }) - } - - /// Returns `true` when `who` has some providers or `insecure_zero_ed` feature is disabled. - /// Returns `false` otherwise. - #[cfg(not(feature = "insecure_zero_ed"))] - fn have_providers_or_no_zero_ed(_: &T::AccountId) -> bool { - true - } - - /// Returns `true` when `who` has some providers or `insecure_zero_ed` feature is disabled. - /// Returns `false` otherwise. - #[cfg(feature = "insecure_zero_ed")] - fn have_providers_or_no_zero_ed(who: &T::AccountId) -> bool { - frame_system::Pallet::::providers(who) > 0 - } - - /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the - /// result of `f` is an `Err`. - /// - /// It returns both the result from the closure, and an optional amount of dust - /// which should be handled once it is known that all nested mutates that could affect - /// storage items what the dust handler touches have completed. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - pub(crate) fn try_mutate_account>( - who: &T::AccountId, - f: impl FnOnce(&mut AccountData, bool) -> Result, - ) -> Result<(R, Option), E> { - Self::ensure_upgraded(who); - let result = T::AccountStore::try_mutate_exists(who, |maybe_account| { - let is_new = maybe_account.is_none(); - let mut account = maybe_account.take().unwrap_or_default(); - let did_provide = - account.free >= Self::ed() && Self::have_providers_or_no_zero_ed(who); - let did_consume = - !is_new && (!account.reserved.is_zero() || !account.frozen.is_zero()); - - let result = f(&mut account, is_new)?; - - let does_provide = account.free >= Self::ed(); - let does_consume = !account.reserved.is_zero() || !account.frozen.is_zero(); - - if !did_provide && does_provide { - frame_system::Pallet::::inc_providers(who); - } - if did_consume && !does_consume { - frame_system::Pallet::::dec_consumers(who); - } - if !did_consume && does_consume { - frame_system::Pallet::::inc_consumers(who)?; - } - if does_consume && frame_system::Pallet::::consumers(who) == 0 { - // NOTE: This is a failsafe and should not happen for normal accounts. A normal - // account should have gotten a consumer ref in `!did_consume && does_consume` - // at some point. - log::error!(target: LOG_TARGET, "Defensively bumping a consumer ref."); - frame_system::Pallet::::inc_consumers(who)?; - } - if did_provide && !does_provide { - // This could reap the account so must go last. - frame_system::Pallet::::dec_providers(who).inspect_err(|_| { - // best-effort revert consumer change. - if did_consume && !does_consume { - let _ = frame_system::Pallet::::inc_consumers(who).defensive(); - } - if !did_consume && does_consume { - let _ = frame_system::Pallet::::dec_consumers(who); - } - })?; - } - - let maybe_endowed = if is_new { Some(account.free) } else { None }; - - // Handle any steps needed after mutating an account. - // - // This includes DustRemoval unbalancing, in the case than the `new` account's total - // balance is non-zero but below ED. - // - // Updates `maybe_account` to `Some` iff the account has sufficient balance. - // Evaluates `maybe_dust`, which is `Some` containing the dust to be dropped, iff - // some dust should be dropped. - // - // We should never be dropping if reserved is non-zero. Reserved being non-zero - // should imply that we have a consumer ref, so this is economically safe. - let ed = Self::ed(); - let maybe_dust = if account.free < ed && account.reserved.is_zero() { - if account.free.is_zero() { - None - } else { - Some(account.free) - } - } else { - assert!( - account.free.is_zero() || account.free >= ed || !account.reserved.is_zero() - ); - *maybe_account = Some(account); - None - }; - Ok((maybe_endowed, maybe_dust, result)) - }); - result.map(|(maybe_endowed, maybe_dust, result)| { - if let Some(endowed) = maybe_endowed { - Self::deposit_event(Event::Endowed { - account: who.clone(), - free_balance: endowed, - }); - } - if let Some(amount) = maybe_dust { - Pallet::::deposit_event(Event::DustLost { account: who.clone(), amount }); - } - (result, maybe_dust) - }) - } - - /// Update the account entry for `who`, given the locks. - pub(crate) fn update_locks(who: &T::AccountId, locks: &[BalanceLock]) { - let bounded_locks = WeakBoundedVec::<_, T::MaxLocks>::force_from( - locks.to_vec(), - Some("Balances Update Locks"), - ); - - if locks.len() as u32 > T::MaxLocks::get() { - log::warn!( - target: LOG_TARGET, - "Warning: A user has more currency locks than expected. \ - A runtime configuration adjustment may be needed." - ); - } - let freezes = Freezes::::get(who); - let mut prev_frozen = Zero::zero(); - let mut after_frozen = Zero::zero(); - // No way this can fail since we do not alter the existential balances. - // TODO: Revisit this assumption. - let res = Self::mutate_account(who, |b| { - prev_frozen = b.frozen; - b.frozen = Zero::zero(); - for l in locks.iter() { - b.frozen = b.frozen.max(l.amount); - } - for l in freezes.iter() { - b.frozen = b.frozen.max(l.amount); - } - after_frozen = b.frozen; - }); - debug_assert!(res.is_ok()); - if let Ok((_, maybe_dust)) = res { - debug_assert!(maybe_dust.is_none(), "Not altering main balance; qed"); - } - - match locks.is_empty() { - true => Locks::::remove(who), - false => Locks::::insert(who, bounded_locks), - } - - if prev_frozen > after_frozen { - let amount = prev_frozen.saturating_sub(after_frozen); - Self::deposit_event(Event::Unlocked { who: who.clone(), amount }); - } else if after_frozen > prev_frozen { - let amount = after_frozen.saturating_sub(prev_frozen); - Self::deposit_event(Event::Locked { who: who.clone(), amount }); - } - } - - /// Update the account entry for `who`, given the locks. - pub(crate) fn update_freezes( - who: &T::AccountId, - freezes: BoundedSlice, T::MaxFreezes>, - ) -> DispatchResult { - let mut prev_frozen = Zero::zero(); - let mut after_frozen = Zero::zero(); - let (_, maybe_dust) = Self::mutate_account(who, |b| { - prev_frozen = b.frozen; - b.frozen = Zero::zero(); - for l in Locks::::get(who).iter() { - b.frozen = b.frozen.max(l.amount); - } - for l in freezes.iter() { - b.frozen = b.frozen.max(l.amount); - } - after_frozen = b.frozen; - })?; - debug_assert!(maybe_dust.is_none(), "Not altering main balance; qed"); - if freezes.is_empty() { - Freezes::::remove(who); - } else { - Freezes::::insert(who, freezes); - } - if prev_frozen > after_frozen { - let amount = prev_frozen.saturating_sub(after_frozen); - Self::deposit_event(Event::Thawed { who: who.clone(), amount }); - } else if after_frozen > prev_frozen { - let amount = after_frozen.saturating_sub(prev_frozen); - Self::deposit_event(Event::Frozen { who: who.clone(), amount }); - } - Ok(()) - } - - /// Move the reserved balance of one account into the balance of another, according to - /// `status`. This will respect freezes/locks only if `fortitude` is `Polite`. - /// - /// Is a no-op if the value to be moved is zero. - /// - /// NOTE: returns actual amount of transferred value in `Ok` case. - pub(crate) fn do_transfer_reserved( - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: T::Balance, - precision: Precision, - fortitude: Fortitude, - status: Status, - ) -> Result { - if value.is_zero() { - return Ok(Zero::zero()) - } - - let max = >::reducible_total_balance_on_hold( - slashed, fortitude, - ); - let actual = match precision { - Precision::BestEffort => value.min(max), - Precision::Exact => value, - }; - ensure!(actual <= max, TokenError::FundsUnavailable); - if slashed == beneficiary { - return match status { - Status::Free => Ok(actual.saturating_sub(Self::unreserve(slashed, actual))), - Status::Reserved => Ok(actual), - } - } - - let ((_, maybe_dust_1), maybe_dust_2) = Self::try_mutate_account( - beneficiary, - |to_account, is_new| -> Result<((), Option), DispatchError> { - ensure!(!is_new, Error::::DeadAccount); - Self::try_mutate_account(slashed, |from_account, _| -> DispatchResult { - match status { - Status::Free => - to_account.free = to_account - .free - .checked_add(&actual) - .ok_or(ArithmeticError::Overflow)?, - Status::Reserved => - to_account.reserved = to_account - .reserved - .checked_add(&actual) - .ok_or(ArithmeticError::Overflow)?, - } - from_account.reserved.saturating_reduce(actual); - Ok(()) - }) - }, - )?; - - if let Some(dust) = maybe_dust_1 { - >::handle_raw_dust(dust); - } - if let Some(dust) = maybe_dust_2 { - >::handle_raw_dust(dust); - } - - Self::deposit_event(Event::ReserveRepatriated { - from: slashed.clone(), - to: beneficiary.clone(), - amount: actual, - destination_status: status, - }); - Ok(actual) - } - - /// Generate dev account from derivation(hard) string. - pub fn derive_dev_account(num_accounts: u32, balance: T::Balance, derivation: &str) { - // Ensure that the number of accounts is not zero. - assert!(num_accounts > 0, "num_accounts must be greater than zero"); - - assert!( - balance >= >::ExistentialDeposit::get(), - "the balance of any account should always be at least the existential deposit.", - ); - - assert!( - derivation.contains("{}"), - "Invalid derivation, expected `{{}}` as part of the derivation" - ); - - for index in 0..num_accounts { - // Replace "{}" in the derivation string with the index. - let derivation_string = derivation.replace("{}", &index.to_string()); - - // Generate the key pair from the derivation string using sr25519. - let pair: SrPair = Pair::from_string(&derivation_string, None) - .expect(&format!("Failed to parse derivation string: {derivation_string}")); - - // Convert the public key to AccountId. - let who = T::AccountId::decode(&mut &pair.public().encode()[..]) - .expect(&format!("Failed to decode public key from pair: {:?}", pair.public())); - - // Set the balance for the generated account. - Self::mutate_account_handling_dust(&who, |account| { - account.free = balance; - }) - .expect(&format!("Failed to add account to keystore: {:?}", who)); - } - } - } -} diff --git a/pallets/balances/src/migration.rs b/pallets/balances/src/migration.rs deleted file mode 100644 index 836deb325..000000000 --- a/pallets/balances/src/migration.rs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Substrate. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use super::*; -use frame_support::{ - pallet_prelude::*, - traits::{OnRuntimeUpgrade, PalletInfoAccess}, - weights::Weight, -}; - -fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { - let on_chain_version = Pallet::::on_chain_storage_version(); - - if on_chain_version == 0 { - let total = accounts - .iter() - .map(|a| Pallet::::total_balance(a)) - .fold(T::Balance::zero(), |a, e| a.saturating_add(e)); - Pallet::::deactivate(total); - - // Remove the old `StorageVersion` type. - frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( - Pallet::::name().as_bytes(), - "StorageVersion".as_bytes(), - )); - - // Set storage version to `1`. - StorageVersion::new(1).put::>(); - - log::info!(target: LOG_TARGET, "Storage to version 1"); - T::DbWeight::get().reads_writes(2 + accounts.len() as u64, 3) - } else { - log::info!( - target: LOG_TARGET, - "Migration did not execute. This probably should be removed" - ); - T::DbWeight::get().reads(1) - } -} - -// NOTE: This must be used alongside the account whose balance is expected to be inactive. -// Generally this will be used for the XCM teleport checking account. -pub struct MigrateToTrackInactive(PhantomData<(T, A, I)>); -impl, A: Get, I: 'static> OnRuntimeUpgrade - for MigrateToTrackInactive -{ - fn on_runtime_upgrade() -> Weight { - migrate_v0_to_v1::(&[A::get()]) - } -} - -// NOTE: This must be used alongside the accounts whose balance is expected to be inactive. -// Generally this will be used for the XCM teleport checking accounts. -pub struct MigrateManyToTrackInactive(PhantomData<(T, A, I)>); -impl, A: Get>, I: 'static> OnRuntimeUpgrade - for MigrateManyToTrackInactive -{ - fn on_runtime_upgrade() -> Weight { - migrate_v0_to_v1::(&A::get()) - } -} - -pub struct ResetInactive(PhantomData<(T, I)>); -impl, I: 'static> OnRuntimeUpgrade for ResetInactive { - fn on_runtime_upgrade() -> Weight { - let on_chain_version = Pallet::::on_chain_storage_version(); - - if on_chain_version == 1 { - // Remove the old `StorageVersion` type. - frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( - Pallet::::name().as_bytes(), - "StorageVersion".as_bytes(), - )); - - InactiveIssuance::::kill(); - - // Set storage version to `0`. - StorageVersion::new(0).put::>(); - - log::info!(target: LOG_TARGET, "Storage to version 0"); - T::DbWeight::get().reads_writes(1, 3) - } else { - log::info!( - target: LOG_TARGET, - "Migration did not execute. This probably should be removed" - ); - T::DbWeight::get().reads(1) - } - } -} diff --git a/pallets/balances/src/tests/currency_tests.rs b/pallets/balances/src/tests/currency_tests.rs deleted file mode 100644 index 0e5d7ccb4..000000000 --- a/pallets/balances/src/tests/currency_tests.rs +++ /dev/null @@ -1,1445 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Tests regarding the functionality of the `Currency` trait set implementations. - -use super::*; -use crate::{Event, NegativeImbalance}; -use frame_support::{ - traits::{ - BalanceStatus::{Free, Reserved}, - Currency, - ExistenceRequirement::{self, AllowDeath, KeepAlive}, - InspectLockableCurrency, LockIdentifier, LockableCurrency, NamedReservableCurrency, - ReservableCurrency, WithdrawReasons, - }, - StorageNoopGuard, -}; -use frame_system::Event as SysEvent; -use sp_runtime::traits::DispatchTransaction; - -const ID_1: LockIdentifier = *b"1 "; -const ID_2: LockIdentifier = *b"2 "; - -pub const CALL: &::RuntimeCall = - &RuntimeCall::Balances(crate::Call::transfer_allow_death { dest: 0, value: 0 }); - -#[test] -fn ed_should_work() { - ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 1000)); - assert_noop!( - >::transfer(&1, &10, 1000, KeepAlive), - TokenError::NotExpendable - ); - assert_ok!(>::transfer(&1, &10, 1000, AllowDeath)); - }); -} - -#[test] -fn set_lock_with_amount_zero_removes_lock() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); - Balances::set_lock(ID_1, &1, 0, WithdrawReasons::all()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn set_lock_with_withdraw_reasons_empty_removes_lock() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); - Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn basic_locking_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_eq!(Balances::free_balance(1), 10); - Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 5, AllowDeath), - TokenError::Frozen - ); - }); -} - -#[test] -fn inspect_lock_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); - Balances::set_lock(ID_2, &1, 10, WithdrawReasons::all()); - Balances::set_lock(ID_1, &2, 20, WithdrawReasons::all()); - - assert_eq!(>::balance_locked(ID_1, &1), 10); - assert_eq!(>::balance_locked(ID_2, &1), 10); - assert_eq!(>::balance_locked(ID_1, &2), 20); - assert_eq!(>::balance_locked(ID_2, &2), 0); - assert_eq!(>::balance_locked(ID_1, &3), 0); - }) -} - -#[test] -fn account_should_be_reaped() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_eq!(Balances::free_balance(1), 10); - assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); - assert_eq!(System::providers(&1), 0); - assert_eq!(System::consumers(&1), 0); - // Check that the account is dead. - assert!(!frame_system::Account::::contains_key(&1)); - }); -} - -#[test] -fn reap_failed_due_to_provider_and_consumer() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - // SCENARIO: only one provider and there are remaining consumers. - assert_ok!(System::inc_consumers(&1)); - assert!(!System::can_dec_provider(&1)); - assert_noop!( - >::transfer(&1, &2, 10, AllowDeath), - TokenError::Frozen - ); - assert!(System::account_exists(&1)); - assert_eq!(Balances::free_balance(1), 10); - - // SCENARIO: more than one provider, but will not kill account due to other provider. - assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed); - assert_eq!(System::providers(&1), 2); - assert!(System::can_dec_provider(&1)); - assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); - assert_eq!(System::providers(&1), 1); - assert!(System::account_exists(&1)); - assert_eq!(Balances::free_balance(1), 0); - }); -} - -#[test] -fn partial_locking_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn lock_removal_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - Balances::remove_lock(ID_1, &1); - assert_eq!(System::consumers(&1), 0); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn lock_replacement_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn double_locking_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn combination_locking_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_eq!(System::consumers(&1), 0); - Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::empty()); - assert_eq!(System::consumers(&1), 0); - Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 0); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn lock_value_extension_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - TokenError::Frozen - ); - Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - TokenError::Frozen - ); - Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - assert_noop!( - >::transfer(&1, &2, 3, AllowDeath), - TokenError::Frozen - ); - }); -} - -#[test] -fn lock_should_work_reserve() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - pallet_transaction_payment::NextFeeMultiplier::::put( - Multiplier::saturating_from_integer(1), - ); - Balances::set_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); - assert_noop!( - >::transfer(&1, &2, 1, AllowDeath), - TokenError::Frozen - ); - assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); - assert!(ChargeTransactionPayment::::validate_and_prepare( - ChargeTransactionPayment::from(1), - Some(1).into(), - CALL, - &info_from_weight(Weight::from_parts(1, 0)), - 1, - 0, - ) - .is_err()); - assert!(ChargeTransactionPayment::::validate_and_prepare( - ChargeTransactionPayment::from(0), - Some(1).into(), - CALL, - &info_from_weight(Weight::from_parts(1, 0)), - 1, - 0, - ) - .is_err()); - }); -} - -#[test] -fn lock_should_work_tx_fee() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); - assert_noop!( - >::transfer(&1, &2, 1, AllowDeath), - TokenError::Frozen - ); - assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); - assert!(ChargeTransactionPayment::::validate_and_prepare( - ChargeTransactionPayment::from(1), - Some(1).into(), - CALL, - &info_from_weight(Weight::from_parts(1, 0)), - 1, - 0, - ) - .is_err()); - assert!(ChargeTransactionPayment::::validate_and_prepare( - ChargeTransactionPayment::from(0), - Some(1).into(), - CALL, - &info_from_weight(Weight::from_parts(1, 0)), - 1, - 0, - ) - .is_err()); - }); -} - -#[test] -fn lock_block_number_extension_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - TokenError::Frozen - ); - Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - TokenError::Frozen - ); - System::set_block_number(2); - Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 3, AllowDeath), - TokenError::Frozen - ); - }); -} - -#[test] -fn lock_reasons_extension_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSFER); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - TokenError::Frozen - ); - Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::empty()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - TokenError::Frozen - ); - Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::RESERVE); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - TokenError::Frozen - ); - }); -} - -#[test] -fn reserved_balance_should_prevent_reclaim_count() { - ExtBuilder::default() - .existential_deposit(256 * 1) - .monied(true) - .build_and_execute_with(|| { - System::inc_account_nonce(&2); - assert_eq!(Balances::total_balance(&2), 256 * 20); - assert_eq!(System::providers(&2), 1); - System::inc_providers(&2); - assert_eq!(System::providers(&2), 2); - - assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved - assert_eq!(System::providers(&2), 1); - assert_eq!(Balances::free_balance(2), 255); // "free" account would be deleted. - assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. - assert_eq!(System::account_nonce(&2), 1); - - // account 4 tries to take index 1 for account 5. - assert_ok!(Balances::transfer_allow_death(Some(4).into(), 5, 256 * 1 + 0x69)); - assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); - - assert!(Balances::slash_reserved(&2, 256 * 19 + 1).1.is_zero()); // account 2 gets slashed - - // "reserve" account reduced to 255 (below ED) so account no longer consuming - assert_ok!(System::dec_providers(&2)); - assert_eq!(System::providers(&2), 0); - // account deleted - assert_eq!(System::account_nonce(&2), 0); // nonce zero - assert_eq!(Balances::total_balance(&2), 0); - - // account 4 tries to take index 1 again for account 6. - assert_ok!(Balances::transfer_allow_death(Some(4).into(), 6, 256 * 1 + 0x69)); - assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); - }); -} - -#[test] -fn reward_should_work() { - ExtBuilder::default().monied(true).build_and_execute_with(|| { - assert_eq!(Balances::total_balance(&1), 10); - assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); - assert_eq!( - events(), - [ - RuntimeEvent::Balances(crate::Event::Deposit { who: 1, amount: 10 }), - RuntimeEvent::Balances(crate::Event::Issued { amount: 10 }), - ] - ); - assert_eq!(Balances::total_balance(&1), 20); - assert_eq!(pallet_balances::TotalIssuance::::get(), 120); - }); -} - -#[test] -fn balance_works() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 42); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { - who: 1, - amount: 42, - })); - assert_eq!(Balances::free_balance(1), 42); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(Balances::total_balance(&1), 42); - assert_eq!(Balances::free_balance(2), 0); - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::total_balance(&2), 0); - }); -} - -#[test] -fn reserving_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - - assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(1), 111); - assert_eq!(Balances::reserved_balance(1), 0); - - assert_ok!(Balances::reserve(&1, 69)); - - assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(1), 42); - assert_eq!(Balances::reserved_balance(1), 69); - }); -} - -#[test] -fn deducting_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 69)); - assert_eq!(Balances::free_balance(1), 42); - }); -} - -#[test] -fn refunding_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 42); - assert_ok!(Balances::mutate_account(&1, |a| a.reserved = 69)); - Balances::unreserve(&1, 69); - assert_eq!(Balances::free_balance(1), 111); - assert_eq!(Balances::reserved_balance(1), 0); - }); -} - -#[test] -fn slashing_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 112); - assert_ok!(Balances::reserve(&1, 69)); - assert!(Balances::slash(&1, 42).1.is_zero()); - assert_eq!(Balances::free_balance(1), 1); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(pallet_balances::TotalIssuance::::get(), 70); - }); -} - -#[test] -fn withdrawing_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&2, 111); - let _ = - Balances::withdraw(&2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Withdraw { - who: 2, - amount: 11, - })); - assert_eq!(Balances::free_balance(2), 100); - assert_eq!(pallet_balances::TotalIssuance::::get(), 100); - }); -} - -#[test] -fn withdrawing_balance_should_fail_when_not_expendable() { - ExtBuilder::default().build_and_execute_with(|| { - ExistentialDeposit::set(10); - let _ = Balances::deposit_creating(&2, 20); - assert_ok!(Balances::reserve(&2, 5)); - assert_noop!( - Balances::withdraw(&2, 6, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive), - Error::::Expendability, - ); - assert_ok!(Balances::withdraw( - &2, - 5, - WithdrawReasons::TRANSFER, - ExistenceRequirement::KeepAlive - ),); - }); -} - -#[test] -fn slashing_incomplete_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 42); - assert_ok!(Balances::reserve(&1, 21)); - assert_eq!(Balances::slash(&1, 69).1, 49); - assert_eq!(Balances::free_balance(1), 1); - assert_eq!(Balances::reserved_balance(1), 21); - assert_eq!(pallet_balances::TotalIssuance::::get(), 22); - }); -} - -#[test] -fn unreserving_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 110)); - Balances::unreserve(&1, 41); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 42); - }); -} - -#[test] -fn slashing_reserved_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 112); - assert_ok!(Balances::reserve(&1, 111)); - assert_eq!(Balances::slash_reserved(&1, 42).1, 0); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 1); - assert_eq!(pallet_balances::TotalIssuance::::get(), 70); - }); -} - -#[test] -fn slashing_incomplete_reserved_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 42)); - assert_eq!(Balances::slash_reserved(&1, 69).1, 27); - assert_eq!(Balances::free_balance(1), 69); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(pallet_balances::TotalIssuance::::get(), 69); - }); -} - -#[test] -fn repatriating_reserved_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - let _ = Balances::deposit_creating(&2, 1); - assert_ok!(Balances::reserve(&1, 110)); - assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Free), 0); - System::assert_last_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { - from: 1, - to: 2, - amount: 41, - destination_status: Free, - })); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 1); - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::free_balance(2), 42); - }); -} - -#[test] -fn transferring_reserved_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - let _ = Balances::deposit_creating(&2, 1); - assert_ok!(Balances::reserve(&1, 110)); - assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Reserved), 0); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 1); - assert_eq!(Balances::reserved_balance(2), 41); - assert_eq!(Balances::free_balance(2), 1); - }); -} - -#[test] -fn transferring_reserved_balance_to_yourself_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 110); - assert_ok!(Balances::reserve(&1, 50)); - assert_ok!(Balances::repatriate_reserved(&1, &1, 50, Free), 0); - assert_eq!(Balances::free_balance(1), 110); - assert_eq!(Balances::reserved_balance(1), 0); - - assert_ok!(Balances::reserve(&1, 50)); - assert_ok!(Balances::repatriate_reserved(&1, &1, 60, Free), 10); - assert_eq!(Balances::free_balance(1), 110); - assert_eq!(Balances::reserved_balance(1), 0); - }); -} - -#[test] -fn transferring_reserved_balance_to_nonexistent_should_fail() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 110)); - assert_noop!( - Balances::repatriate_reserved(&1, &2, 42, Free), - Error::::DeadAccount - ); - }); -} - -#[test] -fn transferring_incomplete_reserved_balance_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 110); - let _ = Balances::deposit_creating(&2, 1); - assert_ok!(Balances::reserve(&1, 41)); - assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Free), 28); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(Balances::free_balance(1), 69); - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::free_balance(2), 42); - }); -} - -#[test] -fn transferring_too_high_value_should_not_panic() { - ExtBuilder::default().build_and_execute_with(|| { - Balances::make_free_balance_be(&1, u64::MAX); - Balances::make_free_balance_be(&2, 1); - - assert_err!( - >::transfer(&1, &2, u64::MAX, AllowDeath), - ArithmeticError::Overflow, - ); - - assert_eq!(Balances::free_balance(1), u64::MAX); - assert_eq!(Balances::free_balance(2), 1); - }); -} - -#[test] -fn account_create_on_free_too_low_with_other() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 100); - assert_eq!(pallet_balances::TotalIssuance::::get(), 100); - - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(2), 0); - assert_eq!(pallet_balances::TotalIssuance::::get(), 100); - }) -} - -#[test] -fn account_create_on_free_too_low() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(2), 0); - assert_eq!(pallet_balances::TotalIssuance::::get(), 0); - }) -} - -#[test] -fn account_removal_on_free_too_low() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - assert_eq!(pallet_balances::TotalIssuance::::get(), 0); - - // Setup two accounts with free balance above the existential threshold. - let _ = Balances::deposit_creating(&1, 110); - let _ = Balances::deposit_creating(&2, 110); - - assert_eq!(Balances::free_balance(1), 110); - assert_eq!(Balances::free_balance(2), 110); - assert_eq!(pallet_balances::TotalIssuance::::get(), 220); - - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. - // This should lead to the removal of all balance of this account. - assert_ok!(Balances::transfer_allow_death(Some(1).into(), 2, 20)); - - // Verify free balance removal of account 1. - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::free_balance(2), 130); - - // Verify that TotalIssuance tracks balance removal when free balance is too low. - assert_eq!(pallet_balances::TotalIssuance::::get(), 130); - }); -} - -#[test] -fn burn_must_work() { - ExtBuilder::default().monied(true).build_and_execute_with(|| { - let init_total_issuance = pallet_balances::TotalIssuance::::get(); - let imbalance = >::burn(10); - assert_eq!(pallet_balances::TotalIssuance::::get(), init_total_issuance - 10); - drop(imbalance); - assert_eq!(pallet_balances::TotalIssuance::::get(), init_total_issuance); - }); -} - -#[test] -#[should_panic = "the balance of any account should always be at least the existential deposit."] -fn cannot_set_genesis_value_below_ed() { - EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = 11); - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let _ = crate::GenesisConfig:: { balances: vec![(1, 10)], ..Default::default() } - .assimilate_storage(&mut t) - .unwrap(); -} - -#[test] -#[should_panic = "duplicate balances in genesis."] -fn cannot_set_genesis_value_twice() { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let _ = crate::GenesisConfig:: { - balances: vec![(1, 10), (2, 20), (1, 15)], - ..Default::default() - } - .assimilate_storage(&mut t) - .unwrap(); -} - -#[test] -fn existential_deposit_respected_when_reserving() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - // Set balance to free and reserved at the existential deposit - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 101)); - // Check balance - assert_eq!(Balances::free_balance(1), 101); - assert_eq!(Balances::reserved_balance(1), 0); - - // Reserve some free balance - assert_ok!(Balances::reserve(&1, 1)); - // Check balance, the account should be ok. - assert_eq!(Balances::free_balance(1), 100); - assert_eq!(Balances::reserved_balance(1), 1); - - // Cannot reserve any more of the free balance. - assert_noop!(Balances::reserve(&1, 1), DispatchError::ConsumerRemaining); - }); -} - -#[test] -fn slash_fails_when_account_needed() { - ExtBuilder::default().existential_deposit(50).build_and_execute_with(|| { - // Set balance to free and reserved at the existential deposit - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 52)); - assert_ok!(Balances::reserve(&1, 1)); - // Check balance - assert_eq!(Balances::free_balance(1), 51); - assert_eq!(Balances::reserved_balance(1), 1); - - // Slash a small amount - let res = Balances::slash(&1, 1); - assert_eq!(res, (NegativeImbalance::new(1), 0)); - - // The account should be dead. - assert_eq!(Balances::free_balance(1), 50); - assert_eq!(Balances::reserved_balance(1), 1); - - // Slashing again doesn't work since we require the ED - let res = Balances::slash(&1, 1); - assert_eq!(res, (NegativeImbalance::new(0), 1)); - - // The account should be dead. - assert_eq!(Balances::free_balance(1), 50); - assert_eq!(Balances::reserved_balance(1), 1); - }); -} - -#[test] -fn account_deleted_when_just_dust() { - ExtBuilder::default().existential_deposit(50).build_and_execute_with(|| { - // Set balance to free and reserved at the existential deposit - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 50)); - // Check balance - assert_eq!(Balances::free_balance(1), 50); - - // Slash a small amount - let res = Balances::slash(&1, 1); - assert_eq!(res, (NegativeImbalance::new(1), 0)); - - // The account should be dead. - assert_eq!(Balances::free_balance(1), 0); - }); -} - -#[test] -fn emit_events_with_reserve_and_unreserve() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 100); - - System::set_block_number(2); - assert_ok!(Balances::reserve(&1, 10)); - - System::assert_last_event(RuntimeEvent::Balances(crate::Event::Reserved { - who: 1, - amount: 10, - })); - - System::set_block_number(3); - assert!(Balances::unreserve(&1, 5).is_zero()); - - System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { - who: 1, - amount: 5, - })); - - System::set_block_number(4); - assert_eq!(Balances::unreserve(&1, 6), 1); - - // should only unreserve 5 - System::assert_last_event(RuntimeEvent::Balances(crate::Event::Unreserved { - who: 1, - amount: 5, - })); - }); -} - -#[test] -fn emit_events_with_changing_locks() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 100); - System::reset_events(); - - // Locks = [] --> [10] - Balances::set_lock(*b"LOCK_000", &1, 10, WithdrawReasons::TRANSFER); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 10 })]); - - // Locks = [10] --> [15] - Balances::set_lock(*b"LOCK_000", &1, 15, WithdrawReasons::TRANSFER); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 5 })]); - - // Locks = [15] --> [15, 20] - Balances::set_lock(*b"LOCK_001", &1, 20, WithdrawReasons::TRANSACTION_PAYMENT); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Locked { who: 1, amount: 5 })]); - - // Locks = [15, 20] --> [17, 20] - Balances::set_lock(*b"LOCK_000", &1, 17, WithdrawReasons::TRANSACTION_PAYMENT); - for event in events() { - match event { - RuntimeEvent::Balances(crate::Event::Locked { .. }) => { - assert!(false, "unexpected lock event") - }, - RuntimeEvent::Balances(crate::Event::Unlocked { .. }) => { - assert!(false, "unexpected unlock event") - }, - _ => continue, - } - } - - // Locks = [17, 20] --> [17, 15] - Balances::set_lock(*b"LOCK_001", &1, 15, WithdrawReasons::TRANSFER); - assert_eq!( - events(), - [RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 3 })] - ); - - // Locks = [17, 15] --> [15] - Balances::remove_lock(*b"LOCK_000", &1); - assert_eq!( - events(), - [RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 2 })] - ); - - // Locks = [15] --> [] - Balances::remove_lock(*b"LOCK_001", &1); - assert_eq!( - events(), - [RuntimeEvent::Balances(crate::Event::Unlocked { who: 1, amount: 15 })] - ); - }); -} - -#[test] -fn emit_events_with_existential_deposit() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 100)); - - assert_eq!( - events(), - [ - RuntimeEvent::System(system::Event::NewAccount { account: 1 }), - RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), - RuntimeEvent::Balances(crate::Event::Issued { amount: 100 }), - RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100 }), - ] - ); - - let res = Balances::slash(&1, 1); - assert_eq!(res, (NegativeImbalance::new(1), 0)); - - assert_eq!( - events(), - [ - RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), - RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 99 }), - RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 1 }), - RuntimeEvent::Balances(crate::Event::Rescinded { amount: 1 }), - ] - ); - }); -} - -#[test] -fn emit_events_with_no_existential_deposit_suicide() { - ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 100); - - assert_eq!( - events(), - [ - RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100 }), - RuntimeEvent::System(system::Event::NewAccount { account: 1 }), - RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), - RuntimeEvent::Balances(crate::Event::Issued { amount: 100 }), - ] - ); - - let res = Balances::slash(&1, 100); - assert_eq!(res, (NegativeImbalance::new(100), 0)); - - assert_eq!( - events(), - [ - RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), - RuntimeEvent::Balances(crate::Event::Slashed { who: 1, amount: 100 }), - RuntimeEvent::Balances(crate::Event::Rescinded { amount: 100 }), - ] - ); - }); -} - -#[test] -fn slash_over_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - // SCENARIO: Over-slash will kill account, and report missing slash amount. - Balances::make_free_balance_be(&1, 1_000); - // Slashed full free_balance, and reports 300 not slashed - assert_eq!(Balances::slash(&1, 1_300), (NegativeImbalance::new(1000), 300)); - // Account is dead - assert!(!System::account_exists(&1)); - }); -} - -#[test] -fn slash_full_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - // Slashed completed in full - assert_eq!(Balances::slash(&1, 1_000), (NegativeImbalance::new(1000), 0)); - // Account is still alive - assert!(!System::account_exists(&1)); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { - who: 1, - amount: 1000, - })); - }); -} - -#[test] -fn slash_partial_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - // Slashed completed in full - assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); - // Account is still alive - assert!(System::account_exists(&1)); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { - who: 1, - amount: 900, - })); - }); -} - -#[test] -fn slash_dusting_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - // Slashed completed in full - assert_eq!(Balances::slash(&1, 950), (NegativeImbalance::new(950), 0)); - assert!(!System::account_exists(&1)); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { - who: 1, - amount: 950, - })); - }); -} - -#[test] -fn slash_does_not_take_from_reserve() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - assert_ok!(Balances::reserve(&1, 100)); - // Slashed completed in full - assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(800), 100)); - assert_eq!(Balances::reserved_balance(&1), 100); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Slashed { - who: 1, - amount: 800, - })); - }); -} - -#[test] -fn slash_consumed_slash_full_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests - // Slashed completed in full - assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0)); - // Account is still alive - assert!(System::account_exists(&1)); - }); -} - -#[test] -fn slash_consumed_slash_over_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests - // Slashed completed in full - assert_eq!(Balances::slash(&1, 1_000), (NegativeImbalance::new(900), 100)); - // Account is still alive - assert!(System::account_exists(&1)); - }); -} - -#[test] -fn slash_consumed_slash_partial_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - assert_ok!(System::inc_consumers(&1)); // <-- Reference counter added here is enough for all tests - // Slashed completed in full - assert_eq!(Balances::slash(&1, 800), (NegativeImbalance::new(800), 0)); - // Account is still alive - assert!(System::account_exists(&1)); - }); -} - -#[test] -fn slash_on_non_existent_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - // Slash on non-existent account is okay. - assert_eq!(Balances::slash(&12345, 1_300), (NegativeImbalance::new(0), 1300)); - }); -} - -#[test] -fn slash_reserved_slash_partial_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - assert_ok!(Balances::reserve(&1, 900)); - // Slashed completed in full - assert_eq!(Balances::slash_reserved(&1, 800), (NegativeImbalance::new(800), 0)); - assert_eq!(System::consumers(&1), 1); - assert_eq!(Balances::reserved_balance(&1), 100); - assert_eq!(Balances::free_balance(&1), 100); - }); -} - -#[test] -fn slash_reserved_slash_everything_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - Balances::make_free_balance_be(&1, 1_000); - assert_ok!(Balances::reserve(&1, 900)); - assert_eq!(System::consumers(&1), 1); - // Slashed completed in full - assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(900), 0)); - assert_eq!(System::consumers(&1), 0); - // Account is still alive - assert!(System::account_exists(&1)); - }); -} - -#[test] -fn slash_reserved_overslash_does_not_touch_free_balance() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - // SCENARIO: Over-slash doesn't touch free balance. - Balances::make_free_balance_be(&1, 1_000); - assert_ok!(Balances::reserve(&1, 800)); - // Slashed done - assert_eq!(Balances::slash_reserved(&1, 900), (NegativeImbalance::new(800), 100)); - assert_eq!(Balances::free_balance(&1), 200); - }); -} - -#[test] -fn slash_reserved_on_non_existent_works() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - // Slash on non-existent account is okay. - assert_eq!(Balances::slash_reserved(&12345, 1_300), (NegativeImbalance::new(0), 1300)); - }); -} - -#[test] -fn operations_on_dead_account_should_not_change_state() { - // These functions all use `mutate_account` which may introduce a storage change when - // the account never existed to begin with, and shouldn't exist in the end. - ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { - assert!(!frame_system::Account::::contains_key(&1337)); - - // Unreserve - assert_storage_noop!(assert_eq!(Balances::unreserve(&1337, 42), 42)); - // Reserve - assert_noop!(Balances::reserve(&1337, 42), Error::::InsufficientBalance); - // Slash Reserve - assert_storage_noop!(assert_eq!(Balances::slash_reserved(&1337, 42).1, 42)); - // Repatriate Reserve - assert_noop!( - Balances::repatriate_reserved(&1337, &1338, 42, Free), - Error::::DeadAccount - ); - // Slash - assert_storage_noop!(assert_eq!(Balances::slash(&1337, 42).1, 42)); - }); -} - -#[test] -#[should_panic = "The existential deposit must be greater than zero!"] -#[cfg(not(feature = "insecure_zero_ed"))] -fn zero_ed_is_prohibited() { - use frame_support::traits::Hooks; - // These functions all use `mutate_account` which may introduce a storage change when - // the account never existed to begin with, and shouldn't exist in the end. - ExtBuilder::default().existential_deposit(0).build_and_execute_with(|| { - Balances::integrity_test(); - }); -} - -#[test] -fn named_reserve_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - - let id_1 = TestId::Foo; - let id_2 = TestId::Bar; - let id_3 = TestId::Baz; - - // reserve - - assert_noop!( - Balances::reserve_named(&id_1, &1, 112), - Error::::InsufficientBalance - ); - - assert_ok!(Balances::reserve_named(&id_1, &1, 12)); - - assert_eq!(Balances::reserved_balance(1), 12); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 12); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - - assert_ok!(Balances::reserve_named(&id_1, &1, 2)); - - assert_eq!(Balances::reserved_balance(1), 14); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - - assert_ok!(Balances::reserve_named(&id_2, &1, 23)); - - assert_eq!(Balances::reserved_balance(1), 37); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - - assert_ok!(Balances::reserve(&1, 34)); - - assert_eq!(Balances::reserved_balance(1), 71); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 14); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - - assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(1), 40); - - assert_noop!(Balances::reserve_named(&id_3, &1, 2), Error::::TooManyReserves); - - // unreserve - - assert_eq!(Balances::unreserve_named(&id_1, &1, 10), 0); - - assert_eq!(Balances::reserved_balance(1), 61); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 4); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - - assert_eq!(Balances::unreserve_named(&id_1, &1, 5), 1); - - assert_eq!(Balances::reserved_balance(1), 57); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 23); - - assert_eq!(Balances::unreserve_named(&id_2, &1, 3), 0); - - assert_eq!(Balances::reserved_balance(1), 54); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); - - assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(1), 57); - - // slash_reserved_named - - assert_ok!(Balances::reserve_named(&id_1, &1, 10)); - - assert_eq!(Balances::slash_reserved_named(&id_1, &1, 25).1, 15); - - assert_eq!(Balances::reserved_balance(1), 54); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 20); - assert_eq!(Balances::total_balance(&1), 101); - - assert_eq!(Balances::slash_reserved_named(&id_2, &1, 5).1, 0); - - assert_eq!(Balances::reserved_balance(1), 49); - assert_eq!(Balances::reserved_balance_named(&id_1, &1), 0); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); - assert_eq!(Balances::total_balance(&1), 96); - - // repatriate_reserved_named - - let _ = Balances::deposit_creating(&2, 100); - - assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Reserved).unwrap(), 0); - - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); - assert_eq!(Balances::reserved_balance_named(&id_2, &2), 10); - assert_eq!(Balances::reserved_balance(&2), 10); - - assert_eq!(Balances::repatriate_reserved_named(&id_2, &2, &1, 11, Reserved).unwrap(), 1); - - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 15); - assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); - assert_eq!(Balances::reserved_balance(&2), 0); - - assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &2, 10, Free).unwrap(), 0); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); - assert_eq!(Balances::reserved_balance_named(&id_2, &2), 0); - assert_eq!(Balances::free_balance(&2), 110); - - // repatriate_reserved_named to self - - assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 10, Reserved).unwrap(), 5); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 5); - - assert_eq!(Balances::free_balance(&1), 47); - - assert_eq!(Balances::repatriate_reserved_named(&id_2, &1, &1, 15, Free).unwrap(), 10); - assert_eq!(Balances::reserved_balance_named(&id_2, &1), 0); - - assert_eq!(Balances::free_balance(&1), 52); - }); -} - -#[test] -fn reserve_must_succeed_if_can_reserve_does() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 1); - let _ = Balances::deposit_creating(&2, 2); - assert!(Balances::can_reserve(&1, 1) == Balances::reserve(&1, 1).is_ok()); - assert!(Balances::can_reserve(&2, 1) == Balances::reserve(&2, 1).is_ok()); - }); -} - -#[test] -fn reserved_named_to_yourself_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 110); - - let id = TestId::Foo; - - assert_ok!(Balances::reserve_named(&id, &1, 50)); - assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 50, Free), 0); - assert_eq!(Balances::free_balance(1), 110); - assert_eq!(Balances::reserved_balance_named(&id, &1), 0); - - assert_ok!(Balances::reserve_named(&id, &1, 50)); - assert_ok!(Balances::repatriate_reserved_named(&id, &1, &1, 60, Free), 10); - assert_eq!(Balances::free_balance(1), 110); - assert_eq!(Balances::reserved_balance_named(&id, &1), 0); - }); -} - -#[test] -fn ensure_reserved_named_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - - let id = TestId::Foo; - - assert_ok!(Balances::ensure_reserved_named(&id, &1, 15)); - assert_eq!(Balances::reserved_balance_named(&id, &1), 15); - - assert_ok!(Balances::ensure_reserved_named(&id, &1, 10)); - assert_eq!(Balances::reserved_balance_named(&id, &1), 10); - - assert_ok!(Balances::ensure_reserved_named(&id, &1, 20)); - assert_eq!(Balances::reserved_balance_named(&id, &1), 20); - }); -} - -#[test] -fn unreserve_all_named_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - - let id = TestId::Foo; - - assert_ok!(Balances::reserve_named(&id, &1, 15)); - - assert_eq!(Balances::unreserve_all_named(&id, &1), 15); - assert_eq!(Balances::reserved_balance_named(&id, &1), 0); - assert_eq!(Balances::free_balance(&1), 111); - - assert_eq!(Balances::unreserve_all_named(&id, &1), 0); - }); -} - -#[test] -fn slash_all_reserved_named_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - - let id = TestId::Foo; - - assert_ok!(Balances::reserve_named(&id, &1, 15)); - - assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 15); - assert_eq!(Balances::reserved_balance_named(&id, &1), 0); - assert_eq!(Balances::free_balance(&1), 96); - - assert_eq!(Balances::slash_all_reserved_named(&id, &1).peek(), 0); - }); -} - -#[test] -fn repatriate_all_reserved_named_should_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - let _ = Balances::deposit_creating(&2, 10); - let _ = Balances::deposit_creating(&3, 10); - - let id = TestId::Foo; - - assert_ok!(Balances::reserve_named(&id, &1, 15)); - - assert_ok!(Balances::repatriate_all_reserved_named(&id, &1, &2, Reserved)); - assert_eq!(Balances::reserved_balance_named(&id, &1), 0); - assert_eq!(Balances::reserved_balance_named(&id, &2), 15); - - assert_ok!(Balances::repatriate_all_reserved_named(&id, &2, &3, Free)); - assert_eq!(Balances::reserved_balance_named(&id, &2), 0); - assert_eq!(Balances::free_balance(&3), 25); - }); -} - -#[test] -fn freezing_and_locking_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - // Consumer is shared between freezing and locking. - assert_eq!(System::consumers(&1), 0); - assert_ok!(>::set_freeze(&TestId::Foo, &1, 4)); - assert_eq!(System::consumers(&1), 1); - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_eq!(System::consumers(&1), 1); - - // Frozen and locked balances update correctly. - assert_eq!(Balances::account(&1).frozen, 5); - assert_ok!(>::set_freeze(&TestId::Foo, &1, 6)); - assert_eq!(Balances::account(&1).frozen, 6); - assert_ok!(>::set_freeze(&TestId::Foo, &1, 4)); - assert_eq!(Balances::account(&1).frozen, 5); - Balances::set_lock(ID_1, &1, 3, WithdrawReasons::all()); - assert_eq!(Balances::account(&1).frozen, 4); - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_eq!(Balances::account(&1).frozen, 5); - - // Locks update correctly. - Balances::remove_lock(ID_1, &1); - assert_eq!(Balances::account(&1).frozen, 4); - assert_eq!(System::consumers(&1), 1); - assert_ok!(>::set_freeze(&TestId::Foo, &1, 0)); - assert_eq!(Balances::account(&1).frozen, 0); - assert_eq!(System::consumers(&1), 0); - }); -} - -#[test] -fn self_transfer_noop() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - assert_eq!(pallet_balances::TotalIssuance::::get(), 0); - let _ = Balances::deposit_creating(&1, 100); - - // The account is set up properly: - assert_eq!( - events(), - [ - Event::Deposit { who: 1, amount: 100 }.into(), - SysEvent::NewAccount { account: 1 }.into(), - Event::Endowed { account: 1, free_balance: 100 }.into(), - Event::Issued { amount: 100 }.into(), - ] - ); - assert_eq!(Balances::free_balance(1), 100); - assert_eq!(pallet_balances::TotalIssuance::::get(), 100); - - // Transfers to self are No-OPs: - let _g = StorageNoopGuard::new(); - for i in 0..200 { - let r = Balances::transfer_allow_death(Some(1).into(), 1, i); - - if i <= 100 { - assert_ok!(r); - } else { - assert!(r.is_err()); - } - - assert!(events().is_empty()); - assert_eq!(Balances::free_balance(1), 100, "Balance unchanged by self transfer"); - assert_eq!( - pallet_balances::TotalIssuance::::get(), - 100, - "TI unchanged by self transfers" - ); - } - }); -} diff --git a/pallets/balances/src/tests/dispatchable_tests.rs b/pallets/balances/src/tests/dispatchable_tests.rs deleted file mode 100644 index 77e44202e..000000000 --- a/pallets/balances/src/tests/dispatchable_tests.rs +++ /dev/null @@ -1,384 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Tests regarding the functionality of the dispatchables/extrinsics. - -use super::*; -use crate::{ - AdjustmentDirection::{Decrease as Dec, Increase as Inc}, - Event, -}; -use frame_support::traits::{fungible::Unbalanced, tokens::Preservation::Expendable}; -use fungible::{hold::Mutate as HoldMutate, Inspect, Mutate}; - -/// Alice account ID for more readable tests. -const ALICE: u64 = 1; - -#[test] -fn default_indexing_on_new_accounts_should_not_work2() { - ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .build_and_execute_with(|| { - // account 5 should not exist - // ext_deposit is 10, value is 9, not satisfies for ext_deposit - assert_noop!( - Balances::transfer_allow_death(Some(1).into(), 5, 9), - TokenError::BelowMinimum, - ); - assert_eq!(Balances::free_balance(1), 100); - }); -} - -#[test] -fn dust_account_removal_should_work() { - ExtBuilder::default() - .existential_deposit(100) - .monied(true) - .build_and_execute_with(|| { - System::inc_account_nonce(&2); - assert_eq!(System::account_nonce(&2), 1); - assert_eq!(Balances::total_balance(&2), 2000); - // index 1 (account 2) becomes zombie - assert_ok!(Balances::transfer_allow_death(Some(2).into(), 5, 1901)); - assert_eq!(Balances::total_balance(&2), 0); - assert_eq!(Balances::total_balance(&5), 1901); - assert_eq!(System::account_nonce(&2), 0); - }); -} - -#[test] -fn balance_transfer_works() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::mint_into(&1, 111); - assert_ok!(Balances::transfer_allow_death(Some(1).into(), 2, 69)); - assert_eq!(Balances::total_balance(&1), 42); - assert_eq!(Balances::total_balance(&2), 69); - }); -} - -#[test] -fn force_transfer_works() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::mint_into(&1, 111); - assert_noop!(Balances::force_transfer(Some(2).into(), 1, 2, 69), BadOrigin,); - assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); - assert_eq!(Balances::total_balance(&1), 42); - assert_eq!(Balances::total_balance(&2), 69); - }); -} - -#[test] -fn balance_transfer_when_on_hold_should_not_work() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::mint_into(&1, 111); - assert_ok!(Balances::hold(&TestId::Foo, &1, 69)); - assert_noop!( - Balances::transfer_allow_death(Some(1).into(), 2, 69), - TokenError::FundsUnavailable, - ); - }); -} - -#[test] -fn transfer_keep_alive_works() { - ExtBuilder::default().existential_deposit(1).build_and_execute_with(|| { - let _ = Balances::mint_into(&1, 100); - assert_noop!( - Balances::transfer_keep_alive(Some(1).into(), 2, 100), - TokenError::NotExpendable - ); - assert_eq!(Balances::total_balance(&1), 100); - assert_eq!(Balances::total_balance(&2), 0); - }); -} - -#[test] -fn transfer_keep_alive_all_free_succeed() { - ExtBuilder::default().existential_deposit(100).build_and_execute_with(|| { - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 300)); - assert_ok!(Balances::hold(&TestId::Foo, &1, 100)); - assert_ok!(Balances::transfer_keep_alive(Some(1).into(), 2, 100)); - assert_eq!(Balances::total_balance(&1), 200); - assert_eq!(Balances::total_balance(&2), 100); - }); -} - -#[test] -fn transfer_all_works_1() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - // setup - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 200)); - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); - // transfer all and allow death - assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); - assert_eq!(Balances::total_balance(&1), 0); - assert_eq!(Balances::total_balance(&2), 200); - }); -} - -#[test] -fn transfer_all_works_2() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - // setup - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 200)); - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); - // transfer all and keep alive - assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); - assert_eq!(Balances::total_balance(&1), 100); - assert_eq!(Balances::total_balance(&2), 100); - }); -} - -#[test] -fn transfer_all_works_3() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - // setup - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 210)); - assert_ok!(Balances::hold(&TestId::Foo, &1, 10)); - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); - // transfer all and allow death w/ reserved - assert_ok!(Balances::transfer_all(Some(1).into(), 2, false)); - assert_eq!(Balances::total_balance(&1), 110); - assert_eq!(Balances::total_balance(&2), 100); - }); -} - -#[test] -fn transfer_all_works_4() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - // setup - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1, 210)); - assert_ok!(Balances::hold(&TestId::Foo, &1, 10)); - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 2, 0)); - // transfer all and keep alive w/ reserved - assert_ok!(Balances::transfer_all(Some(1).into(), 2, true)); - assert_eq!(Balances::total_balance(&1), 110); - assert_eq!(Balances::total_balance(&2), 100); - }); -} - -#[test] -fn set_balance_handles_killing_account() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::mint_into(&1, 111); - assert_ok!(frame_system::Pallet::::inc_consumers(&1)); - assert_noop!( - Balances::force_set_balance(RuntimeOrigin::root(), 1, 0), - DispatchError::ConsumerRemaining, - ); - }); -} - -#[test] -fn set_balance_handles_total_issuance() { - ExtBuilder::default().build_and_execute_with(|| { - let old_total_issuance = pallet_balances::TotalIssuance::::get(); - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 69)); - assert_eq!(pallet_balances::TotalIssuance::::get(), old_total_issuance + 69); - assert_eq!(Balances::total_balance(&1337), 69); - assert_eq!(Balances::free_balance(&1337), 69); - }); -} - -#[test] -fn upgrade_accounts_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - System::inc_providers(&7); - assert_ok!(::AccountStore::try_mutate_exists( - &7, - |a| -> DispatchResult { - *a = Some(AccountData { - free: 5, - reserved: 5, - frozen: Zero::zero(), - flags: crate::types::ExtraFlags::old_logic(), - }); - Ok(()) - } - )); - assert!(!Balances::account(&7).flags.is_new_logic()); - assert_eq!(System::providers(&7), 1); - assert_eq!(System::consumers(&7), 0); - assert_ok!(Balances::upgrade_accounts(Some(1).into(), vec![7])); - assert!(Balances::account(&7).flags.is_new_logic()); - assert_eq!(System::providers(&7), 1); - assert_eq!(System::consumers(&7), 1); - - >::unreserve(&7, 5); - assert_ok!(>::transfer(&7, &1, 10, Expendable)); - assert_eq!(Balances::total_balance(&7), 0); - assert_eq!(System::providers(&7), 0); - assert_eq!(System::consumers(&7), 0); - }); -} - -#[test] -#[docify::export] -fn force_adjust_total_issuance_example() { - ExtBuilder::default().build_and_execute_with(|| { - // First we set the TotalIssuance to 64 by giving Alice a balance of 64. - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), ALICE, 64)); - let old_ti = pallet_balances::TotalIssuance::::get(); - assert_eq!(old_ti, 64, "TI should be 64"); - - // Now test the increase: - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 32)); - let new_ti = pallet_balances::TotalIssuance::::get(); - assert_eq!(old_ti + 32, new_ti, "Should increase by 32"); - - // If Alice tries to call it, it errors: - assert_noop!( - Balances::force_adjust_total_issuance(RawOrigin::Signed(ALICE).into(), Inc, 32), - BadOrigin, - ); - }); -} - -#[test] -fn force_adjust_total_issuance_works() { - ExtBuilder::default().build_and_execute_with(|| { - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 64)); - let ti = pallet_balances::TotalIssuance::::get(); - - // Increase works: - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 32)); - assert_eq!(pallet_balances::TotalIssuance::::get(), ti + 32); - System::assert_last_event(RuntimeEvent::Balances(Event::TotalIssuanceForced { - old: 64, - new: 96, - })); - - // Decrease works: - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 64)); - assert_eq!(pallet_balances::TotalIssuance::::get(), ti - 32); - System::assert_last_event(RuntimeEvent::Balances(Event::TotalIssuanceForced { - old: 96, - new: 32, - })); - }); -} - -#[test] -fn force_adjust_total_issuance_saturates() { - ExtBuilder::default().build_and_execute_with(|| { - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 64)); - let ti = pallet_balances::TotalIssuance::::get(); - let max = ::Balance::max_value(); - assert_eq!(ti, 64); - - // Increment saturates: - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, max)); - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 123)); - assert_eq!(pallet_balances::TotalIssuance::::get(), max); - - // Decrement saturates: - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, max)); - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 123)); - assert_eq!(pallet_balances::TotalIssuance::::get(), 0); - }); -} - -#[test] -fn force_adjust_total_issuance_rejects_zero_delta() { - ExtBuilder::default().build_and_execute_with(|| { - assert_noop!( - Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 0), - Error::::DeltaZero, - ); - assert_noop!( - Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 0), - Error::::DeltaZero, - ); - }); -} - -#[test] -fn force_adjust_total_issuance_rejects_more_than_inactive() { - ExtBuilder::default().build_and_execute_with(|| { - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), 1337, 64)); - Balances::deactivate(16u32.into()); - - assert_eq!(pallet_balances::TotalIssuance::::get(), 64); - assert_eq!(Balances::active_issuance(), 48); - - // Works with up to 48: - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 40),); - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 8),); - assert_eq!(pallet_balances::TotalIssuance::::get(), 16); - assert_eq!(Balances::active_issuance(), 0); - // Errors with more than 48: - assert_noop!( - Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Dec, 1), - Error::::IssuanceDeactivated, - ); - // Increasing again increases the inactive issuance: - assert_ok!(Balances::force_adjust_total_issuance(RawOrigin::Root.into(), Inc, 10),); - assert_eq!(pallet_balances::TotalIssuance::::get(), 26); - assert_eq!(Balances::active_issuance(), 10); - }); -} - -#[test] -fn burn_works() { - ExtBuilder::default().build().execute_with(|| { - // Prepare account with initial balance - let (account, init_balance) = (1, 37); - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), account, init_balance)); - let init_issuance = pallet_balances::TotalIssuance::::get(); - let (keep_alive, allow_death) = (true, false); - - // 1. Cannot burn more than what's available - assert_noop!( - Balances::burn(Some(account).into(), init_balance + 1, allow_death), - TokenError::FundsUnavailable, - ); - - // 2. Burn some funds, without reaping the account - let burn_amount_1 = 1; - assert_ok!(Balances::burn(Some(account).into(), burn_amount_1, allow_death)); - System::assert_last_event(RuntimeEvent::Balances(Event::Burned { - who: account, - amount: burn_amount_1, - })); - assert_eq!(pallet_balances::TotalIssuance::::get(), init_issuance - burn_amount_1); - assert_eq!(Balances::total_balance(&account), init_balance - burn_amount_1); - - // 3. Cannot burn funds below existential deposit if `keep_alive` is `true` - let burn_amount_2 = - init_balance - burn_amount_1 - ::ExistentialDeposit::get() + 1; - assert_noop!( - Balances::burn(Some(account).into(), init_balance + 1, keep_alive), - TokenError::FundsUnavailable, - ); - - // 4. Burn some more funds, this time reaping the account - assert_ok!(Balances::burn(Some(account).into(), burn_amount_2, allow_death)); - System::assert_last_event(RuntimeEvent::Balances(Event::Burned { - who: account, - amount: burn_amount_2, - })); - assert_eq!( - pallet_balances::TotalIssuance::::get(), - init_issuance - burn_amount_1 - burn_amount_2 - ); - assert!(Balances::total_balance(&account).is_zero()); - }); -} diff --git a/pallets/balances/src/tests/fungible_conformance_tests.rs b/pallets/balances/src/tests/fungible_conformance_tests.rs deleted file mode 100644 index 5c0c19a55..000000000 --- a/pallets/balances/src/tests/fungible_conformance_tests.rs +++ /dev/null @@ -1,141 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use super::*; -use frame_support::traits::fungible::{conformance_tests, Inspect, Mutate}; -use paste::paste; - -macro_rules! generate_tests { - // Handle a conformance test that requires special testing with and without a dust trap. - (dust_trap_variation, $base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { - $( - paste! { - #[test] - fn [<$trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_on >]() { - // Some random trap account. - let trap_account = ::AccountId::from(65174286u64); - let builder = ExtBuilder::default().existential_deposit($ext_deposit).dust_trap(trap_account); - builder.build_and_execute_with(|| { - Balances::set_balance(&trap_account, Balances::minimum_balance()); - $base_path::$scope::$trait::$test_name::< - Balances, - ::AccountId, - >(Some(trap_account)); - }); - } - - #[test] - fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_off >]() { - let builder = ExtBuilder::default().existential_deposit($ext_deposit); - builder.build_and_execute_with(|| { - $base_path::$scope::$trait::$test_name::< - Balances, - ::AccountId, - >(None); - }); - } - } - )* - }; - // Regular conformance test - ($base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { - $( - paste! { - #[test] - fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit>]() { - let builder = ExtBuilder::default().existential_deposit($ext_deposit); - builder.build_and_execute_with(|| { - $base_path::$scope::$trait::$test_name::< - Balances, - ::AccountId, - >(); - }); - } - } - )* - }; - ($base_path:path, $ext_deposit:expr) => { - // regular::mutate - generate_tests!( - dust_trap_variation, - $base_path, - regular, - mutate, - $ext_deposit, - transfer_expendable_dust - ); - generate_tests!( - $base_path, - regular, - mutate, - $ext_deposit, - mint_into_success, - mint_into_overflow, - mint_into_below_minimum, - burn_from_exact_success, - burn_from_best_effort_success, - burn_from_exact_insufficient_funds, - restore_success, - restore_overflow, - restore_below_minimum, - shelve_success, - shelve_insufficient_funds, - transfer_success, - transfer_expendable_all, - transfer_protect_preserve, - set_balance_mint_success, - set_balance_burn_success, - can_deposit_success, - can_deposit_below_minimum, - can_deposit_overflow, - can_withdraw_success, - can_withdraw_reduced_to_zero, - can_withdraw_balance_low, - reducible_balance_expendable, - reducible_balance_protect_preserve - ); - // regular::unbalanced - generate_tests!( - $base_path, - regular, - unbalanced, - $ext_deposit, - write_balance, - decrease_balance_expendable, - decrease_balance_preserve, - increase_balance, - set_total_issuance, - deactivate_and_reactivate - ); - // regular::balanced - generate_tests!( - $base_path, - regular, - balanced, - $ext_deposit, - issue_and_resolve_credit, - rescind_and_settle_debt, - deposit, - withdraw, - pair - ); - }; -} - -generate_tests!(conformance_tests, 1); -generate_tests!(conformance_tests, 5); -generate_tests!(conformance_tests, 1000); diff --git a/pallets/balances/src/tests/fungible_tests.rs b/pallets/balances/src/tests/fungible_tests.rs deleted file mode 100644 index 4a8b213c6..000000000 --- a/pallets/balances/src/tests/fungible_tests.rs +++ /dev/null @@ -1,670 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Tests regarding the functionality of the `fungible` trait set implementations. - -use super::*; -use frame_support::traits::{ - tokens::{ - Fortitude::{Force, Polite}, - Precision::{BestEffort, Exact}, - Preservation::{Expendable, Preserve, Protect}, - Restriction::Free, - }, - Consideration, Footprint, LinearStoragePrice, MaybeConsideration, -}; -use fungible::{ - FreezeConsideration, HoldConsideration, Inspect, InspectFreeze, InspectHold, - LoneFreezeConsideration, LoneHoldConsideration, Mutate, MutateFreeze, MutateHold, Unbalanced, -}; -use sp_core::ConstU64; - -#[test] -fn inspect_trait_reducible_balance_basic_works() { - ExtBuilder::default().existential_deposit(10).build_and_execute_with(|| { - Balances::set_balance(&1, 100); - assert_eq!(Balances::reducible_balance(&1, Expendable, Polite), 100); - assert_eq!(Balances::reducible_balance(&1, Protect, Polite), 90); - assert_eq!(Balances::reducible_balance(&1, Preserve, Polite), 90); - assert_eq!(Balances::reducible_balance(&1, Expendable, Force), 100); - assert_eq!(Balances::reducible_balance(&1, Protect, Force), 90); - assert_eq!(Balances::reducible_balance(&1, Preserve, Force), 90); - }); -} - -#[test] -fn inspect_trait_reducible_balance_other_provide_works() { - ExtBuilder::default().existential_deposit(10).build_and_execute_with(|| { - Balances::set_balance(&1, 100); - System::inc_providers(&1); - assert_eq!(Balances::reducible_balance(&1, Expendable, Polite), 100); - assert_eq!(Balances::reducible_balance(&1, Protect, Polite), 100); - assert_eq!(Balances::reducible_balance(&1, Preserve, Polite), 90); - assert_eq!(Balances::reducible_balance(&1, Expendable, Force), 100); - assert_eq!(Balances::reducible_balance(&1, Protect, Force), 100); - assert_eq!(Balances::reducible_balance(&1, Preserve, Force), 90); - }); -} - -#[test] -fn inspect_trait_reducible_balance_frozen_works() { - ExtBuilder::default().existential_deposit(10).build_and_execute_with(|| { - Balances::set_balance(&1, 100); - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 50)); - assert_eq!(Balances::reducible_balance(&1, Expendable, Polite), 50); - assert_eq!(Balances::reducible_balance(&1, Protect, Polite), 50); - assert_eq!(Balances::reducible_balance(&1, Preserve, Polite), 50); - assert_eq!(Balances::reducible_balance(&1, Expendable, Force), 90); - assert_eq!(Balances::reducible_balance(&1, Protect, Force), 90); - assert_eq!(Balances::reducible_balance(&1, Preserve, Force), 90); - }); -} - -#[test] -fn unbalanced_trait_set_balance_works() { - ExtBuilder::default().build_and_execute_with(|| { - assert_eq!(>::balance(&1337), 0); - assert_ok!(Balances::write_balance(&1337, 100)); - assert_eq!(>::balance(&1337), 100); - - assert_ok!(>::hold(&TestId::Foo, &1337, 60)); - assert_eq!(>::balance(&1337), 40); - assert_eq!(>::total_balance_on_hold(&1337), 60); - assert_eq!( - >::balance_on_hold(&TestId::Foo, &1337), - 60 - ); - - assert_noop!(Balances::write_balance(&1337, 0), Error::::InsufficientBalance); - - assert_ok!(Balances::write_balance(&1337, 1)); - assert_eq!(>::balance(&1337), 1); - assert_eq!( - >::balance_on_hold(&TestId::Foo, &1337), - 60 - ); - - assert_ok!(>::release(&TestId::Foo, &1337, 60, Exact)); - assert_eq!(>::balance_on_hold(&TestId::Foo, &1337), 0); - assert_eq!(>::total_balance_on_hold(&1337), 0); - }); -} - -#[test] -fn unbalanced_trait_set_total_issuance_works() { - ExtBuilder::default().build_and_execute_with(|| { - assert_eq!(>::total_issuance(), 0); - Balances::set_total_issuance(100); - assert_eq!(>::total_issuance(), 100); - }); -} - -#[test] -fn unbalanced_trait_decrease_balance_simple_works() { - ExtBuilder::default().build_and_execute_with(|| { - // An Account that starts at 100 - assert_ok!(Balances::write_balance(&1337, 100)); - assert_eq!(>::balance(&1337), 100); - // and reserves 50 - assert_ok!(>::hold(&TestId::Foo, &1337, 50)); - assert_eq!(>::balance(&1337), 50); - // and is decreased by 20 - assert_ok!(Balances::decrease_balance(&1337, 20, Exact, Expendable, Polite)); - assert_eq!(>::balance(&1337), 30); - }); -} - -#[test] -fn unbalanced_trait_decrease_balance_works_1() { - ExtBuilder::default().build_and_execute_with(|| { - assert_ok!(Balances::write_balance(&1337, 100)); - assert_eq!(>::balance(&1337), 100); - - assert_noop!( - Balances::decrease_balance(&1337, 101, Exact, Expendable, Polite), - TokenError::FundsUnavailable - ); - assert_eq!(Balances::decrease_balance(&1337, 100, Exact, Expendable, Polite), Ok(100)); - assert_eq!(>::balance(&1337), 0); - }); -} - -#[test] -fn unbalanced_trait_decrease_balance_works_2() { - ExtBuilder::default().build_and_execute_with(|| { - // free: 40, reserved: 60 - assert_ok!(Balances::write_balance(&1337, 100)); - assert_ok!(Balances::hold(&TestId::Foo, &1337, 60)); - assert_eq!(>::balance(&1337), 40); - assert_eq!(Balances::total_balance_on_hold(&1337), 60); - assert_noop!( - Balances::decrease_balance(&1337, 40, Exact, Expendable, Polite), - TokenError::FundsUnavailable - ); - assert_eq!(Balances::decrease_balance(&1337, 39, Exact, Expendable, Polite), Ok(39)); - assert_eq!(>::balance(&1337), 1); - assert_eq!(Balances::total_balance_on_hold(&1337), 60); - }); -} - -#[test] -fn unbalanced_trait_decrease_balance_at_most_works_1() { - ExtBuilder::default().build_and_execute_with(|| { - assert_ok!(Balances::write_balance(&1337, 100)); - assert_eq!(>::balance(&1337), 100); - - assert_eq!(Balances::decrease_balance(&1337, 101, BestEffort, Expendable, Polite), Ok(100)); - assert_eq!(>::balance(&1337), 0); - }); -} - -#[test] -fn unbalanced_trait_decrease_balance_at_most_works_2() { - ExtBuilder::default().build_and_execute_with(|| { - assert_ok!(Balances::write_balance(&1337, 99)); - assert_eq!(Balances::decrease_balance(&1337, 99, BestEffort, Expendable, Polite), Ok(99)); - assert_eq!(>::balance(&1337), 0); - }); -} - -#[test] -fn unbalanced_trait_decrease_balance_at_most_works_3() { - ExtBuilder::default().build_and_execute_with(|| { - // free: 40, reserved: 60 - assert_ok!(Balances::write_balance(&1337, 100)); - assert_ok!(Balances::hold(&TestId::Foo, &1337, 60)); - assert_eq!(Balances::free_balance(1337), 40); - assert_eq!(Balances::total_balance_on_hold(&1337), 60); - assert_eq!(Balances::decrease_balance(&1337, 0, BestEffort, Expendable, Polite), Ok(0)); - assert_eq!(Balances::free_balance(1337), 40); - assert_eq!(Balances::total_balance_on_hold(&1337), 60); - assert_eq!(Balances::decrease_balance(&1337, 10, BestEffort, Expendable, Polite), Ok(10)); - assert_eq!(Balances::free_balance(1337), 30); - assert_eq!(Balances::decrease_balance(&1337, 200, BestEffort, Expendable, Polite), Ok(29)); - assert_eq!(>::balance(&1337), 1); - assert_eq!(Balances::free_balance(1337), 1); - assert_eq!(Balances::total_balance_on_hold(&1337), 60); - }); -} - -#[test] -fn unbalanced_trait_increase_balance_works() { - ExtBuilder::default().build_and_execute_with(|| { - assert_noop!(Balances::increase_balance(&1337, 0, Exact), TokenError::BelowMinimum); - assert_eq!(Balances::increase_balance(&1337, 1, Exact), Ok(1)); - assert_noop!(Balances::increase_balance(&1337, u64::MAX, Exact), ArithmeticError::Overflow); - }); -} - -#[test] -fn unbalanced_trait_increase_balance_at_most_works() { - ExtBuilder::default().build_and_execute_with(|| { - assert_eq!(Balances::increase_balance(&1337, 0, BestEffort), Ok(0)); - assert_eq!(Balances::increase_balance(&1337, 1, BestEffort), Ok(1)); - assert_eq!(Balances::increase_balance(&1337, u64::MAX, BestEffort), Ok(u64::MAX - 1)); - }); -} - -#[test] -fn freezing_and_holds_should_overlap() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); - assert_ok!(Balances::hold(&TestId::Foo, &1, 9)); - assert_eq!(Balances::account(&1).free, 1); - assert_eq!(System::consumers(&1), 1); - assert_eq!(Balances::account(&1).free, 1); - assert_eq!(Balances::account(&1).frozen, 10); - assert_eq!(Balances::account(&1).reserved, 9); - assert_eq!(Balances::total_balance_on_hold(&1), 9); - }); -} - -#[test] -fn frozen_hold_balance_cannot_be_moved_without_force() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); - assert_ok!(Balances::hold(&TestId::Foo, &1, 9)); - assert_eq!(Balances::reducible_total_balance_on_hold(&1, Force), 9); - assert_eq!(Balances::reducible_total_balance_on_hold(&1, Polite), 0); - let e = TokenError::Frozen; - assert_noop!( - Balances::transfer_on_hold(&TestId::Foo, &1, &2, 1, Exact, Free, Polite), - e - ); - assert_ok!(Balances::transfer_on_hold(&TestId::Foo, &1, &2, 1, Exact, Free, Force)); - }); -} - -#[test] -fn frozen_hold_balance_best_effort_transfer_works() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); - assert_ok!(Balances::hold(&TestId::Foo, &1, 9)); - assert_eq!(Balances::reducible_total_balance_on_hold(&1, Force), 9); - assert_eq!(Balances::reducible_total_balance_on_hold(&1, Polite), 5); - assert_ok!(Balances::transfer_on_hold( - &TestId::Foo, - &1, - &2, - 10, - BestEffort, - Free, - Polite - )); - assert_eq!(Balances::total_balance(&1), 5); - assert_eq!(Balances::total_balance(&2), 25); - }); -} - -#[test] -fn partial_freezing_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); - assert_eq!(System::consumers(&1), 1); - assert_ok!(>::transfer(&1, &2, 5, Expendable)); - assert_noop!( - >::transfer(&1, &2, 1, Expendable), - TokenError::Frozen - ); - }); -} - -#[test] -fn thaw_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, u64::MAX)); - assert_ok!(Balances::thaw(&TestId::Foo, &1)); - assert_eq!(System::consumers(&1), 0); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &1), 0); - assert_eq!(Balances::account(&1).frozen, 0); - assert_ok!(>::transfer(&1, &2, 10, Expendable)); - }); -} - -#[test] -fn set_freeze_zero_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, u64::MAX)); - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 0)); - assert_eq!(System::consumers(&1), 0); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &1), 0); - assert_eq!(Balances::account(&1).frozen, 0); - assert_ok!(>::transfer(&1, &2, 10, Expendable)); - }); -} - -#[test] -fn set_freeze_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, u64::MAX)); - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); - assert_ok!(>::transfer(&1, &2, 5, Expendable)); - assert_noop!( - >::transfer(&1, &2, 1, Expendable), - TokenError::Frozen - ); - }); -} - -#[test] -fn extend_freeze_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); - assert_ok!(Balances::extend_freeze(&TestId::Foo, &1, 10)); - assert_eq!(Balances::account(&1).frozen, 10); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &1), 10); - assert_noop!( - >::transfer(&1, &2, 1, Expendable), - TokenError::Frozen - ); - }); -} - -#[test] -fn double_freezing_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 5)); - assert_ok!(Balances::set_freeze(&TestId::Bar, &1, 5)); - assert_eq!(System::consumers(&1), 1); - assert_ok!(>::transfer(&1, &2, 5, Expendable)); - assert_noop!( - >::transfer(&1, &2, 1, Expendable), - TokenError::Frozen - ); - }); -} - -#[test] -fn can_hold_entire_balance_when_second_provider() { - ExtBuilder::default() - .existential_deposit(1) - .monied(false) - .build_and_execute_with(|| { - >::set_balance(&1, 100); - assert_noop!(Balances::hold(&TestId::Foo, &1, 100), TokenError::FundsUnavailable); - System::inc_providers(&1); - assert_eq!(System::providers(&1), 2); - assert_ok!(Balances::hold(&TestId::Foo, &1, 100)); - assert_eq!(System::providers(&1), 1); - assert_noop!(System::dec_providers(&1), DispatchError::ConsumerRemaining); - }); -} - -#[test] -fn unholding_frees_hold_slot() { - ExtBuilder::default() - .existential_deposit(1) - .monied(false) - .build_and_execute_with(|| { - >::set_balance(&1, 100); - assert_ok!(Balances::hold(&TestId::Foo, &1, 10)); - assert_ok!(Balances::hold(&TestId::Bar, &1, 10)); - assert_ok!(Balances::release(&TestId::Foo, &1, 10, Exact)); - assert_ok!(Balances::hold(&TestId::Baz, &1, 10)); - }); -} - -#[test] -fn sufficients_work_properly_with_reference_counting() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - // Only run PoC when the system pallet is enabled, since the underlying bug is in the - // system pallet it won't work with BalancesAccountStore - if UseSystem::get() { - // Start with a balance of 100 - >::set_balance(&1, 100); - // Emulate a sufficient, in reality this could be reached by transferring a - // sufficient asset to the account - System::inc_sufficients(&1); - // Spend the same balance multiple times - assert_ok!(>::transfer(&1, &1337, 100, Expendable)); - assert_eq!(Balances::free_balance(&1), 0); - assert_noop!( - >::transfer(&1, &1337, 100, Expendable), - TokenError::FundsUnavailable - ); - } - }); -} - -#[test] -fn emit_events_with_changing_freezes() { - ExtBuilder::default().build_and_execute_with(|| { - let _ = Balances::set_balance(&1, 100); - System::reset_events(); - - // Freeze = [] --> [10] - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Frozen { who: 1, amount: 10 })]); - - // Freeze = [10] --> [15] - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 15)); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Frozen { who: 1, amount: 5 })]); - - // Freeze = [15] --> [15, 20] - assert_ok!(Balances::set_freeze(&TestId::Bar, &1, 20)); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Frozen { who: 1, amount: 5 })]); - - // Freeze = [15, 20] --> [17, 20] - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 17)); - for event in events() { - match event { - RuntimeEvent::Balances(crate::Event::Frozen { .. }) => { - assert!(false, "unexpected freeze event") - }, - RuntimeEvent::Balances(crate::Event::Thawed { .. }) => { - assert!(false, "unexpected thaw event") - }, - _ => continue, - } - } - - // Freeze = [17, 20] --> [17, 15] - assert_ok!(Balances::set_freeze(&TestId::Bar, &1, 15)); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Thawed { who: 1, amount: 3 })]); - - // Freeze = [17, 15] --> [15] - assert_ok!(Balances::thaw(&TestId::Foo, &1)); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Thawed { who: 1, amount: 2 })]); - - // Freeze = [15] --> [] - assert_ok!(Balances::thaw(&TestId::Bar, &1)); - assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Thawed { who: 1, amount: 15 })]); - }); -} - -#[test] -fn withdraw_precision_exact_works() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); - assert_eq!(Balances::account(&1).free, 10); - assert_eq!(Balances::account(&1).frozen, 10); - - // `BestEffort` will not reduce anything - assert_ok!(>::withdraw( - &1, 5, BestEffort, Preserve, Polite - )); - - assert_eq!(Balances::account(&1).free, 10); - assert_eq!(Balances::account(&1).frozen, 10); - - assert_noop!( - >::withdraw(&1, 5, Exact, Preserve, Polite), - TokenError::FundsUnavailable - ); - }); -} - -#[test] -fn freeze_consideration_works() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - type Consideration = FreezeConsideration< - u64, - Balances, - FooReason, - LinearStoragePrice, ConstU64<1>, u64>, - Footprint, - >; - - let who = 4; - // freeze amount taken somewhere outside of our (Consideration) scope. - let extend_freeze = 15; - - let ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); - assert!(ticket.is_none()); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); - - let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10); - - let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 4); - - assert_ok!(Balances::increase_frozen(&TestId::Foo, &who, extend_freeze)); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 4 + extend_freeze); - - let ticket = ticket.update(&who, Footprint::from_parts(8, 1)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 8 + extend_freeze); - - let ticket = ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(); - assert!(ticket.is_none()); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0 + extend_freeze); - - let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10 + extend_freeze); - - let _ = ticket.drop(&who).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0 + extend_freeze); - }); -} - -#[test] -fn hold_consideration_works() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - type Consideration = HoldConsideration< - u64, - Balances, - FooReason, - LinearStoragePrice, ConstU64<1>, u64>, - Footprint, - >; - - let who = 4; - // hold amount taken somewhere outside of our (Consideration) scope. - let extend_hold = 15; - - let ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); - assert!(ticket.is_none()); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); - - let ticket = ticket.update(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10); - - let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 4); - - assert_ok!(Balances::hold(&TestId::Foo, &who, extend_hold)); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 4 + extend_hold); - - let ticket = ticket.update(&who, Footprint::from_parts(8, 1)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 8 + extend_hold); - - let ticket = ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(); - assert!(ticket.is_none()); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0 + extend_hold); - - let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10 + extend_hold); - - let _ = ticket.drop(&who).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0 + extend_hold); - }); -} - -#[test] -fn lone_freeze_consideration_works() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - type Consideration = LoneFreezeConsideration< - u64, - Balances, - FooReason, - LinearStoragePrice, ConstU64<1>, u64>, - Footprint, - >; - - let who = 4; - let zero_ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); - - let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10); - - assert_ok!(Balances::increase_frozen(&TestId::Foo, &who, 5)); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 15); - - let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 4); - - assert_eq!(ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(), zero_ticket); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); - - let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 10); - - let _ = ticket.drop(&who).unwrap(); - assert_eq!(Balances::balance_frozen(&TestId::Foo, &who), 0); - }); -} - -#[test] -fn lone_hold_consideration_works() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build_and_execute_with(|| { - type Consideration = LoneHoldConsideration< - u64, - Balances, - FooReason, - LinearStoragePrice, ConstU64<1>, u64>, - Footprint, - >; - - let who = 4; - let zero_ticket = Consideration::new(&who, Footprint::from_parts(0, 0)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); - - let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10); - - assert_ok!(Balances::hold(&TestId::Foo, &who, 5)); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 15); - - let ticket = ticket.update(&who, Footprint::from_parts(4, 1)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 4); - - assert_eq!(ticket.update(&who, Footprint::from_parts(0, 0)).unwrap(), zero_ticket); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); - - let ticket = Consideration::new(&who, Footprint::from_parts(10, 1)).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 10); - - let _ = ticket.drop(&who).unwrap(); - assert_eq!(Balances::balance_on_hold(&TestId::Foo, &who), 0); - }); -} diff --git a/pallets/balances/src/tests/general_tests.rs b/pallets/balances/src/tests/general_tests.rs deleted file mode 100644 index a855fae56..000000000 --- a/pallets/balances/src/tests/general_tests.rs +++ /dev/null @@ -1,143 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#![cfg(test)] - -use crate::{ - system::AccountInfo, - tests::{ensure_ti_valid, Balances, ExtBuilder, System, Test, TestId, UseSystem}, - AccountData, ExtraFlags, TotalIssuance, -}; -use frame_support::{ - assert_noop, assert_ok, hypothetically, - traits::{ - fungible::{Mutate, MutateHold}, - tokens::Precision, - }, -}; -use sp_runtime::DispatchError; - -/// There are some accounts that have one consumer ref too few. These accounts are at risk of losing -/// their held (reserved) balance. They do not just lose it - it is also not accounted for in the -/// Total Issuance. Here we test the case that the account does not reap in such a case, but gets -/// one consumer ref for its reserved balance. -#[test] -fn regression_historic_acc_does_not_evaporate_reserve() { - ExtBuilder::default().build_and_execute_with(|| { - UseSystem::set(true); - let (alice, bob) = (0, 1); - // Alice is in a bad state with consumer == 0 && reserved > 0: - Balances::set_balance(&alice, 100); - TotalIssuance::::put(100); - ensure_ti_valid(); - - assert_ok!(Balances::hold(&TestId::Foo, &alice, 10)); - // This is the issue of the account: - System::dec_consumers(&alice); - - assert_eq!( - System::account(&alice), - AccountInfo { - data: AccountData { - free: 90, - reserved: 10, - frozen: 0, - flags: ExtraFlags(1u128 << 127), - }, - nonce: 0, - consumers: 0, // should be 1 on a good acc - providers: 1, - sufficients: 0, - } - ); - - ensure_ti_valid(); - - // Reaping the account is prevented by the new logic: - assert_noop!( - Balances::transfer_allow_death(Some(alice).into(), bob, 90), - DispatchError::ConsumerRemaining - ); - assert_noop!( - Balances::transfer_all(Some(alice).into(), bob, false), - DispatchError::ConsumerRemaining - ); - - // normal transfers still work: - hypothetically!({ - assert_ok!(Balances::transfer_keep_alive(Some(alice).into(), bob, 40)); - // Alice got back her consumer ref: - assert_eq!(System::consumers(&alice), 1); - ensure_ti_valid(); - }); - hypothetically!({ - assert_ok!(Balances::transfer_all(Some(alice).into(), bob, true)); - // Alice got back her consumer ref: - assert_eq!(System::consumers(&alice), 1); - ensure_ti_valid(); - }); - - // un-reserving all does not add a consumer ref: - hypothetically!({ - assert_ok!(Balances::release(&TestId::Foo, &alice, 10, Precision::Exact)); - assert_eq!(System::consumers(&alice), 0); - assert_ok!(Balances::transfer_keep_alive(Some(alice).into(), bob, 40)); - assert_eq!(System::consumers(&alice), 0); - ensure_ti_valid(); - }); - // un-reserving some does add a consumer ref: - hypothetically!({ - assert_ok!(Balances::release(&TestId::Foo, &alice, 5, Precision::Exact)); - assert_eq!(System::consumers(&alice), 1); - assert_ok!(Balances::transfer_keep_alive(Some(alice).into(), bob, 40)); - assert_eq!(System::consumers(&alice), 1); - ensure_ti_valid(); - }); - }); -} - -#[cfg(feature = "try-runtime")] -#[test] -fn try_state_works() { - use crate::{Config, Freezes, Holds}; - use frame_support::{ - storage, - traits::{Get, Hooks, VariantCount}, - }; - - ExtBuilder::default().build_and_execute_with(|| { - storage::unhashed::put( - &Holds::::hashed_key_for(1), - &vec![0u8; ::RuntimeHoldReason::VARIANT_COUNT as usize + 1], - ); - - assert!(format!("{:?}", Balances::try_state(0).unwrap_err()) - .contains("Found `Hold` with too many elements")); - }); - - ExtBuilder::default().build_and_execute_with(|| { - let max_freezes: u32 = ::MaxFreezes::get(); - - storage::unhashed::put( - &Freezes::::hashed_key_for(1), - &vec![0u8; max_freezes as usize + 1], - ); - - assert!(format!("{:?}", Balances::try_state(0).unwrap_err()) - .contains("Found `Freeze` with too many elements")); - }); -} diff --git a/pallets/balances/src/tests/mod.rs b/pallets/balances/src/tests/mod.rs deleted file mode 100644 index d27d99758..000000000 --- a/pallets/balances/src/tests/mod.rs +++ /dev/null @@ -1,351 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Tests. - -#![cfg(test)] - -use crate::{ - self as pallet_balances, AccountData, Config, CreditOf, Error, Pallet, TotalIssuance, - DEFAULT_ADDRESS_URI, -}; -use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen}; -use frame_support::{ - assert_err, assert_noop, assert_ok, assert_storage_noop, derive_impl, - dispatch::{DispatchInfo, GetDispatchInfo}, - parameter_types, - traits::{ - fungible, ConstU32, ConstU8, Imbalance as ImbalanceT, OnUnbalanced, StorageMapShim, - StoredMap, VariantCount, VariantCountOf, WhitelistedStorageKeys, - }, - weights::{IdentityFee, Weight}, -}; -use frame_system::{self as system, RawOrigin}; -use pallet_transaction_payment::{ChargeTransactionPayment, FungibleAdapter, Multiplier}; -use scale_info::TypeInfo; -use sp_core::{hexdisplay::HexDisplay, sr25519::Pair as SrPair, Pair}; -use sp_io; -use sp_runtime::{ - traits::{BadOrigin, Zero}, - ArithmeticError, BuildStorage, DispatchError, DispatchResult, FixedPointNumber, RuntimeDebug, - TokenError, -}; -use std::collections::BTreeSet; - -mod currency_tests; -mod dispatchable_tests; -mod fungible_conformance_tests; -mod fungible_tests; -mod general_tests; -mod reentrancy_tests; - -type Block = frame_system::mocking::MockBlock; - -#[derive( - Encode, - Decode, - DecodeWithMemTracking, - Copy, - Clone, - Eq, - PartialEq, - Ord, - PartialOrd, - MaxEncodedLen, - TypeInfo, - RuntimeDebug, -)] -pub enum TestId { - Foo, - Bar, - Baz, -} - -impl VariantCount for TestId { - const VARIANT_COUNT: u32 = 3; -} - -frame_support::construct_runtime!( - pub enum Test { - System: frame_system, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - } -); - -parameter_types! { - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max( - frame_support::weights::Weight::from_parts(1024, u64::MAX), - ); - pub static ExistentialDeposit: u64 = 1; -} - -#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] -impl frame_system::Config for Test { - type Block = Block; - type AccountData = super::AccountData; -} - -#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig)] -impl pallet_transaction_payment::Config for Test { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = FungibleAdapter, ()>; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type LengthToFee = IdentityFee; -} - -parameter_types! { - pub FooReason: TestId = TestId::Foo; -} - -#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] -impl Config for Test { - type DustRemoval = DustTrap; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = TestAccountStore; - type MaxReserves = ConstU32<2>; - type ReserveIdentifier = TestId; - type RuntimeHoldReason = TestId; - type RuntimeFreezeReason = TestId; - type FreezeIdentifier = TestId; - type MaxFreezes = VariantCountOf; -} - -#[derive(Clone)] -pub struct ExtBuilder { - existential_deposit: u64, - monied: bool, - dust_trap: Option, -} -impl Default for ExtBuilder { - fn default() -> Self { - Self { existential_deposit: 1, monied: false, dust_trap: None } - } -} -impl ExtBuilder { - pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { - self.existential_deposit = existential_deposit; - self - } - pub fn monied(mut self, monied: bool) -> Self { - self.monied = monied; - if self.existential_deposit == 0 { - self.existential_deposit = 1; - } - self - } - pub fn dust_trap(mut self, account: u64) -> Self { - self.dust_trap = Some(account); - self - } - pub fn set_associated_consts(&self) { - DUST_TRAP_TARGET.with(|v| v.replace(self.dust_trap)); - EXISTENTIAL_DEPOSIT.with(|v| v.replace(self.existential_deposit)); - } - pub fn build(self) -> sp_io::TestExternalities { - self.set_associated_consts(); - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { - balances: if self.monied { - vec![ - (1, 10 * self.existential_deposit), - (2, 20 * self.existential_deposit), - (3, 30 * self.existential_deposit), - (4, 40 * self.existential_deposit), - (12, 10 * self.existential_deposit), - ] - } else { - vec![] - }, - dev_accounts: Some(( - 1000, - self.existential_deposit, - Some(DEFAULT_ADDRESS_URI.to_string()), - )), - } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - pub fn build_and_execute_with(self, f: impl Fn()) { - let other = self.clone(); - UseSystem::set(false); - other.build().execute_with(|| f()); - UseSystem::set(true); - self.build().execute_with(|| f()); - } -} - -parameter_types! { - static DustTrapTarget: Option = None; -} - -pub struct DustTrap; - -impl OnUnbalanced> for DustTrap { - fn on_nonzero_unbalanced(amount: CreditOf) { - match DustTrapTarget::get() { - None => drop(amount), - Some(a) => { - let result = >::resolve(&a, amount); - debug_assert!(result.is_ok()); - }, - } - } -} - -parameter_types! { - pub static UseSystem: bool = false; -} - -type BalancesAccountStore = StorageMapShim, u64, super::AccountData>; -type SystemAccountStore = frame_system::Pallet; - -pub struct TestAccountStore; -impl StoredMap> for TestAccountStore { - fn get(k: &u64) -> super::AccountData { - if UseSystem::get() { - >::get(k) - } else { - >::get(k) - } - } - fn try_mutate_exists>( - k: &u64, - f: impl FnOnce(&mut Option>) -> Result, - ) -> Result { - if UseSystem::get() { - >::try_mutate_exists(k, f) - } else { - >::try_mutate_exists(k, f) - } - } - fn mutate( - k: &u64, - f: impl FnOnce(&mut super::AccountData) -> R, - ) -> Result { - if UseSystem::get() { - >::mutate(k, f) - } else { - >::mutate(k, f) - } - } - fn mutate_exists( - k: &u64, - f: impl FnOnce(&mut Option>) -> R, - ) -> Result { - if UseSystem::get() { - >::mutate_exists(k, f) - } else { - >::mutate_exists(k, f) - } - } - fn insert(k: &u64, t: super::AccountData) -> Result<(), DispatchError> { - if UseSystem::get() { - >::insert(k, t) - } else { - >::insert(k, t) - } - } - fn remove(k: &u64) -> Result<(), DispatchError> { - if UseSystem::get() { - >::remove(k) - } else { - >::remove(k) - } - } -} - -pub fn events() -> Vec { - let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); - System::reset_events(); - evt -} - -/// create a transaction info struct from weight. Handy to avoid building the whole struct. -pub fn info_from_weight(w: Weight) -> DispatchInfo { - DispatchInfo { call_weight: w, ..Default::default() } -} - -/// Check that the total-issuance matches the sum of all accounts' total balances. -pub fn ensure_ti_valid() { - let mut sum = 0; - - // Fetch the dev accounts from Account Storage. - let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, DEFAULT_ADDRESS_URI.to_string()); - let (num_accounts, _balance, ref derivation) = dev_accounts; - - // Generate the dev account public keys. - let dev_account_ids: Vec<_> = (0..num_accounts) - .map(|index| { - let derivation_string = derivation.replace("{}", &index.to_string()); - let pair: SrPair = - Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); - ::AccountId::decode( - &mut &pair.public().encode()[..], - ) - .unwrap() - }) - .collect(); - - // Iterate over all account keys (i.e., the account IDs). - for acc in frame_system::Account::::iter_keys() { - // Skip dev accounts by checking if the account is in the dev_account_ids list. - // This also proves dev_accounts exists in storage. - if dev_account_ids.contains(&acc) { - continue; - } - - // Check if we are using the system pallet or some other custom storage for accounts. - if UseSystem::get() { - let data = frame_system::Pallet::::account(acc); - sum += data.data.total(); - } else { - let data = crate::Account::::get(acc); - sum += data.total(); - } - } - - // Ensure the total issuance matches the sum of the account balances - assert_eq!(TotalIssuance::::get(), sum, "Total Issuance is incorrect"); -} - -#[test] -fn weights_sane() { - let info = crate::Call::::transfer_allow_death { dest: 10, value: 4 }.get_dispatch_info(); - assert_eq!(<() as crate::WeightInfo>::transfer_allow_death(), info.call_weight); - - let info = crate::Call::::force_unreserve { who: 10, amount: 4 }.get_dispatch_info(); - assert_eq!(<() as crate::WeightInfo>::force_unreserve(), info.call_weight); -} - -#[test] -fn check_whitelist() { - let whitelist: BTreeSet = AllPalletsWithSystem::whitelisted_storage_keys() - .iter() - .map(|s| HexDisplay::from(&s.key).to_string()) - .collect(); - // Inactive Issuance - assert!(whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f1ccde6872881f893a21de93dfe970cd5")); - // Total Issuance - assert!(whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")); -} diff --git a/pallets/balances/src/tests/reentrancy_tests.rs b/pallets/balances/src/tests/reentrancy_tests.rs deleted file mode 100644 index 0b66f2c93..000000000 --- a/pallets/balances/src/tests/reentrancy_tests.rs +++ /dev/null @@ -1,196 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Tests regarding the reentrancy functionality. - -use super::*; -use frame_support::traits::tokens::{ - Fortitude::Force, - Precision::BestEffort, - Preservation::{Expendable, Protect}, -}; -use fungible::Balanced; - -#[test] -fn transfer_dust_removal_tst1_should_work() { - ExtBuilder::default() - .existential_deposit(100) - .dust_trap(1) - .build_and_execute_with(|| { - // Verification of reentrancy in dust removal - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 1000)); - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 2, 500)); - - // In this transaction, account 2 free balance - // drops below existential balance - // and dust balance is removed from account 2 - assert_ok!(Balances::transfer_allow_death(RawOrigin::Signed(2).into(), 3, 450)); - - // As expected dust balance is removed. - assert_eq!(Balances::free_balance(&2), 0); - - // As expected beneficiary account 3 - // received the transferred fund. - assert_eq!(Balances::free_balance(&3), 450); - - // Dust balance is deposited to account 1 - // during the process of dust removal. - assert_eq!(Balances::free_balance(&1), 1050); - - // Verify the events - assert_eq!(System::events().len(), 14); - - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { - from: 2, - to: 3, - amount: 450, - })); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { - account: 2, - amount: 50, - })); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { - who: 1, - amount: 50, - })); - }); -} - -#[test] -fn transfer_dust_removal_tst2_should_work() { - ExtBuilder::default() - .existential_deposit(100) - .dust_trap(1) - .build_and_execute_with(|| { - // Verification of reentrancy in dust removal - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 1000)); - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 2, 500)); - - // In this transaction, account 2 free balance - // drops below existential balance - // and dust balance is removed from account 2 - assert_ok!(Balances::transfer_allow_death(RawOrigin::Signed(2).into(), 1, 450)); - - // As expected dust balance is removed. - assert_eq!(Balances::free_balance(&2), 0); - - // Dust balance is deposited to account 1 - // during the process of dust removal. - assert_eq!(Balances::free_balance(&1), 1500); - - // Verify the events - assert_eq!(System::events().len(), 12); - - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { - from: 2, - to: 1, - amount: 450, - })); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { - account: 2, - amount: 50, - })); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { - who: 1, - amount: 50, - })); - }); -} - -#[test] -fn repatriating_reserved_balance_dust_removal_should_work() { - ExtBuilder::default() - .existential_deposit(100) - .dust_trap(1) - .build_and_execute_with(|| { - // Verification of reentrancy in dust removal - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 1000)); - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 2, 500)); - - // Reserve a value on account 2, - // Such that free balance is lower than - // Existential deposit. - assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), 1, 450)); - - // Since free balance of account 2 is lower than - // existential deposit, dust amount is - // removed from the account 2 - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::free_balance(2), 0); - - // account 1 is credited with reserved amount - // together with dust balance during dust - // removal. - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(Balances::free_balance(1), 1500); - - // Verify the events - assert_eq!(System::events().len(), 12); - - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Transfer { - from: 2, - to: 1, - amount: 450, - })); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { - account: 2, - amount: 50, - })); - System::assert_has_event(RuntimeEvent::Balances(crate::Event::Deposit { - who: 1, - amount: 50, - })); - }); -} - -#[test] -fn emit_events_with_no_existential_deposit_suicide_with_dust() { - ExtBuilder::default().existential_deposit(2).build_and_execute_with(|| { - assert_ok!(Balances::force_set_balance(RawOrigin::Root.into(), 1, 100)); - - assert_eq!( - events(), - [ - RuntimeEvent::System(system::Event::NewAccount { account: 1 }), - RuntimeEvent::Balances(crate::Event::Endowed { account: 1, free_balance: 100 }), - RuntimeEvent::Balances(crate::Event::Issued { amount: 100 }), - RuntimeEvent::Balances(crate::Event::BalanceSet { who: 1, free: 100 }), - ] - ); - - let res = Balances::withdraw(&1, 98, BestEffort, Protect, Force); - assert_eq!(res.unwrap().peek(), 98); - - // no events - assert_eq!( - events(), - [RuntimeEvent::Balances(crate::Event::Withdraw { who: 1, amount: 98 })] - ); - - let res = Balances::withdraw(&1, 1, BestEffort, Expendable, Force); - assert_eq!(res.unwrap().peek(), 1); - - assert_eq!( - events(), - [ - RuntimeEvent::System(system::Event::KilledAccount { account: 1 }), - RuntimeEvent::Balances(crate::Event::DustLost { account: 1, amount: 1 }), - RuntimeEvent::Balances(crate::Event::Withdraw { who: 1, amount: 1 }) - ] - ); - }); -} diff --git a/pallets/balances/src/types.rs b/pallets/balances/src/types.rs deleted file mode 100644 index 2ec496a66..000000000 --- a/pallets/balances/src/types.rs +++ /dev/null @@ -1,185 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Types used in the pallet. - -use crate::{Config, CreditOf, Event, Pallet}; -use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen}; -use core::ops::BitOr; -use frame_support::traits::{Imbalance, LockIdentifier, OnUnbalanced, WithdrawReasons}; -use scale_info::TypeInfo; -use sp_runtime::{RuntimeDebug, Saturating}; - -/// Simplified reasons for withdrawing balance. -#[derive( - Encode, - Decode, - DecodeWithMemTracking, - Clone, - Copy, - PartialEq, - Eq, - RuntimeDebug, - MaxEncodedLen, - TypeInfo, -)] -pub enum Reasons { - /// Paying system transaction fees. - Fee = 0, - /// Any reason other than paying system transaction fees. - Misc = 1, - /// Any reason at all. - All = 2, -} - -impl From for Reasons { - fn from(r: WithdrawReasons) -> Reasons { - if r == WithdrawReasons::TRANSACTION_PAYMENT { - Reasons::Fee - } else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) { - Reasons::All - } else { - Reasons::Misc - } - } -} - -impl BitOr for Reasons { - type Output = Reasons; - fn bitor(self, other: Reasons) -> Reasons { - if self == other { - return self - } - Reasons::All - } -} - -/// A single lock on a balance. There can be many of these on an account and they "overlap", so the -/// same balance is frozen by multiple locks. -#[derive( - Encode, - Decode, - DecodeWithMemTracking, - Clone, - PartialEq, - Eq, - RuntimeDebug, - MaxEncodedLen, - TypeInfo, -)] -pub struct BalanceLock { - /// An identifier for this lock. Only one lock may be in existence for each identifier. - pub id: LockIdentifier, - /// The amount which the free balance may not drop below when this lock is in effect. - pub amount: Balance, - /// If true, then the lock remains in effect even for payment of transaction fees. - pub reasons: Reasons, -} - -/// Store named reserved balance. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] -pub struct ReserveData { - /// The identifier for the named reserve. - pub id: ReserveIdentifier, - /// The amount of the named reserve. - pub amount: Balance, -} - -/// All balance information for an account. -#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, MaxEncodedLen, TypeInfo)] -pub struct AccountData { - /// Non-reserved part of the balance which the account holder may be able to control. - /// - /// This is the only balance that matters in terms of most operations on tokens. - pub free: Balance, - /// Balance which is has active holds on it and may not be used at all. - /// - /// This is the sum of all individual holds together with any sums still under the (deprecated) - /// reserves API. - pub reserved: Balance, - /// The amount that `free + reserved` may not drop below when reducing the balance, except for - /// actions where the account owner cannot reasonably benefit from the balance reduction, such - /// as slashing. - pub frozen: Balance, - /// Extra information about this account. The MSB is a flag indicating whether the new ref- - /// counting logic is in place for this account. - pub flags: ExtraFlags, -} - -const IS_NEW_LOGIC: u128 = 0x80000000_00000000_00000000_00000000u128; - -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] -pub struct ExtraFlags(pub(crate) u128); -impl Default for ExtraFlags { - fn default() -> Self { - Self(IS_NEW_LOGIC) - } -} -impl ExtraFlags { - pub fn old_logic() -> Self { - Self(0) - } - pub fn set_new_logic(&mut self) { - self.0 = self.0 | IS_NEW_LOGIC - } - pub fn is_new_logic(&self) -> bool { - (self.0 & IS_NEW_LOGIC) == IS_NEW_LOGIC - } -} - -impl AccountData { - pub fn usable(&self) -> Balance { - self.free.saturating_sub(self.frozen) - } - - /// The total balance in this account including any that is reserved and ignoring any frozen. - pub fn total(&self) -> Balance { - self.free.saturating_add(self.reserved) - } -} - -pub struct DustCleaner, I: 'static = ()>( - pub(crate) Option<(T::AccountId, CreditOf)>, -); - -impl, I: 'static> Drop for DustCleaner { - fn drop(&mut self) { - if let Some((who, dust)) = self.0.take() { - Pallet::::deposit_event(Event::DustLost { account: who, amount: dust.peek() }); - T::DustRemoval::on_unbalanced(dust); - } - } -} - -/// Whether something should be interpreted as an increase or a decrease. -#[derive( - Encode, - Decode, - DecodeWithMemTracking, - Clone, - PartialEq, - Eq, - RuntimeDebug, - MaxEncodedLen, - TypeInfo, -)] -pub enum AdjustmentDirection { - /// Increase the amount. - Increase, - /// Decrease the amount. - Decrease, -} diff --git a/pallets/balances/src/weights.rs b/pallets/balances/src/weights.rs deleted file mode 100644 index d5e55460f..000000000 --- a/pallets/balances/src/weights.rs +++ /dev/null @@ -1,321 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Autogenerated weights for `pallet_balances` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `4563561839a5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` - -// Executed Command: -// frame-omni-bencher -// v1 -// benchmark -// pallet -// --extrinsic=* -// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm -// --pallet=pallet_balances -// --header=/__w/polkadot-sdk/polkadot-sdk/substrate/HEADER-APACHE2 -// --output=/__w/polkadot-sdk/polkadot-sdk/substrate/frame/balances/src/weights.rs -// --wasm-execution=compiled -// --steps=50 -// --repeat=20 -// --heap-pages=4096 -// --template=substrate/.maintain/frame-weight-template.hbs -// --no-storage-info -// --no-min-squares -// --no-median-slopes -// --genesis-builder-policy=none -// --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic,pallet_nomination_pools,pallet_remark,pallet_transaction_storage,pallet_election_provider_multi_block,pallet_election_provider_multi_block::signed,pallet_election_provider_multi_block::unsigned,pallet_election_provider_multi_block::verifier - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] -#![allow(dead_code)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -/// Weight functions needed for `pallet_balances`. -pub trait WeightInfo { - fn transfer_allow_death() -> Weight; - fn transfer_keep_alive() -> Weight; - fn force_set_balance_creating() -> Weight; - fn force_set_balance_killing() -> Weight; - fn force_transfer() -> Weight; - fn transfer_all() -> Weight; - fn force_unreserve() -> Weight; - fn upgrade_accounts(u: u32, ) -> Weight; - fn force_adjust_total_issuance() -> Weight; - fn burn_allow_death() -> Weight; - fn burn_keep_alive() -> Weight; -} - -/// Weights for `pallet_balances` using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn transfer_allow_death() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3593` - // Minimum execution time: 48_203_000 picoseconds. - Weight::from_parts(48_834_000, 3593) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn transfer_keep_alive() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3593` - // Minimum execution time: 38_647_000 picoseconds. - Weight::from_parts(39_051_000, 3593) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_set_balance_creating() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3593` - // Minimum execution time: 12_191_000 picoseconds. - Weight::from_parts(12_547_000, 3593) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_set_balance_killing() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3593` - // Minimum execution time: 18_636_000 picoseconds. - Weight::from_parts(19_206_000, 3593) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_transfer() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `6196` - // Minimum execution time: 49_073_000 picoseconds. - Weight::from_parts(49_519_000, 6196) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn transfer_all() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3593` - // Minimum execution time: 47_572_000 picoseconds. - Weight::from_parts(48_209_000, 3593) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_unreserve() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3593` - // Minimum execution time: 15_290_000 picoseconds. - Weight::from_parts(15_515_000, 3593) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:999 w:999) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `u` is `[1, 1000]`. - fn upgrade_accounts(u: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `0 + u * (135 ±0)` - // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 14_546_000 picoseconds. - Weight::from_parts(14_674_000, 990) - // Standard Error: 11_734 - .saturating_add(Weight::from_parts(14_648_188, 0).saturating_mul(u.into())) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) - .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) - } - fn force_adjust_total_issuance() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 5_096_000 picoseconds. - Weight::from_parts(5_351_000, 0) - } - fn burn_allow_death() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 29_641_000 picoseconds. - Weight::from_parts(30_219_000, 0) - } - fn burn_keep_alive() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 20_462_000 picoseconds. - Weight::from_parts(20_720_000, 0) - } -} - -// For backwards compatibility and tests. -impl WeightInfo for () { - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn transfer_allow_death() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3593` - // Minimum execution time: 48_203_000 picoseconds. - Weight::from_parts(48_834_000, 3593) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn transfer_keep_alive() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3593` - // Minimum execution time: 38_647_000 picoseconds. - Weight::from_parts(39_051_000, 3593) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_set_balance_creating() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3593` - // Minimum execution time: 12_191_000 picoseconds. - Weight::from_parts(12_547_000, 3593) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_set_balance_killing() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3593` - // Minimum execution time: 18_636_000 picoseconds. - Weight::from_parts(19_206_000, 3593) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_transfer() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `6196` - // Minimum execution time: 49_073_000 picoseconds. - Weight::from_parts(49_519_000, 6196) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn transfer_all() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3593` - // Minimum execution time: 47_572_000 picoseconds. - Weight::from_parts(48_209_000, 3593) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn force_unreserve() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3593` - // Minimum execution time: 15_290_000 picoseconds. - Weight::from_parts(15_515_000, 3593) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `System::Account` (r:999 w:999) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `u` is `[1, 1000]`. - fn upgrade_accounts(u: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `0 + u * (135 ±0)` - // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 14_546_000 picoseconds. - Weight::from_parts(14_674_000, 990) - // Standard Error: 11_734 - .saturating_add(Weight::from_parts(14_648_188, 0).saturating_mul(u.into())) - .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(u.into()))) - .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(u.into()))) - .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) - } - fn force_adjust_total_issuance() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 5_096_000 picoseconds. - Weight::from_parts(5_351_000, 0) - } - fn burn_allow_death() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 29_641_000 picoseconds. - Weight::from_parts(30_219_000, 0) - } - fn burn_keep_alive() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 20_462_000 picoseconds. - Weight::from_parts(20_720_000, 0) - } -} diff --git a/pallets/circuit-breaker/src/tests/mock.rs b/pallets/circuit-breaker/src/tests/mock.rs index 04316512d..424804e8a 100644 --- a/pallets/circuit-breaker/src/tests/mock.rs +++ b/pallets/circuit-breaker/src/tests/mock.rs @@ -255,6 +255,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_type_with_key! { @@ -864,6 +865,8 @@ impl MutationHooks for Hooks { type PostDeposit = crate::fuses::issuance::IssuanceIncreaseFuse; type PreTransfer = (); type PostTransfer = (); + type PreWithdraw = (); + type PostWithdraw = (); type OnNewTokenAccount = (); type OnKilledTokenAccount = (); } diff --git a/pallets/claims/src/mock.rs b/pallets/claims/src/mock.rs index df5e70a90..9efc8092d 100644 --- a/pallets/claims/src/mock.rs +++ b/pallets/claims/src/mock.rs @@ -96,6 +96,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_types! { diff --git a/pallets/collator-rewards/src/mock.rs b/pallets/collator-rewards/src/mock.rs index 3f10ced65..a5744e10c 100644 --- a/pallets/collator-rewards/src/mock.rs +++ b/pallets/collator-rewards/src/mock.rs @@ -125,6 +125,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_types! { diff --git a/pallets/currencies/src/mock.rs b/pallets/currencies/src/mock.rs index f37c52515..e71e04d29 100644 --- a/pallets/currencies/src/mock.rs +++ b/pallets/currencies/src/mock.rs @@ -68,6 +68,7 @@ impl pallet_balances::Config for Runtime { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_type_with_key! { diff --git a/pallets/dca/src/tests/mock.rs b/pallets/dca/src/tests/mock.rs index 05f55173b..fb925aed1 100644 --- a/pallets/dca/src/tests/mock.rs +++ b/pallets/dca/src/tests/mock.rs @@ -340,6 +340,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } impl pallet_currencies::Config for Test { diff --git a/pallets/democracy/src/tests.rs b/pallets/democracy/src/tests.rs index b259a4193..7a1a77b8a 100644 --- a/pallets/democracy/src/tests.rs +++ b/pallets/democracy/src/tests.rs @@ -165,6 +165,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_types! { pub static PreimageByteDeposit: u64 = 0; diff --git a/pallets/dispenser/src/tests/mod.rs b/pallets/dispenser/src/tests/mod.rs index 28203b3f5..d65361923 100644 --- a/pallets/dispenser/src/tests/mod.rs +++ b/pallets/dispenser/src/tests/mod.rs @@ -104,6 +104,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_types! { diff --git a/pallets/duster/src/mock.rs b/pallets/duster/src/mock.rs index d72536696..2677ba81e 100644 --- a/pallets/duster/src/mock.rs +++ b/pallets/duster/src/mock.rs @@ -238,6 +238,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } pub struct ExtBuilder { diff --git a/pallets/dynamic-evm-fee/src/tests/mock.rs b/pallets/dynamic-evm-fee/src/tests/mock.rs index 09410deb6..22e03d268 100644 --- a/pallets/dynamic-evm-fee/src/tests/mock.rs +++ b/pallets/dynamic-evm-fee/src/tests/mock.rs @@ -204,6 +204,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_types! { diff --git a/pallets/evm-accounts/src/mock.rs b/pallets/evm-accounts/src/mock.rs index bbd7ae9c6..9e6ce7d6d 100644 --- a/pallets/evm-accounts/src/mock.rs +++ b/pallets/evm-accounts/src/mock.rs @@ -164,6 +164,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } impl pallet_currencies::Config for Test { diff --git a/pallets/liquidation/src/tests/mock.rs b/pallets/liquidation/src/tests/mock.rs index 4978bebfc..4fcebaec8 100644 --- a/pallets/liquidation/src/tests/mock.rs +++ b/pallets/liquidation/src/tests/mock.rs @@ -372,6 +372,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } impl pallet_currencies::Config for Test { diff --git a/pallets/liquidity-mining/src/tests/mock.rs b/pallets/liquidity-mining/src/tests/mock.rs index 2b3db5926..45f7e2231 100644 --- a/pallets/liquidity-mining/src/tests/mock.rs +++ b/pallets/liquidity-mining/src/tests/mock.rs @@ -284,6 +284,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } impl orml_tokens::Config for Test { diff --git a/pallets/nft/src/mock.rs b/pallets/nft/src/mock.rs index 6407ebe95..2b5d22b12 100644 --- a/pallets/nft/src/mock.rs +++ b/pallets/nft/src/mock.rs @@ -175,6 +175,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } pub const ALICE: AccountId = AccountId::new([1u8; 32]); diff --git a/pallets/omnipool-liquidity-mining/src/tests/mock.rs b/pallets/omnipool-liquidity-mining/src/tests/mock.rs index c9f3db173..d6a835e71 100644 --- a/pallets/omnipool-liquidity-mining/src/tests/mock.rs +++ b/pallets/omnipool-liquidity-mining/src/tests/mock.rs @@ -266,6 +266,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_type_with_key! { diff --git a/pallets/omnipool/src/tests/mock.rs b/pallets/omnipool/src/tests/mock.rs index 0ada932c1..f123fa966 100644 --- a/pallets/omnipool/src/tests/mock.rs +++ b/pallets/omnipool/src/tests/mock.rs @@ -141,6 +141,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_type_with_key! { diff --git a/pallets/otc-settlements/src/mock.rs b/pallets/otc-settlements/src/mock.rs index c9ae9ee10..e3a5cb44e 100644 --- a/pallets/otc-settlements/src/mock.rs +++ b/pallets/otc-settlements/src/mock.rs @@ -234,6 +234,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } impl pallet_currencies::Config for Test { diff --git a/pallets/route-executor/src/tests/mock.rs b/pallets/route-executor/src/tests/mock.rs index e5ed6d908..66c27a87f 100644 --- a/pallets/route-executor/src/tests/mock.rs +++ b/pallets/route-executor/src/tests/mock.rs @@ -135,6 +135,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } impl pallet_currencies::Config for Test { diff --git a/pallets/signet/src/tests/mod.rs b/pallets/signet/src/tests/mod.rs index b42229aee..587986163 100644 --- a/pallets/signet/src/tests/mod.rs +++ b/pallets/signet/src/tests/mod.rs @@ -128,6 +128,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_types! { diff --git a/pallets/stableswap/src/tests/mock.rs b/pallets/stableswap/src/tests/mock.rs index 7e7abf29b..63e79780f 100644 --- a/pallets/stableswap/src/tests/mock.rs +++ b/pallets/stableswap/src/tests/mock.rs @@ -708,6 +708,8 @@ impl MutationHooks for Hooks { type PostDeposit = pallet_circuit_breaker::fuses::issuance::IssuanceIncreaseFuse; type PreTransfer = (); type PostTransfer = (); + type PreWithdraw = (); + type PostWithdraw = (); type OnNewTokenAccount = (); type OnKilledTokenAccount = (); } diff --git a/pallets/staking/src/tests/mock.rs b/pallets/staking/src/tests/mock.rs index e1ee86d8c..df722feae 100644 --- a/pallets/staking/src/tests/mock.rs +++ b/pallets/staking/src/tests/mock.rs @@ -135,6 +135,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_types! { diff --git a/pallets/synthetic-logs/src/tests.rs b/pallets/synthetic-logs/src/tests.rs index 82b7cc58b..81cce0074 100644 --- a/pallets/synthetic-logs/src/tests.rs +++ b/pallets/synthetic-logs/src/tests.rs @@ -34,12 +34,7 @@ fn encode_u256_be_round_trip() { #[test] fn encode_uint256_quad_is_128_bytes() { - let data = encode_uint256_quad( - U256::from(1u64), - U256::from(2u64), - U256::from(3u64), - U256::from(4u64), - ); + let data = encode_uint256_quad(U256::from(1u64), U256::from(2u64), U256::from(3u64), U256::from(4u64)); assert_eq!(data.len(), 128); assert_eq!(U256::from_big_endian(&data[0..32]), U256::from(1u64)); assert_eq!(U256::from_big_endian(&data[32..64]), U256::from(2u64)); diff --git a/pallets/tokens/Cargo.toml b/pallets/tokens/Cargo.toml deleted file mode 100644 index b43b611cb..000000000 --- a/pallets/tokens/Cargo.toml +++ /dev/null @@ -1,54 +0,0 @@ -[package] -name = "orml-tokens" -description = "Fungible tokens module that implements `MultiCurrency` trait." -repository = "https://github.com/galacticcouncil/hydration-node" -license = "Apache-2.0" -version = "1.4.0" -authors = ["Laminar Developers "] -edition = "2021" - -[dependencies] -parity-scale-codec = { version = "3.7", default-features = false, features = ["derive", "max-encoded-len"] } -log = { workspace = true } -scale-info = { workspace = true } -serde = { workspace = true, optional = true } - -frame-support = { workspace = true } -frame-system = { workspace = true } -sp-arithmetic = { workspace = true } -sp-runtime = { workspace = true } -sp-std = { workspace = true } - -orml-traits = { workspace = true } - -[dev-dependencies] -pallet-elections-phragmen = { workspace = true, features = ["std"] } -pallet-treasury = { workspace = true, features = ["std"] } -sp-core = { workspace = true, features = ["std"] } -sp-io = { workspace = true, features = ["std"] } -sp-staking = { workspace = true, features = ["std"] } - -[features] -default = ["std"] -std = [ - "frame-support/std", - "frame-system/std", - "log/std", - "orml-traits/std", - "parity-scale-codec/std", - "scale-info/std", - "serde", - "sp-arithmetic/std", - "sp-runtime/std", - "sp-std/std", -] -runtime-benchmarks = [ - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] -try-runtime = [ - "frame-support/try-runtime", - "frame-system/try-runtime", - "sp-runtime/try-runtime", -] diff --git a/pallets/tokens/README.md b/pallets/tokens/README.md deleted file mode 100644 index 20e9e816e..000000000 --- a/pallets/tokens/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Tokens Module - -## Overview - -The tokens module provides fungible multi-currencies functionality that implements `MultiCurrency` trait. - -The tokens module provides functions for: - -- Querying and setting the balance of a given account. -- Getting and managing total issuance. -- Balance transfer between accounts. -- Depositing and withdrawing balance. -- Slashing an account balance. diff --git a/pallets/tokens/runtime-api/Cargo.toml b/pallets/tokens/runtime-api/Cargo.toml deleted file mode 100644 index b70a6b0d1..000000000 --- a/pallets/tokens/runtime-api/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "orml-tokens-runtime-api" -version = "1.4.0" -authors = ["Laminar Developers "] -edition = "2021" -license = "Apache-2.0" -description = "Runtime API module for orml-tokens." -repository = "https://github.com/open-web3-stack/open-runtime-module-library" - -[dependencies] -parity-scale-codec = { workspace = true, default-features = false, features = ["derive"] } -frame-support = { workspace = true } -sp-api = { workspace = true } -sp-runtime = { workspace = true } - -[features] -default = [ "std" ] -std = [ - "frame-support/std", - "parity-scale-codec/std", - "sp-api/std", - "sp-runtime/std", -] diff --git a/pallets/tokens/runtime-api/src/lib.rs b/pallets/tokens/runtime-api/src/lib.rs deleted file mode 100644 index a54962c0c..000000000 --- a/pallets/tokens/runtime-api/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! Runtime API definition for orml tokens pallet. - -#![cfg_attr(not(feature = "std"), no_std)] -// The `too_many_arguments` warning originates from `decl_runtime_apis` macro. -#![allow(clippy::too_many_arguments)] -// The `unnecessary_mut_passed` warning originates from `decl_runtime_apis` macro. -#![allow(clippy::unnecessary_mut_passed)] - -use parity_scale_codec::Codec; - -sp_api::decl_runtime_apis! { - pub trait TokensApi where - Balance: Codec, - CurrencyId: Codec - { - fn query_existential_deposit(currency_id: CurrencyId) -> Balance; - } -} diff --git a/pallets/tokens/src/imbalances.rs b/pallets/tokens/src/imbalances.rs deleted file mode 100644 index 858641130..000000000 --- a/pallets/tokens/src/imbalances.rs +++ /dev/null @@ -1,197 +0,0 @@ -// wrapping these imbalances in a private module is necessary to ensure absolute -// privacy of the inner member. -use crate::{Config, TotalIssuance}; -use frame_support::traits::{tokens::imbalance::TryMerge, Get, Imbalance, SameOrOther, TryDrop}; -use sp_runtime::traits::{Saturating, Zero}; -use sp_std::{marker, mem, result}; - -/// Opaque, move-only struct with private fields that serves as a token -/// denoting that funds have been created without any equal and opposite -/// accounting. -#[must_use] -pub struct PositiveImbalance>( - T::Balance, - marker::PhantomData, -); - -impl> PositiveImbalance { - /// Create a new positive imbalance from a balance. - pub fn new(amount: T::Balance) -> Self { - PositiveImbalance(amount, marker::PhantomData::) - } -} - -impl> Default for PositiveImbalance { - fn default() -> Self { - Self::zero() - } -} - -/// Opaque, move-only struct with private fields that serves as a token -/// denoting that funds have been destroyed without any equal and opposite -/// accounting. -#[must_use] -pub struct NegativeImbalance>( - T::Balance, - marker::PhantomData, -); - -impl> NegativeImbalance { - /// Create a new negative imbalance from a balance. - pub fn new(amount: T::Balance) -> Self { - NegativeImbalance(amount, marker::PhantomData::) - } -} - -impl> Default for NegativeImbalance { - fn default() -> Self { - Self::zero() - } -} - -impl> TryDrop for PositiveImbalance { - fn try_drop(self) -> result::Result<(), Self> { - self.drop_zero() - } -} - -impl> Imbalance for PositiveImbalance { - type Opposite = NegativeImbalance; - - fn zero() -> Self { - Self::new(Zero::zero()) - } - fn drop_zero(self) -> result::Result<(), Self> { - if self.0.is_zero() { - Ok(()) - } else { - Err(self) - } - } - fn split(self, amount: T::Balance) -> (Self, Self) { - let first = self.0.min(amount); - let second = self.0.saturating_sub(first); - - mem::forget(self); - (Self::new(first), Self::new(second)) - } - fn merge(mut self, other: Self) -> Self { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - - self - } - fn subsume(&mut self, other: Self) { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - } - // allow to make the impl same with `pallet-balances` - #[allow(clippy::comparison_chain)] - fn offset(self, other: Self::Opposite) -> SameOrOther { - let (a, b) = (self.0, other.0); - mem::forget((self, other)); - - if a > b { - SameOrOther::Same(Self::new(a.saturating_sub(b))) - } else if b > a { - SameOrOther::Other(NegativeImbalance::new(b.saturating_sub(a))) - } else { - SameOrOther::None - } - } - fn peek(&self) -> T::Balance { - self.0 - } - - fn extract(&mut self, amount: T::Balance) -> Self { - let new: T::Balance = self.0.min(amount); - self.0 -= new; - Self::new(new) - } -} - -impl> TryDrop for NegativeImbalance { - fn try_drop(self) -> result::Result<(), Self> { - self.drop_zero() - } -} - -impl> Imbalance for NegativeImbalance { - type Opposite = PositiveImbalance; - - fn zero() -> Self { - Self::new(Zero::zero()) - } - fn drop_zero(self) -> result::Result<(), Self> { - if self.0.is_zero() { - Ok(()) - } else { - Err(self) - } - } - fn split(self, amount: T::Balance) -> (Self, Self) { - let first = self.0.min(amount); - let second = self.0.saturating_sub(first); - - mem::forget(self); - (Self::new(first), Self::new(second)) - } - fn merge(mut self, other: Self) -> Self { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - - self - } - fn subsume(&mut self, other: Self) { - self.0 = self.0.saturating_add(other.0); - mem::forget(other); - } - // allow to make the impl same with `pallet-balances` - #[allow(clippy::comparison_chain)] - fn offset(self, other: Self::Opposite) -> SameOrOther { - let (a, b) = (self.0, other.0); - mem::forget((self, other)); - - if a > b { - SameOrOther::Same(Self::new(a.saturating_sub(b))) - } else if b > a { - SameOrOther::Other(PositiveImbalance::new(b.saturating_sub(a))) - } else { - SameOrOther::None - } - } - fn peek(&self) -> T::Balance { - self.0 - } - - fn extract(&mut self, amount: T::Balance) -> Self { - let new: T::Balance = self.0.min(amount); - self.0 -= new; - Self::new(new) - } -} - -impl> Drop for PositiveImbalance { - /// Basic drop handler will just square up the total issuance. - fn drop(&mut self) { - TotalIssuance::::mutate(GetCurrencyId::get(), |v| *v = v.saturating_add(self.0)); - } -} - -impl> Drop for NegativeImbalance { - /// Basic drop handler will just square up the total issuance. - fn drop(&mut self) { - TotalIssuance::::mutate(GetCurrencyId::get(), |v| *v = v.saturating_sub(self.0)); - } -} - -impl> TryMerge for PositiveImbalance { - fn try_merge(self, other: Self) -> Result { - Ok(self.merge(other)) - } -} -impl> TryMerge for NegativeImbalance { - fn try_merge(self, other: Self) -> Result { - Ok(self.merge(other)) - } -} diff --git a/pallets/tokens/src/impls.rs b/pallets/tokens/src/impls.rs deleted file mode 100644 index 83a65ad60..000000000 --- a/pallets/tokens/src/impls.rs +++ /dev/null @@ -1,352 +0,0 @@ -use frame_support::traits::tokens::{Fortitude, Precision, Preservation, Provenance}; -use frame_support::traits::{ - fungible, fungibles, - tokens::{Balance as BalanceT, DepositConsequence, WithdrawConsequence}, - Contains, Get, -}; -use sp_arithmetic::{traits::Bounded, ArithmeticError}; -use sp_runtime::DispatchError; - -pub struct Combiner(sp_std::marker::PhantomData<(AccountId, TestKey, A, B)>); - -impl fungibles::Inspect for Combiner -where - TestKey: Contains<>::AssetId>, - A: fungible::Inspect>::Balance>, - B: fungibles::Inspect, -{ - type AssetId = >::AssetId; - type Balance = >::Balance; - - fn total_issuance(asset: Self::AssetId) -> Self::Balance { - if TestKey::contains(&asset) { - A::total_issuance() - } else { - B::total_issuance(asset) - } - } - - fn minimum_balance(asset: Self::AssetId) -> Self::Balance { - if TestKey::contains(&asset) { - A::minimum_balance() - } else { - B::minimum_balance(asset) - } - } - - fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { - if TestKey::contains(&asset) { - A::balance(who) - } else { - B::balance(asset, who) - } - } - - fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { - if TestKey::contains(&asset) { - A::total_balance(who) - } else { - B::total_balance(asset, who) - } - } - - fn reducible_balance( - asset: Self::AssetId, - who: &AccountId, - preservation: Preservation, - fortitude: Fortitude, - ) -> Self::Balance { - if TestKey::contains(&asset) { - A::reducible_balance(who, preservation, fortitude) - } else { - B::reducible_balance(asset, who, preservation, fortitude) - } - } - - fn can_deposit( - asset: Self::AssetId, - who: &AccountId, - amount: Self::Balance, - provenance: Provenance, - ) -> DepositConsequence { - if TestKey::contains(&asset) { - A::can_deposit(who, amount, provenance) - } else { - B::can_deposit(asset, who, amount, provenance) - } - } - - fn can_withdraw( - asset: Self::AssetId, - who: &AccountId, - amount: Self::Balance, - ) -> WithdrawConsequence { - if TestKey::contains(&asset) { - A::can_withdraw(who, amount) - } else { - B::can_withdraw(asset, who, amount) - } - } - - fn asset_exists(asset: Self::AssetId) -> bool { - if TestKey::contains(&asset) { - true - } else { - B::asset_exists(asset) - } - } -} - -impl fungibles::Mutate for Combiner -where - TestKey: Contains<>::AssetId>, - A: fungible::Mutate>::Balance>, - B: fungibles::Mutate, - AccountId: Eq, -{ - fn mint_into( - asset: Self::AssetId, - dest: &AccountId, - amount: Self::Balance, - ) -> Result { - if TestKey::contains(&asset) { - A::mint_into(dest, amount) - } else { - B::mint_into(asset, dest, amount) - } - } - - fn burn_from( - asset: Self::AssetId, - dest: &AccountId, - amount: Self::Balance, - preservation: Preservation, - precision: Precision, - fortitude: Fortitude, - ) -> Result { - if TestKey::contains(&asset) { - A::burn_from(dest, amount, preservation, precision, fortitude) - } else { - B::burn_from(asset, dest, amount, preservation, precision, fortitude) - } - } - - fn transfer( - asset: Self::AssetId, - source: &AccountId, - dest: &AccountId, - amount: Self::Balance, - preservation: Preservation, - ) -> Result { - if TestKey::contains(&asset) { - A::transfer(source, dest, amount, preservation) - } else { - B::transfer(asset, source, dest, amount, preservation) - } - } -} - -impl fungibles::Unbalanced for Combiner -where - TestKey: Contains<>::AssetId>, - A: fungible::Mutate>::Balance>, - B: fungibles::Mutate, - AccountId: Eq, -{ - fn handle_dust(_dust: fungibles::Dust) { - // FIXME: only way to access internals of Dust is into_credit, but T is - // not balanced - } - - fn write_balance( - asset: Self::AssetId, - who: &AccountId, - amount: Self::Balance, - ) -> Result, DispatchError> { - if TestKey::contains(&asset) { - A::write_balance(who, amount) - } else { - B::write_balance(asset, who, amount) - } - } - - fn set_total_issuance(asset: Self::AssetId, amount: Self::Balance) { - if TestKey::contains(&asset) { - A::set_total_issuance(amount) - } else { - B::set_total_issuance(asset, amount) - } - } -} - -pub trait ConvertBalance { - type AssetId; - fn convert_balance(amount: A, asset_id: Self::AssetId) -> Result; - fn convert_balance_back(amount: B, asset_id: Self::AssetId) -> Result; - - fn convert_balance_saturated(amount: A, asset_id: Self::AssetId) -> B { - Self::convert_balance(amount, asset_id).unwrap_or_else(|e| match e { - ArithmeticError::Overflow => B::max_value(), - ArithmeticError::Underflow => B::min_value(), - ArithmeticError::DivisionByZero => B::max_value(), - }) - } - fn convert_balance_back_saturated(amount: B, asset_id: Self::AssetId) -> A { - Self::convert_balance_back(amount, asset_id).unwrap_or_else(|e| match e { - ArithmeticError::Overflow => A::max_value(), - ArithmeticError::Underflow => A::min_value(), - ArithmeticError::DivisionByZero => A::max_value(), - }) - } -} - -pub struct Mapper(sp_std::marker::PhantomData<(AccountId, T, C, B, GetCurrencyId)>); -impl fungible::Inspect for Mapper -where - T: fungibles::Inspect, - C: ConvertBalance< - >::Balance, - B, - AssetId = >::AssetId, - >, - B: BalanceT, - GetCurrencyId: Get<>::AssetId>, -{ - type Balance = B; - - fn total_issuance() -> Self::Balance { - C::convert_balance_saturated(T::total_issuance(GetCurrencyId::get()), GetCurrencyId::get()) - } - - fn minimum_balance() -> Self::Balance { - C::convert_balance_saturated(T::minimum_balance(GetCurrencyId::get()), GetCurrencyId::get()) - } - - fn balance(who: &AccountId) -> Self::Balance { - C::convert_balance_saturated(T::balance(GetCurrencyId::get(), who), GetCurrencyId::get()) - } - - fn total_balance(who: &AccountId) -> Self::Balance { - C::convert_balance_saturated(T::total_balance(GetCurrencyId::get(), who), GetCurrencyId::get()) - } - - fn reducible_balance(who: &AccountId, preservation: Preservation, fortitude: Fortitude) -> Self::Balance { - C::convert_balance_saturated( - T::reducible_balance(GetCurrencyId::get(), who, preservation, fortitude), - GetCurrencyId::get(), - ) - } - - fn can_deposit(who: &AccountId, amount: Self::Balance, provenance: Provenance) -> DepositConsequence { - let amount = C::convert_balance_back(amount, GetCurrencyId::get()); - let amount = match amount { - Ok(amount) => amount, - Err(_) => return DepositConsequence::Overflow, - }; - T::can_deposit(GetCurrencyId::get(), who, amount, provenance) - } - - fn can_withdraw(who: &AccountId, amount: Self::Balance) -> WithdrawConsequence { - use WithdrawConsequence::*; - - let amount = C::convert_balance_back(amount, GetCurrencyId::get()); - let amount = match amount { - Ok(amount) => amount, - Err(ArithmeticError::Overflow) => return Overflow, - Err(ArithmeticError::Underflow) => return Underflow, - Err(ArithmeticError::DivisionByZero) => return Overflow, - }; - - let res = T::can_withdraw(GetCurrencyId::get(), who, amount); - match res { - WithdrawConsequence::ReducedToZero(b) => { - WithdrawConsequence::ReducedToZero(C::convert_balance_saturated(b, GetCurrencyId::get())) - } - BalanceLow => BalanceLow, - WouldDie => WouldDie, - UnknownAsset => UnknownAsset, - Underflow => Underflow, - Overflow => Overflow, - Frozen => Frozen, - Success => Success, - } - } -} - -impl fungible::Mutate for Mapper -where - T: fungibles::Mutate, - C: ConvertBalance< - >::Balance, - B, - AssetId = >::AssetId, - >, - B: BalanceT, - GetCurrencyId: Get<>::AssetId>, - AccountId: Eq, -{ - fn mint_into(dest: &AccountId, amount: Self::Balance) -> Result { - T::mint_into( - GetCurrencyId::get(), - dest, - C::convert_balance_back(amount, GetCurrencyId::get())?, - ) - } - - fn burn_from( - dest: &AccountId, - amount: Self::Balance, - preservation: Preservation, - precision: Precision, - fortitude: Fortitude, - ) -> Result { - T::burn_from( - GetCurrencyId::get(), - dest, - C::convert_balance_back(amount, GetCurrencyId::get())?, - preservation, - precision, - fortitude, - ) - } - - fn transfer( - source: &AccountId, - dest: &AccountId, - amount: B, - preservation: Preservation, - ) -> Result { - T::transfer( - GetCurrencyId::get(), - source, - dest, - C::convert_balance_back(amount, GetCurrencyId::get())?, - preservation, - ) - } -} - -impl fungible::Unbalanced for Mapper -where - T: fungibles::Unbalanced, - C: ConvertBalance< - >::Balance, - B, - AssetId = >::AssetId, - >, - B: BalanceT, - GetCurrencyId: Get<>::AssetId>, -{ - fn handle_dust(_dust: fungible::Dust) { - // FIXME: only way to access internals of Dust is into_credit, but T is - // not balanced - } - - fn write_balance(who: &AccountId, amount: Self::Balance) -> Result, DispatchError> { - T::write_balance(GetCurrencyId::get(), who, amount) - } - - fn set_total_issuance(amount: Self::Balance) { - T::set_total_issuance(GetCurrencyId::get(), amount) - } -} diff --git a/pallets/tokens/src/lib.rs b/pallets/tokens/src/lib.rs deleted file mode 100644 index 9f6a03ee3..000000000 --- a/pallets/tokens/src/lib.rs +++ /dev/null @@ -1,2605 +0,0 @@ -//! # Tokens Module -//! -//! ## Overview -//! -//! The tokens module provides fungible multi-currency functionality that -//! implements `MultiCurrency` trait. -//! -//! The tokens module provides functions for: -//! -//! - Querying and setting the balance of a given account. -//! - Getting and managing total issuance. -//! - Balance transfer between accounts. -//! - Depositing and withdrawing balance. -//! - Slashing an account balance. -//! -//! ### Implementations -//! -//! The tokens module provides implementations for following traits. -//! -//! - `MultiCurrency` - Abstraction over a fungible multi-currency system. -//! - `MultiCurrencyExtended` - Extended `MultiCurrency` with additional helper -//! types and methods, like updating balance by a given signed integer amount. -//! -//! ## Interface -//! -//! ### Dispatchable Functions -//! -//! - `transfer` - Transfer some balance to another account. -//! - `transfer_all` - Transfer all balance to another account. -//! -//! ### Genesis Config -//! -//! The tokens module depends on the `GenesisConfig`. Endowed accounts could be -//! configured in genesis configs. - -#![cfg_attr(not(feature = "std"), no_std)] -#![allow(clippy::unused_unit)] -#![allow(clippy::comparison_chain)] -#![allow(clippy::useless_conversion)] - -pub use crate::imbalances::{NegativeImbalance, PositiveImbalance}; - -use frame_support::{ - ensure, - pallet_prelude::*, - traits::{ - tokens::{ - fungible, fungibles, DepositConsequence, Fortitude, Precision, Preservation, Provenance, Restriction, - WithdrawConsequence, - }, - BalanceStatus as Status, Contains, Currency as PalletCurrency, DefensiveSaturating, ExistenceRequirement, Get, - Imbalance, LockableCurrency as PalletLockableCurrency, - NamedReservableCurrency as PalletNamedReservableCurrency, ReservableCurrency as PalletReservableCurrency, - SignedImbalance, WithdrawReasons, - }, - transactional, BoundedVec, -}; -use frame_system::{ensure_signed, pallet_prelude::*}; -use parity_scale_codec::MaxEncodedLen; -use scale_info::TypeInfo; -use sp_runtime::{ - traits::{Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, Saturating, StaticLookup, Zero}, - ArithmeticError, DispatchError, DispatchResult, RuntimeDebug, TokenError, -}; -use sp_std::{cmp, convert::Infallible, marker, prelude::*, vec::Vec}; - -use orml_traits::{ - arithmetic::{self, Signed}, - currency::{MutationHooks, OnDeposit, OnDust, OnSlash, OnTransfer, TransferAll}, - BalanceStatus, GetByKey, Happened, LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency, - MultiReservableCurrency, NamedMultiReservableCurrency, -}; - -mod imbalances; -mod impls; -mod mock; -mod tests; -mod tests_currency_adapter; -mod tests_events; -mod tests_fungibles; -mod tests_multicurrency; - -mod weights; - -pub use impls::*; -pub use weights::WeightInfo; - -pub struct TransferDust(marker::PhantomData<(T, GetAccountId)>); -impl OnDust for TransferDust -where - T: Config, - GetAccountId: Get, -{ - fn on_dust(who: &T::AccountId, currency_id: T::CurrencyId, amount: T::Balance) { - // transfer the dust to treasury account, ignore the result, - // if failed will leave some dust which still could be recycled. - let _ = Pallet::::do_transfer( - currency_id, - who, - &GetAccountId::get(), - amount, - ExistenceRequirement::AllowDeath, - ); - } -} - -pub struct BurnDust(marker::PhantomData); -impl OnDust for BurnDust { - fn on_dust(who: &T::AccountId, currency_id: T::CurrencyId, amount: T::Balance) { - // burn the dust, ignore the result, - // if failed will leave some dust which still could be recycled. - let _ = Pallet::::do_withdraw(currency_id, who, amount, ExistenceRequirement::AllowDeath, true); - } -} - -/// A single lock on a balance. There can be many of these on an account and -/// they "overlap", so the same balance is frozen by multiple locks. -#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, MaxEncodedLen, RuntimeDebug, TypeInfo)] -pub struct BalanceLock { - /// An identifier for this lock. Only one lock may be in existence for - /// each identifier. - pub id: LockIdentifier, - /// The amount which the free balance may not drop below when this lock - /// is in effect. - pub amount: Balance, -} - -/// Store named reserved balance. -#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] -pub struct ReserveData { - /// The identifier for the named reserve. - pub id: ReserveIdentifier, - /// The amount of the named reserve. - pub amount: Balance, -} - -/// balance information for an account. -#[derive( - Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Default, MaxEncodedLen, RuntimeDebug, TypeInfo, -)] -pub struct AccountData { - /// Non-reserved part of the balance. There may still be restrictions on - /// this, but it is the total pool what may in principle be transferred, - /// reserved. - /// - /// This is the only balance that matters in terms of most operations on - /// tokens. - pub free: Balance, - /// Balance which is reserved and may not be used at all. - /// - /// This can still get slashed, but gets slashed last of all. - /// - /// This balance is a 'reserve' balance that other subsystems use in - /// order to set aside tokens that are still 'owned' by the account - /// holder, but which are suspendable. - pub reserved: Balance, - /// The amount that `free` may not drop below when withdrawing. - pub frozen: Balance, -} - -impl AccountData { - /// The amount that this account's free balance may not be reduced - /// beyond. - pub(crate) fn frozen(&self) -> Balance { - self.frozen - } - /// The total balance in this account including any that is reserved and - /// ignoring any frozen. - fn total(&self) -> Balance { - self.free.saturating_add(self.reserved) - } -} - -pub use module::*; - -#[frame_support::pallet] -pub mod module { - use orml_traits::currency::MutationHooks; - - use super::*; - - #[pallet::config] - pub trait Config: frame_system::Config { - /// The balance type - type Balance: frame_support::traits::tokens::Balance; - - /// The amount type, should be signed version of `Balance` - type Amount: Signed - + TryInto - + TryFrom - + Parameter - + Member - + arithmetic::SimpleArithmetic - + Default - + Copy - + MaybeSerializeDeserialize - + MaxEncodedLen; - - /// The currency ID type - type CurrencyId: Parameter + Member + Copy + MaybeSerializeDeserialize + Ord + TypeInfo + MaxEncodedLen; - - /// Weight information for extrinsics in this module. - type WeightInfo: WeightInfo; - - /// The minimum amount required to keep an account. - /// It's deprecated to config 0 as ED for any currency_id, - /// zero ED will retain account even if its total is zero. - /// Since accounts of orml_tokens are also used as providers of - /// System::AccountInfo, zero ED may cause some problems. - type ExistentialDeposits: GetByKey; - - /// Hooks are actions that are executed on certain events. - /// For example: OnDust, OnNewTokenAccount - type CurrencyHooks: MutationHooks; - - #[pallet::constant] - type MaxLocks: Get; - - /// The maximum number of named reserves that can exist on an account. - #[pallet::constant] - type MaxReserves: Get; - - /// The id type for named reserves. - type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy; - - // The whitelist of accounts that will not be reaped even if its total - // is zero or below ED. - type DustRemovalWhitelist: Contains; - } - - #[pallet::error] - pub enum Error { - /// The balance is too low - BalanceTooLow, - /// Cannot convert Amount into Balance type - AmountIntoBalanceFailed, - /// Failed because liquidity restrictions due to locking - LiquidityRestrictions, - /// Failed because the maximum locks was exceeded - MaxLocksExceeded, - /// Transfer/payment would kill account - KeepAlive, - /// Value too low to create account due to existential deposit - ExistentialDeposit, - /// Beneficiary account must pre-exist - DeadAccount, - // Number of named reserves exceed `T::MaxReserves` - TooManyReserves, - } - - #[pallet::event] - #[pallet::generate_deposit(pub(crate) fn deposit_event)] - pub enum Event { - /// An account was created with some free balance. - Endowed { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// An account was removed whose balance was non-zero but below - /// ExistentialDeposit, resulting in an outright loss. - DustLost { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// Transfer succeeded. - Transfer { - currency_id: T::CurrencyId, - from: T::AccountId, - to: T::AccountId, - amount: T::Balance, - }, - /// Some balance was reserved (moved from free to reserved). - Reserved { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// Some balance was unreserved (moved from reserved to free). - Unreserved { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// Some reserved balance was repatriated (moved from reserved to - /// another account). - ReserveRepatriated { - currency_id: T::CurrencyId, - from: T::AccountId, - to: T::AccountId, - amount: T::Balance, - status: BalanceStatus, - }, - /// A balance was set by root. - BalanceSet { - currency_id: T::CurrencyId, - who: T::AccountId, - free: T::Balance, - reserved: T::Balance, - }, - /// The total issuance of an currency has been set - TotalIssuanceSet { - currency_id: T::CurrencyId, - amount: T::Balance, - }, - /// Some balances were withdrawn (e.g. pay for transaction fee) - Withdrawn { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// Some balances were slashed (e.g. due to mis-behavior) - Slashed { - currency_id: T::CurrencyId, - who: T::AccountId, - free_amount: T::Balance, - reserved_amount: T::Balance, - }, - /// Deposited some balance into an account - Deposited { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// Some funds are locked - LockSet { - lock_id: LockIdentifier, - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// Some locked funds were unlocked - LockRemoved { - lock_id: LockIdentifier, - currency_id: T::CurrencyId, - who: T::AccountId, - }, - /// Some free balance was locked. - Locked { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - /// Some locked balance was freed. - Unlocked { - currency_id: T::CurrencyId, - who: T::AccountId, - amount: T::Balance, - }, - Issued { - currency_id: T::CurrencyId, - amount: T::Balance, - }, - Rescinded { - currency_id: T::CurrencyId, - amount: T::Balance, - }, - } - - /// The total issuance of a token type. - #[pallet::storage] - #[pallet::getter(fn total_issuance)] - pub type TotalIssuance = StorageMap<_, Twox64Concat, T::CurrencyId, T::Balance, ValueQuery>; - - /// Any liquidity locks of a token type under an account. - /// NOTE: Should only be accessed when setting, changing and freeing a lock. - #[pallet::storage] - #[pallet::getter(fn locks)] - pub type Locks = StorageDoubleMap< - _, - Blake2_128Concat, - T::AccountId, - Twox64Concat, - T::CurrencyId, - BoundedVec, T::MaxLocks>, - ValueQuery, - >; - - /// The balance of a token type under an account. - /// - /// NOTE: If the total is ever zero, decrease account ref account. - /// - /// NOTE: This is only used in the case that this module is used to store - /// balances. - #[pallet::storage] - #[pallet::getter(fn accounts)] - pub type Accounts = StorageDoubleMap< - _, - Blake2_128Concat, - T::AccountId, - Twox64Concat, - T::CurrencyId, - AccountData, - ValueQuery, - >; - - /// Named reserves on some account balances. - #[pallet::storage] - #[pallet::getter(fn reserves)] - pub type Reserves = StorageDoubleMap< - _, - Blake2_128Concat, - T::AccountId, - Twox64Concat, - T::CurrencyId, - BoundedVec, T::MaxReserves>, - ValueQuery, - >; - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub balances: Vec<(T::AccountId, T::CurrencyId, T::Balance)>, - } - - impl Default for GenesisConfig { - fn default() -> Self { - GenesisConfig { - balances: Default::default(), - } - } - } - - #[pallet::genesis_build] - impl BuildGenesisConfig for GenesisConfig { - fn build(&self) { - // ensure no duplicates exist. - let unique_endowed_accounts = self - .balances - .iter() - .map(|(account_id, currency_id, _)| (account_id, currency_id)) - .collect::>(); - assert!( - unique_endowed_accounts.len() == self.balances.len(), - "duplicate endowed accounts in genesis." - ); - - self.balances - .iter() - .for_each(|(account_id, currency_id, initial_balance)| { - assert!( - *initial_balance >= T::ExistentialDeposits::get(currency_id), - "the balance of any account should always be more than existential deposit.", - ); - Pallet::::mutate_account(account_id, *currency_id, |account_data, _| { - account_data.free = *initial_balance - }); - TotalIssuance::::mutate(*currency_id, |total_issuance| { - *total_issuance = total_issuance - .checked_add(initial_balance) - .expect("total issuance cannot overflow when building genesis") - }); - }); - } - } - - #[pallet::pallet] - pub struct Pallet(_); - - #[pallet::hooks] - impl Hooks> for Pallet {} - - #[pallet::call] - impl Pallet { - /// Transfer some liquid free balance to another account. - /// - /// `transfer` will set the `FreeBalance` of the sender and receiver. - /// It will decrease the total issuance of the system by the - /// `TransferFee`. If the sender's account is below the existential - /// deposit as a result of the transfer, the account will be reaped. - /// - /// The dispatch origin for this call must be `Signed` by the - /// transactor. - /// - /// - `dest`: The recipient of the transfer. - /// - `currency_id`: currency type. - /// - `amount`: free balance amount to transfer. - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::transfer())] - pub fn transfer( - origin: OriginFor, - dest: ::Source, - currency_id: T::CurrencyId, - #[pallet::compact] amount: T::Balance, - ) -> DispatchResult { - let from = ensure_signed(origin)?; - let to = T::Lookup::lookup(dest)?; - Self::do_transfer(currency_id, &from, &to, amount, ExistenceRequirement::AllowDeath) - } - - /// Transfer all remaining balance to the given account. - /// - /// NOTE: This function only attempts to transfer _transferable_ - /// balances. This means that any locked, reserved, or existential - /// deposits (when `keep_alive` is `true`), will not be transferred by - /// this function. To ensure that this function results in a killed - /// account, you might need to prepare the account by removing any - /// reference counters, storage deposits, etc... - /// - /// The dispatch origin for this call must be `Signed` by the - /// transactor. - /// - /// - `dest`: The recipient of the transfer. - /// - `currency_id`: currency type. - /// - `keep_alive`: A boolean to determine if the `transfer_all` - /// operation should send all of the funds the account has, causing - /// the sender account to be killed (false), or transfer everything - /// except at least the existential deposit, which will guarantee to - /// keep the sender account alive (true). - #[pallet::call_index(1)] - #[pallet::weight(T::WeightInfo::transfer_all())] - pub fn transfer_all( - origin: OriginFor, - dest: ::Source, - currency_id: T::CurrencyId, - keep_alive: bool, - ) -> DispatchResult { - let from = ensure_signed(origin)?; - let to = T::Lookup::lookup(dest)?; - let preservation = if keep_alive { - Preservation::Protect - } else { - Preservation::Expendable - }; - let reducible_balance = >::reducible_balance( - currency_id, - &from, - preservation, - Fortitude::Polite, - ); - >::transfer(currency_id, &from, &to, reducible_balance, preservation) - .map(|_| ()) - } - - /// Same as the [`transfer`] call, but with a check that the transfer - /// will not kill the origin account. - /// - /// 99% of the time you want [`transfer`] instead. - /// - /// The dispatch origin for this call must be `Signed` by the - /// transactor. - /// - /// - `dest`: The recipient of the transfer. - /// - `currency_id`: currency type. - /// - `amount`: free balance amount to transfer. - #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::transfer_keep_alive())] - pub fn transfer_keep_alive( - origin: OriginFor, - dest: ::Source, - currency_id: T::CurrencyId, - #[pallet::compact] amount: T::Balance, - ) -> DispatchResultWithPostInfo { - let from = ensure_signed(origin)?; - let to = T::Lookup::lookup(dest)?; - Self::do_transfer(currency_id, &from, &to, amount, ExistenceRequirement::KeepAlive)?; - Ok(().into()) - } - - /// Exactly as `transfer`, except the origin must be root and the source - /// account may be specified. - /// - /// The dispatch origin for this call must be _Root_. - /// - /// - `source`: The sender of the transfer. - /// - `dest`: The recipient of the transfer. - /// - `currency_id`: currency type. - /// - `amount`: free balance amount to transfer. - #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::force_transfer())] - pub fn force_transfer( - origin: OriginFor, - source: ::Source, - dest: ::Source, - currency_id: T::CurrencyId, - #[pallet::compact] amount: T::Balance, - ) -> DispatchResult { - ensure_root(origin)?; - let from = T::Lookup::lookup(source)?; - let to = T::Lookup::lookup(dest)?; - Self::do_transfer(currency_id, &from, &to, amount, ExistenceRequirement::AllowDeath) - } - - /// Set the balances of a given account. - /// - /// This will alter `FreeBalance` and `ReservedBalance` in storage. it - /// will also decrease the total issuance of the system - /// (`TotalIssuance`). If the new free or reserved balance is below the - /// existential deposit, it will reap the `AccountInfo`. - /// - /// The dispatch origin for this call is `root`. - #[pallet::call_index(4)] - #[pallet::weight(T::WeightInfo::set_balance())] - pub fn set_balance( - origin: OriginFor, - who: ::Source, - currency_id: T::CurrencyId, - #[pallet::compact] new_free: T::Balance, - #[pallet::compact] new_reserved: T::Balance, - ) -> DispatchResult { - ensure_root(origin)?; - let who = T::Lookup::lookup(who)?; - - Self::try_mutate_account(&who, currency_id, |account, _| -> DispatchResult { - let mut new_total = new_free.checked_add(&new_reserved).ok_or(ArithmeticError::Overflow)?; - let (new_free, new_reserved) = if new_total < T::ExistentialDeposits::get(¤cy_id) { - new_total = Zero::zero(); - (Zero::zero(), Zero::zero()) - } else { - (new_free, new_reserved) - }; - let old_total = account.total(); - - account.free = new_free; - account.reserved = new_reserved; - - if new_total > old_total { - TotalIssuance::::try_mutate(currency_id, |t| -> DispatchResult { - *t = t - .checked_add(&(new_total.defensive_saturating_sub(old_total))) - .ok_or(ArithmeticError::Overflow)?; - Ok(()) - })?; - } else if new_total < old_total { - TotalIssuance::::try_mutate(currency_id, |t| -> DispatchResult { - *t = t - .checked_sub(&(old_total.defensive_saturating_sub(new_total))) - .ok_or(ArithmeticError::Underflow)?; - Ok(()) - })?; - } - - Self::deposit_event(Event::BalanceSet { - currency_id, - who: who.clone(), - free: new_free, - reserved: new_reserved, - }); - Ok(()) - })?; - - Ok(()) - } - } -} - -impl Pallet { - pub(crate) fn deposit_consequence( - _who: &T::AccountId, - currency_id: T::CurrencyId, - amount: T::Balance, - account: &AccountData, - ) -> DepositConsequence { - if amount.is_zero() { - return DepositConsequence::Success; - } - - if TotalIssuance::::get(currency_id).checked_add(&amount).is_none() { - return DepositConsequence::Overflow; - } - - let new_total_balance = match account.total().checked_add(&amount) { - Some(x) => x, - None => return DepositConsequence::Overflow, - }; - - if new_total_balance < T::ExistentialDeposits::get(¤cy_id) { - return DepositConsequence::BelowMinimum; - } - - // NOTE: We assume that we are a provider, so don't need to do any checks in the - // case of account creation. - - DepositConsequence::Success - } - - pub(crate) fn withdraw_consequence( - who: &T::AccountId, - currency_id: T::CurrencyId, - amount: T::Balance, - account: &AccountData, - ) -> WithdrawConsequence { - if amount.is_zero() { - return WithdrawConsequence::Success; - } - - if TotalIssuance::::get(currency_id).checked_sub(&amount).is_none() { - return WithdrawConsequence::Underflow; - } - - let new_total_balance = match account.total().checked_sub(&amount) { - Some(x) => x, - None => return WithdrawConsequence::BalanceLow, - }; - - // Provider restriction - total account balance cannot be reduced to zero if it - // cannot sustain the loss of a provider reference. - // NOTE: This assumes that the pallet is a provider (which is true). Is this - // ever changes, then this will need to adapt accordingly. - let ed = T::ExistentialDeposits::get(¤cy_id); - let success = if new_total_balance < ed { - if frame_system::Pallet::::can_dec_provider(who) { - WithdrawConsequence::ReducedToZero(new_total_balance) - } else { - return WithdrawConsequence::WouldDie; - } - } else { - WithdrawConsequence::Success - }; - - // Enough free funds to have them be reduced. - let new_free_balance = match account.free.checked_sub(&amount) { - Some(b) => b, - None => return WithdrawConsequence::BalanceLow, - }; - - // Eventual free funds must be no less than the frozen balance. - if new_free_balance < account.frozen() { - return WithdrawConsequence::Frozen; - } - - success - } - - // Ensure that an account can withdraw from their free balance given any - // existing withdrawal restrictions like locks and vesting balance. - // Is a no-op if amount to be withdrawn is zero. - pub(crate) fn ensure_can_withdraw( - currency_id: T::CurrencyId, - who: &T::AccountId, - amount: T::Balance, - ) -> DispatchResult { - if amount.is_zero() { - return Ok(()); - } - - let new_balance = Self::free_balance(currency_id, who) - .checked_sub(&amount) - .ok_or(Error::::BalanceTooLow)?; - ensure!( - new_balance >= Self::accounts(who, currency_id).frozen(), - Error::::LiquidityRestrictions - ); - Ok(()) - } - - pub(crate) fn try_mutate_account( - who: &T::AccountId, - currency_id: T::CurrencyId, - f: impl FnOnce(&mut AccountData, bool) -> sp_std::result::Result, - ) -> sp_std::result::Result<(R, Option), E> { - Accounts::::try_mutate_exists(who, currency_id, |maybe_account| { - let existed = maybe_account.is_some(); - let mut account = maybe_account.take().unwrap_or_default(); - f(&mut account, existed).map(move |result| { - let maybe_endowed = if !existed { Some(account.free) } else { None }; - let mut maybe_dust: Option = None; - let total = account.total(); - *maybe_account = if total < T::ExistentialDeposits::get(¤cy_id) { - // if ED is not zero, but account total is zero, account will be reaped - if total.is_zero() { - None - } else { - if !T::DustRemovalWhitelist::contains(who) { - maybe_dust = Some(total); - } - Some(account) - } - } else { - // Note: if ED is zero, account will never be reaped - Some(account) - }; - - (maybe_endowed, existed, maybe_account.is_some(), maybe_dust, result) - }) - }) - .map(|(maybe_endowed, existed, exists, maybe_dust, result)| { - if existed && !exists { - // If existed before, decrease account provider. - // Ignore the result, because if it failed then there are remaining consumers, - // and the account storage in frame_system shouldn't be reaped. - let _ = frame_system::Pallet::::dec_providers(who); - >::OnKilledTokenAccount::happened(&(who.clone(), currency_id)); - } else if !existed && exists { - // if new, increase account provider - frame_system::Pallet::::inc_providers(who); - >::OnNewTokenAccount::happened(&(who.clone(), currency_id)); - } - - if let Some(endowed) = maybe_endowed { - Self::deposit_event(Event::Endowed { - currency_id, - who: who.clone(), - amount: endowed, - }); - } - - if let Some(dust_amount) = maybe_dust { - // `OnDust` maybe get/set storage `Accounts` of `who`, trigger handler here - // to avoid some unexpected errors. - >::OnDust::on_dust(who, currency_id, dust_amount); - - Self::deposit_event(Event::DustLost { - currency_id, - who: who.clone(), - amount: dust_amount, - }); - } - - (result, maybe_dust) - }) - } - - pub(crate) fn mutate_account( - who: &T::AccountId, - currency_id: T::CurrencyId, - f: impl FnOnce(&mut AccountData, bool) -> R, - ) -> (R, Option) { - Self::try_mutate_account(who, currency_id, |account, existed| -> Result { - Ok(f(account, existed)) - }) - .expect("Error is infallible; qed") - } - - /// Set free balance of `who` to a new value. - /// - /// Note: this will not maintain total issuance, and the caller is expected - /// to do it. If it will cause the account to be removed dust, shouldn't use - /// it, because maybe the account that should be reaped to remain due to - /// failed transfer/withdraw dust. - pub(crate) fn set_free_balance(currency_id: T::CurrencyId, who: &T::AccountId, amount: T::Balance) { - Self::mutate_account(who, currency_id, |account, _| { - account.free = amount; - - Self::deposit_event(Event::BalanceSet { - currency_id, - who: who.clone(), - free: account.free, - reserved: account.reserved, - }); - }); - } - - /// Set reserved balance of `who` to a new value. - /// - /// Note: this will not maintain total issuance, and the caller is expected - /// to do it. If it will cause the account to be removed dust, shouldn't use - /// it, because maybe the account that should be reaped to remain due to - /// failed transfer/withdraw dust. - pub(crate) fn set_reserved_balance(currency_id: T::CurrencyId, who: &T::AccountId, amount: T::Balance) { - Self::mutate_account(who, currency_id, |account, _| { - account.reserved = amount; - - Self::deposit_event(Event::BalanceSet { - currency_id, - who: who.clone(), - free: account.free, - reserved: account.reserved, - }); - }); - } - - /// Update the account entry for `who` under `currency_id`, given the - /// locks. - pub(crate) fn update_locks( - currency_id: T::CurrencyId, - who: &T::AccountId, - locks: &[BalanceLock], - ) -> DispatchResult { - // track lock delta - let mut total_frozen_prev = Zero::zero(); - let mut total_frozen_after = Zero::zero(); - - // update account data - Self::mutate_account(who, currency_id, |account, _| { - total_frozen_prev = account.frozen; - account.frozen = Zero::zero(); - for lock in locks.iter() { - account.frozen = account.frozen.max(lock.amount); - } - total_frozen_after = account.frozen; - }); - - // update locks - let existed = Locks::::contains_key(who, currency_id); - if locks.is_empty() { - Locks::::remove(who, currency_id); - if existed { - // decrease account ref count when destruct lock - frame_system::Pallet::::dec_consumers(who); - } - } else { - let bounded_locks: BoundedVec, T::MaxLocks> = - locks.to_vec().try_into().map_err(|_| Error::::MaxLocksExceeded)?; - Locks::::insert(who, currency_id, bounded_locks); - if !existed { - // increase account ref count when initialize lock - if frame_system::Pallet::::inc_consumers(who).is_err() { - // No providers for the locks. This is impossible under normal circumstances - // since the funds that are under the lock will themselves be stored in the - // account and therefore will need a reference. - log::warn!( - "Warning: Attempt to introduce lock consumer reference, yet no providers. \ - This is unexpected but should be safe." - ); - } - } - } - - if total_frozen_prev < total_frozen_after { - let amount = total_frozen_after.saturating_sub(total_frozen_prev); - Self::deposit_event(Event::Locked { - currency_id, - who: who.clone(), - amount, - }); - } else if total_frozen_prev > total_frozen_after { - let amount = total_frozen_prev.saturating_sub(total_frozen_after); - Self::deposit_event(Event::Unlocked { - currency_id, - who: who.clone(), - amount, - }); - } - - Ok(()) - } - - /// Transfer some free balance from `from` to `to`. Ensure from_account - /// allow death or new balance will not be reaped, and ensure - /// to_account will not be removed dust. - /// - /// Is a no-op if value to be transferred is zero or the `from` is the same - /// as `to`. - pub(crate) fn do_transfer( - currency_id: T::CurrencyId, - from: &T::AccountId, - to: &T::AccountId, - amount: T::Balance, - existence_requirement: ExistenceRequirement, - ) -> DispatchResult { - if amount.is_zero() || from == to { - return Ok(()); - } - - >::PreTransfer::on_transfer( - currency_id, - from, - to, - amount, - )?; - Self::try_mutate_account(to, currency_id, |to_account, _existed| -> DispatchResult { - Self::try_mutate_account(from, currency_id, |from_account, _existed| -> DispatchResult { - from_account.free = from_account - .free - .checked_sub(&amount) - .ok_or(Error::::BalanceTooLow)?; - to_account.free = to_account.free.checked_add(&amount).ok_or(ArithmeticError::Overflow)?; - - let ed = T::ExistentialDeposits::get(¤cy_id); - // if the total of `to_account` is below existential deposit, would return an - // error. - // Note: if `to_account` is in `T::DustRemovalWhitelist`, can bypass this check. - ensure!( - to_account.total() >= ed || T::DustRemovalWhitelist::contains(to), - Error::::ExistentialDeposit - ); - - Self::ensure_can_withdraw(currency_id, from, amount)?; - - let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; - let allow_death = allow_death && frame_system::Pallet::::can_dec_provider(from); - let would_be_dead = if from_account.total() < ed { - if from_account.total().is_zero() { - true - } else { - // Note: if account is not in `T::DustRemovalWhitelist`, account will eventually - // be reaped due to the dust removal. - !T::DustRemovalWhitelist::contains(from) - } - } else { - false - }; - - ensure!(allow_death || !would_be_dead, Error::::KeepAlive); - Ok(()) - })?; - Ok(()) - })?; - - >::PostTransfer::on_transfer( - currency_id, - from, - to, - amount, - )?; - Self::deposit_event(Event::Transfer { - currency_id, - from: from.clone(), - to: to.clone(), - amount, - }); - Ok(()) - } - - /// Withdraw some free balance from an account, respecting existence - /// requirements. - /// - /// `change_total_issuance`: - /// - true, decrease the total issuance by burned amount. - /// - false, do not update the total issuance. - /// - /// Is a no-op if value to be withdrawn is zero. - pub(crate) fn do_withdraw( - currency_id: T::CurrencyId, - who: &T::AccountId, - amount: T::Balance, - existence_requirement: ExistenceRequirement, - change_total_issuance: bool, - ) -> DispatchResult { - if amount.is_zero() { - return Ok(()); - } - - Self::try_mutate_account(who, currency_id, |account, _existed| -> DispatchResult { - Self::ensure_can_withdraw(currency_id, who, amount)?; - let previous_total = account.total(); - account.free = account.free.defensive_saturating_sub(amount); - - let ed = T::ExistentialDeposits::get(¤cy_id); - let would_be_dead = if account.total() < ed { - if account.total().is_zero() { - true - } else { - // Note: if account is not in `T::DustRemovalWhitelist`, account will eventually - // be reaped due to the dust removal. - !T::DustRemovalWhitelist::contains(who) - } - } else { - false - }; - let would_kill = would_be_dead && (previous_total >= ed || !previous_total.is_zero()); - ensure!( - existence_requirement == ExistenceRequirement::AllowDeath || !would_kill, - Error::::KeepAlive - ); - - if change_total_issuance { - TotalIssuance::::mutate(currency_id, |v| *v = v.defensive_saturating_sub(amount)); - } - - Self::deposit_event(Event::Withdrawn { - currency_id, - who: who.clone(), - amount, - }); - Ok(()) - })?; - - Ok(()) - } - - /// Deposit some `value` into the free balance of `who`. - /// - /// `require_existed`: - /// - true, the account must already exist, do not require ED. - /// - false, possibly creating a new account, require ED if the account does - /// not yet exist, but except this account is in the dust removal - /// whitelist. - /// - /// `change_total_issuance`: - /// - true, increase the issued amount to total issuance. - /// - false, do not update the total issuance. - pub(crate) fn do_deposit( - currency_id: T::CurrencyId, - who: &T::AccountId, - amount: T::Balance, - require_existed: bool, - change_total_issuance: bool, - ) -> Result { - if amount.is_zero() { - return Ok(amount); - } - - >::PreDeposit::on_deposit( - currency_id, - who, - amount, - )?; - Self::try_mutate_account(who, currency_id, |account, existed| -> DispatchResult { - if require_existed { - ensure!(existed, Error::::DeadAccount); - } else { - let ed = T::ExistentialDeposits::get(¤cy_id); - // Note: if who is in dust removal whitelist, allow to deposit the amount that - // below ED to it. - ensure!( - amount >= ed || existed || T::DustRemovalWhitelist::contains(who), - Error::::ExistentialDeposit - ); - } - - let new_total_issuance = Self::total_issuance(currency_id) - .checked_add(&amount) - .ok_or(ArithmeticError::Overflow)?; - if change_total_issuance { - TotalIssuance::::mutate(currency_id, |v| *v = new_total_issuance); - } - account.free = account.free.defensive_saturating_add(amount); - Ok(()) - })?; - >::PostDeposit::on_deposit( - currency_id, - who, - amount, - )?; - Self::deposit_event(Event::Deposited { - currency_id, - who: who.clone(), - amount, - }); - Ok(amount) - } -} - -impl MultiCurrency for Pallet { - type CurrencyId = T::CurrencyId; - type Balance = T::Balance; - - fn minimum_balance(currency_id: Self::CurrencyId) -> Self::Balance { - T::ExistentialDeposits::get(¤cy_id) - } - - fn total_issuance(currency_id: Self::CurrencyId) -> Self::Balance { - Self::total_issuance(currency_id) - } - - fn total_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { - Self::accounts(who, currency_id).total() - } - - fn free_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { - Self::accounts(who, currency_id).free - } - - fn ensure_can_withdraw(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - Self::ensure_can_withdraw(currency_id, who, amount) - } - - fn transfer( - currency_id: Self::CurrencyId, - from: &T::AccountId, - to: &T::AccountId, - amount: Self::Balance, - existence_requirement: ExistenceRequirement, - ) -> DispatchResult { - // allow death - Self::do_transfer(currency_id, from, to, amount, existence_requirement) - } - - fn deposit(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - // do not require existing - Self::do_deposit(currency_id, who, amount, false, true)?; - Ok(()) - } - - fn withdraw( - currency_id: Self::CurrencyId, - who: &T::AccountId, - amount: Self::Balance, - existence_requirement: ExistenceRequirement, - ) -> DispatchResult { - // allow death - Self::do_withdraw(currency_id, who, amount, existence_requirement, true) - } - - // Check if `value` amount of free balance can be slashed from `who`. - fn can_slash(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> bool { - if value.is_zero() { - return true; - } - Self::free_balance(currency_id, who) >= value - } - - /// Is a no-op if `value` to be slashed is zero. - /// - /// NOTE: `slash()` prefers free balance, but assumes that reserve - /// balance can be drawn from in extreme circumstances. `can_slash()` - /// should be used prior to `slash()` to avoid having to draw from - /// reserved funds, however we err on the side of punishment if things - /// are inconsistent or `can_slash` wasn't used appropriately. - fn slash(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> Self::Balance { - if amount.is_zero() { - return amount; - } - - >::OnSlash::on_slash( - currency_id, - who, - amount, - ); - let account = Self::accounts(who, currency_id); - let free_slashed_amount = account.free.min(amount); - // Cannot underflow because free_slashed_amount can never be greater than amount - // but just to be defensive here. - let mut remaining_slash = amount.defensive_saturating_sub(free_slashed_amount); - - // slash free balance - if !free_slashed_amount.is_zero() { - // Cannot underflow because free_slashed_amount can never be greater than - // account.free but just to be defensive here. - Self::set_free_balance( - currency_id, - who, - account.free.defensive_saturating_sub(free_slashed_amount), - ); - } - - // slash reserved balance - let reserved_slashed_amount = account.reserved.min(remaining_slash); - - if !reserved_slashed_amount.is_zero() { - // Cannot underflow due to above line but just to be defensive here. - remaining_slash = remaining_slash.defensive_saturating_sub(reserved_slashed_amount); - Self::set_reserved_balance( - currency_id, - who, - account.reserved.defensive_saturating_sub(reserved_slashed_amount), - ); - } - - // Cannot underflow because the slashed value cannot be greater than total - // issuance but just to be defensive here. - TotalIssuance::::mutate(currency_id, |v| { - *v = v.defensive_saturating_sub(amount.defensive_saturating_sub(remaining_slash)) - }); - - Self::deposit_event(Event::Slashed { - currency_id, - who: who.clone(), - free_amount: free_slashed_amount, - reserved_amount: reserved_slashed_amount, - }); - remaining_slash - } -} - -impl MultiCurrencyExtended for Pallet { - type Amount = T::Amount; - - fn update_balance(currency_id: Self::CurrencyId, who: &T::AccountId, by_amount: Self::Amount) -> DispatchResult { - if by_amount.is_zero() { - return Ok(()); - } - - // Ensure this doesn't overflow. There isn't any traits that exposes - // `saturating_abs` so we need to do it manually. - let by_amount_abs = if by_amount == Self::Amount::min_value() { - Self::Amount::max_value() - } else { - by_amount.abs() - }; - - let by_balance = - TryInto::::try_into(by_amount_abs).map_err(|_| Error::::AmountIntoBalanceFailed)?; - if by_amount.is_positive() { - Self::deposit(currency_id, who, by_balance) - } else { - Self::withdraw(currency_id, who, by_balance, ExistenceRequirement::AllowDeath).map(|_| ()) - } - } -} - -impl MultiLockableCurrency for Pallet { - type Moment = BlockNumberFor; - - // Set a lock on the balance of `who` under `currency_id`. - // Is a no-op if lock amount is zero. - fn set_lock( - lock_id: LockIdentifier, - currency_id: Self::CurrencyId, - who: &T::AccountId, - amount: Self::Balance, - ) -> DispatchResult { - if amount.is_zero() { - return Ok(()); - } - let mut new_lock = Some(BalanceLock { id: lock_id, amount }); - let mut locks = Self::locks(who, currency_id) - .into_iter() - .filter_map(|lock| { - if lock.id == lock_id { - new_lock.take() - } else { - Some(lock) - } - }) - .collect::>(); - if let Some(lock) = new_lock { - locks.push(lock) - } - Self::update_locks(currency_id, who, &locks[..])?; - - Self::deposit_event(Event::LockSet { - lock_id, - currency_id, - who: who.clone(), - amount, - }); - Ok(()) - } - - // Extend a lock on the balance of `who` under `currency_id`. - // Is a no-op if lock amount is zero - fn extend_lock( - lock_id: LockIdentifier, - currency_id: Self::CurrencyId, - who: &T::AccountId, - amount: Self::Balance, - ) -> DispatchResult { - if amount.is_zero() { - return Ok(()); - } - let mut new_lock = Some(BalanceLock { id: lock_id, amount }); - let mut locks = Self::locks(who, currency_id) - .into_iter() - .filter_map(|lock| { - if lock.id == lock_id { - new_lock.take().map(|nl| { - let new_amount = lock.amount.max(nl.amount); - Self::deposit_event(Event::LockSet { - lock_id, - currency_id, - who: who.clone(), - amount: new_amount, - }); - BalanceLock { - id: lock.id, - amount: new_amount, - } - }) - } else { - Some(lock) - } - }) - .collect::>(); - if let Some(lock) = new_lock { - Self::deposit_event(Event::LockSet { - lock_id, - currency_id, - who: who.clone(), - amount: lock.amount, - }); - locks.push(lock) - } - Self::update_locks(currency_id, who, &locks[..]) - } - - fn remove_lock(lock_id: LockIdentifier, currency_id: Self::CurrencyId, who: &T::AccountId) -> DispatchResult { - let mut locks = Self::locks(who, currency_id); - locks.retain(|lock| lock.id != lock_id); - let locks_vec = locks.to_vec(); - Self::update_locks(currency_id, who, &locks_vec[..])?; - - Self::deposit_event(Event::LockRemoved { - lock_id, - currency_id, - who: who.clone(), - }); - Ok(()) - } -} - -impl MultiReservableCurrency for Pallet { - /// Check if `who` can reserve `value` from their free balance. - /// - /// Always `true` if value to be reserved is zero. - fn can_reserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> bool { - if value.is_zero() { - return true; - } - Self::ensure_can_withdraw(currency_id, who, value).is_ok() - } - - /// Slash from reserved balance, returning any amount that was unable to - /// be slashed. - /// - /// Is a no-op if the value to be slashed is zero. - fn slash_reserved(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> Self::Balance { - if value.is_zero() { - return value; - } - - >::OnSlash::on_slash( - currency_id, - who, - value, - ); - let reserved_balance = Self::reserved_balance(currency_id, who); - let actual = reserved_balance.min(value); - Self::mutate_account(who, currency_id, |account, _| { - // ensured reserved_balance >= actual but just to be defensive here. - account.reserved = reserved_balance.defensive_saturating_sub(actual); - }); - TotalIssuance::::mutate(currency_id, |v| *v = v.defensive_saturating_sub(actual)); - - Self::deposit_event(Event::Slashed { - currency_id, - who: who.clone(), - free_amount: Zero::zero(), - reserved_amount: actual, - }); - value.defensive_saturating_sub(actual) - } - - fn reserved_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { - Self::accounts(who, currency_id).reserved - } - - /// Move `value` from the free balance from `who` to their reserved - /// balance. - /// - /// Is a no-op if value to be reserved is zero. - fn reserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> DispatchResult { - if value.is_zero() { - return Ok(()); - } - Self::ensure_can_withdraw(currency_id, who, value)?; - - Self::mutate_account(who, currency_id, |account, _| { - account.free = account.free.defensive_saturating_sub(value); - account.reserved = account.reserved.defensive_saturating_add(value); - - Self::deposit_event(Event::Reserved { - currency_id, - who: who.clone(), - amount: value, - }); - }); - - Ok(()) - } - - /// Unreserve some funds, returning any amount that was unable to be - /// unreserved. - /// - /// Is a no-op if the value to be unreserved is zero. - fn unreserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> Self::Balance { - if value.is_zero() { - return value; - } - - let (remaining, _) = Self::mutate_account(who, currency_id, |account, _| { - let actual = account.reserved.min(value); - account.reserved = account.reserved.defensive_saturating_sub(actual); - account.free = account.free.defensive_saturating_add(actual); - - Self::deposit_event(Event::Unreserved { - currency_id, - who: who.clone(), - amount: actual, - }); - value.defensive_saturating_sub(actual) - }); - - remaining - } - - /// Move the reserved balance of one account into the balance of - /// another, according to `status`. - /// - /// Is a no-op if: - /// - the value to be moved is zero; or - /// - the `slashed` id equal to `beneficiary` and the `status` is - /// `Reserved`. - fn repatriate_reserved( - currency_id: Self::CurrencyId, - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: BalanceStatus, - ) -> sp_std::result::Result { - if value.is_zero() { - return Ok(value); - } - - if slashed == beneficiary { - return match status { - BalanceStatus::Free => Ok(Self::unreserve(currency_id, slashed, value)), - BalanceStatus::Reserved => Ok(value.saturating_sub(Self::reserved_balance(currency_id, slashed))), - }; - } - - let from_account = Self::accounts(slashed, currency_id); - let to_account = Self::accounts(beneficiary, currency_id); - let actual = from_account.reserved.min(value); - match status { - BalanceStatus::Free => { - Self::set_free_balance( - currency_id, - beneficiary, - to_account.free.defensive_saturating_add(actual), - ); - } - BalanceStatus::Reserved => { - Self::set_reserved_balance( - currency_id, - beneficiary, - to_account.reserved.defensive_saturating_add(actual), - ); - } - } - Self::set_reserved_balance( - currency_id, - slashed, - from_account.reserved.defensive_saturating_sub(actual), - ); - - Self::deposit_event(Event::::ReserveRepatriated { - currency_id, - from: slashed.clone(), - to: beneficiary.clone(), - amount: actual, - status, - }); - Ok(value.defensive_saturating_sub(actual)) - } -} - -impl NamedMultiReservableCurrency for Pallet { - type ReserveIdentifier = T::ReserveIdentifier; - - fn reserved_balance_named( - id: &Self::ReserveIdentifier, - currency_id: Self::CurrencyId, - who: &T::AccountId, - ) -> Self::Balance { - let reserves = Self::reserves(who, currency_id); - reserves - .binary_search_by_key(id, |data| data.id) - .map(|index| reserves[index].amount) - .unwrap_or_default() - } - - /// Move `value` from the free balance from `who` to a named reserve - /// balance. - /// - /// Is a no-op if value to be reserved is zero. - fn reserve_named( - id: &Self::ReserveIdentifier, - currency_id: Self::CurrencyId, - who: &T::AccountId, - value: Self::Balance, - ) -> DispatchResult { - if value.is_zero() { - return Ok(()); - } - - Reserves::::try_mutate(who, currency_id, |reserves| -> DispatchResult { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - // this add can't overflow but just to be defensive. - reserves[index].amount = reserves[index].amount.defensive_saturating_add(value); - } - Err(index) => { - reserves - .try_insert(index, ReserveData { id: *id, amount: value }) - .map_err(|_| Error::::TooManyReserves)?; - } - }; - >::reserve(currency_id, who, value) - }) - } - - /// Unreserve some funds, returning any amount that was unable to be - /// unreserved. - /// - /// Is a no-op if the value to be unreserved is zero. - fn unreserve_named( - id: &Self::ReserveIdentifier, - currency_id: Self::CurrencyId, - who: &T::AccountId, - value: Self::Balance, - ) -> Self::Balance { - if value.is_zero() { - return Zero::zero(); - } - - Reserves::::mutate_exists(who, currency_id, |maybe_reserves| -> Self::Balance { - if let Some(reserves) = maybe_reserves.as_mut() { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let remain = >::unreserve(currency_id, who, to_change); - - // remain should always be zero but just to be defensive here. - let actual = to_change.defensive_saturating_sub(remain); - - // `actual <= to_change` and `to_change <= amount`, but just to be defensive - // here. - reserves[index].amount = reserves[index].amount.defensive_saturating_sub(actual); - - if reserves[index].amount.is_zero() { - if reserves.len() == 1 { - // no more named reserves - *maybe_reserves = None; - } else { - // remove this named reserve - reserves.remove(index); - } - } - value.defensive_saturating_sub(actual) - } - Err(_) => value, - } - } else { - value - } - }) - } - - /// Slash from reserved balance, returning the amount that was unable to be - /// slashed. - /// - /// Is a no-op if the value to be slashed is zero. - fn slash_reserved_named( - id: &Self::ReserveIdentifier, - currency_id: Self::CurrencyId, - who: &T::AccountId, - value: Self::Balance, - ) -> Self::Balance { - if value.is_zero() { - return Zero::zero(); - } - - Reserves::::mutate(who, currency_id, |reserves| -> Self::Balance { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let remain = >::slash_reserved(currency_id, who, to_change); - - // remain should always be zero but just to be defensive here. - let actual = to_change.defensive_saturating_sub(remain); - - // `actual <= to_change` and `to_change <= amount` but just to be defensive - // here. - reserves[index].amount = reserves[index].amount.defensive_saturating_sub(actual); - - Self::deposit_event(Event::Slashed { - who: who.clone(), - currency_id, - free_amount: Zero::zero(), - reserved_amount: actual, - }); - value.defensive_saturating_sub(actual) - } - Err(_) => value, - } - }) - } - - /// Move the reserved balance of one account into the balance of another, - /// according to `status`. If `status` is `Reserved`, the balance will be - /// reserved with given `id`. - /// - /// Is a no-op if: - /// - the value to be moved is zero; or - /// - the `slashed` id equal to `beneficiary` and the `status` is - /// `Reserved`. - fn repatriate_reserved_named( - id: &Self::ReserveIdentifier, - currency_id: Self::CurrencyId, - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: Status, - ) -> Result { - if value.is_zero() { - return Ok(Zero::zero()); - } - - if slashed == beneficiary { - return match status { - Status::Free => Ok(Self::unreserve_named(id, currency_id, slashed, value)), - Status::Reserved => Ok(value.saturating_sub(Self::reserved_balance_named(id, currency_id, slashed))), - }; - } - - Reserves::::try_mutate( - slashed, - currency_id, - |reserves| -> Result { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let to_change = cmp::min(reserves[index].amount, value); - - let actual = if status == Status::Reserved { - // make it the reserved under same identifier - Reserves::::try_mutate( - beneficiary, - currency_id, - |reserves| -> Result { - match reserves.binary_search_by_key(id, |data| data.id) { - Ok(index) => { - let remain = >::repatriate_reserved( - currency_id, - slashed, - beneficiary, - to_change, - status, - )?; - - // remain should always be zero but just to be defensive - // here. - let actual = to_change.defensive_saturating_sub(remain); - - // this add can't overflow but just to be defensive. - reserves[index].amount = - reserves[index].amount.defensive_saturating_add(actual); - - Ok(actual) - } - Err(index) => { - let remain = >::repatriate_reserved( - currency_id, - slashed, - beneficiary, - to_change, - status, - )?; - - // remain should always be zero but just to be defensive - // here - let actual = to_change.defensive_saturating_sub(remain); - - reserves - .try_insert( - index, - ReserveData { - id: *id, - amount: actual, - }, - ) - .map_err(|_| Error::::TooManyReserves)?; - - Ok(actual) - } - } - }, - )? - } else { - let remain = >::repatriate_reserved( - currency_id, - slashed, - beneficiary, - to_change, - status, - )?; - - // remain should always be zero but just to be defensive here - to_change.defensive_saturating_sub(remain) - }; - - // `actual <= to_change` and `to_change <= amount` but just to be defensive - // here. - reserves[index].amount = reserves[index].amount.defensive_saturating_sub(actual); - Ok(value.defensive_saturating_sub(actual)) - } - Err(_) => Ok(value), - } - }, - ) - } -} - -impl fungibles::Inspect for Pallet { - type AssetId = T::CurrencyId; - type Balance = T::Balance; - - fn total_issuance(asset_id: Self::AssetId) -> Self::Balance { - Self::total_issuance(asset_id) - } - - fn minimum_balance(asset_id: Self::AssetId) -> Self::Balance { - T::ExistentialDeposits::get(&asset_id) - } - - fn balance(asset_id: Self::AssetId, who: &T::AccountId) -> Self::Balance { - Self::accounts(who, asset_id).free - } - - fn total_balance(asset_id: Self::AssetId, who: &T::AccountId) -> Self::Balance { - Self::accounts(who, asset_id).total() - } - - fn reducible_balance( - asset_id: Self::AssetId, - who: &T::AccountId, - preservation: Preservation, - _force: Fortitude, - ) -> Self::Balance { - let a = Self::accounts(who, asset_id); - // Liquid balance is what is neither reserved nor locked/frozen. - let liquid = a.free.saturating_sub(a.frozen); - if frame_system::Pallet::::can_dec_provider(who) - && !matches!(preservation, Preservation::Protect | Preservation::Preserve) - { - liquid - } else { - // `must_remain_to_exist` is the part of liquid balance which must remain to - // keep total over ED. - let must_remain_to_exist = - T::ExistentialDeposits::get(&asset_id).saturating_sub(a.total().saturating_sub(liquid)); - liquid.saturating_sub(must_remain_to_exist) - } - } - - fn can_deposit( - asset_id: Self::AssetId, - who: &T::AccountId, - amount: Self::Balance, - _provenance: Provenance, - ) -> DepositConsequence { - Self::deposit_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)) - } - - fn can_withdraw( - asset_id: Self::AssetId, - who: &T::AccountId, - amount: Self::Balance, - ) -> WithdrawConsequence { - Self::withdraw_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)) - } - - fn asset_exists(asset: Self::AssetId) -> bool { - TotalIssuance::::contains_key(asset) - } -} - -impl fungibles::Mutate for Pallet { - fn mint_into( - asset_id: Self::AssetId, - who: &T::AccountId, - amount: Self::Balance, - ) -> Result { - Self::deposit_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)).into_result()?; - // do not require existing - Self::do_deposit(asset_id, who, amount, false, true) - } - - fn burn_from( - asset_id: Self::AssetId, - who: &T::AccountId, - amount: Self::Balance, - // TODO: Respect preservation - _preservation: Preservation, - // TODO: Respect precision - _precision: Precision, - // TODO: Respect fortitude - _fortitude: Fortitude, - ) -> Result { - let extra = - Self::withdraw_consequence(who, asset_id, amount, &Self::accounts(who, asset_id)).into_result(false)?; - let actual = amount.defensive_saturating_add(extra); - // allow death - Self::do_withdraw(asset_id, who, actual, ExistenceRequirement::AllowDeath, true).map(|_| actual) - } - - fn transfer( - asset_id: Self::AssetId, - source: &T::AccountId, - dest: &T::AccountId, - amount: T::Balance, - preservation: Preservation, - ) -> Result { - let existence_requirement = match preservation { - Preservation::Expendable => ExistenceRequirement::AllowDeath, - Preservation::Protect | Preservation::Preserve => ExistenceRequirement::KeepAlive, - }; - Self::do_transfer(asset_id, source, dest, amount, existence_requirement).map(|_| amount) - } -} - -impl fungibles::Unbalanced for Pallet { - fn handle_dust(_dust: fungibles::Dust) { - // Dust is handled in account mutate method - } - - fn write_balance( - asset_id: Self::AssetId, - who: &T::AccountId, - amount: Self::Balance, - ) -> Result, DispatchError> { - let max_reduction = >::reducible_balance( - asset_id, - who, - Preservation::Expendable, - Fortitude::Force, - ); - - // Balance is the same type and will not overflow - let (_, dust_amount) = Self::try_mutate_account(who, asset_id, |account, _| -> Result<(), DispatchError> { - // Make sure the reduction (if there is one) is no more than the maximum - // allowed. - let reduction = account.free.saturating_sub(amount); - ensure!(reduction <= max_reduction, Error::::BalanceTooLow); - - account.free = amount; - Self::deposit_event(Event::BalanceSet { - currency_id: asset_id, - who: who.clone(), - free: account.free, - reserved: account.reserved, - }); - - Ok(()) - })?; - - Ok(dust_amount) - } - - fn set_total_issuance(asset_id: Self::AssetId, amount: Self::Balance) { - // Balance is the same type and will not overflow - TotalIssuance::::mutate(asset_id, |t| *t = amount); - - Self::deposit_event(Event::TotalIssuanceSet { - currency_id: asset_id, - amount, - }); - } - - fn decrease_balance( - asset: Self::AssetId, - who: &T::AccountId, - mut amount: Self::Balance, - precision: Precision, - preservation: Preservation, - force: Fortitude, - ) -> Result { - let old_balance = as fungibles::Inspect>::balance(asset, who); - let free = as fungibles::Inspect>::reducible_balance(asset, who, preservation, force); - if let Precision::BestEffort = precision { - amount = amount.min(free); - } - let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?; - let _dust_amount = Self::write_balance(asset, who, new_balance)?.unwrap_or_default(); - - // here just return decrease amount, shouldn't count the dust_amount - Ok(old_balance.saturating_sub(new_balance)) - } -} - -impl fungibles::Balanced for Pallet { - type OnDropDebt = fungibles::IncreaseIssuance; - type OnDropCredit = fungibles::DecreaseIssuance; - - fn done_deposit(currency_id: Self::AssetId, who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::Deposited { - currency_id, - who: who.clone(), - amount, - }); - } - fn done_withdraw(currency_id: Self::AssetId, who: &T::AccountId, amount: Self::Balance) { - Self::deposit_event(Event::Withdrawn { - currency_id, - who: who.clone(), - amount, - }); - } - fn done_issue(currency_id: Self::AssetId, amount: Self::Balance) { - Self::deposit_event(Event::Issued { currency_id, amount }); - } - fn done_rescind(currency_id: Self::AssetId, amount: Self::Balance) { - Self::deposit_event(Event::Rescinded { currency_id, amount }); - } -} - -type ReasonOf =

::AccountId>>::Reason; -impl fungibles::InspectHold for Pallet { - type Reason = (); - - fn balance_on_hold(asset_id: Self::AssetId, _reason: &Self::Reason, who: &T::AccountId) -> T::Balance { - Self::accounts(who, asset_id).reserved - } - - fn total_balance_on_hold(asset: Self::AssetId, who: &T::AccountId) -> Self::Balance { - Self::accounts(who, asset).reserved - } - - fn reducible_total_balance_on_hold(_asset: Self::AssetId, _who: &T::AccountId, _force: Fortitude) -> Self::Balance { - 0u32.into() - } - - fn hold_available(_asset: Self::AssetId, _reason: &Self::Reason, _who: &T::AccountId) -> bool { - true - } - - fn can_hold(asset_id: Self::AssetId, _reason: &Self::Reason, who: &T::AccountId, amount: T::Balance) -> bool { - let a = Self::accounts(who, asset_id); - let min_balance = T::ExistentialDeposits::get(&asset_id).max(a.frozen); - if a.reserved.checked_add(&amount).is_none() { - return false; - } - // We require it to be min_balance + amount to ensure that the full reserved - // funds may be slashed without compromising locked funds or destroying the - // account. - let required_free = match min_balance.checked_add(&amount) { - Some(x) => x, - None => return false, - }; - a.free >= required_free - } -} - -impl fungibles::MutateHold for Pallet { - fn hold( - asset_id: Self::AssetId, - _reason: &ReasonOf, - who: &T::AccountId, - amount: Self::Balance, - ) -> DispatchResult { - as MultiReservableCurrency<_>>::reserve(asset_id, who, amount) - } - - fn release( - asset_id: Self::AssetId, - _reason: &ReasonOf, - who: &T::AccountId, - amount: Self::Balance, - precision: Precision, - ) -> Result { - if amount.is_zero() { - return Ok(amount); - } - - // Done on a best-effort basis. - let (released, _) = - Self::try_mutate_account(who, asset_id, |a, _existed| -> Result { - let new_free = a.free.saturating_add(amount.min(a.reserved)); - let actual = new_free.defensive_saturating_sub(a.free); - // Guaranteed to be <= amount and <= a.reserved - ensure!( - matches!(precision, Precision::BestEffort) || actual == amount, - Error::::BalanceTooLow - ); - a.free = new_free; - a.reserved = a.reserved.saturating_sub(actual); - - Self::deposit_event(Event::Unreserved { - currency_id: asset_id, - who: who.clone(), - amount, - }); - Ok(actual) - })?; - - Ok(released) - } - - fn transfer_on_hold( - asset_id: Self::AssetId, - reason: &ReasonOf, - source: &T::AccountId, - dest: &T::AccountId, - amount: Self::Balance, - precision: Precision, - restriction: Restriction, - _fortitude: Fortitude, - ) -> Result { - let status = if restriction == Restriction::OnHold { - Status::Reserved - } else { - Status::Free - }; - ensure!( - amount <= >::balance_on_hold(asset_id, reason, source) - || precision == Precision::BestEffort, - Error::::BalanceTooLow - ); - let gap = Self::repatriate_reserved(asset_id, source, dest, amount, status)?; - // return actual transferred amount - Ok(amount.saturating_sub(gap)) - } -} - -impl fungibles::UnbalancedHold for Pallet { - fn set_balance_on_hold( - asset: Self::AssetId, - _reason: &Self::Reason, - who: &T::AccountId, - amount: Self::Balance, - ) -> DispatchResult { - // Balance is the same type and will not overflow - Self::try_mutate_account(who, asset, |account, _| -> Result<(), DispatchError> { - let old_reserved = account.reserved; - account.reserved = amount; - // free = free + old - new - account.free = account - .free - .checked_add(&old_reserved) - .ok_or(ArithmeticError::Overflow)? - .checked_sub(&account.reserved) - .ok_or(TokenError::BelowMinimum)?; - - Self::deposit_event(Event::BalanceSet { - currency_id: asset, - who: who.clone(), - free: account.free, - reserved: account.reserved, - }); - - Ok(()) - }) - .map(|_| ()) - } -} - -pub struct CurrencyAdapter(marker::PhantomData<(T, GetCurrencyId)>); - -impl PalletCurrency for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - type Balance = T::Balance; - type PositiveImbalance = PositiveImbalance; - type NegativeImbalance = NegativeImbalance; - - fn total_balance(who: &T::AccountId) -> Self::Balance { - as MultiCurrency<_>>::total_balance(GetCurrencyId::get(), who) - } - - fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { - as MultiCurrency<_>>::can_slash(GetCurrencyId::get(), who, value) - } - - fn total_issuance() -> Self::Balance { - as MultiCurrency<_>>::total_issuance(GetCurrencyId::get()) - } - - fn minimum_balance() -> Self::Balance { - as MultiCurrency<_>>::minimum_balance(GetCurrencyId::get()) - } - - fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { - if amount.is_zero() { - return PositiveImbalance::zero(); - } - let currency_id = GetCurrencyId::get(); - TotalIssuance::::mutate(currency_id, |issued| { - *issued = issued.checked_sub(&amount).unwrap_or_else(|| { - amount = *issued; - Zero::zero() - }) - }); - - Pallet::::deposit_event(Event::TotalIssuanceSet { - currency_id, - amount: Self::total_issuance(), - }); - PositiveImbalance::new(amount) - } - - fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { - if amount.is_zero() { - return NegativeImbalance::zero(); - } - TotalIssuance::::mutate(GetCurrencyId::get(), |issued| { - *issued = issued.checked_add(&amount).unwrap_or_else(|| { - amount = Self::Balance::max_value().defensive_saturating_sub(*issued); - Self::Balance::max_value() - }) - }); - - Pallet::::deposit_event(Event::TotalIssuanceSet { - currency_id: GetCurrencyId::get(), - amount: Self::total_issuance(), - }); - NegativeImbalance::new(amount) - } - - fn free_balance(who: &T::AccountId) -> Self::Balance { - as MultiCurrency<_>>::free_balance(GetCurrencyId::get(), who) - } - - fn ensure_can_withdraw( - who: &T::AccountId, - amount: Self::Balance, - _reasons: WithdrawReasons, - _new_balance: Self::Balance, - ) -> DispatchResult { - as MultiCurrency<_>>::ensure_can_withdraw(GetCurrencyId::get(), who, amount) - } - - fn transfer( - source: &T::AccountId, - dest: &T::AccountId, - value: Self::Balance, - existence_requirement: ExistenceRequirement, - ) -> DispatchResult { - Pallet::::do_transfer(GetCurrencyId::get(), source, dest, value, existence_requirement) - } - - fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { - if value.is_zero() { - return (Self::NegativeImbalance::zero(), value); - } - - let currency_id = GetCurrencyId::get(); - let account = Pallet::::accounts(who, currency_id); - let free_slashed_amount = account.free.min(value); - let mut remaining_slash = value.defensive_saturating_sub(free_slashed_amount); - - // slash free balance - if !free_slashed_amount.is_zero() { - Pallet::::set_free_balance( - currency_id, - who, - account.free.defensive_saturating_sub(free_slashed_amount), - ); - } - - // slash reserved balance - if !remaining_slash.is_zero() { - let reserved_slashed_amount = account.reserved.min(remaining_slash); - remaining_slash = remaining_slash.defensive_saturating_sub(reserved_slashed_amount); - Pallet::::set_reserved_balance( - currency_id, - who, - account.reserved.defensive_saturating_sub(reserved_slashed_amount), - ); - - Pallet::::deposit_event(Event::Slashed { - currency_id, - who: who.clone(), - free_amount: free_slashed_amount, - reserved_amount: reserved_slashed_amount, - }); - ( - Self::NegativeImbalance::new(free_slashed_amount.saturating_add(reserved_slashed_amount)), - remaining_slash, - ) - } else { - Pallet::::deposit_event(Event::Slashed { - currency_id, - who: who.clone(), - free_amount: value, - reserved_amount: Zero::zero(), - }); - (Self::NegativeImbalance::new(value), remaining_slash) - } - } - - /// Deposit some `value` into the free balance of an existing target account - /// `who`. - fn deposit_into_existing( - who: &T::AccountId, - value: Self::Balance, - ) -> sp_std::result::Result { - // do not change total issuance - Pallet::::do_deposit(GetCurrencyId::get(), who, value, true, false).map(|_| PositiveImbalance::new(value)) - } - - /// Deposit some `value` into the free balance of `who`, possibly creating a - /// new account. - fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { - // do not change total issuance - Pallet::::do_deposit(GetCurrencyId::get(), who, value, false, false) - .map_or_else(|_| Self::PositiveImbalance::zero(), |_| PositiveImbalance::new(value)) - } - - fn withdraw( - who: &T::AccountId, - value: Self::Balance, - _reasons: WithdrawReasons, - liveness: ExistenceRequirement, - ) -> sp_std::result::Result { - // do not change total issuance - Pallet::::do_withdraw(GetCurrencyId::get(), who, value, liveness, false) - .map(|_| Self::NegativeImbalance::new(value)) - } - - fn make_free_balance_be( - who: &T::AccountId, - value: Self::Balance, - ) -> SignedImbalance { - let currency_id = GetCurrencyId::get(); - Pallet::::try_mutate_account( - who, - currency_id, - |account, existed| -> Result, ()> { - // If we're attempting to set an existing account to less than ED, then - // bypass the entire operation. It's a no-op if you follow it through, but - // since this is an instance where we might account for a negative imbalance - // (in the dust cleaner of set_account) before we account for its actual - // equal and opposite cause (returned as an Imbalance), then in the - // instance that there's no other accounts on the system at all, we might - // underflow the issuance and our arithmetic will be off. - let ed = T::ExistentialDeposits::get(¤cy_id); - ensure!(value.saturating_add(account.reserved) >= ed || existed, ()); - - let imbalance = if account.free <= value { - SignedImbalance::Positive(PositiveImbalance::new(value.saturating_sub(account.free))) - } else { - SignedImbalance::Negative(NegativeImbalance::new(account.free.saturating_sub(value))) - }; - account.free = value; - - Pallet::::deposit_event(Event::BalanceSet { - currency_id, - who: who.clone(), - free: value, - reserved: account.reserved, - }); - Ok(imbalance) - }, - ) - .map(|(imbalance, _)| imbalance) - .unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero())) - } -} - -impl PalletReservableCurrency for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { - as MultiReservableCurrency<_>>::can_reserve(GetCurrencyId::get(), who, value) - } - - fn slash_reserved(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { - let actual = as MultiReservableCurrency<_>>::slash_reserved(GetCurrencyId::get(), who, value); - (Self::NegativeImbalance::zero(), actual) - } - - fn reserved_balance(who: &T::AccountId) -> Self::Balance { - as MultiReservableCurrency<_>>::reserved_balance(GetCurrencyId::get(), who) - } - - fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { - as MultiReservableCurrency<_>>::reserve(GetCurrencyId::get(), who, value) - } - - fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { - as MultiReservableCurrency<_>>::unreserve(GetCurrencyId::get(), who, value) - } - - fn repatriate_reserved( - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: Status, - ) -> sp_std::result::Result { - as MultiReservableCurrency<_>>::repatriate_reserved( - GetCurrencyId::get(), - slashed, - beneficiary, - value, - status, - ) - } -} - -impl PalletNamedReservableCurrency for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - type ReserveIdentifier = T::ReserveIdentifier; - - fn reserved_balance_named(id: &Self::ReserveIdentifier, who: &T::AccountId) -> Self::Balance { - as NamedMultiReservableCurrency<_>>::reserved_balance_named(id, GetCurrencyId::get(), who) - } - - fn reserve_named(id: &Self::ReserveIdentifier, who: &T::AccountId, value: Self::Balance) -> DispatchResult { - as NamedMultiReservableCurrency<_>>::reserve_named(id, GetCurrencyId::get(), who, value) - } - - fn unreserve_named(id: &Self::ReserveIdentifier, who: &T::AccountId, value: Self::Balance) -> Self::Balance { - as NamedMultiReservableCurrency<_>>::unreserve_named(id, GetCurrencyId::get(), who, value) - } - - fn slash_reserved_named( - id: &Self::ReserveIdentifier, - who: &T::AccountId, - value: Self::Balance, - ) -> (Self::NegativeImbalance, Self::Balance) { - let actual = - as NamedMultiReservableCurrency<_>>::slash_reserved_named(id, GetCurrencyId::get(), who, value); - (Self::NegativeImbalance::zero(), actual) - } - - fn repatriate_reserved_named( - id: &Self::ReserveIdentifier, - slashed: &T::AccountId, - beneficiary: &T::AccountId, - value: Self::Balance, - status: Status, - ) -> sp_std::result::Result { - as NamedMultiReservableCurrency<_>>::repatriate_reserved_named( - id, - GetCurrencyId::get(), - slashed, - beneficiary, - value, - status, - ) - } -} - -impl PalletLockableCurrency for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - type Moment = BlockNumberFor; - type MaxLocks = (); - - fn set_lock(id: LockIdentifier, who: &T::AccountId, amount: Self::Balance, _reasons: WithdrawReasons) { - let _ = as MultiLockableCurrency<_>>::set_lock(id, GetCurrencyId::get(), who, amount); - } - - fn extend_lock(id: LockIdentifier, who: &T::AccountId, amount: Self::Balance, _reasons: WithdrawReasons) { - let _ = as MultiLockableCurrency<_>>::extend_lock(id, GetCurrencyId::get(), who, amount); - } - - fn remove_lock(id: LockIdentifier, who: &T::AccountId) { - let _ = as MultiLockableCurrency<_>>::remove_lock(id, GetCurrencyId::get(), who); - } -} - -impl TransferAll for Pallet { - #[transactional] - fn transfer_all(source: &T::AccountId, dest: &T::AccountId) -> DispatchResult { - Accounts::::iter_prefix(source).try_for_each(|(currency_id, account_data)| -> DispatchResult { - // allow death - Self::do_transfer( - currency_id, - source, - dest, - account_data.free, - ExistenceRequirement::AllowDeath, - ) - }) - } -} - -impl fungible::Inspect for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - type Balance = T::Balance; - - fn total_issuance() -> Self::Balance { - as fungibles::Inspect<_>>::total_issuance(GetCurrencyId::get()) - } - fn minimum_balance() -> Self::Balance { - as fungibles::Inspect<_>>::minimum_balance(GetCurrencyId::get()) - } - fn balance(who: &T::AccountId) -> Self::Balance { - as fungibles::Inspect<_>>::balance(GetCurrencyId::get(), who) - } - fn total_balance(who: &T::AccountId) -> Self::Balance { - as fungibles::Inspect<_>>::total_balance(GetCurrencyId::get(), who) - } - fn reducible_balance(who: &T::AccountId, preservation: Preservation, fortitude: Fortitude) -> Self::Balance { - as fungibles::Inspect<_>>::reducible_balance(GetCurrencyId::get(), who, preservation, fortitude) - } - fn can_deposit(who: &T::AccountId, amount: Self::Balance, provenance: Provenance) -> DepositConsequence { - as fungibles::Inspect<_>>::can_deposit(GetCurrencyId::get(), who, amount, provenance) - } - fn can_withdraw(who: &T::AccountId, amount: Self::Balance) -> WithdrawConsequence { - as fungibles::Inspect<_>>::can_withdraw(GetCurrencyId::get(), who, amount) - } -} - -impl fungible::Mutate for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - fn mint_into(who: &T::AccountId, amount: Self::Balance) -> Result { - as fungibles::Mutate<_>>::mint_into(GetCurrencyId::get(), who, amount) - } - fn burn_from( - who: &T::AccountId, - amount: Self::Balance, - preservation: Preservation, - precision: Precision, - fortitude: Fortitude, - ) -> Result { - as fungibles::Mutate<_>>::burn_from( - GetCurrencyId::get(), - who, - amount, - preservation, - precision, - fortitude, - ) - } - - fn transfer( - source: &T::AccountId, - dest: &T::AccountId, - amount: T::Balance, - preservation: Preservation, - ) -> Result { - as fungibles::Mutate<_>>::transfer(GetCurrencyId::get(), source, dest, amount, preservation) - } -} - -impl fungible::Unbalanced for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - fn handle_dust(_dust: fungible::Dust) { - // Dust is handled in account mutate method - } - - fn write_balance(who: &T::AccountId, amount: Self::Balance) -> Result, DispatchError> { - as fungibles::Unbalanced<_>>::write_balance(GetCurrencyId::get(), who, amount) - } - fn set_total_issuance(amount: Self::Balance) { - as fungibles::Unbalanced<_>>::set_total_issuance(GetCurrencyId::get(), amount) - } -} - -type ReasonOfFungible =

::AccountId>>::Reason; -impl fungible::InspectHold for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - type Reason = as fungibles::InspectHold>::Reason; - - fn balance_on_hold(reason: &Self::Reason, who: &T::AccountId) -> T::Balance { - as fungibles::InspectHold<_>>::balance_on_hold(GetCurrencyId::get(), reason, who) - } - fn total_balance_on_hold(who: &T::AccountId) -> Self::Balance { - as fungibles::InspectHold<_>>::total_balance_on_hold(GetCurrencyId::get(), who) - } - fn reducible_total_balance_on_hold(who: &T::AccountId, force: Fortitude) -> Self::Balance { - as fungibles::InspectHold<_>>::reducible_total_balance_on_hold(GetCurrencyId::get(), who, force) - } - fn hold_available(reason: &Self::Reason, who: &T::AccountId) -> bool { - as fungibles::InspectHold<_>>::hold_available(GetCurrencyId::get(), reason, who) - } - fn can_hold(reason: &Self::Reason, who: &T::AccountId, amount: T::Balance) -> bool { - as fungibles::InspectHold<_>>::can_hold(GetCurrencyId::get(), reason, who, amount) - } -} - -impl fungible::MutateHold for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - fn hold(reason: &ReasonOfFungible, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - as fungibles::MutateHold<_>>::hold(GetCurrencyId::get(), reason, who, amount) - } - fn release( - reason: &ReasonOfFungible, - who: &T::AccountId, - amount: Self::Balance, - precision: Precision, - ) -> Result { - as fungibles::MutateHold<_>>::release(GetCurrencyId::get(), reason, who, amount, precision) - } - fn transfer_on_hold( - reason: &ReasonOfFungible, - source: &T::AccountId, - dest: &T::AccountId, - amount: Self::Balance, - precision: Precision, - restriction: Restriction, - fortitude: Fortitude, - ) -> Result { - as fungibles::MutateHold<_>>::transfer_on_hold( - GetCurrencyId::get(), - reason, - source, - dest, - amount, - precision, - restriction, - fortitude, - ) - } -} - -impl fungible::UnbalancedHold for CurrencyAdapter -where - T: Config, - GetCurrencyId: Get, -{ - fn set_balance_on_hold(reason: &Self::Reason, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - as fungibles::UnbalancedHold<_>>::set_balance_on_hold(GetCurrencyId::get(), reason, who, amount) - } -} diff --git a/pallets/tokens/src/mock.rs b/pallets/tokens/src/mock.rs deleted file mode 100644 index 5e1c62392..000000000 --- a/pallets/tokens/src/mock.rs +++ /dev/null @@ -1,445 +0,0 @@ -//! Mocks for the tokens module. - -#![cfg(test)] - -use super::*; -use frame_support::{ - construct_runtime, derive_impl, parameter_types, - traits::{ - tokens::{PayFromAccount, UnityAssetBalanceConversion}, - ChangeMembers, ConstU32, ConstU64, - }, - PalletId, -}; -use orml_traits::parameter_type_with_key; -use sp_runtime::{ - traits::{AccountIdConversion, BlockNumberProvider, IdentityLookup}, - AccountId32, BuildStorage, Permill, -}; -use sp_std::cell::RefCell; - -pub type AccountId = AccountId32; -pub type CurrencyId = u32; -pub type Balance = u64; -pub type ReserveIdentifier = [u8; 8]; - -pub const DOT: CurrencyId = 1; -pub const BTC: CurrencyId = 2; -pub const ETH: CurrencyId = 3; -pub const ALICE: AccountId = AccountId32::new([0u8; 32]); -pub const BOB: AccountId = AccountId32::new([1u8; 32]); -pub const CHARLIE: AccountId = AccountId32::new([2u8; 32]); -pub const DAVE: AccountId = AccountId32::new([3u8; 32]); -pub const TREASURY_ACCOUNT: AccountId = AccountId32::new([4u8; 32]); -pub const ID_1: LockIdentifier = *b"1 "; -pub const ID_2: LockIdentifier = *b"2 "; -pub const ID_3: LockIdentifier = *b"3 "; -pub const RID_1: ReserveIdentifier = [1u8; 8]; -pub const RID_2: ReserveIdentifier = [2u8; 8]; - -use crate as tokens; - -#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] -impl frame_system::Config for Runtime { - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Block = Block; -} - -thread_local! { - static TEN_TO_FOURTEEN: RefCell> = RefCell::new(vec![ - AccountId32::new([10u8; 32]), - AccountId32::new([11u8; 32]), - AccountId32::new([12u8; 32]), - AccountId32::new([13u8; 32]), - AccountId32::new([14u8; 32]), - ]); -} - -parameter_types! { - pub const ProposalBond: Permill = Permill::from_percent(5); - pub const Burn: Permill = Permill::from_percent(50); - pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); - pub const GetTokenId: CurrencyId = DOT; - pub TreasuryAccount: AccountId = Treasury::account_id(); -} - -pub type MockCurrencyAdapter = CurrencyAdapter; - -parameter_types! { - pub static MockBlockNumberProvider: u64 = 0; -} - -impl BlockNumberProvider for MockBlockNumberProvider { - type BlockNumber = u64; - - fn current_block_number() -> BlockNumberFor { - Self::get() - } -} - -impl pallet_treasury::Config for Runtime { - type PalletId = TreasuryPalletId; - type Currency = MockCurrencyAdapter; - type RejectOrigin = frame_system::EnsureRoot; - type RuntimeEvent = RuntimeEvent; - type SpendPeriod = ConstU64<2>; - type Burn = Burn; - type BurnDestination = (); // Just gets burned. - type WeightInfo = (); - type SpendFunds = (); - type MaxApprovals = ConstU32<100>; - type SpendOrigin = frame_support::traits::NeverEnsureOrigin; - type AssetKind = (); - type Beneficiary = Self::AccountId; - type BeneficiaryLookup = IdentityLookup; - type Paymaster = PayFromAccount; - type BalanceConverter = UnityAssetBalanceConversion; - type PayoutPeriod = ConstU64<10>; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); - type BlockNumberProvider = MockBlockNumberProvider; -} - -thread_local! { - pub static MEMBERS: RefCell> = RefCell::new(vec![]); - pub static PRIME: RefCell> = RefCell::new(None); -} - -pub struct TestChangeMembers; -impl ChangeMembers for TestChangeMembers { - fn change_members_sorted(incoming: &[AccountId], outgoing: &[AccountId], new: &[AccountId]) { - // new, incoming, outgoing must be sorted. - let mut new_sorted = new.to_vec(); - new_sorted.sort(); - assert_eq!(new, &new_sorted[..]); - - let mut incoming_sorted = incoming.to_vec(); - incoming_sorted.sort(); - assert_eq!(incoming, &incoming_sorted[..]); - - let mut outgoing_sorted = outgoing.to_vec(); - outgoing_sorted.sort(); - assert_eq!(outgoing, &outgoing_sorted[..]); - - // incoming and outgoing must be disjoint - for x in incoming.iter() { - assert!(outgoing.binary_search(x).is_err()); - } - - let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); - old_plus_incoming.extend_from_slice(incoming); - old_plus_incoming.sort(); - - let mut new_plus_outgoing = new.to_vec(); - new_plus_outgoing.extend_from_slice(outgoing); - new_plus_outgoing.sort(); - - assert_eq!( - old_plus_incoming, new_plus_outgoing, - "change members call is incorrect!" - ); - - MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); - PRIME.with(|p| *p.borrow_mut() = None); - } - - fn set_prime(who: Option) { - PRIME.with(|p| *p.borrow_mut() = who); - } -} - -parameter_types! { - pub const ElectionsPhragmenPalletId: LockIdentifier = *b"phrelect"; -} - -impl pallet_elections_phragmen::Config for Runtime { - type PalletId = ElectionsPhragmenPalletId; - type RuntimeEvent = RuntimeEvent; - type Currency = MockCurrencyAdapter; - type CurrencyToVote = sp_staking::currency_to_vote::SaturatingCurrencyToVote; - type ChangeMembers = TestChangeMembers; - type InitializeMembers = (); - type CandidacyBond = ConstU64<3>; - type VotingBondBase = ConstU64<2>; - type VotingBondFactor = ConstU64<0>; - type TermDuration = ConstU64<5>; - type DesiredMembers = ConstU32<2>; - type DesiredRunnersUp = ConstU32<2>; - type MaxCandidates = ConstU32<5>; - type MaxVoters = ConstU32<5>; - type MaxVotesPerVoter = (); - type LoserCandidate = (); - type KickedMember = (); - type WeightInfo = (); -} - -pub struct MockDustRemovalWhitelist; -impl Contains for MockDustRemovalWhitelist { - fn contains(a: &AccountId) -> bool { - *a == DAVE || *a == DustReceiver::get() - } -} - -parameter_type_with_key! { - pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance { - #[allow(clippy::match_ref_pats)] // false positive - match currency_id { - &BTC => 1, - &DOT => 2, - _ => 0, - } - }; -} - -thread_local! { - pub static CREATED: RefCell> = RefCell::new(vec![]); - pub static KILLED: RefCell> = RefCell::new(vec![]); -} - -pub struct TrackCreatedAccounts(marker::PhantomData); -impl TrackCreatedAccounts -where - T::AccountId: From + Into, - T::CurrencyId: From + Into, -{ - pub fn accounts() -> Vec<(T::AccountId, T::CurrencyId)> { - CREATED - .with(|accounts| accounts.borrow().clone()) - .iter() - .map(|account| (account.0.clone().into(), account.1.clone().into())) - .collect() - } - - pub fn reset() { - CREATED.with(|accounts| { - accounts.replace(vec![]); - }); - } -} -impl Happened<(T::AccountId, T::CurrencyId)> for TrackCreatedAccounts -where - T::AccountId: From + Into, - T::CurrencyId: From + Into, -{ - fn happened((who, currency): &(T::AccountId, T::CurrencyId)) { - CREATED.with(|accounts| { - accounts.borrow_mut().push((who.clone().into(), (*currency).into())); - }); - } -} - -pub struct TrackKilledAccounts(marker::PhantomData); -impl TrackKilledAccounts -where - T::AccountId: From + Into, - T::CurrencyId: From + Into, -{ - pub fn accounts() -> Vec<(T::AccountId, T::CurrencyId)> { - KILLED - .with(|accounts| accounts.borrow().clone()) - .iter() - .map(|account| (account.0.clone().into(), account.1.clone().into())) - .collect() - } - - pub fn reset() { - KILLED.with(|accounts| { - accounts.replace(vec![]); - }); - } -} -impl Happened<(T::AccountId, T::CurrencyId)> for TrackKilledAccounts -where - T::AccountId: From + Into, - T::CurrencyId: From + Into, -{ - fn happened((who, currency): &(T::AccountId, T::CurrencyId)) { - KILLED.with(|accounts| { - accounts.borrow_mut().push((who.clone().into(), (*currency).into())); - }); - } -} - -thread_local! { - pub static ON_SLASH_CALLS: RefCell = RefCell::new(0); - pub static ON_DEPOSIT_PREHOOK_CALLS: RefCell = RefCell::new(0); - pub static ON_DEPOSIT_POSTHOOK_CALLS: RefCell = RefCell::new(0); - pub static ON_TRANSFER_PREHOOK_CALLS: RefCell = RefCell::new(0); - pub static ON_TRANSFER_POSTHOOK_CALLS: RefCell = RefCell::new(0); -} - -pub struct OnSlashHook(marker::PhantomData); -impl OnSlash for OnSlashHook { - fn on_slash(_currency_id: T::CurrencyId, _account_id: &T::AccountId, _amount: T::Balance) { - ON_SLASH_CALLS.with(|cell| *cell.borrow_mut() += 1); - } -} -impl OnSlashHook { - pub fn calls() -> u32 { - ON_SLASH_CALLS.with(|accounts| *accounts.borrow()) - } -} - -pub struct PreDeposit(marker::PhantomData); -impl OnDeposit for PreDeposit { - fn on_deposit(_currency_id: T::CurrencyId, _account_id: &T::AccountId, _amount: T::Balance) -> DispatchResult { - ON_DEPOSIT_PREHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); - Ok(()) - } -} -impl PreDeposit { - pub fn calls() -> u32 { - ON_DEPOSIT_PREHOOK_CALLS.with(|accounts| accounts.borrow().clone()) - } -} - -pub struct PostDeposit(marker::PhantomData); -impl OnDeposit for PostDeposit { - fn on_deposit(currency_id: T::CurrencyId, account_id: &T::AccountId, amount: T::Balance) -> DispatchResult { - ON_DEPOSIT_POSTHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); - let account_balance: AccountData = - tokens::Pallet::::accounts::(account_id.clone(), currency_id); - assert!( - account_balance.free.ge(&amount), - "Posthook must run after the account balance is updated." - ); - Ok(()) - } -} -impl PostDeposit { - pub fn calls() -> u32 { - ON_DEPOSIT_POSTHOOK_CALLS.with(|accounts| accounts.borrow().clone()) - } -} - -pub struct PreTransfer(marker::PhantomData); -impl OnTransfer for PreTransfer { - fn on_transfer( - _currency_id: T::CurrencyId, - _from: &T::AccountId, - _to: &T::AccountId, - _amount: T::Balance, - ) -> DispatchResult { - ON_TRANSFER_PREHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); - Ok(()) - } -} -impl PreTransfer { - pub fn calls() -> u32 { - ON_TRANSFER_PREHOOK_CALLS.with(|accounts| accounts.borrow().clone()) - } -} - -pub struct PostTransfer(marker::PhantomData); -impl OnTransfer for PostTransfer { - fn on_transfer( - currency_id: T::CurrencyId, - _from: &T::AccountId, - to: &T::AccountId, - amount: T::Balance, - ) -> DispatchResult { - ON_TRANSFER_POSTHOOK_CALLS.with(|cell| *cell.borrow_mut() += 1); - let account_balance: AccountData = - tokens::Pallet::::accounts::(to.clone(), currency_id); - assert!( - account_balance.free.ge(&amount), - "Posthook must run after the account balance is updated." - ); - Ok(()) - } -} -impl PostTransfer { - pub fn calls() -> u32 { - ON_TRANSFER_POSTHOOK_CALLS.with(|accounts| accounts.borrow().clone()) - } -} - -parameter_types! { - pub DustReceiver: AccountId = PalletId(*b"orml/dst").into_account_truncating(); -} - -pub struct CurrencyHooks(marker::PhantomData); -impl MutationHooks for CurrencyHooks -where - T::AccountId: From + Into, - T::CurrencyId: From + Into, -{ - type OnDust = TransferDust; - type OnSlash = OnSlashHook; - type PreDeposit = PreDeposit; - type PostDeposit = PostDeposit; - type PreTransfer = PreTransfer; - type PostTransfer = PostTransfer; - type OnNewTokenAccount = TrackCreatedAccounts; - type OnKilledTokenAccount = TrackKilledAccounts; -} - -impl Config for Runtime { - type Balance = Balance; - type Amount = i64; - type CurrencyId = CurrencyId; - type WeightInfo = (); - type ExistentialDeposits = ExistentialDeposits; - type CurrencyHooks = CurrencyHooks; - type MaxLocks = ConstU32<2>; - type MaxReserves = ConstU32<2>; - type ReserveIdentifier = ReserveIdentifier; - type DustRemovalWhitelist = MockDustRemovalWhitelist; -} -pub type TreasuryCurrencyAdapter = ::Currency; - -type Block = frame_system::mocking::MockBlock; - -construct_runtime!( - pub enum Runtime { - System: frame_system, - Tokens: tokens, - Treasury: pallet_treasury, - ElectionsPhragmen: pallet_elections_phragmen, - } -); - -#[derive(Default)] -pub struct ExtBuilder { - balances: Vec<(AccountId, CurrencyId, Balance)>, - treasury_genesis: bool, -} - -impl ExtBuilder { - pub fn balances(mut self, mut balances: Vec<(AccountId, CurrencyId, Balance)>) -> Self { - self.balances.append(&mut balances); - self - } - - pub fn build(self) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default() - .build_storage() - .unwrap(); - - tokens::GenesisConfig:: { - balances: self.balances, - } - .assimilate_storage(&mut t) - .unwrap(); - - if self.treasury_genesis { - pallet_treasury::GenesisConfig::::default() - .assimilate_storage(&mut t) - .unwrap(); - - pallet_elections_phragmen::GenesisConfig:: { - members: vec![(TREASURY_ACCOUNT, 10)], - } - .assimilate_storage(&mut t) - .unwrap(); - } - - TrackCreatedAccounts::::reset(); - TrackKilledAccounts::::reset(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } -} diff --git a/pallets/tokens/src/tests.rs b/pallets/tokens/src/tests.rs deleted file mode 100644 index f042cf361..000000000 --- a/pallets/tokens/src/tests.rs +++ /dev/null @@ -1,1271 +0,0 @@ -//! Unit tests for the tokens module. - -#![cfg(test)] - -use super::*; -use frame_support::{assert_noop, assert_ok}; -use frame_system::RawOrigin; -use mock::*; -use sp_runtime::{traits::BadOrigin, TokenError}; - -// ************************************************* -// tests for genesis -// ************************************************* - -#[test] -fn genesis_issuance_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); - assert_eq!(Tokens::total_issuance(DOT), 200); - }); -} - -// ************************************************* -// tests for call -// ************************************************* - -#[test] -fn transfer_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::transfer(Some(ALICE).into(), BOB, DOT, 50)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 50, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::free_balance(DOT, &BOB), 150); - assert_eq!(Tokens::total_issuance(DOT), 200); - - assert_noop!( - Tokens::transfer(Some(ALICE).into(), BOB, DOT, 60), - Error::::BalanceTooLow, - ); - assert_noop!( - Tokens::transfer(Some(ALICE).into(), CHARLIE, DOT, 1), - Error::::ExistentialDeposit, - ); - assert_ok!(Tokens::transfer(Some(ALICE).into(), CHARLIE, DOT, 2)); - assert_eq!(TrackCreatedAccounts::::accounts(), vec![(CHARLIE, DOT)]); - - // imply AllowDeath - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_ok!(Tokens::transfer(Some(ALICE).into(), BOB, DOT, 48)); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &BOB), 198); - assert_eq!(Tokens::total_issuance(DOT), 200); - }); -} - -#[test] -fn transfer_keep_alive_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - - // imply KeepAlive - assert_noop!( - Tokens::transfer_keep_alive(Some(ALICE).into(), BOB, DOT, 99), - Error::::KeepAlive, - ); - - assert_ok!(Tokens::transfer_keep_alive(Some(ALICE).into(), BOB, DOT, 98)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 98, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 2); - assert_eq!(Tokens::free_balance(DOT, &BOB), 198); - }); -} - -#[test] -fn transfer_all_keep_alive_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, DOT, true)); - System::assert_has_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: CHARLIE, - amount: 98, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 2); - - assert_ok!(Tokens::set_lock(ID_1, DOT, &BOB, 50)); - assert_eq!(Tokens::accounts(&BOB, DOT).frozen, 50); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_ok!(Tokens::transfer_all(Some(BOB).into(), CHARLIE, DOT, true)); - System::assert_has_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: BOB, - to: CHARLIE, - amount: 50, - })); - }); -} - -#[test] -fn transfer_all_allow_death_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, DOT, false)); - assert_eq!(TrackCreatedAccounts::::accounts(), vec![(CHARLIE, DOT)]); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: CHARLIE, - amount: 100, - })); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(TrackKilledAccounts::::accounts(), vec![(ALICE, DOT)]); - - assert_ok!(Tokens::set_lock(ID_1, DOT, &BOB, 50)); - assert_eq!(Tokens::accounts(&BOB, DOT).frozen, 50); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_ok!(Tokens::transfer_all(Some(BOB).into(), CHARLIE, DOT, false)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: BOB, - to: CHARLIE, - amount: 50, - })); - }); -} - -#[test] -fn force_transfer_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_noop!( - Tokens::force_transfer(Some(ALICE).into(), ALICE, BOB, DOT, 100), - BadOrigin - ); - - // imply AllowDeath - assert_ok!(Tokens::force_transfer(RawOrigin::Root.into(), ALICE, BOB, DOT, 100)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 100, - })); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(TrackKilledAccounts::::accounts(), vec![(ALICE, DOT)]); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &BOB), 200); - }); -} - -#[test] -fn set_balance_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - // bad origin - assert_noop!(Tokens::set_balance(Some(ALICE).into(), ALICE, DOT, 200, 100), BadOrigin); - - // total balance overflow - assert_noop!( - Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, Balance::max_value(), 1), - ArithmeticError::Overflow - ); - - // total issurance overflow - assert_noop!( - Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, Balance::max_value(), 0), - ArithmeticError::Overflow - ); - - // total issurance overflow - assert_noop!( - Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, Balance::max_value(), 0), - ArithmeticError::Overflow - ); - - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 200); - - assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, 200, 100)); - System::assert_has_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { - currency_id: DOT, - who: ALICE, - free: 200, - reserved: 100, - })); - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 200); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::total_issuance(DOT), 400); - - assert!(Accounts::::contains_key(BOB, DOT)); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); - - assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), BOB, DOT, 0, 0)); - System::assert_has_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { - currency_id: DOT, - who: BOB, - free: 0, - reserved: 0, - })); - assert!(!Accounts::::contains_key(BOB, DOT)); - assert_eq!(Tokens::free_balance(DOT, &BOB), 0); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); - assert_eq!(Tokens::total_issuance(DOT), 300); - - assert!(!Accounts::::contains_key(CHARLIE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); - assert_eq!(Tokens::reserved_balance(DOT, &CHARLIE), 0); - - // below ED, - assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), CHARLIE, DOT, 1, 0)); - System::assert_has_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { - currency_id: DOT, - who: CHARLIE, - free: 0, - reserved: 0, - })); - assert!(!Accounts::::contains_key(CHARLIE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); - assert_eq!(Tokens::reserved_balance(DOT, &CHARLIE), 0); - assert_eq!(Tokens::total_issuance(DOT), 300); - }); -} - -// ************************************************* -// tests for inline impl -// ************************************************* - -#[test] -fn deposit_consequence_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - Tokens::deposit_consequence( - &CHARLIE, - DOT, - 0, - &AccountData { - free: 1, - reserved: 0, - frozen: 0 - } - ) - .into_result(), - Ok(()) - ); - - // total issuance overflow - assert_eq!( - Tokens::deposit_consequence( - &CHARLIE, - DOT, - Balance::max_value(), - &AccountData { - free: 1, - reserved: 0, - frozen: 0 - } - ) - .into_result(), - Err(ArithmeticError::Overflow.into()) - ); - - // total balance overflow - assert_eq!( - Tokens::deposit_consequence( - &CHARLIE, - DOT, - 1, - &AccountData { - free: Balance::max_value(), - reserved: 0, - frozen: 0 - } - ) - .into_result(), - Err(ArithmeticError::Overflow.into()) - ); - - // below ed - assert_eq!( - Tokens::deposit_consequence( - &CHARLIE, - DOT, - 1, - &AccountData { - free: 0, - reserved: 0, - frozen: 0 - } - ) - .into_result(), - Err(TokenError::BelowMinimum.into()) - ); - - assert_eq!( - Tokens::deposit_consequence( - &CHARLIE, - DOT, - 1, - &AccountData { - free: 1, - reserved: 0, - frozen: 0 - } - ) - .into_result(), - Ok(()) - ); - }); -} - -#[test] -fn withdraw_consequence_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - Tokens::withdraw_consequence( - &ALICE, - DOT, - 0, - &AccountData { - free: 1, - reserved: 0, - frozen: 0 - } - ) - .into_result(true), - Ok(Zero::zero()) - ); - - // total issuance underflow - assert_ok!(Tokens::update_balance(DOT, &ALICE, 2)); - assert_eq!(Tokens::total_issuance(DOT), 2); - assert_eq!( - Tokens::withdraw_consequence( - &ALICE, - DOT, - 3, - &AccountData { - free: 1, - reserved: 0, - frozen: 0 - } - ) - .into_result(true), - Err(ArithmeticError::Underflow.into()) - ); - - // total issuance is not enough - assert_eq!( - Tokens::withdraw_consequence( - &ALICE, - DOT, - 2, - &AccountData { - free: 1, - reserved: 0, - frozen: 0 - } - ) - .into_result(true), - Err(TokenError::FundsUnavailable.into()) - ); - - // below ED and cannot dec provider - assert_ok!(Tokens::update_balance(DOT, &ALICE, 2)); - assert_eq!(System::providers(&ALICE), 1); - assert_ok!(System::inc_consumers(&ALICE)); - assert!(!System::can_dec_provider(&ALICE)); - assert_eq!( - Tokens::withdraw_consequence( - &ALICE, - DOT, - 1, - &AccountData { - free: 2, - reserved: 0, - frozen: 0 - } - ) - .into_result(true), - Err(TokenError::OnlyProvider.into()) - ); - - // below ED and can dec provider - let _ = System::inc_providers(&ALICE); - assert!(System::can_dec_provider(&ALICE)); - assert_eq!( - Tokens::withdraw_consequence( - &ALICE, - DOT, - 1, - &AccountData { - free: 2, - reserved: 0, - frozen: 0 - } - ) - .into_result(false), - Ok(1) - ); - - // free balance is not enough - assert_eq!( - Tokens::withdraw_consequence( - &ALICE, - DOT, - 2, - &AccountData { - free: 1, - reserved: 1, - frozen: 0 - } - ) - .into_result(true), - Err(TokenError::FundsUnavailable.into()) - ); - - // less to frozen balance - assert_eq!( - Tokens::withdraw_consequence( - &ALICE, - DOT, - 2, - &AccountData { - free: 2, - reserved: 0, - frozen: 2 - } - ) - .into_result(true), - Err(TokenError::Frozen.into()) - ); - }); -} - -#[test] -fn ensure_can_withdraw_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - - assert_noop!( - Tokens::ensure_can_withdraw(DOT, &ALICE, 101), - Error::::BalanceTooLow - ); - - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 50)); - assert_noop!( - Tokens::ensure_can_withdraw(DOT, &ALICE, 51), - Error::::LiquidityRestrictions - ); - - assert_ok!(Tokens::ensure_can_withdraw(DOT, &ALICE, 50)); - }); -} - -#[test] -fn set_free_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - /* Scenarios: ED is not zero, account is not in dust removal whitelist */ - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); - assert_eq!(Tokens::total_issuance(DOT), 0); - - // when total is below ED, account will be reaped. - Tokens::set_free_balance(DOT, &ALICE, 1); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); - // set_free_balance do not change total issuance. - assert_eq!(Tokens::total_issuance(DOT), 0); - - Tokens::set_free_balance(DOT, &ALICE, 2); - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 2); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); - - /* Scenarios: ED is not zero, account is in dust removal whitelist */ - assert!(!Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); - - // set zero will not create account - Tokens::set_free_balance(DOT, &DAVE, 0); - assert!(!Accounts::::contains_key(DAVE, DOT)); - - // when total is below ED, account will not be reaped. - Tokens::set_free_balance(DOT, &DAVE, 1); - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); - - /* Scenarios: ED is zero */ - assert!(!Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &ALICE), 0); - assert_eq!(Tokens::free_balance(ETH, &DustReceiver::get()), 0); - - // set zero will create account - Tokens::set_free_balance(ETH, &ALICE, 0); - assert!(Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &ALICE), 0); - assert_eq!(Tokens::free_balance(ETH, &DustReceiver::get()), 0); - }); -} - -#[test] -fn set_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - /* Scenarios: ED is not zero, account is not in dust removal whitelist */ - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 0); - - // when total is below ED, account should be reaped. - Tokens::set_reserved_balance(DOT, &ALICE, 1); - // but reap it failed because failed to transfer/withdraw dust removal!!! - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 1); - // set_reserved_balance do not change total issuance. - assert_eq!(Tokens::total_issuance(DOT), 0); - - Tokens::set_reserved_balance(DOT, &ALICE, 2); - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 2); - - /* Scenarios: ED is not zero, account is in dust removal whitelist */ - assert!(!Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); - - // set zero will not create account - Tokens::set_reserved_balance(DOT, &DAVE, 0); - assert!(!Accounts::::contains_key(DAVE, DOT)); - - // when total is below ED, account shouldn't be reaped. - Tokens::set_reserved_balance(DOT, &DAVE, 1); - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::reserved_balance(DOT, &DAVE), 1); - - /* Scenarios: ED is zero */ - assert!(!Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::reserved_balance(ETH, &ALICE), 0); - - // set zero will create account - Tokens::set_reserved_balance(ETH, &ALICE, 0); - assert!(Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::reserved_balance(ETH, &ALICE), 0); - }); -} - -#[test] -fn do_transfer_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - // always ok when from == to - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &ALICE, - 101, - ExistenceRequirement::KeepAlive - )); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); - - assert_noop!( - Tokens::do_transfer(DOT, &ALICE, &BOB, 101, ExistenceRequirement::KeepAlive), - Error::::BalanceTooLow - ); - assert_noop!( - Tokens::do_transfer(DOT, &ALICE, &CHARLIE, 1, ExistenceRequirement::KeepAlive), - Error::::ExistentialDeposit - ); - - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &BOB, - 100, - ExistenceRequirement::AllowDeath - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &BOB), 200); - }); -} - -#[test] -fn do_transfer_dust_removal_when_allow_death() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); - - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &BOB, - 99, - ExistenceRequirement::AllowDeath - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &BOB), 199); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); - }); -} - -#[test] -fn do_transfer_report_keep_alive_error_when_ed_is_not_zero() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (DAVE, DOT, 100)]) - .build() - .execute_with(|| { - // total of alice will below ED, account will be reaped. - assert_noop!( - Tokens::do_transfer(DOT, &ALICE, &BOB, 99, ExistenceRequirement::KeepAlive), - Error::::KeepAlive - ); - - // even if dave is in dust removal whitelist, but account drain will still cause - // account be reaped. - assert_noop!( - Tokens::do_transfer(DOT, &DAVE, &BOB, 100, ExistenceRequirement::KeepAlive), - Error::::KeepAlive - ); - - // as long as do not transfer all balance, even if the total is below ED, the - // account will not be reaped. - assert_eq!(Tokens::free_balance(DOT, &DAVE), 100); - assert_eq!(Tokens::free_balance(DOT, &BOB), 0); - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_ok!(Tokens::do_transfer( - DOT, - &DAVE, - &BOB, - 99, - ExistenceRequirement::KeepAlive - )); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); - assert_eq!(Tokens::free_balance(DOT, &BOB), 99); - assert!(Accounts::::contains_key(DAVE, DOT)); - }); -} - -#[test] -fn do_transfer_will_not_report_keep_alive_error_when_ed_is_zero() { - ExtBuilder::default() - .balances(vec![(ALICE, ETH, 100), (DAVE, ETH, 100)]) - .build() - .execute_with(|| { - assert!(Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &ALICE), 100); - assert_eq!(Tokens::free_balance(ETH, &BOB), 0); - assert_ok!(Tokens::do_transfer( - ETH, - &ALICE, - &BOB, - 99, - ExistenceRequirement::KeepAlive - )); - assert!(Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &ALICE), 1); - assert_eq!(Tokens::free_balance(ETH, &BOB), 99); - - // account that total is zero will not be reaped because ED is zero - assert!(Accounts::::contains_key(DAVE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &DAVE), 100); - assert_ok!(Tokens::do_transfer( - ETH, - &DAVE, - &BOB, - 100, - ExistenceRequirement::KeepAlive - )); - assert!(Accounts::::contains_key(DAVE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &DAVE), 0); - assert_eq!(Tokens::free_balance(ETH, &BOB), 199); - }); -} - -#[test] -fn do_transfer_report_keep_alive_error_due_to_cannot_dec_provider_when_allow_death() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (DAVE, DOT, 100)]) - .build() - .execute_with(|| { - assert!(System::can_dec_provider(&ALICE)); - assert_ok!(System::inc_consumers(&ALICE)); - assert!(!System::can_dec_provider(&ALICE)); - assert_noop!( - Tokens::do_transfer(DOT, &ALICE, &BOB, 99, ExistenceRequirement::AllowDeath), - Error::::KeepAlive - ); - - assert_ok!(Tokens::deposit(BTC, &ALICE, 100)); - assert!(System::can_dec_provider(&ALICE)); - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &BOB, - 99, - ExistenceRequirement::AllowDeath - )); - }); -} - -#[test] -fn do_transfer_report_existential_deposit_error_when_ed_is_not_zero() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_noop!( - Tokens::do_transfer(DOT, &ALICE, &BOB, 1, ExistenceRequirement::KeepAlive), - Error::::ExistentialDeposit - ); - - // if receiver is in dust removal whitelist, will not be reaped. - assert!(!Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &DAVE, - 1, - ExistenceRequirement::KeepAlive - )); - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); - }); -} - -#[test] -fn do_withdraw_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - // always ok if amount is zero - assert!(!Accounts::::contains_key(BOB, DOT)); - assert_ok!(Tokens::do_withdraw(DOT, &BOB, 0, ExistenceRequirement::KeepAlive, true)); - assert!(!Accounts::::contains_key(BOB, DOT)); - - assert_noop!( - Tokens::do_withdraw(DOT, &ALICE, 101, ExistenceRequirement::KeepAlive, true), - Error::::BalanceTooLow - ); - - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert_noop!( - Tokens::do_withdraw(DOT, &ALICE, 91, ExistenceRequirement::KeepAlive, true), - Error::::LiquidityRestrictions - ); - - // change issuance - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_ok!(Tokens::do_withdraw( - DOT, - &ALICE, - 10, - ExistenceRequirement::KeepAlive, - true - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 90); - assert_eq!(Tokens::total_issuance(DOT), 90); - - // do not change issuance - assert_ok!(Tokens::do_withdraw( - DOT, - &ALICE, - 10, - ExistenceRequirement::KeepAlive, - false - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 80); - assert_eq!(Tokens::total_issuance(DOT), 90); - }); -} - -#[test] -fn do_withdraw_dust_removal_when_allow_death() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::total_issuance(DOT), 100); - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); - - assert_ok!(Tokens::do_withdraw( - DOT, - &ALICE, - 99, - ExistenceRequirement::AllowDeath, - true - )); - assert_eq!(Tokens::total_issuance(DOT), 1); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); - }); -} - -#[test] -fn do_withdraw_report_keep_alive_error_when_ed_is_not_zero() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (DAVE, DOT, 100)]) - .build() - .execute_with(|| { - assert_noop!( - Tokens::do_withdraw(DOT, &ALICE, 99, ExistenceRequirement::KeepAlive, true), - Error::::KeepAlive - ); - - // dave is in dust removal whitelist, still can withdraw if remainder is not - // zero but below ED. - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 100); - assert_eq!(Tokens::total_issuance(DOT), 200); - assert_ok!(Tokens::do_withdraw( - DOT, - &DAVE, - 99, - ExistenceRequirement::KeepAlive, - true - )); - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); - assert_eq!(Tokens::total_issuance(DOT), 101); - - // even if dave is in dust removal whitelist, but if withdraw all total of it - // will still cause account reaped. - assert_noop!( - Tokens::do_withdraw(DOT, &DAVE, 1, ExistenceRequirement::KeepAlive, true), - Error::::KeepAlive - ); - }); -} - -#[test] -fn do_withdraw_will_not_report_keep_alive_error_when_ed_is_zero() { - ExtBuilder::default() - .balances(vec![(ALICE, ETH, 100), (DAVE, ETH, 100)]) - .build() - .execute_with(|| { - assert!(Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &ALICE), 100); - assert_eq!(Tokens::total_issuance(ETH), 200); - assert_ok!(Tokens::do_withdraw( - ETH, - &ALICE, - 100, - ExistenceRequirement::KeepAlive, - true - )); - assert!(Accounts::::contains_key(ALICE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &ALICE), 0); - assert_eq!(Tokens::total_issuance(ETH), 100); - - assert!(Accounts::::contains_key(DAVE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &DAVE), 100); - assert_ok!(Tokens::do_withdraw( - ETH, - &DAVE, - 100, - ExistenceRequirement::KeepAlive, - true - )); - assert!(Accounts::::contains_key(DAVE, ETH)); - assert_eq!(Tokens::free_balance(ETH, &DAVE), 0); - assert_eq!(Tokens::total_issuance(ETH), 0); - }); -} - -#[test] -fn do_deposit_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - // always ok if deposit amount is zero - assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 0, true, true)); - assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 0, false, true)); - - assert!(!Accounts::::contains_key(CHARLIE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 10, false, true)); - assert!(Accounts::::contains_key(CHARLIE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 10); - assert_eq!(Tokens::total_issuance(DOT), 110); - - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_ok!(Tokens::do_deposit(DOT, &ALICE, 10, true, true)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 110); - assert_eq!(Tokens::total_issuance(DOT), 120); - - assert_noop!( - Tokens::do_deposit(DOT, &ALICE, Balance::max_value(), false, true), - ArithmeticError::Overflow - ); - - // do not change issuance - assert_ok!(Tokens::do_deposit(DOT, &ALICE, 100, true, false)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 210); - assert_eq!(Tokens::total_issuance(DOT), 120); - }); -} - -#[test] -fn do_deposit_report_dead_account_error() { - ExtBuilder::default().build().execute_with(|| { - assert!(!Accounts::::contains_key(CHARLIE, DOT)); - assert_noop!( - Tokens::do_deposit(DOT, &CHARLIE, 10, true, true), - Error::::DeadAccount - ); - }); -} - -#[test] -fn do_deposit_report_existential_deposit_error() { - ExtBuilder::default().build().execute_with(|| { - assert!(!Accounts::::contains_key(CHARLIE, DOT)); - assert_noop!( - Tokens::do_deposit(DOT, &CHARLIE, 1, false, true), - Error::::ExistentialDeposit - ); - - assert!(!Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); - assert_eq!(Tokens::total_issuance(DOT), 0); - assert_ok!(Tokens::do_deposit(DOT, &DAVE, 1, false, true)); - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); - assert_eq!(Tokens::total_issuance(DOT), 1); - }); -} - -// ************************************************* -// tests for endowed account and remove account -// ************************************************* - -#[test] -fn endowed_account_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(System::providers(&ALICE), 0); - assert!(!Accounts::::contains_key(ALICE, DOT)); - Tokens::set_free_balance(DOT, &ALICE, 100); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Endowed { - currency_id: DOT, - who: ALICE, - amount: 100, - })); - assert_eq!(System::providers(&ALICE), 1); - assert!(Accounts::::contains_key(ALICE, DOT)); - }); -} - -#[test] -fn remove_account_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(System::providers(&ALICE), 1); - assert!(Accounts::::contains_key(ALICE, DOT)); - Tokens::set_free_balance(DOT, &ALICE, 0); - assert_eq!(System::providers(&ALICE), 0); - assert!(!Accounts::::contains_key(ALICE, DOT)); - }); -} - -#[test] -fn reap_account_will_dec_providers_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (ALICE, ETH, 100), (ALICE, BTC, 100)]) - .build() - .execute_with(|| { - assert_eq!(System::providers(&ALICE), 3); - assert!(System::account_exists(&ALICE)); - assert!(Accounts::::contains_key(ALICE, DOT)); - - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &BOB, - 100, - ExistenceRequirement::AllowDeath - )); - assert_eq!(System::providers(&ALICE), 2); - assert!(System::account_exists(&ALICE)); - assert!(!Accounts::::contains_key(ALICE, DOT)); - - // ED of ETH is zero, the account will retain even if the total is zero, - // will not dec_providers - assert!(Accounts::::contains_key(ALICE, ETH)); - assert_ok!(Tokens::do_transfer( - ETH, - &ALICE, - &BOB, - 100, - ExistenceRequirement::AllowDeath - )); - assert_eq!(System::providers(&ALICE), 2); - assert!(System::account_exists(&ALICE)); - assert!(Accounts::::contains_key(ALICE, ETH)); - - assert!(Accounts::::contains_key(ALICE, BTC)); - assert_ok!(Tokens::do_transfer( - BTC, - &ALICE, - &BOB, - 100, - ExistenceRequirement::AllowDeath - )); - assert_eq!(System::providers(&ALICE), 1); - assert!(System::account_exists(&ALICE)); - assert!(!Accounts::::contains_key(ALICE, BTC)); - }); -} - -#[test] -fn dust_removal_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(System::providers(&ALICE), 1); - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 0); - Tokens::set_free_balance(DOT, &ALICE, 1); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::DustLost { - currency_id: DOT, - who: ALICE, - amount: 1, - })); - assert_eq!(System::providers(&ALICE), 0); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &DustReceiver::get()), 1); - - // dave is in dust removal whitelist, will not remove its dust even if its total - // below ED - assert!(!Accounts::::contains_key(DAVE, DOT)); - assert_eq!(System::providers(&DAVE), 0); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 0); - Tokens::set_free_balance(DOT, &DAVE, 1); - assert!(Accounts::::contains_key(DAVE, DOT)); - assert_eq!(System::providers(&DAVE), 1); - assert_eq!(Tokens::free_balance(DOT, &DAVE), 1); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Endowed { - currency_id: DOT, - who: DAVE, - amount: 1, - })); - }); -} - -#[test] -fn account_survive_due_to_dust_transfer_failure() { - ExtBuilder::default().build().execute_with(|| { - let dust_account = DustReceiver::get(); - Tokens::set_free_balance(DOT, &dust_account, 0); - assert_eq!(Tokens::free_balance(DOT, &dust_account), 0); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 0); - assert_eq!(System::providers(&ALICE), 0); - assert!(!Accounts::::contains_key(ALICE, DOT)); - - Tokens::set_reserved_balance(DOT, &ALICE, 1); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::DustLost { - currency_id: DOT, - who: ALICE, - amount: 1, - })); - assert_eq!(Tokens::free_balance(DOT, &dust_account), 0); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 1); - assert_eq!(System::providers(&ALICE), 1); - assert!(Accounts::::contains_key(ALICE, DOT)); - }); -} - -#[test] -fn exceeding_max_reserves_should_fail() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let id_3 = [3u8; 8]; - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 10)); - assert_ok!(Tokens::reserve_named(&RID_2, DOT, &ALICE, 10)); - assert_noop!( - Tokens::reserve_named(&id_3, DOT, &ALICE, 10), - Error::::TooManyReserves - ); - }); -} - -#[test] -fn lifecycle_callbacks_are_activated() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, DOT, 200, 0)); - assert_eq!(TrackCreatedAccounts::::accounts(), vec![(ALICE, DOT)]); - - assert_ok!(Tokens::set_balance(RawOrigin::Root.into(), ALICE, BTC, 200, 0)); - assert_eq!( - TrackCreatedAccounts::::accounts(), - vec![(ALICE, DOT), (ALICE, BTC)] - ); - - assert_ok!(Tokens::transfer_all(Some(ALICE).into(), CHARLIE, BTC, false)); - assert_eq!( - TrackCreatedAccounts::::accounts(), - vec![(ALICE, DOT), (ALICE, BTC), (CHARLIE, BTC)] - ); - assert_eq!(TrackKilledAccounts::::accounts(), vec![(ALICE, BTC)]); - }) -} - -// ************************************************* -// tests for mutation hooks (OnDeposit, OnTransfer) -// (tests for the OnSlash hook can be found in `./tests_multicurrency.rs`) -// ************************************************* - -#[test] -fn deposit_hooks_work() { - ExtBuilder::default().build().execute_with(|| { - let initial_prehook_calls = PreDeposit::::calls(); - let initial_posthook_calls = PostDeposit::::calls(); - assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 0, false, true),); - assert_eq!(PreDeposit::::calls(), initial_prehook_calls); - assert_eq!(PostDeposit::::calls(), initial_posthook_calls); - - assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, 100, false, true),); - assert_eq!(PreDeposit::::calls(), initial_prehook_calls + 1); - assert_eq!(PostDeposit::::calls(), initial_posthook_calls + 1); - - assert_noop!( - Tokens::do_deposit(DOT, &BOB, 1, false, true), - Error::::ExistentialDeposit - ); - // The prehook is called - assert_eq!(PreDeposit::::calls(), initial_prehook_calls + 2); - // The posthook is not called - assert_eq!(PostDeposit::::calls(), initial_posthook_calls + 1); - }); -} - -#[test] -fn post_deposit_can_use_new_balance() { - ExtBuilder::default().build().execute_with(|| { - let initial_balance = Tokens::free_balance(DOT, &CHARLIE); - // The following will fail unless Charlie's new balance can be used by the hook, - // because `initial_balance + 100` is higher than Charlie's initial balance. - // If this fails, the posthook is called too soon. - assert_ok!(Tokens::do_deposit(DOT, &CHARLIE, initial_balance + 100, false, true),); - }); -} - -#[test] -fn transfer_hooks_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let initial_prehook_calls = PreTransfer::::calls(); - let initial_posthook_calls = PostTransfer::::calls(); - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &CHARLIE, - 0, - ExistenceRequirement::AllowDeath - ),); - assert_eq!(PreTransfer::::calls(), initial_prehook_calls); - assert_eq!(PostTransfer::::calls(), initial_posthook_calls); - - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &CHARLIE, - 10, - ExistenceRequirement::AllowDeath - )); - assert_eq!(PreTransfer::::calls(), initial_prehook_calls + 1); - assert_eq!(PostTransfer::::calls(), initial_posthook_calls + 1); - - assert_noop!( - Tokens::do_transfer(DOT, &ALICE, &BOB, 1, ExistenceRequirement::AllowDeath), - Error::::ExistentialDeposit - ); - // The prehook is called - assert_eq!(PreTransfer::::calls(), initial_prehook_calls + 2); - // The posthook is not called - assert_eq!(PostTransfer::::calls(), initial_posthook_calls + 1); - }); -} - -#[test] -fn post_transfer_can_use_new_balance() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let initial_balance = Tokens::free_balance(DOT, &CHARLIE); - // The following will fail unless Charlie's new balance can be used by the hook, - // because `initial_balance + 100` is higher than Charlie's initial balance. - // If this fails, the posthook is called too soon. - assert_ok!(Tokens::do_transfer( - DOT, - &ALICE, - &CHARLIE, - initial_balance + 100, - ExistenceRequirement::AllowDeath - )); - }); -} diff --git a/pallets/tokens/src/tests_currency_adapter.rs b/pallets/tokens/src/tests_currency_adapter.rs deleted file mode 100644 index 20929baf2..000000000 --- a/pallets/tokens/src/tests_currency_adapter.rs +++ /dev/null @@ -1,674 +0,0 @@ -//! Unit tests for the tokens module. - -#![cfg(test)] - -use super::*; -use frame_support::{assert_noop, assert_ok}; -use mock::*; - -#[test] -fn currency_adapter_ensure_currency_adapter_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_eq!(Tokens::total_balance(DOT, &TREASURY_ACCOUNT), 100); - assert_eq!(Tokens::reserved_balance(DOT, &TREASURY_ACCOUNT), 0); - assert_eq!(Tokens::free_balance(DOT, &TREASURY_ACCOUNT), 100); - assert_eq!( - ::Currency::total_balance(&TREASURY_ACCOUNT), - 100 - ); - assert!(::Currency::can_slash( - &TREASURY_ACCOUNT, - 10 - )); - assert_eq!( - ::Currency::total_issuance(), - 100 - ); - assert_eq!( - ::Currency::minimum_balance(), - 2 - ); - assert!(::Currency::can_reserve( - &TREASURY_ACCOUNT, - 5 - )); - - // burn - let imbalance = ::Currency::burn(10); - assert_eq!( - ::Currency::total_issuance(), - 90 - ); - drop(imbalance); - assert_eq!( - ::Currency::total_issuance(), - 100 - ); - - // issue - let imbalance = ::Currency::issue(20); - assert_eq!( - ::Currency::total_issuance(), - 120 - ); - drop(imbalance); - assert_eq!( - ::Currency::total_issuance(), - 100 - ); - - // transfer - assert_eq!( - ::Currency::free_balance(&TREASURY_ACCOUNT), - 100 - ); - assert_ok!( - ::Currency::ensure_can_withdraw( - &TREASURY_ACCOUNT, - 10, - WithdrawReasons::TRANSFER, - 0 - ) - ); - assert_ok!(::Currency::transfer( - &TREASURY_ACCOUNT, - &ALICE, - 11, - ExistenceRequirement::KeepAlive - )); - assert_eq!( - ::Currency::free_balance(&TREASURY_ACCOUNT), - 89 - ); - - // deposit - assert_eq!( - ::Currency::total_issuance(), - 100 - ); - let imbalance = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 11); - assert_eq!( - ::Currency::free_balance(&TREASURY_ACCOUNT), - 100 - ); - assert_eq!( - ::Currency::total_issuance(), - 100 - ); - drop(imbalance); - assert_eq!( - ::Currency::free_balance(&TREASURY_ACCOUNT), - 100 - ); - assert_eq!( - ::Currency::total_issuance(), - 111 - ); - - // withdraw - let imbalance = ::Currency::withdraw( - &TREASURY_ACCOUNT, - 10, - WithdrawReasons::TRANSFER, - ExistenceRequirement::KeepAlive, - ); - assert_eq!( - ::Currency::free_balance(&TREASURY_ACCOUNT), - 90 - ); - assert_eq!( - ::Currency::total_issuance(), - 111 - ); - drop(imbalance); - assert_eq!( - ::Currency::free_balance(&TREASURY_ACCOUNT), - 90 - ); - assert_eq!( - ::Currency::total_issuance(), - 101 - ); - }); -} - -#[test] -fn currency_adapter_imbalances_extract_works() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - let init_total_issuance = TreasuryCurrencyAdapter::total_issuance(); - - let mut imbalance = TreasuryCurrencyAdapter::burn(10); - - let imbalance2 = imbalance.extract(3); - - drop(imbalance); - - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance - 3); - - drop(imbalance2); - - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance); - - let mut imbalance = TreasuryCurrencyAdapter::issue(10); - - let imbalance2 = imbalance.extract(3); - - drop(imbalance); - - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance + 3); - - drop(imbalance2); - - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance); - }); -} - -#[test] -fn currency_adapter_burn_must_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - let init_total_issuance = TreasuryCurrencyAdapter::total_issuance(); - let imbalance = TreasuryCurrencyAdapter::burn(10); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance - 10); - drop(imbalance); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), init_total_issuance); - }); -} - -#[test] -fn currency_adapter_reserving_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - - assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 111); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 111); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); - - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); - - assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 111); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 42); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); - }); -} - -#[test] -fn currency_adapter_balance_transfer_when_reserved_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 69, ExistenceRequirement::AllowDeath), - Error::::BalanceTooLow, - ); - }); -} - -#[test] -fn currency_adapter_deducting_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 42); - }); -} - -#[test] -fn currency_adapter_refunding_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 42); - Tokens::set_reserved_balance(DOT, &TREASURY_ACCOUNT, 69); - TreasuryCurrencyAdapter::unreserve(&TREASURY_ACCOUNT, 69); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 111); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); - }); -} - -#[test] -fn currency_adapter_slashing_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 69)); - assert!(TreasuryCurrencyAdapter::slash(&TREASURY_ACCOUNT, 69).1.is_zero()); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 42); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 42); - }); -} - -#[test] -fn currency_adapter_slashing_incomplete_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 42); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 42); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 21)); - assert_eq!(TreasuryCurrencyAdapter::slash(&TREASURY_ACCOUNT, 69).1, 27); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 0); - }); -} - -#[test] -fn currency_adapter_basic_locking_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 100); - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 91, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 10, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn currency_adapter_partial_locking_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 5, WithdrawReasons::all()); - assert_ok!(TreasuryCurrencyAdapter::transfer( - &TREASURY_ACCOUNT, - &ALICE, - 2, - ExistenceRequirement::AllowDeath - )); - }); -} - -#[test] -fn currency_adapter_lock_removal_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, u64::max_value(), WithdrawReasons::all()); - TreasuryCurrencyAdapter::remove_lock(ID_1, &TREASURY_ACCOUNT); - assert_ok!(TreasuryCurrencyAdapter::transfer( - &TREASURY_ACCOUNT, - &ALICE, - 2, - ExistenceRequirement::AllowDeath - )); - }); -} - -#[test] -fn currency_adapter_lock_replacement_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, u64::max_value(), WithdrawReasons::all()); - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 5, WithdrawReasons::all()); - assert_ok!(TreasuryCurrencyAdapter::transfer( - &TREASURY_ACCOUNT, - &ALICE, - 2, - ExistenceRequirement::AllowDeath - )); - }); -} - -#[test] -fn currency_adapter_double_locking_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 5, WithdrawReasons::empty()); - TreasuryCurrencyAdapter::set_lock(ID_2, &TREASURY_ACCOUNT, 5, WithdrawReasons::all()); - assert_ok!(TreasuryCurrencyAdapter::transfer( - &TREASURY_ACCOUNT, - &ALICE, - 2, - ExistenceRequirement::AllowDeath - )); - }); -} - -#[test] -fn currency_adapter_combination_locking_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - // withdrawReasons not work - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, u64::max_value(), WithdrawReasons::empty()); - TreasuryCurrencyAdapter::set_lock(ID_2, &TREASURY_ACCOUNT, 0, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 2, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn currency_adapter_lock_value_extension_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 100, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 2, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 8, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 3, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn currency_adapter_lock_block_number_extension_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 200, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 6, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - System::set_block_number(2); - TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::all()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 3, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn currency_adapter_lock_reasons_extension_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - TreasuryCurrencyAdapter::set_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::TRANSFER); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 11, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::empty()); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 11, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - TreasuryCurrencyAdapter::extend_lock(ID_1, &TREASURY_ACCOUNT, 90, WithdrawReasons::RESERVE); - assert_noop!( - TreasuryCurrencyAdapter::transfer(&TREASURY_ACCOUNT, &ALICE, 11, ExistenceRequirement::AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn currency_adapter_deposit_creating_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 100); - assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 0); - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 2); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 102); - assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 2); - - assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 100); - let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 1); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 103); - assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 101); - }); -} - -#[test] -fn currency_adapter_deposit_into_existing_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 0); - assert_noop!( - TreasuryCurrencyAdapter::deposit_into_existing(&TREASURY_ACCOUNT, 10).map(drop), - Error::::DeadAccount, - ); - - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 100); - assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 100); - assert_ok!(TreasuryCurrencyAdapter::deposit_into_existing(&ALICE, 10).map(drop)); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 110); - assert_eq!(TreasuryCurrencyAdapter::total_balance(&ALICE), 110); - }); -} - -#[test] -fn currency_adapter_reward_should_work() { - ExtBuilder::default() - .balances(vec![(TREASURY_ACCOUNT, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 100); - assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 100); - assert_ok!(TreasuryCurrencyAdapter::deposit_into_existing(&TREASURY_ACCOUNT, 10).map(drop)); - assert_eq!(TreasuryCurrencyAdapter::total_balance(&TREASURY_ACCOUNT), 110); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 110); - }); -} - -#[test] -fn currency_adapter_slashing_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 111)); - assert_eq!(TreasuryCurrencyAdapter::slash_reserved(&TREASURY_ACCOUNT, 42).1, 0); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); - }); -} - -#[test] -fn currency_adapter_slashing_incomplete_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 42)); - assert_eq!(TreasuryCurrencyAdapter::slash_reserved(&TREASURY_ACCOUNT, 69).1, 27); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 69); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); - }); -} - -#[test] -fn currency_adapter_repatriating_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); - let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 110)); - assert_ok!( - TreasuryCurrencyAdapter::repatriate_reserved(&TREASURY_ACCOUNT, &ALICE, 41, Status::Free), - 0 - ); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&ALICE), 0); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 43); - }); -} - -#[test] -fn currency_adapter_transferring_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); - let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 110)); - assert_ok!( - TreasuryCurrencyAdapter::repatriate_reserved(&TREASURY_ACCOUNT, &ALICE, 41, Status::Reserved), - 0 - ); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 69); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&ALICE), 41); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 2); - }); -} - -#[test] -fn currency_adapter_transferring_reserved_balance_to_nonexistent_should_fail() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 111)); - assert_ok!(TreasuryCurrencyAdapter::repatriate_reserved( - &TREASURY_ACCOUNT, - &ALICE, - 42, - Status::Free - )); - }); -} - -#[test] -fn currency_adapter_transferring_incomplete_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); - let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); - assert_ok!(TreasuryCurrencyAdapter::reserve(&TREASURY_ACCOUNT, 41)); - assert_ok!( - TreasuryCurrencyAdapter::repatriate_reserved(&TREASURY_ACCOUNT, &ALICE, 69, Status::Free), - 28 - ); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 69); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance(&ALICE), 0); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 43); - }); -} - -#[test] -fn currency_adapter_transferring_too_high_value_should_not_panic() { - ExtBuilder::default().build().execute_with(|| { - TreasuryCurrencyAdapter::make_free_balance_be(&TREASURY_ACCOUNT, u64::max_value()); - TreasuryCurrencyAdapter::make_free_balance_be(&ALICE, 2); - - assert_noop!( - TreasuryCurrencyAdapter::transfer( - &TREASURY_ACCOUNT, - &ALICE, - u64::max_value(), - ExistenceRequirement::AllowDeath - ), - ArithmeticError::Overflow, - ); - - assert_eq!( - TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), - u64::max_value() - ); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 2); - }); -} - -#[test] -fn exceeding_max_locks_should_fail() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); - assert_noop!( - Tokens::set_lock(ID_3, DOT, &ALICE, 10), - Error::::MaxLocksExceeded - ); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); - }); -} - -#[test] -fn currency_adapter_slashing_named_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); - assert_ok!(TreasuryCurrencyAdapter::reserve_named(&RID_1, &TREASURY_ACCOUNT, 111)); - assert_eq!( - TreasuryCurrencyAdapter::slash_reserved_named(&RID_1, &TREASURY_ACCOUNT, 42).1, - 0 - ); - assert_eq!( - TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &TREASURY_ACCOUNT), - 69 - ); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); - }); -} - -#[test] -fn currency_adapter_named_slashing_incomplete_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 111); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 111); - assert_ok!(TreasuryCurrencyAdapter::reserve_named(&RID_1, &TREASURY_ACCOUNT, 42)); - assert_eq!( - TreasuryCurrencyAdapter::slash_reserved_named(&RID_1, &TREASURY_ACCOUNT, 69).1, - 27 - ); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 69); - assert_eq!( - TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &TREASURY_ACCOUNT), - 0 - ); - assert_eq!(TreasuryCurrencyAdapter::total_issuance(), 69); - }); -} - -#[test] -fn currency_adapter_repatriating_named_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = TreasuryCurrencyAdapter::deposit_creating(&TREASURY_ACCOUNT, 110); - let _ = TreasuryCurrencyAdapter::deposit_creating(&ALICE, 2); - assert_ok!(TreasuryCurrencyAdapter::reserve_named(&RID_1, &TREASURY_ACCOUNT, 110)); - assert_ok!( - TreasuryCurrencyAdapter::repatriate_reserved_named(&RID_1, &TREASURY_ACCOUNT, &ALICE, 41, Status::Free), - 0 - ); - assert_eq!( - TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &TREASURY_ACCOUNT), - 69 - ); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&TREASURY_ACCOUNT), 0); - assert_eq!(TreasuryCurrencyAdapter::reserved_balance_named(&RID_1, &ALICE), 0); - assert_eq!(TreasuryCurrencyAdapter::free_balance(&ALICE), 43); - }); -} diff --git a/pallets/tokens/src/tests_events.rs b/pallets/tokens/src/tests_events.rs deleted file mode 100644 index a81284e8f..000000000 --- a/pallets/tokens/src/tests_events.rs +++ /dev/null @@ -1,469 +0,0 @@ -//! Unit tests for the tokens module. - -#![cfg(test)] - -use super::*; -use frame_support::assert_ok; -use mock::*; - -const REASON: &() = &(); - -fn events() -> Vec { - let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); - System::reset_events(); - evt -} - -#[test] -fn pallet_multicurrency_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(>::transfer( - DOT, - &ALICE, - &BOB, - 10, - ExistenceRequirement::AllowDeath - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 10, - })); - - assert_ok!(>::deposit(DOT, &ALICE, 10)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { - currency_id: DOT, - who: ALICE, - amount: 10, - })); - - assert_ok!(>::withdraw( - DOT, - &ALICE, - 10, - ExistenceRequirement::AllowDeath - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { - currency_id: DOT, - who: ALICE, - amount: 10, - })); - - assert_ok!(>::reserve(DOT, &ALICE, 50)); - assert_eq!(>::slash(DOT, &ALICE, 60), 0); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Slashed { - currency_id: DOT, - who: ALICE, - free_amount: 40, - reserved_amount: 20, - })); - }); -} - -#[test] -fn pallet_multicurrency_extended_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(>::update_balance( - DOT, &ALICE, 500 - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { - currency_id: DOT, - who: ALICE, - amount: 500, - })); - assert_ok!(>::update_balance( - DOT, &ALICE, -500 - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { - currency_id: DOT, - who: ALICE, - amount: 500, - })); - }); -} - -#[test] -fn pallet_multi_lockable_currency_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(>::set_lock( - [0u8; 8], DOT, &ALICE, 10 - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::LockSet { - lock_id: [0u8; 8], - currency_id: DOT, - who: ALICE, - amount: 10, - })); - - assert_ok!(>::remove_lock( - [0u8; 8], DOT, &ALICE - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::LockRemoved { - lock_id: [0u8; 8], - currency_id: DOT, - who: ALICE, - })); - }); -} - -#[test] -fn pallet_multi_reservable_currency_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 1000), (BOB, DOT, 1000)]) - .build() - .execute_with(|| { - assert_ok!(>::reserve( - DOT, &ALICE, 500 - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 500, - })); - - assert_eq!( - >::slash_reserved(DOT, &ALICE, 300), - 0 - ); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Slashed { - currency_id: DOT, - who: ALICE, - free_amount: 0, - reserved_amount: 300, - })); - - assert_eq!( - >::unreserve(DOT, &ALICE, 100), - 0 - ); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: ALICE, - amount: 100, - })); - - assert_ok!(>::repatriate_reserved( - DOT, - &ALICE, - &BOB, - 100, - BalanceStatus::Free - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 100, - status: BalanceStatus::Free, - })); - }); -} - -#[test] -fn pallet_fungibles_mutate_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(>::mint_into(DOT, &ALICE, 500)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { - currency_id: DOT, - who: ALICE, - amount: 500, - })); - assert_ok!(>::burn_from( - DOT, - &ALICE, - 500, - Preservation::Expendable, - Precision::Exact, - Fortitude::Polite - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { - currency_id: DOT, - who: ALICE, - amount: 500, - })); - }); -} - -#[test] -fn pallet_fungibles_transfer_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(>::transfer( - DOT, - &ALICE, - &BOB, - 50, - Preservation::Protect - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 50, - })); - }); -} - -#[test] -fn pallet_fungibles_unbalanced_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(>::reserve(DOT, &ALICE, 50)); - assert_ok!(>::write_balance( - DOT, &ALICE, 500 - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { - currency_id: DOT, - who: ALICE, - free: 500, - reserved: 50, - })); - - >::set_total_issuance(DOT, 1000); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::TotalIssuanceSet { - currency_id: DOT, - amount: 1000, - })); - }); -} - -#[test] -fn pallet_fungibles_mutate_hold_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(>::hold( - DOT, REASON, &ALICE, 50 - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 50, - })); - - assert_ok!(>::transfer_on_hold( - DOT, - REASON, - &ALICE, - &BOB, - 50, - Precision::Exact, - Restriction::OnHold, - Fortitude::Polite - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 50, - status: BalanceStatus::Reserved, - })); - System::reset_events(); - assert_eq!( - >::release(DOT, REASON, &BOB, 50, Precision::Exact), - Ok(50) - ); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: BOB, - amount: 50, - })); - }); -} - -#[test] -fn currency_adapter_pallet_currency_deposit_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - // Use std::mem::forget to get rid the returned imbalance. - std::mem::forget(>::burn(500)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::TotalIssuanceSet { - currency_id: DOT, - amount: 0, - })); - - std::mem::forget(>::issue(200)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::TotalIssuanceSet { - currency_id: DOT, - amount: 200, - })); - - assert_ok!(>::transfer( - &ALICE, - &BOB, - 50, - ExistenceRequirement::AllowDeath - )); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Transfer { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 50, - })); - - assert_ok!(>::reserve(DOT, &BOB, 50)); - std::mem::forget(>::slash(&BOB, 110)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Slashed { - currency_id: DOT, - who: BOB, - free_amount: 100, - reserved_amount: 10, - })); - - std::mem::forget(>::make_free_balance_be(&BOB, 200)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::BalanceSet { - currency_id: DOT, - who: BOB, - free: 200, - reserved: 40, - })); - }); -} - -#[test] -fn pallet_change_locks_events() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Tokens::do_deposit(DOT, &ALICE, 100, false, false)); - assert_ok!(Tokens::do_deposit(BTC, &ALICE, 100, false, false)); - System::reset_events(); - - // Locks: [10/DOT] - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { - currency_id: DOT, - who: ALICE, - amount: 10 - }))); - - // Locks: [15/DOT] - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 15)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { - currency_id: DOT, - who: ALICE, - amount: 5 - }))); - - // Locks: [15/DOT, 20/BTC] - assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 20)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { - currency_id: BTC, - who: ALICE, - amount: 20 - }))); - - // Locks: [15/DOT, 20/BTC, 10/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); - for event in events() { - match event { - RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), - _ => continue, - } - } - - // Locks: [15/DOT, 20/BTC, 12/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 12)); - for event in events() { - match event { - RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), - _ => continue, - } - } - - // Locks: [15/DOT, 20/BTC, 10/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 10)); - for event in events() { - match event { - RuntimeEvent::Tokens(crate::Event::Locked { .. }) => assert!(false, "unexpected lock event"), - RuntimeEvent::Tokens(crate::Event::Unlocked { .. }) => assert!(false, "unexpected unlock event"), - _ => continue, - } - } - - // Locks: [15/DOT, 20/BTC, 20/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Locked { - currency_id: DOT, - who: ALICE, - amount: 5 - }))); - - // Locks: [15/DOT, 20/BTC, 16/DOT] - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 16)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { - currency_id: DOT, - who: ALICE, - amount: 4 - }))); - - // Locks: [15/DOT, 12/BTC, 16/DOT] - assert_ok!(Tokens::set_lock(ID_1, BTC, &ALICE, 12)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { - currency_id: BTC, - who: ALICE, - amount: 8 - }))); - - // Locks: [15/DOT, 12/BTC] - assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::Unlocked { - currency_id: DOT, - who: ALICE, - amount: 1 - }))); - }); -} - -#[test] -fn pallet_multi_lockable_currency_extend_lock_events() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - // lock already exists - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert_ok!(Tokens::extend_lock(ID_1, DOT, &ALICE, 20)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::LockSet { - lock_id: ID_1, - currency_id: DOT, - who: ALICE, - amount: 20, - }))); - // lock doesn't exist - assert_ok!(Tokens::extend_lock(ID_2, DOT, &ALICE, 10)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::LockSet { - lock_id: ID_2, - currency_id: DOT, - who: ALICE, - amount: 10, - }))); - assert_ok!(Tokens::extend_lock(ID_2, DOT, &ALICE, 20)); - assert!(events().contains(&RuntimeEvent::Tokens(crate::Event::LockSet { - lock_id: ID_2, - currency_id: DOT, - who: ALICE, - amount: 20, - }))); - }); -} diff --git a/pallets/tokens/src/tests_fungibles.rs b/pallets/tokens/src/tests_fungibles.rs deleted file mode 100644 index 13c56c33a..000000000 --- a/pallets/tokens/src/tests_fungibles.rs +++ /dev/null @@ -1,741 +0,0 @@ -//! Unit tests for the tokens module. - -#![cfg(test)] - -use super::*; -use frame_support::{assert_noop, assert_ok}; -use mock::*; -use sp_runtime::{ArithmeticError, TokenError}; - -const REASON: &() = &(); - -#[test] -fn fungibles_inspect_trait_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(>::total_issuance(DOT), 100); - assert_eq!(>::minimum_balance(DOT), 2); - assert_eq!(>::balance(DOT, &ALICE), 100); - assert_eq!( - >::reducible_balance( - DOT, - &ALICE, - Preservation::Protect, - Fortitude::Polite - ), - 98 - ); - assert_eq!( - >::reducible_balance( - DOT, - &ALICE, - Preservation::Preserve, - Fortitude::Polite - ), - 98 - ); - assert_ok!( - >::can_deposit(DOT, &ALICE, 1, Provenance::Extant).into_result() - ); - assert_ok!(>::can_withdraw(DOT, &ALICE, 1).into_result(true)); - - assert!(>::asset_exists(DOT)); - assert!(!>::asset_exists(BTC)); - }); -} - -#[test] -fn fungibles_mutate_trait_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(>::mint_into(DOT, &ALICE, 10)); - assert_eq!( - >::burn_from( - DOT, - &ALICE, - 8, - Preservation::Expendable, - Precision::Exact, - Fortitude::Polite - ), - Ok(8) - ); - }); -} - -#[test] -fn fungibles_transfer_trait_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(>::balance(DOT, &ALICE), 100); - assert_eq!(>::balance(DOT, &BOB), 100); - assert_ok!(>::transfer( - DOT, - &ALICE, - &BOB, - 10, - Preservation::Protect - )); - assert_eq!(>::balance(DOT, &ALICE), 90); - assert_eq!(>::balance(DOT, &BOB), 110); - }); -} - -#[test] -fn fungibles_unbalanced_trait_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - // set_balance - assert_eq!(>::balance(DOT, &ALICE), 100); - assert_ok!(>::write_balance(DOT, &ALICE, 10)); - assert_eq!(>::balance(DOT, &ALICE), 10); - - // set_total_issuance - assert_eq!(>::total_issuance(DOT), 100); - >::set_total_issuance(DOT, 10); - assert_eq!(>::total_issuance(DOT), 10); - - // decrease_balance - assert_eq!(>::balance(DOT, &ALICE), 10); - assert_noop!( - >::decrease_balance( - DOT, - &ALICE, - 20, - Precision::Exact, - Preservation::Protect, - Fortitude::Polite - ), - TokenError::FundsUnavailable - ); - assert_eq!( - >::decrease_balance( - DOT, - &ALICE, - 5, - Precision::Exact, - Preservation::Protect, - Fortitude::Polite - ), - Ok(5) - ); - assert_eq!(>::balance(DOT, &ALICE), 5); - // new balance < ExistentialDeposits, clean dust - assert_eq!( - >::decrease_balance( - DOT, - &ALICE, - 4, - Precision::Exact, - Preservation::Expendable, - Fortitude::Polite - ), - Ok(4) - ); - assert_eq!(>::balance(DOT, &ALICE), 0); - assert_eq!(>::total_balance(DOT, &ALICE), 0); - // set reserved - assert_ok!(>::write_balance(DOT, &ALICE, 100)); - assert_ok!(>::reserve(DOT, &ALICE, 50)); - assert_eq!(>::balance(DOT, &ALICE), 50); - assert_eq!(>::total_balance(DOT, &ALICE), 100); - assert_eq!( - >::reducible_balance( - DOT, - &ALICE, - Preservation::Protect, - Fortitude::Polite - ), - 50 - ); - assert_noop!( - >::decrease_balance( - DOT, - &ALICE, - 60, - Precision::Exact, - Preservation::Protect, - Fortitude::Polite - ), - TokenError::FundsUnavailable - ); - assert_eq!( - >::decrease_balance( - DOT, - &ALICE, - 50, - Precision::Exact, - Preservation::Protect, - Fortitude::Polite - ), - Ok(50) - ); - assert_eq!(>::balance(DOT, &ALICE), 0); - assert_eq!(>::total_balance(DOT, &ALICE), 50); - assert_eq!( - >::unreserve(DOT, &ALICE, 50), - 0 - ); - assert_eq!(>::balance(DOT, &ALICE), 50); - assert_eq!(>::total_balance(DOT, &ALICE), 50); - - // decrease_balance_at_most - assert_ok!(>::write_balance(DOT, &ALICE, 10)); - assert_eq!(>::balance(DOT, &ALICE), 10); - assert_eq!(>::total_balance(DOT, &ALICE), 10); - assert_eq!( - >::decrease_balance( - DOT, - &ALICE, - 20, - Precision::BestEffort, - Preservation::Expendable, - Fortitude::Polite - ), - Ok(10) - ); - assert_eq!(>::balance(DOT, &ALICE), 0); - assert_eq!(>::total_balance(DOT, &ALICE), 0); - assert_ok!(>::write_balance(DOT, &ALICE, 10)); - assert_eq!( - >::decrease_balance( - DOT, - &ALICE, - 5, - Precision::BestEffort, - Preservation::Protect, - Fortitude::Polite - ), - Ok(5) - ); - assert_eq!(>::balance(DOT, &ALICE), 5); - assert_eq!(>::total_balance(DOT, &ALICE), 5); - - // new balance < ExistentialDeposits, clean dust - assert_eq!( - >::decrease_balance( - DOT, - &ALICE, - 4, - Precision::BestEffort, - Preservation::Expendable, - Fortitude::Polite - ), - Ok(4) - ); - assert_eq!(>::balance(DOT, &ALICE), 0); - assert_eq!(>::total_balance(DOT, &ALICE), 0); - // set reserved - assert_ok!(>::write_balance(DOT, &ALICE, 100)); - assert_ok!(>::reserve(DOT, &ALICE, 50)); - assert_eq!(>::balance(DOT, &ALICE), 50); - assert_eq!(>::total_balance(DOT, &ALICE), 100); - assert_eq!( - >::reducible_balance( - DOT, - &ALICE, - Preservation::Protect, - Fortitude::Polite - ), - 50 - ); - assert_eq!( - >::decrease_balance( - DOT, - &ALICE, - 60, - Precision::BestEffort, - Preservation::Protect, - Fortitude::Polite - ), - Ok(50), - ); - assert_eq!(>::balance(DOT, &ALICE), 0); - assert_eq!(>::total_balance(DOT, &ALICE), 50); - assert_eq!( - >::unreserve(DOT, &ALICE, 50), - 0 - ); - assert_eq!(>::balance(DOT, &ALICE), 50); - assert_eq!(>::total_balance(DOT, &ALICE), 50); - - // increase_balance - assert_ok!(>::write_balance(DOT, &ALICE, 0)); - assert_noop!( - >::increase_balance(DOT, &ALICE, 1, Precision::Exact), - TokenError::BelowMinimum - ); - assert_eq!( - >::increase_balance(DOT, &ALICE, 2, Precision::Exact), - Ok(2) - ); - assert_eq!(>::balance(DOT, &ALICE), 2); - assert_noop!( - >::increase_balance(DOT, &ALICE, Balance::MAX, Precision::Exact), - ArithmeticError::Overflow - ); - - // increase_balance_at_most - assert_ok!(>::write_balance(DOT, &ALICE, 0)); - assert_eq!( - >::increase_balance(DOT, &ALICE, 1, Precision::BestEffort), - Ok(0) - ); - assert_eq!( - >::increase_balance(DOT, &ALICE, 2, Precision::BestEffort), - Ok(2) - ); - assert_eq!(>::balance(DOT, &ALICE), 2); - assert_eq!( - >::increase_balance( - DOT, - &ALICE, - Balance::MAX, - Precision::BestEffort - ), - Ok(Balance::MAX - 2) - ); - }); -} - -#[test] -fn fungibles_balanced_deposit_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let amount = 42; - let alice_old_balance = >::balance(DOT, &ALICE); - let debt = >::deposit(DOT, &ALICE, amount, Precision::Exact).unwrap(); - assert_eq!(debt.asset(), DOT); - assert_eq!(debt.peek(), amount); - let alice_new_balance = >::balance(DOT, &ALICE); - assert_eq!(alice_old_balance + amount, alice_new_balance); - - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Deposited { - currency_id: DOT, - who: ALICE, - amount, - })); - }); -} - -#[test] -fn fungibles_balanced_withdraw_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let amount = 42; - let alice_old_balance = >::balance(DOT, &ALICE); - let credit = >::withdraw( - DOT, - &ALICE, - amount, - Precision::Exact, - Preservation::Protect, - Fortitude::Polite, - ) - .unwrap(); - assert_eq!(credit.asset(), DOT); - assert_eq!(credit.peek(), amount); - let alice_new_balance = >::balance(DOT, &ALICE); - assert_eq!(alice_old_balance - amount, alice_new_balance); - - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Withdrawn { - currency_id: DOT, - who: ALICE, - amount, - })); - }); -} - -#[test] -fn fungibles_balanced_issue_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let amount = 42; - - let old_total_issuance = >::total_issuance(DOT); - let credit = >::issue(DOT, amount); - assert_eq!(credit.asset(), DOT); - assert_eq!(credit.peek(), amount); - let new_total_issuance = >::total_issuance(DOT); - assert_eq!(old_total_issuance + amount, new_total_issuance); - - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Issued { - currency_id: DOT, - amount, - })); - }); -} - -#[test] -fn fungibles_balanced_rescind_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let amount = 42; - - let old_total_issuance = >::total_issuance(DOT); - let debt = >::rescind(DOT, amount); - assert_eq!(debt.asset(), DOT); - assert_eq!(debt.peek(), amount); - let new_total_issuance = >::total_issuance(DOT); - assert_eq!(old_total_issuance - amount, new_total_issuance); - - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Rescinded { - currency_id: DOT, - amount, - })); - }); -} - -#[test] -fn fungibles_inspect_hold_trait_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 0 - ); - assert!(>::can_hold(DOT, REASON, &ALICE, 50)); - assert!(!>::can_hold( - DOT, REASON, &ALICE, 100 - )); - }); -} - -#[test] -fn fungibles_mutate_hold_trait_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_noop!( - >::hold(DOT, REASON, &ALICE, 200), - Error::::BalanceTooLow - ); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 0 - ); - assert_eq!(>::balance(DOT, &ALICE), 100); - - assert_ok!(>::hold(DOT, REASON, &ALICE, 100)); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 100 - ); - assert_eq!(>::balance(DOT, &ALICE), 0); - - assert_eq!( - >::release(DOT, REASON, &ALICE, 40, Precision::Exact), - Ok(40) - ); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 60 - ); - assert_eq!(>::balance(DOT, &ALICE), 40); - - // exceed hold amount when not in best_effort - assert_noop!( - >::release(DOT, REASON, &ALICE, 61, Precision::Exact), - Error::::BalanceTooLow - ); - - // exceed hold amount when in best_effort - assert_eq!( - >::release(DOT, REASON, &ALICE, 61, Precision::BestEffort), - Ok(60) - ); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 0 - ); - assert_eq!(>::balance(DOT, &ALICE), 100); - - assert_ok!(>::hold(DOT, REASON, &ALICE, 70)); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 70 - ); - assert_eq!(>::balance(DOT, &ALICE), 30); - - assert_eq!( - >::balance_on_hold(DOT, REASON, &BOB), - 0 - ); - assert_eq!(>::balance(DOT, &BOB), 100); - assert_eq!( - >::transfer_on_hold( - DOT, - REASON, - &ALICE, - &BOB, - 5, - Precision::Exact, - Restriction::Free, - Fortitude::Polite - ), - Ok(5) - ); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 65 - ); - assert_eq!(>::balance(DOT, &ALICE), 30); - assert_eq!( - >::balance_on_hold(DOT, REASON, &BOB), - 0 - ); - assert_eq!(>::balance(DOT, &BOB), 105); - - assert_eq!( - >::transfer_on_hold( - DOT, - REASON, - &ALICE, - &BOB, - 5, - Precision::Exact, - Restriction::OnHold, - Fortitude::Polite - ), - Ok(5) - ); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 60 - ); - assert_eq!(>::balance(DOT, &ALICE), 30); - assert_eq!( - >::balance_on_hold(DOT, REASON, &BOB), - 5 - ); - assert_eq!(>::balance(DOT, &BOB), 105); - - // exceed hold amount when not in best_effort - assert_noop!( - >::transfer_on_hold( - DOT, - REASON, - &ALICE, - &BOB, - 61, - Precision::Exact, - Restriction::OnHold, - Fortitude::Polite - ), - Error::::BalanceTooLow - ); - - // exceed hold amount when in best_effort - assert_eq!( - >::transfer_on_hold( - DOT, - REASON, - &ALICE, - &BOB, - 61, - Precision::BestEffort, - Restriction::OnHold, - Fortitude::Polite - ), - Ok(60) - ); - assert_eq!( - >::balance_on_hold(DOT, REASON, &ALICE), - 0 - ); - assert_eq!(>::balance(DOT, &ALICE), 30); - assert_eq!( - >::balance_on_hold(DOT, REASON, &BOB), - 65 - ); - assert_eq!(>::balance(DOT, &BOB), 105); - }); -} - -#[test] -fn fungibles_inspect_convert_should_work() { - pub struct ConvertBalanceTest; - impl ConvertBalance for ConvertBalanceTest { - type AssetId = CurrencyId; - fn convert_balance(balance: Balance, _asset_id: CurrencyId) -> Result { - Ok(balance * 100) - } - - fn convert_balance_back(balance: Balance, _asset_id: CurrencyId) -> Result { - Ok(balance / 100) - } - } - - pub struct IsLiquidToken; - impl Contains for IsLiquidToken { - fn contains(currency_id: &CurrencyId) -> bool { - matches!(currency_id, &DOT) - } - } - - pub struct GetCurrencyId; - impl Get for GetCurrencyId { - fn get() -> CurrencyId { - DOT - } - } - - type RebaseTokens = Combiner< - AccountId, - IsLiquidToken, - Mapper, - Tokens, - >; - - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100), (BOB, BTC, 100)]) - .build() - .execute_with(|| { - assert_eq!( - >::balance(DOT, &ALICE), - 10000 - ); - assert_eq!( - >::total_issuance(DOT), - 20000 - ); - - assert!(>::asset_exists(DOT)); - assert!(>::asset_exists(BTC)); - assert!(!>::asset_exists(ETH)); - }); -} - -#[test] -fn fungibles_transfers_convert_should_work() { - pub struct ConvertBalanceTest; - impl ConvertBalance for ConvertBalanceTest { - type AssetId = CurrencyId; - fn convert_balance(balance: Balance, _asset_id: CurrencyId) -> Result { - Ok(balance * 100) - } - - fn convert_balance_back(balance: Balance, _asset_id: CurrencyId) -> Result { - Ok(balance / 100) - } - } - - pub struct IsLiquidToken; - impl Contains for IsLiquidToken { - fn contains(currency_id: &CurrencyId) -> bool { - matches!(currency_id, &DOT) - } - } - - pub struct GetCurrencyId; - impl Get for GetCurrencyId { - fn get() -> CurrencyId { - DOT - } - } - - type RebaseTokens = Combiner< - AccountId, - IsLiquidToken, - Mapper, - Tokens, - >; - - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 300), (BOB, DOT, 200)]) - .build() - .execute_with(|| { - assert_ok!(>::transfer( - DOT, - &ALICE, - &BOB, - 10000, - Preservation::Protect - )); - assert_eq!( - >::balance(DOT, &ALICE), - 20000 - ); - assert_eq!( - >::balance(DOT, &BOB), - 30000 - ); - }); -} - -#[test] -fn fungibles_mutate_convert_should_work() { - pub struct ConvertBalanceTest; - impl ConvertBalance for ConvertBalanceTest { - type AssetId = CurrencyId; - fn convert_balance(balance: Balance, _asset_id: CurrencyId) -> Result { - Ok(balance * 100) - } - - fn convert_balance_back(balance: Balance, _asset_id: CurrencyId) -> Result { - Ok(balance / 100) - } - } - - pub struct IsLiquidToken; - impl Contains for IsLiquidToken { - fn contains(currency_id: &CurrencyId) -> bool { - matches!(currency_id, &DOT) - } - } - - pub struct GetCurrencyId; - impl Get for GetCurrencyId { - fn get() -> CurrencyId { - DOT - } - } - - type RebaseTokens = Combiner< - AccountId, - IsLiquidToken, - Mapper, - Tokens, - >; - - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 300), (BOB, DOT, 200)]) - .build() - .execute_with(|| { - assert_ok!(>::mint_into( - DOT, &ALICE, 10000 - )); - assert_ok!(>::burn_from( - DOT, - &BOB, - 10000, - Preservation::Expendable, - Precision::Exact, - Fortitude::Polite - )); - assert_eq!( - >::balance(DOT, &ALICE), - 40000 - ); - assert_eq!( - >::balance(DOT, &BOB), - 10000 - ); - }); -} diff --git a/pallets/tokens/src/tests_multicurrency.rs b/pallets/tokens/src/tests_multicurrency.rs deleted file mode 100644 index f1a5684a1..000000000 --- a/pallets/tokens/src/tests_multicurrency.rs +++ /dev/null @@ -1,808 +0,0 @@ -//! Unit tests for the tokens module. - -#![cfg(test)] - -use super::*; -use frame_support::{assert_noop, assert_ok}; -use mock::*; - -#[test] -fn multicurrency_deposit_work() { - ExtBuilder::default().build().execute_with(|| { - assert!(!Accounts::::contains_key(CHARLIE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 0); - assert_eq!(Tokens::total_issuance(DOT), 0); - assert_ok!(Tokens::deposit(DOT, &CHARLIE, 10)); - assert!(Accounts::::contains_key(CHARLIE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &CHARLIE), 10); - assert_eq!(Tokens::total_issuance(DOT), 10); - }); -} - -#[test] -fn multicurrency_withdraw_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_ok!(Tokens::withdraw(DOT, &ALICE, 99, ExistenceRequirement::AllowDeath)); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 1); - }); -} - -#[test] -fn multicurrency_transfer_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert!(Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_ok!(>::transfer( - DOT, - &ALICE, - &BOB, - 99, - ExistenceRequirement::AllowDeath - )); - assert!(!Accounts::::contains_key(ALICE, DOT)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &BOB), 199); - }); -} - -#[test] -fn multicurrency_can_slash_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert!(!Tokens::can_slash(DOT, &ALICE, 101)); - assert!(Tokens::can_slash(DOT, &ALICE, 100)); - }); -} - -#[test] -fn multicurrency_slash_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - // slashed_amount < amount - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_eq!(Tokens::slash(DOT, &ALICE, 50), 0); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 50); - - // slashed_amount == amount - assert_eq!(Tokens::slash(DOT, &ALICE, 51), 1); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 0); - }); -} - -#[test] -fn multicurrency_extended_update_balance_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::update_balance(DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 150); - assert_eq!(Tokens::total_issuance(DOT), 250); - - assert_ok!(Tokens::update_balance(DOT, &BOB, -50)); - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::total_issuance(DOT), 200); - - assert_noop!(Tokens::update_balance(DOT, &BOB, -60), Error::::BalanceTooLow); - }); -} - -#[test] -fn multi_lockable_currency_set_lock_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 10); - assert_eq!(Tokens::accounts(&ALICE, DOT).frozen(), 10); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 50)); - assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 50); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 60)); - assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 60); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); - }); -} - -#[test] -fn multi_lockable_currency_extend_lock_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); - assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 10); - assert_ok!(Tokens::extend_lock(ID_1, DOT, &ALICE, 20)); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); - assert_eq!(Tokens::accounts(&ALICE, DOT).frozen, 20); - assert_ok!(Tokens::extend_lock(ID_2, DOT, &ALICE, 10)); - assert_ok!(Tokens::extend_lock(ID_1, DOT, &ALICE, 20)); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); - }); -} - -#[test] -fn multi_lockable_currency_remove_lock_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::set_lock(ID_1, DOT, &ALICE, 10)); - assert_ok!(Tokens::set_lock(ID_2, DOT, &ALICE, 20)); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 2); - assert_ok!(Tokens::remove_lock(ID_2, DOT, &ALICE)); - assert_eq!(Tokens::locks(ALICE, DOT).len(), 1); - }); -} - -#[test] -fn multi_reservable_currency_can_reserve_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert!(Tokens::can_reserve(DOT, &ALICE, 0)); - assert!(!Tokens::can_reserve(DOT, &ALICE, 101)); - assert!(Tokens::can_reserve(DOT, &ALICE, 100)); - }); -} - -#[test] -fn multi_reservable_currency_slash_reserved_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 0), 0); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 100), 50); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 50); - }); -} - -#[test] -fn multi_reservable_currency_reserve_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_noop!(Tokens::reserve(DOT, &ALICE, 101), Error::::BalanceTooLow); - assert_ok!(Tokens::reserve(DOT, &ALICE, 0)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); - assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 50, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); - - assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); - // ensure will not trigger Endowed event - assert!(System::events().iter().all(|record| !matches!( - record.event, - RuntimeEvent::Tokens(crate::Event::Endowed { - currency_id: DOT, - who: ALICE, - amount: _ - }) - ))); - }); -} - -#[test] -fn multi_reservable_currency_unreserve_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::unreserve(DOT, &ALICE, 0), 0); - assert_eq!(Tokens::unreserve(DOT, &ALICE, 50), 50); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: ALICE, - amount: 0, - })); - assert_ok!(Tokens::reserve(DOT, &ALICE, 30)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 30, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 70); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::unreserve(DOT, &ALICE, 15), 0); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: ALICE, - amount: 15, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 85); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 15); - assert_eq!(Tokens::unreserve(DOT, &ALICE, 30), 15); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: ALICE, - amount: 15, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - // ensure will not trigger Endowed event - assert!(System::events().iter().all(|record| !matches!( - record.event, - RuntimeEvent::Tokens(crate::Event::Endowed { - currency_id: DOT, - who: ALICE, - amount: _ - }) - ))); - }); -} - -#[test] -fn multi_reservable_currency_repatriate_reserved_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!( - Tokens::repatriate_reserved(DOT, &ALICE, &ALICE, 0, BalanceStatus::Free), - Ok(0) - ); - assert_eq!( - Tokens::repatriate_reserved(DOT, &ALICE, &ALICE, 50, BalanceStatus::Free), - Ok(50) - ); - // Repatriating from and to the same account, fund is `unreserved`. - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: ALICE, - amount: 0, - })); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); - assert_ok!(Tokens::reserve(DOT, &BOB, 50)); - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 50); - assert_eq!( - Tokens::repatriate_reserved(DOT, &BOB, &BOB, 60, BalanceStatus::Reserved), - Ok(10) - ); - - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 50); - - assert_eq!( - Tokens::repatriate_reserved(DOT, &BOB, &ALICE, 30, BalanceStatus::Reserved), - Ok(0) - ); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { - currency_id: DOT, - from: BOB, - to: ALICE, - amount: 30, - status: BalanceStatus::Reserved, - })); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 20); - - assert_eq!( - Tokens::repatriate_reserved(DOT, &BOB, &ALICE, 30, BalanceStatus::Free), - Ok(10) - ); - - // Actual amount repatriated is 20. - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { - currency_id: DOT, - from: BOB, - to: ALICE, - amount: 20, - status: BalanceStatus::Free, - })); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 120); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); - }); -} - -#[test] -fn slash_draw_reserved_correct() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 100); - - assert_eq!(Tokens::slash(DOT, &ALICE, 80), 0); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 20); - assert_eq!(Tokens::total_issuance(DOT), 20); - - assert_eq!(Tokens::slash(DOT, &ALICE, 50), 30); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 0); - }); -} - -#[test] -fn no_op_if_amount_is_zero() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Tokens::ensure_can_withdraw(DOT, &ALICE, 0)); - assert_ok!(Tokens::transfer(Some(ALICE).into(), BOB, DOT, 0)); - assert_ok!(Tokens::transfer(Some(ALICE).into(), ALICE, DOT, 0)); - assert_ok!(Tokens::deposit(DOT, &ALICE, 0)); - assert_ok!(Tokens::withdraw(DOT, &ALICE, 0, ExistenceRequirement::AllowDeath)); - assert_eq!(Tokens::slash(DOT, &ALICE, 0), 0); - assert_eq!(Tokens::slash(DOT, &ALICE, 1), 1); - assert_ok!(Tokens::update_balance(DOT, &ALICE, 0)); - }); -} - -#[test] -fn transfer_all_trait_should_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (ALICE, BTC, 200)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::free_balance(BTC, &ALICE), 200); - assert_eq!(Tokens::free_balance(DOT, &BOB), 0); - - assert_ok!(>::transfer_all(&ALICE, &BOB)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::free_balance(BTC, &ALICE), 0); - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::free_balance(BTC, &BOB), 200); - - assert_ok!(Tokens::reserve(DOT, &BOB, 1)); - assert_ok!(>::transfer_all(&BOB, &ALICE)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 99); - assert_eq!(Tokens::free_balance(BTC, &ALICE), 200); - assert_eq!(Tokens::free_balance(DOT, &BOB), 0); - assert_eq!(Tokens::free_balance(BTC, &BOB), 0); - }); -} - -#[test] -fn named_multi_reservable_currency_slash_reserved_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 0), 0); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 100); - assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 100), 50); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 50); - }); -} - -#[test] -fn named_multi_reservable_currency_reserve_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_noop!( - Tokens::reserve_named(&RID_1, DOT, &ALICE, 101), - Error::::BalanceTooLow - ); - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 0)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 50, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); - - assert_ok!(Tokens::reserve_named(&RID_2, DOT, &ALICE, 50)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 50, - })); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 50); - assert_eq!(Tokens::total_balance(DOT, &ALICE), 100); - - // ensure will not trigger Endowed event - assert!(System::events().iter().all(|record| !matches!( - record.event, - RuntimeEvent::Tokens(crate::Event::Endowed { - currency_id: DOT, - who: ALICE, - amount: _ - }) - ))); - }); -} - -#[test] -fn named_multi_reservable_currency_unreserve_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - assert_eq!(Tokens::unreserve_named(&RID_1, DOT, &ALICE, 0), 0); - - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 30)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 30, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 70); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); - - assert_ok!(Tokens::reserve_named(&RID_2, DOT, &ALICE, 30)); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Reserved { - currency_id: DOT, - who: ALICE, - amount: 30, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 40); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 60); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); - assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 30); - - assert_eq!(Tokens::unreserve_named(&RID_1, DOT, &ALICE, 30), 0); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: ALICE, - amount: 30, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 70); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 30); - - assert_eq!(Tokens::unreserve_named(&RID_2, DOT, &ALICE, 30), 0); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::Unreserved { - currency_id: DOT, - who: ALICE, - amount: 30, - })); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance_named(&RID_2, DOT, &ALICE), 0); - // ensure will not trigger Endowed event - assert!(System::events().iter().all(|record| !matches!( - record.event, - RuntimeEvent::Tokens(crate::Event::Endowed { - currency_id: DOT, - who: ALICE, - amount: _ - }) - ))); - }); -} - -#[test] -fn named_multi_reservable_currency_repatriate_reserved_work() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!( - Tokens::repatriate_reserved_named(&RID_1, DOT, &ALICE, &ALICE, 0, BalanceStatus::Free), - Ok(0) - ); - assert_eq!( - Tokens::repatriate_reserved_named(&RID_1, DOT, &ALICE, &ALICE, 50, BalanceStatus::Free), - Ok(50) - ); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 0); - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &BOB, 50)); - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 50); - assert_eq!( - Tokens::repatriate_reserved_named(&RID_1, DOT, &BOB, &BOB, 60, BalanceStatus::Reserved), - Ok(10) - ); - - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 50); - - assert_eq!( - Tokens::repatriate_reserved_named(&RID_1, DOT, &BOB, &ALICE, 30, BalanceStatus::Reserved), - Ok(0) - ); - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { - currency_id: DOT, - from: BOB, - to: ALICE, - amount: 30, - status: BalanceStatus::Reserved, - })); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 20); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 20); - - assert_eq!( - Tokens::repatriate_reserved_named(&RID_1, DOT, &BOB, &ALICE, 30, BalanceStatus::Free), - Ok(10) - ); - - // Actual amount repatriated is 20. - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { - currency_id: DOT, - from: BOB, - to: ALICE, - amount: 20, - status: BalanceStatus::Free, - })); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 120); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); - assert_eq!(Tokens::free_balance(DOT, &BOB), 50); - assert_eq!(Tokens::reserved_balance(DOT, &BOB), 0); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 0); - }); -} - -#[test] -fn slashed_reserved_named_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 100); - - assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 20), 0); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 30); - assert_eq!(Tokens::total_issuance(DOT), 80); - - assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 40), 10); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance(DOT, &ALICE), 0); - assert_eq!(Tokens::total_issuance(DOT), 50); - }); -} - -#[test] -fn named_multi_reservable_ensure_named_reserved_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); - assert_eq!(Tokens::total_issuance(DOT), 100); - - assert_ok!(Tokens::ensure_reserved_named(&RID_1, DOT, &ALICE, 20)); - assert_ok!(Tokens::ensure_reserved_named(&RID_1, DOT, &ALICE, 70)); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 70); - }); -} - -#[test] -fn named_multi_reservable_unreserve_all_named() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 20)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 30); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 70); - - let value = Tokens::unreserve_all_named(&RID_1, DOT, &ALICE); - assert!(value == 70); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - }); -} - -#[test] -fn named_multi_reservable_slash_all_reserved_named() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 50); - - let value = Tokens::slash_all_reserved_named(&RID_1, DOT, &ALICE); - assert!(value == 0); - - assert_eq!(Tokens::free_balance(DOT, &ALICE), 50); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - }); -} - -#[test] -fn named_multi_reservable_repatriate_all_reserved_named_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)]) - .build() - .execute_with(|| { - assert_eq!(Tokens::free_balance(DOT, &ALICE), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &ALICE), 0); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 0); - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 50)); - - assert_ok!(Tokens::repatriate_all_reserved_named( - &RID_1, - DOT, - &ALICE, - &BOB, - BalanceStatus::Reserved - )); - - assert_eq!(Tokens::free_balance(DOT, &BOB), 100); - assert_eq!(Tokens::reserved_balance_named(&RID_1, DOT, &BOB), 50); - - System::assert_last_event(RuntimeEvent::Tokens(crate::Event::ReserveRepatriated { - currency_id: DOT, - from: ALICE, - to: BOB, - amount: 50, - status: BalanceStatus::Reserved, - })); - }); -} - -#[test] -fn slash_hook_works() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let initial_hook_calls = OnSlashHook::::calls(); - - // slashing zero tokens is a no-op - assert_eq!(Tokens::slash(DOT, &ALICE, 0), 0); - assert_eq!(OnSlashHook::::calls(), initial_hook_calls); - - assert_eq!(Tokens::slash(DOT, &ALICE, 50), 0); - assert_eq!(OnSlashHook::::calls(), initial_hook_calls + 1); - - // `slash` calls the hook even if no amount was slashed - assert_eq!(Tokens::slash(DOT, &ALICE, 100), 50); - assert_eq!(OnSlashHook::::calls(), initial_hook_calls + 2); - }); -} - -#[test] -fn slash_hook_works_for_reserved() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let initial_slash_hook_calls = OnSlashHook::::calls(); - - assert_ok!(Tokens::reserve(DOT, &ALICE, 50)); - // slashing zero tokens is a no-op - assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 0), 0); - assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls); - - assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 50), 0); - assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 1); - - // `slash_reserved` calls the hook even if no amount was slashed - assert_eq!(Tokens::slash_reserved(DOT, &ALICE, 50), 50); - assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 2); - }); -} - -#[test] -fn slash_hook_works_for_reserved_named() { - ExtBuilder::default() - .balances(vec![(ALICE, DOT, 100)]) - .build() - .execute_with(|| { - let initial_slash_hook_calls = OnSlashHook::::calls(); - - assert_ok!(Tokens::reserve_named(&RID_1, DOT, &ALICE, 10)); - // slashing zero tokens is a no-op - assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 0), 0); - assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls); - - assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 10), 0); - assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 1); - - // `slash_reserved_named` calls `slash_reserved` under-the-hood with a - // value to slash based on the account's balance. Because the account's - // balance is currently zero, `slash_reserved` will be a no-op and - // the OnSlash hook will not be called. - assert_eq!(Tokens::slash_reserved_named(&RID_1, DOT, &ALICE, 50), 50); - // Same value as previously because of the no-op - assert_eq!(OnSlashHook::::calls(), initial_slash_hook_calls + 1); - }); -} diff --git a/pallets/tokens/src/weights.rs b/pallets/tokens/src/weights.rs deleted file mode 100644 index 8f5637160..000000000 --- a/pallets/tokens/src/weights.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! Autogenerated weights for orml_tokens -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-09-14, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 - -// Executed Command: -// /Users/ermal/Acala/target/release/acala -// benchmark -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=orml_tokens -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --heap-pages=4096 -// --template=../templates/orml-weight-template.hbs -// --output=./tokens/src/weights.rs - - -#![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 orml_tokens. -pub trait WeightInfo { - fn transfer() -> Weight; - fn transfer_all() -> Weight; - fn transfer_keep_alive() -> Weight; - fn force_transfer() -> Weight; - fn set_balance() -> Weight; -} - -/// Default weights. -impl WeightInfo for () { - fn transfer() -> Weight { - Weight::from_parts(69_000_000, 0) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) - } - fn transfer_all() -> Weight { - Weight::from_parts(69_000_000, 0) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) - } - fn transfer_keep_alive() -> Weight { - Weight::from_parts(38_000_000, 0) - .saturating_add(RocksDbWeight::get().reads(3 as u64)) - .saturating_add(RocksDbWeight::get().writes(3 as u64)) - } - fn force_transfer() -> Weight { - Weight::from_parts(45_000_000, 0) - .saturating_add(RocksDbWeight::get().reads(4 as u64)) - .saturating_add(RocksDbWeight::get().writes(3 as u64)) - } - fn set_balance() -> Weight { - Weight::from_parts(34_000_000, 0) - .saturating_add(RocksDbWeight::get().reads(3 as u64)) - .saturating_add(RocksDbWeight::get().writes(3 as u64)) - } -} diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index dbc78e45a..69a3404d1 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -298,6 +298,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } impl pallet_transaction_payment::Config for Test { @@ -333,6 +334,8 @@ impl MutationHooks for CurrencyHooks { type PostDeposit = (); type PreTransfer = (); type PostTransfer = (); + type PreWithdraw = (); + type PostWithdraw = (); type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = RemoveTxAssetOnKilled; } diff --git a/pallets/transaction-pause/src/mock.rs b/pallets/transaction-pause/src/mock.rs index d5b78f2d6..2960fc00e 100644 --- a/pallets/transaction-pause/src/mock.rs +++ b/pallets/transaction-pause/src/mock.rs @@ -90,6 +90,7 @@ impl pallet_balances::Config for Runtime { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_type_with_key! { diff --git a/pallets/xyk-liquidity-mining/src/tests/mock.rs b/pallets/xyk-liquidity-mining/src/tests/mock.rs index 05193487a..7195eeb8e 100644 --- a/pallets/xyk-liquidity-mining/src/tests/mock.rs +++ b/pallets/xyk-liquidity-mining/src/tests/mock.rs @@ -892,6 +892,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_type_with_key! { diff --git a/precompiles/call-permit/src/mock.rs b/precompiles/call-permit/src/mock.rs index 594cd9c50..7999d6532 100644 --- a/precompiles/call-permit/src/mock.rs +++ b/precompiles/call-permit/src/mock.rs @@ -100,6 +100,7 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } mock_account!(CallPermit, |_| MockAccount::from_u64(1)); diff --git a/runtime/adapters/src/tests/mock.rs b/runtime/adapters/src/tests/mock.rs index bb7c8df32..053dd3841 100644 --- a/runtime/adapters/src/tests/mock.rs +++ b/runtime/adapters/src/tests/mock.rs @@ -173,6 +173,7 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = (); } parameter_type_with_key! { diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index d1a5179b5..34e8f9998 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -120,6 +120,7 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = MaxFreezes; type RuntimeFreezeReason = (); type DoneSlashHandler = (); + type RuntimeHooks = crate::evm::erc20_logs::EmitErc20TransferLog; } pub struct CurrencyHooks; @@ -133,6 +134,8 @@ impl MutationHooks for CurrencyHooks { >; type PreTransfer = SufficiencyCheck; type PostTransfer = crate::evm::erc20_logs::EmitErc20TransferLog; + type PreWithdraw = (); + type PostWithdraw = crate::evm::erc20_logs::EmitErc20TransferLog; type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = (RemoveTxAssetOnKilled, OnKilledTokenAccount); } diff --git a/runtime/hydradx/src/evm/erc20_logs.rs b/runtime/hydradx/src/evm/erc20_logs.rs index f9bbf4287..574655a90 100644 --- a/runtime/hydradx/src/evm/erc20_logs.rs +++ b/runtime/hydradx/src/evm/erc20_logs.rs @@ -3,54 +3,42 @@ // Copyright (C) 2020-2026 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 -//! ERC-20 `Transfer(address,address,uint256)` log emission for orml-tokens -//! mutation hooks. Each transfer/deposit/slash on a non-bound asset becomes a -//! log buffered in `pallet_synthetic_logs`, which flushes synthetic ethereum -//! transactions on `on_finalize` so eth-rpc surfaces them. -//! -//! Bound erc20 assets bypass orml-tokens entirely (they route through the -//! EVM runner via `pallet_currencies`), so this handler never fires for them -//! — there's no double-emission risk. - use crate::evm::precompiles::erc20_mapping::HydraErc20Mapping; use crate::Runtime; use frame_support::sp_runtime::DispatchResult; use hydradx_traits::evm::{Erc20Mapping, InspectEvmAccounts}; -use orml_traits::currency::{OnDeposit, OnSlash, OnTransfer}; +use orml_traits::currency::{OnDeposit, OnSlash, OnTransfer, OnWithdraw}; use pallet_synthetic_logs::{encode_u256_be, h160_to_h256, Pallet as SyntheticLogs, TRANSFER_TOPIC}; use primitive_types::{H160, U256}; +use primitives::constants::chain::CORE_ASSET_ID; use primitives::{AccountId, AssetId, Balance}; use sp_std::{marker::PhantomData, vec::Vec}; -/// `OnTransfer` / `OnDeposit` / `OnSlash` handler that emits ERC-20 -/// `Transfer(from, to, amount)` logs. `amount == 0` is skipped — orml allows -/// zero-amount calls but indexers usually filter them anyway. pub struct EmitErc20TransferLog; fn evm_address_of(account: &AccountId) -> H160 { pallet_evm_accounts::Pallet::::evm_address(account) } -fn build_transfer_log(asset: AssetId, from: H160, to: H160, amount: Balance) -> ethereum::Log { +fn push_transfer_log(asset: AssetId, from: H160, to: H160, amount: Balance) { let address = HydraErc20Mapping::asset_address(asset); let mut data = Vec::with_capacity(32); data.extend_from_slice(&encode_u256_be(U256::from(amount))); - ethereum::Log { + let log = ethereum::Log { address, topics: sp_std::vec![TRANSFER_TOPIC, h160_to_h256(from), h160_to_h256(to)], data, - } + }; + SyntheticLogs::::push(address, log); } -fn push_transfer_log(asset: AssetId, from: H160, to: H160, amount: Balance) { - let log = build_transfer_log(asset, from, to, amount); - let address = HydraErc20Mapping::asset_address(asset); - SyntheticLogs::::push(address, log); +fn skip() -> bool { + crate::evm::runner::is_in_evm() } impl OnTransfer for EmitErc20TransferLog { fn on_transfer(asset: AssetId, from: &AccountId, to: &AccountId, amount: Balance) -> DispatchResult { - if amount == 0 || crate::evm::runner::is_in_evm() { + if amount == 0 || skip() { return Ok(()); } push_transfer_log(asset, evm_address_of(from), evm_address_of(to), amount); @@ -60,10 +48,9 @@ impl OnTransfer for EmitErc20TransferLog { impl OnDeposit for EmitErc20TransferLog { fn on_deposit(asset: AssetId, who: &AccountId, amount: Balance) -> DispatchResult { - if amount == 0 || crate::evm::runner::is_in_evm() { + if amount == 0 || skip() { return Ok(()); } - // Mint: Transfer(0x0, who, amount). push_transfer_log(asset, H160::zero(), evm_address_of(who), amount); Ok(()) } @@ -71,21 +58,53 @@ impl OnDeposit for EmitErc20TransferLog { impl OnSlash for EmitErc20TransferLog { fn on_slash(asset: AssetId, who: &AccountId, amount: Balance) { - if amount == 0 || crate::evm::runner::is_in_evm() { + if amount == 0 || skip() { return; } - // Burn-via-slash: Transfer(who, 0x0, amount). NOTE: orml's `OnSlash` - // is invoked with the requested slash amount, before clamping to the - // account's actual free balance. If the account holds less than - // `amount`, the emitted log slightly overstates the burn — accepted - // for v1; revisit if indexer fidelity demands it. push_transfer_log(asset, evm_address_of(who), H160::zero(), amount); } } -/// Generic 2-tuple combinator for `OnDeposit` — orml-traits doesn't provide -/// tuple impls. Used to chain the existing circuit-breaker issuance fuse with -/// our log emission. +impl OnWithdraw for EmitErc20TransferLog { + fn on_withdraw(asset: AssetId, who: &AccountId, amount: Balance) -> DispatchResult { + if amount == 0 || skip() { + return Ok(()); + } + push_transfer_log(asset, evm_address_of(who), H160::zero(), amount); + Ok(()) + } +} + +impl pallet_balances::BalancesHooks for EmitErc20TransferLog { + fn on_transfer(from: &AccountId, to: &AccountId, amount: Balance) { + if amount == 0 || skip() { + return; + } + push_transfer_log(CORE_ASSET_ID, evm_address_of(from), evm_address_of(to), amount); + } + + fn on_mint(who: &AccountId, amount: Balance) { + if amount == 0 || skip() { + return; + } + push_transfer_log(CORE_ASSET_ID, H160::zero(), evm_address_of(who), amount); + } + + fn on_burn(who: &AccountId, amount: Balance) { + if amount == 0 || skip() { + return; + } + push_transfer_log(CORE_ASSET_ID, evm_address_of(who), H160::zero(), amount); + } + + fn on_dust_lost(who: &AccountId, amount: Balance) { + if amount == 0 || skip() { + return; + } + push_transfer_log(CORE_ASSET_ID, evm_address_of(who), H160::zero(), amount); + } +} + pub struct OnDepositTuple(PhantomData<(A, B)>); impl OnDeposit for OnDepositTuple From a38f0cbd3e64ec557f0c6f597a7b3f463aa3180f Mon Sep 17 00:00:00 2001 From: mrq Date: Mon, 4 May 2026 22:18:21 +0200 Subject: [PATCH 05/17] correctly ordering logs --- Cargo.lock | 2 +- .../src/balances_tokens_hooks.rs | 479 +++++++++++++++++- integration-tests/src/erc20.rs | 113 +++++ launch-configs/fork/apply-upgrade.mjs | 52 ++ launch-configs/fork/check-upgrade.mjs | 15 + launch-configs/fork/endow-alice.mjs | 57 +++ launch-configs/fork/package-lock.json | 2 +- .../fork/prepare-state-for-zombienet.js | 2 +- pallets/synthetic-logs/src/lib.rs | 22 +- runtime/hydradx/Cargo.toml | 2 +- .../hydradx/src/evm/aave_trade_executor.rs | 4 +- runtime/hydradx/src/evm/erc20_currency.rs | 3 +- runtime/hydradx/src/evm/erc20_logs.rs | 24 +- runtime/hydradx/src/evm/executor.rs | 26 +- runtime/hydradx/src/evm/precompiles/mod.rs | 33 ++ .../src/evm/precompiles/multicurrency.rs | 41 +- runtime/hydradx/src/evm/runner.rs | 85 +++- runtime/hydradx/src/evm/swap_logs.rs | 12 +- runtime/hydradx/src/lib.rs | 2 +- .../GasEatingToken.sol/GasEatingToken.json | 324 ++++++++++++ .../contracts/LogOrderProbe.sol/IERC20.json | 35 ++ .../LogOrderProbe.sol/LogOrderProbe.json | 47 ++ .../contracts/LogOrderProbe.sol | 28 + 23 files changed, 1323 insertions(+), 87 deletions(-) create mode 100644 launch-configs/fork/apply-upgrade.mjs create mode 100644 launch-configs/fork/check-upgrade.mjs create mode 100644 launch-configs/fork/endow-alice.mjs create mode 100644 scripts/test-contracts/artifacts/contracts/GasEatingToken.sol/GasEatingToken.json create mode 100644 scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/IERC20.json create mode 100644 scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/LogOrderProbe.json create mode 100644 scripts/test-contracts/contracts/LogOrderProbe.sol diff --git a/Cargo.lock b/Cargo.lock index 12ed777b3..bf25148ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6379,7 +6379,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "413.0.0" +version = "414.0.0" dependencies = [ "alloy-primitives 0.7.7", "alloy-sol-types 0.7.7", diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index 696476fb0..6cbd40df3 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -7,7 +7,7 @@ use hydradx_runtime::evm::precompiles::erc20_mapping::HydraErc20Mapping; use hydradx_runtime::{Balances, Currencies, Runtime, RuntimeOrigin, Tokens}; use hydradx_traits::evm::Erc20Mapping; use orml_traits::MultiCurrency; -use pallet_synthetic_logs::{h160_to_h256, Pending as SyntheticLogsPending, TRANSFER_TOPIC}; +use pallet_synthetic_logs::{h160_to_h256, reserved_address_of, Pending as SyntheticLogsPending, TRANSFER_TOPIC}; use xcm_emulator::TestExt; fn buffered_logs() -> Vec<(pallet_synthetic_logs::Bucket, H160, ethereum::Log)> { @@ -284,3 +284,480 @@ fn currencies_withdraw_orml_buffers_burn_log() { ); }); } + +// ---------------------------------------------------------------------- +// Blindspot tests: substrate transfers/swaps triggered through the dispatcher +// precompile from inside an EVM frame. Today the substrate hooks skip on +// `is_in_evm()` and the dispatcher does not inline-emit, so these transfers +// and swaps are silent to `eth_getLogs`. These tests assert the desired +// post-fix behavior — they will fail until the silent-path is closed. +// ---------------------------------------------------------------------- + +#[test] +fn dispatcher_precompile_currencies_transfer_token_emits_transfer_log() { + use codec::Encode; + use hydradx_runtime::evm::precompiles::DISPATCH_ADDR; + use hydradx_runtime::evm::Executor; + use hydradx_runtime::RuntimeCall; + use hydradx_traits::evm::{CallContext, EVM as EVMTrait}; + + TestNet::reset(); + Hydra::execute_with(|| { + assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed(ALICE.into()))); + let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); + + let bob_acc: AccountId = BOB.into(); + let bob_dai_before = >::free_balance(DAI, &bob_acc); + + let amount: u128 = UNITS; + let inner = RuntimeCall::Currencies(pallet_currencies::Call::transfer { + dest: BOB.into(), + currency_id: DAI, + amount, + }); + + SyntheticLogsPending::::kill(); + frame_system::Pallet::::reset_events(); + + let context = CallContext { + contract: DISPATCH_ADDR, + sender: alice_evm, + origin: alice_evm, + }; + let result = Executor::::call(context, inner.encode(), U256::zero(), 1_000_000); + assert!( + matches!(result.exit_reason, fp_evm::ExitReason::Succeed(_)), + "dispatcher precompile call must succeed, got {:?}", + result.exit_reason + ); + + let bob_dai_after = >::free_balance(DAI, &bob_acc); + assert_eq!( + bob_dai_after, + bob_dai_before + amount, + "the substrate Currencies::transfer must have happened" + ); + + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let from_h256 = h160_to_h256(alice_h160()); + let to_h256 = h160_to_h256(bob_h160()); + + let found = buffered_logs().into_iter().any(|(_, emitter, log)| { + emitter == dai_addr + && log.address == dai_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&from_h256) + && log.topics.get(2) == Some(&to_h256) + }); + + assert!( + found, + "BLINDSPOT: dispatcher precompile dispatched Currencies::transfer(DAI) inside an \ + EVM frame; the substrate transfer happened, but no Transfer log made it into \ + pallet_synthetic_logs::Pending (and would be invisible to eth_getLogs). The \ + substrate hooks skip on is_in_evm(); we need them to either push to the current \ + EVM frame's logs (so they end up in info.logs / capture_logs) or to synthetic-logs." + ); + }); +} + +#[test] +fn dispatcher_precompile_omnipool_sell_emits_swap_log() { + use codec::Encode; + use hydradx_runtime::evm::precompiles::DISPATCH_ADDR; + use hydradx_runtime::evm::Executor; + use hydradx_runtime::RuntimeCall; + use hydradx_traits::evm::{CallContext, EVM as EVMTrait}; + use pallet_synthetic_logs::SWAP_TOPIC; + + TestNet::reset(); + Hydra::execute_with(|| { + crate::evm::init_omnipool_with_oracle_for_block_10(); + + assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed(ALICE.into()))); + let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); + assert_ok!(Currencies::update_balance( + RuntimeOrigin::root(), + ALICE.into(), + DOT, + (10u128.pow(10) * 100) as i128, + )); + + let amount: u128 = 10_000_000_000; + let inner = RuntimeCall::Omnipool(pallet_omnipool::Call::sell { + asset_in: DOT, + asset_out: HDX, + amount, + min_buy_amount: 0, + }); + + SyntheticLogsPending::::kill(); + frame_system::Pallet::::reset_events(); + + let context = CallContext { + contract: DISPATCH_ADDR, + sender: alice_evm, + origin: alice_evm, + }; + let result = Executor::::call(context, inner.encode(), U256::zero(), 2_000_000); + assert!( + matches!(result.exit_reason, fp_evm::ExitReason::Succeed(_)), + "dispatcher precompile call must succeed, got {:?}", + result.exit_reason + ); + + let saw_swapped3 = frame_system::Pallet::::events().into_iter().any(|r| { + matches!( + &r.event, + hydradx_runtime::RuntimeEvent::Broadcast(pallet_broadcast::Event::Swapped3 { .. }) + ) + }); + assert!(saw_swapped3, "Omnipool::sell via dispatcher must produce a Swapped3 substrate event"); + + let found = buffered_logs() + .into_iter() + .any(|(_, _, log)| log.topics.first() == Some(&SWAP_TOPIC)); + + assert!( + found, + "BLINDSPOT: dispatcher precompile dispatched Omnipool::sell inside an EVM frame; \ + Swapped3 fired on the substrate side but OnTrade::on_trade silently skips on \ + is_in_evm() and the dispatcher does not inline-emit. No uniswap-v2 Swap log is \ + visible to eth_getLogs. OnTrade should either push into the current EVM frame's \ + logs or to synthetic-logs when triggered from inside an EVM frame." + ); + }); +} + +/// Order test (intra-batch). The dispatcher precompile drains the buffered +/// frame logs and emits them via `handle.log()` *at its own call site*, so +/// when a single dispatch contains a batch of N substrate transfers, the +/// resulting Transfer logs in `info.logs` (and thus in the captured synth tx +/// / real eth tx receipt) appear in the same order as the dispatched calls +/// — not bunched at the end of the receipt. +/// +/// Limitation: this only tests order *within* a single precompile drain. To +/// prove order *between* substrate-hook logs and inline-emitted contract +/// logs in the same EVM frame would require a Solidity contract that emits +/// markers around a precompile call; not added in v1. +#[test] +fn dispatcher_precompile_batch_preserves_substrate_transfer_order() { + use codec::Encode; + use hydradx_runtime::evm::precompiles::DISPATCH_ADDR; + use hydradx_runtime::evm::Executor; + use hydradx_runtime::RuntimeCall; + use hydradx_traits::evm::{CallContext, EVM as EVMTrait}; + + TestNet::reset(); + Hydra::execute_with(|| { + assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed(ALICE.into()))); + let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); + + // dispatch a batch of three transfers in a deterministic asset order + // covers both hook paths: HDX = pallet-balances RuntimeHooks; DAI/DOT = orml-tokens MutationHooks. + let leg_assets: [AssetId; 3] = [HDX, DAI, DOT]; + let amount: u128 = UNITS; + let calls: Vec = leg_assets + .iter() + .map(|asset| { + RuntimeCall::Currencies(pallet_currencies::Call::transfer { + dest: BOB.into(), + currency_id: *asset, + amount, + }) + }) + .collect(); + let batch = RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }); + + SyntheticLogsPending::::kill(); + frame_system::Pallet::::reset_events(); + + let context = CallContext { + contract: DISPATCH_ADDR, + sender: alice_evm, + origin: alice_evm, + }; + let result = Executor::::call(context, batch.encode(), U256::zero(), 5_000_000); + assert!( + matches!(result.exit_reason, fp_evm::ExitReason::Succeed(_)), + "dispatcher batch must succeed, got {:?}", + result.exit_reason + ); + + let alice_h = alice_h160(); + let bob_h = bob_h160(); + + // extract just the Transfer logs that came from one of our three asset addresses, + // in buffer (== insertion / dispatch) order + let observed: Vec = buffered_logs() + .into_iter() + .filter_map(|(_, _, log)| { + if log.topics.first() != Some(&TRANSFER_TOPIC) { + return None; + } + if log.topics.get(1) != Some(&h160_to_h256(alice_h)) { + return None; + } + if log.topics.get(2) != Some(&h160_to_h256(bob_h)) { + return None; + } + leg_assets.iter().copied().find(|a| HydraErc20Mapping::asset_address(*a) == log.address) + }) + .collect(); + + assert_eq!( + observed, + leg_assets.to_vec(), + "Transfer logs from a batched dispatcher call must appear in dispatch order, \ + not bunched at the end. Expected {:?}, got {:?}", + leg_assets, + observed, + ); + }); +} + +/// End-to-end ordering test using a custom Solidity probe contract. +/// +/// `LogOrderProbe.exercise(token, to, amount)` does: +/// 1. emit Marker(0) +/// 2. token.transfer(to, amount) // multicurrency precompile call +/// 3. emit Marker(1) +/// +/// We invoke `exercise` via Executor::call. The captured logs (in synth tx +/// order = info.logs order = log_index order) must be: +/// [Marker(0), Transfer, Marker(1)] +/// +/// If the precompile-level drain weren't there and we relied only on the +/// WrapRunner-end drain, the resulting order would be: +/// [Marker(0), Marker(1), Transfer] +/// — substrate-hook log bunched at the end. This test guards against that +/// regression and proves log_index ordering matches execution order across +/// the precompile→substrate→hook→drain path. +#[test] +fn evm_inline_logs_around_precompile_call_preserve_log_index_order() { + use ethereum_types::H256; + use hex_literal::hex; + use hydradx_runtime::evm::Executor; + use hydradx_traits::evm::{CallContext, EVM as EVMTrait}; + + // keccak256("Marker(uint256)") — see node_modules ethers computation. + const MARKER_TOPIC: H256 = H256(hex!( + "83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b24" + )); + // first 4 bytes of keccak256("exercise(address,address,uint256)") + const EXERCISE_SELECTOR: [u8; 4] = hex!("430c9304"); + + TestNet::reset(); + Hydra::execute_with(|| { + // deploy the probe contract using ALICE as deployer + let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); + let probe = crate::utils::contracts::deploy_contract("LogOrderProbe", alice_evm); + + // fund the probe with DAI so it can transfer to BOB + let probe_acc = hydradx_runtime::EVMAccounts::truncated_account_id(probe); + assert_ok!(Currencies::update_balance( + RuntimeOrigin::root(), + probe_acc, + DAI, + (UNITS * 10) as i128, + )); + + // build calldata: exercise(token=DAI_addr, to=BOB_evm, amount=UNITS) + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let bob_evm = bob_h160(); + let amount = UNITS; + let mut calldata = EXERCISE_SELECTOR.to_vec(); + calldata.extend_from_slice(&[0u8; 12]); + calldata.extend_from_slice(dai_addr.as_bytes()); + calldata.extend_from_slice(&[0u8; 12]); + calldata.extend_from_slice(bob_evm.as_bytes()); + calldata.extend_from_slice(&U256::from(amount).to_big_endian()); + + SyntheticLogsPending::::kill(); + frame_system::Pallet::::reset_events(); + + let context = CallContext { + contract: probe, + sender: alice_evm, + origin: alice_evm, + }; + let result = Executor::::call(context, calldata, U256::zero(), 5_000_000); + assert!( + matches!(result.exit_reason, fp_evm::ExitReason::Succeed(_)), + "probe.exercise must succeed, got {:?}", + result.exit_reason + ); + + // extract the 3 relevant logs in buffered order (= info.logs order = log_index order) + // classify each: 0=Marker(0), 1=Transfer, 2=Marker(1) + let from_h256 = h160_to_h256(probe); + let to_h256 = h160_to_h256(bob_evm); + + let kinds: Vec<&'static str> = buffered_logs() + .into_iter() + .filter_map(|(_, _, log)| { + if log.topics.first() == Some(&MARKER_TOPIC) && log.address == probe { + // extract the uint256 idx from data + let idx = U256::from_big_endian(&log.data); + if idx == U256::zero() { + Some("Marker0") + } else if idx == U256::one() { + Some("Marker1") + } else { + None + } + } else if log.topics.first() == Some(&TRANSFER_TOPIC) + && log.address == dai_addr + && log.topics.get(1) == Some(&from_h256) + && log.topics.get(2) == Some(&to_h256) + { + Some("Transfer") + } else { + None + } + }) + .collect(); + + assert_eq!( + kinds, + vec!["Marker0", "Transfer", "Marker1"], + "log_index ordering must match EVM execution order: \ + inline Marker(0), then precompile-emitted Transfer (drained at multicurrency precompile call site), \ + then inline Marker(1). Got: {:?}", + kinds, + ); + }); +} + +// ---------------------------------------------------------------------- +// Reserve / unreserve — substrate-side encumbrance moves that change the +// erc20-visible `balanceOf` (which returns free balance only). To keep +// erc20 indexers reconstructing balances from Transfer events consistent +// with balanceOf, we mirror reserves as Transfer events to a per-owner +// sentinel: `reserved_address_of(owner) = owner with first byte XOR 0xEE`. +// ---------------------------------------------------------------------- + +#[test] +fn orml_tokens_reserve_buffers_transfer_log_to_reserved_sentinel() { + use orml_traits::MultiReservableCurrency; + + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + let amount = UNITS; + assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + + let asset_addr = HydraErc20Mapping::asset_address(DAI); + let alice_h = alice_h160(); + let reserved = reserved_address_of(alice_h); + + let entry = buffered_logs() + .into_iter() + .find(|(_, emitter, log)| { + *emitter == asset_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_h)) + && log.topics.get(2) == Some(&h160_to_h256(reserved)) + }); + assert!( + entry.is_some(), + "orml_tokens::reserve must buffer Transfer(owner, reserved_sentinel, amount); \ + reserved_sentinel = {:?} for alice = {:?}", + reserved, + alice_h, + ); + }); +} + +#[test] +fn orml_tokens_unreserve_buffers_transfer_log_from_reserved_sentinel() { + use orml_traits::MultiReservableCurrency; + + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + SyntheticLogsPending::::kill(); + + let unreserved = >::unreserve(DAI, &ALICE.into(), amount); + assert_eq!(unreserved, 0, "all of `amount` must be unreserved"); + + let asset_addr = HydraErc20Mapping::asset_address(DAI); + let alice_h = alice_h160(); + let reserved = reserved_address_of(alice_h); + + let entry = buffered_logs() + .into_iter() + .find(|(_, emitter, log)| { + *emitter == asset_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(reserved)) + && log.topics.get(2) == Some(&h160_to_h256(alice_h)) + }); + assert!( + entry.is_some(), + "orml_tokens::unreserve must buffer Transfer(reserved_sentinel, owner, amount)", + ); + }); +} + +#[test] +fn balances_reserve_buffers_transfer_log_to_reserved_sentinel() { + use frame_support::traits::ReservableCurrency; + + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + let amount = UNITS; + assert_ok!(>::reserve(&ALICE.into(), amount)); + + let hdx_addr = HydraErc20Mapping::asset_address(HDX); + let alice_h = alice_h160(); + let reserved = reserved_address_of(alice_h); + + let entry = buffered_logs() + .into_iter() + .find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_h)) + && log.topics.get(2) == Some(&h160_to_h256(reserved)) + }); + assert!( + entry.is_some(), + "pallet_balances::reserve must buffer Transfer(owner, reserved_sentinel, amount) for HDX", + ); + }); +} + +#[test] +fn balances_unreserve_buffers_transfer_log_from_reserved_sentinel() { + use frame_support::traits::ReservableCurrency; + + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + assert_ok!(>::reserve(&ALICE.into(), amount)); + SyntheticLogsPending::::kill(); + + let unreserved = >::unreserve(&ALICE.into(), amount); + assert_eq!(unreserved, 0, "all of `amount` must be unreserved"); + + let hdx_addr = HydraErc20Mapping::asset_address(HDX); + let alice_h = alice_h160(); + let reserved = reserved_address_of(alice_h); + + let entry = buffered_logs() + .into_iter() + .find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(reserved)) + && log.topics.get(2) == Some(&h160_to_h256(alice_h)) + }); + assert!( + entry.is_some(), + "pallet_balances::unreserve must buffer Transfer(reserved_sentinel, owner, amount) for HDX", + ); + }); +} diff --git a/integration-tests/src/erc20.rs b/integration-tests/src/erc20.rs index 8c82de449..c4ac5e178 100644 --- a/integration-tests/src/erc20.rs +++ b/integration-tests/src/erc20.rs @@ -113,6 +113,119 @@ fn executor_call_wont_bump_nonce() { }); } +#[test] +fn executor_call_captures_evm_log_to_synthetic_logs() { + TestNet::reset(); + Hydra::execute_with(|| { + let token = deploy_token_contract(); + + pallet_synthetic_logs::Pending::::kill(); + frame_system::Pallet::::reset_events(); + + let mut data = Into::::into(Function::Transfer).to_be_bytes().to_vec(); + data.extend_from_slice(H256::from(evm_address()).as_bytes()); + data.extend_from_slice(H256::from_uint(&U256::from(100)).as_bytes()); + let context = CallContext { + contract: token, + sender: deployer(), + origin: deployer(), + }; + + let call_result = Executor::::call(context, data, U256::zero(), 100_000); + assert_eq!(call_result.exit_reason, Succeed(Returned)); + + let synth_log = pallet_synthetic_logs::Pending::::get() + .into_iter() + .find(|(_, _, log)| { + log.address == token + && log.topics.first() == Some(&pallet_synthetic_logs::TRANSFER_TOPIC) + && log.topics.get(1) == Some(&pallet_synthetic_logs::h160_to_h256(deployer())) + && log.topics.get(2) == Some(&pallet_synthetic_logs::h160_to_h256(evm_address())) + }) + .expect("Executor::call must capture the EVM Transfer log into the synthetic-logs buffer"); + + let (_, emitter, _) = &synth_log; + assert_eq!(*emitter, token, "synth-log emitter must be the token contract"); + + let evm_log_event = frame_system::Pallet::::events() + .into_iter() + .find(|r| { + matches!( + &r.event, + hydradx_runtime::RuntimeEvent::EVM(pallet_evm::Event::Log { log }) + if log.address == token + && log.topics.first() == Some(&pallet_synthetic_logs::TRANSFER_TOPIC) + ) + }) + .expect("pallet_evm::Event::Log must be emitted as a substrate event for the same log"); + let _ = evm_log_event; + }); +} + +#[test] +fn runner_call_direct_does_not_buffer_synthetic_log() { + TestNet::reset(); + Hydra::execute_with(|| { + let token = deploy_token_contract(); + + pallet_synthetic_logs::Pending::::kill(); + frame_system::Pallet::::reset_events(); + + let mut data = Into::::into(Function::Transfer).to_be_bytes().to_vec(); + data.extend_from_slice(H256::from(evm_address()).as_bytes()); + data.extend_from_slice(H256::from_uint(&U256::from(100)).as_bytes()); + + let evm_config = ::config(); + let info = <::Runner as pallet_evm::Runner>::call( + deployer(), + token, + data, + U256::zero(), + 500_000, + Some(U256::zero()), + None, + None, + vec![], + vec![], + false, + false, + None, + None, + evm_config, + ) + .expect("runner call must succeed"); + assert!(matches!(info.exit_reason, fp_evm::ExitReason::Succeed(_))); + assert!( + info.logs + .iter() + .any(|l| l.address == token && l.topics.first() == Some(&pallet_synthetic_logs::TRANSFER_TOPIC)), + "the EVM frame must produce the Transfer log", + ); + + let buffered = pallet_synthetic_logs::Pending::::get(); + assert!( + buffered.is_empty(), + "a direct T::Runner::call (the path pallet_ethereum::transact uses internally) bypasses \ + Executor::call, so the EVM-frame Transfer log must NOT be duplicated into the \ + synthetic-logs buffer; found {} entries", + buffered.len() + ); + + let evm_log_event = frame_system::Pallet::::events().into_iter().find(|r| { + matches!( + &r.event, + hydradx_runtime::RuntimeEvent::EVM(pallet_evm::Event::Log { log }) + if log.address == token + && log.topics.first() == Some(&pallet_synthetic_logs::TRANSFER_TOPIC) + ) + }); + assert!( + evm_log_event.is_some(), + "pallet_evm::Event::Log substrate event must be deposited on the direct-runner path so substrate observers see the log" + ); + }); +} + #[test] fn name_should_decode_correctly() { TestNet::reset(); diff --git a/launch-configs/fork/apply-upgrade.mjs b/launch-configs/fork/apply-upgrade.mjs new file mode 100644 index 000000000..1326bd956 --- /dev/null +++ b/launch-configs/fork/apply-upgrade.mjs @@ -0,0 +1,52 @@ +import { ApiPromise, WsProvider, Keyring } from '@polkadot/api'; +import { hexToU8a } from '@polkadot/util'; +import fs from 'fs'; + +const WASM_PATH = process.env.WASM || + '../../target/release/wbuild/hydradx-runtime/hydradx_runtime.compact.compressed.wasm'; +const ENDPOINT = process.env.ENDPOINT || 'ws://127.0.0.1:9999'; + +const main = async () => { + const wasm = fs.readFileSync(WASM_PATH); + const api = await ApiPromise.create({ provider: new WsProvider(ENDPOINT) }); + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + + console.log(`endpoint: ${ENDPOINT}`); + console.log(`wasm: ${WASM_PATH} (${wasm.length} bytes)`); + console.log(`spec_version pre: ${(await api.rpc.state.getRuntimeVersion()).specVersion.toString()}`); + const auth = await api.query.system.authorizedUpgrade(); + console.log(`authorized upgrade: ${auth.toString()}`); + + console.log('submitting system.applyAuthorizedUpgrade ...'); + await new Promise((resolve, reject) => { + api.tx.system + .applyAuthorizedUpgrade(`0x${wasm.toString('hex')}`) + .signAndSend(alice, ({ status, dispatchError }) => { + if (dispatchError) { + reject(new Error(dispatchError.toString())); + return; + } + console.log(`status: ${status.type}`); + if (status.isInBlock || status.isFinalized) resolve(); + }) + .catch(reject); + }); + + console.log('waiting for new spec version...'); + for (let i = 0; i < 60; i++) { + await new Promise((r) => setTimeout(r, 2000)); + const v = (await api.rpc.state.getRuntimeVersion()).specVersion.toNumber(); + process.stdout.write(`spec=${v} `); + if (v !== 412) { + console.log(`\nupgraded to spec_version ${v}`); + break; + } + } + await api.disconnect(); +}; + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/launch-configs/fork/check-upgrade.mjs b/launch-configs/fork/check-upgrade.mjs new file mode 100644 index 000000000..d1fa5c2f7 --- /dev/null +++ b/launch-configs/fork/check-upgrade.mjs @@ -0,0 +1,15 @@ +import { ApiPromise, WsProvider } from '@polkadot/api'; +const api = await ApiPromise.create({ provider: new WsProvider('ws://127.0.0.1:9999') }); + +console.log('parachainSystem storage items:'); +const sys = api.query.parachainSystem || {}; +for (const k of Object.keys(sys)) console.log(' ', k); + +const auth = await api.query.system.authorizedUpgrade(); +console.log('\nSystem.AuthorizedUpgrade:', auth.toHuman()); + +const head = await api.rpc.chain.getHeader(); +console.log('Best block:', head.number.toNumber()); +console.log('Spec version:', (await api.rpc.state.getRuntimeVersion()).specVersion.toNumber()); + +await api.disconnect(); diff --git a/launch-configs/fork/endow-alice.mjs b/launch-configs/fork/endow-alice.mjs new file mode 100644 index 000000000..94cdb0627 --- /dev/null +++ b/launch-configs/fork/endow-alice.mjs @@ -0,0 +1,57 @@ +import fs from 'fs'; +import { TypeRegistry } from '@polkadot/types'; +import { xxhashAsHex, blake2AsHex } from '@polkadot/util-crypto'; +import { Keyring } from '@polkadot/keyring'; +import { hexToU8a, u8aToHex } from '@polkadot/util'; + +const CHAIN_SPEC = process.argv[2] || 'data/forked-chainspec.json'; +const ALICE_PUB = '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d'; + +// (asset_id, free_amount_decimal) +const ENDOWMENTS = [ + [2, 1_000_000_000_000_000_000_000n], // DAI (18 decimals): 1000 DAI + [5, 100_000_000_000_000_000_000n], // DOT (10 decimals scaled 10^20 internal): 1000 DOT + [10, 1_000_000_000_000n], // USDT (6 decimals): 1M USDT + [20, 1_000_000_000_000_000_000_000n], // WETH (18 decimals): 1000 WETH + [22, 1_000_000_000_000n], // USDC (6 decimals): 1M USDC +]; + +const tokensAccountsKey = (account, assetId) => { + const palletPrefix = xxhashAsHex('Tokens', 128).replace('0x', ''); + const itemPrefix = xxhashAsHex('Accounts', 128).replace('0x', ''); + const accBlake = blake2AsHex(hexToU8a(account), 128).replace('0x', ''); + const accHex = account.replace('0x', ''); + const idBytes = new Uint8Array(4); + new DataView(idBytes.buffer).setUint32(0, assetId, true); + const idHex = u8aToHex(idBytes).replace('0x', ''); + const idTwox = xxhashAsHex(idBytes, 64).replace('0x', ''); + return '0x' + palletPrefix + itemPrefix + accBlake + accHex + idTwox + idHex; +}; + +const encodeAccountData = (free) => { + const reg = new TypeRegistry(); + reg.register({ + AccountData: { + free: 'u128', + reserved: 'u128', + frozen: 'u128', + }, + }); + const data = reg.createType('AccountData', { free, reserved: 0, frozen: 0 }); + return u8aToHex(data.toU8a()); +}; + +const main = () => { + const spec = JSON.parse(fs.readFileSync(CHAIN_SPEC, 'utf8')); + const top = spec.genesis.raw.top; + for (const [assetId, free] of ENDOWMENTS) { + const key = tokensAccountsKey(ALICE_PUB, assetId); + const value = encodeAccountData(free); + top[key] = value; + console.log(`endowed alice asset=${assetId} free=${free}`); + } + fs.writeFileSync(CHAIN_SPEC, JSON.stringify(spec)); + console.log(`saved ${CHAIN_SPEC}`); +}; + +main(); diff --git a/launch-configs/fork/package-lock.json b/launch-configs/fork/package-lock.json index bd92f53a9..44694ecb4 100644 --- a/launch-configs/fork/package-lock.json +++ b/launch-configs/fork/package-lock.json @@ -2044,4 +2044,4 @@ } } } -} \ No newline at end of file +} diff --git a/launch-configs/fork/prepare-state-for-zombienet.js b/launch-configs/fork/prepare-state-for-zombienet.js index 8d28fd505..f8b17fd62 100644 --- a/launch-configs/fork/prepare-state-for-zombienet.js +++ b/launch-configs/fork/prepare-state-for-zombienet.js @@ -9,7 +9,7 @@ const NEW_ID = process.env.CHAIN_ID || "local_testnet"; const NEW_RELAY_CHAIN = "rococo_local_testnet"; // Define replacement values -const AURA_AUTHORITIES_VALUE = "0x08be4f21c56d926b91f020b5071f14935cb93f001f1127c53d3eac6eed23ffea64dc4d79aad5a9d01a359995838830a80733a0bff7e4eb087bfc621ef1873fec49"; +const AURA_AUTHORITIES_VALUE = "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"; const COUNCIL_AND_TECHNICAL_COMMITTEE_VALUE = "0x04d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"; const SYSTEM_ACCOUNT_VALUE = "0x00000000000000000100000000000000ba31bc09df123864f700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs index 54ea2f016..ada1094ca 100644 --- a/pallets/synthetic-logs/src/lib.rs +++ b/pallets/synthetic-logs/src/lib.rs @@ -144,8 +144,6 @@ impl Pallet { /// Drain buffer, group by bucket, and write one synthetic tx per bucket /// into `pallet_ethereum::Pending`. Must run before `pallet_ethereum::on_finalize`. fn flush(entries: Vec<(Bucket, H160, ethereum::Log)>) { - // sort entries by bucket while preserving in-bucket order - // (insertion order is preserved within each bucket because we iterate stably) let mut groups: Vec<(Bucket, Vec)> = Vec::new(); for (bucket, _emitter, log) in entries { match groups.iter_mut().find(|(b, _)| *b == bucket) { @@ -153,7 +151,6 @@ impl Pallet { None => groups.push((bucket, vec![log])), } } - // stable bucket sort: Hook(Init,*) < Extrinsic(i) < Hook(Final,*) groups.sort_by(|a, b| Self::bucket_sort_key(&a.0).cmp(&Self::bucket_sort_key(&b.0))); let block_number = frame_system::Pallet::::block_number(); @@ -289,6 +286,25 @@ pub fn h160_to_h256(addr: H160) -> H256 { H256(bytes) } +/// Per-owner sentinel address representing the owner's reserved balance +/// bucket. Used as the `to` topic on `reserve` and the `from` topic on +/// `unreserve` so erc20 indexers reconstructing balances from `Transfer` +/// events stay consistent with `balanceOf` (which returns free balance only). +/// +/// Derivation: XOR the first byte of `owner` with `0xEE`. The mapping is +/// trivially reversible (XOR again) so a bookkeeping consumer that wants +/// owner attribution from a sentinel can recover it; reversibility is +/// optional for forward-only indexers (which compute the sentinel from a +/// known owner). Collision with the asset-prefix range +/// (`0x000…01`) requires the owner to start with `0xEE` followed +/// by 11 zero bytes, then `0x01`, then 3 zero bytes — pre-image probability +/// `2^-128` for uniformly distributed addresses. +pub fn reserved_address_of(owner: H160) -> H160 { + let mut bytes = owner.0; + bytes[0] ^= 0xEE; + H160(bytes) +} + /// Encode a single u256 as a 32-byte big-endian word for log `data`. pub fn encode_u256_be(value: U256) -> [u8; 32] { value.to_big_endian() diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 9f03b6cb3..f8965be5b 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "413.0.0" +version = "414.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/evm/aave_trade_executor.rs b/runtime/hydradx/src/evm/aave_trade_executor.rs index 6bc4fbfa2..acd3ab40d 100644 --- a/runtime/hydradx/src/evm/aave_trade_executor.rs +++ b/runtime/hydradx/src/evm/aave_trade_executor.rs @@ -126,6 +126,7 @@ where + pallet_evm_accounts::Config + pallet_broadcast::Config + pallet_dispatcher::Config + + pallet_synthetic_logs::Config + frame_system::Config, T::AssetNativeLocation: Into, BalanceOf: TryFrom + Into, @@ -424,7 +425,8 @@ where + pallet_evm_accounts::Config + pallet_broadcast::Config + frame_system::Config - + pallet_dispatcher::Config, + + pallet_dispatcher::Config + + pallet_synthetic_logs::Config, T::AssetNativeLocation: Into, BalanceOf: TryFrom + Into, T::AddressMapping: pallet_evm::AddressMapping, diff --git a/runtime/hydradx/src/evm/erc20_currency.rs b/runtime/hydradx/src/evm/erc20_currency.rs index 4d5e2e7c7..c5beb54c8 100644 --- a/runtime/hydradx/src/evm/erc20_currency.rs +++ b/runtime/hydradx/src/evm/erc20_currency.rs @@ -44,7 +44,7 @@ pub const HOLDING_ADDRESS: EvmAddress = EvmAddress::repeat_byte(0xFF); impl ERC20 for Erc20Currency where - T: pallet_evm::Config + pallet_dispatcher::Config + frame_system::Config, + T: pallet_evm::Config + pallet_dispatcher::Config + frame_system::Config + pallet_synthetic_logs::Config, T::AddressMapping: pallet_evm::AddressMapping, pallet_evm::AccountIdOf: From, ::AccountId: AsRef<[u8]>, @@ -222,6 +222,7 @@ where + pallet_liquidation::Config + pallet_evm_accounts::Config + pallet_broadcast::Config + + pallet_synthetic_logs::Config + frame_system::Config, pallet_evm_accounts::Pallet: InspectEvmAccounts, AccountId: AsRef<[u8; 32]> + IsType, diff --git a/runtime/hydradx/src/evm/erc20_logs.rs b/runtime/hydradx/src/evm/erc20_logs.rs index 574655a90..d42e81793 100644 --- a/runtime/hydradx/src/evm/erc20_logs.rs +++ b/runtime/hydradx/src/evm/erc20_logs.rs @@ -29,16 +29,14 @@ fn push_transfer_log(asset: AssetId, from: H160, to: H160, amount: Balance) { topics: sp_std::vec![TRANSFER_TOPIC, h160_to_h256(from), h160_to_h256(to)], data, }; - SyntheticLogs::::push(address, log); -} - -fn skip() -> bool { - crate::evm::runner::is_in_evm() + if !crate::evm::runner::append_to_current_evm_frame(log.clone()) { + SyntheticLogs::::push(address, log); + } } impl OnTransfer for EmitErc20TransferLog { fn on_transfer(asset: AssetId, from: &AccountId, to: &AccountId, amount: Balance) -> DispatchResult { - if amount == 0 || skip() { + if amount == 0 { return Ok(()); } push_transfer_log(asset, evm_address_of(from), evm_address_of(to), amount); @@ -48,7 +46,7 @@ impl OnTransfer for EmitErc20TransferLog { impl OnDeposit for EmitErc20TransferLog { fn on_deposit(asset: AssetId, who: &AccountId, amount: Balance) -> DispatchResult { - if amount == 0 || skip() { + if amount == 0 { return Ok(()); } push_transfer_log(asset, H160::zero(), evm_address_of(who), amount); @@ -58,7 +56,7 @@ impl OnDeposit for EmitErc20TransferLog { impl OnSlash for EmitErc20TransferLog { fn on_slash(asset: AssetId, who: &AccountId, amount: Balance) { - if amount == 0 || skip() { + if amount == 0 { return; } push_transfer_log(asset, evm_address_of(who), H160::zero(), amount); @@ -67,7 +65,7 @@ impl OnSlash for EmitErc20TransferLog { impl OnWithdraw for EmitErc20TransferLog { fn on_withdraw(asset: AssetId, who: &AccountId, amount: Balance) -> DispatchResult { - if amount == 0 || skip() { + if amount == 0 { return Ok(()); } push_transfer_log(asset, evm_address_of(who), H160::zero(), amount); @@ -77,28 +75,28 @@ impl OnWithdraw for EmitErc20TransferLog { impl pallet_balances::BalancesHooks for EmitErc20TransferLog { fn on_transfer(from: &AccountId, to: &AccountId, amount: Balance) { - if amount == 0 || skip() { + if amount == 0 { return; } push_transfer_log(CORE_ASSET_ID, evm_address_of(from), evm_address_of(to), amount); } fn on_mint(who: &AccountId, amount: Balance) { - if amount == 0 || skip() { + if amount == 0 { return; } push_transfer_log(CORE_ASSET_ID, H160::zero(), evm_address_of(who), amount); } fn on_burn(who: &AccountId, amount: Balance) { - if amount == 0 || skip() { + if amount == 0 { return; } push_transfer_log(CORE_ASSET_ID, evm_address_of(who), H160::zero(), amount); } fn on_dust_lost(who: &AccountId, amount: Balance) { - if amount == 0 || skip() { + if amount == 0 { return; } push_transfer_log(CORE_ASSET_ID, evm_address_of(who), H160::zero(), amount); diff --git a/runtime/hydradx/src/evm/executor.rs b/runtime/hydradx/src/evm/executor.rs index 179361f33..44beff6f9 100644 --- a/runtime/hydradx/src/evm/executor.rs +++ b/runtime/hydradx/src/evm/executor.rs @@ -24,9 +24,28 @@ pub type NonceIdOf = <::AccountProvider as AccountProvider>::Non pub struct Executor(sp_std::marker::PhantomData); +/// Buffer EVM-frame logs from a `Runner::call` invocation into +/// `pallet_synthetic_logs`. Used by `Executor::call` (the wrapper hydration +/// modules use for direct Runner::call) to surface logs to `eth_getLogs` on +/// paths that bypass `pallet_ethereum::transact` (e.g. HSM arbitrage, +/// dispatcher-driven evm calls). pallet_ethereum::transact does not go +/// through Executor::call, so there is no overlap and no dedup is needed. +fn capture_logs(logs: &[pallet_evm::Log]) { + for log in logs { + pallet_synthetic_logs::Pallet::::push( + log.address, + ethereum::Log { + address: log.address, + topics: log.topics.clone(), + data: log.data.clone(), + }, + ); + } +} + impl Executor where - T: Config + frame_system::Config, + T: Config + frame_system::Config + pallet_synthetic_logs::Config, BalanceOf: TryFrom + Into, T::AddressMapping: AddressMapping, pallet_evm::AccountIdOf: From, @@ -56,7 +75,7 @@ where impl EVM for Executor where - T: frame_system::Config + pallet_evm::Config + pallet_dispatcher::Config, + T: frame_system::Config + pallet_evm::Config + pallet_dispatcher::Config + pallet_synthetic_logs::Config, BalanceOf: TryFrom + Into + Default, NonceIdOf: Into, T::AddressMapping: AddressMapping, @@ -96,6 +115,9 @@ where match call_info_result { Ok(info) => { log::trace!(target: "evm::executor", "Call executed - used gas {:?}", info.used_gas); + if matches!(info.exit_reason, ExitReason::Succeed(_)) { + capture_logs::(&info.logs); + } if extra_gas > 0 { match u64::try_from(info.used_gas.effective) { Ok(standard_gas_u64) => { diff --git a/runtime/hydradx/src/evm/precompiles/mod.rs b/runtime/hydradx/src/evm/precompiles/mod.rs index 0a21a61b2..392b8377e 100644 --- a/runtime/hydradx/src/evm/precompiles/mod.rs +++ b/runtime/hydradx/src/evm/precompiles/mod.rs @@ -191,6 +191,23 @@ where } } + // Drain logs that substrate hooks pushed during the dispatch + // (e.g. orml-tokens PostTransfer, pallet_balances RuntimeHooks, + // pallet_broadcast OnTrade) and emit them inline at the dispatcher + // precompile's call site so log_index ordering matches execution + // order in the resulting eth tx receipt / info.logs. + if matches!( + &dispatch_precompile_result, + Ok(PrecompileOutput { + exit_status: ExitSucceed::Stopped | ExitSucceed::Returned | ExitSucceed::Suicided, + .. + }) + ) { + if let Err(e) = emit_buffered_evm_frame_logs(handle) { + return Some(Err(e)); + } + } + Some(dispatch_precompile_result) } else if is_asset_address(address) { Some(MultiCurrencyPrecompile::::execute(handle)) @@ -213,6 +230,22 @@ pub fn is_precompile(address: H160) -> bool { address == DISPATCH_ADDR || is_asset_address(address) || is_standard_precompile(address) } +/// Drain logs that substrate hooks buffered into the current EVM frame +/// (via `evm::runner::append_to_current_evm_frame`) and emit each through +/// the precompile handle so they land at the precompile's call site in +/// execution order — preserving `log_index` semantics in the final receipt. +/// Charges standard EVM log gas (8 + 375*topics + 8*data_bytes) per entry. +pub fn emit_buffered_evm_frame_logs(handle: &mut impl PrecompileHandle) -> EvmResult<()> { + for log in crate::evm::runner::drain_current_evm_frame_logs() { + let cost = costs::log_costs(log.topics.len(), log.data.len()).map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + })?; + handle.record_cost(cost)?; + handle.log(log.address, log.topics, log.data)?; + } + Ok(()) +} + // This is a reimplementation of the upstream u64->H160 conversion // function, made `const` to make our precompile address `const`s a // bit cleaner. It can be removed when upstream has a const conversion diff --git a/runtime/hydradx/src/evm/precompiles/multicurrency.rs b/runtime/hydradx/src/evm/precompiles/multicurrency.rs index 8e718f6b2..1ede85f65 100644 --- a/runtime/hydradx/src/evm/precompiles/multicurrency.rs +++ b/runtime/hydradx/src/evm/precompiles/multicurrency.rs @@ -38,12 +38,11 @@ use frame_support::traits::{ExistenceRequirement, IsType, OriginTrait}; use hydradx_traits::evm::{Erc20Encoding, InspectEvmAccounts}; use hydradx_traits::registry::Inspect as InspectRegistry; use orml_traits::{MultiCurrency as MultiCurrencyT, MultiCurrency}; -use pallet_evm::{AddressMapping, ExitRevert, Log, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; -use pallet_synthetic_logs::{encode_u256_be, h160_to_h256, TRANSFER_TOPIC}; -use primitive_types::{H160, U256}; +use pallet_evm::{AddressMapping, ExitRevert, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; +use primitive_types::H160; use primitives::{AssetId, Balance}; use sp_runtime::traits::Dispatchable; -use sp_std::{marker::PhantomData, vec}; +use sp_std::marker::PhantomData; pub struct MultiCurrencyPrecompile(PhantomData); @@ -236,10 +235,7 @@ where output: e.encode(), })?; - // Emit ERC-20 Transfer log inline so eth tooling sees the event in the - // real eth tx's logs. The substrate-side orml hooks are suppressed for - // in-evm context (`is_in_evm()` returns true) so we don't double-emit. - emit_erc20_transfer_log(handle, asset_id, from_h160, to_h160, amount)?; + crate::evm::precompiles::emit_buffered_evm_frame_logs(handle)?; Ok(succeed(EvmDataWriter::new().write(true).build())) } @@ -337,35 +333,8 @@ where output: e.encode(), })?; - emit_erc20_transfer_log(handle, asset_id, from, to, amount)?; + crate::evm::precompiles::emit_buffered_evm_frame_logs(handle)?; Ok(succeed(EvmDataWriter::new().write(true).build())) } } - -/// Emit an ERC-20 `Transfer(from, to, amount)` log inline on the precompile -/// handle so it lands in the calling eth transaction's logs. Address used is -/// the precompile's `code_address` (the asset's erc20 contract address). -fn emit_erc20_transfer_log( - handle: &mut impl PrecompileHandle, - asset_id: AssetId, - from: H160, - to: H160, - amount: Balance, -) -> Result<(), PrecompileFailure> { - let _ = asset_id; // contract address is `handle.code_address()`; asset_id reserved for future use - let topics = vec![TRANSFER_TOPIC, h160_to_h256(from), h160_to_h256(to)]; - let data = encode_u256_be(U256::from(amount)).to_vec(); - - // Charge the standard EVM log gas (3 topics, 32 bytes data). - let log_cost = - crate::evm::precompiles::costs::log_costs(topics.len(), data.len()).map_err(|_| PrecompileFailure::Error { - exit_status: pallet_evm::ExitError::OutOfGas, - })?; - handle.record_cost(log_cost)?; - - let address = handle.code_address(); - let log = Log { address, topics, data }; - handle.log(log.address, log.topics, log.data)?; - Ok(()) -} diff --git a/runtime/hydradx/src/evm/runner.rs b/runtime/hydradx/src/evm/runner.rs index 9f3d7069a..47c4aceca 100644 --- a/runtime/hydradx/src/evm/runner.rs +++ b/runtime/hydradx/src/evm/runner.rs @@ -37,16 +37,58 @@ use primitives::{AccountId, AssetId, Balance}; use sp_runtime::traits::UniqueSaturatedInto; use sp_std::vec::Vec; -// Process-local flag set while an EVM execution frame is on the stack. Read by -// substrate-side hooks (e.g. orml-tokens PostTransfer, pallet_broadcast OnTrade) -// to decide whether to buffer a synthetic log or skip — when in-evm, the log is -// expected to be emitted inline by the originating precompile so it lands in the -// real eth tx's logs. Nested frames inherit naturally via `using_once` semantics. -environmental::environmental!(EVM_CONTEXT: bool); +// Per-EVM-frame buffer of substrate-hook-emitted logs. Filled by hooks via +// `append_to_current_evm_frame`; drained by precompiles that trigger +// substrate dispatches (multicurrency, dispatcher) to emit inline at the +// precompile's call site, or — as a safety net — drained by `WrapRunner` +// after `R::call`/`R::create*` returns and appended to `info.logs`. Effect: +// - pallet_ethereum::transact → frontier copies info.logs into the real eth tx +// receipt, so substrate-origin transfers triggered from inside the frame +// surface in the eth tx's receipt. +// - Executor::call → capture_logs surfaces the same logs to pallet_synthetic_logs. +// Active scope also serves as the "in-evm-frame" sentinel: hooks check the +// return value of `append_to_current_evm_frame` to decide whether to fall +// back to pallet_synthetic_logs. +mod evm_frame_logs { + use sp_std::vec::Vec; + environmental::environmental!(EVM_FRAME_LOGS: Vec); -/// Returns true if any EVM execution frame is currently on the call stack. -pub fn is_in_evm() -> bool { - EVM_CONTEXT::with(|in_evm| *in_evm).unwrap_or(false) + pub fn append(log: ethereum::Log) -> bool { + EVM_FRAME_LOGS::with(|buf| buf.push(log)).is_some() + } + + pub fn using R>(buf: &mut Vec, f: F) -> R { + EVM_FRAME_LOGS::using_once(buf, f) + } + + /// Drain all buffered logs from the current EVM frame and return them. + pub fn drain() -> Vec { + EVM_FRAME_LOGS::with(|buf| sp_std::mem::take(buf)).unwrap_or_default() + } +} + +/// Push a substrate-emitted log into the current EVM frame's log buffer. +/// Returns `true` if a frame was active and the log was buffered, `false` +/// otherwise (caller should then fall back to pallet_synthetic_logs). +pub fn append_to_current_evm_frame(log: ethereum::Log) -> bool { + evm_frame_logs::append(log) +} + +/// Drain all logs buffered in the current EVM frame. Precompiles that +/// trigger substrate dispatches (and thus may have caused hooks to push) +/// call this immediately before returning, then re-emit via `handle.log()` +/// so the logs land at their natural position in the EVM execution's log +/// list (preserving log_index order in the eventual eth tx receipt). +pub fn drain_current_evm_frame_logs() -> Vec { + evm_frame_logs::drain() +} + +fn evm_log_to_fp(log: ethereum::Log) -> pallet_evm::Log { + pallet_evm::Log { + address: log.address, + topics: log.topics, + data: log.data, + } } pub struct WrapRunner(sp_std::marker::PhantomData<(T, R, B)>); @@ -168,7 +210,8 @@ where let original_nonce = frame_system::Pallet::::account_nonce(source_account_id.clone()); // Validated, flag set to false - let result = EVM_CONTEXT::using_once(&mut true, || { + let mut frame_logs: Vec = Vec::new(); + let mut result = evm_frame_logs::using(&mut frame_logs, || { R::call( source, target, @@ -187,6 +230,7 @@ where config, ) })?; + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); if validate && is_transactional && nonce.is_none() && max_priority_fee_per_gas.is_none() { let current_nonce = frame_system::Pallet::::account_nonce(source_account_id.clone()); @@ -235,7 +279,8 @@ where )?; } // Validated, flag set to false - EVM_CONTEXT::using_once(&mut true, || { + let mut frame_logs: Vec = Vec::new(); + let mut result = evm_frame_logs::using(&mut frame_logs, || { R::create( source, init, @@ -252,7 +297,9 @@ where proof_size_base_cost, config, ) - }) + })?; + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + Ok(result) } fn create2( @@ -291,7 +338,8 @@ where )?; } //Validated, flag set to false - EVM_CONTEXT::using_once(&mut true, || { + let mut frame_logs: Vec = Vec::new(); + let mut result = evm_frame_logs::using(&mut frame_logs, || { R::create2( source, init, @@ -309,7 +357,9 @@ where proof_size_base_cost, config, ) - }) + })?; + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + Ok(result) } fn create_force_address( @@ -348,7 +398,8 @@ where )?; } //Validated, flag set to false - EVM_CONTEXT::using_once(&mut true, || { + let mut frame_logs: Vec = Vec::new(); + let mut result = evm_frame_logs::using(&mut frame_logs, || { R::create_force_address( source, init, @@ -366,7 +417,9 @@ where config, contract_address, ) - }) + })?; + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + Ok(result) } } diff --git a/runtime/hydradx/src/evm/swap_logs.rs b/runtime/hydradx/src/evm/swap_logs.rs index 084853294..1bcf2fb79 100644 --- a/runtime/hydradx/src/evm/swap_logs.rs +++ b/runtime/hydradx/src/evm/swap_logs.rs @@ -61,14 +61,6 @@ impl OnTrade for EmitUniswapV2SwapLog { return; } - // Today no swap precompile exists, so substrate-side trades never fire - // while inside an evm execution frame. Defensive guard: if a future - // swap precompile is added, it must emit the log inline itself; we - // skip here to avoid double-emission. - if crate::evm::runner::is_in_evm() { - return; - } - let in_asset = inputs[0].asset; let in_amount = inputs[0].amount; let out_asset = outputs[0].asset; @@ -123,6 +115,8 @@ impl OnTrade for EmitUniswapV2SwapLog { data: encode_uint256_quad(a0_in, a1_in, a0_out, a1_out), }; - SyntheticLogs::::push(pool_address, log); + if !crate::evm::runner::append_to_current_evm_frame(log.clone()) { + SyntheticLogs::::push(pool_address, log); + } } } diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 547318a55..f068d3bc1 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: Cow::Borrowed("hydradx"), impl_name: Cow::Borrowed("hydradx"), authoring_version: 1, - spec_version: 413, + spec_version: 414, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/scripts/test-contracts/artifacts/contracts/GasEatingToken.sol/GasEatingToken.json b/scripts/test-contracts/artifacts/contracts/GasEatingToken.sol/GasEatingToken.json new file mode 100644 index 000000000..194c93ded --- /dev/null +++ b/scripts/test-contracts/artifacts/contracts/GasEatingToken.sol/GasEatingToken.json @@ -0,0 +1,324 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "GasEatingToken", + "sourceName": "contracts/GasEatingToken.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b506040518060400160405280600881526020017f47617345617465720000000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f454154455200000000000000000000000000000000000000000000000000000081525081600390816200008f91906200062a565b508060049081620000a191906200062a565b505050620000e433620000b9620000ea60201b60201c565b600a620000c79190620008a1565b633b9aca00620000d89190620008f2565b620000f360201b60201c565b62000a45565b60006012905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620001685760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016200015f919062000982565b60405180910390fd5b6200017c600083836200018060201b60201c565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620001d6578060026000828254620001c991906200099f565b92505081905550620002ac565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101562000265578381836040517fe450d38c0000000000000000000000000000000000000000000000000000000081526004016200025c93929190620009eb565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620002f7578060026000828254039250508190555062000344565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620003a3919062000a28565b60405180910390a3505050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200043257607f821691505b602082108103620004485762000447620003ea565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004b27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000473565b620004be868362000473565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200050b62000505620004ff84620004d6565b620004e0565b620004d6565b9050919050565b6000819050919050565b6200052783620004ea565b6200053f620005368262000512565b84845462000480565b825550505050565b600090565b6200055662000547565b620005638184846200051c565b505050565b5b818110156200058b576200057f6000826200054c565b60018101905062000569565b5050565b601f821115620005da57620005a4816200044e565b620005af8462000463565b81016020851015620005bf578190505b620005d7620005ce8562000463565b83018262000568565b50505b505050565b600082821c905092915050565b6000620005ff60001984600802620005df565b1980831691505092915050565b60006200061a8383620005ec565b9150826002028217905092915050565b6200063582620003b0565b67ffffffffffffffff811115620006515762000650620003bb565b5b6200065d825462000419565b6200066a8282856200058f565b600060209050601f831160018114620006a257600084156200068d578287015190505b6200069985826200060c565b86555062000709565b601f198416620006b2866200044e565b60005b82811015620006dc57848901518255600182019150602085019450602081019050620006b5565b86831015620006fc5784890151620006f8601f891682620005ec565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160011c9050919050565b6000808291508390505b60018511156200079f5780860481111562000777576200077662000711565b5b6001851615620007875780820291505b8081029050620007978562000740565b945062000757565b94509492505050565b600082620007ba57600190506200088d565b81620007ca57600090506200088d565b8160018114620007e35760028114620007ee5762000824565b60019150506200088d565b60ff84111562000803576200080262000711565b5b8360020a9150848211156200081d576200081c62000711565b5b506200088d565b5060208310610133831016604e8410600b84101617156200085e5782820a90508381111562000858576200085762000711565b5b6200088d565b6200086d84848460016200074d565b9250905081840481111562000887576200088662000711565b5b81810290505b9392505050565b600060ff82169050919050565b6000620008ae82620004d6565b9150620008bb8362000894565b9250620008ea7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620007a8565b905092915050565b6000620008ff82620004d6565b91506200090c83620004d6565b92508282026200091c81620004d6565b9150828204841483151762000936576200093562000711565b5b5092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200096a826200093d565b9050919050565b6200097c816200095d565b82525050565b600060208201905062000999600083018462000971565b92915050565b6000620009ac82620004d6565b9150620009b983620004d6565b9250828201905080821115620009d457620009d362000711565b5b92915050565b620009e581620004d6565b82525050565b600060608201905062000a02600083018662000971565b62000a116020830185620009da565b62000a206040830184620009da565b949350505050565b600060208201905062000a3f6000830184620009da565b92915050565b610f658062000a556000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce5671461013457806370a082311461015257806395d89b4114610182578063a9059cbb146101a0578063dd62ed3e146101d057610093565b806306fdde0314610098578063095ea7b3146100b657806318160ddd146100e657806323b872dd14610104575b600080fd5b6100a0610200565b6040516100ad9190610b3d565b60405180910390f35b6100d060048036038101906100cb9190610bf8565b610292565b6040516100dd9190610c53565b60405180910390f35b6100ee6102b5565b6040516100fb9190610c7d565b60405180910390f35b61011e60048036038101906101199190610c98565b6102bf565b60405161012b9190610c53565b60405180910390f35b61013c61030a565b6040516101499190610d07565b60405180910390f35b61016c60048036038101906101679190610d22565b610313565b6040516101799190610c7d565b60405180910390f35b61018a61035b565b6040516101979190610b3d565b60405180910390f35b6101ba60048036038101906101b59190610bf8565b6103ed565b6040516101c79190610c53565b60405180910390f35b6101ea60048036038101906101e59190610d4f565b610436565b6040516101f79190610c7d565b60405180910390f35b60606003805461020f90610dbe565b80601f016020809104026020016040519081016040528092919081815260200182805461023b90610dbe565b80156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b5050505050905090565b60008061029d6104bd565b90506102aa8185856104c5565b600191505092915050565b6000600254905090565b60006205cc6060005a905060005b825a836102da9190610e1e565b10156102f35780806102eb90610e52565b9150506102cd565b6102fe8787876104d7565b93505050509392505050565b60006012905090565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606004805461036a90610dbe565b80601f016020809104026020016040519081016040528092919081815260200182805461039690610dbe565b80156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b5050505050905090565b60006205cc6060005a905060005b825a836104089190610e1e565b101561042157808061041990610e52565b9150506103fb565b61042b8686610506565b935050505092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b6104d28383836001610529565b505050565b6000806104e26104bd565b90506104ef858285610700565b6104fa858585610794565b60019150509392505050565b6000806105116104bd565b905061051e818585610794565b600191505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361059b5760006040517fe602df050000000000000000000000000000000000000000000000000000000081526004016105929190610ea9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361060d5760006040517f94280d620000000000000000000000000000000000000000000000000000000081526004016106049190610ea9565b60405180910390fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080156106fa578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516106f19190610c7d565b60405180910390a35b50505050565b600061070c8484610436565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461078e578181101561077e578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161077593929190610ec4565b60405180910390fd5b61078d84848484036000610529565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108065760006040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016107fd9190610ea9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036108785760006040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161086f9190610ea9565b60405180910390fd5b610883838383610888565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108da5780600260008282546108ce9190610efb565b925050819055506109ad565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610966578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161095d93929190610ec4565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109f65780600260008282540392505081905550610a43565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610aa09190610c7d565b60405180910390a3505050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610ae7578082015181840152602081019050610acc565b60008484015250505050565b6000601f19601f8301169050919050565b6000610b0f82610aad565b610b198185610ab8565b9350610b29818560208601610ac9565b610b3281610af3565b840191505092915050565b60006020820190508181036000830152610b578184610b04565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b8f82610b64565b9050919050565b610b9f81610b84565b8114610baa57600080fd5b50565b600081359050610bbc81610b96565b92915050565b6000819050919050565b610bd581610bc2565b8114610be057600080fd5b50565b600081359050610bf281610bcc565b92915050565b60008060408385031215610c0f57610c0e610b5f565b5b6000610c1d85828601610bad565b9250506020610c2e85828601610be3565b9150509250929050565b60008115159050919050565b610c4d81610c38565b82525050565b6000602082019050610c686000830184610c44565b92915050565b610c7781610bc2565b82525050565b6000602082019050610c926000830184610c6e565b92915050565b600080600060608486031215610cb157610cb0610b5f565b5b6000610cbf86828701610bad565b9350506020610cd086828701610bad565b9250506040610ce186828701610be3565b9150509250925092565b600060ff82169050919050565b610d0181610ceb565b82525050565b6000602082019050610d1c6000830184610cf8565b92915050565b600060208284031215610d3857610d37610b5f565b5b6000610d4684828501610bad565b91505092915050565b60008060408385031215610d6657610d65610b5f565b5b6000610d7485828601610bad565b9250506020610d8585828601610bad565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610dd657607f821691505b602082108103610de957610de8610d8f565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610e2982610bc2565b9150610e3483610bc2565b9250828203905081811115610e4c57610e4b610def565b5b92915050565b6000610e5d82610bc2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610e8f57610e8e610def565b5b600182019050919050565b610ea381610b84565b82525050565b6000602082019050610ebe6000830184610e9a565b92915050565b6000606082019050610ed96000830186610e9a565b610ee66020830185610c6e565b610ef36040830184610c6e565b949350505050565b6000610f0682610bc2565b9150610f1183610bc2565b9250828201905080821115610f2957610f28610def565b5b9291505056fea26469706673582212203bafddc7b544e22a6f9cb5cc7ac40e036ecc256d79e905ac7755e127f009825464736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce5671461013457806370a082311461015257806395d89b4114610182578063a9059cbb146101a0578063dd62ed3e146101d057610093565b806306fdde0314610098578063095ea7b3146100b657806318160ddd146100e657806323b872dd14610104575b600080fd5b6100a0610200565b6040516100ad9190610b3d565b60405180910390f35b6100d060048036038101906100cb9190610bf8565b610292565b6040516100dd9190610c53565b60405180910390f35b6100ee6102b5565b6040516100fb9190610c7d565b60405180910390f35b61011e60048036038101906101199190610c98565b6102bf565b60405161012b9190610c53565b60405180910390f35b61013c61030a565b6040516101499190610d07565b60405180910390f35b61016c60048036038101906101679190610d22565b610313565b6040516101799190610c7d565b60405180910390f35b61018a61035b565b6040516101979190610b3d565b60405180910390f35b6101ba60048036038101906101b59190610bf8565b6103ed565b6040516101c79190610c53565b60405180910390f35b6101ea60048036038101906101e59190610d4f565b610436565b6040516101f79190610c7d565b60405180910390f35b60606003805461020f90610dbe565b80601f016020809104026020016040519081016040528092919081815260200182805461023b90610dbe565b80156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b5050505050905090565b60008061029d6104bd565b90506102aa8185856104c5565b600191505092915050565b6000600254905090565b60006205cc6060005a905060005b825a836102da9190610e1e565b10156102f35780806102eb90610e52565b9150506102cd565b6102fe8787876104d7565b93505050509392505050565b60006012905090565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606004805461036a90610dbe565b80601f016020809104026020016040519081016040528092919081815260200182805461039690610dbe565b80156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b5050505050905090565b60006205cc6060005a905060005b825a836104089190610e1e565b101561042157808061041990610e52565b9150506103fb565b61042b8686610506565b935050505092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b6104d28383836001610529565b505050565b6000806104e26104bd565b90506104ef858285610700565b6104fa858585610794565b60019150509392505050565b6000806105116104bd565b905061051e818585610794565b600191505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361059b5760006040517fe602df050000000000000000000000000000000000000000000000000000000081526004016105929190610ea9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361060d5760006040517f94280d620000000000000000000000000000000000000000000000000000000081526004016106049190610ea9565b60405180910390fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080156106fa578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516106f19190610c7d565b60405180910390a35b50505050565b600061070c8484610436565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461078e578181101561077e578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161077593929190610ec4565b60405180910390fd5b61078d84848484036000610529565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108065760006040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016107fd9190610ea9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036108785760006040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161086f9190610ea9565b60405180910390fd5b610883838383610888565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108da5780600260008282546108ce9190610efb565b925050819055506109ad565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610966578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161095d93929190610ec4565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109f65780600260008282540392505081905550610a43565b806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610aa09190610c7d565b60405180910390a3505050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610ae7578082015181840152602081019050610acc565b60008484015250505050565b6000601f19601f8301169050919050565b6000610b0f82610aad565b610b198185610ab8565b9350610b29818560208601610ac9565b610b3281610af3565b840191505092915050565b60006020820190508181036000830152610b578184610b04565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b8f82610b64565b9050919050565b610b9f81610b84565b8114610baa57600080fd5b50565b600081359050610bbc81610b96565b92915050565b6000819050919050565b610bd581610bc2565b8114610be057600080fd5b50565b600081359050610bf281610bcc565b92915050565b60008060408385031215610c0f57610c0e610b5f565b5b6000610c1d85828601610bad565b9250506020610c2e85828601610be3565b9150509250929050565b60008115159050919050565b610c4d81610c38565b82525050565b6000602082019050610c686000830184610c44565b92915050565b610c7781610bc2565b82525050565b6000602082019050610c926000830184610c6e565b92915050565b600080600060608486031215610cb157610cb0610b5f565b5b6000610cbf86828701610bad565b9350506020610cd086828701610bad565b9250506040610ce186828701610be3565b9150509250925092565b600060ff82169050919050565b610d0181610ceb565b82525050565b6000602082019050610d1c6000830184610cf8565b92915050565b600060208284031215610d3857610d37610b5f565b5b6000610d4684828501610bad565b91505092915050565b60008060408385031215610d6657610d65610b5f565b5b6000610d7485828601610bad565b9250506020610d8585828601610bad565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610dd657607f821691505b602082108103610de957610de8610d8f565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610e2982610bc2565b9150610e3483610bc2565b9250828203905081811115610e4c57610e4b610def565b5b92915050565b6000610e5d82610bc2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610e8f57610e8e610def565b5b600182019050919050565b610ea381610b84565b82525050565b6000602082019050610ebe6000830184610e9a565b92915050565b6000606082019050610ed96000830186610e9a565b610ee66020830185610c6e565b610ef36040830184610c6e565b949350505050565b6000610f0682610bc2565b9150610f1183610bc2565b9250828201905080821115610f2957610f28610def565b5b9291505056fea26469706673582212203bafddc7b544e22a6f9cb5cc7ac40e036ecc256d79e905ac7755e127f009825464736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/IERC20.json b/scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/IERC20.json new file mode 100644 index 000000000..66919cc8e --- /dev/null +++ b/scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/IERC20.json @@ -0,0 +1,35 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "IERC20", + "sourceName": "contracts/LogOrderProbe.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/LogOrderProbe.json b/scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/LogOrderProbe.json new file mode 100644 index 000000000..e02726894 --- /dev/null +++ b/scripts/test-contracts/artifacts/contracts/LogOrderProbe.sol/LogOrderProbe.json @@ -0,0 +1,47 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "LogOrderProbe", + "sourceName": "contracts/LogOrderProbe.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "idx", + "type": "uint256" + } + ], + "name": "Marker", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exercise", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b506103c4806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063430c930414610030575b600080fd5b61004a600480360381019061004591906101d9565b61004c565b005b7f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b24600060405161007c9190610271565b60405180910390a18273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b81526004016100bf9291906102aa565b6020604051808303816000875af11580156100de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610102919061030b565b507f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b2460016040516101339190610373565b60405180910390a1505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061017082610145565b9050919050565b61018081610165565b811461018b57600080fd5b50565b60008135905061019d81610177565b92915050565b6000819050919050565b6101b6816101a3565b81146101c157600080fd5b50565b6000813590506101d3816101ad565b92915050565b6000806000606084860312156101f2576101f1610140565b5b60006102008682870161018e565b93505060206102118682870161018e565b9250506040610222868287016101c4565b9150509250925092565b6000819050919050565b6000819050919050565b600061025b6102566102518461022c565b610236565b6101a3565b9050919050565b61026b81610240565b82525050565b60006020820190506102866000830184610262565b92915050565b61029581610165565b82525050565b6102a4816101a3565b82525050565b60006040820190506102bf600083018561028c565b6102cc602083018461029b565b9392505050565b60008115159050919050565b6102e8816102d3565b81146102f357600080fd5b50565b600081519050610305816102df565b92915050565b60006020828403121561032157610320610140565b5b600061032f848285016102f6565b91505092915050565b6000819050919050565b600061035d61035861035384610338565b610236565b6101a3565b9050919050565b61036d81610342565b82525050565b60006020820190506103886000830184610364565b9291505056fea2646970667358221220737d96a602a1437aee784f9959dfb12b28e1ed46dc9f2f6dda81d7bb84adf3b164736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063430c930414610030575b600080fd5b61004a600480360381019061004591906101d9565b61004c565b005b7f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b24600060405161007c9190610271565b60405180910390a18273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b81526004016100bf9291906102aa565b6020604051808303816000875af11580156100de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610102919061030b565b507f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b2460016040516101339190610373565b60405180910390a1505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061017082610145565b9050919050565b61018081610165565b811461018b57600080fd5b50565b60008135905061019d81610177565b92915050565b6000819050919050565b6101b6816101a3565b81146101c157600080fd5b50565b6000813590506101d3816101ad565b92915050565b6000806000606084860312156101f2576101f1610140565b5b60006102008682870161018e565b93505060206102118682870161018e565b9250506040610222868287016101c4565b9150509250925092565b6000819050919050565b6000819050919050565b600061025b6102566102518461022c565b610236565b6101a3565b9050919050565b61026b81610240565b82525050565b60006020820190506102866000830184610262565b92915050565b61029581610165565b82525050565b6102a4816101a3565b82525050565b60006040820190506102bf600083018561028c565b6102cc602083018461029b565b9392505050565b60008115159050919050565b6102e8816102d3565b81146102f357600080fd5b50565b600081519050610305816102df565b92915050565b60006020828403121561032157610320610140565b5b600061032f848285016102f6565b91505092915050565b6000819050919050565b600061035d61035861035384610338565b610236565b6101a3565b9050919050565b61036d81610342565b82525050565b60006020820190506103886000830184610364565b9291505056fea2646970667358221220737d96a602a1437aee784f9959dfb12b28e1ed46dc9f2f6dda81d7bb84adf3b164736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/scripts/test-contracts/contracts/LogOrderProbe.sol b/scripts/test-contracts/contracts/LogOrderProbe.sol new file mode 100644 index 000000000..b1eede4aa --- /dev/null +++ b/scripts/test-contracts/contracts/LogOrderProbe.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +interface IERC20 { + function transfer(address to, uint256 amount) external returns (bool); +} + +/// Probe contract used to verify EVM log ordering. +/// +/// `exercise(token, to, amount)` emits Marker(0), then calls +/// token.transfer(to, amount) (which goes through the multicurrency +/// precompile and triggers the substrate-side hook), then emits Marker(1). +/// +/// In the resulting receipt logs we expect log_index ordering: +/// [Marker(0), Transfer(from=this, to=to, value=amount), Marker(1)] +/// +/// — proving that substrate-hook-emitted logs land at the precompile's +/// call site (via the per-precompile drain) and are NOT bunched at the +/// end of the EVM frame's logs. +contract LogOrderProbe { + event Marker(uint256 idx); + + function exercise(address token, address to, uint256 amount) external { + emit Marker(0); + IERC20(token).transfer(to, amount); + emit Marker(1); + } +} From 0d0d569079a9ebf3d9cf8343c16332a4c8e219e4 Mon Sep 17 00:00:00 2001 From: mrq Date: Mon, 4 May 2026 23:21:06 +0200 Subject: [PATCH 06/17] reserve support --- Cargo.lock | 766 +++++++++--------- .../src/balances_tokens_hooks.rs | 115 +++ pallets/circuit-breaker/src/tests/mock.rs | 3 + pallets/stableswap/src/tests/mock.rs | 3 + pallets/synthetic-logs/Cargo.toml | 2 +- pallets/transaction-multi-payment/src/mock.rs | 3 + runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/assets.rs | 3 + runtime/hydradx/src/evm/erc20_logs.rs | 82 +- runtime/hydradx/src/lib.rs | 2 +- 10 files changed, 593 insertions(+), 388 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf25148ff..a6a9742a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1086,7 +1086,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "asset-test-utils" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -1116,7 +1116,7 @@ dependencies = [ [[package]] name = "assets-common" version = "0.22.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "ethereum-standards", @@ -1482,7 +1482,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "binary-merkle-tree" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "hash-db", "log", @@ -1779,7 +1779,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1796,7 +1796,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-runtime", @@ -1812,7 +1812,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -1829,7 +1829,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-messages", "bp-runtime", @@ -1846,7 +1846,7 @@ dependencies = [ [[package]] name = "bp-relayers" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-messages", @@ -1864,7 +1864,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -1887,7 +1887,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-parachains", @@ -1907,7 +1907,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-messages", "bp-runtime", @@ -1924,7 +1924,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub-router" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -1936,7 +1936,7 @@ dependencies = [ [[package]] name = "bridge-hub-common" version = "0.14.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1955,7 +1955,7 @@ dependencies = [ [[package]] name = "bridge-hub-test-utils" version = "0.23.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "asset-test-utils", "bp-header-chain", @@ -1997,7 +1997,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.22.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-messages", @@ -2928,7 +2928,7 @@ dependencies = [ [[package]] name = "cumulus-client-bootnodes" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -2954,7 +2954,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "clap", "parity-scale-codec", @@ -2971,7 +2971,7 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -2994,7 +2994,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" version = "0.24.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-client-collator", @@ -3041,7 +3041,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -3073,7 +3073,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-proposer" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "anyhow", "async-trait", @@ -3088,7 +3088,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-relay-chain" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-client-consensus-common", @@ -3111,7 +3111,7 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -3138,7 +3138,7 @@ dependencies = [ [[package]] name = "cumulus-client-parachain-inherent" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3159,7 +3159,7 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3187,7 +3187,7 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.25.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-channel 1.9.0", "cumulus-client-cli", @@ -3228,7 +3228,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-aura-ext" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3245,7 +3245,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system" version = "0.21.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "bytes", @@ -3300,7 +3300,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.6.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -3311,7 +3311,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-session-benchmarking" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-solo-to-para" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-weight-reclaim" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-storage-weight-reclaim", "derive-where", @@ -3358,7 +3358,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3373,7 +3373,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.21.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "approx", "bounded-collections 0.2.4", @@ -3399,7 +3399,7 @@ dependencies = [ [[package]] name = "cumulus-ping" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-pallet-xcm", "cumulus-primitives-core", @@ -3414,7 +3414,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-aura" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "sp-api", "sp-consensus-aura", @@ -3423,7 +3423,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -3440,7 +3440,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3454,7 +3454,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-proof-size-hostfunction" version = "0.13.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "sp-externalities", "sp-runtime-interface", @@ -3464,7 +3464,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-storage-weight-reclaim" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-proof-size-hostfunction", @@ -3481,7 +3481,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-timestamp" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "sp-inherents", @@ -3491,7 +3491,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-utility" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3508,7 +3508,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -3536,7 +3536,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3556,7 +3556,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-minimal-node" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -3592,7 +3592,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-streams" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-relay-chain-interface", "futures", @@ -3647,7 +3647,7 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -4417,7 +4417,7 @@ dependencies = [ [[package]] name = "ethereum-standards" version = "0.1.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "alloy-core", ] @@ -4922,7 +4922,7 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fork-tree" version = "13.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", ] @@ -5060,7 +5060,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-support-procedural", @@ -5084,7 +5084,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "49.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "Inflector", "array-bytes 6.2.2", @@ -5149,7 +5149,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-pallet-pov" version = "31.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -5177,7 +5177,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "16.1.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -5188,7 +5188,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -5205,7 +5205,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "aquamarine", "frame-support", @@ -5247,7 +5247,7 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" version = "0.9.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "const-hex", @@ -5263,7 +5263,7 @@ dependencies = [ [[package]] name = "frame-remote-externalities" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "indicatif", @@ -5285,7 +5285,7 @@ dependencies = [ [[package]] name = "frame-storage-access-test-runtime" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-pallet-parachain-system", "parity-scale-codec", @@ -5299,7 +5299,7 @@ dependencies = [ [[package]] name = "frame-support" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "aquamarine", "array-bytes 6.2.2", @@ -5340,7 +5340,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "34.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "Inflector", "cfg-expr", @@ -5360,7 +5360,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "13.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.1.0", @@ -5372,7 +5372,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro2", "quote", @@ -5382,7 +5382,7 @@ dependencies = [ [[package]] name = "frame-system" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cfg-if", "docify", @@ -5401,7 +5401,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -5415,7 +5415,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "parity-scale-codec", @@ -5425,7 +5425,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.47.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "parity-scale-codec", @@ -6379,7 +6379,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "414.0.0" +version = "415.0.0" dependencies = [ "alloy-primitives 0.7.7", "alloy-sol-types 0.7.7", @@ -8456,7 +8456,7 @@ dependencies = [ [[package]] name = "mmr-gadget" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "log", @@ -8475,7 +8475,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -9141,7 +9141,7 @@ dependencies = [ [[package]] name = "orml-benchmarking" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-benchmarking", "frame-support", @@ -9162,7 +9162,7 @@ dependencies = [ [[package]] name = "orml-tokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "frame-system", @@ -9179,7 +9179,7 @@ dependencies = [ [[package]] name = "orml-traits" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -9199,7 +9199,7 @@ dependencies = [ [[package]] name = "orml-unknown-tokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "frame-system", @@ -9214,7 +9214,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "parity-scale-codec", @@ -9229,7 +9229,7 @@ dependencies = [ [[package]] name = "orml-vesting" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "frame-system", @@ -9244,7 +9244,7 @@ dependencies = [ [[package]] name = "orml-xcm" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "frame-system", @@ -9258,7 +9258,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "orml-traits", @@ -9272,7 +9272,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#bbcd8744f11d3d7376f89ff9f8c21761a4bfaf52" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" dependencies = [ "frame-support", "frame-system", @@ -9299,7 +9299,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pallet-alliance" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "frame-benchmarking", @@ -9319,7 +9319,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9337,7 +9337,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-ops" version = "0.9.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9355,7 +9355,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-tx-payment" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9370,7 +9370,7 @@ dependencies = [ [[package]] name = "pallet-asset-rate" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9413,7 +9413,7 @@ dependencies = [ [[package]] name = "pallet-asset-rewards" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9431,7 +9431,7 @@ dependencies = [ [[package]] name = "pallet-asset-tx-payment" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9447,7 +9447,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "43.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "ethereum-standards", "frame-benchmarking", @@ -9465,7 +9465,7 @@ dependencies = [ [[package]] name = "pallet-assets-freezer" version = "0.8.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "pallet-assets", @@ -9477,7 +9477,7 @@ dependencies = [ [[package]] name = "pallet-assets-holder" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9492,7 +9492,7 @@ dependencies = [ [[package]] name = "pallet-atomic-swap" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -9502,7 +9502,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -9518,7 +9518,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -9533,7 +9533,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -9546,7 +9546,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9569,7 +9569,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "aquamarine", "docify", @@ -9590,7 +9590,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -9606,7 +9606,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -9625,7 +9625,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "binary-merkle-tree", @@ -9674,7 +9674,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9691,7 +9691,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-runtime", @@ -9710,7 +9710,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-messages", @@ -9729,7 +9729,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-parachains", @@ -9749,7 +9749,7 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-header-chain", "bp-messages", @@ -9792,7 +9792,7 @@ dependencies = [ [[package]] name = "pallet-broker" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "frame-benchmarking", @@ -9810,7 +9810,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9919,7 +9919,7 @@ dependencies = [ [[package]] name = "pallet-collator-selection" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9938,7 +9938,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -9955,7 +9955,7 @@ dependencies = [ [[package]] name = "pallet-collective-content" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -9969,7 +9969,7 @@ dependencies = [ [[package]] name = "pallet-contracts" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "environmental", "frame-benchmarking", @@ -10000,7 +10000,7 @@ dependencies = [ [[package]] name = "pallet-contracts-mock-network" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -10031,7 +10031,7 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "23.0.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro2", "quote", @@ -10041,7 +10041,7 @@ dependencies = [ [[package]] name = "pallet-contracts-uapi" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -10052,7 +10052,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "assert_matches", "frame-benchmarking", @@ -10068,7 +10068,7 @@ dependencies = [ [[package]] name = "pallet-core-fellowship" version = "25.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -10160,7 +10160,7 @@ dependencies = [ [[package]] name = "pallet-delegated-staking" version = "8.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -10195,7 +10195,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -10212,7 +10212,7 @@ dependencies = [ [[package]] name = "pallet-dev-mode" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -10280,7 +10280,7 @@ dependencies = [ [[package]] name = "pallet-dummy-dim" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -10379,7 +10379,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-block" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10400,7 +10400,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10421,7 +10421,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10434,7 +10434,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -10674,7 +10674,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -10710,7 +10710,7 @@ dependencies = [ [[package]] name = "pallet-glutton" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "blake2 0.10.6", "frame-benchmarking", @@ -10728,7 +10728,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -10801,7 +10801,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "enumflags2", "frame-benchmarking", @@ -10817,7 +10817,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -10836,7 +10836,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -10851,7 +10851,7 @@ dependencies = [ [[package]] name = "pallet-insecure-randomness-collective-flip" version = "29.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11016,7 +11016,7 @@ dependencies = [ [[package]] name = "pallet-lottery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11029,7 +11029,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11045,7 +11045,7 @@ dependencies = [ [[package]] name = "pallet-message-queue" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "environmental", "frame-benchmarking", @@ -11064,7 +11064,7 @@ dependencies = [ [[package]] name = "pallet-meta-tx" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -11082,7 +11082,7 @@ dependencies = [ [[package]] name = "pallet-migrations" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -11101,7 +11101,7 @@ dependencies = [ [[package]] name = "pallet-mixnet" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "parity-scale-codec", @@ -11115,7 +11115,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "parity-scale-codec", @@ -11127,7 +11127,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "parity-scale-codec", @@ -11158,7 +11158,7 @@ dependencies = [ [[package]] name = "pallet-nft-fractionalization" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "pallet-assets", @@ -11171,7 +11171,7 @@ dependencies = [ [[package]] name = "pallet-nfts" version = "35.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "enumflags2", "frame-benchmarking", @@ -11188,7 +11188,7 @@ dependencies = [ [[package]] name = "pallet-nfts-runtime-api" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "sp-api", @@ -11197,7 +11197,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11207,7 +11207,7 @@ dependencies = [ [[package]] name = "pallet-node-authorization" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "parity-scale-codec", @@ -11218,7 +11218,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -11236,7 +11236,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11256,7 +11256,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -11266,7 +11266,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -11281,7 +11281,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11364,7 +11364,7 @@ dependencies = [ [[package]] name = "pallet-origin-restriction" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11436,7 +11436,7 @@ dependencies = [ [[package]] name = "pallet-paged-list" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "parity-scale-codec", @@ -11448,7 +11448,7 @@ dependencies = [ [[package]] name = "pallet-parameters" version = "0.12.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -11479,7 +11479,7 @@ dependencies = [ [[package]] name = "pallet-people" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11497,7 +11497,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11513,7 +11513,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11523,7 +11523,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11541,7 +11541,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11551,7 +11551,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "assert_matches", "frame-benchmarking", @@ -11605,7 +11605,7 @@ dependencies = [ [[package]] name = "pallet-remark" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11621,7 +11621,7 @@ dependencies = [ [[package]] name = "pallet-revive" version = "0.7.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "alloy-core", "derive_more 0.99.20", @@ -11667,7 +11667,7 @@ dependencies = [ [[package]] name = "pallet-revive-fixtures" version = "0.4.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "anyhow", "cargo_metadata", @@ -11681,7 +11681,7 @@ dependencies = [ [[package]] name = "pallet-revive-proc-macro" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro2", "quote", @@ -11691,7 +11691,7 @@ dependencies = [ [[package]] name = "pallet-revive-uapi" version = "0.5.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitflags 1.3.2", "pallet-revive-proc-macro", @@ -11703,7 +11703,7 @@ dependencies = [ [[package]] name = "pallet-root-offences" version = "38.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -11719,7 +11719,7 @@ dependencies = [ [[package]] name = "pallet-root-testing" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -11759,7 +11759,7 @@ dependencies = [ [[package]] name = "pallet-safe-mode" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "pallet-balances", @@ -11773,7 +11773,7 @@ dependencies = [ [[package]] name = "pallet-salary" version = "26.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "pallet-ranked-collective", @@ -11785,7 +11785,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -11802,7 +11802,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -11815,7 +11815,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -11836,7 +11836,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11870,7 +11870,7 @@ dependencies = [ [[package]] name = "pallet-skip-feeless-payment" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -11882,7 +11882,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -11958,7 +11958,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11980,7 +11980,7 @@ dependencies = [ [[package]] name = "pallet-staking-async" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -12003,7 +12003,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-ah-client" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -12022,7 +12022,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-rc-client" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -12039,7 +12039,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-reward-fn" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "sp-arithmetic", @@ -12048,7 +12048,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-runtime-api" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "sp-api", @@ -12058,7 +12058,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "sp-arithmetic", @@ -12067,7 +12067,7 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "sp-api", @@ -12077,7 +12077,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12093,7 +12093,7 @@ dependencies = [ [[package]] name = "pallet-statement" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", @@ -12110,7 +12110,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -12124,7 +12124,7 @@ dependencies = [ [[package]] name = "pallet-synthetic-logs" -version = "0.1.0" +version = "0.2.0" dependencies = [ "ethereum", "ethereum-types", @@ -12149,7 +12149,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -12167,7 +12167,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12255,7 +12255,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12270,7 +12270,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -12286,7 +12286,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -12298,7 +12298,7 @@ dependencies = [ [[package]] name = "pallet-transaction-storage" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "frame-benchmarking", @@ -12318,7 +12318,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -12337,7 +12337,7 @@ dependencies = [ [[package]] name = "pallet-tx-pause" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "parity-scale-codec", @@ -12348,7 +12348,7 @@ dependencies = [ [[package]] name = "pallet-uniques" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12362,7 +12362,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12378,7 +12378,7 @@ dependencies = [ [[package]] name = "pallet-verify-signature" version = "0.4.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12393,7 +12393,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12407,7 +12407,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -12417,7 +12417,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "20.1.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bounded-collections 0.2.4", "frame-benchmarking", @@ -12443,7 +12443,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -12460,7 +12460,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-messages", "bp-runtime", @@ -12482,7 +12482,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub-router" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-xcm-bridge-hub-router", "frame-benchmarking", @@ -12555,7 +12555,7 @@ dependencies = [ [[package]] name = "parachains-common" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -12584,7 +12584,7 @@ dependencies = [ [[package]] name = "parachains-runtimes-test-utils" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -12942,7 +12942,7 @@ dependencies = [ [[package]] name = "polkadot-approval-distribution" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "futures-timer", @@ -12960,7 +12960,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "futures-timer", @@ -12975,7 +12975,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "fatality", "futures", @@ -12998,7 +12998,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "fatality", @@ -13031,7 +13031,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "clap", "frame-benchmarking-cli", @@ -13055,7 +13055,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "24.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "fatality", @@ -13078,7 +13078,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -13089,7 +13089,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "fatality", "futures", @@ -13111,7 +13111,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -13125,7 +13125,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "futures-timer", @@ -13146,7 +13146,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "always-assert", "async-trait", @@ -13169,7 +13169,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "parity-scale-codec", @@ -13187,7 +13187,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "bitvec", @@ -13219,7 +13219,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting-parallel" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -13243,7 +13243,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "futures", @@ -13262,7 +13262,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "fatality", @@ -13283,7 +13283,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "polkadot-node-subsystem", @@ -13298,7 +13298,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -13320,7 +13320,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "polkadot-node-metrics", @@ -13334,7 +13334,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "futures-timer", @@ -13350,7 +13350,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "fatality", "futures", @@ -13368,7 +13368,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -13385,7 +13385,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-prospective-parachains" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "fatality", "futures", @@ -13399,7 +13399,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "fatality", @@ -13416,7 +13416,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "always-assert", "array-bytes 6.2.2", @@ -13444,7 +13444,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "polkadot-node-subsystem", @@ -13457,7 +13457,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-common" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cpu-time", "futures", @@ -13483,7 +13483,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "polkadot-node-metrics", @@ -13498,7 +13498,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bs58", "futures", @@ -13515,7 +13515,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -13540,7 +13540,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "20.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "bounded-vec", @@ -13564,7 +13564,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "polkadot-node-subsystem-types", "polkadot-overseer", @@ -13573,7 +13573,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "derive_more 0.99.20", @@ -13601,7 +13601,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "fatality", "futures", @@ -13632,7 +13632,7 @@ dependencies = [ [[package]] name = "polkadot-omni-node-lib" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "clap", @@ -13718,7 +13718,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -13738,7 +13738,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-primitives" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bounded-collections 0.2.4", "derive_more 0.99.20", @@ -13754,7 +13754,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "bounded-collections 0.2.4", @@ -13783,7 +13783,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "jsonrpsee", "mmr-rpc", @@ -13816,7 +13816,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "frame-benchmarking", @@ -13866,7 +13866,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bs58", "frame-benchmarking", @@ -13878,7 +13878,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "20.0.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -13926,7 +13926,7 @@ dependencies = [ [[package]] name = "polkadot-sdk" version = "2506.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "asset-test-utils", "assets-common", @@ -14165,7 +14165,7 @@ dependencies = [ [[package]] name = "polkadot-sdk-frame" version = "0.10.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-benchmarking", @@ -14200,7 +14200,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "frame-benchmarking", @@ -14308,7 +14308,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitvec", "fatality", @@ -14328,7 +14328,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -15489,7 +15489,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "binary-merkle-tree", "bitvec", @@ -15587,7 +15587,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "polkadot-primitives", @@ -16156,7 +16156,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "32.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "sp-core", @@ -16167,7 +16167,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.51.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -16198,7 +16198,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "log", @@ -16219,7 +16219,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.45.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "sp-api", @@ -16234,7 +16234,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "clap", @@ -16261,7 +16261,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -16272,7 +16272,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.53.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "chrono", @@ -16314,7 +16314,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "fnv", "futures", @@ -16340,7 +16340,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.47.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "hash-db", "kvdb", @@ -16368,7 +16368,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -16391,7 +16391,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -16420,7 +16420,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "fork-tree", @@ -16456,7 +16456,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "jsonrpsee", @@ -16478,7 +16478,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16512,7 +16512,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "jsonrpsee", @@ -16532,7 +16532,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "fork-tree", "parity-scale-codec", @@ -16545,7 +16545,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "ahash", "array-bytes 6.2.2", @@ -16589,7 +16589,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "finality-grandpa", "futures", @@ -16609,7 +16609,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "assert_matches", "async-trait", @@ -16644,7 +16644,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -16667,7 +16667,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -16690,7 +16690,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "polkavm 0.24.0", "sc-allocator", @@ -16703,7 +16703,7 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "polkavm 0.24.0", @@ -16714,7 +16714,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "anyhow", "log", @@ -16730,7 +16730,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "console", "futures", @@ -16746,7 +16746,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "36.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "parking_lot 0.12.3", @@ -16760,7 +16760,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "arrayvec 0.7.4", @@ -16788,7 +16788,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.51.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16838,7 +16838,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.49.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -16848,7 +16848,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "ahash", "futures", @@ -16867,7 +16867,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16888,7 +16888,7 @@ dependencies = [ [[package]] name = "sc-network-statement" version = "0.33.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16909,7 +16909,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16944,7 +16944,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "futures", @@ -16963,7 +16963,7 @@ dependencies = [ [[package]] name = "sc-network-types" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bs58", "bytes", @@ -16984,7 +16984,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bytes", "fnv", @@ -17018,7 +17018,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -17027,7 +17027,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "jsonrpsee", @@ -17059,7 +17059,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17079,7 +17079,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "dyn-clone", "forwarded-header-value", @@ -17103,7 +17103,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "futures", @@ -17136,7 +17136,7 @@ dependencies = [ [[package]] name = "sc-runtime-utilities" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "sc-executor", @@ -17151,7 +17151,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "directories", @@ -17215,7 +17215,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "parity-scale-codec", @@ -17226,7 +17226,7 @@ dependencies = [ [[package]] name = "sc-statement-store" version = "22.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "parity-db", @@ -17246,7 +17246,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "clap", "fs4", @@ -17259,7 +17259,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17278,7 +17278,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "43.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "derive_more 0.99.20", "futures", @@ -17298,7 +17298,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "29.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "chrono", "futures", @@ -17317,7 +17317,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "40.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "chrono", "console", @@ -17347,7 +17347,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -17358,7 +17358,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "40.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -17389,7 +17389,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -17406,7 +17406,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-channel 1.9.0", "futures", @@ -18161,7 +18161,7 @@ dependencies = [ [[package]] name = "slot-range-helper" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "enumn", "parity-scale-codec", @@ -18424,7 +18424,7 @@ dependencies = [ [[package]] name = "snowbridge-core" version = "0.14.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bp-relayers", "frame-support", @@ -18509,7 +18509,7 @@ dependencies = [ [[package]] name = "sp-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "hash-db", @@ -18531,7 +18531,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "Inflector", "blake2 0.10.6", @@ -18545,7 +18545,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -18557,7 +18557,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "integer-sqrt", @@ -18571,7 +18571,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -18583,7 +18583,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "sp-api", "sp-inherents", @@ -18593,7 +18593,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "futures", "parity-scale-codec", @@ -18614,7 +18614,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "futures", @@ -18628,7 +18628,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "parity-scale-codec", @@ -18644,7 +18644,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "parity-scale-codec", @@ -18662,7 +18662,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -18682,7 +18682,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "finality-grandpa", "log", @@ -18699,7 +18699,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "sp-api", @@ -18710,7 +18710,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -18721,7 +18721,7 @@ dependencies = [ [[package]] name = "sp-core" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "ark-vrf", "array-bytes 6.2.2", @@ -18769,7 +18769,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "sp-crypto-hashing", ] @@ -18777,7 +18777,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.16.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -18797,7 +18797,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "blake2b_simd", "byteorder", @@ -18810,7 +18810,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "quote", "sp-crypto-hashing", @@ -18820,7 +18820,7 @@ dependencies = [ [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "kvdb", "parking_lot 0.12.3", @@ -18829,7 +18829,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "proc-macro2", "quote", @@ -18839,7 +18839,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.30.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "environmental", "parity-scale-codec", @@ -18849,7 +18849,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -18861,7 +18861,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -18874,7 +18874,7 @@ dependencies = [ [[package]] name = "sp-io" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bytes", "docify", @@ -18900,7 +18900,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "sp-core", "sp-runtime", @@ -18910,7 +18910,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -18921,7 +18921,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "thiserror 1.0.69", "zstd 0.12.4", @@ -18930,7 +18930,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.11.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-metadata 23.0.1", "parity-scale-codec", @@ -18940,7 +18940,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.15.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -18951,7 +18951,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "log", "parity-scale-codec", @@ -18968,7 +18968,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -18981,7 +18981,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "sp-api", "sp-core", @@ -18991,7 +18991,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "backtrace", "regex", @@ -19000,7 +19000,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "35.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "rustc-hash 1.1.0", "serde", @@ -19010,7 +19010,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "binary-merkle-tree", "docify", @@ -19039,7 +19039,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -19058,7 +19058,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "Inflector", "expander", @@ -19071,7 +19071,7 @@ dependencies = [ [[package]] name = "sp-session" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "scale-info", @@ -19085,7 +19085,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -19098,7 +19098,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.46.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "hash-db", "log", @@ -19118,7 +19118,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "21.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "aes-gcm", "curve25519-dalek", @@ -19142,12 +19142,12 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" [[package]] name = "sp-storage" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "impl-serde", "parity-scale-codec", @@ -19159,7 +19159,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "parity-scale-codec", @@ -19171,7 +19171,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "17.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "tracing", @@ -19182,7 +19182,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "sp-api", "sp-runtime", @@ -19191,7 +19191,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "parity-scale-codec", @@ -19205,7 +19205,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "40.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "ahash", "foldhash 0.1.5", @@ -19230,7 +19230,7 @@ dependencies = [ [[package]] name = "sp-version" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "impl-serde", "parity-scale-codec", @@ -19247,7 +19247,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "15.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "parity-scale-codec", "proc-macro-warning", @@ -19259,7 +19259,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -19271,7 +19271,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "32.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "bounded-collections 0.2.4", "parity-scale-codec", @@ -19348,7 +19348,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-chain-spec-builder" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "clap", "docify", @@ -19361,7 +19361,7 @@ dependencies = [ [[package]] name = "staging-node-inspect" version = "0.29.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "clap", "parity-scale-codec", @@ -19379,7 +19379,7 @@ dependencies = [ [[package]] name = "staging-parachain-info" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -19392,7 +19392,7 @@ dependencies = [ [[package]] name = "staging-xcm" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "bounded-collections 0.2.4", @@ -19413,7 +19413,7 @@ dependencies = [ [[package]] name = "staging-xcm-builder" version = "21.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "environmental", "frame-support", @@ -19437,7 +19437,7 @@ dependencies = [ [[package]] name = "staging-xcm-executor" version = "20.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "environmental", "frame-benchmarking", @@ -19552,7 +19552,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.6.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -19577,12 +19577,12 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" [[package]] name = "substrate-frame-rpc-system" version = "45.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "docify", "frame-system-rpc-runtime-api", @@ -19602,7 +19602,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.6" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "http-body-util", "hyper 1.5.1", @@ -19616,7 +19616,7 @@ dependencies = [ [[package]] name = "substrate-rpc-client" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "async-trait", "jsonrpsee", @@ -19646,7 +19646,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -19663,7 +19663,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "27.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "build-helper", @@ -20101,7 +20101,7 @@ dependencies = [ [[package]] name = "testnet-parachains-constants" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -20614,7 +20614,7 @@ dependencies = [ [[package]] name = "tracing-gum" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "coarsetime", "polkadot-primitives", @@ -20625,7 +20625,7 @@ dependencies = [ [[package]] name = "tracing-gum-proc-macro" version = "5.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "expander", "proc-macro-crate 3.1.0", @@ -21539,7 +21539,7 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "westend-runtime" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "binary-merkle-tree", "bitvec", @@ -21646,7 +21646,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "polkadot-primitives", @@ -22253,7 +22253,7 @@ dependencies = [ [[package]] name = "xcm-emulator" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "array-bytes 6.2.2", "cumulus-pallet-parachain-system", @@ -22287,7 +22287,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "11.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "Inflector", "proc-macro2", @@ -22298,7 +22298,7 @@ dependencies = [ [[package]] name = "xcm-runtime-apis" version = "0.8.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "parity-scale-codec", @@ -22312,7 +22312,7 @@ dependencies = [ [[package]] name = "xcm-simulator" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#d92cbbd5868cf20cd6281c4aaf5eebc803aeefa7" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" dependencies = [ "frame-support", "frame-system", diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index 6cbd40df3..ee439f85c 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -761,3 +761,118 @@ fn balances_unreserve_buffers_transfer_log_from_reserved_sentinel() { ); }); } + +// ---------------------------------------------------------------------- +// Repatriate — moves reserved balance from one account to another. We need +// the eth-rpc Transfer-event accounting to stay consistent: amount leaves +// the slashed account's reserved bucket and lands either in beneficiary's +// free balance (status=Free) or in beneficiary's reserved bucket +// (status=Reserved). +// ---------------------------------------------------------------------- + +#[test] +fn orml_tokens_repatriate_to_free_buffers_transfer_log_to_beneficiary() { + use orml_traits::{BalanceStatus, MultiReservableCurrency}; + + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + SyntheticLogsPending::::kill(); + + assert_ok!(>::repatriate_reserved( + DAI, + &ALICE.into(), + &BOB.into(), + amount, + BalanceStatus::Free, + )); + + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let alice_reserved = reserved_address_of(alice_h160()); + let bob_h = bob_h160(); + + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == dai_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_reserved)) + && log.topics.get(2) == Some(&h160_to_h256(bob_h)) + }); + assert!( + entry.is_some(), + "orml_tokens::repatriate_reserved (status=Free) must buffer \ + Transfer(reserved_address_of(slashed), beneficiary, amount)", + ); + }); +} + +#[test] +fn orml_tokens_repatriate_to_reserved_buffers_transfer_log_between_reserved_buckets() { + use orml_traits::{BalanceStatus, MultiReservableCurrency}; + + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + SyntheticLogsPending::::kill(); + + assert_ok!(>::repatriate_reserved( + DAI, + &ALICE.into(), + &BOB.into(), + amount, + BalanceStatus::Reserved, + )); + + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let alice_reserved = reserved_address_of(alice_h160()); + let bob_reserved = reserved_address_of(bob_h160()); + + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == dai_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_reserved)) + && log.topics.get(2) == Some(&h160_to_h256(bob_reserved)) + }); + assert!( + entry.is_some(), + "orml_tokens::repatriate_reserved (status=Reserved) must buffer \ + Transfer(reserved_address_of(slashed), reserved_address_of(beneficiary), amount)", + ); + }); +} + +#[test] +fn balances_repatriate_to_free_buffers_transfer_log_to_beneficiary() { + use frame_support::traits::{tokens::BalanceStatus, ReservableCurrency}; + + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + assert_ok!(>::reserve(&ALICE.into(), amount)); + SyntheticLogsPending::::kill(); + + assert_ok!(>::repatriate_reserved( + &ALICE.into(), + &BOB.into(), + amount, + BalanceStatus::Free, + )); + + let hdx_addr = HydraErc20Mapping::asset_address(HDX); + let alice_reserved = reserved_address_of(alice_h160()); + let bob_h = bob_h160(); + + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_reserved)) + && log.topics.get(2) == Some(&h160_to_h256(bob_h)) + }); + assert!( + entry.is_some(), + "pallet_balances::repatriate_reserved (status=Free) must buffer \ + Transfer(reserved_address_of(slashed), beneficiary, amount) for HDX", + ); + }); +} diff --git a/pallets/circuit-breaker/src/tests/mock.rs b/pallets/circuit-breaker/src/tests/mock.rs index 424804e8a..63ba92592 100644 --- a/pallets/circuit-breaker/src/tests/mock.rs +++ b/pallets/circuit-breaker/src/tests/mock.rs @@ -867,6 +867,9 @@ impl MutationHooks for Hooks { type PostTransfer = (); type PreWithdraw = (); type PostWithdraw = (); + type PostReserve = (); + type PostUnreserve = (); + type PostRepatriate = (); type OnNewTokenAccount = (); type OnKilledTokenAccount = (); } diff --git a/pallets/stableswap/src/tests/mock.rs b/pallets/stableswap/src/tests/mock.rs index 63e79780f..13f2505d6 100644 --- a/pallets/stableswap/src/tests/mock.rs +++ b/pallets/stableswap/src/tests/mock.rs @@ -710,6 +710,9 @@ impl MutationHooks for Hooks { type PostTransfer = (); type PreWithdraw = (); type PostWithdraw = (); + type PostReserve = (); + type PostUnreserve = (); + type PostRepatriate = (); type OnNewTokenAccount = (); type OnKilledTokenAccount = (); } diff --git a/pallets/synthetic-logs/Cargo.toml b/pallets/synthetic-logs/Cargo.toml index eb80cf56f..4906a939f 100644 --- a/pallets/synthetic-logs/Cargo.toml +++ b/pallets/synthetic-logs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-synthetic-logs" -version = "0.1.0" +version = "0.2.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index 69a3404d1..1e67d7c1f 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -336,6 +336,9 @@ impl MutationHooks for CurrencyHooks { type PostTransfer = (); type PreWithdraw = (); type PostWithdraw = (); + type PostReserve = (); + type PostUnreserve = (); + type PostRepatriate = (); type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = RemoveTxAssetOnKilled; } diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index f8965be5b..b9add0fb0 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "414.0.0" +version = "415.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index e8f7df299..57e7086a9 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -136,6 +136,9 @@ impl MutationHooks for CurrencyHooks { type PostTransfer = crate::evm::erc20_logs::EmitErc20TransferLog; type PreWithdraw = (); type PostWithdraw = crate::evm::erc20_logs::EmitErc20TransferLog; + type PostReserve = crate::evm::erc20_logs::EmitErc20TransferLog; + type PostUnreserve = crate::evm::erc20_logs::EmitErc20TransferLog; + type PostRepatriate = crate::evm::erc20_logs::EmitErc20TransferLog; type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = (RemoveTxAssetOnKilled, OnKilledTokenAccount); } diff --git a/runtime/hydradx/src/evm/erc20_logs.rs b/runtime/hydradx/src/evm/erc20_logs.rs index d42e81793..4e37951b3 100644 --- a/runtime/hydradx/src/evm/erc20_logs.rs +++ b/runtime/hydradx/src/evm/erc20_logs.rs @@ -7,8 +7,11 @@ use crate::evm::precompiles::erc20_mapping::HydraErc20Mapping; use crate::Runtime; use frame_support::sp_runtime::DispatchResult; use hydradx_traits::evm::{Erc20Mapping, InspectEvmAccounts}; -use orml_traits::currency::{OnDeposit, OnSlash, OnTransfer, OnWithdraw}; -use pallet_synthetic_logs::{encode_u256_be, h160_to_h256, Pallet as SyntheticLogs, TRANSFER_TOPIC}; +use orml_traits::currency::{OnDeposit, OnRepatriate, OnReserve, OnSlash, OnTransfer, OnUnreserve, OnWithdraw}; +use orml_traits::BalanceStatus; +use pallet_synthetic_logs::{ + encode_u256_be, h160_to_h256, reserved_address_of, Pallet as SyntheticLogs, TRANSFER_TOPIC, +}; use primitive_types::{H160, U256}; use primitives::constants::chain::CORE_ASSET_ID; use primitives::{AccountId, AssetId, Balance}; @@ -73,6 +76,46 @@ impl OnWithdraw for EmitErc20TransferLog { } } +impl OnReserve for EmitErc20TransferLog { + fn on_reserve(asset: AssetId, who: &AccountId, amount: Balance) { + if amount == 0 { + return; + } + let owner = evm_address_of(who); + push_transfer_log(asset, owner, reserved_address_of(owner), amount); + } +} + +impl OnUnreserve for EmitErc20TransferLog { + fn on_unreserve(asset: AssetId, who: &AccountId, amount: Balance) { + if amount == 0 { + return; + } + let owner = evm_address_of(who); + push_transfer_log(asset, reserved_address_of(owner), owner, amount); + } +} + +impl OnRepatriate for EmitErc20TransferLog { + fn on_repatriate( + asset: AssetId, + slashed: &AccountId, + beneficiary: &AccountId, + amount: Balance, + status: BalanceStatus, + ) { + if amount == 0 { + return; + } + let from = reserved_address_of(evm_address_of(slashed)); + let to = match status { + BalanceStatus::Free => evm_address_of(beneficiary), + BalanceStatus::Reserved => reserved_address_of(evm_address_of(beneficiary)), + }; + push_transfer_log(asset, from, to, amount); + } +} + impl pallet_balances::BalancesHooks for EmitErc20TransferLog { fn on_transfer(from: &AccountId, to: &AccountId, amount: Balance) { if amount == 0 { @@ -101,6 +144,41 @@ impl pallet_balances::BalancesHooks for EmitErc20TransferLog } push_transfer_log(CORE_ASSET_ID, evm_address_of(who), H160::zero(), amount); } + + fn on_reserve(who: &AccountId, amount: Balance) { + if amount == 0 { + return; + } + let owner = evm_address_of(who); + push_transfer_log(CORE_ASSET_ID, owner, reserved_address_of(owner), amount); + } + + fn on_unreserve(who: &AccountId, amount: Balance) { + if amount == 0 { + return; + } + let owner = evm_address_of(who); + push_transfer_log(CORE_ASSET_ID, reserved_address_of(owner), owner, amount); + } + + fn on_repatriate( + slashed: &AccountId, + beneficiary: &AccountId, + amount: Balance, + status: frame_support::traits::tokens::BalanceStatus, + ) { + if amount == 0 { + return; + } + let from = reserved_address_of(evm_address_of(slashed)); + let to = match status { + frame_support::traits::tokens::BalanceStatus::Free => evm_address_of(beneficiary), + frame_support::traits::tokens::BalanceStatus::Reserved => { + reserved_address_of(evm_address_of(beneficiary)) + } + }; + push_transfer_log(CORE_ASSET_ID, from, to, amount); + } } pub struct OnDepositTuple(PhantomData<(A, B)>); diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index f068d3bc1..81ea7784a 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: Cow::Borrowed("hydradx"), impl_name: Cow::Borrowed("hydradx"), authoring_version: 1, - spec_version: 414, + spec_version: 415, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From a60e451ad6411ad7e2ae8f0bae008dd95220f113 Mon Sep 17 00:00:00 2001 From: mrq Date: Mon, 4 May 2026 23:23:23 +0200 Subject: [PATCH 07/17] fmt --- .../src/balances_tokens_hooks.rs | 121 +++++++++++------- runtime/hydradx/src/assets.rs | 21 ++- runtime/hydradx/src/evm/erc20_logs.rs | 4 +- 3 files changed, 85 insertions(+), 61 deletions(-) diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index ee439f85c..63c1e21f8 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -303,7 +303,9 @@ fn dispatcher_precompile_currencies_transfer_token_emits_transfer_log() { TestNet::reset(); Hydra::execute_with(|| { - assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed(ALICE.into()))); + assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed( + ALICE.into() + ))); let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); let bob_acc: AccountId = BOB.into(); @@ -374,7 +376,9 @@ fn dispatcher_precompile_omnipool_sell_emits_swap_log() { Hydra::execute_with(|| { crate::evm::init_omnipool_with_oracle_for_block_10(); - assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed(ALICE.into()))); + assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed( + ALICE.into() + ))); let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); assert_ok!(Currencies::update_balance( RuntimeOrigin::root(), @@ -412,7 +416,10 @@ fn dispatcher_precompile_omnipool_sell_emits_swap_log() { hydradx_runtime::RuntimeEvent::Broadcast(pallet_broadcast::Event::Swapped3 { .. }) ) }); - assert!(saw_swapped3, "Omnipool::sell via dispatcher must produce a Swapped3 substrate event"); + assert!( + saw_swapped3, + "Omnipool::sell via dispatcher must produce a Swapped3 substrate event" + ); let found = buffered_logs() .into_iter() @@ -450,7 +457,9 @@ fn dispatcher_precompile_batch_preserves_substrate_transfer_order() { TestNet::reset(); Hydra::execute_with(|| { - assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed(ALICE.into()))); + assert_ok!(hydradx_runtime::EVMAccounts::bind_evm_address(RuntimeOrigin::signed( + ALICE.into() + ))); let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); // dispatch a batch of three transfers in a deterministic asset order @@ -501,7 +510,10 @@ fn dispatcher_precompile_batch_preserves_substrate_transfer_order() { if log.topics.get(2) != Some(&h160_to_h256(bob_h)) { return None; } - leg_assets.iter().copied().find(|a| HydraErc20Mapping::asset_address(*a) == log.address) + leg_assets + .iter() + .copied() + .find(|a| HydraErc20Mapping::asset_address(*a) == log.address) }) .collect(); @@ -541,9 +553,7 @@ fn evm_inline_logs_around_precompile_call_preserve_log_index_order() { use hydradx_traits::evm::{CallContext, EVM as EVMTrait}; // keccak256("Marker(uint256)") — see node_modules ethers computation. - const MARKER_TOPIC: H256 = H256(hex!( - "83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b24" - )); + const MARKER_TOPIC: H256 = H256(hex!("83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b24")); // first 4 bytes of keccak256("exercise(address,address,uint256)") const EXERCISE_SELECTOR: [u8; 4] = hex!("430c9304"); @@ -645,20 +655,22 @@ fn orml_tokens_reserve_buffers_transfer_log_to_reserved_sentinel() { Hydra::execute_with(|| { SyntheticLogsPending::::kill(); let amount = UNITS; - assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + assert_ok!(>::reserve( + DAI, + &ALICE.into(), + amount + )); let asset_addr = HydraErc20Mapping::asset_address(DAI); let alice_h = alice_h160(); let reserved = reserved_address_of(alice_h); - let entry = buffered_logs() - .into_iter() - .find(|(_, emitter, log)| { - *emitter == asset_addr - && log.topics.first() == Some(&TRANSFER_TOPIC) - && log.topics.get(1) == Some(&h160_to_h256(alice_h)) - && log.topics.get(2) == Some(&h160_to_h256(reserved)) - }); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == asset_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_h)) + && log.topics.get(2) == Some(&h160_to_h256(reserved)) + }); assert!( entry.is_some(), "orml_tokens::reserve must buffer Transfer(owner, reserved_sentinel, amount); \ @@ -676,7 +688,11 @@ fn orml_tokens_unreserve_buffers_transfer_log_from_reserved_sentinel() { TestNet::reset(); Hydra::execute_with(|| { let amount = UNITS; - assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + assert_ok!(>::reserve( + DAI, + &ALICE.into(), + amount + )); SyntheticLogsPending::::kill(); let unreserved = >::unreserve(DAI, &ALICE.into(), amount); @@ -686,14 +702,12 @@ fn orml_tokens_unreserve_buffers_transfer_log_from_reserved_sentinel() { let alice_h = alice_h160(); let reserved = reserved_address_of(alice_h); - let entry = buffered_logs() - .into_iter() - .find(|(_, emitter, log)| { - *emitter == asset_addr - && log.topics.first() == Some(&TRANSFER_TOPIC) - && log.topics.get(1) == Some(&h160_to_h256(reserved)) - && log.topics.get(2) == Some(&h160_to_h256(alice_h)) - }); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == asset_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(reserved)) + && log.topics.get(2) == Some(&h160_to_h256(alice_h)) + }); assert!( entry.is_some(), "orml_tokens::unreserve must buffer Transfer(reserved_sentinel, owner, amount)", @@ -709,20 +723,21 @@ fn balances_reserve_buffers_transfer_log_to_reserved_sentinel() { Hydra::execute_with(|| { SyntheticLogsPending::::kill(); let amount = UNITS; - assert_ok!(>::reserve(&ALICE.into(), amount)); + assert_ok!(>::reserve( + &ALICE.into(), + amount + )); let hdx_addr = HydraErc20Mapping::asset_address(HDX); let alice_h = alice_h160(); let reserved = reserved_address_of(alice_h); - let entry = buffered_logs() - .into_iter() - .find(|(_, emitter, log)| { - *emitter == hdx_addr - && log.topics.first() == Some(&TRANSFER_TOPIC) - && log.topics.get(1) == Some(&h160_to_h256(alice_h)) - && log.topics.get(2) == Some(&h160_to_h256(reserved)) - }); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_h)) + && log.topics.get(2) == Some(&h160_to_h256(reserved)) + }); assert!( entry.is_some(), "pallet_balances::reserve must buffer Transfer(owner, reserved_sentinel, amount) for HDX", @@ -737,7 +752,10 @@ fn balances_unreserve_buffers_transfer_log_from_reserved_sentinel() { TestNet::reset(); Hydra::execute_with(|| { let amount = UNITS; - assert_ok!(>::reserve(&ALICE.into(), amount)); + assert_ok!(>::reserve( + &ALICE.into(), + amount + )); SyntheticLogsPending::::kill(); let unreserved = >::unreserve(&ALICE.into(), amount); @@ -747,14 +765,12 @@ fn balances_unreserve_buffers_transfer_log_from_reserved_sentinel() { let alice_h = alice_h160(); let reserved = reserved_address_of(alice_h); - let entry = buffered_logs() - .into_iter() - .find(|(_, emitter, log)| { - *emitter == hdx_addr - && log.topics.first() == Some(&TRANSFER_TOPIC) - && log.topics.get(1) == Some(&h160_to_h256(reserved)) - && log.topics.get(2) == Some(&h160_to_h256(alice_h)) - }); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(reserved)) + && log.topics.get(2) == Some(&h160_to_h256(alice_h)) + }); assert!( entry.is_some(), "pallet_balances::unreserve must buffer Transfer(reserved_sentinel, owner, amount) for HDX", @@ -777,7 +793,11 @@ fn orml_tokens_repatriate_to_free_buffers_transfer_log_to_beneficiary() { TestNet::reset(); Hydra::execute_with(|| { let amount = UNITS; - assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + assert_ok!(>::reserve( + DAI, + &ALICE.into(), + amount + )); SyntheticLogsPending::::kill(); assert_ok!(>::repatriate_reserved( @@ -813,7 +833,11 @@ fn orml_tokens_repatriate_to_reserved_buffers_transfer_log_between_reserved_buck TestNet::reset(); Hydra::execute_with(|| { let amount = UNITS; - assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + assert_ok!(>::reserve( + DAI, + &ALICE.into(), + amount + )); SyntheticLogsPending::::kill(); assert_ok!(>::repatriate_reserved( @@ -849,7 +873,10 @@ fn balances_repatriate_to_free_buffers_transfer_log_to_beneficiary() { TestNet::reset(); Hydra::execute_with(|| { let amount = UNITS; - assert_ok!(>::reserve(&ALICE.into(), amount)); + assert_ok!(>::reserve( + &ALICE.into(), + amount + )); SyntheticLogsPending::::kill(); assert_ok!(>::repatriate_reserved( diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index 57e7086a9..e32bc0a66 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -120,25 +120,23 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = MaxFreezes; type RuntimeFreezeReason = (); type DoneSlashHandler = (); - type RuntimeHooks = crate::evm::erc20_logs::EmitErc20TransferLog; + type RuntimeHooks = EmitErc20TransferLog; } pub struct CurrencyHooks; impl MutationHooks for CurrencyHooks { type OnDust = Duster; - type OnSlash = crate::evm::erc20_logs::EmitErc20TransferLog; + type OnSlash = EmitErc20TransferLog; type PreDeposit = SufficiencyCheck; - type PostDeposit = crate::evm::erc20_logs::OnDepositTuple< - pallet_circuit_breaker::fuses::issuance::IssuanceIncreaseFuse, - crate::evm::erc20_logs::EmitErc20TransferLog, - >; + type PostDeposit = + OnDepositTuple, EmitErc20TransferLog>; type PreTransfer = SufficiencyCheck; - type PostTransfer = crate::evm::erc20_logs::EmitErc20TransferLog; + type PostTransfer = EmitErc20TransferLog; type PreWithdraw = (); - type PostWithdraw = crate::evm::erc20_logs::EmitErc20TransferLog; - type PostReserve = crate::evm::erc20_logs::EmitErc20TransferLog; - type PostUnreserve = crate::evm::erc20_logs::EmitErc20TransferLog; - type PostRepatriate = crate::evm::erc20_logs::EmitErc20TransferLog; + type PostWithdraw = EmitErc20TransferLog; + type PostReserve = EmitErc20TransferLog; + type PostUnreserve = EmitErc20TransferLog; + type PostRepatriate = EmitErc20TransferLog; type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = (RemoveTxAssetOnKilled, OnKilledTokenAccount); } @@ -2004,6 +2002,7 @@ impl GetByKey for ReferralsLevelVolumeAndRewa } use crate::evm::aave_trade_executor::Aave; +use crate::evm::erc20_logs::{EmitErc20TransferLog, OnDepositTuple}; #[cfg(feature = "runtime-benchmarks")] use crate::helpers::benchmark_helpers::CircuitBreakerBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] diff --git a/runtime/hydradx/src/evm/erc20_logs.rs b/runtime/hydradx/src/evm/erc20_logs.rs index 4e37951b3..23c29a27e 100644 --- a/runtime/hydradx/src/evm/erc20_logs.rs +++ b/runtime/hydradx/src/evm/erc20_logs.rs @@ -173,9 +173,7 @@ impl pallet_balances::BalancesHooks for EmitErc20TransferLog let from = reserved_address_of(evm_address_of(slashed)); let to = match status { frame_support::traits::tokens::BalanceStatus::Free => evm_address_of(beneficiary), - frame_support::traits::tokens::BalanceStatus::Reserved => { - reserved_address_of(evm_address_of(beneficiary)) - } + frame_support::traits::tokens::BalanceStatus::Reserved => reserved_address_of(evm_address_of(beneficiary)), }; push_transfer_log(CORE_ASSET_ID, from, to, amount); } From 503a973de969dda9c118c7b4801521909dba5f3d Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 00:19:25 +0200 Subject: [PATCH 08/17] fees and slashing support --- Cargo.lock | 764 +++++++++--------- .../src/balances_tokens_hooks.rs | 113 +++ launch-configs/fork/clean-fork.sh | 20 + launch-configs/fork/inject-wasm.mjs | 33 + pallets/circuit-breaker/src/tests/mock.rs | 1 + pallets/stableswap/src/tests/mock.rs | 1 + pallets/transaction-multi-payment/src/mock.rs | 1 + runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/assets.rs | 1 + runtime/hydradx/src/evm/erc20_logs.rs | 22 +- runtime/hydradx/src/lib.rs | 2 +- 11 files changed, 575 insertions(+), 385 deletions(-) create mode 100755 launch-configs/fork/clean-fork.sh create mode 100644 launch-configs/fork/inject-wasm.mjs diff --git a/Cargo.lock b/Cargo.lock index a6a9742a6..4f2f70c8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1086,7 +1086,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "asset-test-utils" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -1116,7 +1116,7 @@ dependencies = [ [[package]] name = "assets-common" version = "0.22.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "ethereum-standards", @@ -1482,7 +1482,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "binary-merkle-tree" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "hash-db", "log", @@ -1779,7 +1779,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1796,7 +1796,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-runtime", @@ -1812,7 +1812,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -1829,7 +1829,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-messages", "bp-runtime", @@ -1846,7 +1846,7 @@ dependencies = [ [[package]] name = "bp-relayers" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-messages", @@ -1864,7 +1864,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -1887,7 +1887,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-parachains", @@ -1907,7 +1907,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-messages", "bp-runtime", @@ -1924,7 +1924,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub-router" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -1936,7 +1936,7 @@ dependencies = [ [[package]] name = "bridge-hub-common" version = "0.14.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1955,7 +1955,7 @@ dependencies = [ [[package]] name = "bridge-hub-test-utils" version = "0.23.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "asset-test-utils", "bp-header-chain", @@ -1997,7 +1997,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.22.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-messages", @@ -2928,7 +2928,7 @@ dependencies = [ [[package]] name = "cumulus-client-bootnodes" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -2954,7 +2954,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "clap", "parity-scale-codec", @@ -2971,7 +2971,7 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -2994,7 +2994,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" version = "0.24.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-client-collator", @@ -3041,7 +3041,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -3073,7 +3073,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-proposer" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "anyhow", "async-trait", @@ -3088,7 +3088,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-relay-chain" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-client-consensus-common", @@ -3111,7 +3111,7 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -3138,7 +3138,7 @@ dependencies = [ [[package]] name = "cumulus-client-parachain-inherent" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3159,7 +3159,7 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3187,7 +3187,7 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.25.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-channel 1.9.0", "cumulus-client-cli", @@ -3228,7 +3228,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-aura-ext" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3245,7 +3245,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system" version = "0.21.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "bytes", @@ -3300,7 +3300,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.6.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -3311,7 +3311,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-session-benchmarking" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-solo-to-para" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-weight-reclaim" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-storage-weight-reclaim", "derive-where", @@ -3358,7 +3358,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3373,7 +3373,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.21.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "approx", "bounded-collections 0.2.4", @@ -3399,7 +3399,7 @@ dependencies = [ [[package]] name = "cumulus-ping" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-pallet-xcm", "cumulus-primitives-core", @@ -3414,7 +3414,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-aura" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "sp-api", "sp-consensus-aura", @@ -3423,7 +3423,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -3440,7 +3440,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3454,7 +3454,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-proof-size-hostfunction" version = "0.13.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "sp-externalities", "sp-runtime-interface", @@ -3464,7 +3464,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-storage-weight-reclaim" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-proof-size-hostfunction", @@ -3481,7 +3481,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-timestamp" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "sp-inherents", @@ -3491,7 +3491,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-utility" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3508,7 +3508,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -3536,7 +3536,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3556,7 +3556,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-minimal-node" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -3592,7 +3592,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" version = "0.24.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-streams" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-relay-chain-interface", "futures", @@ -3647,7 +3647,7 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -4417,7 +4417,7 @@ dependencies = [ [[package]] name = "ethereum-standards" version = "0.1.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "alloy-core", ] @@ -4922,7 +4922,7 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fork-tree" version = "13.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", ] @@ -5060,7 +5060,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-support-procedural", @@ -5084,7 +5084,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "49.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "Inflector", "array-bytes 6.2.2", @@ -5149,7 +5149,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-pallet-pov" version = "31.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -5177,7 +5177,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "16.1.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -5188,7 +5188,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -5205,7 +5205,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "aquamarine", "frame-support", @@ -5247,7 +5247,7 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" version = "0.9.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "const-hex", @@ -5263,7 +5263,7 @@ dependencies = [ [[package]] name = "frame-remote-externalities" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "indicatif", @@ -5285,7 +5285,7 @@ dependencies = [ [[package]] name = "frame-storage-access-test-runtime" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-pallet-parachain-system", "parity-scale-codec", @@ -5299,7 +5299,7 @@ dependencies = [ [[package]] name = "frame-support" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "aquamarine", "array-bytes 6.2.2", @@ -5340,7 +5340,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "34.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "Inflector", "cfg-expr", @@ -5360,7 +5360,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "13.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.1.0", @@ -5372,7 +5372,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro2", "quote", @@ -5382,7 +5382,7 @@ dependencies = [ [[package]] name = "frame-system" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cfg-if", "docify", @@ -5401,7 +5401,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -5415,7 +5415,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "parity-scale-codec", @@ -5425,7 +5425,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.47.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "parity-scale-codec", @@ -6379,7 +6379,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "415.0.0" +version = "416.0.0" dependencies = [ "alloy-primitives 0.7.7", "alloy-sol-types 0.7.7", @@ -8456,7 +8456,7 @@ dependencies = [ [[package]] name = "mmr-gadget" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "log", @@ -8475,7 +8475,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -9141,7 +9141,7 @@ dependencies = [ [[package]] name = "orml-benchmarking" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-benchmarking", "frame-support", @@ -9162,7 +9162,7 @@ dependencies = [ [[package]] name = "orml-tokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "frame-system", @@ -9179,7 +9179,7 @@ dependencies = [ [[package]] name = "orml-traits" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -9199,7 +9199,7 @@ dependencies = [ [[package]] name = "orml-unknown-tokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "frame-system", @@ -9214,7 +9214,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "parity-scale-codec", @@ -9229,7 +9229,7 @@ dependencies = [ [[package]] name = "orml-vesting" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "frame-system", @@ -9244,7 +9244,7 @@ dependencies = [ [[package]] name = "orml-xcm" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "frame-system", @@ -9258,7 +9258,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "orml-traits", @@ -9272,7 +9272,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "1.4.0" -source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#b79f0e6cc5a5144b5c7b87ea7666ae7eed04267b" +source = "git+https://github.com/galacticcouncil/open-runtime-module-library?branch=polkadot-stable2506-patch-hooks#7e26f9a8fc47dc6f515b328f39c5fa7fc520223b" dependencies = [ "frame-support", "frame-system", @@ -9299,7 +9299,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pallet-alliance" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "frame-benchmarking", @@ -9319,7 +9319,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9337,7 +9337,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-ops" version = "0.9.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9355,7 +9355,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-tx-payment" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9370,7 +9370,7 @@ dependencies = [ [[package]] name = "pallet-asset-rate" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9413,7 +9413,7 @@ dependencies = [ [[package]] name = "pallet-asset-rewards" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9431,7 +9431,7 @@ dependencies = [ [[package]] name = "pallet-asset-tx-payment" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9447,7 +9447,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "43.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "ethereum-standards", "frame-benchmarking", @@ -9465,7 +9465,7 @@ dependencies = [ [[package]] name = "pallet-assets-freezer" version = "0.8.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "pallet-assets", @@ -9477,7 +9477,7 @@ dependencies = [ [[package]] name = "pallet-assets-holder" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9492,7 +9492,7 @@ dependencies = [ [[package]] name = "pallet-atomic-swap" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -9502,7 +9502,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -9518,7 +9518,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -9533,7 +9533,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -9546,7 +9546,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9569,7 +9569,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "aquamarine", "docify", @@ -9590,7 +9590,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -9606,7 +9606,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -9625,7 +9625,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "binary-merkle-tree", @@ -9674,7 +9674,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9691,7 +9691,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-runtime", @@ -9710,7 +9710,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-messages", @@ -9729,7 +9729,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-parachains", @@ -9749,7 +9749,7 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-header-chain", "bp-messages", @@ -9792,7 +9792,7 @@ dependencies = [ [[package]] name = "pallet-broker" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "frame-benchmarking", @@ -9810,7 +9810,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9919,7 +9919,7 @@ dependencies = [ [[package]] name = "pallet-collator-selection" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9938,7 +9938,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -9955,7 +9955,7 @@ dependencies = [ [[package]] name = "pallet-collective-content" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -9969,7 +9969,7 @@ dependencies = [ [[package]] name = "pallet-contracts" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "environmental", "frame-benchmarking", @@ -10000,7 +10000,7 @@ dependencies = [ [[package]] name = "pallet-contracts-mock-network" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -10031,7 +10031,7 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "23.0.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro2", "quote", @@ -10041,7 +10041,7 @@ dependencies = [ [[package]] name = "pallet-contracts-uapi" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -10052,7 +10052,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "assert_matches", "frame-benchmarking", @@ -10068,7 +10068,7 @@ dependencies = [ [[package]] name = "pallet-core-fellowship" version = "25.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -10160,7 +10160,7 @@ dependencies = [ [[package]] name = "pallet-delegated-staking" version = "8.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -10195,7 +10195,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -10212,7 +10212,7 @@ dependencies = [ [[package]] name = "pallet-dev-mode" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -10280,7 +10280,7 @@ dependencies = [ [[package]] name = "pallet-dummy-dim" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -10379,7 +10379,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-block" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10400,7 +10400,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10421,7 +10421,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10434,7 +10434,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -10674,7 +10674,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -10710,7 +10710,7 @@ dependencies = [ [[package]] name = "pallet-glutton" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "blake2 0.10.6", "frame-benchmarking", @@ -10728,7 +10728,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -10801,7 +10801,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "enumflags2", "frame-benchmarking", @@ -10817,7 +10817,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -10836,7 +10836,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -10851,7 +10851,7 @@ dependencies = [ [[package]] name = "pallet-insecure-randomness-collective-flip" version = "29.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11016,7 +11016,7 @@ dependencies = [ [[package]] name = "pallet-lottery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11029,7 +11029,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11045,7 +11045,7 @@ dependencies = [ [[package]] name = "pallet-message-queue" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "environmental", "frame-benchmarking", @@ -11064,7 +11064,7 @@ dependencies = [ [[package]] name = "pallet-meta-tx" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -11082,7 +11082,7 @@ dependencies = [ [[package]] name = "pallet-migrations" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -11101,7 +11101,7 @@ dependencies = [ [[package]] name = "pallet-mixnet" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "parity-scale-codec", @@ -11115,7 +11115,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "parity-scale-codec", @@ -11127,7 +11127,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "parity-scale-codec", @@ -11158,7 +11158,7 @@ dependencies = [ [[package]] name = "pallet-nft-fractionalization" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "pallet-assets", @@ -11171,7 +11171,7 @@ dependencies = [ [[package]] name = "pallet-nfts" version = "35.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "enumflags2", "frame-benchmarking", @@ -11188,7 +11188,7 @@ dependencies = [ [[package]] name = "pallet-nfts-runtime-api" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "sp-api", @@ -11197,7 +11197,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11207,7 +11207,7 @@ dependencies = [ [[package]] name = "pallet-node-authorization" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "parity-scale-codec", @@ -11218,7 +11218,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -11236,7 +11236,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11256,7 +11256,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -11266,7 +11266,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -11281,7 +11281,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11364,7 +11364,7 @@ dependencies = [ [[package]] name = "pallet-origin-restriction" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11436,7 +11436,7 @@ dependencies = [ [[package]] name = "pallet-paged-list" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "parity-scale-codec", @@ -11448,7 +11448,7 @@ dependencies = [ [[package]] name = "pallet-parameters" version = "0.12.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -11479,7 +11479,7 @@ dependencies = [ [[package]] name = "pallet-people" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11497,7 +11497,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11513,7 +11513,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11523,7 +11523,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "41.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11541,7 +11541,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11551,7 +11551,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "assert_matches", "frame-benchmarking", @@ -11605,7 +11605,7 @@ dependencies = [ [[package]] name = "pallet-remark" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11621,7 +11621,7 @@ dependencies = [ [[package]] name = "pallet-revive" version = "0.7.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "alloy-core", "derive_more 0.99.20", @@ -11667,7 +11667,7 @@ dependencies = [ [[package]] name = "pallet-revive-fixtures" version = "0.4.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "anyhow", "cargo_metadata", @@ -11681,7 +11681,7 @@ dependencies = [ [[package]] name = "pallet-revive-proc-macro" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro2", "quote", @@ -11691,7 +11691,7 @@ dependencies = [ [[package]] name = "pallet-revive-uapi" version = "0.5.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitflags 1.3.2", "pallet-revive-proc-macro", @@ -11703,7 +11703,7 @@ dependencies = [ [[package]] name = "pallet-root-offences" version = "38.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -11719,7 +11719,7 @@ dependencies = [ [[package]] name = "pallet-root-testing" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -11759,7 +11759,7 @@ dependencies = [ [[package]] name = "pallet-safe-mode" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "pallet-balances", @@ -11773,7 +11773,7 @@ dependencies = [ [[package]] name = "pallet-salary" version = "26.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "pallet-ranked-collective", @@ -11785,7 +11785,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -11802,7 +11802,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -11815,7 +11815,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -11836,7 +11836,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11870,7 +11870,7 @@ dependencies = [ [[package]] name = "pallet-skip-feeless-payment" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -11882,7 +11882,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -11958,7 +11958,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -11980,7 +11980,7 @@ dependencies = [ [[package]] name = "pallet-staking-async" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -12003,7 +12003,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-ah-client" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -12022,7 +12022,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-rc-client" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -12039,7 +12039,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-reward-fn" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "sp-arithmetic", @@ -12048,7 +12048,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-runtime-api" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "sp-api", @@ -12058,7 +12058,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "sp-arithmetic", @@ -12067,7 +12067,7 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "sp-api", @@ -12077,7 +12077,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12093,7 +12093,7 @@ dependencies = [ [[package]] name = "pallet-statement" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", @@ -12110,7 +12110,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -12149,7 +12149,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -12167,7 +12167,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12255,7 +12255,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12270,7 +12270,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -12286,7 +12286,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -12298,7 +12298,7 @@ dependencies = [ [[package]] name = "pallet-transaction-storage" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "frame-benchmarking", @@ -12318,7 +12318,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -12337,7 +12337,7 @@ dependencies = [ [[package]] name = "pallet-tx-pause" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "parity-scale-codec", @@ -12348,7 +12348,7 @@ dependencies = [ [[package]] name = "pallet-uniques" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12362,7 +12362,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12378,7 +12378,7 @@ dependencies = [ [[package]] name = "pallet-verify-signature" version = "0.4.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12393,7 +12393,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12407,7 +12407,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -12417,7 +12417,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "20.1.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bounded-collections 0.2.4", "frame-benchmarking", @@ -12443,7 +12443,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-benchmarking", "frame-support", @@ -12460,7 +12460,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-messages", "bp-runtime", @@ -12482,7 +12482,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub-router" version = "0.19.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-xcm-bridge-hub-router", "frame-benchmarking", @@ -12555,7 +12555,7 @@ dependencies = [ [[package]] name = "parachains-common" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -12584,7 +12584,7 @@ dependencies = [ [[package]] name = "parachains-runtimes-test-utils" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -12942,7 +12942,7 @@ dependencies = [ [[package]] name = "polkadot-approval-distribution" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "futures-timer", @@ -12960,7 +12960,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "futures-timer", @@ -12975,7 +12975,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "fatality", "futures", @@ -12998,7 +12998,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "fatality", @@ -13031,7 +13031,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "clap", "frame-benchmarking-cli", @@ -13055,7 +13055,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "24.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "fatality", @@ -13078,7 +13078,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -13089,7 +13089,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "fatality", "futures", @@ -13111,7 +13111,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -13125,7 +13125,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "futures-timer", @@ -13146,7 +13146,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "always-assert", "async-trait", @@ -13169,7 +13169,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "parity-scale-codec", @@ -13187,7 +13187,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "bitvec", @@ -13219,7 +13219,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting-parallel" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -13243,7 +13243,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "futures", @@ -13262,7 +13262,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "fatality", @@ -13283,7 +13283,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "polkadot-node-subsystem", @@ -13298,7 +13298,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -13320,7 +13320,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "polkadot-node-metrics", @@ -13334,7 +13334,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "futures-timer", @@ -13350,7 +13350,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "fatality", "futures", @@ -13368,7 +13368,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -13385,7 +13385,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-prospective-parachains" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "fatality", "futures", @@ -13399,7 +13399,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "fatality", @@ -13416,7 +13416,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "always-assert", "array-bytes 6.2.2", @@ -13444,7 +13444,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "polkadot-node-subsystem", @@ -13457,7 +13457,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-common" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cpu-time", "futures", @@ -13483,7 +13483,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "polkadot-node-metrics", @@ -13498,7 +13498,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bs58", "futures", @@ -13515,7 +13515,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -13540,7 +13540,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "20.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "bounded-vec", @@ -13564,7 +13564,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "polkadot-node-subsystem-types", "polkadot-overseer", @@ -13573,7 +13573,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "derive_more 0.99.20", @@ -13601,7 +13601,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "fatality", "futures", @@ -13632,7 +13632,7 @@ dependencies = [ [[package]] name = "polkadot-omni-node-lib" version = "0.7.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "clap", @@ -13718,7 +13718,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -13738,7 +13738,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-primitives" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bounded-collections 0.2.4", "derive_more 0.99.20", @@ -13754,7 +13754,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "bounded-collections 0.2.4", @@ -13783,7 +13783,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "jsonrpsee", "mmr-rpc", @@ -13816,7 +13816,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "frame-benchmarking", @@ -13866,7 +13866,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bs58", "frame-benchmarking", @@ -13878,7 +13878,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "20.0.3" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -13926,7 +13926,7 @@ dependencies = [ [[package]] name = "polkadot-sdk" version = "2506.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "asset-test-utils", "assets-common", @@ -14165,7 +14165,7 @@ dependencies = [ [[package]] name = "polkadot-sdk-frame" version = "0.10.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-benchmarking", @@ -14200,7 +14200,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "frame-benchmarking", @@ -14308,7 +14308,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitvec", "fatality", @@ -14328,7 +14328,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -15489,7 +15489,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "binary-merkle-tree", "bitvec", @@ -15587,7 +15587,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "polkadot-primitives", @@ -16156,7 +16156,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "32.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "sp-core", @@ -16167,7 +16167,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.51.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -16198,7 +16198,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "log", @@ -16219,7 +16219,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.45.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "sp-api", @@ -16234,7 +16234,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "clap", @@ -16261,7 +16261,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -16272,7 +16272,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.53.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "chrono", @@ -16314,7 +16314,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "fnv", "futures", @@ -16340,7 +16340,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.47.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "hash-db", "kvdb", @@ -16368,7 +16368,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -16391,7 +16391,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -16420,7 +16420,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "fork-tree", @@ -16456,7 +16456,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "jsonrpsee", @@ -16478,7 +16478,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16512,7 +16512,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "jsonrpsee", @@ -16532,7 +16532,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "fork-tree", "parity-scale-codec", @@ -16545,7 +16545,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "ahash", "array-bytes 6.2.2", @@ -16589,7 +16589,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "finality-grandpa", "futures", @@ -16609,7 +16609,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "assert_matches", "async-trait", @@ -16644,7 +16644,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -16667,7 +16667,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -16690,7 +16690,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "polkavm 0.24.0", "sc-allocator", @@ -16703,7 +16703,7 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.36.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "polkavm 0.24.0", @@ -16714,7 +16714,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "anyhow", "log", @@ -16730,7 +16730,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "console", "futures", @@ -16746,7 +16746,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "36.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "parking_lot 0.12.3", @@ -16760,7 +16760,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "arrayvec 0.7.4", @@ -16788,7 +16788,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.51.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16838,7 +16838,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.49.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -16848,7 +16848,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "ahash", "futures", @@ -16867,7 +16867,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16888,7 +16888,7 @@ dependencies = [ [[package]] name = "sc-network-statement" version = "0.33.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16909,7 +16909,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -16944,7 +16944,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "futures", @@ -16963,7 +16963,7 @@ dependencies = [ [[package]] name = "sc-network-types" version = "0.17.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bs58", "bytes", @@ -16984,7 +16984,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bytes", "fnv", @@ -17018,7 +17018,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -17027,7 +17027,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "46.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "jsonrpsee", @@ -17059,7 +17059,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17079,7 +17079,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "dyn-clone", "forwarded-header-value", @@ -17103,7 +17103,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "futures", @@ -17136,7 +17136,7 @@ dependencies = [ [[package]] name = "sc-runtime-utilities" version = "0.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "sc-executor", @@ -17151,7 +17151,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.52.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "directories", @@ -17215,7 +17215,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.39.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "parity-scale-codec", @@ -17226,7 +17226,7 @@ dependencies = [ [[package]] name = "sc-statement-store" version = "22.3.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "parity-db", @@ -17246,7 +17246,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.25.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "clap", "fs4", @@ -17259,7 +17259,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.51.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17278,7 +17278,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "43.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "derive_more 0.99.20", "futures", @@ -17298,7 +17298,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "29.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "chrono", "futures", @@ -17317,7 +17317,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "40.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "chrono", "console", @@ -17347,7 +17347,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -17358,7 +17358,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "40.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -17389,7 +17389,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -17406,7 +17406,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-channel 1.9.0", "futures", @@ -18161,7 +18161,7 @@ dependencies = [ [[package]] name = "slot-range-helper" version = "18.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "enumn", "parity-scale-codec", @@ -18424,7 +18424,7 @@ dependencies = [ [[package]] name = "snowbridge-core" version = "0.14.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bp-relayers", "frame-support", @@ -18509,7 +18509,7 @@ dependencies = [ [[package]] name = "sp-api" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "hash-db", @@ -18531,7 +18531,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "23.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "Inflector", "blake2 0.10.6", @@ -18545,7 +18545,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "41.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -18557,7 +18557,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "27.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "integer-sqrt", @@ -18571,7 +18571,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -18583,7 +18583,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "sp-api", "sp-inherents", @@ -18593,7 +18593,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "futures", "parity-scale-codec", @@ -18614,7 +18614,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "futures", @@ -18628,7 +18628,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "parity-scale-codec", @@ -18644,7 +18644,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "parity-scale-codec", @@ -18662,7 +18662,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "25.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -18682,7 +18682,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "24.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "finality-grandpa", "log", @@ -18699,7 +18699,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "sp-api", @@ -18710,7 +18710,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -18721,7 +18721,7 @@ dependencies = [ [[package]] name = "sp-core" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "ark-vrf", "array-bytes 6.2.2", @@ -18769,7 +18769,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "16.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "sp-crypto-hashing", ] @@ -18777,7 +18777,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.16.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -18797,7 +18797,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "blake2b_simd", "byteorder", @@ -18810,7 +18810,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "quote", "sp-crypto-hashing", @@ -18820,7 +18820,7 @@ dependencies = [ [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "kvdb", "parking_lot 0.12.3", @@ -18829,7 +18829,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "proc-macro2", "quote", @@ -18839,7 +18839,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.30.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "environmental", "parity-scale-codec", @@ -18849,7 +18849,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.18.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -18861,7 +18861,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -18874,7 +18874,7 @@ dependencies = [ [[package]] name = "sp-io" version = "41.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bytes", "docify", @@ -18900,7 +18900,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "sp-core", "sp-runtime", @@ -18910,7 +18910,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.43.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -18921,7 +18921,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "thiserror 1.0.69", "zstd 0.12.4", @@ -18930,7 +18930,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.11.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-metadata 23.0.1", "parity-scale-codec", @@ -18940,7 +18940,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.15.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -18951,7 +18951,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "log", "parity-scale-codec", @@ -18968,7 +18968,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -18981,7 +18981,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "sp-api", "sp-core", @@ -18991,7 +18991,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "backtrace", "regex", @@ -19000,7 +19000,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "35.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "rustc-hash 1.1.0", "serde", @@ -19010,7 +19010,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "42.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "binary-merkle-tree", "docify", @@ -19039,7 +19039,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "30.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -19058,7 +19058,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "19.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "Inflector", "expander", @@ -19071,7 +19071,7 @@ dependencies = [ [[package]] name = "sp-session" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "scale-info", @@ -19085,7 +19085,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "39.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -19098,7 +19098,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.46.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "hash-db", "log", @@ -19118,7 +19118,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "21.2.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "aes-gcm", "curve25519-dalek", @@ -19142,12 +19142,12 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" [[package]] name = "sp-storage" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "impl-serde", "parity-scale-codec", @@ -19159,7 +19159,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "parity-scale-codec", @@ -19171,7 +19171,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "17.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "tracing", @@ -19182,7 +19182,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "sp-api", "sp-runtime", @@ -19191,7 +19191,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "37.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "parity-scale-codec", @@ -19205,7 +19205,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "40.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "ahash", "foldhash 0.1.5", @@ -19230,7 +19230,7 @@ dependencies = [ [[package]] name = "sp-version" version = "40.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "impl-serde", "parity-scale-codec", @@ -19247,7 +19247,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "15.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "parity-scale-codec", "proc-macro-warning", @@ -19259,7 +19259,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "22.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -19271,7 +19271,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "32.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "bounded-collections 0.2.4", "parity-scale-codec", @@ -19348,7 +19348,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-chain-spec-builder" version = "12.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "clap", "docify", @@ -19361,7 +19361,7 @@ dependencies = [ [[package]] name = "staging-node-inspect" version = "0.29.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "clap", "parity-scale-codec", @@ -19379,7 +19379,7 @@ dependencies = [ [[package]] name = "staging-parachain-info" version = "0.21.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -19392,7 +19392,7 @@ dependencies = [ [[package]] name = "staging-xcm" version = "17.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "bounded-collections 0.2.4", @@ -19413,7 +19413,7 @@ dependencies = [ [[package]] name = "staging-xcm-builder" version = "21.1.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "environmental", "frame-support", @@ -19437,7 +19437,7 @@ dependencies = [ [[package]] name = "staging-xcm-executor" version = "20.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "environmental", "frame-benchmarking", @@ -19552,7 +19552,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.6.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -19577,12 +19577,12 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" [[package]] name = "substrate-frame-rpc-system" version = "45.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "docify", "frame-system-rpc-runtime-api", @@ -19602,7 +19602,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.6" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "http-body-util", "hyper 1.5.1", @@ -19616,7 +19616,7 @@ dependencies = [ [[package]] name = "substrate-rpc-client" version = "0.50.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "async-trait", "jsonrpsee", @@ -19646,7 +19646,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "44.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -19663,7 +19663,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "27.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "build-helper", @@ -20101,7 +20101,7 @@ dependencies = [ [[package]] name = "testnet-parachains-constants" version = "14.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -20614,7 +20614,7 @@ dependencies = [ [[package]] name = "tracing-gum" version = "20.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "coarsetime", "polkadot-primitives", @@ -20625,7 +20625,7 @@ dependencies = [ [[package]] name = "tracing-gum-proc-macro" version = "5.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "expander", "proc-macro-crate 3.1.0", @@ -21539,7 +21539,7 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "westend-runtime" version = "24.0.1" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "binary-merkle-tree", "bitvec", @@ -21646,7 +21646,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "polkadot-primitives", @@ -22253,7 +22253,7 @@ dependencies = [ [[package]] name = "xcm-emulator" version = "0.20.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "array-bytes 6.2.2", "cumulus-pallet-parachain-system", @@ -22287,7 +22287,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "11.0.2" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "Inflector", "proc-macro2", @@ -22298,7 +22298,7 @@ dependencies = [ [[package]] name = "xcm-runtime-apis" version = "0.8.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "parity-scale-codec", @@ -22312,7 +22312,7 @@ dependencies = [ [[package]] name = "xcm-simulator" version = "21.0.0" -source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#c43252bc76306658434413637f4bb714c75747bd" +source = "git+https://github.com/galacticcouncil/polkadot-sdk?branch=polkadot-stable2506-10-patch-hooks#918b29bd7b6e22da37bc0938306d76b1828df199" dependencies = [ "frame-support", "frame-system", diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index 63c1e21f8..a1543dbfb 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -866,6 +866,119 @@ fn orml_tokens_repatriate_to_reserved_buffers_transfer_log_between_reserved_buck }); } +#[test] +fn orml_tokens_slash_reserved_buffers_burn_log_from_reserved_sentinel() { + use orml_traits::MultiReservableCurrency; + + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + SyntheticLogsPending::::kill(); + + let remaining = >::slash_reserved(DAI, &ALICE.into(), amount); + assert_eq!(remaining, 0); + + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let reserved = reserved_address_of(alice_h160()); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == dai_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(reserved)) + && log.topics.get(2) == Some(&h160_to_h256(H160::zero())) + }); + assert!( + entry.is_some(), + "orml_tokens::slash_reserved must buffer Transfer(reserved_sentinel, 0x0, amount)", + ); + }); +} + +#[test] +fn balances_slash_reserved_buffers_burn_log_from_reserved_sentinel() { + use frame_support::traits::ReservableCurrency; + + TestNet::reset(); + Hydra::execute_with(|| { + let amount = UNITS; + assert_ok!(>::reserve(&ALICE.into(), amount)); + SyntheticLogsPending::::kill(); + + let (_imbalance, remaining) = >::slash_reserved(&ALICE.into(), amount); + assert_eq!(remaining, 0); + + let hdx_addr = HydraErc20Mapping::asset_address(HDX); + let reserved = reserved_address_of(alice_h160()); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(reserved)) + && log.topics.get(2) == Some(&h160_to_h256(H160::zero())) + }); + assert!( + entry.is_some(), + "pallet_balances::slash_reserved must buffer Transfer(reserved_sentinel, 0x0, amount) for HDX", + ); + }); +} + +#[test] +fn balances_currency_withdraw_buffers_burn_log() { + // covers the native HDX fee path which routes through + // `BasicCurrencyAdapter::withdraw` → `pallet_balances::Currency::withdraw` + use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons}; + + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + let _imbalance = >::withdraw( + &ALICE.into(), + UNITS, + WithdrawReasons::TRANSACTION_PAYMENT, + ExistenceRequirement::AllowDeath, + ) + .expect("alice has enough HDX"); + + let hdx_addr = HydraErc20Mapping::asset_address(HDX); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_h160())) + && log.topics.get(2) == Some(&h160_to_h256(H160::zero())) + }); + assert!( + entry.is_some(), + "pallet_balances::Currency::withdraw must buffer Transfer(payer, 0x0, amount); \ + this is the native HDX fee burn path", + ); + }); +} + +#[test] +fn balances_currency_deposit_creating_buffers_mint_log() { + // covers the deposit half of the fee path + // (treasury credit, etc.): `Currency::deposit_creating` was silent before. + use frame_support::traits::Currency; + + TestNet::reset(); + Hydra::execute_with(|| { + SyntheticLogsPending::::kill(); + let _imbalance = >::deposit_creating(&BOB.into(), UNITS); + + let hdx_addr = HydraErc20Mapping::asset_address(HDX); + let entry = buffered_logs().into_iter().find(|(_, emitter, log)| { + *emitter == hdx_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(H160::zero())) + && log.topics.get(2) == Some(&h160_to_h256(bob_h160())) + }); + assert!( + entry.is_some(), + "pallet_balances::Currency::deposit_creating must buffer Transfer(0x0, recipient, amount)", + ); + }); +} + #[test] fn balances_repatriate_to_free_buffers_transfer_log_to_beneficiary() { use frame_support::traits::{tokens::BalanceStatus, ReservableCurrency}; diff --git a/launch-configs/fork/clean-fork.sh b/launch-configs/fork/clean-fork.sh new file mode 100755 index 000000000..0b89c54fe --- /dev/null +++ b/launch-configs/fork/clean-fork.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# Clear zombienet's per-run artifacts under data/ so a restart picks up the +# updated chainspec / freshly injected wasm. Keeps the source files +# (data/forked-chainspec.json, data/state.json, the *.yaml templates, +# zombie-wrapper.sh). +set -euo pipefail +cd "$(dirname "$0")" + +rm -rf \ + data/alice data/alice-1 \ + data/bob data/bob-1 \ + data/charlie data/dave \ + data/cfg data/2034 \ + data/temp data/temp-1 data/temp-collator \ + data/export-genesis-state data/zombie.json \ + data/local-2034-rococo-local*.json data/rococo-local*.json \ + data/logs data/namespace data/finished.txt \ + data/*.log + +echo "cleaned data/ — keeping forked-chainspec.json, state.json, *.yaml" diff --git a/launch-configs/fork/inject-wasm.mjs b/launch-configs/fork/inject-wasm.mjs new file mode 100644 index 000000000..2202656ad --- /dev/null +++ b/launch-configs/fork/inject-wasm.mjs @@ -0,0 +1,33 @@ +// Replace the runtime wasm in a forked chainspec with a freshly-built local +// wasm. Faster than running a full preauth + applyAuthorizedUpgrade dance +// when iterating on the fork — the parachain comes up at the new spec from +// block 1 (no upgrade extrinsic required). +// +// Usage: +// node inject-wasm.mjs # uses defaults below +// WASM=/path/to.wasm SPEC=data/foo.json node inject-wasm.mjs +// +// Note: zombienet caches a derived spec in data/local-2034-rococo-local.json +// after the first launch — clear data/ before restart so the new wasm is +// picked up. (See `clean-fork.sh` if you have one, or rm -rf the data +// subdirs before `npm run zombie:init`.) + +import fs from 'fs'; + +const WASM_PATH = + process.env.WASM || + '../../target/release/wbuild/hydradx-runtime/hydradx_runtime.compact.compressed.wasm'; +const SPEC_PATH = process.env.SPEC || 'data/forked-chainspec.json'; +const CODE_KEY = '0x3a636f6465'; // sp_storage::well_known_keys::CODE = b":code" + +const wasm = fs.readFileSync(WASM_PATH); +const spec = JSON.parse(fs.readFileSync(SPEC_PATH, 'utf8')); + +const oldLen = (spec.genesis.raw.top[CODE_KEY] || '').length; +spec.genesis.raw.top[CODE_KEY] = '0x' + wasm.toString('hex'); + +fs.writeFileSync(SPEC_PATH, JSON.stringify(spec)); + +console.log(`wasm: ${WASM_PATH} (${wasm.length} bytes)`); +console.log(`spec: ${SPEC_PATH}`); +console.log(`:code: ${oldLen} -> ${spec.genesis.raw.top[CODE_KEY].length} hex chars`); diff --git a/pallets/circuit-breaker/src/tests/mock.rs b/pallets/circuit-breaker/src/tests/mock.rs index 63ba92592..d836db5d5 100644 --- a/pallets/circuit-breaker/src/tests/mock.rs +++ b/pallets/circuit-breaker/src/tests/mock.rs @@ -869,6 +869,7 @@ impl MutationHooks for Hooks { type PostWithdraw = (); type PostReserve = (); type PostUnreserve = (); + type PostSlashReserved = (); type PostRepatriate = (); type OnNewTokenAccount = (); type OnKilledTokenAccount = (); diff --git a/pallets/stableswap/src/tests/mock.rs b/pallets/stableswap/src/tests/mock.rs index 13f2505d6..0077ae70f 100644 --- a/pallets/stableswap/src/tests/mock.rs +++ b/pallets/stableswap/src/tests/mock.rs @@ -712,6 +712,7 @@ impl MutationHooks for Hooks { type PostWithdraw = (); type PostReserve = (); type PostUnreserve = (); + type PostSlashReserved = (); type PostRepatriate = (); type OnNewTokenAccount = (); type OnKilledTokenAccount = (); diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index 1e67d7c1f..ec975b61e 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -338,6 +338,7 @@ impl MutationHooks for CurrencyHooks { type PostWithdraw = (); type PostReserve = (); type PostUnreserve = (); + type PostSlashReserved = (); type PostRepatriate = (); type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = RemoveTxAssetOnKilled; diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index b9add0fb0..ace6ea49a 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "415.0.0" +version = "416.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index e32bc0a66..6fe0219fb 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -136,6 +136,7 @@ impl MutationHooks for CurrencyHooks { type PostWithdraw = EmitErc20TransferLog; type PostReserve = EmitErc20TransferLog; type PostUnreserve = EmitErc20TransferLog; + type PostSlashReserved = EmitErc20TransferLog; type PostRepatriate = EmitErc20TransferLog; type OnNewTokenAccount = AddTxAssetOnAccount; type OnKilledTokenAccount = (RemoveTxAssetOnKilled, OnKilledTokenAccount); diff --git a/runtime/hydradx/src/evm/erc20_logs.rs b/runtime/hydradx/src/evm/erc20_logs.rs index 23c29a27e..dcf76eaeb 100644 --- a/runtime/hydradx/src/evm/erc20_logs.rs +++ b/runtime/hydradx/src/evm/erc20_logs.rs @@ -7,7 +7,9 @@ use crate::evm::precompiles::erc20_mapping::HydraErc20Mapping; use crate::Runtime; use frame_support::sp_runtime::DispatchResult; use hydradx_traits::evm::{Erc20Mapping, InspectEvmAccounts}; -use orml_traits::currency::{OnDeposit, OnRepatriate, OnReserve, OnSlash, OnTransfer, OnUnreserve, OnWithdraw}; +use orml_traits::currency::{ + OnDeposit, OnRepatriate, OnReserve, OnSlash, OnSlashReserved, OnTransfer, OnUnreserve, OnWithdraw, +}; use orml_traits::BalanceStatus; use pallet_synthetic_logs::{ encode_u256_be, h160_to_h256, reserved_address_of, Pallet as SyntheticLogs, TRANSFER_TOPIC, @@ -96,6 +98,16 @@ impl OnUnreserve for EmitErc20TransferLog { } } +impl OnSlashReserved for EmitErc20TransferLog { + fn on_slash_reserved(asset: AssetId, who: &AccountId, amount: Balance) { + if amount == 0 { + return; + } + let owner = evm_address_of(who); + push_transfer_log(asset, reserved_address_of(owner), H160::zero(), amount); + } +} + impl OnRepatriate for EmitErc20TransferLog { fn on_repatriate( asset: AssetId, @@ -161,6 +173,14 @@ impl pallet_balances::BalancesHooks for EmitErc20TransferLog push_transfer_log(CORE_ASSET_ID, reserved_address_of(owner), owner, amount); } + fn on_slash_reserved(who: &AccountId, amount: Balance) { + if amount == 0 { + return; + } + let owner = evm_address_of(who); + push_transfer_log(CORE_ASSET_ID, reserved_address_of(owner), H160::zero(), amount); + } + fn on_repatriate( slashed: &AccountId, beneficiary: &AccountId, diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 81ea7784a..93abd99c9 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: Cow::Borrowed("hydradx"), impl_name: Cow::Borrowed("hydradx"), authoring_version: 1, - spec_version: 415, + spec_version: 416, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 18ad5778a44f03e1eeb8363ea8dc8682e7fb4433 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 01:01:48 +0200 Subject: [PATCH 09/17] check for reverts --- .../src/balances_tokens_hooks.rs | 94 +++++++++++++++++++ runtime/hydradx/src/evm/runner.rs | 18 +++- 2 files changed, 107 insertions(+), 5 deletions(-) diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index a1543dbfb..7d8abfffd 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -979,6 +979,100 @@ fn balances_currency_deposit_creating_buffers_mint_log() { }); } +/// Revert safety. When an EVM frame reverts, frontier drops `info.logs` +/// (the substate's logs). Substrate hooks that fired during the frame may +/// have pushed entries into the `EVM_FRAME_LOGS` buffer; the WrapRunner's +/// end-drain must NOT append those buffered entries onto a reverted-frame +/// `info.logs`, or we get ghost logs for transfers whose substrate state +/// was rolled back by `pallet_evm`'s `with_storage_layer` wrapping. +/// +/// The probe contract calls dispatcher precompile (a substrate +/// Currencies::transfer), then reverts. We assert: +/// 1. Bob's DAI balance is unchanged (substrate state rolled back). +/// 2. No DAI Transfer log lands in the synth tx for this block. +#[test] +fn evm_frame_revert_drops_buffered_substrate_hook_logs() { + use codec::Encode; + use hex_literal::hex; + use hydradx_runtime::evm::precompiles::DISPATCH_ADDR; + use hydradx_runtime::evm::Executor; + use hydradx_runtime::RuntimeCall; + use hydradx_traits::evm::{CallContext, EVM as EVMTrait}; + + // keccak256("try_dispatch_then_revert(address,bytes)")[..4] + const PROBE_SELECTOR: [u8; 4] = hex!("4351d800"); + + TestNet::reset(); + Hydra::execute_with(|| { + let alice_evm = hydradx_runtime::EVMAccounts::evm_address(&AccountId::from(ALICE)); + let probe = crate::utils::contracts::deploy_contract("RevertingDispatcher", alice_evm); + + // Fund probe with DAI so the inner dispatch would succeed if not reverted. + let probe_acc = hydradx_runtime::EVMAccounts::truncated_account_id(probe); + assert_ok!(Currencies::update_balance( + RuntimeOrigin::root(), + probe_acc, + DAI, + (UNITS * 10) as i128, + )); + + let bob_acc: AccountId = BOB.into(); + let bob_dai_before = >::free_balance(DAI, &bob_acc); + + let amount: u128 = UNITS; + let inner = RuntimeCall::Currencies(pallet_currencies::Call::transfer { + dest: BOB.into(), + currency_id: DAI, + amount, + }); + let inner_encoded = inner.encode(); + + // abi-encode try_dispatch_then_revert(address dispatcher, bytes sub_call_data): + // selector || dispatcher (32 bytes) || offset_to_bytes (=0x40, 32 bytes) + // || bytes_len (32) || bytes_payload (padded) + let mut calldata = PROBE_SELECTOR.to_vec(); + calldata.extend_from_slice(&[0u8; 12]); + calldata.extend_from_slice(DISPATCH_ADDR.as_bytes()); + calldata.extend_from_slice(&U256::from(0x40u64).to_big_endian()); + calldata.extend_from_slice(&U256::from(inner_encoded.len() as u64).to_big_endian()); + calldata.extend_from_slice(&inner_encoded); + // pad to 32-byte boundary + let pad = (32 - inner_encoded.len() % 32) % 32; + calldata.extend(sp_std::iter::repeat(0u8).take(pad)); + + SyntheticLogsPending::::kill(); + + let context = CallContext { + contract: probe, + sender: alice_evm, + origin: alice_evm, + }; + let result = Executor::::call(context, calldata, U256::zero(), 5_000_000); + // The contract reverts intentionally — the outer call result is Revert. + assert!( + matches!(result.exit_reason, fp_evm::ExitReason::Revert(_)), + "probe must revert, got {:?}", + result.exit_reason + ); + + let bob_dai_after = >::free_balance(DAI, &bob_acc); + assert_eq!( + bob_dai_after, bob_dai_before, + "substrate state must be rolled back: bob's DAI balance must NOT change", + ); + + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let leaked = buffered_logs() + .into_iter() + .any(|(_, _, log)| log.address == dai_addr && log.topics.first() == Some(&TRANSFER_TOPIC)); + assert!( + !leaked, + "BLINDSPOT: a DAI Transfer log leaked into the synth tx even though the outer EVM frame reverted; \ + the WrapRunner end-drain is appending buffered hook logs unconditionally — must gate on Succeed.", + ); + }); +} + #[test] fn balances_repatriate_to_free_buffers_transfer_log_to_beneficiary() { use frame_support::traits::{tokens::BalanceStatus, ReservableCurrency}; diff --git a/runtime/hydradx/src/evm/runner.rs b/runtime/hydradx/src/evm/runner.rs index 47c4aceca..5f9ded9fc 100644 --- a/runtime/hydradx/src/evm/runner.rs +++ b/runtime/hydradx/src/evm/runner.rs @@ -26,7 +26,7 @@ use crate::evm::evm_fee::evm_fee_payer; use crate::evm::WethAssetId; use ethereum::AuthorizationList; -use fp_evm::{Account, TransactionValidationError}; +use fp_evm::{Account, ExitReason, TransactionValidationError}; use frame_support::traits::Get; use hydradx_traits::AccountFeeCurrencyBalanceInCurrency; use pallet_evm::runner::Runner; @@ -230,7 +230,9 @@ where config, ) })?; - result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + if matches!(result.exit_reason, ExitReason::Succeed(_)) { + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + } if validate && is_transactional && nonce.is_none() && max_priority_fee_per_gas.is_none() { let current_nonce = frame_system::Pallet::::account_nonce(source_account_id.clone()); @@ -298,7 +300,9 @@ where config, ) })?; - result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + if matches!(result.exit_reason, ExitReason::Succeed(_)) { + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + } Ok(result) } @@ -358,7 +362,9 @@ where config, ) })?; - result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + if matches!(result.exit_reason, ExitReason::Succeed(_)) { + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + } Ok(result) } @@ -418,7 +424,9 @@ where contract_address, ) })?; - result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + if matches!(result.exit_reason, ExitReason::Succeed(_)) { + result.logs.extend(frame_logs.into_iter().map(evm_log_to_fp)); + } Ok(result) } } From eb54ced3dbf8ae01b44754a5faefedd6fd826655 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 01:10:23 +0200 Subject: [PATCH 10/17] approval logs --- pallets/synthetic-logs/src/lib.rs | 6 +++++ runtime/hydradx/src/evm/precompiles/mod.rs | 23 +++++++++++++++++++ .../src/evm/precompiles/multicurrency.rs | 4 +++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs index ada1094ca..16a02e518 100644 --- a/pallets/synthetic-logs/src/lib.rs +++ b/pallets/synthetic-logs/src/lib.rs @@ -279,6 +279,12 @@ pub const SWAP_TOPIC: H256 = H256([ 0x37, 0x65, 0x7f, 0xb8, 0xd5, 0xe3, 0xd1, 0x30, 0x84, 0x01, 0x59, 0xd8, 0x22, ]); +/// Helper: standard ERC-20 `Approval(address,address,uint256)` topic0. +pub const APPROVAL_TOPIC: H256 = H256([ + 0x8c, 0x5b, 0xe1, 0xe5, 0xeb, 0xec, 0x7d, 0x5b, 0xd1, 0x4f, 0x71, 0x42, 0x7d, 0x1e, 0x84, 0xf3, 0xdd, 0x03, 0x14, + 0xc0, 0xf7, 0xb2, 0x29, 0x1e, 0x5b, 0x20, 0x0a, 0xc8, 0xc7, 0xc3, 0xb9, 0x25, +]); + /// Pad an `H160` to a 32-byte topic word (left-pad with 12 zero bytes). pub fn h160_to_h256(addr: H160) -> H256 { let mut bytes = [0u8; 32]; diff --git a/runtime/hydradx/src/evm/precompiles/mod.rs b/runtime/hydradx/src/evm/precompiles/mod.rs index 392b8377e..6019ecbae 100644 --- a/runtime/hydradx/src/evm/precompiles/mod.rs +++ b/runtime/hydradx/src/evm/precompiles/mod.rs @@ -246,6 +246,29 @@ pub fn emit_buffered_evm_frame_logs(handle: &mut impl PrecompileHandle) -> EvmRe Ok(()) } +/// Emit a standard ERC-20 `Approval(owner, spender, value)` log inline at +/// the calling precompile's address. Used by the multicurrency precompile's +/// `approve` and (on allowance-decrement) `transfer_from` paths so erc20 +/// indexers tracking allowance changes can observe substrate-side +/// `pallet_evm_accounts::set_allowance` calls. +pub fn emit_approval_log( + handle: &mut impl PrecompileHandle, + owner: H160, + spender: H160, + amount: U256, +) -> EvmResult<()> { + use pallet_synthetic_logs::{encode_u256_be, h160_to_h256, APPROVAL_TOPIC}; + let topics = sp_std::vec![APPROVAL_TOPIC, h160_to_h256(owner), h160_to_h256(spender)]; + let data = encode_u256_be(amount).to_vec(); + let cost = costs::log_costs(topics.len(), data.len()).map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + })?; + handle.record_cost(cost)?; + let address = handle.code_address(); + handle.log(address, topics, data)?; + Ok(()) +} + // This is a reimplementation of the upstream u64->H160 conversion // function, made `const` to make our precompile address `const`s a // bit cleaner. It can be removed when upstream has a const conversion diff --git a/runtime/hydradx/src/evm/precompiles/multicurrency.rs b/runtime/hydradx/src/evm/precompiles/multicurrency.rs index 1ede85f65..66dc6e6bb 100644 --- a/runtime/hydradx/src/evm/precompiles/multicurrency.rs +++ b/runtime/hydradx/src/evm/precompiles/multicurrency.rs @@ -39,7 +39,7 @@ use hydradx_traits::evm::{Erc20Encoding, InspectEvmAccounts}; use hydradx_traits::registry::Inspect as InspectRegistry; use orml_traits::{MultiCurrency as MultiCurrencyT, MultiCurrency}; use pallet_evm::{AddressMapping, ExitRevert, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; -use primitive_types::H160; +use primitive_types::{H160, U256}; use primitives::{AssetId, Balance}; use sp_runtime::traits::Dispatchable; use sp_std::marker::PhantomData; @@ -276,6 +276,8 @@ where pallet_evm_accounts::Pallet::::set_allowance(asset_id.into(), owner, spender, amount); + crate::evm::precompiles::emit_approval_log(handle, owner, spender, U256::from(amount))?; + Ok(succeed(EvmDataWriter::new().write(true).build())) } From 6c08e09bf3314de9b646fb6fc9a57668dba43c89 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 01:11:00 +0200 Subject: [PATCH 11/17] reverting dispatcher --- .../RevertingDispatcher.sol/IDispatcher.json | 30 +++++++++++++ .../RevertingDispatcher.json | 42 +++++++++++++++++++ .../contracts/RevertingDispatcher.sol | 28 +++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/IDispatcher.json create mode 100644 scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/RevertingDispatcher.json create mode 100644 scripts/test-contracts/contracts/RevertingDispatcher.sol diff --git a/scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/IDispatcher.json b/scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/IDispatcher.json new file mode 100644 index 000000000..b7120d49e --- /dev/null +++ b/scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/IDispatcher.json @@ -0,0 +1,30 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "IDispatcher", + "sourceName": "contracts/RevertingDispatcher.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "dispatch", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/RevertingDispatcher.json b/scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/RevertingDispatcher.json new file mode 100644 index 000000000..fea037c8f --- /dev/null +++ b/scripts/test-contracts/artifacts/contracts/RevertingDispatcher.sol/RevertingDispatcher.json @@ -0,0 +1,42 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "RevertingDispatcher", + "sourceName": "contracts/RevertingDispatcher.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "idx", + "type": "uint256" + } + ], + "name": "Marker", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dispatcher", + "type": "address" + }, + { + "internalType": "bytes", + "name": "sub_call_data", + "type": "bytes" + } + ], + "name": "try_dispatch_then_revert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610530806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80634351d80014610030575b600080fd5b61004a60048036038101906100459190610273565b61004c565b005b7f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b24600060405161007c9190610322565b60405180910390a160008373ffffffffffffffffffffffffffffffffffffffff1683836040516100ad92919061037c565b6000604051808303816000865af19150503d80600081146100ea576040519150601f19603f3d011682016040523d82523d6000602084013e6100ef565b606091505b5050905080610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012a906103f2565b60405180910390fd5b7f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b246001604051610163919061044d565b60405180910390a16040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161019d906104da565b60405180910390fd5b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101db826101b0565b9050919050565b6101eb816101d0565b81146101f657600080fd5b50565b600081359050610208816101e2565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126102335761023261020e565b5b8235905067ffffffffffffffff8111156102505761024f610213565b5b60208301915083600182028301111561026c5761026b610218565b5b9250929050565b60008060006040848603121561028c5761028b6101a6565b5b600061029a868287016101f9565b935050602084013567ffffffffffffffff8111156102bb576102ba6101ab565b5b6102c78682870161021d565b92509250509250925092565b6000819050919050565b6000819050919050565b6000819050919050565b600061030c610307610302846102d3565b6102e7565b6102dd565b9050919050565b61031c816102f1565b82525050565b60006020820190506103376000830184610313565b92915050565b600081905092915050565b82818337600083830152505050565b6000610363838561033d565b9350610370838584610348565b82840190509392505050565b6000610389828486610357565b91508190509392505050565b600082825260208201905092915050565b7f6469737061746368206661696c65640000000000000000000000000000000000600082015250565b60006103dc600f83610395565b91506103e7826103a6565b602082019050919050565b6000602082019050818103600083015261040b816103cf565b9050919050565b6000819050919050565b600061043761043261042d84610412565b6102e7565b6102dd565b9050919050565b6104478161041c565b82525050565b6000602082019050610462600083018461043e565b92915050565b7f696e74656e74696f6e616c20726576657274206166746572206469737061746360008201527f6800000000000000000000000000000000000000000000000000000000000000602082015250565b60006104c4602183610395565b91506104cf82610468565b604082019050919050565b600060208201905081810360008301526104f3816104b7565b905091905056fea264697066735822122006a2182eb335756d2c37f9d3e077a3a7856fa3899cb4f90410c9cca0029aee4464736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80634351d80014610030575b600080fd5b61004a60048036038101906100459190610273565b61004c565b005b7f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b24600060405161007c9190610322565b60405180910390a160008373ffffffffffffffffffffffffffffffffffffffff1683836040516100ad92919061037c565b6000604051808303816000865af19150503d80600081146100ea576040519150601f19603f3d011682016040523d82523d6000602084013e6100ef565b606091505b5050905080610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012a906103f2565b60405180910390fd5b7f83264c98256454386201e4c55918ea57058c5c0052e60bd0b0f9a8fd2f3c1b246001604051610163919061044d565b60405180910390a16040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161019d906104da565b60405180910390fd5b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101db826101b0565b9050919050565b6101eb816101d0565b81146101f657600080fd5b50565b600081359050610208816101e2565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126102335761023261020e565b5b8235905067ffffffffffffffff8111156102505761024f610213565b5b60208301915083600182028301111561026c5761026b610218565b5b9250929050565b60008060006040848603121561028c5761028b6101a6565b5b600061029a868287016101f9565b935050602084013567ffffffffffffffff8111156102bb576102ba6101ab565b5b6102c78682870161021d565b92509250509250925092565b6000819050919050565b6000819050919050565b6000819050919050565b600061030c610307610302846102d3565b6102e7565b6102dd565b9050919050565b61031c816102f1565b82525050565b60006020820190506103376000830184610313565b92915050565b600081905092915050565b82818337600083830152505050565b6000610363838561033d565b9350610370838584610348565b82840190509392505050565b6000610389828486610357565b91508190509392505050565b600082825260208201905092915050565b7f6469737061746368206661696c65640000000000000000000000000000000000600082015250565b60006103dc600f83610395565b91506103e7826103a6565b602082019050919050565b6000602082019050818103600083015261040b816103cf565b9050919050565b6000819050919050565b600061043761043261042d84610412565b6102e7565b6102dd565b9050919050565b6104478161041c565b82525050565b6000602082019050610462600083018461043e565b92915050565b7f696e74656e74696f6e616c20726576657274206166746572206469737061746360008201527f6800000000000000000000000000000000000000000000000000000000000000602082015250565b60006104c4602183610395565b91506104cf82610468565b604082019050919050565b600060208201905081810360008301526104f3816104b7565b905091905056fea264697066735822122006a2182eb335756d2c37f9d3e077a3a7856fa3899cb4f90410c9cca0029aee4464736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/scripts/test-contracts/contracts/RevertingDispatcher.sol b/scripts/test-contracts/contracts/RevertingDispatcher.sol new file mode 100644 index 000000000..8662cfd4c --- /dev/null +++ b/scripts/test-contracts/contracts/RevertingDispatcher.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +interface IDispatcher { + function dispatch(bytes calldata) external returns (bool); +} + +/// Probe for the "revert with substrate state changes pending" path. +/// +/// `try_dispatch_then_revert(target, data)` calls `target.call(data)` (assumed +/// to be the dispatcher precompile) and then unconditionally reverts. +/// The dispatch's substrate state changes get rolled back by pallet_evm's +/// `with_storage_layer` wrapping; the dispatcher's inline-emitted logs get +/// dropped by frontier when the outer frame reverts (substate logs are +/// cleared on revert). This contract verifies that NO Transfer logs leak +/// into the resulting eth-tx receipt or the synthetic-logs buffer when the +/// outer EVM frame reverts. +contract RevertingDispatcher { + event Marker(uint256 idx); + + function try_dispatch_then_revert(address dispatcher, bytes calldata sub_call_data) external { + emit Marker(0); + (bool ok, ) = dispatcher.call(sub_call_data); + require(ok, "dispatch failed"); + emit Marker(1); + revert("intentional revert after dispatch"); + } +} From 4d9bc935dad372779fe36e4758d92912ede1b7dd Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 01:47:20 +0200 Subject: [PATCH 12/17] hook phases consideration --- Cargo.lock | 3 - .../src/balances_tokens_hooks.rs | 97 +- launch-configs/fork/package-lock.json | 2449 ++++++++++++++++- launch-configs/fork/package.json | 3 + pallets/synthetic-logs/Cargo.toml | 6 - pallets/synthetic-logs/src/lib.rs | 79 +- runtime/hydradx/src/lib.rs | 12 +- 7 files changed, 2524 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f2f70c8b..496d38ba9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12128,14 +12128,11 @@ version = "0.2.0" dependencies = [ "ethereum", "ethereum-types", - "fp-evm", - "fp-rpc", "frame-support", "frame-system", "log", "pallet-broadcast", "pallet-ethereum", - "pallet-evm", "parity-scale-codec", "primitives", "scale-info", diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index 7d8abfffd..5d6fa845a 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -4,7 +4,7 @@ use crate::polkadot_test_net::*; use ethereum_types::{H160, U256}; use frame_support::assert_ok; use hydradx_runtime::evm::precompiles::erc20_mapping::HydraErc20Mapping; -use hydradx_runtime::{Balances, Currencies, Runtime, RuntimeOrigin, Tokens}; +use hydradx_runtime::{Balances, Currencies, Ethereum, Runtime, RuntimeOrigin, SyntheticLogs, Tokens}; use hydradx_traits::evm::Erc20Mapping; use orml_traits::MultiCurrency; use pallet_synthetic_logs::{h160_to_h256, reserved_address_of, Pending as SyntheticLogsPending, TRANSFER_TOPIC}; @@ -979,6 +979,101 @@ fn balances_currency_deposit_creating_buffers_mint_log() { }); } +/// End-to-end synth-tx flush: pushing a hook log into the buffer, then +/// running every pallet's `on_finalize` in `construct_runtime!` order, must +/// land a synthetic `pallet_ethereum::Transaction` in `pallet_ethereum::Pending` +/// with the expected log, status, receipt — i.e. the synthetic-logs pallet +/// runs BEFORE `pallet_ethereum::on_finalize` (which would otherwise have +/// already rolled `Pending` into the canonical block). +#[test] +fn on_finalize_drains_buffer_into_pallet_ethereum_pending_before_ethereum_seal() { + use frame_support::traits::OnFinalize; + + TestNet::reset(); + Hydra::execute_with(|| { + let n = frame_system::Pallet::::block_number(); + SyntheticLogsPending::::kill(); + + // Push a Transfer log directly into the buffer (skip the extrinsic to + // avoid xcm-emulator's auto-finalize coupling). + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let mut data = Vec::with_capacity(32); + data.extend_from_slice(&U256::from(UNITS).to_big_endian()); + let log = ethereum::Log { + address: dai_addr, + topics: vec![TRANSFER_TOPIC, h160_to_h256(alice_h160()), h160_to_h256(bob_h160())], + data, + }; + pallet_synthetic_logs::Pallet::::push(dai_addr, log); + assert!(!SyntheticLogsPending::::get().is_empty()); + + // Verify the runtime ordering directly: SyntheticLogs::on_finalize must + // drain the buffer into pallet_ethereum::Pending BEFORE + // Ethereum::on_finalize rolls Pending into CurrentBlock + statuses. + // (construct_runtime! order: SyntheticLogs=86 runs before Ethereum=92.) + SyntheticLogs::on_finalize(n); + + // After SyntheticLogs's flush but BEFORE Ethereum::on_finalize, the + // synth tx must already be in pallet_ethereum::Pending. + let pending: Vec<_> = pallet_ethereum::Pending::::iter().collect(); + assert!( + !pending.is_empty(), + "flush must write into pallet_ethereum::Pending", + ); + + // Now seal the ethereum block. + Ethereum::on_finalize(n); + + // Buffer drained. + assert!( + SyntheticLogsPending::::get().is_empty(), + "buffer must be empty after on_finalize flush", + ); + + // pallet_ethereum::on_finalize moves Pending → CurrentBlock + per-tx + // CurrentTransactionStatuses + CurrentReceipts. After the seal, the + // synth tx should appear in the block's tx list, statuses, and receipts. + let block = pallet_ethereum::CurrentBlock::::get().expect("ethereum block sealed"); + let statuses = pallet_ethereum::CurrentTransactionStatuses::::get() + .expect("statuses stored after seal"); + let receipts = pallet_ethereum::CurrentReceipts::::get().expect("receipts stored after seal"); + + assert_eq!(block.transactions.len(), statuses.len(), "tx count == status count"); + assert_eq!(block.transactions.len(), receipts.len(), "tx count == receipt count"); + + let dai_addr = HydraErc20Mapping::asset_address(DAI); + let synth_status = statuses.iter().find(|s| { + s.from == pallet_synthetic_logs::SENTINEL_ADDRESS + && s.logs.iter().any(|log| { + log.address == dai_addr + && log.topics.first() == Some(&TRANSFER_TOPIC) + && log.topics.get(1) == Some(&h160_to_h256(alice_h160())) + && log.topics.get(2) == Some(&h160_to_h256(bob_h160())) + }) + }); + assert!( + synth_status.is_some(), + "synthetic tx with the DAI Transfer log must be in CurrentTransactionStatuses after seal; \ + got {} statuses", + statuses.len(), + ); + let synth_status = synth_status.unwrap(); + + // Receipt at the same index must have matching logs (logs_bloom too). + let receipt_logs = match &receipts[synth_status.transaction_index as usize] { + pallet_ethereum::Receipt::EIP1559(d) + | pallet_ethereum::Receipt::EIP2930(d) + | pallet_ethereum::Receipt::Legacy(d) => &d.logs, + _ => panic!("unexpected receipt variant"), + }; + assert_eq!( + receipt_logs.len(), + synth_status.logs.len(), + "receipt logs match status logs", + ); + }); +} + /// Revert safety. When an EVM frame reverts, frontier drops `info.logs` /// (the substate's logs). Substrate hooks that fired during the frame may /// have pushed entries into the `EVM_FRAME_LOGS` buffer; the WrapRunner's diff --git a/launch-configs/fork/package-lock.json b/launch-configs/fork/package-lock.json index 44694ecb4..5a8628444 100644 --- a/launch-configs/fork/package-lock.json +++ b/launch-configs/fork/package-lock.json @@ -9,16 +9,26 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@polkadot/api": "^16.5.6", "@polkadot/types": "^15.0.2", + "@polkadot/util-crypto": "^14.0.3", + "ethers": "^6.16.0", "npm-run-all": "^4.1.5" } }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" + }, "node_modules/@noble/curves": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz", - "integrity": "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "license": "MIT", "dependencies": { - "@noble/hashes": "1.6.0" + "@noble/hashes": "1.8.0" }, "engines": { "node": "^14.21.3 || >=16" @@ -27,110 +37,1837 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.0.tgz", - "integrity": "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==", + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", "engines": { "node": "^14.21.3 || >=16" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-api/json-rpc-provider": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1.tgz", + "integrity": "sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==", + "license": "MIT", + "optional": true + }, + "node_modules/@polkadot-api/json-rpc-provider-proxy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.1.0.tgz", + "integrity": "sha512-8GSFE5+EF73MCuLQm8tjrbCqlgclcHBSRaswvXziJ0ZW7iw3UEMsKkkKvELayWyBuOPa2T5i1nj6gFOeIsqvrg==", + "license": "MIT", + "optional": true + }, + "node_modules/@polkadot-api/metadata-builders": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.3.2.tgz", + "integrity": "sha512-TKpfoT6vTb+513KDzMBTfCb/ORdgRnsS3TDFpOhAhZ08ikvK+hjHMt5plPiAX/OWkm1Wc9I3+K6W0hX5Ab7MVg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/substrate-bindings": "0.6.0", + "@polkadot-api/utils": "0.1.0" + } + }, + "node_modules/@polkadot-api/observable-client": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@polkadot-api/observable-client/-/observable-client-0.3.2.tgz", + "integrity": "sha512-HGgqWgEutVyOBXoGOPp4+IAq6CNdK/3MfQJmhCJb8YaJiaK4W6aRGrdQuQSTPHfERHCARt9BrOmEvTXAT257Ug==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/metadata-builders": "0.3.2", + "@polkadot-api/substrate-bindings": "0.6.0", + "@polkadot-api/utils": "0.1.0" + }, + "peerDependencies": { + "@polkadot-api/substrate-client": "0.1.4", + "rxjs": ">=7.8.0" + } + }, + "node_modules/@polkadot-api/substrate-bindings": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.6.0.tgz", + "integrity": "sha512-lGuhE74NA1/PqdN7fKFdE5C1gNYX357j1tWzdlPXI0kQ7h3kN0zfxNOpPUN7dIrPcOFZ6C0tRRVrBylXkI6xPw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@noble/hashes": "^1.3.1", + "@polkadot-api/utils": "0.1.0", + "@scure/base": "^1.1.1", + "scale-ts": "^1.6.0" + } + }, + "node_modules/@polkadot-api/substrate-client": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.1.4.tgz", + "integrity": "sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.1", + "@polkadot-api/utils": "0.1.0" + } + }, + "node_modules/@polkadot-api/utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.1.0.tgz", + "integrity": "sha512-MXzWZeuGxKizPx2Xf/47wx9sr/uxKw39bVJUptTJdsaQn/TGq+z310mHzf1RCGvC1diHM8f593KrnDgc9oNbJA==", + "license": "MIT", + "optional": true + }, + "node_modules/@polkadot/api": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-16.5.6.tgz", + "integrity": "sha512-5h/X3pY8WpqGk4XTaiIUjKD6Pnk8k4bJ6EIwPKLP8/kfFWKSOenpN6ggZxANr+Qj+RgXrp4TxJVcuhXSiBh9Sg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api-augment": "16.5.6", + "@polkadot/api-base": "16.5.6", + "@polkadot/api-derive": "16.5.6", + "@polkadot/keyring": "^14.0.3", + "@polkadot/rpc-augment": "16.5.6", + "@polkadot/rpc-core": "16.5.6", + "@polkadot/rpc-provider": "16.5.6", + "@polkadot/types": "16.5.6", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/types-known": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "eventemitter3": "^5.0.1", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-16.5.6.tgz", + "integrity": "sha512-bunJF1c3nIuDtU6iwa+reTt9U47Y8iOC8Gw7PfANlZmLJmO/XVXnWc3JJLM+g9ESDn2raHJELeWBFVOXQrbtUw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api-base": "16.5.6", + "@polkadot/rpc-augment": "16.5.6", + "@polkadot/types": "16.5.6", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-16.5.6.tgz", + "integrity": "sha512-eBLIv86ZZY4t5OrobVoGC+QXbErOGlBpI2rJI5OMvTNPoVvtEoI++u+wwRScjkOZaUhXyQikd+0Uv71qr3xnsA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-core": "16.5.6", + "@polkadot/types": "16.5.6", + "@polkadot/util": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-16.5.6.tgz", + "integrity": "sha512-cHdvPvhYFch18uPTcuOZJ8VceOfercod2fi4xCnHJAmattzlgj9qCgnOoxdmBS9GZ403ZyRHOjBuUwZy/IsUWQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api": "16.5.6", + "@polkadot/api-augment": "16.5.6", + "@polkadot/api-base": "16.5.6", + "@polkadot/rpc-core": "16.5.6", + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/keyring": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-13.2.3.tgz", + "integrity": "sha512-pgTo6DXNXub0wGD+MnVHYhKxf80Jl+QMOCb818ioGdXz++Uw4mTueFAwtB+N7TGo0HafhChUiNJDxFdlDkcAng==", + "dependencies": { + "@polkadot/util": "13.2.3", + "@polkadot/util-crypto": "13.2.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.2.3", + "@polkadot/util-crypto": "13.2.3" + } + }, + "node_modules/@polkadot/keyring/node_modules/@polkadot/networks": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-13.2.3.tgz", + "integrity": "sha512-mG+zkXg/33AyPrkv2xBbAo3LBUwOwBn6qznBU/4jxiZPnVvCwMaxE7xHM22B5riItbNJ169FXv3wy0v6ZmkFbw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "13.2.3", + "@substrate/ss58-registry": "^1.51.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/keyring/node_modules/@polkadot/util-crypto": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.2.3.tgz", + "integrity": "sha512-5sbggmLbn5eiuVMyPROPlT5roHRqdKHOfSpioNbGvGIZ1qIWVoC1RfsK0NWJOVGDzy6DpQe0KYT/kgcU5Xsrzw==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "13.2.3", + "@polkadot/util": "13.2.3", + "@polkadot/wasm-crypto": "^7.4.1", + "@polkadot/wasm-util": "^7.4.1", + "@polkadot/x-bigint": "13.2.3", + "@polkadot/x-randomvalues": "13.2.3", + "@scure/base": "^1.1.7", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.2.3" + } + }, + "node_modules/@polkadot/networks": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-14.0.3.tgz", + "integrity": "sha512-/VqTLUDn+Wm8S2L/yaGFddo3oW4vRYav0Rg4pLg/semMZLaN8PJ6h927ucn9JyWdH82QfZfyiIPORt0ZF3isyw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@substrate/ss58-registry": "^1.51.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/networks/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/networks/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/networks/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/networks/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/networks/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-16.5.6.tgz", + "integrity": "sha512-vlrNvl2VtU09jZV/AvH7jBb/cNUO+dWu8Xj9pId5ctSUnZHm8o8wRk9ekyieKP57OUoKMd8+VScwMKd624SxTw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-core": "16.5.6", + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-16.5.6.tgz", + "integrity": "sha512-l6od++WlvKH4mw5mtsIh2AhiBs3H+TtdOoUHVLCx/R9il7+gl+arltzZ8vBuffyh/O+uQ36lI8yUoD1g4gi1tA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-augment": "16.5.6", + "@polkadot/rpc-provider": "16.5.6", + "@polkadot/types": "16.5.6", + "@polkadot/util": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-16.5.6.tgz", + "integrity": "sha512-46sHIjKYr4aSzBCfbyqtCwuP8MMJ3jOp0xx9eggOGbKyP8Z0j0Cp+1nNkZUYzehcdGjjrmCxCbQp17wc6cj4zA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types": "16.5.6", + "@polkadot/types-support": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "@polkadot/x-fetch": "^14.0.3", + "@polkadot/x-global": "^14.0.3", + "@polkadot/x-ws": "^14.0.3", + "eventemitter3": "^5.0.1", + "mock-socket": "^9.3.1", + "nock": "^13.5.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@substrate/connect": "0.8.11" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-15.0.2.tgz", + "integrity": "sha512-6gZBnuXU58hQAXWI2daED2OaQwFMxbQdkE8HVGMovMobEf0PxPfIqf+GdnVmWbe09EU9mv2gCWBcdnvHSRBlQg==", + "dependencies": { + "@polkadot/keyring": "^13.2.3", + "@polkadot/types-augment": "15.0.2", + "@polkadot/types-codec": "15.0.2", + "@polkadot/types-create": "15.0.2", + "@polkadot/util": "^13.2.3", + "@polkadot/util-crypto": "^13.2.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-augment": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-15.0.2.tgz", + "integrity": "sha512-UiFJVEYML30+V9GdFAHPbA3s4MVQTL1CevsZMnX0+ApvlgEHJMZnVFfYF7jL2bl9BcUYM/zoxEAhj2MpqFFfxw==", + "dependencies": { + "@polkadot/types": "15.0.2", + "@polkadot/types-codec": "15.0.2", + "@polkadot/util": "^13.2.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-codec": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-15.0.2.tgz", + "integrity": "sha512-44Q40p1rl0t7Bl1QUamewqXNVPway9xgqByyifv6ODSGhtt+lFoarb3U4JzqRUuuK0PP57ePB0L8q81Totxeew==", + "dependencies": { + "@polkadot/util": "^13.2.3", + "@polkadot/x-bigint": "^13.2.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-create": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-15.0.2.tgz", + "integrity": "sha512-YhpcqbH3oI87PkgrV6Fez9jWDqFIep0KcS1YWQcwc9gsBNnuour80t2AAK41/tqAYwOZi6tpJwIevnEhVkxFYA==", + "dependencies": { + "@polkadot/types-codec": "15.0.2", + "@polkadot/util": "^13.2.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-16.5.6.tgz", + "integrity": "sha512-c78NcVO3LIvi4xzxB39WewE+80I4jOYUtPBaB4AzSMespEwIr92VTeX3KzFWuutxDXLSPqeVfXhaAhBB0NssiQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/networks": "^14.0.3", + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/keyring": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-14.0.3.tgz", + "integrity": "sha512-ozp1dQwaHCjgX/fpTTORmHjxdUNQnyiTVJszpzUaUpvtH/IGZhSU/mSHXMqNETS/g57vQa7NatIDcWfyR9abyA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/util-crypto": "14.0.3" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/types": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.6.tgz", + "integrity": "sha512-X/sfMHJS4RkRhnsc4CQqzUy7BM/s2y71TrBFHPYAjs2q/rbZ/BwvBk70SrUiSa0+iRRn3RewbBZm+AB8CbkdKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^14.0.3", + "@polkadot/types-augment": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/types-create": "16.5.6", + "@polkadot/util": "^14.0.3", + "@polkadot/util-crypto": "^14.0.3", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/types-augment": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.6.tgz", + "integrity": "sha512-QN5UrluUZCVgknUDW0gps/FRQ13Qgm24w53pCd2HgD0nmTtXDt9D4psjWwx5JkGTkUAvpzFWwN41bkxAeCiV6g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.6", + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/types-codec": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.6.tgz", + "integrity": "sha512-3tzUv1LZOL97IlQmko4dqbfRC0cg9IQ2QAHRVoDIWsXrVovp1V3kPdP0o6e3I8T2XB9IlbabK91v+ZiIxhGMZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "@polkadot/x-bigint": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/types-create": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.6.tgz", + "integrity": "sha512-g7g3hrjpz4KgqQqei9PU0JY9fsFHBmThWALZk5pWB32vyDyDcXZiyhH3agDhqfmzQiolTW2FuvcNJxgS634J1w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.6", + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support": { + "version": "16.5.6", + "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-16.5.6.tgz", + "integrity": "sha512-Hqpa/hCvXZXUTUiJMAE55UXpzAeCVLaFlzzXQXLkne0vhmv3/JkWcBnX755a/b9+C4b3MKEz2i0tSKLsa3DldA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^14.0.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types/node_modules/@polkadot/networks": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-13.5.9.tgz", + "integrity": "sha512-nmKUKJjiLgcih0MkdlJNMnhEYdwEml2rv/h59ll2+rAvpsVWMTLCb6Cq6q7UC44+8kiWK2UUJMkFU+3PFFxndA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "13.5.9", + "@substrate/ss58-registry": "^1.51.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@noble/hashes": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz", - "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==", - "engines": { - "node": "^14.21.3 || >=16" + "node_modules/@polkadot/types/node_modules/@polkadot/util": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-13.5.9.tgz", + "integrity": "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-global": "13.5.9", + "@polkadot/x-textdecoder": "13.5.9", + "@polkadot/x-textencoder": "13.5.9", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=18" } }, - "node_modules/@polkadot/keyring": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-13.2.3.tgz", - "integrity": "sha512-pgTo6DXNXub0wGD+MnVHYhKxf80Jl+QMOCb818ioGdXz++Uw4mTueFAwtB+N7TGo0HafhChUiNJDxFdlDkcAng==", + "node_modules/@polkadot/types/node_modules/@polkadot/util-crypto": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.5.9.tgz", + "integrity": "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/util": "13.2.3", - "@polkadot/util-crypto": "13.2.3", + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "13.5.9", + "@polkadot/util": "13.5.9", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-randomvalues": "13.5.9", + "@scure/base": "^1.1.7", "tslib": "^2.8.0" }, "engines": { "node": ">=18" }, "peerDependencies": { - "@polkadot/util": "13.2.3", - "@polkadot/util-crypto": "13.2.3" + "@polkadot/util": "13.5.9" } }, - "node_modules/@polkadot/networks": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-13.2.3.tgz", - "integrity": "sha512-mG+zkXg/33AyPrkv2xBbAo3LBUwOwBn6qznBU/4jxiZPnVvCwMaxE7xHM22B5riItbNJ169FXv3wy0v6ZmkFbw==", + "node_modules/@polkadot/types/node_modules/@polkadot/x-bigint": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-13.5.9.tgz", + "integrity": "sha512-JVW6vw3e8fkcRyN9eoc6JIl63MRxNQCP/tuLdHWZts1tcAYao0hpWUzteqJY93AgvmQ91KPsC1Kf3iuuZCi74g==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/util": "13.2.3", - "@substrate/ss58-registry": "^1.51.0", + "@polkadot/x-global": "13.5.9", "tslib": "^2.8.0" }, "engines": { "node": ">=18" } }, - "node_modules/@polkadot/types": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-15.0.2.tgz", - "integrity": "sha512-6gZBnuXU58hQAXWI2daED2OaQwFMxbQdkE8HVGMovMobEf0PxPfIqf+GdnVmWbe09EU9mv2gCWBcdnvHSRBlQg==", + "node_modules/@polkadot/types/node_modules/@polkadot/x-global": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-13.5.9.tgz", + "integrity": "sha512-zSRWvELHd3Q+bFkkI1h2cWIqLo1ETm+MxkNXLec3lB56iyq/MjWBxfXnAFFYFayvlEVneo7CLHcp+YTFd9aVSA==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/keyring": "^13.2.3", - "@polkadot/types-augment": "15.0.2", - "@polkadot/types-codec": "15.0.2", - "@polkadot/types-create": "15.0.2", - "@polkadot/util": "^13.2.3", - "@polkadot/util-crypto": "^13.2.3", - "rxjs": "^7.8.1", "tslib": "^2.8.0" }, "engines": { "node": ">=18" } }, - "node_modules/@polkadot/types-augment": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-15.0.2.tgz", - "integrity": "sha512-UiFJVEYML30+V9GdFAHPbA3s4MVQTL1CevsZMnX0+ApvlgEHJMZnVFfYF7jL2bl9BcUYM/zoxEAhj2MpqFFfxw==", + "node_modules/@polkadot/types/node_modules/@polkadot/x-randomvalues": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-13.5.9.tgz", + "integrity": "sha512-Uuuz3oubf1JCCK97fsnVUnHvk4BGp/W91mQWJlgl5TIOUSSTIRr+lb5GurCfl4kgnQq53Zi5fJV+qR9YumbnZw==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/types": "15.0.2", - "@polkadot/types-codec": "15.0.2", - "@polkadot/util": "^13.2.3", + "@polkadot/x-global": "13.5.9", "tslib": "^2.8.0" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9", + "@polkadot/wasm-util": "*" } }, - "node_modules/@polkadot/types-codec": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-15.0.2.tgz", - "integrity": "sha512-44Q40p1rl0t7Bl1QUamewqXNVPway9xgqByyifv6ODSGhtt+lFoarb3U4JzqRUuuK0PP57ePB0L8q81Totxeew==", + "node_modules/@polkadot/types/node_modules/@polkadot/x-textdecoder": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-13.5.9.tgz", + "integrity": "sha512-W2HhVNUbC/tuFdzNMbnXAWsIHSg9SC9QWDNmFD3nXdSzlXNgL8NmuiwN2fkYvCQBtp/XSoy0gDLx0C+Fo19cfw==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/util": "^13.2.3", - "@polkadot/x-bigint": "^13.2.3", + "@polkadot/x-global": "13.5.9", "tslib": "^2.8.0" }, "engines": { "node": ">=18" } }, - "node_modules/@polkadot/types-create": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-15.0.2.tgz", - "integrity": "sha512-YhpcqbH3oI87PkgrV6Fez9jWDqFIep0KcS1YWQcwc9gsBNnuour80t2AAK41/tqAYwOZi6tpJwIevnEhVkxFYA==", + "node_modules/@polkadot/types/node_modules/@polkadot/x-textencoder": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-13.5.9.tgz", + "integrity": "sha512-SG0MHnLUgn1ZxFdm0KzMdTHJ47SfqFhdIPMcGA0Mg/jt2rwrfrP3jtEIJMsHfQpHvfsNPfv55XOMmoPWuQnP/Q==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/types-codec": "15.0.2", - "@polkadot/util": "^13.2.3", + "@polkadot/x-global": "13.5.9", "tslib": "^2.8.0" }, "engines": { @@ -155,34 +1892,123 @@ } }, "node_modules/@polkadot/util-crypto": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.2.3.tgz", - "integrity": "sha512-5sbggmLbn5eiuVMyPROPlT5roHRqdKHOfSpioNbGvGIZ1qIWVoC1RfsK0NWJOVGDzy6DpQe0KYT/kgcU5Xsrzw==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-14.0.3.tgz", + "integrity": "sha512-V00BI6XnZLCkrAmV8uN0eSB6fy48CkxdDZT29cgSMSwHPtY6oKUNgd1ST07PGCL5x8XflwjoA7CTlhdbp1Y9gw==", + "license": "Apache-2.0", "dependencies": { "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", - "@polkadot/networks": "13.2.3", - "@polkadot/util": "13.2.3", - "@polkadot/wasm-crypto": "^7.4.1", - "@polkadot/wasm-util": "^7.4.1", - "@polkadot/x-bigint": "13.2.3", - "@polkadot/x-randomvalues": "13.2.3", + "@polkadot/networks": "14.0.3", + "@polkadot/util": "14.0.3", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-randomvalues": "14.0.3", "@scure/base": "^1.1.7", + "@scure/sr25519": "^0.2.0", "tslib": "^2.8.0" }, "engines": { "node": ">=18" }, "peerDependencies": { - "@polkadot/util": "13.2.3" + "@polkadot/util": "14.0.3" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/util": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.3.tgz", + "integrity": "sha512-mg1NR7ixHlNiz2zbvdcdy1OXZmca2tVA4DpewGpY/qFkW/gq9HdDrHLu7g0k90QnunDcFW4emb7NB60sGJQ0bw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.3", + "@polkadot/x-global": "14.0.3", + "@polkadot/x-textdecoder": "14.0.3", + "@polkadot/x-textencoder": "14.0.3", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-bigint": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.3.tgz", + "integrity": "sha512-U0al6BKgldFrEbmSObRAlzv9VDs5SMa/rbvZKvvkVec0sWTzYPWQZU1ZC/biXLYdjdKML89BeuCKmXZtCcGhUQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-randomvalues": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-14.0.3.tgz", + "integrity": "sha512-qTPcrk0nIHL2tIu5e0cLj3puQvjCK7onehnqO2fvlmWeIlvDel66fwWs06Ipsib+CwLJdmE6WgNy+8Jv74r6YA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.3", + "@polkadot/wasm-util": "*" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.3.tgz", + "integrity": "sha512-4RJYDG00iUzQ7YAuS/yvkWRZlkjYU8PUNdJHRfqtJ+SjrSPB7LYYxFhLgw43TZUtHmIueNTsml2Ukv3xXTr2kA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-textencoder": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.3.tgz", + "integrity": "sha512-9HH6o2L+r99wEfXhPb5g+Xwn7qouqD32PsMux7B0dFGR2KNqP4KwO19Hu+gdij6wsEhy7delhZwzHenrWwDfhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/@polkadot/wasm-bridge": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.4.1.tgz", - "integrity": "sha512-tdkJaV453tezBxhF39r4oeG0A39sPKGDJmN81LYLf+Fihb7astzwju+u75BRmDrHZjZIv00un3razJEWCxze6g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.5.4.tgz", + "integrity": "sha512-6xaJVvoZbnbgpQYXNw9OHVNWjXmtcoPcWh7hlwx3NpfiLkkjljj99YS+XGZQlq7ks2fVCg7FbfknkNb8PldDaA==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/wasm-util": "7.4.1", + "@polkadot/wasm-util": "7.5.4", "tslib": "^2.7.0" }, "engines": { @@ -194,15 +2020,16 @@ } }, "node_modules/@polkadot/wasm-crypto": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.4.1.tgz", - "integrity": "sha512-kHN/kF7hYxm1y0WeFLWeWir6oTzvcFmR4N8fJJokR+ajYbdmrafPN+6iLgQVbhZnDdxyv9jWDuRRsDnBx8tPMQ==", - "dependencies": { - "@polkadot/wasm-bridge": "7.4.1", - "@polkadot/wasm-crypto-asmjs": "7.4.1", - "@polkadot/wasm-crypto-init": "7.4.1", - "@polkadot/wasm-crypto-wasm": "7.4.1", - "@polkadot/wasm-util": "7.4.1", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.5.4.tgz", + "integrity": "sha512-1seyClxa7Jd7kQjfnCzTTTfYhTa/KUTDUaD3DMHBk5Q4ZUN1D1unJgX+v1aUeXSPxmzocdZETPJJRZjhVOqg9g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-bridge": "7.5.4", + "@polkadot/wasm-crypto-asmjs": "7.5.4", + "@polkadot/wasm-crypto-init": "7.5.4", + "@polkadot/wasm-crypto-wasm": "7.5.4", + "@polkadot/wasm-util": "7.5.4", "tslib": "^2.7.0" }, "engines": { @@ -214,9 +2041,10 @@ } }, "node_modules/@polkadot/wasm-crypto-asmjs": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.4.1.tgz", - "integrity": "sha512-pwU8QXhUW7IberyHJIQr37IhbB6DPkCG5FhozCiNTq4vFBsFPjm9q8aZh7oX1QHQaiAZa2m2/VjIVE+FHGbvHQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.5.4.tgz", + "integrity": "sha512-ZYwxQHAJ8pPt6kYk9XFmyuFuSS+yirJLonvP+DYbxOrARRUHfN4nzp4zcZNXUuaFhpbDobDSFn6gYzye6BUotA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.7.0" }, @@ -228,14 +2056,15 @@ } }, "node_modules/@polkadot/wasm-crypto-init": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.4.1.tgz", - "integrity": "sha512-AVka33+f7MvXEEIGq5U0dhaA2SaXMXnxVCQyhJTaCnJ5bRDj0Xlm3ijwDEQUiaDql7EikbkkRtmlvs95eSUWYQ==", - "dependencies": { - "@polkadot/wasm-bridge": "7.4.1", - "@polkadot/wasm-crypto-asmjs": "7.4.1", - "@polkadot/wasm-crypto-wasm": "7.4.1", - "@polkadot/wasm-util": "7.4.1", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.5.4.tgz", + "integrity": "sha512-U6s4Eo2rHs2n1iR01vTz/sOQ7eOnRPjaCsGWhPV+ZC/20hkVzwPAhiizu/IqMEol4tO2yiSheD4D6bn0KxUJhg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-bridge": "7.5.4", + "@polkadot/wasm-crypto-asmjs": "7.5.4", + "@polkadot/wasm-crypto-wasm": "7.5.4", + "@polkadot/wasm-util": "7.5.4", "tslib": "^2.7.0" }, "engines": { @@ -247,11 +2076,12 @@ } }, "node_modules/@polkadot/wasm-crypto-wasm": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.4.1.tgz", - "integrity": "sha512-PE1OAoupFR0ZOV2O8tr7D1FEUAwaggzxtfs3Aa5gr+yxlSOaWUKeqsOYe1KdrcjmZVV3iINEAXxgrbzCmiuONg==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.5.4.tgz", + "integrity": "sha512-PsHgLsVTu43eprwSvUGnxybtOEuHPES6AbApcs7y5ZbM2PiDMzYbAjNul098xJK/CPtrxZ0ePDFnaQBmIJyTFw==", + "license": "Apache-2.0", "dependencies": { - "@polkadot/wasm-util": "7.4.1", + "@polkadot/wasm-util": "7.5.4", "tslib": "^2.7.0" }, "engines": { @@ -262,9 +2092,10 @@ } }, "node_modules/@polkadot/wasm-util": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.4.1.tgz", - "integrity": "sha512-RAcxNFf3zzpkr+LX/ItAsvj+QyM56TomJ0xjUMo4wKkHjwsxkz4dWJtx5knIgQz/OthqSDMR59VNEycQeNuXzA==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.5.4.tgz", + "integrity": "sha512-hqPpfhCpRAqCIn/CYbBluhh0TXmwkJnDRjxrU9Bnqtw9nMNa97D8JuOjdd2pi0rxm+eeLQ/f1rQMp71RMM9t4w==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.7.0" }, @@ -287,6 +2118,32 @@ "node": ">=18" } }, + "node_modules/@polkadot/x-fetch": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-14.0.3.tgz", + "integrity": "sha512-695c5aPBPtYcnn2zM+u0mXgyNHINlO0qGlGcJq3/0t5NVRZv5KZhk7NNm6antOay9uUjGG40F/r+LPzDT3QamA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "node-fetch": "^3.3.2", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-fetch/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@polkadot/x-global": { "version": "13.2.3", "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-13.2.3.tgz", @@ -302,6 +2159,7 @@ "version": "13.2.3", "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-13.2.3.tgz", "integrity": "sha512-Zf0GTfLmVk+VzPUmcQSpXjjmFzMTjPhXoLuIoE7xIu73T+vQ+TX9j7DvorN6bIRsnZ9l1SyTZsSf/NTjNZKIZg==", + "license": "Apache-2.0", "dependencies": { "@polkadot/x-global": "13.2.3", "tslib": "^2.8.0" @@ -338,6 +2196,53 @@ "node": ">=18" } }, + "node_modules/@polkadot/x-ws": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-14.0.3.tgz", + "integrity": "sha512-tOPdkMye3iuXnuFtdNg5+iSu7Cz9LRL8z5psMuZpUpThMYChGsS2pDFtNvXOKU8ohhO+frY9VdJ9VBg1WL9Iug==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.3", + "tslib": "^2.8.0", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-ws/node_modules/@polkadot/x-global": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.3.tgz", + "integrity": "sha512-MzMEynJ7HMTy/plLmdyP8rv14RS/6s29HZodUG9aCOscBnEiEDxVEax/ztRJqxhhQuHeYdx0LYDwVbdQDTkqNw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-ws/node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@scure/base": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.1.tgz", @@ -346,10 +2251,71 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@scure/sr25519": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@scure/sr25519/-/sr25519-0.2.0.tgz", + "integrity": "sha512-uUuLP7Z126XdSizKtrCGqYyR3b3hYtJ6Fg/XFUXmc2//k2aXHDLqZwFeXxL97gg4XydPROPVnuaHGF2+xriSKg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.2", + "@noble/hashes": "~1.8.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@substrate/connect": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.11.tgz", + "integrity": "sha512-ofLs1PAO9AtDdPbdyTYj217Pe+lBfTLltdHDs3ds8no0BseoLeAGxpz1mHfi7zB4IxI3YyAiLjH6U8cw4pj4Nw==", + "deprecated": "versions below 1.x are no longer maintained", + "license": "GPL-3.0-only", + "optional": true, + "dependencies": { + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.1.5", + "@substrate/light-client-extension-helpers": "^1.0.0", + "smoldot": "2.0.26" + } + }, + "node_modules/@substrate/connect-extension-protocol": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.2.2.tgz", + "integrity": "sha512-t66jwrXA0s5Goq82ZtjagLNd7DPGCNjHeehRlE/gcJmJ+G56C0W+2plqOMRicJ8XGR1/YFnUSEqUFiSNbjGrAA==", + "license": "GPL-3.0-only", + "optional": true + }, + "node_modules/@substrate/connect-known-chains": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.10.3.tgz", + "integrity": "sha512-OJEZO1Pagtb6bNE3wCikc2wrmvEU5x7GxFFLqqbz1AJYYxSlrPCGu4N2og5YTExo4IcloNMQYFRkBGue0BKZ4w==", + "license": "GPL-3.0-only", + "optional": true + }, + "node_modules/@substrate/light-client-extension-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-1.0.0.tgz", + "integrity": "sha512-TdKlni1mBBZptOaeVrKnusMg/UBpWUORNDv5fdCaJklP4RJiFOzBCrzC+CyVI5kQzsXBisZ+2pXm+rIjS38kHg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/json-rpc-provider": "^0.0.1", + "@polkadot-api/json-rpc-provider-proxy": "^0.1.0", + "@polkadot-api/observable-client": "^0.3.0", + "@polkadot-api/substrate-client": "^0.1.2", + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.1.5", + "rxjs": "^7.8.1" + }, + "peerDependencies": { + "smoldot": "2.x" + } + }, "node_modules/@substrate/ss58-registry": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.51.0.tgz", - "integrity": "sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==" + "integrity": "sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==", + "license": "Apache-2.0" }, "node_modules/@types/bn.js": { "version": "5.1.6", @@ -367,6 +2333,12 @@ "undici-types": "~6.20.0" } }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -536,6 +2508,15 @@ "node": ">=4.8" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -584,6 +2565,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -761,6 +2759,108 @@ "node": ">=0.8.0" } }, + "node_modules/ethers": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", + "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -769,6 +2869,18 @@ "is-callable": "^1.1.3" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1288,6 +3400,12 @@ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -1329,11 +3447,78 @@ "node": "*" } }, + "node_modules/mock-socket": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz", + "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "node_modules/nock": { + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.6.tgz", + "integrity": "sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -1470,6 +3655,15 @@ "node": ">= 0.4" } }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -1582,6 +3776,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/scale-ts": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.1.tgz", + "integrity": "sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==", + "license": "MIT", + "optional": true + }, "node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -1718,6 +3919,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/smoldot": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.26.tgz", + "integrity": "sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig==", + "license": "GPL-3.0-or-later WITH Classpath-exception-2.0", + "optional": true, + "dependencies": { + "ws": "^8.8.1" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -1952,6 +4163,15 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -2042,6 +4262,27 @@ "funding": { "url": "https://github.com/sponsors/ljharb" } + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } } } } diff --git a/launch-configs/fork/package.json b/launch-configs/fork/package.json index 71140e923..19d1f4e1b 100644 --- a/launch-configs/fork/package.json +++ b/launch-configs/fork/package.json @@ -28,7 +28,10 @@ "author": "", "license": "ISC", "dependencies": { + "@polkadot/api": "^16.5.6", "@polkadot/types": "^15.0.2", + "@polkadot/util-crypto": "^14.0.3", + "ethers": "^6.16.0", "npm-run-all": "^4.1.5" } } diff --git a/pallets/synthetic-logs/Cargo.toml b/pallets/synthetic-logs/Cargo.toml index 4906a939f..77143bc96 100644 --- a/pallets/synthetic-logs/Cargo.toml +++ b/pallets/synthetic-logs/Cargo.toml @@ -27,9 +27,6 @@ frame-system = { workspace = true } ethereum = { workspace = true } ethereum-types = { workspace = true } pallet-ethereum = { workspace = true } -fp-rpc = { workspace = true } -fp-evm = { workspace = true } -pallet-evm = { workspace = true } # HydraDX pallet-broadcast = { workspace = true } @@ -51,9 +48,6 @@ std = [ "ethereum/std", "ethereum-types/std", "pallet-ethereum/std", - "pallet-evm/std", - "fp-rpc/std", - "fp-evm/std", "pallet-broadcast/std", "primitives/std", ] diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs index 16a02e518..fe4e48369 100644 --- a/pallets/synthetic-logs/src/lib.rs +++ b/pallets/synthetic-logs/src/lib.rs @@ -74,12 +74,21 @@ pub const MAX_PENDING_LOGS: u32 = 4096; /// doesn't expose a stable public api to distinguish initialize from finalize /// at hook-fire time, so we collapse them and rely on the broadcast /// `ExecutionContext` for finer attribution (e.g. DCA schedule_id, xcm origin). +#[derive(Clone, Copy, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug, PartialEq, Eq)] +pub enum HookPhase { + Initialization, + Finalization, +} + #[derive(Clone, Copy, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug, PartialEq, Eq)] pub enum Bucket { /// One synth tx per substrate extrinsic. Extrinsic(u32), /// One synth tx per (hook-phase + originating broadcast context). - Hook { origin: Option }, + /// `phase` distinguishes init-time work (runs before extrinsics) from + /// finalize-time work (runs after) so transaction_index ordering of the + /// resulting synth tx matches the wall-clock order of substrate execution. + Hook { phase: HookPhase, origin: Option }, } #[frame_support::pallet] @@ -132,10 +141,26 @@ impl Pallet { } /// Determine the bucket for the currently-executing substrate phase. + /// Reads `frame_system::ExecutionPhase` directly via its storage key so we + /// distinguish init/finalize/idle correctly: + /// * Initialization → `HookPhase::Initialization` + /// * Finalization → `HookPhase::Finalization` (covers on_idle too, + /// since substrate sets Phase=Finalization before + /// on_idle runs) + /// * ApplyExtrinsic → `Bucket::Extrinsic(i)` fn current_bucket() -> Bucket { - match frame_system::Pallet::::extrinsic_index() { - Some(i) => Bucket::Extrinsic(i), - None => Bucket::Hook { + use frame_system::Phase; + let phase_key = + frame_support::storage::storage_prefix(b"System", b"ExecutionPhase"); + let phase: Phase = frame_support::storage::unhashed::get::(&phase_key).unwrap_or_default(); + match phase { + Phase::ApplyExtrinsic(i) => Bucket::Extrinsic(i), + Phase::Finalization => Bucket::Hook { + phase: HookPhase::Finalization, + origin: pallet_broadcast::Pallet::::get_context().first().copied(), + }, + Phase::Initialization => Bucket::Hook { + phase: HookPhase::Initialization, origin: pallet_broadcast::Pallet::::get_context().first().copied(), }, } @@ -162,20 +187,58 @@ impl Pallet { } fn bucket_sort_key(bucket: &Bucket) -> (u8, u64) { + // Init-phase hooks: 0 (before extrinsics) + // Extrinsic dispatch: 1 (sub-sorted by extrinsic_index) + // Finalize-phase hooks: 2 (after extrinsics) match bucket { - Bucket::Hook { origin: None } => (0, 0), - Bucket::Hook { origin: Some(_) } => (0, Self::bucket_nonce(*bucket)), + Bucket::Hook { + phase: HookPhase::Initialization, + origin: None, + } => (0, 0), + Bucket::Hook { + phase: HookPhase::Initialization, + origin: Some(_), + } => (0, Self::bucket_nonce(*bucket)), Bucket::Extrinsic(i) => (1, *i as u64), + Bucket::Hook { + phase: HookPhase::Finalization, + origin: None, + } => (2, 0), + Bucket::Hook { + phase: HookPhase::Finalization, + origin: Some(_), + } => (2, Self::bucket_nonce(*bucket)), } } /// Encodes the bucket as the synthetic tx's `nonce`, so indexers can /// reverse the synth tx back to its substrate origin. + /// + /// Layout: + /// Extrinsic(i) → i (low) + /// Hook { phase: Init, origin: None } → MAX - 3 + /// Hook { phase: Init, origin: Some(t) } → 0xDCA0… | tag(t) + /// Hook { phase: Final, origin: None } → MAX - 2 + /// Hook { phase: Final, origin: Some(t) } → 0xF1A1… | tag(t) pub fn bucket_nonce(bucket: Bucket) -> u64 { match bucket { Bucket::Extrinsic(i) => i as u64, - Bucket::Hook { origin: None } => u64::MAX - 1, - Bucket::Hook { origin: Some(o) } => 0xDCA0_0000_0000_0000u64 | Self::origin_tag(&o), + Bucket::Hook { + phase: HookPhase::Initialization, + origin: None, + } => u64::MAX - 3, + Bucket::Hook { + phase: HookPhase::Initialization, + origin: Some(o), + } => 0xDCA0_0000_0000_0000u64 | Self::origin_tag(&o), + Bucket::Hook { + phase: HookPhase::Finalization, + origin: None, + } => u64::MAX - 2, + Bucket::Hook { + phase: HookPhase::Finalization, + origin: Some(o), + } => 0xF1A1_0000_0000_0000u64 | Self::origin_tag(&o), } } diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 93abd99c9..598df9b26 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -211,9 +211,15 @@ construct_runtime!( // Frontier and EVM pallets EVM: pallet_evm = 90, EVMChainId: pallet_evm_chain_id = 91, - // SyntheticLogs MUST come before Ethereum so its on_finalize runs first - // and writes synthetic txs into pallet_ethereum::Pending before the - // ethereum pallet rolls Pending into the canonical block. + // SyntheticLogs is declared IMMEDIATELY before Ethereum so its on_finalize + // drains the buffer into pallet_ethereum::Pending right before Ethereum's + // on_finalize seals the block. Covers all on_initialize, on_idle, and + // on_finalize work of pallets declared before this line. Limitation: + // hooks fired during on_finalize of pallets declared AFTER Ethereum + // (EVMAccounts, DynamicEvmFee, XYK, MessageQueue, etc.) are not flushed + // in the same block — none of them currently fire token-balance hooks + // in their on_finalize, and MessageQueue's on_idle XCM processing is + // disabled on this runtime (`IdleMaxServiceWeight = ()`). SyntheticLogs: pallet_synthetic_logs = 86, Ethereum: pallet_ethereum = 92, EVMAccounts: pallet_evm_accounts = 93, From b3bf322218c32afeb0654ff6fc22c45467c3dc39 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 01:54:48 +0200 Subject: [PATCH 13/17] fixed tx hash indexing --- pallets/synthetic-logs/src/lib.rs | 51 +++++++++++-------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs index fe4e48369..bc3e208b8 100644 --- a/pallets/synthetic-logs/src/lib.rs +++ b/pallets/synthetic-logs/src/lib.rs @@ -52,10 +52,6 @@ pub const SENTINEL_ADDRESS: H160 = H160([ 0xef, ]); -/// Domain separator mixed into synthetic tx hashes so they can never collide -/// with real ethereum tx hashes computed from real signatures. -pub const SYNTH_DOMAIN: &[u8] = b"hydration-synth-v1"; - /// Constant `r`/`s` value for synthetic signatures. Inside the valid ECDSA /// range required by the ethereum crate, but clearly not a real signature. pub const SYNTH_SIG_RS: H256 = H256([ @@ -178,11 +174,8 @@ impl Pallet { } groups.sort_by(|a, b| Self::bucket_sort_key(&a.0).cmp(&Self::bucket_sort_key(&b.0))); - let block_number = frame_system::Pallet::::block_number(); - let parent_hash = frame_system::Pallet::::parent_hash(); - for (idx, (bucket, logs)) in groups.into_iter().enumerate() { - Self::insert_synth_tx(bucket, logs, idx as u32, &parent_hash, block_number); + Self::insert_synth_tx(bucket, logs, idx as u32); } } @@ -253,35 +246,21 @@ impl Pallet { } } - fn insert_synth_tx( - bucket: Bucket, - logs: Vec, - group_index: u32, - parent_hash: &T::Hash, - block_number: BlockNumberFor, - ) { + fn insert_synth_tx(bucket: Bucket, logs: Vec, group_index: u32) { let chain_id = ::ChainId::get(); let nonce = Self::bucket_nonce(bucket); - // Build a deterministic synthetic tx hash: - // keccak256(SYNTH_DOMAIN || parent_hash || block_number || nonce || group_index) - // `parent_hash` makes hashes unique across forks; nonce + group_index make them - // unique within a block. - let mut preimage: Vec = Vec::with_capacity(64); - preimage.extend_from_slice(SYNTH_DOMAIN); - preimage.extend_from_slice(parent_hash.as_ref()); - preimage.extend_from_slice(&block_number.encode()); - preimage.extend_from_slice(&nonce.to_be_bytes()); - preimage.extend_from_slice(&group_index.to_be_bytes()); - let transaction_hash = H256::from(sp_io::hashing::keccak_256(&preimage)); - - // Synthetic transaction. EIP-1559 envelope; fees and gas are zero. The - // signature is a constant fake (r=s=0x01..01) that satisfies the ECDSA - // range check imposed by the ethereum crate but obviously corresponds - // to no real signer. Synthetic txs are never recovered — `from` is - // sourced from `TransactionStatus.from`. + // EIP-1559 envelope. Fee fields zero; constant fake signature + // (r=s=0x01..01) inside the ECDSA range but obviously not a real + // signature — `from` is read from `TransactionStatus.from`, never + // ecrecovered. The `nonce` encodes the bucket so indexers can reverse + // the synth tx back to its substrate origin (see `bucket_nonce`). let signature = ethereum::eip2930::TransactionSignature::new(false, SYNTH_SIG_RS, SYNTH_SIG_RS) .expect("synthetic signature constants are within valid ECDSA range; qed"); + // Encode `group_index` into `value` so two synth txs in the same block + // (same bucket-nonce class) hash differently — without it, two + // `Hook { Init, None }` synth txs in one block would share the + // canonical envelope hash and collide in frontier's tx-hash index. let transaction = Transaction::EIP1559(EIP1559Transaction { chain_id, nonce: U256::from(nonce), @@ -289,12 +268,18 @@ impl Pallet { max_fee_per_gas: U256::zero(), gas_limit: U256::zero(), action: TransactionAction::Call(SENTINEL_ADDRESS), - value: U256::zero(), + value: U256::from(group_index), input: Vec::new(), access_list: Vec::new(), signature, }); + // Use the canonical envelope hash so frontier's tx-index lookups + // (eth_getTransactionByHash, eth_getTransactionReceipt) resolve, and + // so the `transactionHash` field on each emitted log matches what + // indexers see when they query the receipt. + let transaction_hash = transaction.hash(); + let mut bloom: Bloom = Bloom::default(); Self::compute_logs_bloom(&logs, &mut bloom); From abb4c2e214c8511738cf12cf548dbd4afa327391 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 02:31:21 +0200 Subject: [PATCH 14/17] lessblabla --- .../src/balances_tokens_hooks.rs | 77 ++---------- pallets/synthetic-logs/src/lib.rs | 111 ++++-------------- runtime/hydradx/src/evm/executor.rs | 8 +- runtime/hydradx/src/evm/precompiles/mod.rs | 13 +- runtime/hydradx/src/evm/runner.rs | 29 +---- runtime/hydradx/src/evm/swap_logs.rs | 39 ++---- runtime/hydradx/src/lib.rs | 13 +- 7 files changed, 52 insertions(+), 238 deletions(-) diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index 5d6fa845a..e9a8a25e6 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -285,13 +285,7 @@ fn currencies_withdraw_orml_buffers_burn_log() { }); } -// ---------------------------------------------------------------------- -// Blindspot tests: substrate transfers/swaps triggered through the dispatcher -// precompile from inside an EVM frame. Today the substrate hooks skip on -// `is_in_evm()` and the dispatcher does not inline-emit, so these transfers -// and swaps are silent to `eth_getLogs`. These tests assert the desired -// post-fix behavior — they will fail until the silent-path is closed. -// ---------------------------------------------------------------------- +// dispatcher precompile → substrate transfer/swap → must surface via eth_getLogs. #[test] fn dispatcher_precompile_currencies_transfer_token_emits_transfer_log() { @@ -436,17 +430,8 @@ fn dispatcher_precompile_omnipool_sell_emits_swap_log() { }); } -/// Order test (intra-batch). The dispatcher precompile drains the buffered -/// frame logs and emits them via `handle.log()` *at its own call site*, so -/// when a single dispatch contains a batch of N substrate transfers, the -/// resulting Transfer logs in `info.logs` (and thus in the captured synth tx -/// / real eth tx receipt) appear in the same order as the dispatched calls -/// — not bunched at the end of the receipt. -/// -/// Limitation: this only tests order *within* a single precompile drain. To -/// prove order *between* substrate-hook logs and inline-emitted contract -/// logs in the same EVM frame would require a Solidity contract that emits -/// markers around a precompile call; not added in v1. +/// intra-batch order: a dispatcher batch of N transfers produces logs in +/// dispatch order (drained inline at the precompile's call site). #[test] fn dispatcher_precompile_batch_preserves_substrate_transfer_order() { use codec::Encode; @@ -528,23 +513,8 @@ fn dispatcher_precompile_batch_preserves_substrate_transfer_order() { }); } -/// End-to-end ordering test using a custom Solidity probe contract. -/// -/// `LogOrderProbe.exercise(token, to, amount)` does: -/// 1. emit Marker(0) -/// 2. token.transfer(to, amount) // multicurrency precompile call -/// 3. emit Marker(1) -/// -/// We invoke `exercise` via Executor::call. The captured logs (in synth tx -/// order = info.logs order = log_index order) must be: -/// [Marker(0), Transfer, Marker(1)] -/// -/// If the precompile-level drain weren't there and we relied only on the -/// WrapRunner-end drain, the resulting order would be: -/// [Marker(0), Marker(1), Transfer] -/// — substrate-hook log bunched at the end. This test guards against that -/// regression and proves log_index ordering matches execution order across -/// the precompile→substrate→hook→drain path. +/// inline contract logs interleaved with a precompile-triggered substrate transfer +/// must produce `[Marker(0), Transfer, Marker(1)]` in log_index order. #[test] fn evm_inline_logs_around_precompile_call_preserve_log_index_order() { use ethereum_types::H256; @@ -639,13 +609,7 @@ fn evm_inline_logs_around_precompile_call_preserve_log_index_order() { }); } -// ---------------------------------------------------------------------- -// Reserve / unreserve — substrate-side encumbrance moves that change the -// erc20-visible `balanceOf` (which returns free balance only). To keep -// erc20 indexers reconstructing balances from Transfer events consistent -// with balanceOf, we mirror reserves as Transfer events to a per-owner -// sentinel: `reserved_address_of(owner) = owner with first byte XOR 0xEE`. -// ---------------------------------------------------------------------- +// reserve/unreserve mirror as `Transfer(owner, reserved_address_of(owner))`. #[test] fn orml_tokens_reserve_buffers_transfer_log_to_reserved_sentinel() { @@ -778,13 +742,7 @@ fn balances_unreserve_buffers_transfer_log_from_reserved_sentinel() { }); } -// ---------------------------------------------------------------------- -// Repatriate — moves reserved balance from one account to another. We need -// the eth-rpc Transfer-event accounting to stay consistent: amount leaves -// the slashed account's reserved bucket and lands either in beneficiary's -// free balance (status=Free) or in beneficiary's reserved bucket -// (status=Reserved). -// ---------------------------------------------------------------------- +// repatriate_reserved: A.reserved → B.free or B.reserved. #[test] fn orml_tokens_repatriate_to_free_buffers_transfer_log_to_beneficiary() { @@ -979,12 +937,8 @@ fn balances_currency_deposit_creating_buffers_mint_log() { }); } -/// End-to-end synth-tx flush: pushing a hook log into the buffer, then -/// running every pallet's `on_finalize` in `construct_runtime!` order, must -/// land a synthetic `pallet_ethereum::Transaction` in `pallet_ethereum::Pending` -/// with the expected log, status, receipt — i.e. the synthetic-logs pallet -/// runs BEFORE `pallet_ethereum::on_finalize` (which would otherwise have -/// already rolled `Pending` into the canonical block). +/// SyntheticLogs::on_finalize must run before Ethereum::on_finalize so the +/// synth tx lands in pallet_ethereum::Pending → CurrentBlock/Statuses/Receipts. #[test] fn on_finalize_drains_buffer_into_pallet_ethereum_pending_before_ethereum_seal() { use frame_support::traits::OnFinalize; @@ -1074,17 +1028,8 @@ fn on_finalize_drains_buffer_into_pallet_ethereum_pending_before_ethereum_seal() }); } -/// Revert safety. When an EVM frame reverts, frontier drops `info.logs` -/// (the substate's logs). Substrate hooks that fired during the frame may -/// have pushed entries into the `EVM_FRAME_LOGS` buffer; the WrapRunner's -/// end-drain must NOT append those buffered entries onto a reverted-frame -/// `info.logs`, or we get ghost logs for transfers whose substrate state -/// was rolled back by `pallet_evm`'s `with_storage_layer` wrapping. -/// -/// The probe contract calls dispatcher precompile (a substrate -/// Currencies::transfer), then reverts. We assert: -/// 1. Bob's DAI balance is unchanged (substrate state rolled back). -/// 2. No DAI Transfer log lands in the synth tx for this block. +/// outer EVM frame reverts → substrate state rolls back; runner end-drain +/// must NOT append buffered hook logs (would be ghost logs for non-events). #[test] fn evm_frame_revert_drops_buffered_substrate_hook_logs() { use codec::Encode; diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs index bc3e208b8..cc19aaeb8 100644 --- a/pallets/synthetic-logs/src/lib.rs +++ b/pallets/synthetic-logs/src/lib.rs @@ -3,29 +3,12 @@ // Copyright (C) 2020-2026 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 -//! # Synthetic Logs Pallet +//! buffers ethereum-shaped logs from substrate hooks; on_finalize flushes them +//! as synthetic `pallet_ethereum::Transaction` records so eth json-rpc surfaces +//! them. one synth tx per bucket: per-extrinsic, or per hook-phase + broadcast +//! origin (so each dca schedule etc. gets its own tx). //! -//! Buffers ethereum-shaped logs that originate from substrate-side hooks -//! (orml-tokens transfers, pallet-broadcast trades, etc.) and flushes them on -//! `on_finalize` as synthetic `pallet_ethereum::Transaction` records. This -//! makes substrate-origin events visible to eth json-rpc (`eth_getLogs`, -//! `eth_getTransactionReceipt`) and to standard EVM tooling — ethers.js, -//! etherscan-style explorers, the graph, dex aggregators. -//! -//! ## Bucket model -//! -//! Each pushed log is tagged with a `Bucket` derived from the current -//! `frame_system::Phase` plus `pallet_broadcast::ExecutionContext` (when in -//! a hook phase). One synthetic transaction is built per bucket, so: -//! - one synth tx per substrate extrinsic (containing all logs from that extrinsic) -//! - one synth tx per `(on_initialize/on_finalize, originating broadcast context)` -//! — e.g. each scheduled DCA execution gets its own tx attributed by `schedule_id` -//! -//! ## Pallet ordering -//! -//! Must be declared **before** `pallet_ethereum` in `construct_runtime!` so this -//! pallet's `on_finalize` runs first and writes into `pallet_ethereum::Pending` -//! before the ethereum pallet rolls Pending into the canonical block. +//! must be declared before `pallet_ethereum` in `construct_runtime!`. #![cfg_attr(not(feature = "std"), no_std)] @@ -44,32 +27,20 @@ use sp_std::prelude::*; pub use pallet::*; -/// Sentinel address used as both `from` and (default) `to` for synthetic txs. -/// Indicates "non-real-tx origin"; logs inside still carry their own emitter -/// address (asset's erc20 contract for transfers, pool address for swaps). +/// `from`/`to` for synthetic txs. logs inside carry their own emitter address. pub const SENTINEL_ADDRESS: H160 = H160([ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, ]); -/// Constant `r`/`s` value for synthetic signatures. Inside the valid ECDSA -/// range required by the ethereum crate, but clearly not a real signature. +/// Constant fake `r`/`s`. Inside ECDSA range so the envelope decodes; never recovered. pub const SYNTH_SIG_RS: H256 = H256([ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ]); -/// Hard cap on number of buffered logs per block. On overflow we drop the -/// newest pushes and emit a `log::warn!` so operators notice. pub const MAX_PENDING_LOGS: u32 = 4096; -/// One synthetic-tx attribution bucket. All logs sharing a bucket end up in -/// the same synthetic transaction. -/// -/// `Hook` covers `on_initialize` / `on_idle` / `on_finalize` work — substrate -/// doesn't expose a stable public api to distinguish initialize from finalize -/// at hook-fire time, so we collapse them and rely on the broadcast -/// `ExecutionContext` for finer attribution (e.g. DCA schedule_id, xcm origin). #[derive(Clone, Copy, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug, PartialEq, Eq)] pub enum HookPhase { Initialization, @@ -78,12 +49,7 @@ pub enum HookPhase { #[derive(Clone, Copy, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug, PartialEq, Eq)] pub enum Bucket { - /// One synth tx per substrate extrinsic. Extrinsic(u32), - /// One synth tx per (hook-phase + originating broadcast context). - /// `phase` distinguishes init-time work (runs before extrinsics) from - /// finalize-time work (runs after) so transaction_index ordering of the - /// resulting synth tx matches the wall-clock order of substrate execution. Hook { phase: HookPhase, origin: Option }, } @@ -96,11 +62,9 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config + pallet_ethereum::Config + pallet_broadcast::Config { - /// EVM chain id, mirrored from `pallet_evm::Config::ChainId`. type ChainId: Get; } - /// Buffered `(bucket, emitter, log)` entries, drained on every `on_finalize`. #[pallet::storage] #[pallet::whitelist_storage] #[pallet::unbounded] @@ -119,8 +83,6 @@ pub mod pallet { } impl Pallet { - /// Buffer a log to be emitted as part of a synthetic tx at end of block. - /// Bucket is derived from current substrate phase and broadcast context. pub fn push(emitter: H160, log: ethereum::Log) { let bucket = Self::current_bucket(); Pending::::mutate(|v| { @@ -136,14 +98,8 @@ impl Pallet { }); } - /// Determine the bucket for the currently-executing substrate phase. - /// Reads `frame_system::ExecutionPhase` directly via its storage key so we - /// distinguish init/finalize/idle correctly: - /// * Initialization → `HookPhase::Initialization` - /// * Finalization → `HookPhase::Finalization` (covers on_idle too, - /// since substrate sets Phase=Finalization before - /// on_idle runs) - /// * ApplyExtrinsic → `Bucket::Extrinsic(i)` + // reads `frame_system::ExecutionPhase` directly so on_idle (where substrate + // has already set Phase=Finalization) buckets as Finalization too. fn current_bucket() -> Bucket { use frame_system::Phase; let phase_key = @@ -162,8 +118,6 @@ impl Pallet { } } - /// Drain buffer, group by bucket, and write one synthetic tx per bucket - /// into `pallet_ethereum::Pending`. Must run before `pallet_ethereum::on_finalize`. fn flush(entries: Vec<(Bucket, H160, ethereum::Log)>) { let mut groups: Vec<(Bucket, Vec)> = Vec::new(); for (bucket, _emitter, log) in entries { @@ -179,10 +133,8 @@ impl Pallet { } } + // 0=init hooks, 1=extrinsics (by index), 2=finalize hooks — preserves wall-clock order. fn bucket_sort_key(bucket: &Bucket) -> (u8, u64) { - // Init-phase hooks: 0 (before extrinsics) - // Extrinsic dispatch: 1 (sub-sorted by extrinsic_index) - // Finalize-phase hooks: 2 (after extrinsics) match bucket { Bucket::Hook { phase: HookPhase::Initialization, @@ -250,17 +202,10 @@ impl Pallet { let chain_id = ::ChainId::get(); let nonce = Self::bucket_nonce(bucket); - // EIP-1559 envelope. Fee fields zero; constant fake signature - // (r=s=0x01..01) inside the ECDSA range but obviously not a real - // signature — `from` is read from `TransactionStatus.from`, never - // ecrecovered. The `nonce` encodes the bucket so indexers can reverse - // the synth tx back to its substrate origin (see `bucket_nonce`). let signature = ethereum::eip2930::TransactionSignature::new(false, SYNTH_SIG_RS, SYNTH_SIG_RS) .expect("synthetic signature constants are within valid ECDSA range; qed"); - // Encode `group_index` into `value` so two synth txs in the same block - // (same bucket-nonce class) hash differently — without it, two - // `Hook { Init, None }` synth txs in one block would share the - // canonical envelope hash and collide in frontier's tx-hash index. + // `value = group_index` so two synth txs sharing the same bucket-nonce in + // one block produce distinct envelope hashes (frontier indexes by hash). let transaction = Transaction::EIP1559(EIP1559Transaction { chain_id, nonce: U256::from(nonce), @@ -274,10 +219,7 @@ impl Pallet { signature, }); - // Use the canonical envelope hash so frontier's tx-index lookups - // (eth_getTransactionByHash, eth_getTransactionReceipt) resolve, and - // so the `transactionHash` field on each emitted log matches what - // indexers see when they query the receipt. + // canonical envelope hash so frontier's tx-index resolves it. let transaction_hash = transaction.hash(); let mut bloom: Bloom = Bloom::default(); @@ -315,57 +257,44 @@ impl Pallet { } } -/// Helper: standard ERC-20 `Transfer(address,address,uint256)` topic0. +/// keccak256("Transfer(address,address,uint256)") pub const TRANSFER_TOPIC: H256 = H256([ 0xdd, 0xf2, 0x52, 0xad, 0x1b, 0xe2, 0xc8, 0x9b, 0x69, 0xc2, 0xb0, 0x68, 0xfc, 0x37, 0x8d, 0xaa, 0x95, 0x2b, 0xa7, 0xf1, 0x63, 0xc4, 0xa1, 0x16, 0x28, 0xf5, 0x5a, 0x4d, 0xf5, 0x23, 0xb3, 0xef, ]); -/// Helper: Uniswap V2 `Swap(address,uint256,uint256,uint256,uint256,address)` topic0. +/// keccak256("Swap(address,uint256,uint256,uint256,uint256,address)") (uniswap v2) pub const SWAP_TOPIC: H256 = H256([ 0xd7, 0x8a, 0xd9, 0x5f, 0xa4, 0x6c, 0x99, 0x4b, 0x65, 0x51, 0xd0, 0xda, 0x85, 0xfc, 0x27, 0x5f, 0xe6, 0x13, 0xce, 0x37, 0x65, 0x7f, 0xb8, 0xd5, 0xe3, 0xd1, 0x30, 0x84, 0x01, 0x59, 0xd8, 0x22, ]); -/// Helper: standard ERC-20 `Approval(address,address,uint256)` topic0. +/// keccak256("Approval(address,address,uint256)") pub const APPROVAL_TOPIC: H256 = H256([ 0x8c, 0x5b, 0xe1, 0xe5, 0xeb, 0xec, 0x7d, 0x5b, 0xd1, 0x4f, 0x71, 0x42, 0x7d, 0x1e, 0x84, 0xf3, 0xdd, 0x03, 0x14, 0xc0, 0xf7, 0xb2, 0x29, 0x1e, 0x5b, 0x20, 0x0a, 0xc8, 0xc7, 0xc3, 0xb9, 0x25, ]); -/// Pad an `H160` to a 32-byte topic word (left-pad with 12 zero bytes). pub fn h160_to_h256(addr: H160) -> H256 { let mut bytes = [0u8; 32]; bytes[12..].copy_from_slice(&addr.0); H256(bytes) } -/// Per-owner sentinel address representing the owner's reserved balance -/// bucket. Used as the `to` topic on `reserve` and the `from` topic on -/// `unreserve` so erc20 indexers reconstructing balances from `Transfer` -/// events stay consistent with `balanceOf` (which returns free balance only). -/// -/// Derivation: XOR the first byte of `owner` with `0xEE`. The mapping is -/// trivially reversible (XOR again) so a bookkeeping consumer that wants -/// owner attribution from a sentinel can recover it; reversibility is -/// optional for forward-only indexers (which compute the sentinel from a -/// known owner). Collision with the asset-prefix range -/// (`0x000…01`) requires the owner to start with `0xEE` followed -/// by 11 zero bytes, then `0x01`, then 3 zero bytes — pre-image probability -/// `2^-128` for uniformly distributed addresses. +/// per-owner sentinel for reserved balance: `Transfer(owner, reserved_address_of(owner))` +/// on reserve, inverse on unreserve. derivation: xor first byte with `0xEE` +/// (reversible). collision with asset-prefix range `0x000…01` is `2^-128`. pub fn reserved_address_of(owner: H160) -> H160 { let mut bytes = owner.0; bytes[0] ^= 0xEE; H160(bytes) } -/// Encode a single u256 as a 32-byte big-endian word for log `data`. pub fn encode_u256_be(value: U256) -> [u8; 32] { value.to_big_endian() } -/// Encode four u256 values as 128 bytes (the ABI shape of the -/// uniswap v2 Swap event's non-indexed fields). +/// 4 × u256 = 128 bytes — abi shape of uniswap v2 `Swap` non-indexed fields. pub fn encode_uint256_quad(a: U256, b: U256, c: U256, d: U256) -> Vec { let mut data = Vec::with_capacity(128); data.extend_from_slice(&encode_u256_be(a)); diff --git a/runtime/hydradx/src/evm/executor.rs b/runtime/hydradx/src/evm/executor.rs index 44beff6f9..c80e9f492 100644 --- a/runtime/hydradx/src/evm/executor.rs +++ b/runtime/hydradx/src/evm/executor.rs @@ -24,12 +24,8 @@ pub type NonceIdOf = <::AccountProvider as AccountProvider>::Non pub struct Executor(sp_std::marker::PhantomData); -/// Buffer EVM-frame logs from a `Runner::call` invocation into -/// `pallet_synthetic_logs`. Used by `Executor::call` (the wrapper hydration -/// modules use for direct Runner::call) to surface logs to `eth_getLogs` on -/// paths that bypass `pallet_ethereum::transact` (e.g. HSM arbitrage, -/// dispatcher-driven evm calls). pallet_ethereum::transact does not go -/// through Executor::call, so there is no overlap and no dedup is needed. +// surfaces evm-frame logs from non-transact paths (hsm, dispatcher-driven +// evm calls) into pallet_synthetic_logs. transact bypasses Executor::call. fn capture_logs(logs: &[pallet_evm::Log]) { for log in logs { pallet_synthetic_logs::Pallet::::push( diff --git a/runtime/hydradx/src/evm/precompiles/mod.rs b/runtime/hydradx/src/evm/precompiles/mod.rs index 6019ecbae..9244b3839 100644 --- a/runtime/hydradx/src/evm/precompiles/mod.rs +++ b/runtime/hydradx/src/evm/precompiles/mod.rs @@ -230,11 +230,8 @@ pub fn is_precompile(address: H160) -> bool { address == DISPATCH_ADDR || is_asset_address(address) || is_standard_precompile(address) } -/// Drain logs that substrate hooks buffered into the current EVM frame -/// (via `evm::runner::append_to_current_evm_frame`) and emit each through -/// the precompile handle so they land at the precompile's call site in -/// execution order — preserving `log_index` semantics in the final receipt. -/// Charges standard EVM log gas (8 + 375*topics + 8*data_bytes) per entry. +/// drains hook logs buffered during the current frame and emits each via +/// `handle.log()` so they land at the precompile's call site (preserves log_index). pub fn emit_buffered_evm_frame_logs(handle: &mut impl PrecompileHandle) -> EvmResult<()> { for log in crate::evm::runner::drain_current_evm_frame_logs() { let cost = costs::log_costs(log.topics.len(), log.data.len()).map_err(|_| PrecompileFailure::Error { @@ -246,11 +243,7 @@ pub fn emit_buffered_evm_frame_logs(handle: &mut impl PrecompileHandle) -> EvmRe Ok(()) } -/// Emit a standard ERC-20 `Approval(owner, spender, value)` log inline at -/// the calling precompile's address. Used by the multicurrency precompile's -/// `approve` and (on allowance-decrement) `transfer_from` paths so erc20 -/// indexers tracking allowance changes can observe substrate-side -/// `pallet_evm_accounts::set_allowance` calls. +/// emits ERC-20 `Approval(owner, spender, value)` inline at the precompile's address. pub fn emit_approval_log( handle: &mut impl PrecompileHandle, owner: H160, diff --git a/runtime/hydradx/src/evm/runner.rs b/runtime/hydradx/src/evm/runner.rs index 5f9ded9fc..3856f9aa0 100644 --- a/runtime/hydradx/src/evm/runner.rs +++ b/runtime/hydradx/src/evm/runner.rs @@ -37,18 +37,9 @@ use primitives::{AccountId, AssetId, Balance}; use sp_runtime::traits::UniqueSaturatedInto; use sp_std::vec::Vec; -// Per-EVM-frame buffer of substrate-hook-emitted logs. Filled by hooks via -// `append_to_current_evm_frame`; drained by precompiles that trigger -// substrate dispatches (multicurrency, dispatcher) to emit inline at the -// precompile's call site, or — as a safety net — drained by `WrapRunner` -// after `R::call`/`R::create*` returns and appended to `info.logs`. Effect: -// - pallet_ethereum::transact → frontier copies info.logs into the real eth tx -// receipt, so substrate-origin transfers triggered from inside the frame -// surface in the eth tx's receipt. -// - Executor::call → capture_logs surfaces the same logs to pallet_synthetic_logs. -// Active scope also serves as the "in-evm-frame" sentinel: hooks check the -// return value of `append_to_current_evm_frame` to decide whether to fall -// back to pallet_synthetic_logs. +// per-evm-frame buffer of substrate-hook logs. precompiles that trigger +// substrate dispatches drain it inline (preserves log_index order); the +// runner's end-drain is a safety net. mod evm_frame_logs { use sp_std::vec::Vec; environmental::environmental!(EVM_FRAME_LOGS: Vec); @@ -61,24 +52,16 @@ mod evm_frame_logs { EVM_FRAME_LOGS::using_once(buf, f) } - /// Drain all buffered logs from the current EVM frame and return them. pub fn drain() -> Vec { EVM_FRAME_LOGS::with(|buf| sp_std::mem::take(buf)).unwrap_or_default() } } -/// Push a substrate-emitted log into the current EVM frame's log buffer. -/// Returns `true` if a frame was active and the log was buffered, `false` -/// otherwise (caller should then fall back to pallet_synthetic_logs). +/// returns true if a frame is active; false → caller should fall back to synthetic-logs. pub fn append_to_current_evm_frame(log: ethereum::Log) -> bool { evm_frame_logs::append(log) } -/// Drain all logs buffered in the current EVM frame. Precompiles that -/// trigger substrate dispatches (and thus may have caused hooks to push) -/// call this immediately before returning, then re-emit via `handle.log()` -/// so the logs land at their natural position in the EVM execution's log -/// list (preserving log_index order in the eventual eth tx receipt). pub fn drain_current_evm_frame_logs() -> Vec { evm_frame_logs::drain() } @@ -209,7 +192,6 @@ where let source_account_id = T::AddressMapping::into_account_id(source); let original_nonce = frame_system::Pallet::::account_nonce(source_account_id.clone()); - // Validated, flag set to false let mut frame_logs: Vec = Vec::new(); let mut result = evm_frame_logs::using(&mut frame_logs, || { R::call( @@ -280,7 +262,6 @@ where config, )?; } - // Validated, flag set to false let mut frame_logs: Vec = Vec::new(); let mut result = evm_frame_logs::using(&mut frame_logs, || { R::create( @@ -341,7 +322,6 @@ where config, )?; } - //Validated, flag set to false let mut frame_logs: Vec = Vec::new(); let mut result = evm_frame_logs::using(&mut frame_logs, || { R::create2( @@ -403,7 +383,6 @@ where config, )?; } - //Validated, flag set to false let mut frame_logs: Vec = Vec::new(); let mut result = evm_frame_logs::using(&mut frame_logs, || { R::create_force_address( diff --git a/runtime/hydradx/src/evm/swap_logs.rs b/runtime/hydradx/src/evm/swap_logs.rs index 1bcf2fb79..ff7dd5743 100644 --- a/runtime/hydradx/src/evm/swap_logs.rs +++ b/runtime/hydradx/src/evm/swap_logs.rs @@ -3,17 +3,8 @@ // Copyright (C) 2020-2026 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 -//! Translates `pallet_broadcast::Event::Swapped3` trades into uniswap-v2-style -//! `Swap(address,uint256,uint256,uint256,uint256,address)` evm logs and -//! buffers them in `pallet_synthetic_logs`. Picked the uniswap v2 signature -//! because every defi aggregator (1inch, paraswap, defillama) and every dex -//! subgraph already indexes by it — emitting it from a stable per-pool -//! address gets us auto-discovery for free. -//! -//! v1 scope: bilateral 1-input / 1-output swaps (`ExactIn`/`ExactOut`). -//! Liquidity add/remove and multi-asset trades are skipped — they don't fit -//! the uniswap v2 mental model. Future extensions: `Mint`/`Burn` for -//! liquidity ops, custom `OTCFilled` for limit orders. +//! translates `Swapped3` events to uniswap-v2 `Swap` logs (every defi aggregator +//! indexes by that signature). v1: bilateral `ExactIn`/`ExactOut` only. use crate::evm::precompiles::erc20_mapping::is_asset_address; use crate::Runtime; @@ -31,13 +22,8 @@ fn evm_address_of(account: &AccountId) -> H160 { pallet_evm_accounts::Pallet::::evm_address(account) } -/// Derive a stable evm address for a substrate-side pool (the trade `filler`). -/// -/// Each pool has a unique substrate `AccountId` (omnipool's pallet account, -/// each stableswap pool's account, each xyk pool's share-token account). The -/// h160 derivation from that accountId is stable across blocks and 1:1 with -/// the pool — exactly what indexers need. -fn derive_pool_address(filler: &AccountId, _filler_type: &Filler) -> H160 { +// pool's evm address = h160-derivation of the filler's substrate accountid. +fn derive_pool_address(filler: &AccountId) -> H160 { evm_address_of(filler) } @@ -45,15 +31,13 @@ impl OnTrade for EmitUniswapV2SwapLog { fn on_trade( swapper: &AccountId, filler: &AccountId, - filler_type: &Filler, + _filler_type: &Filler, operation: &TradeOperation, inputs: &[Asset], outputs: &[Asset], _fees: &[Fee], _operation_stack: &[ExecutionType], ) { - // v1: only swap-shaped trades. Liquidity ops, OTC limit fills, and - // multi-asset stableswap legs don't fit the uniswap v2 mental model. if !matches!(operation, TradeOperation::ExactIn | TradeOperation::ExactOut) { return; } @@ -70,8 +54,7 @@ impl OnTrade for EmitUniswapV2SwapLog { return; } - // Sort assets by id so token0 < token1 deterministically. Indexers - // assume this ordering when interpreting the four amount fields. + // token0 < token1 by id so amounts map deterministically. let token0_id = in_asset.min(out_asset); let (a0_in, a1_in, a0_out, a1_out) = if in_asset == token0_id { ( @@ -89,12 +72,8 @@ impl OnTrade for EmitUniswapV2SwapLog { ) }; - let pool_address = derive_pool_address(filler, filler_type); - // Defensive: pool address must not collide with the erc20 prefix range - // used by `HydraErc20Mapping::asset_address`. If a pool's accountId - // happened to derive to that range we'd emit logs from an asset - // contract address by mistake. Skip silently if it does — this is - // astronomically unlikely with any real pool accountId. + let pool_address = derive_pool_address(filler); + // would clash with HydraErc20Mapping; skip (probability ~2^-128). if is_asset_address(pool_address) { log::warn!( target: "runtime::synthetic-logs", @@ -105,8 +84,6 @@ impl OnTrade for EmitUniswapV2SwapLog { } let sender = evm_address_of(swapper); - // Hydration trades always credit the swapper. There's no separate - // recipient field on `Swapped3` to encode here. let recipient = sender; let log = ethereum::Log { diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 598df9b26..bbdd88e37 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -211,15 +211,10 @@ construct_runtime!( // Frontier and EVM pallets EVM: pallet_evm = 90, EVMChainId: pallet_evm_chain_id = 91, - // SyntheticLogs is declared IMMEDIATELY before Ethereum so its on_finalize - // drains the buffer into pallet_ethereum::Pending right before Ethereum's - // on_finalize seals the block. Covers all on_initialize, on_idle, and - // on_finalize work of pallets declared before this line. Limitation: - // hooks fired during on_finalize of pallets declared AFTER Ethereum - // (EVMAccounts, DynamicEvmFee, XYK, MessageQueue, etc.) are not flushed - // in the same block — none of them currently fire token-balance hooks - // in their on_finalize, and MessageQueue's on_idle XCM processing is - // disabled on this runtime (`IdleMaxServiceWeight = ()`). + // must be declared before Ethereum so on_finalize flushes into + // pallet_ethereum::Pending before the block is sealed. hooks fired + // during on_finalize of pallets declared AFTER Ethereum are not + // captured (none currently emit token-balance hooks there). SyntheticLogs: pallet_synthetic_logs = 86, Ethereum: pallet_ethereum = 92, EVMAccounts: pallet_evm_accounts = 93, From 1a9dd187f0d19d44ffc700d93128b441e1688347 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 03:16:56 +0200 Subject: [PATCH 15/17] clippy --- .../src/balances_tokens_hooks.rs | 13 +- integration-tests/src/dca.rs | 10 +- integration-tests/src/dispatcher.rs | 13 +- integration-tests/src/dynamic_fees.rs | 18 +- integration-tests/src/evm.rs | 10 +- integration-tests/src/evm_permit.rs | 10 +- .../src/global_withdraw_limit.rs | 20 +-- integration-tests/src/hsm.rs | 4 +- integration-tests/src/liquidation.rs | 3 +- .../src/omnipool_add_all_liquidity.rs | 4 +- integration-tests/src/omnipool_fixed_fees.rs | 9 +- integration-tests/src/omnipool_slip_fees.rs | 32 +--- .../src/omnipool_slip_fees_xval.rs | 49 ++---- integration-tests/src/oracle.rs | 3 +- integration-tests/src/polkadot_test_net.rs | 8 +- integration-tests/src/router.rs | 12 +- .../src/stableswap_curve_comparison.rs | 27 +-- integration-tests/src/utils/contracts.rs | 5 +- pallets/synthetic-logs/src/lib.rs | 138 +++++++-------- pallets/synthetic-logs/src/tests.rs | 162 ++++++++++++++++++ runtime/hydradx/src/evm/runner.rs | 2 +- runtime/hydradx/src/evm/swap_logs.rs | 3 +- 22 files changed, 309 insertions(+), 246 deletions(-) diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index e9a8a25e6..afe8e5978 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -506,9 +506,7 @@ fn dispatcher_precompile_batch_preserves_substrate_transfer_order() { observed, leg_assets.to_vec(), "Transfer logs from a batched dispatcher call must appear in dispatch order, \ - not bunched at the end. Expected {:?}, got {:?}", - leg_assets, - observed, + not bunched at the end. Expected {leg_assets:?}, got {observed:?}", ); }); } @@ -603,8 +601,7 @@ fn evm_inline_logs_around_precompile_call_preserve_log_index_order() { vec!["Marker0", "Transfer", "Marker1"], "log_index ordering must match EVM execution order: \ inline Marker(0), then precompile-emitted Transfer (drained at multicurrency precompile call site), \ - then inline Marker(1). Got: {:?}", - kinds, + then inline Marker(1). Got: {kinds:?}", ); }); } @@ -638,9 +635,7 @@ fn orml_tokens_reserve_buffers_transfer_log_to_reserved_sentinel() { assert!( entry.is_some(), "orml_tokens::reserve must buffer Transfer(owner, reserved_sentinel, amount); \ - reserved_sentinel = {:?} for alice = {:?}", - reserved, - alice_h, + reserved_sentinel = {reserved:?} for alice = {alice_h:?}", ); }); } @@ -1078,7 +1073,7 @@ fn evm_frame_revert_drops_buffered_substrate_hook_logs() { calldata.extend_from_slice(&inner_encoded); // pad to 32-byte boundary let pad = (32 - inner_encoded.len() % 32) % 32; - calldata.extend(sp_std::iter::repeat(0u8).take(pad)); + calldata.extend(std::iter::repeat_n(0u8, pad)); SyntheticLogsPending::::kill(); diff --git a/integration-tests/src/dca.rs b/integration-tests/src/dca.rs index 290e97da4..f262828f3 100644 --- a/integration-tests/src/dca.rs +++ b/integration-tests/src/dca.rs @@ -3723,14 +3723,12 @@ mod stableswap { assert_eq!( alice_stable_shares_after, 0, - "User should have 0 pool shares since DCA execution failed. Got {}", - alice_stable_shares_after + "User should have 0 pool shares since DCA execution failed. Got {alice_stable_shares_after}" ); assert_eq!( router_reserved_shares, 0, - "Router should have 0 reserved shares. Got {}", - router_reserved_shares + "Router should have 0 reserved shares. Got {router_reserved_shares}" ); TransactionOutcome::Commit(DispatchResult::Ok(())) @@ -5491,9 +5489,7 @@ mod extra_gas_erc20 { assert!( fee_with_extra > base_fee, - "Fee with extra gas ({}) should be > base fee ({})", - fee_with_extra, - base_fee + "Fee with extra gas ({fee_with_extra}) should be > base fee ({base_fee})" ); // The first attempt charged base fee (before extra gas was added) diff --git a/integration-tests/src/dispatcher.rs b/integration-tests/src/dispatcher.rs index 8ec103a6b..41de5542a 100644 --- a/integration-tests/src/dispatcher.rs +++ b/integration-tests/src/dispatcher.rs @@ -101,7 +101,7 @@ fn dispatch_as_aave_admin_can_modify_supply_cap_on_testnet() { RuntimeEvent::Dispatcher(pallet_dispatcher::Event::AaveManagerCallDispatched { result: Ok(..), .. }) => {} - _ => panic!("Unexpected event: {:?}", event), + _ => panic!("Unexpected event: {event:?}"), } }); } @@ -248,8 +248,7 @@ fn dispatch_with_extra_gas_should_pay_for_extra_gas_used_when_it_is_not_used() { let gas_eater_paid_fee = initial_alice_hdx_balance - alice_balance_final; assert_eq!( gas_eater_paid_fee, hydra_paid_fee, - "GasEater transfer should cost the same as HydraToken transfer: {:?} == {:?}", - gas_eater_paid_fee, hydra_paid_fee + "GasEater transfer should cost the same as HydraToken transfer: {gas_eater_paid_fee:?} == {hydra_paid_fee:?}" ); }); } @@ -363,17 +362,13 @@ fn dispatch_with_extra_gas_should_not_refund_extra_gas_correctly() { // Fee charged on tx submit should be higher in the second case assert!( fee_charge_2 > fee_charge_1, - "Fee charged on tx submit should be higher in the second case: {:?} > {:?}", - fee_charge_2, - fee_charge_1 + "Fee charged on tx submit should be higher in the second case: {fee_charge_2:?} > {fee_charge_1:?}" ); // the two tx fees should be the same because it should refund correctly the unused gas assert!( actual_fee_paid_1 < actual_fee_paid_2, - "Paid fee should be higher for the second tx: {:?} < {:?}", - actual_fee_paid_1, - actual_fee_paid_2 + "Paid fee should be higher for the second tx: {actual_fee_paid_1:?} < {actual_fee_paid_2:?}" ); } diff --git a/integration-tests/src/dynamic_fees.rs b/integration-tests/src/dynamic_fees.rs index 6dc9e5e1b..82a408781 100644 --- a/integration-tests/src/dynamic_fees.rs +++ b/integration-tests/src/dynamic_fees.rs @@ -834,10 +834,10 @@ fn fees_should_be_applied_correctly_when_min_equals_max_in_dynamic_config() { println!("DOT asset fee: 1% (applied on DOT being sold)"); println!("HDX protocol fee: 0.5% (applied on HDX being received)"); println!("---"); - println!("Amount received with zero fees: {}", amount_out_with_zero_fee); - println!("Amount received with fees: {}", amount_out_with_fee); - println!("Difference: {}", actual_difference); - println!("Actual percentage difference: {:.4}%", actual_percentage_value); + println!("Amount received with zero fees: {amount_out_with_zero_fee}"); + println!("Amount received with fees: {amount_out_with_fee}"); + println!("Difference: {actual_difference}"); + println!("Actual percentage difference: {actual_percentage_value:.4}%"); println!("====================================\n"); // Verify the fees were applied (should see some difference) @@ -850,16 +850,10 @@ fn fees_should_be_applied_correctly_when_min_equals_max_in_dynamic_config() { assert!( actual_percentage_value >= expected_percentage - tolerance, - "Actual fee percentage ({:.4}%) is lower than expected ({:.2}% - {:.2}%)", - actual_percentage_value, - expected_percentage, - tolerance + "Actual fee percentage ({actual_percentage_value:.4}%) is lower than expected ({expected_percentage:.2}% - {tolerance:.2}%)" ); assert!( actual_percentage_value <= expected_percentage + tolerance, - "Actual fee percentage ({:.4}%) is higher than expected ({:.2}% + {:.2}%)", - actual_percentage_value, - expected_percentage, - tolerance + "Actual fee percentage ({actual_percentage_value:.4}%) is higher than expected ({expected_percentage:.2}% + {tolerance:.2}%)" ); } diff --git a/integration-tests/src/evm.rs b/integration-tests/src/evm.rs index f7bc36cb1..236f5372a 100644 --- a/integration-tests/src/evm.rs +++ b/integration-tests/src/evm.rs @@ -350,7 +350,7 @@ mod account_conversion { ExitReason::Succeed(ExitSucceed::Stopped) ); - println!("{:?}", res); + println!("{res:?}"); }); } @@ -3721,9 +3721,7 @@ fn compare_fee_in_eth_between_evm_and_native_omnipool_calls() { let native_fee = new_alice_currency_balance - alice_currency_balance_pre_dispatch; assert!( evm_fee > native_fee, - "assertion failed evm_fee > native fee. Evm fee: {:?} Native fee: {:?}", - evm_fee, - native_fee + "assertion failed evm_fee > native fee. Evm fee: {evm_fee:?} Native fee: {native_fee:?}" ); let fee_difference = evm_fee - native_fee; @@ -3734,9 +3732,7 @@ fn compare_fee_in_eth_between_evm_and_native_omnipool_calls() { // EVM fees should be not higher than 20% assert!( relative_fee_difference < tolerated_fee_difference, - "relative_fee_difference: {:?} is bigger than tolerated {:?}", - relative_fee_difference, - tolerated_fee_difference + "relative_fee_difference: {relative_fee_difference:?} is bigger than tolerated {tolerated_fee_difference:?}" ); }) } diff --git a/integration-tests/src/evm_permit.rs b/integration-tests/src/evm_permit.rs index 532144983..9b7baba36 100644 --- a/integration-tests/src/evm_permit.rs +++ b/integration-tests/src/evm_permit.rs @@ -169,9 +169,7 @@ fn compare_fee_in_hdx_between_evm_and_native_omnipool_calls_when_permit_is_dispa // EVM fees should be not higher than 20% assert!( relative_fee_difference < tolerated_fee_difference, - "relative_fee_difference: {:?} is bigger than tolerated {:?}", - relative_fee_difference, - tolerated_fee_difference + "relative_fee_difference: {relative_fee_difference:?} is bigger than tolerated {tolerated_fee_difference:?}" ); }) } @@ -1195,13 +1193,11 @@ fn evm_permit_set_currency_dispatch_should_pay_evm_fee_in_insufficient_asset() { let payed_fee = initial_user_insufficient_balance - user_insufficient_asset_balance; assert!( payed_fee > 50_000_000, - "payed_fee: {:?} is less than 50_000_000", - payed_fee + "payed_fee: {payed_fee:?} is less than 50_000_000" ); assert!( payed_fee < 120_000_000, - "payed_fee: {:?} is more than 120_000_000", - payed_fee + "payed_fee: {payed_fee:?} is more than 120_000_000" ); TransactionOutcome::Commit(DispatchResult::Ok(())) diff --git a/integration-tests/src/global_withdraw_limit.rs b/integration-tests/src/global_withdraw_limit.rs index f5105deae..ecf433a28 100644 --- a/integration-tests/src/global_withdraw_limit.rs +++ b/integration-tests/src/global_withdraw_limit.rs @@ -32,7 +32,7 @@ fn xcm_message_withdraw_deposit(token_location: Location, amount: Balance) -> Xc Xcm(vec![ WithdrawAsset(asset.clone().into()), BuyExecution { - fees: asset.into(), + fees: asset, weight_limit: Unlimited, }, DepositReserveAsset { @@ -54,7 +54,7 @@ fn set_dot_external_and_get_transfer_call() -> hydradx_runtime::RuntimeCall { let dot: Asset = Asset { id: cumulus_primitives_core::AssetId(DOT_ASSET_LOCATION.into()), - fun: Fungible(1 * UNITS), + fun: Fungible(UNITS), }; let bob_beneficiary = Location::new( @@ -195,7 +195,7 @@ fn xtokens_transfer_should_fail_when_lockdown_active_and_asset_is_egress() { let call = RuntimeCall::XTokens(orml_xtokens::Call::transfer { currency_id: HDX, - amount: 1 * UNITS, + amount: UNITS, dest: Box::new(bob_location.into_versioned()), dest_weight_limit: WeightLimit::Unlimited, }); @@ -238,7 +238,7 @@ fn on_charge_transaction_skips_global_withdraw_accounting_for_native_asset() { let call = RuntimeCall::System(frame_system::Call::remark { remark: vec![1, 2, 3] }); // Act - let fee_amount = 1 * UNITS; + let fee_amount = UNITS; let _ = ::OnChargeTransaction::withdraw_fee( &alice, &call, @@ -264,7 +264,7 @@ fn on_charge_transaction_skips_global_withdraw_accounting_for_native_asset() { Currencies::withdraw( HDX, &BOB.into(), - 1 * UNITS, + UNITS, frame_support::traits::ExistenceRequirement::AllowDeath ), pallet_circuit_breaker::Error::::WithdrawLockdownActive @@ -311,7 +311,7 @@ fn on_charge_transaction_skips_global_withdraw_accounting_for_external_asset() { let call = RuntimeCall::System(frame_system::Call::remark { remark: vec![1, 2, 3] }); // Act - let fee_amount = 1 * UNITS; + let fee_amount = UNITS; let _ = ::OnChargeTransaction::withdraw_fee( &alice, &call, @@ -337,7 +337,7 @@ fn on_charge_transaction_skips_global_withdraw_accounting_for_external_asset() { Currencies::withdraw( DOT, &ALICE.into(), - 1 * UNITS, + UNITS, frame_support::traits::ExistenceRequirement::AllowDeath ), pallet_circuit_breaker::Error::::WithdrawLockdownActive @@ -407,7 +407,7 @@ fn evm_on_charge_transaction_skips_global_withdraw_accounting() { Currencies::withdraw( WETH, &evm_account, - 1 * UNITS, + UNITS, frame_support::traits::ExistenceRequirement::AllowDeath ), pallet_circuit_breaker::Error::::WithdrawLockdownActive @@ -804,7 +804,7 @@ fn dot_external_limit_trigger_fails_then_decays_to_zero() { assert_ok!(AssetRegistry::set_location(DOT, DOT_ASSET_LOCATION)); let alice: AccountId = ALICE.into(); - let amount = 1 * UNITS; + let amount = UNITS; assert!( Currencies::free_balance(DOT, &alice) >= amount * 3, "Test requires Alice to have enough DOT" @@ -877,7 +877,7 @@ fn dot_external_lockdown_blocks_withdraw_but_regular_dot_transfer_still_works() let alice: AccountId = ALICE.into(); let bob: AccountId = BOB.into(); - let amount = 1 * UNITS; + let amount = UNITS; assert!(Currencies::free_balance(DOT, &alice) >= amount * 2); assert_eq!(CircuitBreaker::withdraw_limit_accumulator().0, 0); diff --git a/integration-tests/src/hsm.rs b/integration-tests/src/hsm.rs index 1935368ab..4fb75a5b7 100644 --- a/integration-tests/src/hsm.rs +++ b/integration-tests/src/hsm.rs @@ -2768,7 +2768,7 @@ fn arb_should_repeg_continuously_when_more_hollar_in_pool() { Some(state.fee), &state.pegs, ); - println!("Block: {:?}: spot: {:?}", block_idx, spot_price); + println!("Block: {block_idx:?}: spot: {spot_price:?}"); assert!(spot_price < last_spot_price); last_spot_price = spot_price; hydradx_run_to_next_block(); @@ -2955,7 +2955,7 @@ fn arb_should_repeg_continuously_when_more_hollar_in_pool_and_collateral_has_12_ Some(state.fee), &state.pegs, ); - println!("Block: {:?}: spot: {:?}", block_idx, spot_price); + println!("Block: {block_idx:?}: spot: {spot_price:?}"); assert!(spot_price < last_spot_price); last_spot_price = spot_price; hydradx_run_to_next_block(); diff --git a/integration-tests/src/liquidation.rs b/integration-tests/src/liquidation.rs index c3e6a727b..0ada91f58 100644 --- a/integration-tests/src/liquidation.rs +++ b/integration-tests/src/liquidation.rs @@ -530,8 +530,7 @@ fn assert_health_factor_is_within_tolerance(health_factor: U256, target_health_f // HF uses 18 decimal places assert!( health_factor_diff < U256::from(10).pow(15.into()), - "HF diff: {:?}", - health_factor_diff + "HF diff: {health_factor_diff:?}" ); } diff --git a/integration-tests/src/omnipool_add_all_liquidity.rs b/integration-tests/src/omnipool_add_all_liquidity.rs index 2647c2605..d1b17a90a 100644 --- a/integration-tests/src/omnipool_add_all_liquidity.rs +++ b/integration-tests/src/omnipool_add_all_liquidity.rs @@ -35,7 +35,7 @@ fn add_all_liquidity_should_work() { // circuit-breaker's per-block add-liquidity limit (5% of the pool's reserve). // The DOT pool reserve after add_token is ~87_719_298_250_000, so the limit is // ~4_385_964_912_500. We keep 1 * UNITS (1_000_000_000_000) for ALICE to deposit. - let keep_amount = 1 * UNITS; // 1 DOT — well within 5% of the pool + let keep_amount = UNITS; // 1 DOT — well within 5% of the pool let lp_balance = Currencies::free_balance(DOT, &lp); let transfer_away = lp_balance.saturating_sub(keep_amount); assert_ok!(Currencies::transfer( @@ -145,7 +145,7 @@ fn add_all_liquidity_position_matches_explicit_add_liquidity_with_limit() { // add-liquidity limit is 5%, so we stay well within it. let prepare_lp = || { let lp = AccountId::from(ALICE); - let keep = 1 * UNITS; + let keep = UNITS; let balance = Currencies::free_balance(DOT, &lp); let transfer_away = balance.saturating_sub(keep); if transfer_away > 0 { diff --git a/integration-tests/src/omnipool_fixed_fees.rs b/integration-tests/src/omnipool_fixed_fees.rs index 75394db8d..f4dce62a5 100644 --- a/integration-tests/src/omnipool_fixed_fees.rs +++ b/integration-tests/src/omnipool_fixed_fees.rs @@ -76,14 +76,9 @@ fn omnipool_fixed_fees_should_override_dynamic_fees() { // With 50% fixed fee, the received amount should be approximately half of the original let expected_half = hdx_received_dynamic / 2; let tolerance = hdx_received_dynamic / 10; // 10% tolerance - let difference = if hdx_received_fixed > expected_half { - hdx_received_fixed - expected_half - } else { - expected_half - hdx_received_fixed - }; + let difference = hdx_received_fixed.abs_diff(expected_half); assert!(difference <= tolerance, - "HDX received with 50% fee ({}) should be approximately half of dynamic fee amount ({}), expected around {}, tolerance: {}", - hdx_received_fixed, hdx_received_dynamic, expected_half, tolerance); + "HDX received with 50% fee ({hdx_received_fixed}) should be approximately half of dynamic fee amount ({hdx_received_dynamic}), expected around {expected_half}, tolerance: {tolerance}"); let asset_state = hydradx_runtime::Omnipool::load_asset_state(ASSET_ID_TO_TEST).unwrap(); let current_fees = pallet_dynamic_fees::UpdateAndRetrieveFees::::get((ASSET_ID_TO_TEST, asset_state.reserve)); diff --git a/integration-tests/src/omnipool_slip_fees.rs b/integration-tests/src/omnipool_slip_fees.rs index fbe446b1a..e50a81137 100644 --- a/integration-tests/src/omnipool_slip_fees.rs +++ b/integration-tests/src/omnipool_slip_fees.rs @@ -72,9 +72,7 @@ fn sell_with_slip_fees_gives_less_output_than_without() { assert!( output_with_slip < output_no_slip, - "Slip fee should reduce sell output: no_slip={} with_slip={}", - output_no_slip, - output_with_slip + "Slip fee should reduce sell output: no_slip={output_no_slip} with_slip={output_with_slip}" ); } @@ -147,9 +145,7 @@ fn buy_with_slip_fees_costs_more_than_without() { assert!( cost_with_slip > cost_no_slip, - "Slip fee should increase buy cost: no_slip={} with_slip={}", - cost_no_slip, - cost_with_slip + "Slip fee should increase buy cost: no_slip={cost_no_slip} with_slip={cost_with_slip}" ); } @@ -206,9 +202,7 @@ fn sell_lrna_with_slip_fees_gives_less_output_than_without() { assert!( output_with_slip < output_no_slip, - "Slip fee should reduce LRNA sell output: no_slip={} with_slip={}", - output_no_slip, - output_with_slip + "Slip fee should reduce LRNA sell output: no_slip={output_no_slip} with_slip={output_with_slip}" ); } @@ -265,9 +259,7 @@ fn buy_with_lrna_with_slip_fees_costs_more_than_without() { assert!( cost_with_slip > cost_no_slip, - "Slip fee should increase LRNA buy cost: no_slip={} with_slip={}", - cost_no_slip, - cost_with_slip + "Slip fee should increase LRNA buy cost: no_slip={cost_no_slip} with_slip={cost_with_slip}" ); } @@ -340,18 +332,14 @@ fn slip_fee_deltas_are_cleared_across_blocks() { // Slip fees are active: first trade gives less than no-slip baseline assert!( first_output < output_no_slip, - "Slip fee should reduce output: no_slip={} with_slip={}", - output_no_slip, - first_output + "Slip fee should reduce output: no_slip={output_no_slip} with_slip={first_output}" ); // After delta clearing, output should be close to first trade (no accumulated penalty). // Pool state changed slightly from the first trade, but the slip fee restarts from zero. assert!( cleared_output >= first_output * 99 / 100, - "Cleared trade should not suffer accumulated slip penalty: first={} cleared={}", - first_output, - cleared_output + "Cleared trade should not suffer accumulated slip penalty: first={first_output} cleared={cleared_output}" ); } @@ -432,9 +420,7 @@ fn sequential_trades_accumulate_slip_within_block() { // Basic: second trade gets less output in both cases assert!( slip_second < slip_first, - "Second trade should get less output due to accumulated slip: first={} second={}", - slip_first, - slip_second + "Second trade should get less output due to accumulated slip: first={slip_first} second={slip_second}" ); // The drop between first and second trade should be LARGER with slip fees than without. @@ -444,8 +430,6 @@ fn sequential_trades_accumulate_slip_within_block() { let slip_drop = slip_first - slip_second; assert!( slip_drop > no_slip_drop, - "Slip fees should cause a larger drop between sequential trades: slip_drop={} no_slip_drop={}", - slip_drop, - no_slip_drop + "Slip fees should cause a larger drop between sequential trades: slip_drop={slip_drop} no_slip_drop={no_slip_drop}" ); } diff --git a/integration-tests/src/omnipool_slip_fees_xval.rs b/integration-tests/src/omnipool_slip_fees_xval.rs index 9aae067fc..4d968467d 100644 --- a/integration-tests/src/omnipool_slip_fees_xval.rs +++ b/integration-tests/src/omnipool_slip_fees_xval.rs @@ -23,19 +23,10 @@ fn enable_slip_fees() { /// Assert that `actual` is within `tolerance` of `expected`. fn assert_approx(actual: u128, expected: u128, tolerance: u128, label: &str) { - let diff = if actual >= expected { - actual - expected - } else { - expected - actual - }; + let diff = actual.abs_diff(expected); assert!( diff <= tolerance, - "{}: rust={} python={} diff={} tolerance={}", - label, - actual, - expected, - diff, - tolerance + "{label}: rust={actual} python={expected} diff={diff} tolerance={tolerance}" ); } @@ -64,9 +55,9 @@ fn dump_pool_state_and_fees() { let dai_reserve = Currencies::free_balance(DAI, &Omnipool::protocol_account()); println!("=== POOL STATE ==="); - println!("HDX reserve: {}", hdx_reserve); + println!("HDX reserve: {hdx_reserve}"); println!("HDX hub_reserve: {}", hdx_state.hub_reserve); - println!("DAI reserve: {}", dai_reserve); + println!("DAI reserve: {dai_reserve}"); println!("DAI hub_reserve: {}", dai_state.hub_reserve); let (hdx_asset_fee, hdx_protocol_fee) = @@ -74,8 +65,8 @@ fn dump_pool_state_and_fees() { let (dai_asset_fee, dai_protocol_fee) = pallet_dynamic_fees::UpdateAndRetrieveFees::::get((DAI, dai_state.reserve)); - println!("HDX asset_fee={:?} protocol_fee={:?}", hdx_asset_fee, hdx_protocol_fee); - println!("DAI asset_fee={:?} protocol_fee={:?}", dai_asset_fee, dai_protocol_fee); + println!("HDX asset_fee={hdx_asset_fee:?} protocol_fee={hdx_protocol_fee:?}"); + println!("DAI asset_fee={dai_asset_fee:?} protocol_fee={dai_protocol_fee:?}"); }); } @@ -168,9 +159,7 @@ fn xval_single_buy() { // Slip fees must increase cost vs baseline assert!( hdx_spent > cost_no_slip, - "Slip fee should increase buy cost: with_slip={} no_slip={}", - hdx_spent, - cost_no_slip + "Slip fee should increase buy cost: with_slip={hdx_spent} no_slip={cost_no_slip}" ); } @@ -340,9 +329,7 @@ fn xval_multiple_buys_same_direction() { let slip_total = trade1_cost + trade2_cost; assert!( slip_total > no_slip_total, - "Slip fees should increase total buy cost: with_slip={} no_slip={}", - slip_total, - no_slip_total + "Slip fees should increase total buy cost: with_slip={slip_total} no_slip={no_slip_total}" ); } @@ -432,15 +419,11 @@ fn xval_multiple_buys_opposite_direction() { // Slip fees must increase costs vs baseline assert!( trade1_cost > no_slip_trade1, - "Slip fee should increase trade1 cost: with_slip={} no_slip={}", - trade1_cost, - no_slip_trade1 + "Slip fee should increase trade1 cost: with_slip={trade1_cost} no_slip={no_slip_trade1}" ); assert!( trade2_cost > no_slip_trade2, - "Slip fee should increase trade2 cost: with_slip={} no_slip={}", - trade2_cost, - no_slip_trade2 + "Slip fee should increase trade2 cost: with_slip={trade2_cost} no_slip={no_slip_trade2}" ); } @@ -550,9 +533,7 @@ fn xval_mixed_trades() { // Slip fees must reduce trade 1 output vs no-slip baseline assert!( t1 < t1_no_slip, - "Slip fee should reduce trade1 output: no_slip={} with_slip={}", - t1_no_slip, - t1 + "Slip fee should reduce trade1 output: no_slip={t1_no_slip} with_slip={t1}" ); }); } @@ -735,9 +716,7 @@ fn xval_sell_lrna_for_dai_with_prior_delta() { let py_fresh: u128 = 2035714285714285714285; assert!( t2_dai < py_fresh, - "Prior delta should reduce sell_lrna output: {} < {}", - t2_dai, - py_fresh + "Prior delta should reduce sell_lrna output: {t2_dai} < {py_fresh}" ); }); } @@ -785,9 +764,7 @@ fn xval_buy_dai_with_lrna_after_prior_sell() { let py_fresh_cost: u128 = 4511278; assert!( t2_lrna_cost >= py_fresh_cost, - "Prior delta should increase buy_lrna cost: {} >= {}", - t2_lrna_cost, - py_fresh_cost + "Prior delta should increase buy_lrna cost: {t2_lrna_cost} >= {py_fresh_cost}" ); }); } diff --git a/integration-tests/src/oracle.rs b/integration-tests/src/oracle.rs index 81c248b5e..7f1d24203 100644 --- a/integration-tests/src/oracle.rs +++ b/integration-tests/src/oracle.rs @@ -65,8 +65,7 @@ fn oracle_smoothing_period_matches_configuration() { let smoothing_from_period = smoothing_from_period(configured_length); assert_eq!( configured_smoothing, smoothing_from_period, - "Smoothing period for {:?} does not match configured length of {:?}", - supported_period, configured_length, + "Smoothing period for {supported_period:?} does not match configured length of {configured_length:?}", ); } } diff --git a/integration-tests/src/polkadot_test_net.rs b/integration-tests/src/polkadot_test_net.rs index 4bccb2359..755f56be7 100644 --- a/integration-tests/src/polkadot_test_net.rs +++ b/integration-tests/src/polkadot_test_net.rs @@ -336,7 +336,7 @@ pub mod rococo { /// Helper function to generate a crypto pair from seed fn get_from_seed(seed: &str) -> ::Public { - TPublic::Pair::from_string(&format!("//{}", seed), None) + TPublic::Pair::from_string(&format!("//{seed}"), None) .expect("static values are valid; qed") .public() } @@ -396,7 +396,7 @@ pub mod rococo { AuthorityDiscoveryId, ) { ( - get_account_id_from_seed::(&format!("{}//stash", seed)), + get_account_id_from_seed::(&format!("{seed}//stash")), get_account_id_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), @@ -463,7 +463,7 @@ type AccountPublic = ::Signer; /// Helper function to generate a crypto pair from seed fn get_from_seed(seed: &str) -> ::Public { - TPublic::Pair::from_string(&format!("//{}", seed), None) + TPublic::Pair::from_string(&format!("//{seed}"), None) .expect("static values are valid; qed") .public() } @@ -896,7 +896,7 @@ pub fn hydradx_run_to_next_block() { pub fn hydradx_run_to_block(to: BlockNumber) { let b = hydradx_runtime::System::block_number(); - assert!(b <= to, "the current block number {:?} is higher than expected.", b); + assert!(b <= to, "the current block number {b:?} is higher than expected."); if b < to { go_to_block(to); diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index e8d107d02..b21febc49 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -5320,11 +5320,7 @@ mod route_spot_price { .unwrap() .checked_mul_int(amount_to_sell) .unwrap(); - let difference = if expected_amount_out > calculated_amount_out { - expected_amount_out - calculated_amount_out - } else { - calculated_amount_out - expected_amount_out - }; + let difference = expected_amount_out.abs_diff(calculated_amount_out); let relative_difference = FixedU128::from_rational(difference, expected_amount_out); let tolerated_difference = FixedU128::from_rational(1, 100); // The difference of the amount out calculated with spot price should be less than 1% @@ -5391,11 +5387,7 @@ mod route_spot_price { .unwrap() .checked_mul_int(amount_to_sell) .unwrap(); - let difference = if expected_amount_out > calculated_amount_out { - expected_amount_out - calculated_amount_out - } else { - calculated_amount_out - expected_amount_out - }; + let difference = expected_amount_out.abs_diff(calculated_amount_out); let relative_difference = FixedU128::from_rational(difference, expected_amount_out); let tolerated_difference = FixedU128::from_rational(1, 100); // The difference of the amount out calculated with spot price should be less than 1% diff --git a/integration-tests/src/stableswap_curve_comparison.rs b/integration-tests/src/stableswap_curve_comparison.rs index 541eba715..2605c4f64 100644 --- a/integration-tests/src/stableswap_curve_comparison.rs +++ b/integration-tests/src/stableswap_curve_comparison.rs @@ -320,20 +320,12 @@ fn assert_parity(label: &str, hydra: u128, curve: u128, max_tolerance: u128, exp let diff = hydra.abs_diff(curve); assert!( diff <= max_tolerance, - "{}: diff {} exceeds tolerance {} (hydra={}, curve={})", - label, - diff, - max_tolerance, - hydra, - curve + "{label}: diff {diff} exceeds tolerance {max_tolerance} (hydra={hydra}, curve={curve})" ); if expect_hydra_gte { assert!( hydra >= curve, - "{}: expected hydra ({}) >= curve ({})", - label, - hydra, - curve + "{label}: expected hydra ({hydra}) >= curve ({curve})" ); } } @@ -345,14 +337,7 @@ fn assert_parity_with_fee(label: &str, hydra: u128, curve: u128, max_abs_toleran let tolerance = max_abs_tolerance.max(relative_tolerance); assert!( diff <= tolerance, - "{}: diff {} exceeds tolerance {} (abs={}, rel={}) (hydra={}, curve={})", - label, - diff, - tolerance, - max_abs_tolerance, - relative_tolerance, - hydra, - curve + "{label}: diff {diff} exceeds tolerance {tolerance} (abs={max_abs_tolerance}, rel={relative_tolerance}) (hydra={hydra}, curve={curve})" ); } @@ -763,7 +748,7 @@ fn run_shares_with_fee_comparison( let hydra_shares = hydra_calc_shares(old, new, amp, supply, fee); assert_parity_with_fee( - &format!("{} fee={:?}", label, fee), + &format!("{label} fee={fee:?}"), hydra_shares, curve_shares, MAX_SHARE_TOLERANCE, @@ -960,13 +945,13 @@ fn run_withdraw_with_fee_comparison( hydra_calc_withdraw_one_asset(balances, withdraw_shares, i, total_supply, amp, fee); assert_parity_with_fee( - &format!("{} withdraw amount", label), + &format!("{label} withdraw amount"), hydra_dy, curve_dy, MAX_SWAP_TOLERANCE, ); assert_parity_with_fee( - &format!("{} withdraw fee", label), + &format!("{label} withdraw fee"), hydra_fee_amount, curve_fee_amount, MAX_SWAP_TOLERANCE, diff --git a/integration-tests/src/utils/contracts.rs b/integration-tests/src/utils/contracts.rs index a14a2d4ac..f96b1cf7f 100644 --- a/integration-tests/src/utils/contracts.rs +++ b/integration-tests/src/utils/contracts.rs @@ -8,8 +8,7 @@ use std::fs; pub fn get_contract_bytecode(name: &str) -> Vec { let path = format!( - "../scripts/test-contracts/artifacts/contracts/{}.sol/{}.json", - name, name + "../scripts/test-contracts/artifacts/contracts/{name}.sol/{name}.json" ); let str = fs::read_to_string(path).unwrap(); let json: serde_json::Value = serde_json::from_str(&str).unwrap(); @@ -38,7 +37,7 @@ pub fn deploy_contract_code(code: Vec, deployer: EvmAddress) -> EvmAddress { let address = match info.clone().unwrap().exit_reason { ExitReason::Succeed(_) => info.unwrap().value, - reason => panic!("{:?}", reason), + reason => panic!("{reason:?}"), }; let deployed = hydradx_runtime::Runtime::account_code_at(address); diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs index cc19aaeb8..9ed342314 100644 --- a/pallets/synthetic-logs/src/lib.rs +++ b/pallets/synthetic-logs/src/lib.rs @@ -87,10 +87,10 @@ impl Pallet { let bucket = Self::current_bucket(); Pending::::mutate(|v| { if v.len() as u32 >= MAX_PENDING_LOGS { + let n = v.len(); log::warn!( target: "runtime::synthetic-logs", - "pending buffer full ({} entries); dropping log for {:?}", - v.len(), emitter, + "pending buffer full ({n} entries); dropping log for {emitter:?}", ); return; } @@ -126,81 +126,17 @@ impl Pallet { None => groups.push((bucket, vec![log])), } } - groups.sort_by(|a, b| Self::bucket_sort_key(&a.0).cmp(&Self::bucket_sort_key(&b.0))); + + groups.sort_by(|a, b| bucket_sort_key(&a.0).cmp(&bucket_sort_key(&b.0))); for (idx, (bucket, logs)) in groups.into_iter().enumerate() { Self::insert_synth_tx(bucket, logs, idx as u32); } } - // 0=init hooks, 1=extrinsics (by index), 2=finalize hooks — preserves wall-clock order. - fn bucket_sort_key(bucket: &Bucket) -> (u8, u64) { - match bucket { - Bucket::Hook { - phase: HookPhase::Initialization, - origin: None, - } => (0, 0), - Bucket::Hook { - phase: HookPhase::Initialization, - origin: Some(_), - } => (0, Self::bucket_nonce(*bucket)), - Bucket::Extrinsic(i) => (1, *i as u64), - Bucket::Hook { - phase: HookPhase::Finalization, - origin: None, - } => (2, 0), - Bucket::Hook { - phase: HookPhase::Finalization, - origin: Some(_), - } => (2, Self::bucket_nonce(*bucket)), - } - } - - /// Encodes the bucket as the synthetic tx's `nonce`, so indexers can - /// reverse the synth tx back to its substrate origin. - /// - /// Layout: - /// Extrinsic(i) → i (low) - /// Hook { phase: Init, origin: None } → MAX - 3 - /// Hook { phase: Init, origin: Some(t) } → 0xDCA0… | tag(t) - /// Hook { phase: Final, origin: None } → MAX - 2 - /// Hook { phase: Final, origin: Some(t) } → 0xF1A1… | tag(t) - pub fn bucket_nonce(bucket: Bucket) -> u64 { - match bucket { - Bucket::Extrinsic(i) => i as u64, - Bucket::Hook { - phase: HookPhase::Initialization, - origin: None, - } => u64::MAX - 3, - Bucket::Hook { - phase: HookPhase::Initialization, - origin: Some(o), - } => 0xDCA0_0000_0000_0000u64 | Self::origin_tag(&o), - Bucket::Hook { - phase: HookPhase::Finalization, - origin: None, - } => u64::MAX - 2, - Bucket::Hook { - phase: HookPhase::Finalization, - origin: Some(o), - } => 0xF1A1_0000_0000_0000u64 | Self::origin_tag(&o), - } - } - - fn origin_tag(origin: &ExecutionType) -> u64 { - match origin { - ExecutionType::Router(id) => 0x01_00_0000_0000 | (*id as u64), - ExecutionType::DCA(schedule_id, _) => 0x02_00_0000_0000 | (*schedule_id as u64), - ExecutionType::Batch(id) => 0x03_00_0000_0000 | (*id as u64), - ExecutionType::Omnipool(id) => 0x04_00_0000_0000 | (*id as u64), - ExecutionType::XcmExchange(id) => 0x05_00_0000_0000 | (*id as u64), - ExecutionType::Xcm(_, id) => 0x06_00_0000_0000 | (*id as u64), - } - } - fn insert_synth_tx(bucket: Bucket, logs: Vec, group_index: u32) { let chain_id = ::ChainId::get(); - let nonce = Self::bucket_nonce(bucket); + let nonce = bucket_nonce(bucket); let signature = ethereum::eip2930::TransactionSignature::new(false, SYNTH_SIG_RS, SYNTH_SIG_RS) .expect("synthetic signature constants are within valid ECDSA range; qed"); @@ -303,3 +239,67 @@ pub fn encode_uint256_quad(a: U256, b: U256, c: U256, d: U256) -> Vec { data.extend_from_slice(&encode_u256_be(d)); data } + +// 0=init hooks, 1=extrinsics (by index), 2=finalize hooks — preserves wall-clock order. +fn bucket_sort_key(bucket: &Bucket) -> (u8, u64) { + match bucket { + Bucket::Hook { + phase: HookPhase::Initialization, + origin: None, + } => (0, 0), + Bucket::Hook { + phase: HookPhase::Initialization, + origin: Some(_), + } => (0, bucket_nonce(*bucket)), + Bucket::Extrinsic(i) => (1, *i as u64), + Bucket::Hook { + phase: HookPhase::Finalization, + origin: None, + } => (2, 0), + Bucket::Hook { + phase: HookPhase::Finalization, + origin: Some(_), + } => (2, bucket_nonce(*bucket)), + } +} + +/// `nonce` field on the synth tx. lets indexers reverse a synth tx to its origin. +/// +/// layout: +/// Extrinsic(i) → i (low) +/// Hook { Init, None } → MAX - 3 +/// Hook { Init, Some(t) } → 0xDCA0… | tag(t) +/// Hook { Final, None } → MAX - 2 +/// Hook { Final, Some(t) } → 0xF1A1… | tag(t) +pub fn bucket_nonce(bucket: Bucket) -> u64 { + match bucket { + Bucket::Extrinsic(i) => i as u64, + Bucket::Hook { + phase: HookPhase::Initialization, + origin: None, + } => u64::MAX - 3, + Bucket::Hook { + phase: HookPhase::Initialization, + origin: Some(o), + } => 0xDCA0_0000_0000_0000u64 | origin_tag(&o), + Bucket::Hook { + phase: HookPhase::Finalization, + origin: None, + } => u64::MAX - 2, + Bucket::Hook { + phase: HookPhase::Finalization, + origin: Some(o), + } => 0xF1A1_0000_0000_0000u64 | origin_tag(&o), + } +} + +fn origin_tag(origin: &ExecutionType) -> u64 { + match origin { + ExecutionType::Router(id) => 0x0100_0000_0000 | (*id as u64), + ExecutionType::DCA(schedule_id, _) => 0x0200_0000_0000 | (*schedule_id as u64), + ExecutionType::Batch(id) => 0x0300_0000_0000 | (*id as u64), + ExecutionType::Omnipool(id) => 0x0400_0000_0000 | (*id as u64), + ExecutionType::XcmExchange(id) => 0x0500_0000_0000 | (*id as u64), + ExecutionType::Xcm(_, id) => 0x0600_0000_0000 | (*id as u64), + } +} diff --git a/pallets/synthetic-logs/src/tests.rs b/pallets/synthetic-logs/src/tests.rs index 81cce0074..c3d5c7fa0 100644 --- a/pallets/synthetic-logs/src/tests.rs +++ b/pallets/synthetic-logs/src/tests.rs @@ -65,4 +65,166 @@ fn known_topic_constants_match_expected_keccak256() { 0xce, 0x37, 0x65, 0x7f, 0xb8, 0xd5, 0xe3, 0xd1, 0x30, 0x84, 0x01, 0x59, 0xd8, 0x22, ]; assert_eq!(SWAP_TOPIC.0, expected_swap); + + // ERC-20 Approval(address,address,uint256) + let expected_approval = [ + 0x8c, 0x5b, 0xe1, 0xe5, 0xeb, 0xec, 0x7d, 0x5b, 0xd1, 0x4f, 0x71, 0x42, 0x7d, 0x1e, 0x84, 0xf3, 0xdd, 0x03, + 0x14, 0xc0, 0xf7, 0xb2, 0x29, 0x1e, 0x5b, 0x20, 0x0a, 0xc8, 0xc7, 0xc3, 0xb9, 0x25, + ]; + assert_eq!(APPROVAL_TOPIC.0, expected_approval); +} + +#[test] +fn reserved_address_of_is_reversible() { + let owner = H160([ + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, + 0xbb, 0xcc, + ]); + let sentinel = reserved_address_of(owner); + assert_ne!(owner, sentinel); + assert_eq!(reserved_address_of(sentinel), owner, "xor with 0xEE is its own inverse"); } + +// Two synth txs sharing the same bucket-nonce class but different group_index +// must have distinct canonical envelope hashes — frontier indexes by hash, so +// a collision would mean one synth tx shadows the other in eth_getTransactionByHash. +#[test] +fn synth_envelope_hash_is_unique_per_group_index() { + use crate::Transaction; + use ethereum::{eip2930::TransactionSignature, EIP1559Transaction, TransactionAction}; + + let signature = TransactionSignature::new(false, SYNTH_SIG_RS, SYNTH_SIG_RS).expect("synth sig in range"); + let mk = |group_index: u32, nonce: u64| { + Transaction::EIP1559(EIP1559Transaction { + chain_id: 222_222, + nonce: U256::from(nonce), + max_priority_fee_per_gas: U256::zero(), + max_fee_per_gas: U256::zero(), + gas_limit: U256::zero(), + action: TransactionAction::Call(SENTINEL_ADDRESS), + value: U256::from(group_index), + input: Vec::new(), + access_list: Vec::new(), + signature: signature.clone(), + }) + }; + + // same nonce (same bucket-nonce class) but different group_index → distinct hashes + let nonce = u64::MAX - 3; // Hook { Init, None } + assert_ne!(mk(0, nonce).hash(), mk(1, nonce).hash()); + assert_ne!(mk(0, nonce).hash(), mk(2, nonce).hash()); + assert_ne!(mk(1, nonce).hash(), mk(2, nonce).hash()); + + // determinism: same (group_index, nonce) → same hash + assert_eq!(mk(7, 42).hash(), mk(7, 42).hash()); +} + +// Bucket grouping must (a) collapse repeated (bucket, log) entries from the +// same bucket into one group, and (b) sort init < extrinsic < finalize. +#[test] +fn flush_bucket_grouping_and_sort_order() { + use pallet_broadcast::types::ExecutionType; + + // Bare grouping helper that mirrors `flush`'s grouping step (without + // driving the full pallet runtime). We test the visible invariants: + // 1. preserves insertion order within a bucket + // 2. produces one group per distinct bucket + let entries: Vec<(Bucket, ethereum::Log)> = vec![ + (Bucket::Extrinsic(2), log(1)), + ( + Bucket::Hook { + phase: HookPhase::Initialization, + origin: None, + }, + log(2), + ), + (Bucket::Extrinsic(2), log(3)), + ( + Bucket::Hook { + phase: HookPhase::Finalization, + origin: None, + }, + log(4), + ), + (Bucket::Extrinsic(0), log(5)), + ( + Bucket::Hook { + phase: HookPhase::Initialization, + origin: Some(ExecutionType::DCA(7, 1)), + }, + log(6), + ), + ]; + + let mut groups: Vec<(Bucket, Vec)> = Vec::new(); + for (bucket, log) in entries { + match groups.iter_mut().find(|(b, _)| *b == bucket) { + Some((_, logs)) => logs.push(log), + None => groups.push((bucket, vec![log])), + } + } + groups.sort_by(|a, b| bucket_sort_key(&a.0).cmp(&bucket_sort_key(&b.0))); + + // 5 distinct buckets, in order: Init/None < Init/DCA < Extrinsic(0) < Extrinsic(2) < Final/None + let order: Vec = groups.iter().map(|(b, _)| *b).collect(); + assert!(matches!(order[0], Bucket::Hook { phase: HookPhase::Initialization, origin: None })); + assert!(matches!( + order[1], + Bucket::Hook { + phase: HookPhase::Initialization, + origin: Some(ExecutionType::DCA(_, _)) + } + )); + assert!(matches!(order[2], Bucket::Extrinsic(0))); + assert!(matches!(order[3], Bucket::Extrinsic(2))); + assert!(matches!(order[4], Bucket::Hook { phase: HookPhase::Finalization, origin: None })); + + // Extrinsic(2) holds both its logs in insertion order. + let ext2_logs = &groups + .iter() + .find(|(b, _)| matches!(b, Bucket::Extrinsic(2))) + .unwrap() + .1; + assert_eq!(ext2_logs.len(), 2); + assert_eq!(ext2_logs[0].address.0[19], 1); + assert_eq!(ext2_logs[1].address.0[19], 3); +} + +#[test] +fn bucket_nonce_layout_is_distinct_per_class() { + use pallet_broadcast::types::ExecutionType; + let cases = [ + Bucket::Extrinsic(0), + Bucket::Extrinsic(7), + Bucket::Hook { + phase: HookPhase::Initialization, + origin: None, + }, + Bucket::Hook { + phase: HookPhase::Initialization, + origin: Some(ExecutionType::DCA(123, 1)), + }, + Bucket::Hook { + phase: HookPhase::Finalization, + origin: None, + }, + Bucket::Hook { + phase: HookPhase::Finalization, + origin: Some(ExecutionType::Router(99)), + }, + ]; + let nonces: Vec = cases.iter().map(|b| bucket_nonce(*b)).collect(); + let unique: std::collections::BTreeSet<_> = nonces.iter().collect(); + assert_eq!(unique.len(), cases.len(), "every bucket class must produce a distinct nonce"); +} + +fn log(tag: u8) -> ethereum::Log { + let mut addr = [0u8; 20]; + addr[19] = tag; + ethereum::Log { + address: H160(addr), + topics: vec![TRANSFER_TOPIC], + data: Vec::new(), + } +} + diff --git a/runtime/hydradx/src/evm/runner.rs b/runtime/hydradx/src/evm/runner.rs index 3856f9aa0..f5c0a01e6 100644 --- a/runtime/hydradx/src/evm/runner.rs +++ b/runtime/hydradx/src/evm/runner.rs @@ -53,7 +53,7 @@ mod evm_frame_logs { } pub fn drain() -> Vec { - EVM_FRAME_LOGS::with(|buf| sp_std::mem::take(buf)).unwrap_or_default() + EVM_FRAME_LOGS::with(sp_std::mem::take).unwrap_or_default() } } diff --git a/runtime/hydradx/src/evm/swap_logs.rs b/runtime/hydradx/src/evm/swap_logs.rs index ff7dd5743..4d0e68e1c 100644 --- a/runtime/hydradx/src/evm/swap_logs.rs +++ b/runtime/hydradx/src/evm/swap_logs.rs @@ -77,8 +77,7 @@ impl OnTrade for EmitUniswapV2SwapLog { if is_asset_address(pool_address) { log::warn!( target: "runtime::synthetic-logs", - "pool address collides with erc20 prefix; skipping swap log for filler {:?}", - filler, + "pool address collides with erc20 prefix; skipping swap log for filler {filler:?}", ); return; } From a10fefa8e27aa2f5acafeccb7094bb614c951504 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 05:06:33 +0200 Subject: [PATCH 16/17] bumps --- Cargo.lock | 74 ++++++++++---------- integration-tests/Cargo.toml | 2 +- pallets/circuit-breaker/Cargo.toml | 2 +- pallets/claims/Cargo.toml | 2 +- pallets/collator-rewards/Cargo.toml | 2 +- pallets/currencies/Cargo.toml | 2 +- pallets/dca/Cargo.toml | 2 +- pallets/democracy/Cargo.toml | 2 +- pallets/dispenser/Cargo.toml | 2 +- pallets/duster/Cargo.toml | 2 +- pallets/dynamic-evm-fee/Cargo.toml | 2 +- pallets/evm-accounts/Cargo.toml | 2 +- pallets/hsm/Cargo.toml | 2 +- pallets/lbp/Cargo.toml | 2 +- pallets/liquidation/Cargo.toml | 2 +- pallets/liquidity-mining/Cargo.toml | 2 +- pallets/nft/Cargo.toml | 2 +- pallets/omnipool-liquidity-mining/Cargo.toml | 2 +- pallets/omnipool/Cargo.toml | 2 +- pallets/otc-settlements/Cargo.toml | 2 +- pallets/otc/Cargo.toml | 2 +- pallets/route-executor/Cargo.toml | 2 +- pallets/signet/Cargo.toml | 2 +- pallets/stableswap/Cargo.toml | 2 +- pallets/staking/Cargo.toml | 2 +- pallets/transaction-multi-payment/Cargo.toml | 2 +- pallets/transaction-pause/Cargo.toml | 2 +- pallets/xyk-liquidity-mining/Cargo.toml | 2 +- pallets/xyk/Cargo.toml | 2 +- precompiles/call-permit/Cargo.toml | 2 +- runtime/adapters/Cargo.toml | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- 33 files changed, 69 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 496d38ba9..cd4eda9e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6322,7 +6322,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.13.1" +version = "1.13.2" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -6357,7 +6357,7 @@ dependencies = [ "pallet-referrals", "pallet-route-executor", "pallet-stableswap", - "pallet-staking 4.3.1", + "pallet-staking 4.3.2", "pallet-timestamp", "pallet-transaction-multi-payment", "pallet-uniques", @@ -6379,7 +6379,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "416.0.0" +version = "413.0.0" dependencies = [ "alloy-primitives 0.7.7", "alloy-sol-types 0.7.7", @@ -6446,7 +6446,7 @@ dependencies = [ "pallet-currencies", "pallet-currencies-rpc-runtime-api", "pallet-dca", - "pallet-democracy 4.5.0", + "pallet-democracy 4.5.1", "pallet-dispatcher", "pallet-dispenser", "pallet-duster", @@ -6494,7 +6494,7 @@ dependencies = [ "pallet-session", "pallet-signet", "pallet-stableswap", - "pallet-staking 4.3.1", + "pallet-staking 4.3.2", "pallet-state-trie-migration", "pallet-synthetic-logs", "pallet-timestamp", @@ -9827,7 +9827,7 @@ dependencies = [ [[package]] name = "pallet-circuit-breaker" -version = "1.6.3" +version = "1.6.4" dependencies = [ "frame-benchmarking", "frame-support", @@ -9856,7 +9856,7 @@ dependencies = [ [[package]] name = "pallet-claims" -version = "3.6.0" +version = "3.6.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -9878,7 +9878,7 @@ dependencies = [ [[package]] name = "pallet-collator-rewards" -version = "1.3.0" +version = "1.3.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -10085,7 +10085,7 @@ dependencies = [ [[package]] name = "pallet-currencies" -version = "4.1.1" +version = "4.1.2" dependencies = [ "frame-support", "frame-system", @@ -10117,7 +10117,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.18.1" +version = "1.18.2" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -10174,7 +10174,7 @@ dependencies = [ [[package]] name = "pallet-democracy" -version = "4.5.0" +version = "4.5.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -10248,7 +10248,7 @@ dependencies = [ [[package]] name = "pallet-dispenser" -version = "0.4.0" +version = "0.4.1" dependencies = [ "alloy-primitives 0.7.7", "alloy-sol-types 0.7.7", @@ -10297,7 +10297,7 @@ dependencies = [ [[package]] name = "pallet-duster" -version = "3.8.0" +version = "3.8.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -10330,7 +10330,7 @@ dependencies = [ [[package]] name = "pallet-dynamic-evm-fee" -version = "1.3.0" +version = "1.3.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -10527,7 +10527,7 @@ dependencies = [ [[package]] name = "pallet-evm-accounts" -version = "1.6.1" +version = "1.6.2" dependencies = [ "frame-benchmarking", "frame-support", @@ -10587,7 +10587,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-call-permit" -version = "0.3.0" +version = "0.3.1" dependencies = [ "derive_more 0.99.20", "evm", @@ -10749,7 +10749,7 @@ dependencies = [ [[package]] name = "pallet-hsm" -version = "1.7.0" +version = "1.7.1" dependencies = [ "ethabi", "evm", @@ -10916,7 +10916,7 @@ dependencies = [ [[package]] name = "pallet-lbp" -version = "4.13.0" +version = "4.13.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -10942,7 +10942,7 @@ dependencies = [ [[package]] name = "pallet-liquidation" -version = "2.4.2" +version = "2.4.3" dependencies = [ "ethabi", "ethereum", @@ -10989,7 +10989,7 @@ dependencies = [ [[package]] name = "pallet-liquidity-mining" -version = "4.7.0" +version = "4.7.1" dependencies = [ "fixed", "frame-support", @@ -11137,7 +11137,7 @@ dependencies = [ [[package]] name = "pallet-nft" -version = "7.3.0" +version = "7.3.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -11303,7 +11303,7 @@ dependencies = [ [[package]] name = "pallet-omnipool" -version = "7.3.1" +version = "7.3.2" dependencies = [ "bitflags 1.3.2", "frame-benchmarking", @@ -11332,7 +11332,7 @@ dependencies = [ [[package]] name = "pallet-omnipool-liquidity-mining" -version = "3.4.0" +version = "3.4.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -11381,7 +11381,7 @@ dependencies = [ [[package]] name = "pallet-otc" -version = "2.4.0" +version = "2.4.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -11404,7 +11404,7 @@ dependencies = [ [[package]] name = "pallet-otc-settlements" -version = "1.4.1" +version = "1.4.2" dependencies = [ "frame-benchmarking", "frame-support", @@ -11731,7 +11731,7 @@ dependencies = [ [[package]] name = "pallet-route-executor" -version = "2.12.0" +version = "2.12.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -11851,7 +11851,7 @@ dependencies = [ [[package]] name = "pallet-signet" -version = "1.3.0" +version = "1.3.1" dependencies = [ "ethereum", "frame-benchmarking", @@ -11898,7 +11898,7 @@ dependencies = [ [[package]] name = "pallet-stableswap" -version = "7.3.0" +version = "7.3.1" dependencies = [ "bitflags 1.3.2", "frame-benchmarking", @@ -11931,7 +11931,7 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "4.3.1" +version = "4.3.2" dependencies = [ "frame-benchmarking", "frame-support", @@ -11942,7 +11942,7 @@ dependencies = [ "orml-traits", "pallet-balances", "pallet-conviction-voting", - "pallet-democracy 4.5.0", + "pallet-democracy 4.5.1", "pallet-referenda", "pallet-uniques", "parity-scale-codec", @@ -12202,7 +12202,7 @@ dependencies = [ [[package]] name = "pallet-transaction-multi-payment" -version = "10.5.0" +version = "10.5.1" dependencies = [ "frame-support", "frame-system", @@ -12230,7 +12230,7 @@ dependencies = [ [[package]] name = "pallet-transaction-pause" -version = "1.3.0" +version = "1.3.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -12498,7 +12498,7 @@ dependencies = [ [[package]] name = "pallet-xyk" -version = "8.2.0" +version = "8.2.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -12525,7 +12525,7 @@ dependencies = [ [[package]] name = "pallet-xyk-liquidity-mining" -version = "1.8.0" +version = "1.8.1" dependencies = [ "frame-support", "frame-system", @@ -15687,7 +15687,7 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "runtime-integration-tests" -version = "1.80.0" +version = "1.80.1" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -15770,7 +15770,7 @@ dependencies = [ "pallet-scheduler", "pallet-session", "pallet-stableswap", - "pallet-staking 4.3.1", + "pallet-staking 4.3.2", "pallet-synthetic-logs", "pallet-timestamp", "pallet-transaction-multi-payment", @@ -15837,7 +15837,7 @@ dependencies = [ "pallet-asset-registry", "pallet-omnipool", "pallet-stableswap", - "pallet-staking 4.3.1", + "pallet-staking 4.3.2", "primitives", "scraper", "serde", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 73ab32e99..0e356b1fa 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "1.80.0" +version = "1.80.1" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/circuit-breaker/Cargo.toml b/pallets/circuit-breaker/Cargo.toml index ba20b01af..49e6e21b1 100644 --- a/pallets/circuit-breaker/Cargo.toml +++ b/pallets/circuit-breaker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-circuit-breaker" -version = "1.6.3" +version = "1.6.4" authors = ["GalacticCouncil "] edition = "2021" license = "Apache-2.0" diff --git a/pallets/claims/Cargo.toml b/pallets/claims/Cargo.toml index 887096257..8ad243683 100644 --- a/pallets/claims/Cargo.toml +++ b/pallets/claims/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-claims" -version = "3.6.0" +version = "3.6.1" description = "HydraDX Claims Module" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/collator-rewards/Cargo.toml b/pallets/collator-rewards/Cargo.toml index bc3e5e009..ec18c23f3 100644 --- a/pallets/collator-rewards/Cargo.toml +++ b/pallets/collator-rewards/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-collator-rewards" -version = "1.3.0" +version = "1.3.1" description = "Pallet for collator rewards" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/currencies/Cargo.toml b/pallets/currencies/Cargo.toml index 9c6b9646d..40220d72f 100644 --- a/pallets/currencies/Cargo.toml +++ b/pallets/currencies/Cargo.toml @@ -3,7 +3,7 @@ name = "pallet-currencies" description = "Provide `MultiCurrency` implementation using `pallet-balances` and `orml-tokens` module." repository = "https://github.com/open-web3-stack/open-runtime-module-library/tree/master/currencies" license = "Apache-2.0" -version = "4.1.1" +version = "4.1.2" authors = ["Laminar Developers "] edition = "2021" diff --git a/pallets/dca/Cargo.toml b/pallets/dca/Cargo.toml index b65f45a52..91ee6eaae 100644 --- a/pallets/dca/Cargo.toml +++ b/pallets/dca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-dca' -version = "1.18.1" +version = "1.18.2" description = 'A pallet to manage DCA scheduling' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/democracy/Cargo.toml b/pallets/democracy/Cargo.toml index 5ee10de73..dd73a1771 100644 --- a/pallets/democracy/Cargo.toml +++ b/pallets/democracy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-democracy" -version = "4.5.0" +version = "4.5.1" authors = ["Parity Technologies "] edition = "2021" license = "Apache-2.0" diff --git a/pallets/dispenser/Cargo.toml b/pallets/dispenser/Cargo.toml index 8671ddfca..e9aefcedd 100644 --- a/pallets/dispenser/Cargo.toml +++ b/pallets/dispenser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-dispenser" -version = "0.4.0" +version = "0.4.1" edition = "2021" [package.metadata.docs.rs] diff --git a/pallets/duster/Cargo.toml b/pallets/duster/Cargo.toml index 68d698344..90be16338 100644 --- a/pallets/duster/Cargo.toml +++ b/pallets/duster/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-duster" -version = "3.8.0" +version = "3.8.1" description = "Account duster" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/dynamic-evm-fee/Cargo.toml b/pallets/dynamic-evm-fee/Cargo.toml index e46b8c968..0058f84f4 100644 --- a/pallets/dynamic-evm-fee/Cargo.toml +++ b/pallets/dynamic-evm-fee/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-dynamic-evm-fee" -version = "1.3.0" +version = "1.3.1" description = "Storing and mutating the dynamic fee for EVM transactions." authors = ["GalacticCoucil"] edition = "2021" diff --git a/pallets/evm-accounts/Cargo.toml b/pallets/evm-accounts/Cargo.toml index 9204ffbeb..40e75655b 100644 --- a/pallets/evm-accounts/Cargo.toml +++ b/pallets/evm-accounts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm-accounts" -version = "1.6.1" +version = "1.6.2" authors = ["GalacticCouncil"] edition = "2021" license = "Apache-2.0" diff --git a/pallets/hsm/Cargo.toml b/pallets/hsm/Cargo.toml index 40d41754a..d4337f84d 100644 --- a/pallets/hsm/Cargo.toml +++ b/pallets/hsm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-hsm" -version = "1.7.0" +version = "1.7.1" edition = "2021" description = "Hollar stability module" authors = ["GalacticCouncil"] diff --git a/pallets/lbp/Cargo.toml b/pallets/lbp/Cargo.toml index ac26e8003..42195324b 100644 --- a/pallets/lbp/Cargo.toml +++ b/pallets/lbp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-lbp" -version = "4.13.0" +version = "4.13.1" description = "HydraDX Liquidity Bootstrapping Pool Pallet" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/liquidation/Cargo.toml b/pallets/liquidation/Cargo.toml index be3216b6c..c1a0924d4 100644 --- a/pallets/liquidation/Cargo.toml +++ b/pallets/liquidation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-liquidation" -version = "2.4.2" +version = "2.4.3" description = "A pallet for money market liquidations" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/liquidity-mining/Cargo.toml b/pallets/liquidity-mining/Cargo.toml index 6bc0c52aa..1bace5bf2 100644 --- a/pallets/liquidity-mining/Cargo.toml +++ b/pallets/liquidity-mining/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-liquidity-mining" -version = "4.7.0" +version = "4.7.1" description = "Liquidity mining" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/nft/Cargo.toml b/pallets/nft/Cargo.toml index 8f7db0d3d..b45fa2be0 100644 --- a/pallets/nft/Cargo.toml +++ b/pallets/nft/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-nft" -version = "7.3.0" +version = "7.3.1" description = "A generic NFT pallet for managing non-fungible tokens" authors = ["GalacticCoucil"] edition = "2021" diff --git a/pallets/omnipool-liquidity-mining/Cargo.toml b/pallets/omnipool-liquidity-mining/Cargo.toml index 77e0d67a7..0a1ceef61 100644 --- a/pallets/omnipool-liquidity-mining/Cargo.toml +++ b/pallets/omnipool-liquidity-mining/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-omnipool-liquidity-mining" -version = "3.4.0" +version = "3.4.1" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" diff --git a/pallets/omnipool/Cargo.toml b/pallets/omnipool/Cargo.toml index 063996a7e..71854fc5f 100644 --- a/pallets/omnipool/Cargo.toml +++ b/pallets/omnipool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-omnipool" -version = "7.3.1" +version = "7.3.2" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" diff --git a/pallets/otc-settlements/Cargo.toml b/pallets/otc-settlements/Cargo.toml index 5d7c2027f..91b5d89d1 100644 --- a/pallets/otc-settlements/Cargo.toml +++ b/pallets/otc-settlements/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-otc-settlements' -version = '1.4.1' +version = "1.4.2" description = 'A pallet with offchain worker closing OTC arbs' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/otc/Cargo.toml b/pallets/otc/Cargo.toml index e6feaafcf..25f59ae8a 100644 --- a/pallets/otc/Cargo.toml +++ b/pallets/otc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-otc' -version = '2.4.0' +version = "2.4.1" description = 'A pallet for trustless over-the-counter trading' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/route-executor/Cargo.toml b/pallets/route-executor/Cargo.toml index d923a5d9a..1c1734eb3 100644 --- a/pallets/route-executor/Cargo.toml +++ b/pallets/route-executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-route-executor" -version = "2.12.0" +version = "2.12.1" description = "A pallet to execute a route containing a sequence of trades" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/signet/Cargo.toml b/pallets/signet/Cargo.toml index 5f8b8e30b..779d45ac3 100644 --- a/pallets/signet/Cargo.toml +++ b/pallets/signet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-signet" -version = "1.3.0" +version = "1.3.1" authors = ["Signet"] edition = "2021" license = "Apache-2.0" diff --git a/pallets/stableswap/Cargo.toml b/pallets/stableswap/Cargo.toml index 8de5ff294..b35b62ce5 100644 --- a/pallets/stableswap/Cargo.toml +++ b/pallets/stableswap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-stableswap" -version = "7.3.0" +version = "7.3.1" description = "AMM for correlated assets" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/staking/Cargo.toml b/pallets/staking/Cargo.toml index 6d7bbe8df..8133cfd1b 100644 --- a/pallets/staking/Cargo.toml +++ b/pallets/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-staking" -version = "4.3.1" +version = "4.3.2" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" diff --git a/pallets/transaction-multi-payment/Cargo.toml b/pallets/transaction-multi-payment/Cargo.toml index d49d16783..2b1ff313b 100644 --- a/pallets/transaction-multi-payment/Cargo.toml +++ b/pallets/transaction-multi-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-multi-payment" -version = "10.5.0" +version = "10.5.1" description = "Transaction multi currency payment support module" authors = ["GalacticCoucil"] edition = "2021" diff --git a/pallets/transaction-pause/Cargo.toml b/pallets/transaction-pause/Cargo.toml index 668a91ebd..5b6ae31bf 100644 --- a/pallets/transaction-pause/Cargo.toml +++ b/pallets/transaction-pause/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-pause" -version = "1.3.0" +version = "1.3.1" authors = ["Acala Developers", "GalacticCouncil"] edition = "2021" diff --git a/pallets/xyk-liquidity-mining/Cargo.toml b/pallets/xyk-liquidity-mining/Cargo.toml index c5d213379..ffa1e31b5 100644 --- a/pallets/xyk-liquidity-mining/Cargo.toml +++ b/pallets/xyk-liquidity-mining/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-xyk-liquidity-mining" -version = "1.8.0" +version = "1.8.1" description = "Liquidity mining" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/xyk/Cargo.toml b/pallets/xyk/Cargo.toml index e2656944e..de0054c9e 100644 --- a/pallets/xyk/Cargo.toml +++ b/pallets/xyk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-xyk" -version = "8.2.0" +version = "8.2.1" description = "XYK automated market maker" authors = ["GalacticCouncil"] edition = "2021" diff --git a/precompiles/call-permit/Cargo.toml b/precompiles/call-permit/Cargo.toml index f06c671df..21c8e5ae9 100644 --- a/precompiles/call-permit/Cargo.toml +++ b/precompiles/call-permit/Cargo.toml @@ -2,7 +2,7 @@ name = "pallet-evm-precompile-call-permit" description = "A Precompile to dispatch a call with a ERC712 permit." edition = "2021" -version = "0.3.0" +version = "0.3.1" authors = ["PureStake"] repository = "https://github.com/PureStake/moonbeam" diff --git a/runtime/adapters/Cargo.toml b/runtime/adapters/Cargo.toml index 45b41ea38..d1efb7767 100644 --- a/runtime/adapters/Cargo.toml +++ b/runtime/adapters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-adapters" -version = "1.13.1" +version = "1.13.2" description = "Structs and other generic types for building runtimes." authors = ["GalacticCouncil"] edition = "2021" diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index ace6ea49a..9f03b6cb3 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "416.0.0" +version = "413.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index bbdd88e37..0eb0c154d 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: Cow::Borrowed("hydradx"), impl_name: Cow::Borrowed("hydradx"), authoring_version: 1, - spec_version: 416, + spec_version: 413, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 01c2fe53672143463803ab971e96f678934e537d Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 5 May 2026 05:07:10 +0200 Subject: [PATCH 17/17] fmt --- .../src/balances_tokens_hooks.rs | 23 +++++++++++-------- .../src/stableswap_curve_comparison.rs | 5 +--- integration-tests/src/utils/contracts.rs | 4 +--- pallets/synthetic-logs/src/lib.rs | 8 ++++--- pallets/synthetic-logs/src/tests.rs | 23 +++++++++++++++---- 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/integration-tests/src/balances_tokens_hooks.rs b/integration-tests/src/balances_tokens_hooks.rs index afe8e5978..ac3143211 100644 --- a/integration-tests/src/balances_tokens_hooks.rs +++ b/integration-tests/src/balances_tokens_hooks.rs @@ -826,7 +826,11 @@ fn orml_tokens_slash_reserved_buffers_burn_log_from_reserved_sentinel() { TestNet::reset(); Hydra::execute_with(|| { let amount = UNITS; - assert_ok!(>::reserve(DAI, &ALICE.into(), amount)); + assert_ok!(>::reserve( + DAI, + &ALICE.into(), + amount + )); SyntheticLogsPending::::kill(); let remaining = >::slash_reserved(DAI, &ALICE.into(), amount); @@ -854,10 +858,14 @@ fn balances_slash_reserved_buffers_burn_log_from_reserved_sentinel() { TestNet::reset(); Hydra::execute_with(|| { let amount = UNITS; - assert_ok!(>::reserve(&ALICE.into(), amount)); + assert_ok!(>::reserve( + &ALICE.into(), + amount + )); SyntheticLogsPending::::kill(); - let (_imbalance, remaining) = >::slash_reserved(&ALICE.into(), amount); + let (_imbalance, remaining) = + >::slash_reserved(&ALICE.into(), amount); assert_eq!(remaining, 0); let hdx_addr = HydraErc20Mapping::asset_address(HDX); @@ -965,10 +973,7 @@ fn on_finalize_drains_buffer_into_pallet_ethereum_pending_before_ethereum_seal() // After SyntheticLogs's flush but BEFORE Ethereum::on_finalize, the // synth tx must already be in pallet_ethereum::Pending. let pending: Vec<_> = pallet_ethereum::Pending::::iter().collect(); - assert!( - !pending.is_empty(), - "flush must write into pallet_ethereum::Pending", - ); + assert!(!pending.is_empty(), "flush must write into pallet_ethereum::Pending",); // Now seal the ethereum block. Ethereum::on_finalize(n); @@ -983,8 +988,8 @@ fn on_finalize_drains_buffer_into_pallet_ethereum_pending_before_ethereum_seal() // CurrentTransactionStatuses + CurrentReceipts. After the seal, the // synth tx should appear in the block's tx list, statuses, and receipts. let block = pallet_ethereum::CurrentBlock::::get().expect("ethereum block sealed"); - let statuses = pallet_ethereum::CurrentTransactionStatuses::::get() - .expect("statuses stored after seal"); + let statuses = + pallet_ethereum::CurrentTransactionStatuses::::get().expect("statuses stored after seal"); let receipts = pallet_ethereum::CurrentReceipts::::get().expect("receipts stored after seal"); assert_eq!(block.transactions.len(), statuses.len(), "tx count == status count"); diff --git a/integration-tests/src/stableswap_curve_comparison.rs b/integration-tests/src/stableswap_curve_comparison.rs index 2605c4f64..570ed1184 100644 --- a/integration-tests/src/stableswap_curve_comparison.rs +++ b/integration-tests/src/stableswap_curve_comparison.rs @@ -323,10 +323,7 @@ fn assert_parity(label: &str, hydra: u128, curve: u128, max_tolerance: u128, exp "{label}: diff {diff} exceeds tolerance {max_tolerance} (hydra={hydra}, curve={curve})" ); if expect_hydra_gte { - assert!( - hydra >= curve, - "{label}: expected hydra ({hydra}) >= curve ({curve})" - ); + assert!(hydra >= curve, "{label}: expected hydra ({hydra}) >= curve ({curve})"); } } diff --git a/integration-tests/src/utils/contracts.rs b/integration-tests/src/utils/contracts.rs index f96b1cf7f..464965ca8 100644 --- a/integration-tests/src/utils/contracts.rs +++ b/integration-tests/src/utils/contracts.rs @@ -7,9 +7,7 @@ use sp_core::U256; use std::fs; pub fn get_contract_bytecode(name: &str) -> Vec { - let path = format!( - "../scripts/test-contracts/artifacts/contracts/{name}.sol/{name}.json" - ); + let path = format!("../scripts/test-contracts/artifacts/contracts/{name}.sol/{name}.json"); let str = fs::read_to_string(path).unwrap(); let json: serde_json::Value = serde_json::from_str(&str).unwrap(); let code = json.get("bytecode").unwrap().as_str().unwrap(); diff --git a/pallets/synthetic-logs/src/lib.rs b/pallets/synthetic-logs/src/lib.rs index 9ed342314..ede223701 100644 --- a/pallets/synthetic-logs/src/lib.rs +++ b/pallets/synthetic-logs/src/lib.rs @@ -50,7 +50,10 @@ pub enum HookPhase { #[derive(Clone, Copy, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug, PartialEq, Eq)] pub enum Bucket { Extrinsic(u32), - Hook { phase: HookPhase, origin: Option }, + Hook { + phase: HookPhase, + origin: Option, + }, } #[frame_support::pallet] @@ -102,8 +105,7 @@ impl Pallet { // has already set Phase=Finalization) buckets as Finalization too. fn current_bucket() -> Bucket { use frame_system::Phase; - let phase_key = - frame_support::storage::storage_prefix(b"System", b"ExecutionPhase"); + let phase_key = frame_support::storage::storage_prefix(b"System", b"ExecutionPhase"); let phase: Phase = frame_support::storage::unhashed::get::(&phase_key).unwrap_or_default(); match phase { Phase::ApplyExtrinsic(i) => Bucket::Extrinsic(i), diff --git a/pallets/synthetic-logs/src/tests.rs b/pallets/synthetic-logs/src/tests.rs index c3d5c7fa0..bae6141ac 100644 --- a/pallets/synthetic-logs/src/tests.rs +++ b/pallets/synthetic-logs/src/tests.rs @@ -167,7 +167,13 @@ fn flush_bucket_grouping_and_sort_order() { // 5 distinct buckets, in order: Init/None < Init/DCA < Extrinsic(0) < Extrinsic(2) < Final/None let order: Vec = groups.iter().map(|(b, _)| *b).collect(); - assert!(matches!(order[0], Bucket::Hook { phase: HookPhase::Initialization, origin: None })); + assert!(matches!( + order[0], + Bucket::Hook { + phase: HookPhase::Initialization, + origin: None + } + )); assert!(matches!( order[1], Bucket::Hook { @@ -177,7 +183,13 @@ fn flush_bucket_grouping_and_sort_order() { )); assert!(matches!(order[2], Bucket::Extrinsic(0))); assert!(matches!(order[3], Bucket::Extrinsic(2))); - assert!(matches!(order[4], Bucket::Hook { phase: HookPhase::Finalization, origin: None })); + assert!(matches!( + order[4], + Bucket::Hook { + phase: HookPhase::Finalization, + origin: None + } + )); // Extrinsic(2) holds both its logs in insertion order. let ext2_logs = &groups @@ -215,7 +227,11 @@ fn bucket_nonce_layout_is_distinct_per_class() { ]; let nonces: Vec = cases.iter().map(|b| bucket_nonce(*b)).collect(); let unique: std::collections::BTreeSet<_> = nonces.iter().collect(); - assert_eq!(unique.len(), cases.len(), "every bucket class must produce a distinct nonce"); + assert_eq!( + unique.len(), + cases.len(), + "every bucket class must produce a distinct nonce" + ); } fn log(tag: u8) -> ethereum::Log { @@ -227,4 +243,3 @@ fn log(tag: u8) -> ethereum::Log { data: Vec::new(), } } -