Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement genesis liquidity protocol #545

Merged
merged 25 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ exceptions = [
{ allow = ["AGPL-3.0"], name = "serai-coins-pallet" },
{ allow = ["AGPL-3.0"], name = "serai-dex-pallet" },

{ allow = ["AGPL-3.0"], name = "serai-genesis-liquidity-pallet" },

{ allow = ["AGPL-3.0"], name = "serai-in-instructions-pallet" },

{ allow = ["AGPL-3.0"], name = "serai-validator-sets-pallet" },
Expand Down
4 changes: 4 additions & 0 deletions substrate/abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ frame-support = { git = "https://github.com/serai-dex/substrate", default-featur
serai-primitives = { path = "../primitives", version = "0.1", default-features = false }
serai-coins-primitives = { path = "../coins/primitives", version = "0.1", default-features = false }
serai-validator-sets-primitives = { path = "../validator-sets/primitives", version = "0.1", default-features = false }
serai-genesis-liquidity-primitives = { path = "../genesis-liquidity/primitives", version = "0.1", default-features = false }
serai-in-instructions-primitives = { path = "../in-instructions/primitives", version = "0.1", default-features = false }
serai-signals-primitives = { path = "../signals/primitives", version = "0.1", default-features = false }

Expand All @@ -55,6 +56,7 @@ std = [
"serai-primitives/std",
"serai-coins-primitives/std",
"serai-validator-sets-primitives/std",
"serai-genesis-liquidity-primitives/std",
"serai-in-instructions-primitives/std",
"serai-signals-primitives/std",
]
Expand All @@ -63,6 +65,7 @@ borsh = [
"serai-primitives/borsh",
"serai-coins-primitives/borsh",
"serai-validator-sets-primitives/borsh",
"serai-genesis-liquidity-primitives/borsh",
"serai-in-instructions-primitives/borsh",
"serai-signals-primitives/borsh",
]
Expand All @@ -71,6 +74,7 @@ serde = [
"serai-primitives/serde",
"serai-coins-primitives/serde",
"serai-validator-sets-primitives/serde",
"serai-genesis-liquidity-primitives/serde",
"serai-in-instructions-primitives/serde",
"serai-signals-primitives/serde",
]
Expand Down
9 changes: 0 additions & 9 deletions substrate/abi/src/coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@ pub enum Call {
burn_with_instruction { instruction: OutInstructionWithBalance },
}

#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(all(feature = "std", feature = "serde"), derive(serde::Deserialize))]
pub enum LiquidityTokensCall {
transfer { to: SeraiAddress, balance: Balance },
burn { balance: Balance },
}

#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
Expand Down
21 changes: 21 additions & 0 deletions substrate/abi/src/genesis_liquidity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
pub use serai_genesis_liquidity_primitives as primitives;

use serai_primitives::*;
use primitives::*;

#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Call {
remove_coin_liquidity { balance: Balance },
set_initial_price { prices: Prices, signature: Signature },
akildemir marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Event {
GenesisLiquidityAdded { by: SeraiAddress, balance: Balance },
GenesisLiquidityRemoved { by: SeraiAddress, balance: Balance },
GenesisLiquidityAddedToPool { coin1: Balance, coin2: Balance },
akildemir marked this conversation as resolved.
Show resolved Hide resolved
EconomicSecurityReached { network: NetworkId },
akildemir marked this conversation as resolved.
Show resolved Hide resolved
}
9 changes: 7 additions & 2 deletions substrate/abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ pub mod system;
pub mod timestamp;

pub mod coins;
pub mod liquidity_tokens;
pub mod dex;

pub mod validator_sets;
pub mod in_instructions;
pub mod signals;

pub mod genesis_liquidity;

pub mod babe;
pub mod grandpa;

Expand All @@ -27,8 +30,9 @@ pub mod tx;
pub enum Call {
Timestamp(timestamp::Call),
Coins(coins::Call),
LiquidityTokens(coins::LiquidityTokensCall),
LiquidityTokens(liquidity_tokens::Call),
Dex(dex::Call),
GenesisLiquidity(genesis_liquidity::Call),
ValidatorSets(validator_sets::Call),
InInstructions(in_instructions::Call),
Signals(signals::Call),
Expand All @@ -48,8 +52,9 @@ pub enum Event {
Timestamp,
TransactionPayment(TransactionPaymentEvent),
Coins(coins::Event),
LiquidityTokens(coins::Event),
LiquidityTokens(liquidity_tokens::Event),
Dex(dex::Event),
GenesisLiquidity(genesis_liquidity::Event),
ValidatorSets(validator_sets::Event),
InInstructions(in_instructions::Event),
Signals(signals::Event),
Expand Down
18 changes: 18 additions & 0 deletions substrate/abi/src/liquidity_tokens.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use serai_primitives::{Balance, SeraiAddress};
akildemir marked this conversation as resolved.
Show resolved Hide resolved

#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Call {
burn { balance: Balance },
transfer { to: SeraiAddress, balance: Balance },
}

#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Event {
Mint { to: SeraiAddress, balance: Balance },
Burn { from: SeraiAddress, balance: Balance },
Transfer { from: SeraiAddress, to: SeraiAddress, balance: Balance },
}
20 changes: 19 additions & 1 deletion substrate/client/src/serai/dex.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use sp_core::bounded_vec::BoundedVec;
use serai_abi::primitives::{SeraiAddress, Amount, Coin};

use crate::{SeraiError, TemporalSerai};
use scale::{decode_from_bytes, Encode};

use crate::{Serai, SeraiError, TemporalSerai};

pub type DexEvent = serai_abi::dex::Event;

Expand Down Expand Up @@ -57,4 +59,20 @@ impl<'a> SeraiDex<'a> {
send_to: address,
})
}

/// Returns the reserves of `coin:SRI` pool.
pub async fn get_reserves(&self, coin: Coin) -> Result<Option<(Amount, Amount)>, SeraiError> {
let reserves = self
.0
.serai
.call(
"state_call",
["DexApi_get_reserves".to_string(), hex::encode((coin, Coin::Serai).encode())],
)
.await?;
let bytes = Serai::hex_decode(reserves)?;
let result = decode_from_bytes::<Option<(u64, u64)>>(bytes.into())
.map_err(|e| SeraiError::ErrorInResponse(e.to_string()))?;
Ok(result.map(|amounts| (Amount(amounts.0), Amount(amounts.1))))
}
}
65 changes: 65 additions & 0 deletions substrate/client/src/serai/genesis_liquidity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
pub use serai_abi::genesis_liquidity::primitives;
use primitives::Prices;

use serai_abi::primitives::*;

use sp_core::sr25519::Signature;

use scale::Encode;

use crate::{Serai, SeraiError, TemporalSerai, Transaction};

pub type GenesisLiquidityEvent = serai_abi::genesis_liquidity::Event;

const PALLET: &str = "GenesisLiquidity";

#[derive(Clone, Copy)]
pub struct SeraiGenesisLiquidity<'a>(pub(crate) &'a TemporalSerai<'a>);
impl<'a> SeraiGenesisLiquidity<'a> {
pub async fn events(&self) -> Result<Vec<GenesisLiquidityEvent>, SeraiError> {
self
.0
.events(|event| {
if let serai_abi::Event::GenesisLiquidity(event) = event {
Some(event.clone())
} else {
None
}
})
.await
}

pub fn set_initial_price(prices: Prices, signature: Signature) -> Transaction {
Serai::unsigned(serai_abi::Call::GenesisLiquidity(
serai_abi::genesis_liquidity::Call::set_initial_price { prices, signature },
))
}

pub fn remove_coin_liquidity(balance: Balance) -> serai_abi::Call {
serai_abi::Call::GenesisLiquidity(serai_abi::genesis_liquidity::Call::remove_coin_liquidity {
balance,
})
}

pub async fn liquidity(
&self,
address: &SeraiAddress,
coin: Coin,
) -> Result<(Amount, Amount), SeraiError> {
Ok(
self
.0
.storage(
PALLET,
"Liquidity",
(coin, sp_core::hashing::blake2_128(&address.encode()), &address.0),
)
.await?
.unwrap_or((Amount(0), Amount(0))),
)
}

pub async fn supply(&self, coin: Coin) -> Result<(Amount, Amount), SeraiError> {
Ok(self.0.storage(PALLET, "Supply", coin).await?.unwrap_or((Amount(0), Amount(0))))
}
}
41 changes: 41 additions & 0 deletions substrate/client/src/serai/liquidity_tokens.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use scale::Encode;

use serai_abi::primitives::{SeraiAddress, Amount, Coin, Balance};

use crate::{TemporalSerai, SeraiError};

const PALLET: &str = "LiquidityTokens";

#[derive(Clone, Copy)]
pub struct SeraiLiquidityTokens<'a>(pub(crate) &'a TemporalSerai<'a>);
impl<'a> SeraiLiquidityTokens<'a> {
pub async fn token_supply(&self, coin: Coin) -> Result<Amount, SeraiError> {
Ok(self.0.storage(PALLET, "Supply", coin).await?.unwrap_or(Amount(0)))
}

pub async fn token_balance(
&self,
coin: Coin,
address: SeraiAddress,
) -> Result<Amount, SeraiError> {
Ok(
self
.0
.storage(
PALLET,
"Balances",
(sp_core::hashing::blake2_128(&address.encode()), &address.0, coin),
)
.await?
.unwrap_or(Amount(0)),
)
}

pub fn transfer(to: SeraiAddress, balance: Balance) -> serai_abi::Call {
serai_abi::Call::LiquidityTokens(serai_abi::liquidity_tokens::Call::transfer { to, balance })
}

pub fn burn(balance: Balance) -> serai_abi::Call {
serai_abi::Call::LiquidityTokens(serai_abi::liquidity_tokens::Call::burn { balance })
}
}
13 changes: 13 additions & 0 deletions substrate/client/src/serai/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ pub mod in_instructions;
pub use in_instructions::SeraiInInstructions;
pub mod validator_sets;
pub use validator_sets::SeraiValidatorSets;
pub mod genesis_liquidity;
pub use genesis_liquidity::SeraiGenesisLiquidity;
pub mod liquidity_tokens;
pub use liquidity_tokens::SeraiLiquidityTokens;

#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode)]
pub struct Block {
Expand Down Expand Up @@ -194,6 +198,7 @@ impl Serai {
Ok(())
}

// TODO: move this into substrate/client/src/validator_sets.rs
async fn active_network_validators(&self, network: NetworkId) -> Result<Vec<Public>, SeraiError> {
let validators: String = self
.call("state_call", ["SeraiRuntimeApi_validators".to_string(), hex::encode(network.encode())])
Expand Down Expand Up @@ -388,4 +393,12 @@ impl<'a> TemporalSerai<'a> {
pub fn validator_sets(&'a self) -> SeraiValidatorSets<'a> {
SeraiValidatorSets(self)
}

pub fn genesis_liquidity(&'a self) -> SeraiGenesisLiquidity {
SeraiGenesisLiquidity(self)
}

pub fn liquidity_tokens(&'a self) -> SeraiLiquidityTokens {
SeraiLiquidityTokens(self)
}
}
Loading
Loading