mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Implement block emissions (#551)
* add genesis liquidity implementation * add missing deposit event * fix CI issues * minor fixes * make math safer * fix fmt * implement block emissions * make remove liquidity an authorized call * implement setting initial values for coins * add genesis liquidity test & misc fixes * updato develop latest * fix rotation test * fix licencing * add fast-epoch feature * only create the pool when adding liquidity first time * add initial reward era test * test whole pre ec security emissions * fix clippy * add swap-to-staked-sri feature * rebase changes * fix tests * Remove accidentally commited ETH ABI files * fix some pr comments * Finish up fixing pr comments * exclude SRI from is_allowed check * Misc changes --------- Co-authored-by: akildemir <aeg_asd@hotmail.com> Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This commit is contained in:
@@ -194,6 +194,11 @@ pub mod pallet {
|
||||
#[pallet::getter(fn security_oracle_value)]
|
||||
pub type SecurityOracleValue<T: Config> = StorageMap<_, Identity, Coin, Amount, OptionQuery>;
|
||||
|
||||
/// Total swap volume of a given pool in terms of SRI.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn swap_volume)]
|
||||
pub type SwapVolume<T: Config> = StorageMap<_, Identity, PoolId, u64, OptionQuery>;
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
fn restore_median(
|
||||
coin: Coin,
|
||||
@@ -373,31 +378,6 @@ pub mod pallet {
|
||||
},
|
||||
}
|
||||
|
||||
#[pallet::genesis_config]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)]
|
||||
pub struct GenesisConfig<T: Config> {
|
||||
/// Pools to create at launch.
|
||||
pub pools: Vec<Coin>,
|
||||
/// field just to have T.
|
||||
pub _ignore: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Config> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig { pools: Default::default(), _ignore: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::genesis_build]
|
||||
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
|
||||
fn build(&self) {
|
||||
// create the pools
|
||||
for coin in &self.pools {
|
||||
Pallet::<T>::create_pool(*coin).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
/// Provided coins are equal.
|
||||
@@ -510,19 +490,15 @@ pub mod pallet {
|
||||
///
|
||||
/// Once a pool is created, someone may [`Pallet::add_liquidity`] to it.
|
||||
pub(crate) fn create_pool(coin: Coin) -> DispatchResult {
|
||||
ensure!(coin != Coin::Serai, Error::<T>::EqualCoins);
|
||||
|
||||
// prepare pool_id
|
||||
let pool_id = Self::get_pool_id(coin, Coin::Serai).unwrap();
|
||||
// get pool_id
|
||||
let pool_id = Self::get_pool_id(coin, Coin::Serai)?;
|
||||
ensure!(!Pools::<T>::contains_key(pool_id), Error::<T>::PoolExists);
|
||||
|
||||
let pool_account = Self::get_pool_account(pool_id);
|
||||
frame_system::Pallet::<T>::inc_providers(&pool_account);
|
||||
|
||||
Pools::<T>::insert(pool_id, ());
|
||||
|
||||
Self::deposit_event(Event::PoolCreated { pool_id, pool_account });
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -561,11 +537,14 @@ pub mod pallet {
|
||||
) -> DispatchResult {
|
||||
let sender = ensure_signed(origin)?;
|
||||
ensure!((sri_desired > 0) && (coin_desired > 0), Error::<T>::WrongDesiredAmount);
|
||||
ensure!(coin != Coin::Serai, Error::<T>::EqualCoins);
|
||||
|
||||
let pool_id = Self::get_pool_id(coin, Coin::Serai).unwrap();
|
||||
let pool_id = Self::get_pool_id(coin, Coin::Serai)?;
|
||||
|
||||
Pools::<T>::get(pool_id).as_ref().ok_or(Error::<T>::PoolNotFound)?;
|
||||
// create the pool if it doesn't exist. We can just attempt to do that because our checks
|
||||
// far enough to allow that.
|
||||
if Pools::<T>::get(pool_id).is_none() {
|
||||
Self::create_pool(coin)?;
|
||||
}
|
||||
let pool_account = Self::get_pool_account(pool_id);
|
||||
|
||||
let sri_reserve = Self::get_balance(&pool_account, Coin::Serai);
|
||||
@@ -887,9 +866,20 @@ pub mod pallet {
|
||||
&to,
|
||||
Balance { coin: *coin2, amount: Amount(*amount_out) },
|
||||
)?;
|
||||
|
||||
// update the volume
|
||||
let swap_volume = if *coin1 == Coin::Serai {
|
||||
amounts.get(i as usize).ok_or(Error::<T>::CorrespondenceError)?
|
||||
} else {
|
||||
amount_out
|
||||
};
|
||||
let existing = SwapVolume::<T>::get(pool_id).unwrap_or(0);
|
||||
let new_volume = existing.saturating_add(*swap_volume);
|
||||
SwapVolume::<T>::set(pool_id, Some(new_volume));
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Self::deposit_event(Event::SwapExecuted {
|
||||
who: sender,
|
||||
send_to,
|
||||
|
||||
@@ -1155,16 +1155,8 @@ fn can_not_swap_same_coin() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let user = system_address(b"user1").into();
|
||||
let coin1 = Coin::Dai;
|
||||
|
||||
assert_ok!(CoinsPallet::<Test>::mint(user, Balance { coin: coin1, amount: Amount(1000) }));
|
||||
|
||||
let liquidity1 = 1000;
|
||||
let liquidity2 = 20;
|
||||
assert_noop!(
|
||||
Dex::add_liquidity(RuntimeOrigin::signed(user), coin1, liquidity2, liquidity1, 1, 1, user,),
|
||||
Error::<Test>::PoolNotFound
|
||||
);
|
||||
|
||||
let exchange_amount = 10;
|
||||
assert_noop!(
|
||||
Dex::swap_exact_tokens_for_tokens(
|
||||
|
||||
Reference in New Issue
Block a user