Skip to content

Commit

Permalink
Implement basic DEX Router pallet.
Browse files Browse the repository at this point in the history
  • Loading branch information
vivekvpandya committed Jan 5, 2022
1 parent 40c44c1 commit 2307265
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 2 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

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

20 changes: 18 additions & 2 deletions frame/composable-traits/src/dex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_runtime::{DispatchError, FixedU128, Permill};
use sp_std::vec::Vec;
use frame_support::RuntimeDebug;

/// Implement AMM curve from "StableSwap - efficient mechanism for Stablecoin liquidity by Micheal
/// Egorov" Also blog at https://miguelmota.com/blog/understanding-stableswap-curve/ has very good explanation.
Expand Down Expand Up @@ -66,7 +67,7 @@ pub trait CurveAmm {
}

/// Pool type
#[derive(Encode, Decode, TypeInfo, Clone, Default, PartialEq, Eq, Debug)]
#[derive(Encode, Decode, TypeInfo, Clone, Default, PartialEq, Eq, RuntimeDebug)]
pub struct StableSwapPoolInfo<AccountId> {
/// Owner of pool
pub owner: AccountId,
Expand Down Expand Up @@ -100,10 +101,25 @@ pub trait SimpleExchange {
) -> Result<Self::Balance, DispatchError>;
}

#[derive(Encode, Decode, TypeInfo, Clone, Default, PartialEq, Eq, Debug)]
#[derive(Encode, Decode, TypeInfo, Clone, Default, PartialEq, Eq, RuntimeDebug)]
pub struct ConstantProductPoolInfo<AccountId> {
/// Owner of pool
pub owner: AccountId,
/// Amount of the fee pool charges for the exchange
pub fee: Permill,
}

/// Describes route for DEX, Direct gives pool_id to use,
/// Via gives recursive route with pair of pool_id, route_id.
#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
pub enum DexRoute<PoolId, RouteId> {
Direct(PoolId),
Via((PoolId, RouteId))
}

pub trait DexRouter<AssetId, PoolId, RouteId> {
/// if route is `None` then delete existing entry for `asset_pair`
/// if route is `Some` and no entry exist for `asset_pair` then add new entry else update
/// existing entry.
fn update(asset_pair : (AssetId, AssetId), route : Option<DexRoute<PoolId, RouteId>>);
}
43 changes: 43 additions & 0 deletions frame/dex-router/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[package]
name = "pallet-dex-router"
version = "0.0.1"
authors = ["Composable Developers"]
homepage = "https://composable.finance"
edition = "2021"
rust-version = "1.56"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }

sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }

composable-traits = { path = "../composable-traits", default-features = false }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "17a791edf431d7d7aee1ea3dfaeeb7bc21944301", default-features = false }
scale-info = { version = "1.0", default-features = false, features = ["derive"] }

[dependencies.codec]
default-features = false
features = ["derive"]
package = "parity-scale-codec"
version = "2.0.0"

[dev-dependencies]
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }

[features]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
"frame-system/std",
"sp-runtime/std",
"orml-traits/std",
]
105 changes: 105 additions & 0 deletions frame/dex-router/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//! # DEX Router Pallet
//!
//! Is used to add route to DEX for given asset_id's pair.

#![cfg_attr(not(test), warn(clippy::disallowed_method, clippy::indexing_slicing))] // allow in tests
#![warn(clippy::unseparated_literal_suffix, clippy::disallowed_type)]
#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[cfg(test)]
mod mock;

#[cfg(test)]
mod tests;

#[frame_support::pallet]
pub mod pallet {
use codec::FullCodec;
use composable_traits::{
currency::AssetIdLike,
dex::{DexRoute, DexRouter},
};
use frame_support::pallet_prelude::*;


#[pallet::config]
pub trait Config: frame_system::Config {
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
type AssetId: AssetIdLike + Decode + Clone + core::fmt::Debug + Default;
type RouteId: FullCodec + Copy + Eq + PartialEq + core::fmt::Debug + TypeInfo;
type PoolId: FullCodec + Copy + Eq + PartialEq + core::fmt::Debug + TypeInfo;
}

#[pallet::pallet]
#[pallet::generate_store(trait Store)]
pub struct Pallet<T>(_);

#[pallet::storage]
pub type DexRoutes<T: Config> = StorageDoubleMap<
_,
Blake2_128Concat,
T::AssetId,
Blake2_128Concat,
T::AssetId,
DexRoute<T::PoolId, T::RouteId>,
OptionQuery,
>;

#[pallet::error]
pub enum Error<T> {
}

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
RouteAdded { x_asset_id: T::AssetId, y_asset_id: T::AssetId, route : DexRoute<T::PoolId, T::RouteId> },
RouteDeleted { x_asset_id: T::AssetId, y_asset_id: T::AssetId, route : DexRoute<T::PoolId, T::RouteId> },
RouteUpdated { x_asset_id: T::AssetId, y_asset_id: T::AssetId, route : DexRoute<T::PoolId, T::RouteId> },
}

#[pallet::call]
impl<T: Config> Pallet<T> {
}

impl<T: Config> Pallet<T> {
}

impl<T: Config> DexRouter<T::AssetId, T::PoolId, T::RouteId> for Pallet<T> {
fn update(asset_pair : (T::AssetId, T::AssetId), route : Option<DexRoute<T::PoolId, T::RouteId>>) {
match route {
Some(r) => {
let mut update = false;
if DexRoutes::<T>::contains_key(asset_pair.0, asset_pair.1) {
update = true;
}
DexRoutes::<T>::insert(asset_pair.0, asset_pair.1, r.clone());
if update {
Self::deposit_event(Event::RouteUpdated {
x_asset_id : asset_pair.0,
y_asset_id : asset_pair.1,
route: r,
});
} else {
Self::deposit_event(Event::RouteAdded {
x_asset_id : asset_pair.0,
y_asset_id : asset_pair.1,
route: r,
});
}
},
None => {
if DexRoutes::<T>::contains_key(asset_pair.0, asset_pair.1) {
let r = DexRoutes::<T>::take(asset_pair.0, asset_pair.1).expect("inconsistent storage");
Self::deposit_event(Event::RouteDeleted {
x_asset_id : asset_pair.0,
y_asset_id : asset_pair.1,
route: r,
});
}
}
}
}
}
}
Empty file added frame/dex-router/src/mock.rs
Empty file.
Empty file added frame/dex-router/src/tests.rs
Empty file.

0 comments on commit 2307265

Please sign in to comment.