Skip to content

Commit

Permalink
New Asset System - Implement asset-router (#1189)
Browse files Browse the repository at this point in the history
* Add new asset types

* Add custom assets to runtime

* Add market assets to runtime

* Add pallet_assets benchmark and weights

* Expose MarketAssets call enum

* Update todo comment to incluse issue number

* Add campaign assets instance to runtime

* Cargo fmt

* Taplo fmt

* Refine asset class types

* Use efficient asset types

* Add all variants to overarching Asset enum

* Make MarketId compactable

* Adjust SerdeWrapper

Soon to be deprecated

* Make Battery Station compileable

* Make Zeitgeist compileable

* Cleanup code

* Remove NewForeignAsset

Conversion to compact encoding implies massive migration effort

* Implement asset type conversions

* Add Currency asset class

* Remove deprecated SerdeWrapper

* Add Currencies asset class

Also renames existing CurrencyId to Assets

* Add scale codec index matching tests

* Add asset conversion tests

* Update docstring

* Improve assets module structure

* Update license

* Create asset-router pallet scaffold

* Start implementing all traits

* Implement MultiCurrency partially for asset-router

* Implement MultiCurrency for asset-router

* Implement MultiCurrencyExtended

* MultiLockableCurrency

* Implement MultiReservableCurrency

* Implement NamedMultiReservableCurrency

* Fix runtime

* Integrate asset-router in runtime

* Fix a couple of bugs

* Prepare asset-router test environment

* Start MultiCurrency test impl

* Complete MultiCurrency tests

* Add MultiCurrencyExtended tests

* Implement MultiReserveableCurrency tests

* Implement NamedMultiReserveableCurrency tests

* Implement MultiLockableCurrency tests

* Improve test structure

* Undo unnecessary change

* Format code

* Implement fungibles::{Create, Destroy, Inspect}

* Remove comment

* Add tests for Inspect impl

* Add tests for Create impl

* Add tests for Destroy impl

* Make asset types configurable

* Use less restricitve traits for pm AssetManager

* Make project compilable

* Merge branch 'sea212-new-asset-system' into sea212-new-asset-system-part-3

* Update licenses

* Repair tests partially

* Comment out irrelevant test

* Partially satisfy Clippy

* Adjust XCM to use Currencies

* Adjust XCM to use Currencies (zeitgeist runtime)

* Adjust prediction markets tests

* Adjust neo-swaps mock

* Satisfy Clippy

* Format code

* Update licenses

* Remove pallet-asset benchmark helper from mock

* Format code

* Repair tests with runtime-benchmarks

* Format code

* Remove TODO comment

* Implement log for unhandled errors in asset-router

* Use log target

* Improve and prettify readmes

* Use assert_noop! in favor of asset_err!

Co-authored-by: Malte Kliemann <mail@maltekliemann.com>

* Make sea212 codeowner of zrml/asset-router

* Fix typo

* Rename variable

* Better abs() overflow handling

* Check Bob's balance in MultiCurrency tests

* Fix Create test for Currencies

* Improve test precision

* Verify total issuance via direct pallet invocation

* Implement Inspect for Currencies

* Satisfy Clippy

---------

Co-authored-by: Malte Kliemann <mail@maltekliemann.com>
  • Loading branch information
sea212 and maltekliemann authored Jan 24, 2024
1 parent 4628f8c commit ddaa364
Show file tree
Hide file tree
Showing 49 changed files with 2,426 additions and 235 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# Ignore everything but mod.rs in /runtime/common/src/weights/
/runtime/common/src/weights/*
/runtime/common/src/weights/mod.rs @sea212
/zrml/asset-router/ @sea212
/zrml/authorized/ @Chralt98
/zrml/court/ @Chralt98
/zrml/global-disputes/ @Chralt98
Expand Down
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ default-members = [
"runtime/battery-station",
"runtime/zeitgeist",
"zrml/authorized",
"zrml/asset-router",
"zrml/court",
"zrml/global-disputes",
"zrml/liquidity-mining",
Expand All @@ -29,6 +30,7 @@ members = [
"runtime/battery-station",
"runtime/zeitgeist",
"zrml/authorized",
"zrml/asset-router",
"zrml/court",
"zrml/global-disputes",
"zrml/liquidity-mining",
Expand Down Expand Up @@ -229,6 +231,7 @@ zrml-swaps-rpc = { path = "zrml/swaps/rpc" }
# Zeitgeist (wasm)
common-runtime = { path = "runtime/common", default-features = false }
zeitgeist-primitives = { path = "primitives", default-features = false }
zrml-asset-router = { path = "zrml/asset-router", default-features = false }
zrml-authorized = { path = "zrml/authorized", default-features = false }
zrml-court = { path = "zrml/court", default-features = false }
zrml-global-disputes = { path = "zrml/global-disputes", default-features = false }
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ _anything_.

## Modules

- [asset-router](./zrml/asset-router) - Routes all asset classes to the
respective pallets and provides a garbage collection for destructible assets.
- [authorized](./zrml/authorized) - Offers authorized resolution of disputes.
- [court](./zrml/court) - An implementation of a court mechanism used to resolve
disputes in a decentralized fashion.
Expand All @@ -33,9 +35,9 @@ _anything_.
- [neo-swaps](./zrml/neo-swaps) - An implementation of the Logarithmic Market
Scoring Rule as constant function market maker, tailor-made for decentralized
combinatorial markets and Futarchy.
- [orderbook](./zrml/orderbook) - A naive orderbook implementation that's
only part of Zeitgeist's PoC. Will be replaced by a v2 orderbook that uses
0x-style hybrid on-chain and off-chain trading.
- [orderbook](./zrml/orderbook) - A naive orderbook implementation that's only
part of Zeitgeist's PoC. Will be replaced by a v2 orderbook that uses 0x-style
hybrid on-chain and off-chain trading.
- [parimutuel](./zrml/parimutuel) - A straightforward parimutuel market maker
for categorical markets.
- [prediction-markets](./zrml/prediction-markets) - The core implementation of
Expand Down
2 changes: 1 addition & 1 deletion primitives/src/assets/campaign_assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use super::*;
#[derive(
Clone, CompactAs, Copy, Debug, Decode, Default, Eq, Encode, MaxEncodedLen, PartialEq, TypeInfo,
)]
pub struct CampaignAssetClass(#[codec(compact)] pub(super) CampaignAssetId);
pub struct CampaignAssetClass(#[codec(compact)] pub CampaignAssetId);

impl From<Compact<CampaignAssetId>> for CampaignAssetClass {
fn from(value: Compact<CampaignAssetId>) -> CampaignAssetClass {
Expand Down
7 changes: 5 additions & 2 deletions primitives/src/assets/currencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

use super::*;

/// The `CurrencyClass` enum represents all non-ztg currencies.
/// The `CurrencyClass` enum represents all non-ztg currencies
// used in orml-tokens
#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[derive(Clone, Copy, Debug, Decode, Eq, Encode, MaxEncodedLen, PartialEq, TypeInfo)]
#[derive(
Clone, Copy, Debug, Decode, Eq, Encode, MaxEncodedLen, Ord, PartialEq, PartialOrd, TypeInfo,
)]
pub enum CurrencyClass<MI> {
// All "Old" variants will be removed once the lazy migration from
// orml-tokens to pallet-assets is complete
Expand Down
2 changes: 1 addition & 1 deletion primitives/src/assets/custom_assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use super::*;
#[derive(
Clone, CompactAs, Copy, Debug, Decode, Default, Eq, Encode, MaxEncodedLen, PartialEq, TypeInfo,
)]
pub struct CustomAssetClass(#[codec(compact)] pub(super) CustomAssetId);
pub struct CustomAssetClass(#[codec(compact)] pub CustomAssetId);

impl From<Compact<CustomAssetId>> for CustomAssetClass {
fn from(value: Compact<CustomAssetId>) -> CustomAssetClass {
Expand Down
19 changes: 18 additions & 1 deletion primitives/src/constants/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,22 @@
pub use super::*;
use crate::{
assets::Asset,
types::{Assets, Balance, Moment},
types::{Assets, Balance, Currencies, Moment},
};
use frame_support::{parameter_types, traits::LockIdentifier, PalletId};
use orml_traits::parameter_type_with_key;
use sp_arithmetic::Perbill;

// Assets
parameter_types! {
pub const AssetsAccountDeposit: Balance = 0;
pub const AssetsApprovalDeposit: Balance = 0;
pub const AssetsDeposit: Balance = 0;
pub const AssetsStringLimit: u32 = 256;
pub const AssetsMetadataDepositBase: Balance = 0;
pub const AssetsMetadataDepositPerByte: Balance = 0;
}

// Authorized
parameter_types! {
pub const AuthorizedPalletId: PalletId = PalletId(*b"zge/atzd");
Expand Down Expand Up @@ -164,6 +174,7 @@ parameter_types! {
pub const GetNativeCurrencyId: Assets = Asset::Ztg;
}

// Will be removed once asset-system is completely integerated
parameter_type_with_key! {
pub ExistentialDeposits: |currency_id: Assets| -> Balance {
match currency_id {
Expand All @@ -173,6 +184,12 @@ parameter_type_with_key! {
};
}

parameter_type_with_key! {
pub ExistentialDepositsNew: |_currency_id: Currencies| -> Balance {
1
};
}

// System
parameter_types! {
pub const BlockHashCount: u64 = 250;
Expand Down
7 changes: 2 additions & 5 deletions primitives/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ pub type Assets = Asset<MarketId>;
/// Asset type representing campaign assets
pub type CampaignAsset = CampaignAssetClass;

// ID type for campaign asset class
// ID type of the campaign asset class
pub type CampaignAssetId = u128;

/// Asset type representing custom assets
pub type CustomAsset = CustomAssetClass;

// ID type for campaign asset class
// ID type of the custom asset class
pub type CustomAssetId = u128;

// Asset type representing currencies (excluding ZTG)
Expand All @@ -102,9 +102,6 @@ pub type Currencies = CurrencyClass<MarketId>;
/// Asset type representing assets used by prediction markets
pub type MarketAsset = MarketAssetClass<MarketId>;

/// ID type for asset classes that anyone can create
pub type AssetId = u128;

/// The asset id specifically used for pallet_assets_tx_payment for
/// paying transaction fees in different assets.
/// Since the polkadot extension and wallets can't handle custom asset ids other than just u32,
Expand Down
2 changes: 2 additions & 0 deletions runtime/battery-station/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ xcm-executor = { workspace = true, optional = true }

common-runtime = { workspace = true }
zeitgeist-primitives = { workspace = true }
zrml-asset-router = { workspace = true }
zrml-authorized = { workspace = true }
zrml-court = { workspace = true }
zrml-global-disputes = { workspace = true, optional = true }
Expand Down Expand Up @@ -382,6 +383,7 @@ try-runtime = [
"orml-xtokens?/try-runtime",

# Zeitgeist runtime pallets
"zrml-asset-router/try-runtime",
"zrml-authorized/try-runtime",
"zrml-court/try-runtime",
"zrml-liquidity-mining/try-runtime",
Expand Down
13 changes: 8 additions & 5 deletions runtime/battery-station/src/integration_tests/xcm/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use xcm::{
latest::{Junction::Parachain, Junctions::X2, MultiLocation},
VersionedMultiLocation,
};
use zeitgeist_primitives::types::{Asset, CustomMetadata};
use zeitgeist_primitives::types::{Currencies, CustomMetadata};

pub(super) struct ExtBuilder {
balances: Vec<(AccountId, Assets, Balance)>,
Expand Down Expand Up @@ -71,6 +71,9 @@ impl ExtBuilder {
.balances
.into_iter()
.filter(|(_, currency_id, _)| *currency_id != native_currency_id)
.map(|(account_id, currency_id, initial_balance)| {
(account_id, currency_id.try_into().unwrap(), initial_balance)
})
.collect::<Vec<_>>(),
}
.assimilate_storage(&mut t)
Expand Down Expand Up @@ -103,10 +106,10 @@ pub const BOB: AccountId32 = AccountId32::new([1u8; 32]);
pub const PARA_ID_SIBLING: u32 = 3000;

/// IDs that are used to represent tokens from other chains
pub const FOREIGN_ZTG_ID: Asset<u128> = Assets::ForeignAsset(0);
pub const FOREIGN_PARENT_ID: Asset<u128> = Assets::ForeignAsset(1);
pub const FOREIGN_SIBLING_ID: Asset<u128> = Assets::ForeignAsset(2);
pub const BTC_ID: Asset<u128> = Assets::ForeignAsset(3);
pub const FOREIGN_ZTG_ID: Currencies = Currencies::ForeignAsset(0);
pub const FOREIGN_PARENT_ID: Currencies = Currencies::ForeignAsset(1);
pub const FOREIGN_SIBLING_ID: Currencies = Currencies::ForeignAsset(2);
pub const BTC_ID: Currencies = Currencies::ForeignAsset(3);

#[inline]
pub(super) const fn ztg(amount: Balance) -> Balance {
Expand Down
4 changes: 2 additions & 2 deletions runtime/battery-station/src/integration_tests/xcm/test_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ pub(super) fn para_ext(parachain_id: u32) -> sp_io::TestExternalities {
ExtBuilder::default()
.set_balances(vec![
(ALICE, Assets::Ztg, ztg(10)),
(ALICE, FOREIGN_PARENT_ID, roc(10)),
(ZeitgeistTreasuryAccount::get(), FOREIGN_PARENT_ID, roc(1)),
(ALICE, FOREIGN_PARENT_ID.into(), roc(10)),
(ZeitgeistTreasuryAccount::get(), FOREIGN_PARENT_ID.into(), roc(1)),
])
.set_parachain_id(parachain_id)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,18 @@ fn convert_any_registered_parent_multilocation() {
foreign_parent_multilocation()
);

assert_eq!(<AssetConvert as C2<_, _>>::convert(FOREIGN_PARENT_ID), None);
assert_eq!(<AssetConvert as C2<_, _>>::convert(Assets::from(FOREIGN_PARENT_ID)), None);

// Register parent as foreign asset in the Zeitgeist parachain
register_foreign_parent(None);

assert_eq!(
<AssetConvert as C1<_, _>>::convert(foreign_parent_multilocation()),
Ok(FOREIGN_PARENT_ID),
Ok(FOREIGN_PARENT_ID.into()),
);

assert_eq!(
<AssetConvert as C2<_, _>>::convert(FOREIGN_PARENT_ID),
<AssetConvert as C2<_, _>>::convert(Assets::from(FOREIGN_PARENT_ID)),
Some(foreign_parent_multilocation())
);
});
Expand All @@ -87,18 +87,18 @@ fn convert_any_registered_sibling_multilocation() {
foreign_sibling_multilocation()
);

assert_eq!(<AssetConvert as C2<_, _>>::convert(FOREIGN_SIBLING_ID), None);
assert_eq!(<AssetConvert as C2<_, _>>::convert(Assets::from(FOREIGN_SIBLING_ID)), None);

// Register sibling as foreign asset in the Zeitgeist parachain
register_foreign_sibling(None);

assert_eq!(
<AssetConvert as C1<_, _>>::convert(foreign_sibling_multilocation()),
Ok(FOREIGN_SIBLING_ID),
Ok(FOREIGN_SIBLING_ID.into()),
);

assert_eq!(
<AssetConvert as C2<_, _>>::convert(FOREIGN_SIBLING_ID),
<AssetConvert as C2<_, _>>::convert(Assets::from(FOREIGN_SIBLING_ID)),
Some(foreign_sibling_multilocation())
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ fn transfer_ztg_sibling_to_zeitgeist() {
assert_eq!(Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), bob_initial_balance);
assert_ok!(XTokens::transfer(
RuntimeOrigin::signed(BOB),
FOREIGN_ZTG_ID,
FOREIGN_ZTG_ID.into(),
transfer_amount,
Box::new(
MultiLocation::new(
Expand Down Expand Up @@ -250,7 +250,7 @@ fn transfer_btc_zeitgeist_to_sibling() {
Zeitgeist::execute_with(|| {
assert_ok!(XTokens::transfer(
RuntimeOrigin::signed(ALICE),
BTC_ID,
BTC_ID.into(),
transfer_amount,
Box::new(
MultiLocation::new(
Expand Down Expand Up @@ -328,7 +328,7 @@ fn transfer_roc_to_relay_chain() {

assert_ok!(XTokens::transfer(
RuntimeOrigin::signed(ALICE),
FOREIGN_PARENT_ID,
FOREIGN_PARENT_ID.into(),
transfer_amount,
Box::new(
MultiLocation::new(1, X1(Junction::AccountId32 { id: BOB.into(), network: None }))
Expand Down
25 changes: 8 additions & 17 deletions runtime/battery-station/src/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,16 +497,17 @@ parameter_type_with_key! {
// are cleaned up automatically. In case of scalar outcomes, the market account can have dust.
// Unless LPs use `pool_exit_with_exact_asset_amount`, there can be some dust pool shares remaining.
// Explicit match arms are used to ensure new asset types are respected.
pub ExistentialDeposits: |currency_id: Assets| -> Balance {
pub ExistentialDeposits: |currency_id: Currencies| -> Balance {
match currency_id {
Asset::CategoricalOutcome(_,_) => ExistentialDeposit::get(),
Asset::PoolShare(_) => ExistentialDeposit::get(),
Asset::ScalarOutcome(_,_) => ExistentialDeposit::get(),
Currencies::OldCategoricalOutcome(_,_) => ExistentialDeposit::get(),
Currencies::OldParimutuelShare(_,_) => ExistentialDeposit::get(),
Currencies::OldPoolShare(_) => ExistentialDeposit::get(),
Currencies::OldScalarOutcome(_,_) => ExistentialDeposit::get(),
#[cfg(feature = "parachain")]
Asset::ForeignAsset(id) => {
Currencies::ForeignAsset(id) => {
let maybe_metadata = <
orml_asset_registry::Pallet<Runtime> as orml_traits::asset_registry::Inspect
>::metadata(&Asset::ForeignAsset(*id));
>::metadata(&Currencies::ForeignAsset(*id));

if let Some(metadata) = maybe_metadata {
return metadata.existential_deposit;
Expand All @@ -515,17 +516,7 @@ parameter_type_with_key! {
1
}
#[cfg(not(feature = "parachain"))]
Asset::ForeignAsset(_) => ExistentialDeposit::get(),
Asset::Ztg => ExistentialDeposit::get(),
Asset::ParimutuelShare(_,_) => ExistentialDeposit::get(),

// The following assets are irrelevant, as they are managed by pallet-assets
Asset::NewParimutuelShare(_,_)
| Asset::NewCategoricalOutcome(_, _)
| Asset::NewScalarOutcome(_,_)
| Asset::NewPoolShare(_)
| Asset::CustomAssetClass(_)
| Asset::CampaignAssetClass(_) => ExistentialDeposit::get(),
Currencies::ForeignAsset(_) => ExistentialDeposit::get(),
}
};
}
Expand Down
Loading

0 comments on commit ddaa364

Please sign in to comment.