-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* dutch auction Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * fixed tests Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * fixed clippy Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * fixed review comments Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * adding tests and fixing bugs Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * refactoring Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * fix fmt Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * fixed udeps Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro> * fixed clippy Signed-off-by: dzmitry-lahoda <dzmitry@lahoda.pro>
- Loading branch information
1 parent
7ce087d
commit b46e402
Showing
35 changed files
with
1,273 additions
and
1,170 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
//! Common codes for defi pallets | ||
|
||
use codec::{Codec, Decode, Encode, FullCodec}; | ||
use frame_support::{pallet_prelude::MaybeSerializeDeserialize, Parameter}; | ||
use scale_info::TypeInfo; | ||
use sp_runtime::{ | ||
traits::{CheckedAdd, CheckedMul, CheckedSub, Zero}, | ||
ArithmeticError, DispatchError, FixedPointOperand, | ||
}; | ||
|
||
use crate::{ | ||
currency::{AssetIdLike, BalanceLike}, | ||
math::{LiftedFixedBalance, SafeArithmetic}, | ||
}; | ||
|
||
#[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq)] | ||
pub struct Take<Balance> { | ||
/// amount of `base` | ||
pub amount: Balance, | ||
/// direction depends on referenced order type | ||
/// either minimal or maximal amount of `quote` for given unit of `base` | ||
pub limit: Balance, | ||
} | ||
|
||
impl<Balance: PartialOrd + Zero + SafeArithmetic> Take<Balance> { | ||
pub fn is_valid(&self) -> bool { | ||
self.amount > Balance::zero() && self.limit > Balance::zero() | ||
} | ||
pub fn new(amount: Balance, limit: Balance) -> Self { | ||
Self { amount, limit } | ||
} | ||
|
||
pub fn quote_amount(&self) -> Result<Balance, ArithmeticError> { | ||
self.amount.safe_mul(&self.limit) | ||
} | ||
} | ||
|
||
/// take `quote` currency and give `base` currency | ||
#[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq)] | ||
pub struct Sell<AssetId, Balance> { | ||
pub pair: CurrencyPair<AssetId>, | ||
pub take: Take<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() | ||
} | ||
pub fn new( | ||
base: AssetId, | ||
quote: AssetId, | ||
base_amount: Balance, | ||
minimal_base_unit_price_in_quote: Balance, | ||
) -> Self { | ||
Self { | ||
take: Take { amount: base_amount, limit: minimal_base_unit_price_in_quote }, | ||
pair: CurrencyPair { base, quote }, | ||
} | ||
} | ||
} | ||
|
||
/// given `base`, how much `quote` needed for unit | ||
/// see [currency pair](https://www.investopedia.com/terms/c/currencypair.asp) | ||
#[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq)] | ||
pub struct CurrencyPair<AssetId> { | ||
/// See [Base Currency](https://www.investopedia.com/terms/b/basecurrency.asp) | ||
pub base: AssetId, | ||
/// counter currency | ||
pub quote: AssetId, | ||
} | ||
|
||
impl<AssetId: PartialEq> CurrencyPair<AssetId> { | ||
pub fn is_valid(&self) -> bool { | ||
self.base != self.quote | ||
} | ||
} | ||
|
||
/// type parameters for traits in pure defi area | ||
pub trait DeFiEngine { | ||
/// The asset ID type | ||
type AssetId: AssetIdLike; | ||
/// The balance type of an account | ||
type Balance: BalanceLike; | ||
/// The user account identifier type for the runtime | ||
type AccountId; | ||
} | ||
|
||
/// take nothing | ||
impl<Balance: Default> Default for Take<Balance> { | ||
fn default() -> Self { | ||
Self { amount: Default::default(), limit: Default::default() } | ||
} | ||
} | ||
|
||
impl<AssetId: Default> Default for CurrencyPair<AssetId> { | ||
fn default() -> Self { | ||
Self { base: Default::default(), quote: Default::default() } | ||
} | ||
} | ||
|
||
/// default sale is no sale and invalid sale | ||
impl<AssetId: Default, Balance: Default> Default for Sell<AssetId, Balance> { | ||
fn default() -> Self { | ||
Self { pair: Default::default(), take: Default::default() } | ||
} | ||
} | ||
|
||
/// order is something that lives some some time until taken | ||
pub trait OrderIdLike: | ||
FullCodec + Copy + Eq + PartialEq + sp_std::fmt::Debug + TypeInfo + sp_std::hash::Hash + Default | ||
{ | ||
} | ||
impl< | ||
T: FullCodec | ||
+ Copy | ||
+ Eq | ||
+ PartialEq | ||
+ sp_std::fmt::Debug | ||
+ TypeInfo | ||
+ sp_std::hash::Hash | ||
+ Default, | ||
> OrderIdLike for T | ||
{ | ||
} | ||
|
||
pub trait SellEngine<Configuration>: DeFiEngine { | ||
type OrderId: OrderIdLike; | ||
/// sell base asset for price given or higher | ||
/// - `from_to` - account requesting sell | ||
fn ask( | ||
from_to: &Self::AccountId, | ||
order: Sell<Self::AssetId, Self::Balance>, | ||
configuration: Configuration, | ||
) -> Result<Self::OrderId, DispatchError>; | ||
/// take order. get not found error if order never existed or was removed. | ||
/// - `take.limit` - for `sell` order it is maximal value are you to pay for `base` in `quote` | ||
/// asset, for `buy` | ||
/// order it is minimal value you are eager to accept for `base` | ||
/// - `take.amount` - amount of | ||
/// `base` you are ready to exchange for this order | ||
fn take( | ||
from_to: &Self::AccountId, | ||
order_id: Self::OrderId, | ||
take: Take<Self::Balance>, | ||
) -> Result<(), DispatchError>; | ||
} | ||
|
||
pub trait DeFiComposableConfig: frame_system::Config { | ||
// what. | ||
type AssetId: AssetIdLike + MaybeSerializeDeserialize + Default; | ||
|
||
type Balance: BalanceLike | ||
+ Default | ||
+ Parameter | ||
+ Codec | ||
+ Copy | ||
+ Ord | ||
+ CheckedAdd | ||
+ CheckedSub | ||
+ CheckedMul | ||
+ CheckedSub | ||
+ From<u64> // at least 64 bit | ||
+ Zero | ||
+ FixedPointOperand | ||
+ Into<LiftedFixedBalance> // integer part not more than bits in this | ||
+ Into<u128>; // cannot do From<u128>, until LiftedFixedBalance integer part is larger than 128 | ||
// bit | ||
} |
Oops, something went wrong.