mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +00:00
add genesis liquidity implementation
This commit is contained in:
46
substrate/genesis-liquidity/pallet/Cargo.toml
Normal file
46
substrate/genesis-liquidity/pallet/Cargo.toml
Normal file
@@ -0,0 +1,46 @@
|
||||
[package]
|
||||
name = "serai-genesis-liquidity-pallet"
|
||||
version = "0.1.0"
|
||||
description = "Genesis liquidity pallet for Serai"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/genesis-liquidity/pallet"
|
||||
authors = ["Akil Demir <aeg_asd@hotmail.com>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.77"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["scale", "scale-info"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
|
||||
[dependencies]
|
||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
|
||||
scale-info = { version = "2", default-features = false, features = ["derive"] }
|
||||
|
||||
frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
|
||||
sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
|
||||
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false }
|
||||
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false }
|
||||
|
||||
serai-primitives = { path = "../../primitives", default-features = false }
|
||||
genesis-liquidity-primitives = { package = "serai-genesis-liquidity-primitives", path = "../primitives", default-features = false }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
"frame-system/std",
|
||||
"frame-support/std",
|
||||
|
||||
"coins-pallet/std",
|
||||
"dex-pallet/std",
|
||||
]
|
||||
|
||||
default = ["std"]
|
||||
15
substrate/genesis-liquidity/pallet/LICENSE
Normal file
15
substrate/genesis-liquidity/pallet/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
||||
AGPL-3.0-only license
|
||||
|
||||
Copyright (c) 2024 Luke Parker
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License Version 3 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
271
substrate/genesis-liquidity/pallet/src/lib.rs
Normal file
271
substrate/genesis-liquidity/pallet/src/lib.rs
Normal file
@@ -0,0 +1,271 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[allow(clippy::cast_possible_truncation, clippy::no_effect_underscore_binding)]
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
use frame_system::{pallet_prelude::*, RawOrigin};
|
||||
use frame_support::{pallet_prelude::*, sp_runtime::SaturatedConversion};
|
||||
|
||||
use sp_std::{vec, collections::btree_map::BTreeMap};
|
||||
|
||||
use dex_pallet::{Pallet as Dex, Config as DexConfig};
|
||||
use coins_pallet::{
|
||||
primitives::{OutInstructionWithBalance, OutInstruction},
|
||||
Config as CoinsConfig, Pallet as Coins, AllowMint,
|
||||
};
|
||||
|
||||
use serai_primitives::*;
|
||||
pub use genesis_liquidity_primitives as primitives;
|
||||
use primitives::*;
|
||||
|
||||
/// LiquidityTokens Pallet as an instance of coins pallet.
|
||||
pub type LiquidityTokens<T> = coins_pallet::Pallet<T, coins_pallet::Instance1>;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config:
|
||||
frame_system::Config + DexConfig + CoinsConfig + coins_pallet::Config<coins_pallet::Instance1>
|
||||
{
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||
}
|
||||
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
GenesisPeriodEnded,
|
||||
AmountOverflowed,
|
||||
NotEnoughLiquidity,
|
||||
CanOnlyRemoveFullAmount,
|
||||
}
|
||||
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
GenesisLiquidityAdded { by: SeraiAddress, balance: Balance },
|
||||
GenesisLiquidityRemoved { by: SeraiAddress, balance: Balance },
|
||||
GenesisLiquidityAddedToPool { coin1: Balance, coin2: Balance },
|
||||
EconomicSecurityReached { network: NetworkId },
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
pub struct Pallet<T>(PhantomData<T>);
|
||||
|
||||
#[pallet::storage]
|
||||
pub(crate) type Liquidity<T: Config> =
|
||||
StorageDoubleMap<_, Identity, Coin, Blake2_128Concat, PublicKey, SubstrateAmount, OptionQuery>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub(crate) type LiquidityTokensPerAddress<T: Config> =
|
||||
StorageDoubleMap<_, Identity, Coin, Blake2_128Concat, PublicKey, SubstrateAmount, OptionQuery>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub(crate) type EconomicSecurityReached<T: Config> =
|
||||
StorageMap<_, Identity, NetworkId, BlockNumberFor<T>, ValueQuery>;
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
|
||||
fn on_finalize(n: BlockNumberFor<T>) {
|
||||
// Distribute the genesis sri to pools after a month
|
||||
if n > BLOCKS_PER_MONTH.into() {
|
||||
// mint the SRI
|
||||
Coins::<T>::mint(
|
||||
GENESIS_LIQUIDITY_ACCOUNT.into(),
|
||||
Balance { coin: Coin::Serai, amount: Amount(GENESIS_SRI) },
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// get coin values & total
|
||||
let mut account_values = BTreeMap::new();
|
||||
let mut pool_values = BTreeMap::new();
|
||||
let mut total_value: u64 = 0;
|
||||
for coin in COINS {
|
||||
// TODO: following line is just a place holder till we get the actual coin value
|
||||
// in terms of btc.
|
||||
let value = Dex::<T>::security_oracle_value(coin).unwrap_or(Amount(0)).0;
|
||||
account_values.insert(coin, vec![]);
|
||||
let mut pool_amount: u64 = 0;
|
||||
for (account, amount) in Liquidity::<T>::iter_prefix(coin) {
|
||||
pool_amount += amount;
|
||||
let value_this_addr = amount * value;
|
||||
account_values.get_mut(&coin).unwrap().push((account, value_this_addr))
|
||||
}
|
||||
|
||||
let pool_value = pool_amount * value;
|
||||
total_value += pool_value;
|
||||
pool_values.insert(coin, (pool_amount, pool_value));
|
||||
}
|
||||
|
||||
// add the liquidity per pool
|
||||
for (coin, (amount, value)) in &pool_values {
|
||||
let sri_amount = (GENESIS_SRI * value) / total_value;
|
||||
let origin = RawOrigin::Signed(GENESIS_LIQUIDITY_ACCOUNT.into());
|
||||
Dex::<T>::add_liquidity(
|
||||
origin.into(),
|
||||
*coin,
|
||||
*amount,
|
||||
sri_amount,
|
||||
*amount,
|
||||
sri_amount,
|
||||
GENESIS_LIQUIDITY_ACCOUNT.into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// set liquidity tokens per account
|
||||
let tokens = LiquidityTokens::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), *coin).0;
|
||||
let mut total_tokens_this_coin: u64 = 0;
|
||||
for (acc, value) in account_values.get(coin).unwrap() {
|
||||
let liq_tokens_this_acc = (tokens * value) / pool_values.get(coin).unwrap().1;
|
||||
total_tokens_this_coin += liq_tokens_this_acc;
|
||||
LiquidityTokensPerAddress::<T>::set(coin, acc, Some(liq_tokens_this_acc));
|
||||
}
|
||||
assert_eq!(tokens, total_tokens_this_coin);
|
||||
}
|
||||
|
||||
// we shouldn't have any coin left in our account at this moment, including SRI.
|
||||
for coin in COINS {
|
||||
assert_eq!(Coins::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), coin), Amount(0));
|
||||
}
|
||||
}
|
||||
|
||||
// we accept we reached economic security once we can mint smallest amount of a network's coin
|
||||
for coin in COINS {
|
||||
let existing = EconomicSecurityReached::<T>::get(coin.network());
|
||||
if existing == 0u32.into() &&
|
||||
<T as CoinsConfig>::AllowMint::is_allowed(&Balance { coin, amount: Amount(1) })
|
||||
{
|
||||
EconomicSecurityReached::<T>::set(coin.network(), n);
|
||||
Self::deposit_event(Event::EconomicSecurityReached { network: coin.network() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Add genesis liquidity for the given account. All accounts that provide liquidity
|
||||
/// will receive the genesis SRI according to their liquidity ratio.
|
||||
pub fn add_coin_liquidity(account: PublicKey, balance: Balance) -> DispatchResult {
|
||||
// check we are still in genesis period
|
||||
if Self::genesis_ended() {
|
||||
Err(Error::<T>::GenesisPeriodEnded)?;
|
||||
}
|
||||
|
||||
// mint the coins
|
||||
Coins::<T>::mint(GENESIS_LIQUIDITY_ACCOUNT.into(), balance)?;
|
||||
|
||||
// save
|
||||
let existing = Liquidity::<T>::get(balance.coin, account).unwrap_or(0);
|
||||
let new = existing.checked_add(balance.amount.0).ok_or(Error::<T>::AmountOverflowed)?;
|
||||
Liquidity::<T>::set(balance.coin, account, Some(new));
|
||||
|
||||
Self::deposit_event(Event::GenesisLiquidityAdded { by: account.into(), balance });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove the provided genesis liquidity for an account. If called pre-economic security era,
|
||||
pub fn remove_coin_liquidity(
|
||||
account: PublicKey,
|
||||
balance: Balance,
|
||||
out_address: ExternalAddress,
|
||||
) -> DispatchResult {
|
||||
let origin = RawOrigin::Signed(GENESIS_LIQUIDITY_ACCOUNT.into());
|
||||
|
||||
// check we are still in genesis period
|
||||
if Self::genesis_ended() {
|
||||
// check user have enough to remove
|
||||
let existing = LiquidityTokensPerAddress::<T>::get(balance.coin, account).unwrap_or(0);
|
||||
if balance.amount.0 > existing {
|
||||
Err(Error::<T>::NotEnoughLiquidity)?;
|
||||
}
|
||||
|
||||
// remove liquidity from pool
|
||||
let prev_sri = Coins::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), Coin::Serai);
|
||||
let prev_coin = Coins::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), balance.coin);
|
||||
Dex::<T>::remove_liquidity(
|
||||
origin.clone().into(),
|
||||
balance.coin,
|
||||
balance.amount.0,
|
||||
1,
|
||||
1,
|
||||
GENESIS_LIQUIDITY_ACCOUNT.into(),
|
||||
)?;
|
||||
let current_sri = Coins::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), Coin::Serai);
|
||||
let current_coin = Coins::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), balance.coin);
|
||||
|
||||
// burn the SRI if necessary
|
||||
let mut sri = current_sri.0 - prev_sri.0;
|
||||
let burn_sri_amount = (sri *
|
||||
(GENESIS_SRI_TRICKLE_FEED - Self::blocks_since_ec_security(&balance.coin))) /
|
||||
GENESIS_SRI_TRICKLE_FEED;
|
||||
Coins::<T>::burn(
|
||||
origin.clone().into(),
|
||||
Balance { coin: Coin::Serai, amount: Amount(burn_sri_amount) },
|
||||
)?;
|
||||
sri -= burn_sri_amount;
|
||||
|
||||
// transfer to owner
|
||||
let coin_out = current_coin.0 - prev_coin.0;
|
||||
Coins::<T>::transfer(
|
||||
origin.clone().into(),
|
||||
account,
|
||||
Balance { coin: balance.coin, amount: Amount(coin_out) },
|
||||
)?;
|
||||
Coins::<T>::transfer(
|
||||
origin.into(),
|
||||
account,
|
||||
Balance { coin: Coin::Serai, amount: Amount(sri) },
|
||||
)?;
|
||||
|
||||
// save
|
||||
let existing = LiquidityTokensPerAddress::<T>::get(balance.coin, account).unwrap_or(0);
|
||||
let new = existing.checked_sub(balance.amount.0).ok_or(Error::<T>::AmountOverflowed)?;
|
||||
LiquidityTokensPerAddress::<T>::set(balance.coin, account, Some(new));
|
||||
} else {
|
||||
let existing = Liquidity::<T>::get(balance.coin, account).unwrap_or(0);
|
||||
if balance.amount.0 > existing || balance.amount.0 == 0 {
|
||||
Err(Error::<T>::NotEnoughLiquidity)?;
|
||||
}
|
||||
if balance.amount.0 < existing {
|
||||
Err(Error::<T>::CanOnlyRemoveFullAmount)?;
|
||||
}
|
||||
|
||||
// TODO: do internal transfer instead?
|
||||
let origin = RawOrigin::Signed(GENESIS_LIQUIDITY_ACCOUNT.into());
|
||||
let instruction = OutInstructionWithBalance {
|
||||
instruction: OutInstruction { address: out_address, data: None },
|
||||
balance,
|
||||
};
|
||||
Coins::<T>::burn_with_instruction(origin.into(), instruction)?;
|
||||
|
||||
// save
|
||||
Liquidity::<T>::set(balance.coin, account, None);
|
||||
}
|
||||
|
||||
Self::deposit_event(Event::GenesisLiquidityRemoved { by: account.into(), balance });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Returns the number of blocks since the coin's network reached economic security first time.
|
||||
// If the network is yet to be reached that threshold 0 is returned, and maximum of
|
||||
// GENESIS_SRI_TRICKLE_FEED returned.
|
||||
fn blocks_since_ec_security(coin: &Coin) -> u64 {
|
||||
let ec_security_block =
|
||||
EconomicSecurityReached::<T>::get(coin.network()).saturated_into::<u64>();
|
||||
let current = <frame_system::Pallet<T>>::block_number().saturated_into::<u64>();
|
||||
if ec_security_block > 0 {
|
||||
let diff = current - ec_security_block;
|
||||
if diff > GENESIS_SRI_TRICKLE_FEED {
|
||||
return GENESIS_SRI_TRICKLE_FEED;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn genesis_ended() -> bool {
|
||||
<frame_system::Pallet<T>>::block_number() >= BLOCKS_PER_MONTH.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use pallet::*;
|
||||
25
substrate/genesis-liquidity/primitives/Cargo.toml
Normal file
25
substrate/genesis-liquidity/primitives/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "serai-genesis-liquidity-primitives"
|
||||
version = "0.1.0"
|
||||
description = "Serai genesis liquidity primitives"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/genesis-liquidity/primitives"
|
||||
authors = ["Akil Demir <aeg_asd@hotmail.com>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.77"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
serai-primitives = { path = "../../primitives", default-features = false }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
"serai-primitives/std",
|
||||
]
|
||||
default = ["std"]
|
||||
21
substrate/genesis-liquidity/primitives/LICENSE
Normal file
21
substrate/genesis-liquidity/primitives/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Luke Parker
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
17
substrate/genesis-liquidity/primitives/src/lib.rs
Normal file
17
substrate/genesis-liquidity/primitives/src/lib.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use serai_primitives::*;
|
||||
|
||||
// amount of blocks in 30 days for 6s per block.
|
||||
pub const BLOCKS_PER_MONTH: u32 = 10 * 60 * 24 * 30;
|
||||
|
||||
/// 180 days of blocks
|
||||
pub const GENESIS_SRI_TRICKLE_FEED: u64 = 10 * 60 * 24 * 180;
|
||||
|
||||
// 100 Million SRI
|
||||
pub const GENESIS_SRI: u64 = 100_000_000 * 10_u64.pow(8);
|
||||
|
||||
// This is the account which will be the origin for any dispatched `InInstruction`s.
|
||||
pub const GENESIS_LIQUIDITY_ACCOUNT: SeraiAddress = system_address(b"Genesis-liquidity-account");
|
||||
@@ -37,6 +37,7 @@ in-instructions-primitives = { package = "serai-in-instructions-primitives", pat
|
||||
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false }
|
||||
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false }
|
||||
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false }
|
||||
genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../../genesis-liquidity/pallet", default-features = false }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
@@ -58,5 +59,6 @@ std = [
|
||||
"coins-pallet/std",
|
||||
"dex-pallet/std",
|
||||
"validator-sets-pallet/std",
|
||||
"genesis-liquidity-pallet/std",
|
||||
]
|
||||
default = ["std"]
|
||||
|
||||
@@ -33,10 +33,14 @@ pub mod pallet {
|
||||
Config as ValidatorSetsConfig, Pallet as ValidatorSets,
|
||||
};
|
||||
|
||||
use genesis_liquidity_pallet::{Pallet as GenesisLiq, Config as GenesisLiqConfig};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config + CoinsConfig + DexConfig + ValidatorSetsConfig {
|
||||
pub trait Config:
|
||||
frame_system::Config + CoinsConfig + DexConfig + ValidatorSetsConfig + GenesisLiqConfig
|
||||
{
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||
}
|
||||
|
||||
@@ -200,6 +204,14 @@ pub mod pallet {
|
||||
}
|
||||
}
|
||||
}
|
||||
InInstruction::GenesisLiquidity(ops) => match ops {
|
||||
GenesisLiquidityOperation::Add(address, balance) => {
|
||||
GenesisLiq::<T>::add_coin_liquidity(address.into(), balance)?;
|
||||
}
|
||||
GenesisLiquidityOperation::Remove(address, balance, out_address) => {
|
||||
GenesisLiq::<T>::remove_coin_liquidity(address.into(), balance, out_address)?;
|
||||
}
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -71,6 +71,15 @@ pub enum DexCall {
|
||||
Swap(Balance, OutAddress),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||
#[cfg_attr(feature = "std", derive(Zeroize))]
|
||||
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum GenesisLiquidityOperation {
|
||||
Add(SeraiAddress, Balance),
|
||||
Remove(SeraiAddress, Balance, ExternalAddress),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||
#[cfg_attr(feature = "std", derive(Zeroize))]
|
||||
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||
@@ -78,6 +87,7 @@ pub enum DexCall {
|
||||
pub enum InInstruction {
|
||||
Transfer(SeraiAddress),
|
||||
Dex(DexCall),
|
||||
GenesisLiquidity(GenesisLiquidityOperation),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug)]
|
||||
|
||||
@@ -59,6 +59,7 @@ coins-pallet = { package = "serai-coins-pallet", path = "../coins/pallet", defau
|
||||
dex-pallet = { package = "serai-dex-pallet", path = "../dex/pallet", default-features = false }
|
||||
|
||||
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets/pallet", default-features = false }
|
||||
genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../genesis-liquidity/pallet", default-features = false }
|
||||
|
||||
in-instructions-pallet = { package = "serai-in-instructions-pallet", path = "../in-instructions/pallet", default-features = false }
|
||||
|
||||
@@ -112,6 +113,7 @@ std = [
|
||||
"dex-pallet/std",
|
||||
|
||||
"validator-sets-pallet/std",
|
||||
"genesis-liquidity-pallet/std",
|
||||
|
||||
"in-instructions-pallet/std",
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ pub use signals_pallet as signals;
|
||||
pub use pallet_babe as babe;
|
||||
pub use pallet_grandpa as grandpa;
|
||||
|
||||
pub use genesis_liquidity_pallet as genesis_liquidity;
|
||||
|
||||
// Actually used by the runtime
|
||||
use sp_core::OpaqueMetadata;
|
||||
use sp_std::prelude::*;
|
||||
@@ -288,6 +290,10 @@ impl in_instructions::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
}
|
||||
|
||||
impl genesis_liquidity::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
}
|
||||
|
||||
// for publishing equivocation evidences.
|
||||
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
|
||||
where
|
||||
@@ -362,6 +368,7 @@ construct_runtime!(
|
||||
Coins: coins,
|
||||
LiquidityTokens: coins::<Instance1>::{Pallet, Call, Storage, Event<T>},
|
||||
Dex: dex,
|
||||
GenesisLiquidity: genesis_liquidity,
|
||||
|
||||
ValidatorSets: validator_sets,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user