feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,414 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Asset Conversion pallet benchmarking.
|
||||
|
||||
use super::*;
|
||||
use crate::Pallet as AssetConversion;
|
||||
use alloc::vec;
|
||||
use core::marker::PhantomData;
|
||||
use pezframe_benchmarking::{v2::*, whitelisted_caller};
|
||||
use pezframe_support::{
|
||||
assert_ok,
|
||||
traits::{
|
||||
fungible::NativeOrWithId,
|
||||
fungibles::{Create, Inspect, Mutate, Refund},
|
||||
},
|
||||
};
|
||||
use pezframe_system::RawOrigin as SystemOrigin;
|
||||
use pezsp_core::Get;
|
||||
|
||||
/// Benchmark Helper
|
||||
pub trait BenchmarkHelper<AssetKind> {
|
||||
/// Returns a valid assets pair for the pool creation.
|
||||
///
|
||||
/// When a specific asset, such as the native asset, is required in every pool, it should be
|
||||
/// returned for each odd-numbered seed.
|
||||
fn create_pair(seed1: u32, seed2: u32) -> (AssetKind, AssetKind);
|
||||
}
|
||||
|
||||
impl<AssetKind> BenchmarkHelper<AssetKind> for ()
|
||||
where
|
||||
AssetKind: From<u32>,
|
||||
{
|
||||
fn create_pair(seed1: u32, seed2: u32) -> (AssetKind, AssetKind) {
|
||||
(seed1.into(), seed2.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Factory for creating a valid asset pairs with [`NativeOrWithId::Native`] always leading in the
|
||||
/// pair.
|
||||
pub struct NativeOrWithIdFactory<AssetId>(PhantomData<AssetId>);
|
||||
impl<AssetId: From<u32> + Ord> BenchmarkHelper<NativeOrWithId<AssetId>>
|
||||
for NativeOrWithIdFactory<AssetId>
|
||||
{
|
||||
fn create_pair(seed1: u32, seed2: u32) -> (NativeOrWithId<AssetId>, NativeOrWithId<AssetId>) {
|
||||
if seed1 % 2 == 0 {
|
||||
(NativeOrWithId::WithId(seed2.into()), NativeOrWithId::Native)
|
||||
} else {
|
||||
(NativeOrWithId::Native, NativeOrWithId::WithId(seed2.into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides a pair of amounts expected to serve as sufficient initial liquidity for a pool.
|
||||
fn valid_liquidity_amount<T: Config>(ed1: T::Balance, ed2: T::Balance) -> (T::Balance, T::Balance)
|
||||
where
|
||||
T::Assets: Inspect<T::AccountId>,
|
||||
{
|
||||
let l =
|
||||
ed1.max(ed2) + T::MintMinLiquidity::get() + T::MintMinLiquidity::get() + T::Balance::one();
|
||||
(l, l)
|
||||
}
|
||||
|
||||
/// Create the `asset` and mint the `amount` for the `caller`.
|
||||
fn create_asset<T: Config>(
|
||||
caller: &T::AccountId,
|
||||
asset: &T::AssetKind,
|
||||
amount: T::Balance,
|
||||
is_sufficient: bool,
|
||||
) where
|
||||
T::Assets: Create<T::AccountId> + Mutate<T::AccountId>,
|
||||
{
|
||||
if !T::Assets::asset_exists(asset.clone()) {
|
||||
assert_ok!(T::Assets::create(
|
||||
asset.clone(),
|
||||
caller.clone(),
|
||||
is_sufficient,
|
||||
T::Balance::one()
|
||||
));
|
||||
}
|
||||
assert_ok!(T::Assets::mint_into(
|
||||
asset.clone(),
|
||||
&caller,
|
||||
amount + T::Assets::minimum_balance(asset.clone())
|
||||
));
|
||||
}
|
||||
|
||||
/// Create the designated fee asset for pool creation.
|
||||
fn create_fee_asset<T: Config>(caller: &T::AccountId)
|
||||
where
|
||||
T::Assets: Create<T::AccountId> + Mutate<T::AccountId>,
|
||||
{
|
||||
let fee_asset = T::PoolSetupFeeAsset::get();
|
||||
if !T::Assets::asset_exists(fee_asset.clone()) {
|
||||
assert_ok!(T::Assets::create(fee_asset.clone(), caller.clone(), true, T::Balance::one()));
|
||||
}
|
||||
assert_ok!(T::Assets::mint_into(
|
||||
fee_asset.clone(),
|
||||
&caller,
|
||||
T::Assets::minimum_balance(fee_asset)
|
||||
));
|
||||
}
|
||||
|
||||
/// Mint the fee asset for the `caller` sufficient to cover the fee for creating a new pool.
|
||||
fn mint_setup_fee_asset<T: Config>(
|
||||
caller: &T::AccountId,
|
||||
asset1: &T::AssetKind,
|
||||
asset2: &T::AssetKind,
|
||||
lp_token: &T::PoolAssetId,
|
||||
) where
|
||||
T::Assets: Create<T::AccountId> + Mutate<T::AccountId>,
|
||||
{
|
||||
assert_ok!(T::Assets::mint_into(
|
||||
T::PoolSetupFeeAsset::get(),
|
||||
&caller,
|
||||
T::PoolSetupFee::get() +
|
||||
T::Assets::deposit_required(asset1.clone()) +
|
||||
T::Assets::deposit_required(asset2.clone()) +
|
||||
T::PoolAssets::deposit_required(lp_token.clone())
|
||||
));
|
||||
}
|
||||
|
||||
/// Creates a pool for a given asset pair.
|
||||
///
|
||||
/// This action mints the necessary amounts of the given assets for the `caller` to provide initial
|
||||
/// liquidity. It returns the LP token ID along with a pair of amounts sufficient for the pool's
|
||||
/// initial liquidity.
|
||||
fn create_asset_and_pool<T: Config>(
|
||||
caller: &T::AccountId,
|
||||
asset1: &T::AssetKind,
|
||||
asset2: &T::AssetKind,
|
||||
) -> (T::PoolAssetId, T::Balance, T::Balance)
|
||||
where
|
||||
T::Assets: Create<T::AccountId> + Mutate<T::AccountId>,
|
||||
{
|
||||
let (liquidity1, liquidity2) = valid_liquidity_amount::<T>(
|
||||
T::Assets::minimum_balance(asset1.clone()),
|
||||
T::Assets::minimum_balance(asset2.clone()),
|
||||
);
|
||||
create_asset::<T>(caller, asset1, liquidity1, true);
|
||||
create_asset::<T>(caller, asset2, liquidity2, true);
|
||||
let lp_token = AssetConversion::<T>::get_next_pool_asset_id();
|
||||
|
||||
mint_setup_fee_asset::<T>(caller, asset1, asset2, &lp_token);
|
||||
|
||||
assert_ok!(AssetConversion::<T>::create_pool(
|
||||
SystemOrigin::Signed(caller.clone()).into(),
|
||||
Box::new(asset1.clone()),
|
||||
Box::new(asset2.clone())
|
||||
));
|
||||
|
||||
(lp_token, liquidity1, liquidity2)
|
||||
}
|
||||
|
||||
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
|
||||
let events = pezframe_system::Pallet::<T>::events();
|
||||
let system_event: <T as pezframe_system::Config>::RuntimeEvent = generic_event.into();
|
||||
// compare to the last event record
|
||||
let pezframe_system::EventRecord { event, .. } = &events[events.len() - 1];
|
||||
assert_eq!(event, &system_event);
|
||||
}
|
||||
|
||||
#[benchmarks(where T::Assets: Create<T::AccountId> + Mutate<T::AccountId>, T::PoolAssetId: Into<u32>,)]
|
||||
mod benchmarks {
|
||||
use super::*;
|
||||
|
||||
#[benchmark]
|
||||
fn create_pool() {
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
let (asset1, asset2) = T::BenchmarkHelper::create_pair(0, 1);
|
||||
create_asset::<T>(&caller, &asset1, T::Assets::minimum_balance(asset1.clone()), true);
|
||||
create_asset::<T>(&caller, &asset2, T::Assets::minimum_balance(asset2.clone()), true);
|
||||
|
||||
let lp_token = AssetConversion::<T>::get_next_pool_asset_id();
|
||||
create_fee_asset::<T>(&caller);
|
||||
mint_setup_fee_asset::<T>(&caller, &asset1, &asset2, &lp_token);
|
||||
|
||||
#[extrinsic_call]
|
||||
_(SystemOrigin::Signed(caller.clone()), Box::new(asset1.clone()), Box::new(asset2.clone()));
|
||||
|
||||
let pool_id = T::PoolLocator::pool_id(&asset1, &asset2).unwrap();
|
||||
let pool_account = T::PoolLocator::address(&pool_id).unwrap();
|
||||
assert_last_event::<T>(
|
||||
Event::PoolCreated { creator: caller, pool_account, pool_id, lp_token }.into(),
|
||||
);
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn add_liquidity() {
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
let (asset1, asset2) = T::BenchmarkHelper::create_pair(0, 1);
|
||||
|
||||
create_fee_asset::<T>(&caller);
|
||||
let (lp_token, liquidity1, liquidity2) =
|
||||
create_asset_and_pool::<T>(&caller, &asset1, &asset2);
|
||||
|
||||
#[extrinsic_call]
|
||||
_(
|
||||
SystemOrigin::Signed(caller.clone()),
|
||||
Box::new(asset1.clone()),
|
||||
Box::new(asset2.clone()),
|
||||
liquidity1,
|
||||
liquidity2,
|
||||
T::Balance::one(),
|
||||
T::Balance::zero(),
|
||||
caller.clone(),
|
||||
);
|
||||
|
||||
let pool_account = T::PoolLocator::pool_address(&asset1, &asset2).unwrap();
|
||||
let lp_minted =
|
||||
AssetConversion::<T>::calc_lp_amount_for_zero_supply(&liquidity1, &liquidity2).unwrap();
|
||||
assert_eq!(T::PoolAssets::balance(lp_token, &caller), lp_minted);
|
||||
assert_eq!(T::Assets::balance(asset1, &pool_account), liquidity1);
|
||||
assert_eq!(T::Assets::balance(asset2, &pool_account), liquidity2);
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn remove_liquidity() {
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
let (asset1, asset2) = T::BenchmarkHelper::create_pair(0, 1);
|
||||
|
||||
create_fee_asset::<T>(&caller);
|
||||
let (lp_token, liquidity1, liquidity2) =
|
||||
create_asset_and_pool::<T>(&caller, &asset1, &asset2);
|
||||
|
||||
let remove_lp_amount = T::Balance::one();
|
||||
|
||||
assert_ok!(AssetConversion::<T>::add_liquidity(
|
||||
SystemOrigin::Signed(caller.clone()).into(),
|
||||
Box::new(asset1.clone()),
|
||||
Box::new(asset2.clone()),
|
||||
liquidity1,
|
||||
liquidity2,
|
||||
T::Balance::one(),
|
||||
T::Balance::zero(),
|
||||
caller.clone(),
|
||||
));
|
||||
let total_supply =
|
||||
<T::PoolAssets as Inspect<T::AccountId>>::total_issuance(lp_token.clone());
|
||||
|
||||
#[extrinsic_call]
|
||||
_(
|
||||
SystemOrigin::Signed(caller.clone()),
|
||||
Box::new(asset1),
|
||||
Box::new(asset2),
|
||||
remove_lp_amount,
|
||||
T::Balance::zero(),
|
||||
T::Balance::zero(),
|
||||
caller.clone(),
|
||||
);
|
||||
|
||||
let new_total_supply = <T::PoolAssets as Inspect<T::AccountId>>::total_issuance(lp_token);
|
||||
assert_eq!(new_total_supply, total_supply - remove_lp_amount);
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn swap_exact_tokens_for_tokens(n: Linear<2, { T::MaxSwapPathLength::get() }>) {
|
||||
let mut swap_amount = T::Balance::one();
|
||||
let mut path = vec![];
|
||||
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
create_fee_asset::<T>(&caller);
|
||||
for n in 1..n {
|
||||
let (asset1, asset2) = T::BenchmarkHelper::create_pair(n - 1, n);
|
||||
swap_amount = swap_amount + T::Balance::one();
|
||||
if path.len() == 0 {
|
||||
path = vec![Box::new(asset1.clone()), Box::new(asset2.clone())];
|
||||
} else {
|
||||
path.push(Box::new(asset2.clone()));
|
||||
}
|
||||
|
||||
let (_, liquidity1, liquidity2) = create_asset_and_pool::<T>(&caller, &asset1, &asset2);
|
||||
|
||||
assert_ok!(AssetConversion::<T>::add_liquidity(
|
||||
SystemOrigin::Signed(caller.clone()).into(),
|
||||
Box::new(asset1.clone()),
|
||||
Box::new(asset2.clone()),
|
||||
liquidity1,
|
||||
liquidity2,
|
||||
T::Balance::one(),
|
||||
T::Balance::zero(),
|
||||
caller.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
let asset_in = *path.first().unwrap().clone();
|
||||
assert_ok!(T::Assets::mint_into(
|
||||
asset_in.clone(),
|
||||
&caller,
|
||||
swap_amount + T::Balance::one()
|
||||
));
|
||||
let init_caller_balance = T::Assets::balance(asset_in.clone(), &caller);
|
||||
|
||||
#[extrinsic_call]
|
||||
_(
|
||||
SystemOrigin::Signed(caller.clone()),
|
||||
path,
|
||||
swap_amount,
|
||||
T::Balance::one(),
|
||||
caller.clone(),
|
||||
true,
|
||||
);
|
||||
|
||||
let actual_balance = T::Assets::balance(asset_in, &caller);
|
||||
assert_eq!(actual_balance, init_caller_balance - swap_amount);
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn swap_tokens_for_exact_tokens(n: Linear<2, { T::MaxSwapPathLength::get() }>) {
|
||||
let mut max_swap_amount = T::Balance::one();
|
||||
let mut path = vec![];
|
||||
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
create_fee_asset::<T>(&caller);
|
||||
for n in 1..n {
|
||||
let (asset1, asset2) = T::BenchmarkHelper::create_pair(n - 1, n);
|
||||
max_swap_amount = max_swap_amount + T::Balance::one() + T::Balance::one();
|
||||
if path.len() == 0 {
|
||||
path = vec![Box::new(asset1.clone()), Box::new(asset2.clone())];
|
||||
} else {
|
||||
path.push(Box::new(asset2.clone()));
|
||||
}
|
||||
|
||||
let (_, liquidity1, liquidity2) = create_asset_and_pool::<T>(&caller, &asset1, &asset2);
|
||||
|
||||
assert_ok!(AssetConversion::<T>::add_liquidity(
|
||||
SystemOrigin::Signed(caller.clone()).into(),
|
||||
Box::new(asset1.clone()),
|
||||
Box::new(asset2.clone()),
|
||||
liquidity1,
|
||||
liquidity2,
|
||||
T::Balance::one(),
|
||||
T::Balance::zero(),
|
||||
caller.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
let asset_in = *path.first().unwrap().clone();
|
||||
let asset_out = *path.last().unwrap().clone();
|
||||
assert_ok!(T::Assets::mint_into(asset_in, &caller, max_swap_amount));
|
||||
let init_caller_balance = T::Assets::balance(asset_out.clone(), &caller);
|
||||
|
||||
#[extrinsic_call]
|
||||
_(
|
||||
SystemOrigin::Signed(caller.clone()),
|
||||
path,
|
||||
T::Balance::one(),
|
||||
max_swap_amount,
|
||||
caller.clone(),
|
||||
true,
|
||||
);
|
||||
|
||||
let actual_balance = T::Assets::balance(asset_out, &caller);
|
||||
assert_eq!(actual_balance, init_caller_balance + T::Balance::one());
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn touch(n: Linear<0, 3>) {
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
let (asset1, asset2) = T::BenchmarkHelper::create_pair(0, 1);
|
||||
let pool_id = T::PoolLocator::pool_id(&asset1, &asset2).unwrap();
|
||||
let pool_account = T::PoolLocator::address(&pool_id).unwrap();
|
||||
|
||||
create_fee_asset::<T>(&caller);
|
||||
create_asset::<T>(&caller, &asset1, <T as Config>::Balance::one(), false);
|
||||
create_asset::<T>(&caller, &asset2, <T as Config>::Balance::one(), false);
|
||||
let lp_token = AssetConversion::<T>::get_next_pool_asset_id();
|
||||
mint_setup_fee_asset::<T>(&caller, &asset1, &asset2, &lp_token);
|
||||
|
||||
assert_ok!(AssetConversion::<T>::create_pool(
|
||||
SystemOrigin::Signed(caller.clone()).into(),
|
||||
Box::new(asset1.clone()),
|
||||
Box::new(asset2.clone())
|
||||
));
|
||||
|
||||
if n > 0 &&
|
||||
<T as Config>::Assets::deposit_held(asset1.clone(), pool_account.clone()).is_some()
|
||||
{
|
||||
let _ = <T as Config>::Assets::refund(asset1.clone(), pool_account.clone());
|
||||
}
|
||||
if n > 1 &&
|
||||
<T as Config>::Assets::deposit_held(asset2.clone(), pool_account.clone()).is_some()
|
||||
{
|
||||
let _ = <T as Config>::Assets::refund(asset2.clone(), pool_account.clone());
|
||||
}
|
||||
if n > 2 &&
|
||||
<T as Config>::PoolAssets::deposit_held(lp_token.clone(), pool_account.clone())
|
||||
.is_some()
|
||||
{
|
||||
let _ = <T as Config>::PoolAssets::refund(lp_token, pool_account);
|
||||
}
|
||||
|
||||
#[extrinsic_call]
|
||||
_(SystemOrigin::Signed(caller.clone()), Box::new(asset1.clone()), Box::new(asset2.clone()));
|
||||
|
||||
assert_last_event::<T>(Event::Touched { pool_id, who: caller }.into());
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(AssetConversion, crate::mock::new_test_ext(), crate::mock::Test);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,138 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Trait for providing methods to mutate liquidity pools.
|
||||
|
||||
use pezframe_support::{traits::tokens::Balance, transactional};
|
||||
use pezsp_runtime::DispatchError;
|
||||
|
||||
use crate::{Config, Pallet};
|
||||
|
||||
/// A struct to represent an asset and its desired and minimum amounts for adding liquidity.
|
||||
pub struct AddLiquidityAsset<AssetKind, Balance> {
|
||||
/// The kind of asset.
|
||||
pub asset: AssetKind,
|
||||
/// The desired amount of the asset to add.
|
||||
pub amount_desired: Balance,
|
||||
/// The minimum amount of the asset to add.
|
||||
pub amount_min: Balance,
|
||||
}
|
||||
|
||||
/// Trait for providing methods to mutate liquidity pools. This includes creating pools,
|
||||
/// adding liquidity, and removing liquidity.
|
||||
pub trait MutateLiquidity<AccountId> {
|
||||
/// The balance type for assets.
|
||||
type Balance: Balance;
|
||||
/// The type used to identify assets.
|
||||
type AssetKind;
|
||||
/// The type used to identify a liquidity pool.
|
||||
type PoolId;
|
||||
|
||||
/// Creates a new liquidity pool for the given assets.
|
||||
///
|
||||
/// Mints LP tokens to the `creator` account.
|
||||
///
|
||||
/// Returns the ID of the newly created pool.
|
||||
fn create_pool(
|
||||
creator: &AccountId,
|
||||
asset1: Self::AssetKind,
|
||||
asset2: Self::AssetKind,
|
||||
) -> Result<Self::PoolId, DispatchError>;
|
||||
|
||||
/// Adds liquidity to an existing pool.
|
||||
///
|
||||
/// Mints LP tokens to the `mint_to` account.
|
||||
///
|
||||
/// Returns the amount of LP tokens minted.
|
||||
fn add_liquidity(
|
||||
who: &AccountId,
|
||||
asset1: AddLiquidityAsset<Self::AssetKind, Self::Balance>,
|
||||
asset2: AddLiquidityAsset<Self::AssetKind, Self::Balance>,
|
||||
mint_to: &AccountId,
|
||||
) -> Result<Self::Balance, DispatchError>;
|
||||
|
||||
/// Removes liquidity from a pool.
|
||||
///
|
||||
/// Burns LP tokens from the `who` account and transfers the withdrawn assets to the
|
||||
/// `withdraw_to` account.
|
||||
///
|
||||
/// Returns the amounts of assets withdrawn.
|
||||
fn remove_liquidity(
|
||||
who: &AccountId,
|
||||
asset1: Self::AssetKind,
|
||||
asset2: Self::AssetKind,
|
||||
lp_token_burn: Self::Balance,
|
||||
amount1_min_receive: Self::Balance,
|
||||
amount2_min_receive: Self::Balance,
|
||||
withdraw_to: &AccountId,
|
||||
) -> Result<(Self::Balance, Self::Balance), DispatchError>;
|
||||
}
|
||||
|
||||
impl<T: Config> MutateLiquidity<T::AccountId> for Pallet<T> {
|
||||
type Balance = T::Balance;
|
||||
type AssetKind = T::AssetKind;
|
||||
type PoolId = T::PoolId;
|
||||
|
||||
#[transactional]
|
||||
fn create_pool(
|
||||
creator: &T::AccountId,
|
||||
asset1: T::AssetKind,
|
||||
asset2: T::AssetKind,
|
||||
) -> Result<T::PoolId, DispatchError> {
|
||||
Self::do_create_pool(creator, asset1, asset2)
|
||||
}
|
||||
|
||||
#[transactional]
|
||||
fn add_liquidity(
|
||||
who: &T::AccountId,
|
||||
asset1: AddLiquidityAsset<Self::AssetKind, Self::Balance>,
|
||||
asset2: AddLiquidityAsset<Self::AssetKind, Self::Balance>,
|
||||
mint_to: &T::AccountId,
|
||||
) -> Result<T::Balance, DispatchError> {
|
||||
Self::do_add_liquidity(
|
||||
who,
|
||||
asset1.asset,
|
||||
asset2.asset,
|
||||
asset1.amount_desired,
|
||||
asset2.amount_desired,
|
||||
asset1.amount_min,
|
||||
asset2.amount_min,
|
||||
mint_to,
|
||||
)
|
||||
}
|
||||
|
||||
#[transactional]
|
||||
fn remove_liquidity(
|
||||
who: &T::AccountId,
|
||||
asset1: T::AssetKind,
|
||||
asset2: T::AssetKind,
|
||||
lp_token_burn: T::Balance,
|
||||
amount1_min_receive: T::Balance,
|
||||
amount2_min_receive: T::Balance,
|
||||
withdraw_to: &T::AccountId,
|
||||
) -> Result<(T::Balance, T::Balance), DispatchError> {
|
||||
Self::do_remove_liquidity(
|
||||
who,
|
||||
asset1,
|
||||
asset2,
|
||||
lp_token_burn,
|
||||
amount1_min_receive,
|
||||
amount2_min_receive,
|
||||
withdraw_to,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Test environment for Asset Conversion pallet.
|
||||
|
||||
use super::*;
|
||||
use crate as pezpallet_asset_conversion;
|
||||
use core::default::Default;
|
||||
use pezframe_support::{
|
||||
construct_runtime, derive_impl,
|
||||
instances::{Instance1, Instance2},
|
||||
ord_parameter_types, parameter_types,
|
||||
traits::{
|
||||
tokens::{
|
||||
fungible::{NativeFromLeft, NativeOrWithId, UnionOf},
|
||||
imbalance::ResolveAssetTo,
|
||||
},
|
||||
AsEnsureOriginWithArg, ConstU128, ConstU32,
|
||||
},
|
||||
PalletId,
|
||||
};
|
||||
use pezframe_system::{EnsureSigned, EnsureSignedBy};
|
||||
use pezsp_arithmetic::Permill;
|
||||
use pezsp_runtime::{
|
||||
traits::{AccountIdConversion, IdentityLookup},
|
||||
BuildStorage,
|
||||
};
|
||||
|
||||
type Block = pezframe_system::mocking::MockBlock<Test>;
|
||||
|
||||
construct_runtime!(
|
||||
pub enum Test
|
||||
{
|
||||
System: pezframe_system,
|
||||
Balances: pezpallet_balances,
|
||||
Assets: pezpallet_assets::<Instance1>,
|
||||
PoolAssets: pezpallet_assets::<Instance2>,
|
||||
AssetConversion: pezpallet_asset_conversion,
|
||||
}
|
||||
);
|
||||
|
||||
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
|
||||
impl pezframe_system::Config for Test {
|
||||
type AccountId = u128;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Block = Block;
|
||||
type AccountData = pezpallet_balances::AccountData<u128>;
|
||||
}
|
||||
|
||||
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
|
||||
impl pezpallet_balances::Config for Test {
|
||||
type Balance = u128;
|
||||
type ExistentialDeposit = ConstU128<100>;
|
||||
type AccountStore = System;
|
||||
}
|
||||
|
||||
impl pezpallet_assets::Config<Instance1> for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Balance = u128;
|
||||
type RemoveItemsLimit = ConstU32<1000>;
|
||||
type AssetId = u32;
|
||||
type AssetIdParameter = u32;
|
||||
type ReserveData = ();
|
||||
type Currency = Balances;
|
||||
type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<Self::AccountId>>;
|
||||
type ForceOrigin = pezframe_system::EnsureRoot<Self::AccountId>;
|
||||
type AssetDeposit = ConstU128<1>;
|
||||
type AssetAccountDeposit = ConstU128<10>;
|
||||
type MetadataDepositBase = ConstU128<1>;
|
||||
type MetadataDepositPerByte = ConstU128<1>;
|
||||
type ApprovalDeposit = ConstU128<1>;
|
||||
type StringLimit = ConstU32<50>;
|
||||
type Holder = ();
|
||||
type Freezer = ();
|
||||
type Extra = ();
|
||||
type WeightInfo = ();
|
||||
type CallbackHandle = ();
|
||||
pezpallet_assets::runtime_benchmarks_enabled! {
|
||||
type BenchmarkHelper = ();
|
||||
}
|
||||
}
|
||||
|
||||
impl pezpallet_assets::Config<Instance2> for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Balance = u128;
|
||||
type RemoveItemsLimit = ConstU32<1000>;
|
||||
type AssetId = u32;
|
||||
type AssetIdParameter = u32;
|
||||
type ReserveData = ();
|
||||
type Currency = Balances;
|
||||
type CreateOrigin =
|
||||
AsEnsureOriginWithArg<EnsureSignedBy<AssetConversionOrigin, Self::AccountId>>;
|
||||
type ForceOrigin = pezframe_system::EnsureRoot<Self::AccountId>;
|
||||
type AssetDeposit = ConstU128<0>;
|
||||
type AssetAccountDeposit = ConstU128<0>;
|
||||
type MetadataDepositBase = ConstU128<0>;
|
||||
type MetadataDepositPerByte = ConstU128<0>;
|
||||
type ApprovalDeposit = ConstU128<0>;
|
||||
type StringLimit = ConstU32<50>;
|
||||
type Holder = ();
|
||||
type Freezer = ();
|
||||
type Extra = ();
|
||||
type WeightInfo = ();
|
||||
type CallbackHandle = ();
|
||||
pezpallet_assets::runtime_benchmarks_enabled! {
|
||||
type BenchmarkHelper = ();
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon");
|
||||
pub const Native: NativeOrWithId<u32> = NativeOrWithId::Native;
|
||||
pub storage LiquidityWithdrawalFee: Permill = Permill::from_percent(0);
|
||||
}
|
||||
|
||||
ord_parameter_types! {
|
||||
pub const AssetConversionOrigin: u128 = AccountIdConversion::<u128>::into_account_truncating(&AssetConversionPalletId::get());
|
||||
}
|
||||
|
||||
pub type NativeAndAssets = UnionOf<Balances, Assets, NativeFromLeft, NativeOrWithId<u32>, u128>;
|
||||
pub type PoolIdToAccountId =
|
||||
AccountIdConverter<AssetConversionPalletId, (NativeOrWithId<u32>, NativeOrWithId<u32>)>;
|
||||
pub type AscendingLocator = Ascending<u128, NativeOrWithId<u32>, PoolIdToAccountId>;
|
||||
pub type WithFirstAssetLocator =
|
||||
WithFirstAsset<Native, u128, NativeOrWithId<u32>, PoolIdToAccountId>;
|
||||
|
||||
impl Config for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Balance = <Self as pezpallet_balances::Config>::Balance;
|
||||
type HigherPrecisionBalance = pezsp_core::U256;
|
||||
type AssetKind = NativeOrWithId<u32>;
|
||||
type Assets = NativeAndAssets;
|
||||
type PoolId = (Self::AssetKind, Self::AssetKind);
|
||||
type PoolLocator = Chain<WithFirstAssetLocator, AscendingLocator>;
|
||||
type PoolAssetId = u32;
|
||||
type PoolAssets = PoolAssets;
|
||||
type PoolSetupFee = ConstU128<100>; // should be more or equal to the existential deposit
|
||||
type PoolSetupFeeAsset = Native;
|
||||
type PoolSetupFeeTarget = ResolveAssetTo<AssetConversionOrigin, Self::Assets>;
|
||||
type PalletId = AssetConversionPalletId;
|
||||
type WeightInfo = ();
|
||||
type LPFee = ConstU32<3>; // means 0.3%
|
||||
type LiquidityWithdrawalFee = LiquidityWithdrawalFee;
|
||||
type MaxSwapPathLength = ConstU32<4>;
|
||||
type MintMinLiquidity = ConstU128<100>; // 100 is good enough when the main currency has 12 decimals.
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type BenchmarkHelper = ();
|
||||
}
|
||||
|
||||
pub(crate) fn new_test_ext() -> pezsp_io::TestExternalities {
|
||||
let mut t = pezframe_system::GenesisConfig::<Test>::default().build_storage().unwrap();
|
||||
|
||||
pezpallet_balances::GenesisConfig::<Test> {
|
||||
balances: vec![(1, 10000), (2, 20000), (3, 30000), (4, 40000)],
|
||||
..Default::default()
|
||||
}
|
||||
.assimilate_storage(&mut t)
|
||||
.unwrap();
|
||||
|
||||
let mut ext = pezsp_io::TestExternalities::new(t);
|
||||
ext.execute_with(|| System::set_block_number(1));
|
||||
ext
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Traits and implementations for swap between the various asset classes.
|
||||
|
||||
use super::*;
|
||||
use pezframe_support::{storage::with_transaction, transactional};
|
||||
|
||||
/// Trait for providing methods to swap between the various asset classes.
|
||||
pub trait Swap<AccountId> {
|
||||
/// Measure units of the asset classes for swapping.
|
||||
type Balance: Balance;
|
||||
/// Kind of assets that are going to be swapped.
|
||||
type AssetKind;
|
||||
|
||||
/// Returns the upper limit on the length of the swap path.
|
||||
fn max_path_len() -> u32;
|
||||
|
||||
/// Swap exactly `amount_in` of asset `path[0]` for asset `path[last]`.
|
||||
/// If an `amount_out_min` is specified, it will return an error if it is unable to acquire
|
||||
/// the amount desired.
|
||||
///
|
||||
/// Withdraws the `path[0]` asset from `sender`, deposits the `path[last]` asset to `send_to`,
|
||||
/// respecting `keep_alive`.
|
||||
///
|
||||
/// If successful, returns the amount of `path[last]` acquired for the `amount_in`.
|
||||
///
|
||||
/// This operation is expected to be atomic.
|
||||
fn swap_exact_tokens_for_tokens(
|
||||
sender: AccountId,
|
||||
path: Vec<Self::AssetKind>,
|
||||
amount_in: Self::Balance,
|
||||
amount_out_min: Option<Self::Balance>,
|
||||
send_to: AccountId,
|
||||
keep_alive: bool,
|
||||
) -> Result<Self::Balance, DispatchError>;
|
||||
|
||||
/// Take the `path[0]` asset and swap some amount for `amount_out` of the `path[last]`. If an
|
||||
/// `amount_in_max` is specified, it will return an error if acquiring `amount_out` would be
|
||||
/// too costly.
|
||||
///
|
||||
/// Withdraws `path[0]` asset from `sender`, deposits `path[last]` asset to `send_to`,
|
||||
/// respecting `keep_alive`.
|
||||
///
|
||||
/// If successful returns the amount of the `path[0]` taken to provide `path[last]`.
|
||||
///
|
||||
/// This operation is expected to be atomic.
|
||||
fn swap_tokens_for_exact_tokens(
|
||||
sender: AccountId,
|
||||
path: Vec<Self::AssetKind>,
|
||||
amount_out: Self::Balance,
|
||||
amount_in_max: Option<Self::Balance>,
|
||||
send_to: AccountId,
|
||||
keep_alive: bool,
|
||||
) -> Result<Self::Balance, DispatchError>;
|
||||
}
|
||||
|
||||
/// Trait providing methods to swap between the various asset classes.
|
||||
pub trait SwapCredit<AccountId> {
|
||||
/// Measure units of the asset classes for swapping.
|
||||
type Balance: Balance;
|
||||
/// Kind of assets that are going to be swapped.
|
||||
type AssetKind;
|
||||
/// Credit implying a negative imbalance in the system that can be placed into an account or
|
||||
/// alter the total supply.
|
||||
type Credit;
|
||||
|
||||
/// Returns the upper limit on the length of the swap path.
|
||||
fn max_path_len() -> u32;
|
||||
|
||||
/// Swap exactly `credit_in` of asset `path[0]` for asset `path[last]`. If `amount_out_min` is
|
||||
/// provided and the swap can't achieve at least this amount, an error is returned.
|
||||
///
|
||||
/// On a successful swap, the function returns the `credit_out` of `path[last]` obtained from
|
||||
/// the `credit_in`. On failure, it returns an `Err` containing the original `credit_in` and the
|
||||
/// associated error code.
|
||||
///
|
||||
/// This operation is expected to be atomic.
|
||||
fn swap_exact_tokens_for_tokens(
|
||||
path: Vec<Self::AssetKind>,
|
||||
credit_in: Self::Credit,
|
||||
amount_out_min: Option<Self::Balance>,
|
||||
) -> Result<Self::Credit, (Self::Credit, DispatchError)>;
|
||||
|
||||
/// Swaps a portion of `credit_in` of `path[0]` asset to obtain the desired `amount_out` of
|
||||
/// the `path[last]` asset. The provided `credit_in` must be adequate to achieve the target
|
||||
/// `amount_out`, or an error will occur.
|
||||
///
|
||||
/// On success, the function returns a (`credit_out`, `credit_change`) tuple, where `credit_out`
|
||||
/// represents the acquired amount of the `path[last]` asset, and `credit_change` is the
|
||||
/// remaining portion from the `credit_in`. On failure, an `Err` with the initial `credit_in`
|
||||
/// and error code is returned.
|
||||
///
|
||||
/// This operation is expected to be atomic.
|
||||
fn swap_tokens_for_exact_tokens(
|
||||
path: Vec<Self::AssetKind>,
|
||||
credit_in: Self::Credit,
|
||||
amount_out: Self::Balance,
|
||||
) -> Result<(Self::Credit, Self::Credit), (Self::Credit, DispatchError)>;
|
||||
}
|
||||
|
||||
/// Trait providing methods to quote swap prices between asset classes.
|
||||
///
|
||||
/// The quoted price is only guaranteed if no other swaps are made after the price is quoted and
|
||||
/// before the target swap (e.g., the swap is made immediately within the same transaction).
|
||||
pub trait QuotePrice {
|
||||
/// Measurement units of the asset classes for pricing.
|
||||
type Balance: Balance;
|
||||
/// Type representing the kind of assets for which the price is being quoted.
|
||||
type AssetKind;
|
||||
/// Quotes the amount of `asset1` required to obtain the exact `amount` of `asset2`.
|
||||
///
|
||||
/// If `include_fee` is set to `true`, the price will include the pool's fee.
|
||||
/// If the pool does not exist or the swap cannot be made, `None` is returned.
|
||||
fn quote_price_tokens_for_exact_tokens(
|
||||
asset1: Self::AssetKind,
|
||||
asset2: Self::AssetKind,
|
||||
amount: Self::Balance,
|
||||
include_fee: bool,
|
||||
) -> Option<Self::Balance>;
|
||||
/// Quotes the amount of `asset2` resulting from swapping the exact `amount` of `asset1`.
|
||||
///
|
||||
/// If `include_fee` is set to `true`, the price will include the pool's fee.
|
||||
/// If the pool does not exist or the swap cannot be made, `None` is returned.
|
||||
fn quote_price_exact_tokens_for_tokens(
|
||||
asset1: Self::AssetKind,
|
||||
asset2: Self::AssetKind,
|
||||
amount: Self::Balance,
|
||||
include_fee: bool,
|
||||
) -> Option<Self::Balance>;
|
||||
}
|
||||
|
||||
impl<T: Config> Swap<T::AccountId> for Pallet<T> {
|
||||
type Balance = T::Balance;
|
||||
type AssetKind = T::AssetKind;
|
||||
|
||||
fn max_path_len() -> u32 {
|
||||
T::MaxSwapPathLength::get()
|
||||
}
|
||||
|
||||
#[transactional]
|
||||
fn swap_exact_tokens_for_tokens(
|
||||
sender: T::AccountId,
|
||||
path: Vec<Self::AssetKind>,
|
||||
amount_in: Self::Balance,
|
||||
amount_out_min: Option<Self::Balance>,
|
||||
send_to: T::AccountId,
|
||||
keep_alive: bool,
|
||||
) -> Result<Self::Balance, DispatchError> {
|
||||
Self::do_swap_exact_tokens_for_tokens(
|
||||
sender,
|
||||
path,
|
||||
amount_in,
|
||||
amount_out_min,
|
||||
send_to,
|
||||
keep_alive,
|
||||
)
|
||||
}
|
||||
|
||||
#[transactional]
|
||||
fn swap_tokens_for_exact_tokens(
|
||||
sender: T::AccountId,
|
||||
path: Vec<Self::AssetKind>,
|
||||
amount_out: Self::Balance,
|
||||
amount_in_max: Option<Self::Balance>,
|
||||
send_to: T::AccountId,
|
||||
keep_alive: bool,
|
||||
) -> Result<Self::Balance, DispatchError> {
|
||||
Self::do_swap_tokens_for_exact_tokens(
|
||||
sender,
|
||||
path,
|
||||
amount_out,
|
||||
amount_in_max,
|
||||
send_to,
|
||||
keep_alive,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> SwapCredit<T::AccountId> for Pallet<T> {
|
||||
type Balance = T::Balance;
|
||||
type AssetKind = T::AssetKind;
|
||||
type Credit = CreditOf<T>;
|
||||
|
||||
fn max_path_len() -> u32 {
|
||||
T::MaxSwapPathLength::get()
|
||||
}
|
||||
|
||||
fn swap_exact_tokens_for_tokens(
|
||||
path: Vec<Self::AssetKind>,
|
||||
credit_in: Self::Credit,
|
||||
amount_out_min: Option<Self::Balance>,
|
||||
) -> Result<Self::Credit, (Self::Credit, DispatchError)> {
|
||||
let credit_asset = credit_in.asset();
|
||||
with_transaction(|| -> TransactionOutcome<Result<_, DispatchError>> {
|
||||
let res = Self::do_swap_exact_credit_tokens_for_tokens(path, credit_in, amount_out_min);
|
||||
match &res {
|
||||
Ok(_) => TransactionOutcome::Commit(Ok(res)),
|
||||
// wrapping `res` with `Ok`, since our `Err` doesn't satisfy the
|
||||
// `From<DispatchError>` bound of the `with_transaction` function.
|
||||
Err(_) => TransactionOutcome::Rollback(Ok(res)),
|
||||
}
|
||||
})
|
||||
// should never map an error since `with_transaction` above never returns it.
|
||||
.map_err(|_| (Self::Credit::zero(credit_asset), DispatchError::Corruption))?
|
||||
}
|
||||
|
||||
fn swap_tokens_for_exact_tokens(
|
||||
path: Vec<Self::AssetKind>,
|
||||
credit_in: Self::Credit,
|
||||
amount_out: Self::Balance,
|
||||
) -> Result<(Self::Credit, Self::Credit), (Self::Credit, DispatchError)> {
|
||||
let credit_asset = credit_in.asset();
|
||||
with_transaction(|| -> TransactionOutcome<Result<_, DispatchError>> {
|
||||
let res = Self::do_swap_credit_tokens_for_exact_tokens(path, credit_in, amount_out);
|
||||
match &res {
|
||||
Ok(_) => TransactionOutcome::Commit(Ok(res)),
|
||||
// wrapping `res` with `Ok`, since our `Err` doesn't satisfy the
|
||||
// `From<DispatchError>` bound of the `with_transaction` function.
|
||||
Err(_) => TransactionOutcome::Rollback(Ok(res)),
|
||||
}
|
||||
})
|
||||
// should never map an error since `with_transaction` above never returns it.
|
||||
.map_err(|_| (Self::Credit::zero(credit_asset), DispatchError::Corruption))?
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> QuotePrice for Pallet<T> {
|
||||
type Balance = T::Balance;
|
||||
type AssetKind = T::AssetKind;
|
||||
fn quote_price_exact_tokens_for_tokens(
|
||||
asset1: Self::AssetKind,
|
||||
asset2: Self::AssetKind,
|
||||
amount: Self::Balance,
|
||||
include_fee: bool,
|
||||
) -> Option<Self::Balance> {
|
||||
Self::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee)
|
||||
}
|
||||
fn quote_price_tokens_for_exact_tokens(
|
||||
asset1: Self::AssetKind,
|
||||
asset2: Self::AssetKind,
|
||||
amount: Self::Balance,
|
||||
include_fee: bool,
|
||||
) -> Option<Self::Balance> {
|
||||
Self::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,171 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use super::*;
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use core::marker::PhantomData;
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_runtime::traits::TryConvert;
|
||||
|
||||
/// Represents a swap path with associated asset amounts indicating how much of the asset needs to
|
||||
/// be deposited to get the following asset's amount withdrawn (this is inclusive of fees).
|
||||
///
|
||||
/// Example:
|
||||
/// Given path [(asset1, amount_in), (asset2, amount_out2), (asset3, amount_out3)], can be resolved:
|
||||
/// 1. `asset(asset1, amount_in)` take from `user` and move to the pool(asset1, asset2);
|
||||
/// 2. `asset(asset2, amount_out2)` transfer from pool(asset1, asset2) to pool(asset2, asset3);
|
||||
/// 3. `asset(asset3, amount_out3)` move from pool(asset2, asset3) to `user`.
|
||||
pub type BalancePath<T> = Vec<(<T as Config>::AssetKind, <T as Config>::Balance)>;
|
||||
|
||||
/// Credit of [Config::Assets].
|
||||
pub type CreditOf<T> = Credit<<T as pezframe_system::Config>::AccountId, <T as Config>::Assets>;
|
||||
|
||||
/// Stores the lp_token asset id a particular pool has been assigned.
|
||||
#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
|
||||
pub struct PoolInfo<PoolAssetId> {
|
||||
/// Liquidity pool asset
|
||||
pub lp_token: PoolAssetId,
|
||||
}
|
||||
|
||||
/// Provides means to resolve the `PoolId` and `AccountId` from a pair of assets.
|
||||
///
|
||||
/// Resulting `PoolId` remains consistent whether the asset pair is presented as (asset1, asset2)
|
||||
/// or (asset2, asset1). The derived `AccountId` may serve as an address for liquidity provider
|
||||
/// tokens.
|
||||
pub trait PoolLocator<AccountId, AssetKind, PoolId> {
|
||||
/// Retrieves the account address associated with a valid `PoolId`.
|
||||
fn address(id: &PoolId) -> Result<AccountId, ()>;
|
||||
/// Identifies the `PoolId` for a given pair of assets.
|
||||
///
|
||||
/// Returns an error if the asset pair isn't supported.
|
||||
fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<PoolId, ()>;
|
||||
/// Retrieves the account address associated with a given asset pair.
|
||||
///
|
||||
/// Returns an error if the asset pair isn't supported.
|
||||
fn pool_address(asset1: &AssetKind, asset2: &AssetKind) -> Result<AccountId, ()> {
|
||||
if let Ok(id) = Self::pool_id(asset1, asset2) {
|
||||
Self::address(&id)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pool locator that mandates the inclusion of the specified `FirstAsset` in every asset pair.
|
||||
///
|
||||
/// The `PoolId` is represented as a tuple of `AssetKind`s with `FirstAsset` always positioned as
|
||||
/// the first element.
|
||||
pub struct WithFirstAsset<FirstAsset, AccountId, AssetKind, AccountIdConverter>(
|
||||
PhantomData<(FirstAsset, AccountId, AssetKind, AccountIdConverter)>,
|
||||
);
|
||||
impl<FirstAsset, AccountId, AssetKind, AccountIdConverter>
|
||||
PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>
|
||||
for WithFirstAsset<FirstAsset, AccountId, AssetKind, AccountIdConverter>
|
||||
where
|
||||
AssetKind: Eq + Clone + Encode,
|
||||
AccountId: Decode,
|
||||
FirstAsset: Get<AssetKind>,
|
||||
AccountIdConverter: for<'a> TryConvert<&'a (AssetKind, AssetKind), AccountId>,
|
||||
{
|
||||
fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> {
|
||||
if asset1 == asset2 {
|
||||
return Err(());
|
||||
}
|
||||
let first = FirstAsset::get();
|
||||
if first == *asset1 {
|
||||
Ok((first, asset2.clone()))
|
||||
} else if first == *asset2 {
|
||||
Ok((first, asset1.clone()))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
fn address(id: &(AssetKind, AssetKind)) -> Result<AccountId, ()> {
|
||||
AccountIdConverter::try_convert(id).map_err(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Pool locator where the `PoolId` is a tuple of `AssetKind`s arranged in ascending order.
|
||||
pub struct Ascending<AccountId, AssetKind, AccountIdConverter>(
|
||||
PhantomData<(AccountId, AssetKind, AccountIdConverter)>,
|
||||
);
|
||||
impl<AccountId, AssetKind, AccountIdConverter>
|
||||
PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>
|
||||
for Ascending<AccountId, AssetKind, AccountIdConverter>
|
||||
where
|
||||
AssetKind: Ord + Clone + Encode,
|
||||
AccountId: Decode,
|
||||
AccountIdConverter: for<'a> TryConvert<&'a (AssetKind, AssetKind), AccountId>,
|
||||
{
|
||||
fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> {
|
||||
if asset1 > asset2 {
|
||||
Ok((asset2.clone(), asset1.clone()))
|
||||
} else if asset1 < asset2 {
|
||||
Ok((asset1.clone(), asset2.clone()))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
fn address(id: &(AssetKind, AssetKind)) -> Result<AccountId, ()> {
|
||||
AccountIdConverter::try_convert(id).map_err(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Pool locator that chains the `First` and `Second` implementations of [`PoolLocator`].
|
||||
///
|
||||
/// If the `First` implementation fails, it falls back to the `Second`.
|
||||
pub struct Chain<First, Second>(PhantomData<(First, Second)>);
|
||||
impl<First, Second, AccountId, AssetKind> PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>
|
||||
for Chain<First, Second>
|
||||
where
|
||||
First: PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>,
|
||||
Second: PoolLocator<AccountId, AssetKind, (AssetKind, AssetKind)>,
|
||||
{
|
||||
fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> {
|
||||
First::pool_id(asset1, asset2).or(Second::pool_id(asset1, asset2))
|
||||
}
|
||||
fn address(id: &(AssetKind, AssetKind)) -> Result<AccountId, ()> {
|
||||
First::address(id).or(Second::address(id))
|
||||
}
|
||||
}
|
||||
|
||||
/// `PoolId` to `AccountId` conversion.
|
||||
pub struct AccountIdConverter<Seed, PoolId>(PhantomData<(Seed, PoolId)>);
|
||||
impl<Seed, PoolId, AccountId> TryConvert<&PoolId, AccountId> for AccountIdConverter<Seed, PoolId>
|
||||
where
|
||||
PoolId: Encode,
|
||||
AccountId: Decode,
|
||||
Seed: Get<PalletId>,
|
||||
{
|
||||
fn try_convert(id: &PoolId) -> Result<AccountId, &PoolId> {
|
||||
pezsp_io::hashing::blake2_256(&Encode::encode(&(Seed::get(), id))[..])
|
||||
.using_encoded(|e| Decode::decode(&mut TrailingZeroInput::new(e)).map_err(|_| id))
|
||||
}
|
||||
}
|
||||
|
||||
/// `PoolId` to `AccountId` conversion without an addition arguments to the seed.
|
||||
pub struct AccountIdConverterNoSeed<PoolId>(PhantomData<PoolId>);
|
||||
impl<PoolId, AccountId> TryConvert<&PoolId, AccountId> for AccountIdConverterNoSeed<PoolId>
|
||||
where
|
||||
PoolId: Encode,
|
||||
AccountId: Decode,
|
||||
{
|
||||
fn try_convert(id: &PoolId) -> Result<AccountId, &PoolId> {
|
||||
pezsp_io::hashing::blake2_256(&Encode::encode(id)[..])
|
||||
.using_encoded(|e| Decode::decode(&mut TrailingZeroInput::new(e)).map_err(|_| id))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Autogenerated weights for `pezpallet_asset_conversion`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `4563561839a5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024`
|
||||
|
||||
// Executed Command:
|
||||
// frame-omni-bencher
|
||||
// v1
|
||||
// benchmark
|
||||
// pallet
|
||||
// --extrinsic=*
|
||||
// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm
|
||||
// --pallet=pezpallet_asset_conversion
|
||||
// --header=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/HEADER-APACHE2
|
||||
// --output=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/pezframe/asset-conversion/src/weights.rs
|
||||
// --wasm-execution=compiled
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --heap-pages=4096
|
||||
// --template=bizinikiwi/.maintain/frame-weight-template.hbs
|
||||
// --no-storage-info
|
||||
// --no-min-squares
|
||||
// --no-median-slopes
|
||||
// --genesis-builder-policy=none
|
||||
// --exclude-pallets=pezpallet_xcm,pezpallet_xcm_benchmarks::fungible,pezpallet_xcm_benchmarks::generic,pezpallet_nomination_pools,pezpallet_remark,pezpallet_transaction_storage,pezpallet_election_provider_multi_block,pezpallet_election_provider_multi_block::signed,pezpallet_election_provider_multi_block::unsigned,pezpallet_election_provider_multi_block::verifier
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(missing_docs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use pezframe_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// Weight functions needed for `pezpallet_asset_conversion`.
|
||||
pub trait WeightInfo {
|
||||
fn create_pool() -> Weight;
|
||||
fn add_liquidity() -> Weight;
|
||||
fn remove_liquidity() -> Weight;
|
||||
fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight;
|
||||
fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight;
|
||||
fn touch(n: u32, ) -> Weight;
|
||||
}
|
||||
|
||||
/// Weights for `pezpallet_asset_conversion` using the Bizinikiwi node and recommended hardware.
|
||||
pub struct BizinikiwiWeight<T>(PhantomData<T>);
|
||||
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:1)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `System::Account` (r:2 w:1)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:0)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `AssetConversion::NextPoolAssetId` (r:1 w:1)
|
||||
/// Proof: `AssetConversion::NextPoolAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::NextAssetId` (r:1 w:0)
|
||||
/// Proof: `PoolAssets::NextAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
fn create_pool() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `476`
|
||||
// Estimated: `6360`
|
||||
// Minimum execution time: 81_898_000 picoseconds.
|
||||
Weight::from_parts(83_910_000, 6360)
|
||||
.saturating_add(T::DbWeight::get().reads(9_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(5_u64))
|
||||
}
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:0)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:2)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:4 w:4)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// Storage: `System::Account` (r:1 w:1)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:2 w:2)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
fn add_liquidity() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1090`
|
||||
// Estimated: `11426`
|
||||
// Minimum execution time: 138_751_000 picoseconds.
|
||||
Weight::from_parts(141_390_000, 11426)
|
||||
.saturating_add(T::DbWeight::get().reads(11_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(10_u64))
|
||||
}
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:0)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:2)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:4 w:4)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
fn remove_liquidity() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1233`
|
||||
// Estimated: `11426`
|
||||
// Minimum execution time: 124_722_000 picoseconds.
|
||||
Weight::from_parts(128_644_000, 11426)
|
||||
.saturating_add(T::DbWeight::get().reads(9_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(8_u64))
|
||||
}
|
||||
/// Storage: `Assets::Asset` (r:4 w:4)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:8 w:8)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// The range of component `n` is `[2, 4]`.
|
||||
fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + n * (419 ±0)`
|
||||
// Estimated: `990 + n * (5218 ±0)`
|
||||
// Minimum execution time: 88_884_000 picoseconds.
|
||||
Weight::from_parts(91_036_000, 990)
|
||||
// Standard Error: 337_841
|
||||
.saturating_add(Weight::from_parts(11_478_919, 0).saturating_mul(n.into()))
|
||||
.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into()))
|
||||
}
|
||||
/// Storage: `Assets::Asset` (r:4 w:4)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:8 w:8)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// The range of component `n` is `[2, 4]`.
|
||||
fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + n * (419 ±0)`
|
||||
// Estimated: `990 + n * (5218 ±0)`
|
||||
// Minimum execution time: 89_080_000 picoseconds.
|
||||
Weight::from_parts(90_913_000, 990)
|
||||
// Standard Error: 340_609
|
||||
.saturating_add(Weight::from_parts(11_562_623, 0).saturating_mul(n.into()))
|
||||
.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into()))
|
||||
}
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:0)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:2)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `System::Account` (r:1 w:0)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:2 w:2)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// The range of component `n` is `[0, 3]`.
|
||||
fn touch(n: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1154`
|
||||
// Estimated: `6360`
|
||||
// Minimum execution time: 43_815_000 picoseconds.
|
||||
Weight::from_parts(46_005_208, 6360)
|
||||
// Standard Error: 68_937
|
||||
.saturating_add(Weight::from_parts(19_974_807, 0).saturating_mul(n.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(8_u64))
|
||||
.saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into())))
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests.
|
||||
impl WeightInfo for () {
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:1)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `System::Account` (r:2 w:1)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:0)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `AssetConversion::NextPoolAssetId` (r:1 w:1)
|
||||
/// Proof: `AssetConversion::NextPoolAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::NextAssetId` (r:1 w:0)
|
||||
/// Proof: `PoolAssets::NextAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
fn create_pool() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `476`
|
||||
// Estimated: `6360`
|
||||
// Minimum execution time: 81_898_000 picoseconds.
|
||||
Weight::from_parts(83_910_000, 6360)
|
||||
.saturating_add(RocksDbWeight::get().reads(9_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(5_u64))
|
||||
}
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:0)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:2)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:4 w:4)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// Storage: `System::Account` (r:1 w:1)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:2 w:2)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
fn add_liquidity() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1090`
|
||||
// Estimated: `11426`
|
||||
// Minimum execution time: 138_751_000 picoseconds.
|
||||
Weight::from_parts(141_390_000, 11426)
|
||||
.saturating_add(RocksDbWeight::get().reads(11_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(10_u64))
|
||||
}
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:0)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:2)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:4 w:4)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
fn remove_liquidity() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1233`
|
||||
// Estimated: `11426`
|
||||
// Minimum execution time: 124_722_000 picoseconds.
|
||||
Weight::from_parts(128_644_000, 11426)
|
||||
.saturating_add(RocksDbWeight::get().reads(9_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(8_u64))
|
||||
}
|
||||
/// Storage: `Assets::Asset` (r:4 w:4)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:8 w:8)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// The range of component `n` is `[2, 4]`.
|
||||
fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + n * (419 ±0)`
|
||||
// Estimated: `990 + n * (5218 ±0)`
|
||||
// Minimum execution time: 88_884_000 picoseconds.
|
||||
Weight::from_parts(91_036_000, 990)
|
||||
// Standard Error: 337_841
|
||||
.saturating_add(Weight::from_parts(11_478_919, 0).saturating_mul(n.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into()))
|
||||
}
|
||||
/// Storage: `Assets::Asset` (r:4 w:4)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:8 w:8)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// The range of component `n` is `[2, 4]`.
|
||||
fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + n * (419 ±0)`
|
||||
// Estimated: `990 + n * (5218 ±0)`
|
||||
// Minimum execution time: 89_080_000 picoseconds.
|
||||
Weight::from_parts(90_913_000, 990)
|
||||
// Standard Error: 340_609
|
||||
.saturating_add(Weight::from_parts(11_562_623, 0).saturating_mul(n.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into())))
|
||||
.saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into()))
|
||||
}
|
||||
/// Storage: `AssetConversion::Pools` (r:1 w:0)
|
||||
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Asset` (r:2 w:2)
|
||||
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `System::Account` (r:1 w:0)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// Storage: `Assets::Account` (r:2 w:2)
|
||||
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Asset` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
|
||||
/// Storage: `PoolAssets::Account` (r:1 w:1)
|
||||
/// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
|
||||
/// The range of component `n` is `[0, 3]`.
|
||||
fn touch(n: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1154`
|
||||
// Estimated: `6360`
|
||||
// Minimum execution time: 43_815_000 picoseconds.
|
||||
Weight::from_parts(46_005_208, 6360)
|
||||
// Standard Error: 68_937
|
||||
.saturating_add(Weight::from_parts(19_974_807, 0).saturating_mul(n.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(8_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(n.into())))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user