Add Dex pallet (#407)

* Move pallet-asset-conversion

* update licensing

* initial integration

* Integrate Currency & Assets types

* integrate liquidity tokens

* fmt

* integrate dex pallet tests

* fmt

* compilation error fixes

* integrate dex benchmarks

* fmt

* cargo clippy

* replace all occurrences of "asset" with "coin"

* add the actual add liq/swap logic to in-instructions

* add client side & tests

* fix deny

* Lint and changes

- Renames InInstruction::AddLiquidity to InInstruction::SwapAndAddLiquidity
- Makes create_pool an internal function
- Makes dex-pallet exclusively create pools against a native coin
- Removes various fees
- Adds new crates to GH workflow

* Fix rebase artifacts

* Correct other rebase artifact

* Correct CI specification for liquidity-tokens

* Correct primitives' test to the standardized pallet account scheme

---------

Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This commit is contained in:
akildemir
2023-11-05 20:02:34 +03:00
committed by GitHub
parent facb5817c4
commit 899a9604e1
38 changed files with 5327 additions and 27 deletions

View File

@@ -0,0 +1,71 @@
use sp_core::bounded_vec::BoundedVec;
use serai_runtime::{
primitives::{SeraiAddress, Amount, Coin},
dex, Dex, Runtime,
};
use subxt::tx::Payload;
use crate::{SeraiError, Composite, TemporalSerai, scale_composite};
const PALLET: &str = "Dex";
pub type DexEvent = dex::Event<Runtime>;
#[derive(Clone, Copy)]
pub struct SeraiDex<'a>(pub(crate) TemporalSerai<'a>);
impl<'a> SeraiDex<'a> {
pub async fn all_events(&self) -> Result<Vec<DexEvent>, SeraiError> {
self.0.events::<Dex, _>(|_| true).await
}
pub fn add_liquidity(
coin: Coin,
coin_amount: Amount,
sri_amount: Amount,
min_coin_amount: Amount,
min_sri_amount: Amount,
address: SeraiAddress,
) -> Payload<Composite<()>> {
Payload::new(
PALLET,
"add_liquidity",
scale_composite(dex::Call::<Runtime>::add_liquidity {
coin1: coin,
coin2: Coin::Serai,
amount1_desired: coin_amount.0,
amount2_desired: sri_amount.0,
amount1_min: min_coin_amount.0,
amount2_min: min_sri_amount.0,
mint_to: address.into(),
}),
)
}
pub fn swap(
from_coin: Coin,
to_coin: Coin,
amount_in: Amount,
amount_out_min: Amount,
address: SeraiAddress,
) -> Payload<Composite<()>> {
let path = if to_coin.is_native() {
BoundedVec::try_from(vec![from_coin, Coin::Serai]).unwrap()
} else if from_coin.is_native() {
BoundedVec::try_from(vec![Coin::Serai, to_coin]).unwrap()
} else {
BoundedVec::try_from(vec![from_coin, Coin::Serai, to_coin]).unwrap()
};
Payload::new(
PALLET,
"swap_exact_tokens_for_tokens",
scale_composite(dex::Call::<Runtime>::swap_exact_tokens_for_tokens {
path,
amount_in: amount_in.0,
amount_out_min: amount_out_min.0,
send_to: address.into(),
}),
)
}
}

View File

@@ -35,6 +35,8 @@ use serai_runtime::{
pub mod coins;
pub use coins::SeraiCoins;
pub mod dex;
pub use dex::SeraiDex;
pub mod in_instructions;
pub use in_instructions::SeraiInInstructions;
pub mod validator_sets;
@@ -347,6 +349,10 @@ impl<'a> TemporalSerai<'a> {
SeraiCoins(self)
}
pub fn dex(self) -> SeraiDex<'a> {
SeraiDex(self)
}
pub fn in_instructions(self) -> SeraiInInstructions<'a> {
SeraiInInstructions(self)
}