generated from substrate-developer-hub/substrate-node-template
-
Notifications
You must be signed in to change notification settings - Fork 60
/
types.rs
168 lines (148 loc) · 4.6 KB
/
types.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#![allow(clippy::bad_bit_mask)]
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use crate::{Config, Pallet, MAX_ASSETS_IN_POOL};
use sp_runtime::Permill;
use sp_std::collections::btree_set::BTreeSet;
use sp_std::num::NonZeroU16;
use sp_std::prelude::*;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::traits::ConstU32;
use frame_support::weights::Weight;
use frame_support::BoundedVec;
use hydra_dx_math::stableswap::types::AssetReserve;
use orml_traits::MultiCurrency;
use scale_info::TypeInfo;
use sp_core::RuntimeDebug;
use sp_runtime::DispatchResult;
pub(crate) type Balance = u128;
/// Pool properties for 2-asset pool (v1)
/// `assets`: pool assets
/// `amplification`: amp parameter
/// `fee`: trade fee to be withdrawn on sell/buy
#[derive(Encode, Decode, Eq, PartialEq, Clone, RuntimeDebug, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct PoolInfo<AssetId, BlockNumber> {
pub assets: BoundedVec<AssetId, ConstU32<MAX_ASSETS_IN_POOL>>,
pub initial_amplification: NonZeroU16,
pub final_amplification: NonZeroU16,
pub initial_block: BlockNumber,
pub final_block: BlockNumber,
pub fee: Permill,
}
fn has_unique_elements<T>(iter: &mut T) -> bool
where
T: Iterator,
T::Item: Ord,
{
let mut uniq = BTreeSet::new();
iter.all(move |x| uniq.insert(x))
}
impl<AssetId, Blocknumber> PoolInfo<AssetId, Blocknumber>
where
AssetId: Ord + Copy,
{
pub(crate) fn find_asset(&self, asset: AssetId) -> Option<usize> {
self.assets.iter().position(|v| *v == asset)
}
pub(crate) fn is_valid(&self) -> bool {
self.assets.len() >= 2 && has_unique_elements(&mut self.assets.iter())
}
pub(crate) fn reserves_with_decimals<T: Config>(&self, account: &T::AccountId) -> Option<Vec<AssetReserve>>
where
T::AssetId: From<AssetId>,
{
self.assets
.iter()
.map(|asset| {
let reserve = T::Currency::free_balance((*asset).into(), account);
let decimals = Pallet::<T>::retrieve_decimals((*asset).into())?;
Some(AssetReserve {
amount: reserve,
decimals,
})
})
.collect()
}
}
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo, Default)]
pub struct AssetAmount<AssetId> {
pub asset_id: AssetId,
pub amount: Balance,
}
impl<AssetId: Default> AssetAmount<AssetId> {
pub fn new(asset_id: AssetId, amount: Balance) -> Self {
Self { asset_id, amount }
}
}
impl<AssetId> From<AssetAmount<AssetId>> for u128 {
fn from(value: AssetAmount<AssetId>) -> Self {
value.amount
}
}
impl<AssetId> From<&AssetAmount<AssetId>> for u128 {
fn from(value: &AssetAmount<AssetId>) -> Self {
value.amount
}
}
bitflags::bitflags! {
/// Indicates whether asset can be bought or sold to/from Omnipool and/or liquidity added/removed.
#[derive(Encode,Decode, MaxEncodedLen, TypeInfo)]
pub struct Tradability: u8 {
/// Asset is frozen. No operations are allowed.
const FROZEN = 0b0000_0000;
/// Asset is allowed to be sold into stable pool
const SELL = 0b0000_0001;
/// Asset is allowed to be bought into stable pool
const BUY = 0b0000_0010;
/// Adding liquidity of asset is allowed
const ADD_LIQUIDITY = 0b0000_0100;
/// Removing liquidity of asset is not allowed
const REMOVE_LIQUIDITY = 0b0000_1000;
}
}
impl Default for Tradability {
fn default() -> Self {
Tradability::SELL | Tradability::BUY | Tradability::ADD_LIQUIDITY | Tradability::REMOVE_LIQUIDITY
}
}
#[cfg(feature = "runtime-benchmarks")]
pub trait BenchmarkHelper<AssetId> {
fn register_asset(asset_id: AssetId, decimals: u8) -> DispatchResult;
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct PoolState<AssetId> {
pub assets: Vec<AssetId>,
pub before: Vec<Balance>,
pub after: Vec<Balance>,
pub delta: Vec<Balance>,
pub issuance_before: Balance,
pub issuance_after: Balance,
pub share_prices: Vec<(Balance, Balance)>,
}
/// Interface for populating oracle from stableswap, and getting their weights
pub trait StableswapHooks<AssetId> {
fn on_liquidity_changed(pool_id: AssetId, state: PoolState<AssetId>) -> DispatchResult;
fn on_trade(pool_id: AssetId, asset_in: AssetId, asset_out: AssetId, state: PoolState<AssetId>) -> DispatchResult;
fn on_liquidity_changed_weight(n: usize) -> Weight;
fn on_trade_weight(n: usize) -> Weight;
}
impl<AssetId> StableswapHooks<AssetId> for () {
fn on_liquidity_changed(_pool_id: AssetId, _state: PoolState<AssetId>) -> DispatchResult {
Ok(())
}
fn on_trade(
_pool_id: AssetId,
_asset_in: AssetId,
_asset_out: AssetId,
_state: PoolState<AssetId>,
) -> DispatchResult {
Ok(())
}
fn on_liquidity_changed_weight(_n: usize) -> Weight {
Weight::zero()
}
fn on_trade_weight(_n: usize) -> Weight {
Weight::zero()
}
}