Skip to content

Commit

Permalink
Implement genesis liquidity protocol (#545)
Browse files Browse the repository at this point in the history
* add genesis liquidity implementation

* add missing deposit event

* fix CI issues

* minor fixes

* make math safer

* fix fmt

* make remove liquidity an authorized call

* implement setting initial values for coins

* add genesis liquidity test & misc fixes

* updato develop latest

* fix rotation test

* Finish merging develop

* Remove accidentally committed ETH files

* fix pr comments

* further bug fixes

* fix last pr comments

* tidy up

* Misc

---------

Co-authored-by: Luke Parker <[email protected]>
  • Loading branch information
akildemir and kayabaNerve authored Jul 18, 2024
1 parent 2ccb0cd commit 1493f49
Show file tree
Hide file tree
Showing 28 changed files with 1,287 additions and 43 deletions.
37 changes: 37 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 },
oraclize_values { values: Values, signature: Signature },
}

#[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 },
EconomicSecurityReached { network: NetworkId },
}
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};

#[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::{Values, LiquidityAmount};

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 oraclize_values(values: Values, signature: Signature) -> Transaction {
Serai::unsigned(serai_abi::Call::GenesisLiquidity(
serai_abi::genesis_liquidity::Call::oraclize_values { values, 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<LiquidityAmount, SeraiError> {
Ok(
self
.0
.storage(
PALLET,
"Liquidity",
(coin, sp_core::hashing::blake2_128(&address.encode()), &address.0),
)
.await?
.unwrap_or(LiquidityAmount::zero()),
)
}

pub async fn supply(&self, coin: Coin) -> Result<LiquidityAmount, SeraiError> {
Ok(self.0.storage(PALLET, "Supply", coin).await?.unwrap_or(LiquidityAmount::zero()))
}
}
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

0 comments on commit 1493f49

Please sign in to comment.