Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dex amm #1122

Merged
merged 9 commits into from
Jun 1, 2023
Merged

dex amm #1122

Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ jsonrpsee = { version = "0.16.2", features = ["server"] }
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" }
sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" }

zenlink-protocol = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" }
zenlink-protocol-rpc = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" }
zenlink-protocol-runtime-api = { git = 'https://github.com/manta-network/Zenlink', branch = "polkadot-v0.9.37" }

# Substrate client dependencies
sc-basic-authorship = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" }
sc-chain-spec = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.37" }
Expand Down
11 changes: 10 additions & 1 deletion node/src/rpc/calamari.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ use pallet_manta_sbt::{
rpc::{SBTPull, SBTPullApiServer},
runtime::SBTPullLedgerDiffApi,
};
use zenlink_protocol::AssetId;
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
use zenlink_protocol_rpc::{ZenlinkProtocol, ZenlinkProtocolApiServer};
use zenlink_protocol_runtime_api::ZenlinkProtocolApi as ZenlinkProtocolRuntimeApi;

/// Instantiate all RPC extensions for calamari.
pub fn create_calamari_full<C, P>(deps: FullDeps<C, P>) -> Result<RpcExtension, sc_service::Error>
Expand All @@ -41,6 +44,7 @@ where
C::Api: BlockBuilder<Block>,
C::Api: PullLedgerDiffApi<Block>,
C::Api: SBTPullLedgerDiffApi<Block>,
C::Api: ZenlinkProtocolRuntimeApi<Block, AccountId, AssetId>,
P: TransactionPool + Sync + Send + 'static,
{
use frame_rpc_system::{System, SystemApiServer};
Expand All @@ -65,10 +69,15 @@ where
.merge(manta_pay_rpc)
.map_err(|e| sc_service::Error::Other(e.to_string()))?;

let manta_sbt_rpc: jsonrpsee::RpcModule<SBTPull<Block, C>> = SBTPull::new(client).into_rpc();
let manta_sbt_rpc: jsonrpsee::RpcModule<SBTPull<Block, C>> =
SBTPull::new(client.clone()).into_rpc();
module
.merge(manta_sbt_rpc)
.map_err(|e| sc_service::Error::Other(e.to_string()))?;

module
.merge(ZenlinkProtocol::new(client).into_rpc())
.map_err(|e| sc_service::Error::Other(e.to_string()))?;

Ok(module)
}
159 changes: 137 additions & 22 deletions pallets/asset-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ pub mod pallet {
};
use frame_system::pallet_prelude::*;
use manta_primitives::assets::{
self, AssetConfig, AssetIdLocationMap, AssetIdType, AssetMetadata, AssetRegistry,
FungibleLedger, LocationType,
self, AssetConfig, AssetIdLocationMap, AssetIdLpMap, AssetIdType, AssetMetadata,
AssetRegistry, FungibleLedger, LocationType,
};
use orml_traits::GetByKey;
use sp_runtime::{
Expand Down Expand Up @@ -152,6 +152,22 @@ pub mod pallet {
}
}

impl<T> AssetIdLpMap for Pallet<T>
where
T: Config,
{
fn lp_asset_id(
asset_id0: &Self::AssetId,
asset_id1: &Self::AssetId,
) -> Option<Self::AssetId> {
AssetIdLp::<T>::get((asset_id0, asset_id1))
}

fn lp_asset_pool(pool_id: &Self::AssetId) -> Option<Self::AssetId> {
PoolIdLp::<T>::get(pool_id).map(|_| *pool_id)
}
}

impl<T> assets::UnitsPerSecond for Pallet<T>
where
T: Config,
Expand Down Expand Up @@ -208,6 +224,24 @@ pub mod pallet {
metadata: <T::AssetConfig as AssetConfig<T>>::AssetRegistryMetadata,
},

/// A LP asset was registered
LPAssetRegistered {
/// Asset Id of new Asset
asset_id0: T::AssetId,

/// Asset Id of new Asset
asset_id1: T::AssetId,

/// Asset Id of new Asset
asset_id: T::AssetId,

/// Location of the new Asset
location: T::Location,

/// Metadata Registered to Asset Manager
metadata: <T::AssetConfig as AssetConfig<T>>::AssetRegistryMetadata,
},

/// Updated the location of an asset
AssetLocationUpdated {
/// Asset Id of the updated Asset
Expand Down Expand Up @@ -275,7 +309,7 @@ pub mod pallet {
/// Location Already Exists
LocationAlreadyExists,

/// An error occured while creating a new asset at the [`AssetRegistry`].
/// An error occurred while creating a new asset at the [`AssetRegistry`].
ErrorCreatingAsset,

/// There was an attempt to update a non-existent asset.
Expand All @@ -292,6 +326,12 @@ pub mod pallet {

/// An error occurred while updating the parachain id.
UpdateParaIdError,

/// Two asset that used for generate LP asset should different
AssetIdNotDifferent,

/// Two asset that used for generate LP asset should exist
AssetIdNotExist,
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
}

/// [`AssetId`](AssetConfig::AssetId) to [`MultiLocation`] Map
Expand Down Expand Up @@ -345,11 +385,21 @@ pub mod pallet {
pub type FilteredOutgoingAssetLocations<T: Config> =
StorageMap<_, Blake2_128Concat, Option<MultiLocation>, ()>;

#[pallet::storage]
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
#[pallet::getter(fn asset_id_lp)]
pub(super) type AssetIdLp<T: Config> =
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
StorageMap<_, Blake2_128Concat, (T::AssetId, T::AssetId), T::AssetId>;

#[pallet::storage]
#[pallet::getter(fn pool_id_lp)]
pub(super) type PoolIdLp<T: Config> =
StorageMap<_, Blake2_128Concat, T::AssetId, (T::AssetId, T::AssetId)>;

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Register a new asset in the asset manager.
///
/// * `origin`: Caller of this extrinsic, the access control is specified by `ForceOrigin`.
/// * `origin`: Caller of this extrinsic, the access control is specified by `ModifierOrigin`.
/// * `location`: Location of the asset.
/// * `metadata`: Asset metadata.
/// * `min_balance`: Minimum balance to keep an account alive, used in conjunction with `is_sufficient`.
Expand All @@ -364,21 +414,8 @@ pub mod pallet {
metadata: <T::AssetConfig as AssetConfig<T>>::AssetRegistryMetadata,
) -> DispatchResult {
T::ModifierOrigin::ensure_origin(origin)?;
ensure!(
!LocationAssetId::<T>::contains_key(&location),
Error::<T>::LocationAlreadyExists
);
let asset_id = Self::next_asset_id_and_increment()?;
<T::AssetConfig as AssetConfig<T>>::AssetRegistry::create_asset(
asset_id,
metadata.clone().into(),
metadata.min_balance().clone(),
metadata.is_sufficient(),
)
.map_err(|_| Error::<T>::ErrorCreatingAsset)?;
AssetIdLocation::<T>::insert(asset_id, &location);
AssetIdMetadata::<T>::insert(asset_id, &metadata);
LocationAssetId::<T>::insert(&location, asset_id);

let asset_id = Self::do_register_asset(&location, &metadata)?;

// If it's a new para id, which will be inserted with AssetCount as 1.
// If not, AssetCount will increased by 1.
Expand All @@ -390,15 +427,15 @@ pub mod pallet {

Self::deposit_event(Event::<T>::AssetRegistered {
asset_id,
location,
metadata,
location: location.clone(),
metadata: metadata.clone(),
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
});
Ok(())
}

/// Update an asset by its asset id in the asset manager.
///
/// * `origin`: Caller of this extrinsic, the access control is specified by `ForceOrigin`.
/// * `origin`: Caller of this extrinsic, the access control is specified by `ModifierOrigin`.
/// * `asset_id`: AssetId to be updated.
/// * `location`: `location` to update the asset location.
#[pallet::call_index(1)]
Expand Down Expand Up @@ -598,12 +635,81 @@ pub mod pallet {
}
Ok(())
}

/// Register a LP(liquidity provider) asset in the asset manager based on two given already exist asset.
///
/// * `origin`: Caller of this extrinsic, the access control is specified by `ModifierOrigin`.
/// * `asset_0`: First assetId.
/// * `asset_1`: Second assetId.
/// * `location`: Location of the LP asset.
/// * `metadata`: LP Asset metadata.
#[pallet::call_index(7)]
#[pallet::weight(T::WeightInfo::register_asset())]
#[transactional]
pub fn register_lp_asset(
origin: OriginFor<T>,
asset_0: T::AssetId,
asset_1: T::AssetId,
location: T::Location,
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
metadata: <T::AssetConfig as AssetConfig<T>>::AssetRegistryMetadata,
) -> DispatchResult {
T::ModifierOrigin::ensure_origin(origin)?;
ensure!(asset_0 != asset_1, Error::<T>::AssetIdNotDifferent);
ensure!(
AssetIdLocation::<T>::contains_key(asset_0)
&& AssetIdLocation::<T>::contains_key(asset_1),
Error::<T>::AssetIdNotExist
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
);

let (asset_id0, asset_id1) = Self::sort_asset_id(asset_0, asset_1);
ensure!(
!AssetIdLp::<T>::contains_key((&asset_id0, &asset_id1)),
Error::<T>::AssetAlreadyRegistered
);

let asset_id = Self::do_register_asset(&location, &metadata)?;

AssetIdLp::<T>::insert((asset_id0, asset_id1), asset_id);
PoolIdLp::<T>::insert(asset_id, (asset_id0, asset_id1));

Self::deposit_event(Event::<T>::LPAssetRegistered {
asset_id0,
asset_id1,
asset_id,
location: location.clone(),
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
metadata: metadata.clone(),
});
Ok(())
}
}

impl<T> Pallet<T>
where
T: Config,
{
/// Register asset by providing location and metadata.
pub fn do_register_asset(
location: &T::Location,
metadata: &<T::AssetConfig as AssetConfig<T>>::AssetRegistryMetadata,
) -> Result<T::AssetId, DispatchError> {
ensure!(
!LocationAssetId::<T>::contains_key(location),
Error::<T>::LocationAlreadyExists
);
let asset_id = Self::next_asset_id_and_increment()?;
<T::AssetConfig as AssetConfig<T>>::AssetRegistry::create_asset(
asset_id,
metadata.clone().into(),
metadata.min_balance().clone(),
metadata.is_sufficient(),
)
.map_err(|_| Error::<T>::ErrorCreatingAsset)?;
AssetIdLocation::<T>::insert(asset_id, location);
AssetIdMetadata::<T>::insert(asset_id, metadata);
LocationAssetId::<T>::insert(location, asset_id);
Ok(asset_id)
}

/// Returns and increments the [`NextAssetId`] by one.
#[inline]
fn next_asset_id_and_increment() -> Result<T::AssetId, DispatchError> {
Expand Down Expand Up @@ -654,6 +760,15 @@ pub mod pallet {
pub fn check_outgoing_assets_filter(asset_location: &Option<MultiLocation>) -> bool {
FilteredOutgoingAssetLocations::<T>::contains_key(asset_location)
}

/// Sorted the assets pair
pub fn sort_asset_id(asset_0: T::AssetId, asset_1: T::AssetId) -> (T::AssetId, T::AssetId) {
if asset_0 < asset_1 {
(asset_0, asset_1)
} else {
(asset_1, asset_0)
}
}
}

/// Check the multilocation destination is supported by calamari/manta.
Expand Down
Loading
Loading