Skip to content

Commit

Permalink
dutch auction
Browse files Browse the repository at this point in the history
Signed-off-by: Dzmitry Lahoda <dzmitry@lahoda.pro>
  • Loading branch information
dzmitry-lahoda committed Jan 5, 2022
1 parent a150c48 commit 066226f
Show file tree
Hide file tree
Showing 19 changed files with 393 additions and 92 deletions.
8 changes: 6 additions & 2 deletions Cargo.lock

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

1 change: 0 additions & 1 deletion frame/bonded-finance/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use frame_support::{
use frame_system::RawOrigin;

const BALANCE: u64 = 10 * 1_000_000_000_000;

fn assets<T>() -> [AssetIdOf<T>; 2]
where
T: Config,
Expand Down
38 changes: 31 additions & 7 deletions frame/composable-traits/src/defi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub struct Sell<AssetId, Balance> {

impl<AssetId: PartialEq, Balance: PartialOrd + Zero + SafeArithmetic> Sell<AssetId, Balance> {
pub fn is_valid(&self) -> bool {
self.take.is_valid() && self.pair.is_valid()
self.take.is_valid()
}
pub fn new(
base: AssetId,
Expand All @@ -61,6 +61,9 @@ impl<AssetId: PartialEq, Balance: PartialOrd + Zero + SafeArithmetic> Sell<Asset

/// given `base`, how much `quote` needed for unit
/// see [currency pair](https://www.investopedia.com/terms/c/currencypair.asp)
/// Pair with same base and quote is considered valid as it allows to have mixer, money laundering
/// like behavior.
#[repr(C)]
#[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq)]
pub struct CurrencyPair<AssetId> {
/// See [Base Currency](https://www.investopedia.com/terms/b/basecurrency.asp)
Expand All @@ -70,15 +73,37 @@ pub struct CurrencyPair<AssetId> {
}

impl<AssetId: PartialEq> CurrencyPair<AssetId> {
pub fn is_valid(&self) -> bool {
self.base != self.quote
pub fn new(base: AssetId, quote: AssetId) -> Self {
Self { base, quote }
}

///```rust
/// let pair = composable_traits::defi::CurrencyPair::<u128>::new(13, 42);
/// let slice = pair.as_slice();
/// assert_eq!(slice[0], pair.base);
/// assert_eq!(slice[1], pair.quote);
/// ```
/// ```compile_fail
/// # let pair = composable_traits::defi::CurrencyPair::<u128>::new(13, 42);
/// # let slice = pair.as_slice();
/// drop(pair);
/// let _ = slice[0];
/// ```
pub fn as_slice(&self) -> &[AssetId] {
unsafe { sp_std::slice::from_raw_parts(self as *const Self as *const AssetId, 2) }
}
}

impl<AssetId: PartialEq> AsRef<[AssetId]> for CurrencyPair<AssetId> {
fn as_ref(&self) -> &[AssetId] {
self.as_slice()
}
}

/// type parameters for traits in pure defi area
pub trait DeFiEngine {
/// The asset ID type
type AssetId: AssetIdLike;
type MayBeAssetId: AssetIdLike;
/// The balance type of an account
type Balance: BalanceLike;
/// The user account identifier type for the runtime
Expand Down Expand Up @@ -129,7 +154,7 @@ pub trait SellEngine<Configuration>: DeFiEngine {
/// - `from_to` - account requesting sell
fn ask(
from_to: &Self::AccountId,
order: Sell<Self::AssetId, Self::Balance>,
order: Sell<Self::MayBeAssetId, Self::Balance>,
configuration: Configuration,
) -> Result<Self::OrderId, DispatchError>;
/// take order. get not found error if order never existed or was removed.
Expand All @@ -146,8 +171,7 @@ pub trait SellEngine<Configuration>: DeFiEngine {
}

pub trait DeFiComposableConfig: frame_system::Config {
// what.
type AssetId: AssetIdLike + MaybeSerializeDeserialize + Default;
type MayBeAssetId: AssetIdLike + MaybeSerializeDeserialize + Default;

type Balance: BalanceLike
+ Default
Expand Down
32 changes: 19 additions & 13 deletions frame/dutch-auction/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "pallet-dutch-auctions"
name = "pallet-dutch-auction"
version = "0.0.1"
authors = ["Composable Developers"]
homepage = "https://composable.finance"
Expand All @@ -21,43 +21,49 @@ sp-runtime = { default-features = false, git = "https://github.com/paritytech/su
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-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
smallvec = "1.7.0"
serde = { version = "1.0.130", optional = true }
scale-info = { version = "1.0", default-features = false, features = ["derive"] }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "17a791edf431d7d7aee1ea3dfaeeb7bc21944301", default-features = false }
num-traits = { version = "0.2.14", default-features = false }

frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' }
composable-traits = { path = "../composable-traits", default-features = false }

[dev-dependencies]
serde = "1.0.119"
proptest = "1.0"
hex-literal = "0.3.3"
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
pallet-currency-factory = { path = "../currency-factory" }
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" }
pallet-assets = { path = '../assets', default-features = false}
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "17a791edf431d7d7aee1ea3dfaeeb7bc21944301" }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "17a791edf431d7d7aee1ea3dfaeeb7bc21944301", default-features = false }
pallet-currency-factory = { path = "../currency-factory" }
hex-literal = {version = "0.3.3", default-features = false }
composable-tests-helpers = { path = "../composable-tests-helpers" }

[package.metadata.cargo-udeps.ignore]
development = ["composable-tests-helpers"]

[features]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
"frame-system/std",
"sp-std/std",
"sp-runtime/std",
"sp-io/std",
"sp-core/std",
"sp-std/std",
"sp-arithmetic/std",
"composable-traits/std",
"serde",
"scale-info/std",
"orml-traits/std",
"serde/std",
"frame-system/std",
"frame-support/std",
"codec/std",
"composable-traits/std",
]

runtime-benchmarks = [
"frame-benchmarking",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
]
108 changes: 108 additions & 0 deletions frame/dutch-auction/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use super::*;
use crate::Pallet as DutchAuction;
use codec::Decode;
use composable_traits::defi::{CurrencyPair, DeFiComposableConfig, Sell, Take};
use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller};
use frame_support::traits::{fungibles::Mutate, Hooks};
use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
use sp_std::prelude::*;

// meaningless sell of 1 to 1
pub fn sell_identity<T: Config>(
) -> Sell<<T as DeFiComposableConfig>::MayBeAssetId, <T as DeFiComposableConfig>::Balance> {
let one: <T as DeFiComposableConfig>::Balance = 1u64.into();
let pair = assets::<T>();
Sell::new(pair.base, pair.quote, one, one)
}

// meaningless take of 1 to 1
pub fn take_identity<T: Config>() -> Take<<T as DeFiComposableConfig>::Balance> {
let one: <T as DeFiComposableConfig>::Balance = 1u64.into();
Take::new(one, one)
}

pub type AssetIdOf<T> = <T as DeFiComposableConfig>::MayBeAssetId;

fn assets<T>() -> CurrencyPair<AssetIdOf<T>>
where
T: Config,
{
let a = 0u128.to_be_bytes();
let b = 1u128.to_be_bytes();
CurrencyPair::new(
AssetIdOf::<T>::decode(&mut &a[..]).unwrap(),
AssetIdOf::<T>::decode(&mut &b[..]).unwrap(),
)
}

benchmarks! {
where_clause {
where
<T as Config>::MultiCurrency:
Mutate<T::AccountId, Balance = T::Balance, AssetId = T::MayBeAssetId>,
}
ask {
let sell = sell_identity::<T>();
let account_id : T::AccountId = whitelisted_caller();
let caller = RawOrigin::Signed(account_id.clone());
let amount: T::Balance = 1_000_000u64.into();
<T as pallet::Config>::MultiCurrency::mint_into(sell.pair.base, &account_id, amount).unwrap();
}: _(
caller,
sell,
<_>::default()
)
take {
let x in 1..2^16;
let sell = sell_identity::<T>();
let account_id : T::AccountId = whitelisted_caller();
let caller = RawOrigin::Signed(account_id.clone());
let amount: T::Balance = 1_000_000u64.into();
<T as pallet::Config>::MultiCurrency::mint_into(sell.pair.base, &account_id, amount).unwrap();
<T as pallet::Config>::MultiCurrency::mint_into(sell.pair.quote, &account_id, amount).unwrap();
DutchAuction::<T>::ask(caller.clone().into(), sell, <_>::default()).unwrap();
let order_id = OrdersIndex::<T>::get();
let take_order = take_identity::<T>();
for i in 0..x {
DutchAuction::<T>::take(caller.clone().into(), order_id, take_order.clone()).unwrap();
}
}: _(
caller,
order_id,
take_order
)
liquidate {
let sell = sell_identity::<T>();
let account_id : T::AccountId = whitelisted_caller();
let caller = RawOrigin::Signed(account_id.clone());
let amount: T::Balance = 1_000_000u64.into();
<T as pallet::Config>::MultiCurrency::mint_into(sell.pair.base, &account_id, amount).unwrap();
DutchAuction::<T>::ask(caller.clone().into(), sell, <_>::default()).unwrap();
let order_id = OrdersIndex::<T>::get();
}: _(
caller,
order_id
)
known_overhead_for_on_finalize {
let sell = sell_identity::<T>();
let account_id : T::AccountId = whitelisted_caller();
let caller = RawOrigin::Signed(account_id.clone());
let amount: T::Balance = 1_000_000u64.into();

<T as pallet::Config>::MultiCurrency::mint_into(sell.pair.base, &account_id, amount).unwrap();
<T as pallet::Config>::MultiCurrency::mint_into(sell.pair.quote, &account_id, amount).unwrap();
DutchAuction::<T>::ask(caller.clone().into(), sell, <_>::default()).unwrap();
let order_id = OrdersIndex::<T>::get();
let take_order = take_identity::<T>();
DutchAuction::<T>::take(caller.clone().into(), order_id, take_order.clone()).unwrap();
} : {
<DutchAuction::<T> as Hooks<BlockNumberFor<T>>>::on_finalize(T::BlockNumber::default())
}

}

impl_benchmark_test_suite!(
DutchAuction,
crate::mock::runtime::new_test_externalities(),
crate::mock::runtime::Runtime,
);

0 comments on commit 066226f

Please sign in to comment.