From 7a751ec326e2a7ba22d1af8d62199ea988d1b972 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Tue, 26 Mar 2024 19:55:35 +0100 Subject: [PATCH] New Asset System - Integrate into XCM (#1287) * Merge release v0.4.2 (#1174) * Update versions (#1168) * Add updated weights from reference machine (#1169) * Add license header Co-authored-by: Chralt --------- Co-authored-by: Chralt * Remove migrations (#1180) * Filter admin functions for main-net (#1190) filter admin functions for main-net * Add debug assertions for slashes and reserves (#1188) * add debug assertions for missing slashes * place debug_assert for unreserves * Add some verify checks to court (#1187) add some verify checks to court * Bypass battery stations contracts call filter for court, parimutuel, order book markets (#1185) update contracts call filter * Fix failing court benchmark (#1191) * fix court assertion for resolve_at * remove unnecessary variable * mirror mock and actual impl for DisputeResolution * Implement trusted market close (#1184) * implement trusted market close * remove unnecessary benchmark helper function * Update zrml/prediction-markets/src/lib.rs Co-authored-by: Malte Kliemann * remove unnecessary function * check market end * check auto close * add invalid market status test --------- Co-authored-by: Malte Kliemann * Modify court events for indexer (#1182) * modify events for indexer * gracefully handle panicers * handle binary search by key error * improve style * Ensure MinBetSize after fee (#1193) * handle own existential deposit errors * use require_transactional * correct benchmark and test min bet size amounts * Replace fixed math operations with traited versions (#1149) * Replace `bmul` and `bdiv` with traited versions * Restructure directories * Replace `saturating_*` from neo-swaps * Fix formatting * Restructure zrml-swaps math * Implement and test `b*` * Fix formatting * Use new math in orderbook-v1 * Replace checked multiplication with new math * Use correct rounding in neo-swaps * Add docs * Update licenses * Remove `fixed` module from `primitives` * Fix formatting * Update primitives/src/math/fixed.rs Co-authored-by: Harald Heckmann --------- Co-authored-by: Harald Heckmann * Add env_logger and add force-debug feature (#1205) * add env_logger and add force-debug feature * taplo fmt, fix copyrights * Update zrml/styx/src/mock.rs Co-authored-by: Malte Kliemann * Update zrml/rikiddo/src/mock.rs Co-authored-by: Malte Kliemann * update comment to clarify logging --------- Co-authored-by: Malte Kliemann * Inflate defensively (#1195) * inflate defensively * add tests * Update zrml/court/src/tests.rs Co-authored-by: Malte Kliemann * fix test * fix test name --------- Co-authored-by: Malte Kliemann * Maintain order book (#1183) * integrate market creator fees into orderbook * edit tests * update tests * modify tests * avoid order side * Update primitives/src/traits/distribute_fees.rs Co-authored-by: Malte Kliemann * remove asset and account from get_fee api call * take base asset fees from fill_order * adjust orderbook for taking fees in fill_order * adjust without order side for fill_order * adapt to avoid concept of order side * adapt benchmarks, tests and weights, restructure * use DispatchResult * remove unused import * do not adjust maker amount for place_order * correct fuzz of orderbook * check if maker_amount is zero * fix order book name in benchmarks * use remove instead of cancel order book * correct order book test names * update READMEs * fmt * add tests * use minimum balance as min order size * Update zrml/orderbook/README.md Co-authored-by: Malte Kliemann * Update zrml/orderbook/README.md Co-authored-by: Malte Kliemann * Apply suggestions from code review Co-authored-by: Malte Kliemann * prettier orderbook md * remove comments from benchmarks * fix tests and benchmarks readibility * use order book instead of orderbook * clarify error message * clarify comments * rename is to ensure * error for repatriate * fix unnecessary clone * correct mocks behaviour * improve test * improve test of near full fill error * use turbofish syntax * add filled_maker_amount to event * split tests * combine two functions, add docs * abandon get_fees * fix order book tests and mock * remove check for impossible behaviour * fix toml and benchs * prepare migration * add migration for order structure * return zero fees if transfer fails * delete unnecessary assert * fix naming * fix naming the second * fix maker fill description * add scoring rule check to remove order * fix post_upgrade * fix terminology * Update zrml/orderbook/src/migrations.rs Co-authored-by: Malte Kliemann * use storage root check in migration test * Update zrml/orderbook/src/lib.rs Co-authored-by: Harald Heckmann * Update zrml/orderbook/src/lib.rs Co-authored-by: Harald Heckmann * Update zrml/orderbook/src/lib.rs Co-authored-by: Harald Heckmann * delete debug_assert --------- Co-authored-by: Malte Kliemann Co-authored-by: Harald Heckmann * Implement AMM 2.0 (#1173) * Replace `bmul` and `bdiv` with traited versions * Restructure directories * Replace `saturating_*` from neo-swaps * Fix formatting * Restructure zrml-swaps math * Implement and test `b*` * Fix formatting * Use new math in orderbook-v1 * Replace checked multiplication with new math * Use correct rounding in neo-swaps * Add docs * Update licenses * Remove `fixed` module from `primitives` * Fix formatting * . * Rewrite math functions * Remove training wheels * Fix docs.pdf * Fix quotes * Add tests for buying * Add tests for selling and improve error names * Update docs * Check adjusted amount in for numerical bounds * Remove unused implementations * Adjust docs * Add stress test exploring various scenarios * Add swap fees to stress test * Add underscore separators * Clean up * Benchmark `buy` as function of `asset_count` * Update benchmarks * Clippy fix * Fix benchmark tests * Update benchmarks of zrml-prediction-markets * Fix broken comment * Add comment explaining benchmark spot prices * Use clearer constants for `amount_in` in tests * Update zrml/neo-swaps/src/traits/pool_operations.rs Co-authored-by: Chralt * Fix botched merge * Fix merge * Update benchmarks * Update zrml/neo-swaps/docs/docs.tex Co-authored-by: Harald Heckmann * Apply suggestions from code review Co-authored-by: Harald Heckmann * Rename `Fixed` and clean up * Hotfix exponential function and extend tests * Complete math test suite * Fix broken sentence * Remove unused imports * Extend `ln` test cases * Merge & fix formatting --------- Co-authored-by: Chralt Co-authored-by: Harald Heckmann * Implement Liquidity Tree (#1178) * Replace `bmul` and `bdiv` with traited versions * Restructure directories * Replace `saturating_*` from neo-swaps * Fix formatting * Restructure zrml-swaps math * Implement and test `b*` * Fix formatting * Use new math in orderbook-v1 * Replace checked multiplication with new math * Use correct rounding in neo-swaps * Add docs * Update licenses * Remove `fixed` module from `primitives` * Fix formatting * Add liquidity tree draft * Fix compiler error in draft * Clean up `propagate_fees` * Add docs * Reorganize * Clean up, add max iterations * Remove migrations * Prepare switch to bounded vector * Use `BoundedVec` * Use bounded `BTreeMap` and insert `LiquidityTree` into neo-swaps * Resolve TODO * Clean up tests * Add migration and fix clippy errors * Make tree depth a generic * Make tree depth a config parameter * Update runtime complexities * Add benchmarking utilities * Fix runtime complexity for `deploy_pool` * Add missing lazy propagation * Fix comment * Fix error type * Add `join` benchmarking and fix a bug in `LiquidityTree` * Clean up benchmarks * Fix clippy issues * Remove unnecessary type hint * Fix bugs in liquidity tree * Fix comments * Some fixes in benchmarks * Implement `BenchmarkHelper` * Update benchmarks to use the LT * Clean up and format * Add testing framework for liquidity trees * Add first extensive test and fix a bug * Add more tests * Clean up test * Add news tests and use better numerics for ratio calculations * Make docs more explicit * Add tests for `exit` * Add tests for deposit fees * Add tests for getters * Clean up tests some more * Finalize liquidity tree tests * Clean up comments * Introduce exit fees * Rewrite `exit_works` * Fix liquidity parameter calculation * Make test a bit more complex * Test liquidity shares * Clean up tests * Update test for destruction * Enhance `exit_destroys_pool` test * More cleanup * Add test for full tree * Add tests for `join` * Improve test * Test withdrawal * Clean up the test * Add test for noop * Add minimum relative liquidity * Verify that buys deduct the correct amount of fees * Add last tests * Add notes about the liquidity tree * Fix benchmarks * Fix clippy errors * Fix benchmarks * Do more work on benchmarks * Fix benchmarks, deduce max tree depth * Remove already solved TODO * Document macros * Remove TODO (not a good idea to edit LaTeX docs now) * Fix `bmul_bdiv` * Make `bmul_bdiv_*` not implemented * Double-check that there's a non-zero check for `ratio` * Fix formatting * Fix taplo formatting * Remove TODO * Remove TODOs and fix documents * Update primitives/src/math/fixed.rs Co-authored-by: Chralt * Mark `SoloLp` as deprecated * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Make `bmul_bdiv` a little more idiomatic * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Update zrml/neo-swaps/README.md Co-authored-by: Chralt * Rewrite and format `README.md` * Fix comment about existential deposit * Remove FIXME * Add a check against misconfiguration of the pallet * Fix field docstrings * Add comment about `assert_ok_with_transaction` * Update zrml/neo-swaps/src/mock.rs Co-authored-by: Chralt * Format code * Fix comment * Prettify extrinsic calls in benchmarks * Improve code quality of `assert_pool_state!` * Extend comment about order of abandoned nodes * Clarify the meaning of "leaf" in `is_leaf` * Rename `index_maybe` to `opt_index` * Add unexpected storage overflow error for bounded objects * Rename `UnclaimedFees` to `UnwithdrawnFees` * Fix documentation * Use enum to signal update direction in `update_descendant_stake` * Add verification to `join_*` benchmarks * Improve documentation * Use builtin log * Remove illegal token from `README.md` * Update zrml/neo-swaps/src/types/liquidity_tree.rs Co-authored-by: Chralt * Fix unintentional doctest * Improve `mutate_children` * Add helpful comment * Update zrml/neo-swaps/src/types/liquidity_tree.rs Co-authored-by: Chralt * Fix migration * Fix balances in parachain mock * use PartialEqNoBound and CloneNoBound for tree * Fix formatting * Make `debug_assert!` more clear * Redesign node assignment * Clean up comments * Add some storage overflow errors * Introduce `LiquidityTreeChildIndices` * Remove outdated docs * Rename `update_descendant_stake` * Remove `Default` usage * Make liquidity tree types `pub(crate)` where possible * Make all fields of `Node` only `pub(crate)` * Make `Node` an associated type of `LiquidityTreeHelper` * Update zrml/neo-swaps/src/lib.rs Co-authored-by: Harald Heckmann * Fix comment * Update zrml/neo-swaps/src/types/liquidity_tree.rs Co-authored-by: Harald Heckmann * Fix tests * Prettify `path_to_node` * Add max iterations to `path_to_node` * Add test for complex liquidity tree interactions * Improve documentation of `LiquidityTreeChildIndices` * Reorganize crate structure * Update weights and fix formatting --------- Co-authored-by: Chralt Co-authored-by: Chralt98 Co-authored-by: Harald Heckmann * Improve XCM fee handling (#1225) * Fix padding of foreign fees in Zeitgeist runtime * Fix padding of foreign fees in Battery Station runtime * Format * Update copyright * Use adjusted_balance function * Remove court and global disputes from call filter for the main-net (#1226) * remove from call filter * update copyright * Sunset old AMMs and their pools (#1197) * Replace `bmul` and `bdiv` with traited versions * Restructure directories * Replace `saturating_*` from neo-swaps * Fix formatting * Restructure zrml-swaps math * Implement and test `b*` * Fix formatting * Use new math in orderbook-v1 * Replace checked multiplication with new math * Use correct rounding in neo-swaps * Add docs * Update licenses * Remove `fixed` module from `primitives` * Fix formatting * . * Rewrite math functions * Remove training wheels * Fix docs.pdf * Fix quotes * Add tests for buying * Add tests for selling and improve error names * Update docs * Check adjusted amount in for numerical bounds * Remove unused implementations * Adjust docs * Add stress test exploring various scenarios * Add swap fees to stress test * Add underscore separators * Clean up * Benchmark `buy` as function of `asset_count` * Update benchmarks * Clippy fix * Fix benchmark tests * Update benchmarks of zrml-prediction-markets * Fix broken comment * Add comment explaining benchmark spot prices * Use clearer constants for `amount_in` in tests * Update zrml/neo-swaps/src/traits/pool_operations.rs Co-authored-by: Chralt * Fix botched merge * Fix merge * Update benchmarks * Remove `pool_*_subsidy` * Remove `distribute_pool_share_rewards` * Remove `end_subsidy_phase` * Remove `destroy_pool_in_subsidy_phase` * Remove `MinSubsidy*` * Remove `SubsidyProviders` * Remove `start_subsidy` * Rewrite `create_pool` * Rewrite `swap_exact_amount_in` * Rewrite `swap_exact_amount_out` * Rewrite utility functions * Remove Rikiddo from weight calculation * Remove Rikiddo from zrml-swaps * Remove unused errors * Remove `ScoringRule::Rikiddo...` * Remove `*SubsidyPeriod` * Remove Rikiddo-related storage and events * Remove automatic opening of pools * Remove `open_pool` from prediction-markets * Remove `Swaps::close_pool` from prediction-markets * Remove `clean_up_pool` from prediction-markets * Remove `clean_up_pool` from `Swaps` trait * Remove CPMM deployment from prediction-markets * Remove automatic arbitrage * Move `market_account` back to prediction-markets * Remove unused market states * Fix fuzz tests * Implement market migration * Minor changes * Fix migration behavior * Remove creator fees from swaps * Fix try-runtime * Fix clippy issues * Remove `LiquidityMining` from swaps * Fix `get_spot_prices` * Take first step to remove `MarketCommons` from swaps * Remove `MarketCommons` from swaps * Rewrite `PoolStatus` * Move `Pool*` to swaps * Use `Bounded*` types in `Pool` * Finish swaps migration * Add missing files * Fix formatting and clippy errors * Remove `pool_status.rs` * Ignore doctests * Fix fuzz tests * Add prediciton-markets migration * Test prediction-markets migration * Finish tests of the market-commons migration * Add migrations to runtime and fix various errors * Clean up * Clean up * Format code * Fix pool migration behavior * Remove `MarketId` from swaps * Fix formatting * Fix formatting * Remove `CPMM` and allow other scoring rules on Battery Station * Update macros/Cargo.toml Co-authored-by: Harald Heckmann * Update primitives/src/traits/zeitgeist_asset.rs Co-authored-by: Harald Heckmann * Update zrml/market-commons/src/migrations.rs Co-authored-by: Harald Heckmann * Update zrml/swaps/src/migrations.rs Co-authored-by: Harald Heckmann * Update zrml/swaps/src/migrations.rs Co-authored-by: Harald Heckmann * Update zrml/prediction-markets/src/migrations.rs Co-authored-by: Harald Heckmann * Update zrml/market-commons/src/migrations.rs Co-authored-by: Harald Heckmann * Clean up TODOs/FIXMEs * Update changelog * Make more changes to changelog * Clear zrml-swaps storage * Remove cfg-if dependency * Fix formatting * Trigger CI * Update copyright notices * Update docs/changelog_for_devs.md Co-authored-by: Chralt * Make benchmark helper only available if feature flags are set * Remove `ZeitgeistAsset` trait * Remove preliminary benchmarks with more steps * Format code * Fix copyright notice --------- Co-authored-by: Chralt Co-authored-by: Harald Heckmann * Merge release v0.4.3 (#1211) * Use hotfixed `exp` * Reorganize tests * Fix formatting * Bump versions to v0.4.3 * Update spec versions * Add missing version bumps * Format * Update licenses --------- Co-authored-by: Malte Kliemann Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Reduce `market_status_manager` aka `on_initialize` iterations (#1160) * remove dangerous loop * limit iterations of dangerous loop * reintegrate last time frame storage item * wip * benchmark manual close and open * fix stall test * emit event and log for recovery time frame * add tests * add trailing comma * Update zrml/prediction-markets/src/benchmarks.rs Co-authored-by: Malte Kliemann * change should_be_closed condition * Apply suggestions from code review Co-authored-by: Malte Kliemann * change recursion limit line * regard period not started yet * add error tests * correct benchmarks * fix after merge and clippy * use turbofish, add test checks * remove manually open broken market * correct errors and call index * correct wrong error name * correct position of call index * correct error position * update copyrights * fix after merge * Update zrml/prediction-markets/src/benchmarks.rs Co-authored-by: Malte Kliemann * set market end for manual close --------- Co-authored-by: Malte Kliemann Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Update style guide to streamline reviews (#1228) * Reduce benchmark runs of Zeitgeist pallets (#1233) Reduce bencharm runs of Zeitgeist pallets Running benchmarks of Zeitgeist pallets on the Zeitgeist reference machine currently takes four days. * Set inflation to more than zero for a full benchmark of handle_inflation (#1234) Update benchmarks.rs * Implement `force_pool_exit` and disable other zrml-swaps functions (#1235) * Abstract `pool_exit` business logic into `do_*` function * Add `force_pool_exit` and test * Install call filters for zrml-swaps * Implement and test `bmul_bdiv_*`; use in zrml-orderbook and zrml-parimutuel (#1223) * Implement and test `bmul_bdiv_*` * Use `bmul_bdiv_*` in pallets * Update copyright * Utilize Merigify's Merge Queue (#1243) ci(Mergify): configuration update Signed-off-by: Harald Heckmann * Set in-progress when needed and rerun CI in merge queue (#1244) * Set in-progress when need and rerun CI in merge queue --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Avoid mergify dequeue (#1245) * Avoid mergify deque * Set review needed only shortly after Mergify commit * Extend neo-swaps tests and clean up `math.rs` (#1238) * Add tests to neo-swaps that check large buy/sell amounts at high liquidity * Use new implementation of HydraDX's `exp` * Add failure tests to neo-swaps's `math.rs` * Fix formatting * Update copyright notices --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Remove migrations and dead code (#1241) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Reorganize prediction-market tests (#1242) * Rename `tests.rs` to `old_tests.rs` to avoid naming conflicts * Move `buy_complete_set` tests to new tests * Clean up `buy_complete_set` tests * Extract `sell_complete_set_tests` * Clean up `sell_complete_set` tests * Extract `admin_move_market_to_closed` tests * Extract `create_market` tests * Extract `admin_move_market_to_resolved` tests * Remove superfluous test * Extract more `create_market` tests * Extract `approve_market` tests * Extract `edit_market` tests * Extract `edit_market` tests * Add `on_market_close` tests * Extract `manually_close_market` tests * Extract `on_initialize` tests * Extract `report` tests * Extract `dispute` tests * Extract `schedule_early_close` tests * Extract `dispute_early_close` tests * Extract `reject_early_close` tests * Extract more `dispute` tests * Extract `close_trusted_market` tests * Extract `start_global_dispute` tests * Extract `redeem_shares` tests and add missing tests * Extract `on_resolution` and additional `redeem_shares` tests * Move integration tests into new test module * Automatically set block to `1` at the start of test * Replace `crate::Config` with `Config` * Access constant through `Config` * Add TODOs for missing execution paths * Fix formatting --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Improve fee payment management (#1246) * Improve fee payment management * Make code compileable * Do not remit TX fees for redeem_shares Co-authored-by: Malte Kliemann --------- Co-authored-by: Malte Kliemann Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix Rust and Discord badge (#1247) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix neo-swaps doc strings (#1250) * Improve `SellExecuted` documentation * Clean up math in comments and doc strings * Fix formatting * Adjust style guide (loops) and add unreachable macro (#1252) * Adjust style guide (loops) and add unreachable macro * Add macros module to lib.rs * Update docs/STYLE_GUIDE.md Co-authored-by: Malte Kliemann * Move macro to zeitgeist-macros and add examples --------- Co-authored-by: Malte Kliemann * Merge Old* and New* asset variants * Partially integrate lazy migration routing * Integrate lazy migration routing * Fix ExistentialDeposit mapping & Satisfy Clippy * Remove primitives/macros * Filter certain asset destroy calls (they're managed) * Integrate asset destruction into prediction markets * Add BaseAssetClass * Update prediction-markets & market-commons * Update authorized * Update liquidity-mining * Update simple-disputes * Update parimutuels (wip) * Move functions into market struct and properly delete assets * Add ParimutuelAssetClass * Add parimutuel.rs * Remove duplicate code * Adjust asset type and managed destroy after refund in parimutuels * Add MarketTransitionApi This will allow prediction-markets to signal other pallets that state transitions happened * Add MarketTransitionApi * Implement MarketTransitionApi for Parimutuels * Partially implement asset creation/destruction in parimutuels * Add all asset creation / destruction tests to parimutuels * Adjust Court * Update global-disputes * Update swaps * Update neo-swaps * Integrate OnStateTransition hooks into prediction-markets * Use proper state transition weights * Make cargo check succeed * Partially update orderbook * Update orderbook * Update orderbook * Finalize orderbook update * Improve style * Add XcmAssetClass * Add sub asset classes, extend Market, provide market transition trait * Update asset-router * Integrate asset system into prediction-market, market-commons and parimutuel - Market commons now uses the BaseAsset class for base assets - Prediction markets now creates and destroys MarketAssets only if market.is_redeemable - Prediction markets now calls OnStateTransition when transitioning it's state - Parimutuel markets now implements StateTransitionApi - Parimutuel markets now properly creates and destroys ParimutuelShares * Implement support for non-reservable assets in orderbook * Integrate new asset system into Battery Station XCM * Integrate new asset system into Zeitgeist XCM * Fix conditional import * Format * Fix unfillable / unremovable order bug Co-authored-by: Chralt * Make compileable * Resolve one merge conflict * Format * Satisfy Clippy --------- Signed-off-by: Harald Heckmann Co-authored-by: Chralt Co-authored-by: Malte Kliemann Co-authored-by: Chralt98 Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- primitives/src/types.rs | 5 +- .../src/integration_tests/xcm/setup.rs | 10 +- .../xcm/tests/currency_id_convert.rs | 154 ++++++++++++------ .../integration_tests/xcm/tests/transfers.rs | 64 ++++---- runtime/battery-station/src/parameters.rs | 2 +- .../src/xcm_config/asset_registry.rs | 10 +- .../battery-station/src/xcm_config/config.rs | 32 ++-- .../battery-station/src/xcm_config/fees.rs | 4 +- runtime/common/src/fees.rs | 20 +-- runtime/common/src/lib.rs | 4 +- .../src/integration_tests/xcm/setup.rs | 12 +- .../xcm/tests/currency_id_convert.rs | 154 ++++++++++++------ .../integration_tests/xcm/tests/transfers.rs | 85 +++++----- runtime/zeitgeist/src/parameters.rs | 2 +- .../src/xcm_config/asset_registry.rs | 10 +- runtime/zeitgeist/src/xcm_config/config.rs | 32 ++-- runtime/zeitgeist/src/xcm_config/fees.rs | 4 +- zrml/neo-swaps/src/mock.rs | 2 +- zrml/neo-swaps/src/tests/join.rs | 1 + zrml/orderbook/src/lib.rs | 2 +- zrml/prediction-markets/src/lib.rs | 9 +- zrml/prediction-markets/src/mock.rs | 7 +- 22 files changed, 379 insertions(+), 246 deletions(-) diff --git a/primitives/src/types.rs b/primitives/src/types.rs index 76290a56d..68ce0b1c1 100644 --- a/primitives/src/types.rs +++ b/primitives/src/types.rs @@ -104,9 +104,12 @@ pub type Currencies = CurrencyClass; /// Asset type representing assets used by prediction markets. pub type MarketAsset = MarketAssetClass; -/// Asset type representing types used in parimutuel markets. +/// Asset type representing assets used in parimutuel markets. pub type ParimutuelAsset = ParimutuelAssetClass; +/// Asset type representing assets that can be transferred via XCM. +pub type XcmAsset = XcmAssetClass; + /// 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, diff --git a/runtime/battery-station/src/integration_tests/xcm/setup.rs b/runtime/battery-station/src/integration_tests/xcm/setup.rs index 24d4be69c..092184ade 100644 --- a/runtime/battery-station/src/integration_tests/xcm/setup.rs +++ b/runtime/battery-station/src/integration_tests/xcm/setup.rs @@ -27,7 +27,7 @@ use xcm::{ latest::{Junction::Parachain, Junctions::X2, MultiLocation}, VersionedMultiLocation, }; -use zeitgeist_primitives::types::{Currencies, CustomMetadata}; +use zeitgeist_primitives::types::{CustomMetadata, XcmAsset}; pub(super) struct ExtBuilder { balances: Vec<(AccountId, Assets, Balance)>, @@ -106,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: 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); +pub const FOREIGN_ZTG_ID: XcmAsset = XcmAsset::ForeignAsset(0); +pub const FOREIGN_PARENT_ID: XcmAsset = XcmAsset::ForeignAsset(1); +pub const FOREIGN_SIBLING_ID: XcmAsset = XcmAsset::ForeignAsset(2); +pub const BTC_ID: XcmAsset = XcmAsset::ForeignAsset(3); #[inline] pub(super) const fn ztg(amount: Balance) -> Balance { diff --git a/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs b/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs index a51401686..e28c94407 100644 --- a/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs +++ b/runtime/battery-station/src/integration_tests/xcm/tests/currency_id_convert.rs @@ -26,82 +26,97 @@ use crate::{ test_net::Zeitgeist, }, xcm_config::config::{battery_station, general_key, AssetConvert}, - Assets, + Assets, CustomMetadata, ScalarPosition, XcmAsset, }; - +use core::fmt::Debug; use frame_support::assert_err; use sp_runtime::traits::Convert as C2; +use test_case::test_case; use xcm::latest::{Junction::*, Junctions::*, MultiLocation}; use xcm_emulator::TestExt; use xcm_executor::traits::Convert as C1; -#[test] -fn convert_native() { +fn convert_common_native(expected: T) +where + T: Copy + Debug + PartialEq, + AssetConvert: C1 + C2>, +{ assert_eq!(battery_station::KEY.to_vec(), vec![0, 1]); // The way Ztg is represented relative within the Zeitgeist runtime let ztg_location_inner: MultiLocation = MultiLocation::new(0, X1(general_key(battery_station::KEY))); - assert_eq!(>::convert(ztg_location_inner), Ok(Assets::Ztg)); + assert_eq!(>::convert(ztg_location_inner), Ok(expected)); // The canonical way Ztg is represented out in the wild Zeitgeist::execute_with(|| { - assert_eq!( - >::convert(Assets::Ztg), - Some(foreign_ztg_multilocation()) - ) + assert_eq!(>::convert(expected), Some(foreign_ztg_multilocation())) }); } -#[test] -fn convert_any_registered_parent_multilocation() { +fn convert_common_non_native( + expected: T, + multilocation: MultiLocation, + register: fn(Option), +) where + T: Copy + Debug + PartialEq, + AssetConvert: C1 + C2>, +{ Zeitgeist::execute_with(|| { - assert_err!( - >::convert(foreign_parent_multilocation()), - foreign_parent_multilocation() - ); - - assert_eq!(>::convert(Assets::from(FOREIGN_PARENT_ID)), None); - + assert_err!(>::convert(multilocation), multilocation); + assert_eq!(>::convert(expected), None); // Register parent as foreign asset in the Zeitgeist parachain - register_foreign_parent(None); - - assert_eq!( - >::convert(foreign_parent_multilocation()), - Ok(FOREIGN_PARENT_ID.into()), - ); - - assert_eq!( - >::convert(Assets::from(FOREIGN_PARENT_ID)), - Some(foreign_parent_multilocation()) - ); + register(None); + assert_eq!(>::convert(multilocation), Ok(expected)); + assert_eq!(>::convert(expected), Some(multilocation)); }); } #[test] -fn convert_any_registered_sibling_multilocation() { - Zeitgeist::execute_with(|| { - assert_err!( - >::convert(foreign_sibling_multilocation()), - foreign_sibling_multilocation() - ); +fn convert_native_assets() { + convert_common_native(Assets::Ztg); +} - assert_eq!(>::convert(Assets::from(FOREIGN_SIBLING_ID)), None); +#[test] +fn convert_native_xcm_assets() { + convert_common_native(XcmAsset::Ztg); +} - // Register sibling as foreign asset in the Zeitgeist parachain - register_foreign_sibling(None); +#[test] +fn convert_any_registered_parent_multilocation_assets() { + convert_common_non_native( + Assets::from(FOREIGN_PARENT_ID), + foreign_parent_multilocation(), + register_foreign_parent, + ); +} - assert_eq!( - >::convert(foreign_sibling_multilocation()), - Ok(FOREIGN_SIBLING_ID.into()), - ); +#[test] +fn convert_any_registered_parent_multilocation_xcm_assets() { + convert_common_non_native( + XcmAsset::try_from(Assets::from(FOREIGN_PARENT_ID)).unwrap(), + foreign_parent_multilocation(), + register_foreign_parent, + ); +} - assert_eq!( - >::convert(Assets::from(FOREIGN_SIBLING_ID)), - Some(foreign_sibling_multilocation()) - ); - }); +#[test] +fn convert_any_registered_sibling_multilocation_assets() { + convert_common_non_native( + Assets::from(FOREIGN_SIBLING_ID), + foreign_sibling_multilocation(), + register_foreign_sibling, + ); +} + +#[test] +fn convert_any_registered_sibling_multilocation_xcm_assets() { + convert_common_non_native( + XcmAsset::try_from(Assets::from(FOREIGN_SIBLING_ID)).unwrap(), + foreign_sibling_multilocation(), + register_foreign_sibling, + ); } #[test] @@ -110,13 +125,46 @@ fn convert_unkown_multilocation() { MultiLocation::new(1, X2(Parachain(battery_station::ID), general_key(&[42]))); Zeitgeist::execute_with(|| { - assert!(>::convert(unknown_location).is_err()); + assert!(>::convert(unknown_location).is_err()); }); } -#[test] -fn convert_unsupported_currency() { - Zeitgeist::execute_with(|| { - assert_eq!(>::convert(Assets::PoolShare(42)), None) - }); +#[test_case( + Assets::CategoricalOutcome(7, 8); + "assets_categorical" +)] +#[test_case( + Assets::ScalarOutcome(7, ScalarPosition::Long); + "assets_scalar" +)] +#[test_case( + Assets::PoolShare(7); + "assets_pool_share" +)] +#[test_case( + Assets::ForeignAsset(7); + "assets_foreign" +)] +#[test_case( + Assets::ParimutuelShare(7, 8); + "assets_parimutuel_share" +)] +#[test_case( + Assets::CampaignAsset(7); + "assets_campaign_asset" +)] +#[test_case( + Assets::CustomAsset(7); + "assets_custom_asset" +)] +#[test_case( + XcmAsset::ForeignAsset(7); + "xcm_assets_foreign" +)] +fn convert_unsupported_asset(asset: T) +where + T: Copy + Debug + PartialEq, + AssetConvert: C2>, +{ + Zeitgeist::execute_with(|| assert_eq!(>::convert(asset), None)); } diff --git a/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs b/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs index 149a7f093..109a388dd 100644 --- a/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs +++ b/runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs @@ -26,7 +26,7 @@ use crate::{ test_net::{RococoNet, Sibling, TestNet, Zeitgeist}, }, xcm_config::{config::battery_station, fees::default_per_second}, - AssetRegistry, Assets, Balance, Balances, RuntimeOrigin, Tokens, XTokens, + AssetManager, AssetRegistry, Balance, Balances, RuntimeOrigin, XTokens, ZeitgeistTreasuryAccount, }; @@ -36,7 +36,7 @@ use xcm::latest::{Junction, Junction::*, Junctions::*, MultiLocation, WeightLimi use xcm_emulator::TestExt; use zeitgeist_primitives::{ constants::{BalanceFractionalDecimals, BASE}, - types::{CustomMetadata, XcmMetadata}, + types::{CustomMetadata, XcmAsset, XcmMetadata}, }; #[test] @@ -49,8 +49,8 @@ fn transfer_ztg_to_sibling() { Sibling::execute_with(|| { treasury_initial_balance = - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()); - assert_eq!(Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), 0); + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); + assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); register_foreign_ztg(None); }); @@ -59,7 +59,7 @@ fn transfer_ztg_to_sibling() { assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - Assets::Ztg, + XcmAsset::Ztg, transfer_amount, Box::new( MultiLocation::new( @@ -82,14 +82,14 @@ fn transfer_ztg_to_sibling() { }); Sibling::execute_with(|| { - let current_balance = Tokens::free_balance(FOREIGN_ZTG_ID, &BOB); + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); // Verify that BOB now has (amount transferred - fee) assert_eq!(current_balance, transfer_amount - ztg_fee()); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), treasury_initial_balance + ztg_fee() ) }); @@ -123,10 +123,10 @@ fn transfer_ztg_sibling_to_zeitgeist() { Sibling::execute_with(|| { assert_eq!(Balances::free_balance(zeitgeist_parachain_account()), 0); - assert_eq!(Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), bob_initial_balance); + assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), bob_initial_balance); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(BOB), - FOREIGN_ZTG_ID.into(), + FOREIGN_ZTG_ID, transfer_amount, Box::new( MultiLocation::new( @@ -143,7 +143,7 @@ fn transfer_ztg_sibling_to_zeitgeist() { // Confirm that Bobs's balance is initial balance - amount transferred assert_eq!( - Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), bob_initial_balance - transfer_amount ); }); @@ -181,8 +181,12 @@ fn transfer_btc_sibling_to_zeitgeist() { Zeitgeist::execute_with(|| { register_btc(None); - treasury_initial_balance = Tokens::free_balance(BTC_ID, &ZeitgeistTreasuryAccount::get()); - assert_eq!(Tokens::free_balance(BTC_ID, &ALICE), zeitgeist_alice_initial_balance,); + treasury_initial_balance = + AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()); + assert_eq!( + AssetManager::free_balance(BTC_ID.into(), &ALICE), + zeitgeist_alice_initial_balance, + ); }); Sibling::execute_with(|| { @@ -196,8 +200,8 @@ fn transfer_btc_sibling_to_zeitgeist() { )); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - // Target chain will interpret Assets::Ztg as BTC in this context. - Assets::Ztg, + // Target chain will interpret XcmAsset::Ztg as BTC in this context. + XcmAsset::Ztg, transfer_amount, Box::new( MultiLocation::new( @@ -228,13 +232,13 @@ fn transfer_btc_sibling_to_zeitgeist() { // Verify that remote Alice now has initial balance + amount transferred - fee assert_eq!( - Tokens::free_balance(BTC_ID, &ALICE), + AssetManager::free_balance(BTC_ID.into(), &ALICE), zeitgeist_alice_initial_balance + expected_adjusted, ); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(BTC_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()), // Align decimal fractional places treasury_initial_balance + adjusted_balance(btc(1), btc_fee()) ) @@ -252,13 +256,13 @@ fn transfer_btc_zeitgeist_to_sibling() { transfer_btc_sibling_to_zeitgeist(); Sibling::execute_with(|| { - assert_eq!(Tokens::free_balance(BTC_ID, &BOB), sibling_bob_initial_balance,); + assert_eq!(AssetManager::free_balance(BTC_ID.into(), &BOB), sibling_bob_initial_balance,); }); Zeitgeist::execute_with(|| { assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - BTC_ID.into(), + BTC_ID, transfer_amount, Box::new( MultiLocation::new( @@ -274,7 +278,7 @@ fn transfer_btc_zeitgeist_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Tokens::free_balance(BTC_ID, &ALICE), 0); + assert_eq!(AssetManager::free_balance(BTC_ID.into(), &ALICE), 0); }); Sibling::execute_with(|| { @@ -302,7 +306,7 @@ fn transfer_roc_from_relay_chain() { Zeitgeist::execute_with(|| { register_foreign_parent(None); treasury_initial_balance = - Tokens::free_balance(FOREIGN_PARENT_ID, &ZeitgeistTreasuryAccount::get()); + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ZeitgeistTreasuryAccount::get()); }); RococoNet::execute_with(|| { @@ -321,10 +325,10 @@ fn transfer_roc_from_relay_chain() { Zeitgeist::execute_with(|| { let expected = transfer_amount - roc_fee(); let expected_adjusted = adjusted_balance(roc(1), expected); - assert_eq!(Tokens::free_balance(FOREIGN_PARENT_ID, &BOB), expected_adjusted); + assert_eq!(AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &BOB), expected_adjusted); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(FOREIGN_PARENT_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ZeitgeistTreasuryAccount::get()), // Align decimal fractional places treasury_initial_balance + adjusted_balance(roc(1), roc_fee()) ) @@ -340,12 +344,12 @@ fn transfer_roc_to_relay_chain() { transfer_roc_from_relay_chain(); Zeitgeist::execute_with(|| { - let initial_balance = Tokens::free_balance(FOREIGN_PARENT_ID, &ALICE); + let initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE); assert!(initial_balance >= transfer_amount); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - FOREIGN_PARENT_ID.into(), + FOREIGN_PARENT_ID, transfer_amount, Box::new( MultiLocation::new(1, X1(Junction::AccountId32 { id: BOB.into(), network: None })) @@ -355,7 +359,7 @@ fn transfer_roc_to_relay_chain() { )); assert_eq!( - Tokens::free_balance(FOREIGN_PARENT_ID, &ALICE), + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE), initial_balance - transfer_amount_local ) }); @@ -377,8 +381,8 @@ fn transfer_ztg_to_sibling_with_custom_fee() { Sibling::execute_with(|| { treasury_initial_balance = - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()); - assert_eq!(Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), 0); + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); + assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); register_foreign_ztg(None); let custom_metadata = CustomMetadata { @@ -401,7 +405,7 @@ fn transfer_ztg_to_sibling_with_custom_fee() { assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - Assets::Ztg, + XcmAsset::Ztg, transfer_amount, Box::new( MultiLocation::new( @@ -424,7 +428,7 @@ fn transfer_ztg_to_sibling_with_custom_fee() { }); Sibling::execute_with(|| { - let current_balance = Tokens::free_balance(FOREIGN_ZTG_ID, &BOB); + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); let custom_fee = calc_fee(default_per_second(10) * 10); // Verify that BOB now has (amount transferred - fee) @@ -432,7 +436,7 @@ fn transfer_ztg_to_sibling_with_custom_fee() { // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), treasury_initial_balance + custom_fee ) }); diff --git a/runtime/battery-station/src/parameters.rs b/runtime/battery-station/src/parameters.rs index e5892fc62..e3f43ce33 100644 --- a/runtime/battery-station/src/parameters.rs +++ b/runtime/battery-station/src/parameters.rs @@ -519,7 +519,7 @@ parameter_type_with_key! { Currencies::ForeignAsset(id) => { let maybe_metadata = < orml_asset_registry::Pallet as orml_traits::asset_registry::Inspect - >::metadata(&Currencies::ForeignAsset(*id)); + >::metadata(&XcmAsset::ForeignAsset(*id)); if let Some(metadata) = maybe_metadata { return metadata.existential_deposit; diff --git a/runtime/battery-station/src/xcm_config/asset_registry.rs b/runtime/battery-station/src/xcm_config/asset_registry.rs index 20d23e90d..9deb85aa0 100644 --- a/runtime/battery-station/src/xcm_config/asset_registry.rs +++ b/runtime/battery-station/src/xcm_config/asset_registry.rs @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{Balance, Currencies}; +use crate::{Balance, XcmAsset}; use orml_traits::asset_registry::{AssetMetadata, AssetProcessor}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; @@ -29,11 +29,11 @@ use zeitgeist_primitives::types::CustomMetadata; /// Only pre check is to ensure an asset id was passed. pub struct CustomAssetProcessor; -impl AssetProcessor> for CustomAssetProcessor { +impl AssetProcessor> for CustomAssetProcessor { fn pre_register( - id: Option, + id: Option, metadata: AssetMetadata, - ) -> Result<(Currencies, AssetMetadata), DispatchError> { + ) -> Result<(XcmAsset, AssetMetadata), DispatchError> { match id { Some(id) => Ok((id, metadata)), None => Err(DispatchError::Other("asset-registry: AssetId is required")), @@ -41,7 +41,7 @@ impl AssetProcessor> for Cust } fn post_register( - _id: Currencies, + _id: XcmAsset, _asset_metadata: AssetMetadata, ) -> Result<(), DispatchError> { Ok(()) diff --git a/runtime/battery-station/src/xcm_config/config.rs b/runtime/battery-station/src/xcm_config/config.rs index ef4a1da90..c68d81f3d 100644 --- a/runtime/battery-station/src/xcm_config/config.rs +++ b/runtime/battery-station/src/xcm_config/config.rs @@ -51,10 +51,7 @@ use xcm_builder::{ TakeWeightCredit, }; use xcm_executor::{traits::TransactAsset, Assets as ExecutorAssets, Config}; -use zeitgeist_primitives::{ - constants::BalanceFractionalDecimals, - types::{Asset, Currencies}, -}; +use zeitgeist_primitives::{constants::BalanceFractionalDecimals, types::XcmAsset}; pub mod battery_station { #[cfg(test)] @@ -214,7 +211,7 @@ pub struct AlignedFractionalTransactAsset< } impl< - AssetRegistry: Inspect, + AssetRegistry: Inspect, FracDecPlaces: Get, CurrencyIdConvert: Convert>, TransactAssetDelegate: TransactAsset, @@ -238,7 +235,7 @@ impl< return asset.clone(); }; - let currency = if let Ok(currency) = Currencies::try_from(asset_id) { + let currency = if let Ok(currency) = XcmAsset::try_from(asset_id) { currency } else { return asset.clone(); @@ -269,7 +266,7 @@ impl< } impl< - AssetRegistry: Inspect, + AssetRegistry: Inspect, CurrencyIdConvert: Convert>, FracDecPlaces: Get, TransactAssetDelegate: TransactAsset, @@ -350,22 +347,28 @@ pub struct AssetConvert; impl Convert> for AssetConvert { fn convert(id: Assets) -> Option { match id { - Asset::Ztg => Some(MultiLocation::new( + Assets::Ztg => Some(MultiLocation::new( 1, X2( Junction::Parachain(ParachainInfo::parachain_id().into()), general_key(battery_station::KEY), ), )), - Asset::ForeignAsset(_) => { - let currency = Currencies::try_from(id).ok()?; - AssetRegistry::multilocation(¤cy).ok()? + Assets::ForeignAsset(_) => { + let asset = XcmAsset::try_from(id).ok()?; + AssetRegistry::multilocation(&asset).ok()? } _ => None, } } } +impl Convert> for AssetConvert { + fn convert(id: XcmAsset) -> Option { + >>::convert(id.into()) + } +} + /// Convert an incoming `MultiLocation` into a `Asset` if possible. /// Here we need to know the canonical representation of all the tokens we handle in order to /// correctly convert their `MultiLocation` representation into our internal `Asset` type. @@ -402,6 +405,13 @@ impl xcm_executor::traits::Convert for AssetConvert { } } +impl xcm_executor::traits::Convert for AssetConvert { + fn convert(location: MultiLocation) -> Result { + >::convert(location) + .and_then(|asset| asset.try_into().map_err(|_| location)) + } +} + impl Convert> for AssetConvert { fn convert(asset: MultiAsset) -> Option { if let MultiAsset { id: Concrete(location), .. } = asset { diff --git a/runtime/battery-station/src/xcm_config/fees.rs b/runtime/battery-station/src/xcm_config/fees.rs index 29ae027ab..bc6178eee 100644 --- a/runtime/battery-station/src/xcm_config/fees.rs +++ b/runtime/battery-station/src/xcm_config/fees.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{Balance, Currencies}; +use crate::{Balance, XcmAsset}; use core::marker::PhantomData; use frame_support::weights::constants::{ExtrinsicBaseWeight, WEIGHT_REF_TIME_PER_SECOND}; use xcm::latest::MultiLocation; @@ -56,7 +56,7 @@ pub struct FixedConversionRateProvider(PhantomData impl< AssetRegistry: orml_traits::asset_registry::Inspect< - AssetId = Currencies, + AssetId = XcmAsset, Balance = Balance, CustomMetadata = CustomMetadata, >, diff --git a/runtime/common/src/fees.rs b/runtime/common/src/fees.rs index b3072c061..ff2f0a0ea 100644 --- a/runtime/common/src/fees.rs +++ b/runtime/common/src/fees.rs @@ -95,7 +95,7 @@ macro_rules! impl_foreign_fees { // It does calculate foreign fees by extending transactions to include an optional // `AssetId` that specifies the asset to be used for payment (defaulting to the native // token on `None`), such that for each transaction the asset id can be specified. - // For real ZTG `None` is used and for DOT `Some(Currencies::Foreign(0))` is used. + // For real ZTG `None` is used and for DOT `Some(Currencies::ForeignAsset(0))` is used. pub(crate) fn calculate_fee( native_fee: Balance, @@ -118,7 +118,7 @@ macro_rules! impl_foreign_fees { #[cfg(feature = "parachain")] pub(crate) fn get_fee_factor( - currency: Currencies, + currency: XcmAsset, ) -> Result { let metadata = ::metadata(¤cy).ok_or( TransactionValidityError::Invalid(InvalidTransaction::Custom( @@ -142,7 +142,7 @@ macro_rules! impl_foreign_fees { ) -> Result { #[cfg(feature = "parachain")] { - let currency = Currencies::ForeignAsset(currency_id); + let currency = XcmAsset::ForeignAsset(currency_id); let fee_factor = get_fee_factor(currency)?; let converted_fee = calculate_fee(native_fee, fee_factor)?; Ok(converted_fee) @@ -387,7 +387,7 @@ macro_rules! fee_tests { }; let dot = Currencies::ForeignAsset(0); - assert_ok!(AssetRegistry::register_asset(RuntimeOrigin::root(), meta.clone(), Some(dot))); + assert_ok!(AssetRegistry::register_asset(RuntimeOrigin::root(), meta.clone(), Some(Assets::from(dot).try_into().unwrap()))); assert_ok!(>::deposit(dot, &Treasury::account_id(), BASE)); @@ -454,7 +454,7 @@ macro_rules! fee_tests { additional: custom_metadata, }; let dot_asset_id = 0u32; - let dot = Currencies::ForeignAsset(dot_asset_id); + let dot = XcmAsset::ForeignAsset(dot_asset_id); assert_ok!(AssetRegistry::register_asset( RuntimeOrigin::root(), @@ -476,7 +476,7 @@ macro_rules! fee_tests { { // no registering of dot assert_noop!( - get_fee_factor(Currencies::ForeignAsset(0)), + get_fee_factor(XcmAsset::ForeignAsset(0)), TransactionValidityError::Invalid(InvalidTransaction::Custom(2u8)) ); } @@ -505,7 +505,7 @@ macro_rules! fee_tests { additional: custom_metadata, }; let dot_asset_id = 0u32; - let dot = Currencies::ForeignAsset(dot_asset_id); + let dot = XcmAsset::ForeignAsset(dot_asset_id); assert_ok!(AssetRegistry::register_asset( RuntimeOrigin::root(), @@ -539,12 +539,12 @@ macro_rules! fee_tests { location: None, additional: custom_metadata, }; - let non_location_token = Currencies::ForeignAsset(1); + let non_location_token = XcmAsset::ForeignAsset(1); assert_ok!(AssetRegistry::register_asset( RuntimeOrigin::root(), meta, - Some(non_location_token) + Some(Assets::from(non_location_token).try_into().unwrap()) )); assert_eq!(get_fee_factor(non_location_token).unwrap(), 10_393); @@ -579,7 +579,7 @@ macro_rules! fee_tests { assert_ok!(AssetRegistry::register_asset( RuntimeOrigin::root(), meta, - Some(dot) + Some(Assets::from(dot).try_into().unwrap()) )); let fees_and_tips = >::issue(dot, 0); diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index d23e3c007..dca2c2a76 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -566,7 +566,7 @@ macro_rules! impl_config_traits { #[cfg(feature = "parachain")] impl orml_asset_registry::Config for Runtime { - type AssetId = Currencies; + type AssetId = XcmAsset; type AssetProcessor = CustomAssetProcessor; type AuthorityOrigin = AsEnsureOriginWithArg; type Balance = Balance; @@ -621,7 +621,7 @@ macro_rules! impl_config_traits { type AccountIdToMultiLocation = AccountIdToMultiLocation; type Balance = Balance; type BaseXcmWeight = BaseXcmWeight; - type CurrencyId = Assets; + type CurrencyId = XcmAsset; type CurrencyIdConvert = AssetConvert; type RuntimeEvent = RuntimeEvent; type MaxAssetsForTransfer = MaxAssetsForTransfer; diff --git a/runtime/zeitgeist/src/integration_tests/xcm/setup.rs b/runtime/zeitgeist/src/integration_tests/xcm/setup.rs index bfb31474e..525a2e369 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/setup.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/setup.rs @@ -27,7 +27,7 @@ use xcm::{ latest::{Junction::Parachain, Junctions::X2, MultiLocation}, VersionedMultiLocation, }; -use zeitgeist_primitives::types::{Currencies, CustomMetadata}; +use zeitgeist_primitives::types::{CustomMetadata, XcmAsset}; pub(super) struct ExtBuilder { balances: Vec<(AccountId, Assets, Balance)>, @@ -106,11 +106,11 @@ 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: 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); -pub const ETH_ID: Currencies = Currencies::ForeignAsset(4); +pub const FOREIGN_ZTG_ID: XcmAsset = XcmAsset::ForeignAsset(0); +pub const FOREIGN_PARENT_ID: XcmAsset = XcmAsset::ForeignAsset(1); +pub const FOREIGN_SIBLING_ID: XcmAsset = XcmAsset::ForeignAsset(2); +pub const BTC_ID: XcmAsset = XcmAsset::ForeignAsset(3); +pub const ETH_ID: XcmAsset = XcmAsset::ForeignAsset(4); #[inline] pub(super) const fn ztg(amount: Balance) -> Balance { diff --git a/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs b/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs index a687a5edd..d23021334 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/tests/currency_id_convert.rs @@ -26,81 +26,96 @@ use crate::{ test_net::Zeitgeist, }, xcm_config::config::{general_key, zeitgeist, AssetConvert}, - Assets, + Assets, CustomMetadata, ScalarPosition, XcmAsset, }; - +use core::fmt::Debug; use frame_support::assert_err; use sp_runtime::traits::Convert as C2; +use test_case::test_case; use xcm::latest::{Junction::*, Junctions::*, MultiLocation}; use xcm_emulator::TestExt; use xcm_executor::traits::Convert as C1; -#[test] -fn convert_native() { +fn convert_common_native(expected: T) +where + T: Copy + Debug + PartialEq, + AssetConvert: C1 + C2>, +{ assert_eq!(zeitgeist::KEY.to_vec(), vec![0, 1]); // The way Ztg is represented relative within the Zeitgeist runtime let ztg_location_inner: MultiLocation = MultiLocation::new(0, X1(general_key(zeitgeist::KEY))); - assert_eq!(>::convert(ztg_location_inner), Ok(Assets::Ztg)); + assert_eq!(>::convert(ztg_location_inner), Ok(expected)); // The canonical way Ztg is represented out in the wild Zeitgeist::execute_with(|| { - assert_eq!( - >::convert(Assets::Ztg), - Some(foreign_ztg_multilocation()) - ) + assert_eq!(>::convert(expected), Some(foreign_ztg_multilocation())) }); } -#[test] -fn convert_any_registered_parent_multilocation() { +fn convert_common_non_native( + expected: T, + multilocation: MultiLocation, + register: fn(Option), +) where + T: Copy + Debug + PartialEq, + AssetConvert: C1 + C2>, +{ Zeitgeist::execute_with(|| { - assert_err!( - >::convert(foreign_parent_multilocation()), - foreign_parent_multilocation() - ); - - assert_eq!(>::convert(Assets::from(FOREIGN_PARENT_ID)), None); - + assert_err!(>::convert(multilocation), multilocation); + assert_eq!(>::convert(expected), None); // Register parent as foreign asset in the Zeitgeist parachain - register_foreign_parent(None); - - assert_eq!( - >::convert(foreign_parent_multilocation()), - Ok(FOREIGN_PARENT_ID.into()), - ); - - assert_eq!( - >::convert(Assets::from(FOREIGN_PARENT_ID)), - Some(foreign_parent_multilocation()) - ); + register(None); + assert_eq!(>::convert(multilocation), Ok(expected)); + assert_eq!(>::convert(expected), Some(multilocation)); }); } #[test] -fn convert_any_registered_sibling_multilocation() { - Zeitgeist::execute_with(|| { - assert_err!( - >::convert(foreign_sibling_multilocation()), - foreign_sibling_multilocation() - ); +fn convert_native_assets() { + convert_common_native(Assets::Ztg); +} - assert_eq!(>::convert(Assets::from(FOREIGN_SIBLING_ID)), None); +#[test] +fn convert_native_xcm_assets() { + convert_common_native(XcmAsset::Ztg); +} - // Register sibling as foreign asset in the Zeitgeist parachain - register_foreign_sibling(None); +#[test] +fn convert_any_registered_parent_multilocation_assets() { + convert_common_non_native( + Assets::from(FOREIGN_PARENT_ID), + foreign_parent_multilocation(), + register_foreign_parent, + ); +} - assert_eq!( - >::convert(foreign_sibling_multilocation()), - Ok(FOREIGN_SIBLING_ID.into()), - ); +#[test] +fn convert_any_registered_parent_multilocation_xcm_assets() { + convert_common_non_native( + XcmAsset::try_from(Assets::from(FOREIGN_PARENT_ID)).unwrap(), + foreign_parent_multilocation(), + register_foreign_parent, + ); +} - assert_eq!( - >::convert(Assets::from(FOREIGN_SIBLING_ID)), - Some(foreign_sibling_multilocation()) - ); - }); +#[test] +fn convert_any_registered_sibling_multilocation_assets() { + convert_common_non_native( + Assets::from(FOREIGN_SIBLING_ID), + foreign_sibling_multilocation(), + register_foreign_sibling, + ); +} + +#[test] +fn convert_any_registered_sibling_multilocation_xcm_assets() { + convert_common_non_native( + XcmAsset::try_from(Assets::from(FOREIGN_SIBLING_ID)).unwrap(), + foreign_sibling_multilocation(), + register_foreign_sibling, + ); } #[test] @@ -109,13 +124,46 @@ fn convert_unkown_multilocation() { MultiLocation::new(1, X2(Parachain(zeitgeist::ID), general_key(&[42]))); Zeitgeist::execute_with(|| { - assert!(>::convert(unknown_location).is_err()); + assert!(>::convert(unknown_location).is_err()); }); } -#[test] -fn convert_unsupported_currency() { - Zeitgeist::execute_with(|| { - assert_eq!(>::convert(Assets::PoolShare(42)), None) - }); +#[test_case( + Assets::CategoricalOutcome(7, 8); + "assets_categorical" +)] +#[test_case( + Assets::ScalarOutcome(7, ScalarPosition::Long); + "assets_scalar" +)] +#[test_case( + Assets::PoolShare(7); + "assets_pool_share" +)] +#[test_case( + Assets::ForeignAsset(7); + "assets_foreign" +)] +#[test_case( + Assets::ParimutuelShare(7, 8); + "assets_parimutuel_share" +)] +#[test_case( + Assets::CampaignAsset(7); + "assets_campaign_asset" +)] +#[test_case( + Assets::CustomAsset(7); + "assets_custom_asset" +)] +#[test_case( + XcmAsset::ForeignAsset(7); + "xcm_assets_foreign" +)] +fn convert_unsupported_asset(asset: T) +where + T: Copy + Debug + PartialEq, + AssetConvert: C2>, +{ + Zeitgeist::execute_with(|| assert_eq!(>::convert(asset), None)); } diff --git a/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs b/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs index 0222c99a3..bb5d66e3a 100644 --- a/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs +++ b/runtime/zeitgeist/src/integration_tests/xcm/tests/transfers.rs @@ -26,7 +26,7 @@ use crate::{ test_net::{PolkadotNet, Sibling, TestNet, Zeitgeist}, }, xcm_config::{config::zeitgeist, fees::default_per_second}, - AssetRegistry, Assets, Balance, Balances, RuntimeOrigin, Tokens, XTokens, + AssetManager, AssetRegistry, Balance, Balances, RuntimeOrigin, XTokens, ZeitgeistTreasuryAccount, }; @@ -36,7 +36,7 @@ use xcm::latest::{Junction, Junction::*, Junctions::*, MultiLocation, WeightLimi use xcm_emulator::TestExt; use zeitgeist_primitives::{ constants::{BalanceFractionalDecimals, BASE}, - types::{CustomMetadata, XcmMetadata}, + types::{CustomMetadata, XcmAsset, XcmMetadata}, }; #[test] @@ -49,8 +49,8 @@ fn transfer_ztg_to_sibling() { Sibling::execute_with(|| { treasury_initial_balance = - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()); - assert_eq!(Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), 0); + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); + assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); register_foreign_ztg(None); }); @@ -59,7 +59,7 @@ fn transfer_ztg_to_sibling() { assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - Assets::Ztg, + XcmAsset::Ztg, transfer_amount, Box::new( MultiLocation::new( @@ -82,14 +82,14 @@ fn transfer_ztg_to_sibling() { }); Sibling::execute_with(|| { - let current_balance = Tokens::free_balance(FOREIGN_ZTG_ID, &BOB); + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); // Verify that BOB now has (amount transferred - fee) assert_eq!(current_balance, transfer_amount - ztg_fee()); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), treasury_initial_balance + ztg_fee() ) }); @@ -123,10 +123,10 @@ fn transfer_ztg_sibling_to_zeitgeist() { Sibling::execute_with(|| { assert_eq!(Balances::free_balance(zeitgeist_parachain_account()), 0); - assert_eq!(Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), bob_initial_balance); + assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), bob_initial_balance); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(BOB), - FOREIGN_ZTG_ID.into(), + FOREIGN_ZTG_ID, transfer_amount, Box::new( MultiLocation::new( @@ -143,7 +143,7 @@ fn transfer_ztg_sibling_to_zeitgeist() { // Confirm that Bobs's balance is initial balance - amount transferred assert_eq!( - Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), bob_initial_balance - transfer_amount ); }); @@ -181,8 +181,12 @@ fn transfer_btc_sibling_to_zeitgeist() { Zeitgeist::execute_with(|| { register_btc(None); - treasury_initial_balance = Tokens::free_balance(BTC_ID, &ZeitgeistTreasuryAccount::get()); - assert_eq!(Tokens::free_balance(BTC_ID, &ALICE), zeitgeist_alice_initial_balance,); + treasury_initial_balance = + AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()); + assert_eq!( + AssetManager::free_balance(BTC_ID.into(), &ALICE), + zeitgeist_alice_initial_balance, + ); }); Sibling::execute_with(|| { @@ -196,8 +200,8 @@ fn transfer_btc_sibling_to_zeitgeist() { )); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - // Target chain will interpret Assets::Ztg as BTC in this context. - Assets::Ztg, + // Target chain will interpret XcmAsset::Ztg as BTC in this context. + XcmAsset::Ztg, transfer_amount, Box::new( MultiLocation::new( @@ -228,13 +232,13 @@ fn transfer_btc_sibling_to_zeitgeist() { // Verify that remote Alice now has initial balance + amount transferred - fee assert_eq!( - Tokens::free_balance(BTC_ID, &ALICE), + AssetManager::free_balance(BTC_ID.into(), &ALICE), zeitgeist_alice_initial_balance + expected_adjusted, ); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(BTC_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(BTC_ID.into(), &ZeitgeistTreasuryAccount::get()), // Align decimal fractional places treasury_initial_balance + adjusted_balance(btc(1), btc_fee()) ) @@ -252,13 +256,13 @@ fn transfer_btc_zeitgeist_to_sibling() { transfer_btc_sibling_to_zeitgeist(); Sibling::execute_with(|| { - assert_eq!(Tokens::free_balance(BTC_ID, &BOB), sibling_bob_initial_balance,); + assert_eq!(AssetManager::free_balance(BTC_ID.into(), &BOB), sibling_bob_initial_balance,); }); Zeitgeist::execute_with(|| { assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - BTC_ID.into(), + BTC_ID, transfer_amount, Box::new( MultiLocation::new( @@ -274,7 +278,7 @@ fn transfer_btc_zeitgeist_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Tokens::free_balance(BTC_ID, &ALICE), 0); + assert_eq!(AssetManager::free_balance(BTC_ID.into(), &ALICE), 0); }); Sibling::execute_with(|| { @@ -304,8 +308,12 @@ fn transfer_eth_sibling_to_zeitgeist() { Zeitgeist::execute_with(|| { register_eth(None); - treasury_initial_balance = Tokens::free_balance(ETH_ID, &ZeitgeistTreasuryAccount::get()); - assert_eq!(Tokens::free_balance(ETH_ID, &ALICE), zeitgeist_alice_initial_balance,); + treasury_initial_balance = + AssetManager::free_balance(ETH_ID.into(), &ZeitgeistTreasuryAccount::get()); + assert_eq!( + AssetManager::free_balance(ETH_ID.into(), &ALICE), + zeitgeist_alice_initial_balance, + ); }); Sibling::execute_with(|| { @@ -325,8 +333,8 @@ fn transfer_eth_sibling_to_zeitgeist() { )); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - // Target chain will interpret Assets::Ztg as ETH in this context. - Assets::Ztg, + // Target chain will interpret XcmAsset::Ztg as ETH in this context. + XcmAsset::Ztg, transfer_amount, Box::new( MultiLocation::new( @@ -357,13 +365,13 @@ fn transfer_eth_sibling_to_zeitgeist() { // Verify that remote Alice now has initial balance + amount transferred - fee assert_eq!( - Tokens::free_balance(ETH_ID, &ALICE), + AssetManager::free_balance(ETH_ID.into(), &ALICE), zeitgeist_alice_initial_balance + expected_adjusted, ); // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(ETH_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(ETH_ID.into(), &ZeitgeistTreasuryAccount::get()), // Align decimal fractional places treasury_initial_balance + adjusted_balance(eth(1), eth_fee()) ) @@ -381,13 +389,13 @@ fn transfer_eth_zeitgeist_to_sibling() { transfer_eth_sibling_to_zeitgeist(); Sibling::execute_with(|| { - assert_eq!(Tokens::free_balance(ETH_ID, &BOB), sibling_bob_initial_balance,); + assert_eq!(AssetManager::free_balance(ETH_ID.into(), &BOB), sibling_bob_initial_balance,); }); Zeitgeist::execute_with(|| { assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - ETH_ID.into(), + ETH_ID, transfer_amount, Box::new( MultiLocation::new( @@ -403,7 +411,7 @@ fn transfer_eth_zeitgeist_to_sibling() { )); // Confirm that Alice's balance is initial_balance - amount_transferred - assert_eq!(Tokens::free_balance(ETH_ID, &ALICE), 0); + assert_eq!(AssetManager::free_balance(ETH_ID.into(), &ALICE), 0); }); Sibling::execute_with(|| { @@ -445,7 +453,10 @@ fn transfer_dot_from_relay_chain() { }); Zeitgeist::execute_with(|| { - assert_eq!(Tokens::free_balance(FOREIGN_PARENT_ID, &BOB), transfer_amount - dot_fee()); + assert_eq!( + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &BOB), + transfer_amount - dot_fee() + ); }); } @@ -457,12 +468,12 @@ fn transfer_dot_to_relay_chain() { transfer_dot_from_relay_chain(); Zeitgeist::execute_with(|| { - let initial_balance = Tokens::free_balance(FOREIGN_PARENT_ID, &ALICE); + let initial_balance = AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE); assert!(initial_balance >= transfer_amount); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - FOREIGN_PARENT_ID.into(), + FOREIGN_PARENT_ID, transfer_amount, Box::new( MultiLocation::new(1, X1(Junction::AccountId32 { id: BOB.into(), network: None })) @@ -472,7 +483,7 @@ fn transfer_dot_to_relay_chain() { )); assert_eq!( - Tokens::free_balance(FOREIGN_PARENT_ID, &ALICE), + AssetManager::free_balance(FOREIGN_PARENT_ID.into(), &ALICE), initial_balance - transfer_amount ) }); @@ -494,8 +505,8 @@ fn transfer_ztg_to_sibling_with_custom_fee() { Sibling::execute_with(|| { treasury_initial_balance = - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()); - assert_eq!(Tokens::free_balance(FOREIGN_ZTG_ID, &BOB), 0); + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()); + assert_eq!(AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB), 0); register_foreign_ztg(None); let custom_metadata = CustomMetadata { @@ -518,7 +529,7 @@ fn transfer_ztg_to_sibling_with_custom_fee() { assert_eq!(Balances::free_balance(sibling_parachain_account()), 0); assert_ok!(XTokens::transfer( RuntimeOrigin::signed(ALICE), - Assets::Ztg, + XcmAsset::Ztg, transfer_amount, Box::new( MultiLocation::new( @@ -541,7 +552,7 @@ fn transfer_ztg_to_sibling_with_custom_fee() { }); Sibling::execute_with(|| { - let current_balance = Tokens::free_balance(FOREIGN_ZTG_ID, &BOB); + let current_balance = AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &BOB); let custom_fee = calc_fee(default_per_second(10) * 10); // Verify that BOB now has (amount transferred - fee) @@ -552,7 +563,7 @@ fn transfer_ztg_to_sibling_with_custom_fee() { // Verify that fees (of foreign currency) have been put into treasury assert_eq!( - Tokens::free_balance(FOREIGN_ZTG_ID, &ZeitgeistTreasuryAccount::get()), + AssetManager::free_balance(FOREIGN_ZTG_ID.into(), &ZeitgeistTreasuryAccount::get()), treasury_initial_balance + custom_fee ) }); diff --git a/runtime/zeitgeist/src/parameters.rs b/runtime/zeitgeist/src/parameters.rs index 3ba53e6f5..38ad05703 100644 --- a/runtime/zeitgeist/src/parameters.rs +++ b/runtime/zeitgeist/src/parameters.rs @@ -517,7 +517,7 @@ parameter_type_with_key! { Currencies::ForeignAsset(id) => { let maybe_metadata = < orml_asset_registry::Pallet as orml_traits::asset_registry::Inspect - >::metadata(&Currencies::ForeignAsset(*id)); + >::metadata(&XcmAsset::ForeignAsset(*id)); if let Some(metadata) = maybe_metadata { return metadata.existential_deposit; diff --git a/runtime/zeitgeist/src/xcm_config/asset_registry.rs b/runtime/zeitgeist/src/xcm_config/asset_registry.rs index 20d23e90d..9deb85aa0 100644 --- a/runtime/zeitgeist/src/xcm_config/asset_registry.rs +++ b/runtime/zeitgeist/src/xcm_config/asset_registry.rs @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{Balance, Currencies}; +use crate::{Balance, XcmAsset}; use orml_traits::asset_registry::{AssetMetadata, AssetProcessor}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; @@ -29,11 +29,11 @@ use zeitgeist_primitives::types::CustomMetadata; /// Only pre check is to ensure an asset id was passed. pub struct CustomAssetProcessor; -impl AssetProcessor> for CustomAssetProcessor { +impl AssetProcessor> for CustomAssetProcessor { fn pre_register( - id: Option, + id: Option, metadata: AssetMetadata, - ) -> Result<(Currencies, AssetMetadata), DispatchError> { + ) -> Result<(XcmAsset, AssetMetadata), DispatchError> { match id { Some(id) => Ok((id, metadata)), None => Err(DispatchError::Other("asset-registry: AssetId is required")), @@ -41,7 +41,7 @@ impl AssetProcessor> for Cust } fn post_register( - _id: Currencies, + _id: XcmAsset, _asset_metadata: AssetMetadata, ) -> Result<(), DispatchError> { Ok(()) diff --git a/runtime/zeitgeist/src/xcm_config/config.rs b/runtime/zeitgeist/src/xcm_config/config.rs index 6bcc84d60..27d6c1e54 100644 --- a/runtime/zeitgeist/src/xcm_config/config.rs +++ b/runtime/zeitgeist/src/xcm_config/config.rs @@ -53,10 +53,7 @@ use xcm_builder::{ TakeWeightCredit, }; use xcm_executor::{traits::TransactAsset, Assets as ExecutorAssets, Config}; -use zeitgeist_primitives::{ - constants::BalanceFractionalDecimals, - types::{Asset, Currencies}, -}; +use zeitgeist_primitives::{constants::BalanceFractionalDecimals, types::XcmAsset}; pub mod zeitgeist { #[cfg(test)] @@ -216,7 +213,7 @@ pub struct AlignedFractionalTransactAsset< } impl< - AssetRegistry: Inspect, + AssetRegistry: Inspect, FracDecPlaces: Get, CurrencyIdConvert: Convert>, TransactAssetDelegate: TransactAsset, @@ -240,7 +237,7 @@ impl< return asset.clone(); }; - let currency = if let Ok(currency) = Currencies::try_from(asset_id) { + let currency = if let Ok(currency) = XcmAsset::try_from(asset_id) { currency } else { return asset.clone(); @@ -271,7 +268,7 @@ impl< } impl< - AssetRegistry: Inspect, + AssetRegistry: Inspect, CurrencyIdConvert: Convert>, FracDecPlaces: Get, TransactAssetDelegate: TransactAsset, @@ -352,22 +349,28 @@ pub struct AssetConvert; impl Convert> for AssetConvert { fn convert(id: Assets) -> Option { match id { - Asset::Ztg => Some(MultiLocation::new( + Assets::Ztg => Some(MultiLocation::new( 1, X2( Junction::Parachain(ParachainInfo::parachain_id().into()), general_key(zeitgeist::KEY), ), )), - Asset::ForeignAsset(_) => { - let currency = Currencies::try_from(id).ok()?; - AssetRegistry::multilocation(¤cy).ok()? + Assets::ForeignAsset(_) => { + let asset = XcmAsset::try_from(id).ok()?; + AssetRegistry::multilocation(&asset).ok()? } _ => None, } } } +impl Convert> for AssetConvert { + fn convert(id: XcmAsset) -> Option { + >>::convert(id.into()) + } +} + /// Convert an incoming `MultiLocation` into a `Asset` if possible. /// Here we need to know the canonical representation of all the tokens we handle in order to /// correctly convert their `MultiLocation` representation into our internal `Asset` type. @@ -404,6 +407,13 @@ impl xcm_executor::traits::Convert for AssetConvert { } } +impl xcm_executor::traits::Convert for AssetConvert { + fn convert(location: MultiLocation) -> Result { + >::convert(location) + .and_then(|asset| asset.try_into().map_err(|_| location)) + } +} + impl Convert> for AssetConvert { fn convert(asset: MultiAsset) -> Option { if let MultiAsset { id: Concrete(location), .. } = asset { diff --git a/runtime/zeitgeist/src/xcm_config/fees.rs b/runtime/zeitgeist/src/xcm_config/fees.rs index ba3d7d56a..0b2f18661 100644 --- a/runtime/zeitgeist/src/xcm_config/fees.rs +++ b/runtime/zeitgeist/src/xcm_config/fees.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{Balance, Currencies}; +use crate::{Balance, XcmAsset}; use core::marker::PhantomData; use frame_support::weights::constants::{ExtrinsicBaseWeight, WEIGHT_REF_TIME_PER_SECOND}; use xcm::latest::MultiLocation; @@ -56,7 +56,7 @@ pub struct FixedConversionRateProvider(PhantomData impl< AssetRegistry: orml_traits::asset_registry::Inspect< - AssetId = Currencies, + AssetId = XcmAsset, Balance = Balance, CustomMetadata = CustomMetadata, >, diff --git a/zrml/neo-swaps/src/mock.rs b/zrml/neo-swaps/src/mock.rs index eae7a1789..1ef50ebe8 100644 --- a/zrml/neo-swaps/src/mock.rs +++ b/zrml/neo-swaps/src/mock.rs @@ -543,7 +543,7 @@ impl pallet_treasury::Config for Runtime { #[cfg(feature = "parachain")] zrml_prediction_markets::impl_mock_registry! { MockRegistry, - Currencies, + zeitgeist_primitives::types::XcmAsset, Balance, zeitgeist_primitives::types::CustomMetadata } diff --git a/zrml/neo-swaps/src/tests/join.rs b/zrml/neo-swaps/src/tests/join.rs index f1dde0de8..7107bf1ac 100644 --- a/zrml/neo-swaps/src/tests/join.rs +++ b/zrml/neo-swaps/src/tests/join.rs @@ -208,6 +208,7 @@ fn join_fails_on_insufficient_funds() { vec![_1_2, _1_2], CENT, ); + assert_noop!( NeoSwaps::join( RuntimeOrigin::signed(ALICE), diff --git a/zrml/orderbook/src/lib.rs b/zrml/orderbook/src/lib.rs index 27bdb2b93..cde97ae57 100644 --- a/zrml/orderbook/src/lib.rs +++ b/zrml/orderbook/src/lib.rs @@ -301,7 +301,7 @@ mod pallet { let asset = order_data.maker_asset; let amount = order_data.maker_amount; - if !T::AssetManager::reserved_balance_named(&Self::reserve_id(), asset, &maker) + if !T::AssetManager::reserved_balance_named(&Self::reserve_id(), asset, maker) .is_zero() { let missing = diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 9e6d729c6..e4d2c405c 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -58,7 +58,7 @@ mod pallet { #[cfg(feature = "parachain")] use { orml_traits::asset_registry::Inspect as RegistryInspect, - zeitgeist_primitives::types::{CurrencyClass, CustomMetadata}, + zeitgeist_primitives::types::{CustomMetadata, XcmAsset}, }; use orml_traits::{MultiCurrency, NamedMultiReservableCurrency}; @@ -1562,7 +1562,7 @@ mod pallet { #[cfg(feature = "parachain")] type AssetRegistry: RegistryInspect< - AssetId = CurrencyClass>, + AssetId = XcmAsset, Balance = BalanceOf, CustomMetadata = CustomMetadata, >; @@ -2962,10 +2962,7 @@ mod pallet { BaseAsset::Ztg => true, #[cfg(feature = "parachain")] BaseAsset::ForeignAsset(id) => { - if let Some(metadata) = - T::AssetRegistry::metadata(&CurrencyClass::>::ForeignAsset( - id, - )) + if let Some(metadata) = T::AssetRegistry::metadata(&XcmAsset::ForeignAsset(id)) { metadata.additional.allow_as_base_asset } else { diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index d30a2a962..edfc86a3f 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -68,6 +68,7 @@ use zeitgeist_primitives::{ AccountIdTest, Amount, Assets, Balance, BasicCurrencyAdapter, BlockNumber, BlockTest, CampaignAsset, CampaignAssetClass, CampaignAssetId, Currencies, CustomAsset, CustomAssetId, Hash, Index, MarketAsset, MarketId, Moment, ResultWithWeightInfo, UncheckedExtrinsicTest, + XcmAsset, }, }; @@ -333,7 +334,7 @@ impl orml_tokens::Config for Runtime { #[cfg(feature = "parachain")] crate::orml_asset_registry::impl_mock_registry! { MockRegistry, - Currencies, + XcmAsset, Balance, zeitgeist_primitives::types::CustomMetadata } @@ -644,7 +645,7 @@ impl ExtBuilder { orml_asset_registry_mock::GenesisConfig { metadata: vec![ ( - Currencies::ForeignAsset(100), + XcmAsset::ForeignAsset(100), AssetMetadata { decimals: 18, name: "ACALA USD".as_bytes().to_vec(), @@ -655,7 +656,7 @@ impl ExtBuilder { }, ), ( - Currencies::ForeignAsset(420), + XcmAsset::ForeignAsset(420), AssetMetadata { decimals: 18, name: "FANCY_TOKEN".as_bytes().to_vec(),