diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0a71d480b..8e0e7e3ee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -63,7 +63,6 @@ jobs: -p serai-primitives \ -p serai-coins-primitives \ -p serai-coins-pallet \ - -p serai-dex-primitives \ -p serai-dex-pallet \ -p serai-validator-sets-primitives \ -p serai-validator-sets-pallet \ diff --git a/Cargo.lock b/Cargo.lock index d1ace4872..497cdd0b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8269,7 +8269,6 @@ dependencies = [ "parity-scale-codec", "scale-info", "serai-coins-pallet", - "serai-dex-primitives", "serai-primitives", "sp-api", "sp-arithmetic", @@ -8279,17 +8278,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "serai-dex-primitives" -version = "0.1.0" -dependencies = [ - "frame-benchmarking", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-std", -] - [[package]] name = "serai-docker-tests" version = "0.1.0" @@ -8577,7 +8565,6 @@ dependencies = [ "scale-info", "serai-coins-pallet", "serai-dex-pallet", - "serai-dex-primitives", "serai-in-instructions-pallet", "serai-primitives", "serai-signals-pallet", diff --git a/coordinator/src/substrate/mod.rs b/coordinator/src/substrate/mod.rs index 6f314d915..78bdfd26c 100644 --- a/coordinator/src/substrate/mod.rs +++ b/coordinator/src/substrate/mod.rs @@ -208,8 +208,8 @@ async fn handle_batch_and_burns( } } - for burn in serai.coins().burn_events().await? { - if let CoinsEvent::Burn { from: _, instruction } = burn { + for burn in serai.coins().burn_with_instruction_events().await? { + if let CoinsEvent::BurnWithInstruction { from: _, instruction } = burn { let network = instruction.balance.coin.network(); network_had_event(&mut burns, &mut batches, network); diff --git a/deny.toml b/deny.toml index 67d1f64bd..72ffdf033 100644 --- a/deny.toml +++ b/deny.toml @@ -54,7 +54,6 @@ exceptions = [ { allow = ["AGPL-3.0"], name = "serai-coordinator" }, { allow = ["AGPL-3.0"], name = "serai-coins-pallet" }, - { allow = ["AGPL-3.0"], name = "serai-dex-primitives" }, { allow = ["AGPL-3.0"], name = "serai-dex-pallet" }, { allow = ["AGPL-3.0"], name = "serai-in-instructions-pallet" }, diff --git a/substrate/client/src/serai/coins.rs b/substrate/client/src/serai/coins.rs index b197aedd2..b73f0e7d9 100644 --- a/substrate/client/src/serai/coins.rs +++ b/substrate/client/src/serai/coins.rs @@ -24,8 +24,8 @@ impl<'a> SeraiCoins<'a> { self.0.events::(|event| matches!(event, CoinsEvent::Mint { .. })).await } - pub async fn burn_events(&self) -> Result, SeraiError> { - self.0.events::(|event| matches!(event, CoinsEvent::Burn { .. })).await + pub async fn burn_with_instruction_events(&self) -> Result, SeraiError> { + self.0.events::(|event| matches!(event, CoinsEvent::BurnWithInstruction { .. })).await } pub async fn coin_supply(&self, coin: Coin) -> Result { @@ -64,7 +64,15 @@ impl<'a> SeraiCoins<'a> { ) } - pub fn burn(instruction: OutInstructionWithBalance) -> Payload> { - Payload::new(PALLET, "burn", scale_composite(coins::Call::::burn { instruction })) + pub fn burn(balance: Balance) -> Payload> { + Payload::new(PALLET, "burn", scale_composite(coins::Call::::burn { balance })) + } + + pub fn burn_with_instruction(instruction: OutInstructionWithBalance) -> Payload> { + Payload::new( + PALLET, + "burn_with_instruction", + scale_composite(coins::Call::::burn_with_instruction { instruction }), + ) } } diff --git a/substrate/client/tests/burn.rs b/substrate/client/tests/burn.rs index cfdf943a3..456dc131d 100644 --- a/substrate/client/tests/burn.rs +++ b/substrate/client/tests/burn.rs @@ -93,7 +93,7 @@ serai_test!( &serai .sign( &PairSigner::new(pair), - &SeraiCoins::burn(instruction.clone()), + &SeraiCoins::burn_with_instruction(instruction.clone()), 0, BaseExtrinsicParamsBuilder::new(), ) @@ -102,8 +102,8 @@ serai_test!( .await; let serai = serai.as_of(block).coins(); - let events = serai.burn_events().await.unwrap(); - assert_eq!(events, vec![CoinsEvent::Burn { from: address.into(), instruction }]); + let events = serai.burn_with_instruction_events().await.unwrap(); + assert_eq!(events, vec![CoinsEvent::BurnWithInstruction { from: address.into(), instruction }]); assert_eq!(serai.coin_supply(coin).await.unwrap(), Amount(0)); assert_eq!(serai.coin_balance(coin, address).await.unwrap(), Amount(0)); }) diff --git a/substrate/coins/pallet/src/lib.rs b/substrate/coins/pallet/src/lib.rs index b0a454588..42fca5b35 100644 --- a/substrate/coins/pallet/src/lib.rs +++ b/substrate/coins/pallet/src/lib.rs @@ -2,7 +2,7 @@ #[frame_support::pallet] pub mod pallet { - use sp_std::vec::Vec; + use sp_std::{vec::Vec, any::TypeId}; use sp_core::sr25519::Public; use sp_runtime::{ traits::{DispatchInfoOf, PostDispatchInfoOf}, @@ -18,6 +18,8 @@ pub mod pallet { pub use coins_primitives as primitives; use primitives::*; + type LiquidityTokensInstance = crate::Instance1; + #[pallet::config] pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -27,12 +29,12 @@ pub mod pallet { #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] pub struct GenesisConfig, I: 'static = ()> { pub accounts: Vec<(T::AccountId, Balance)>, - pub ignore: PhantomData, // TODO: just to own I. + pub _ignore: PhantomData, } impl, I: 'static> Default for GenesisConfig { fn default() -> Self { - GenesisConfig { accounts: Default::default(), ignore: Default::default() } + GenesisConfig { accounts: Default::default(), _ignore: Default::default() } } } @@ -47,8 +49,8 @@ pub mod pallet { #[pallet::generate_deposit(fn deposit_event)] pub enum Event, I: 'static = ()> { Mint { to: Public, balance: Balance }, - Burn { from: Public, instruction: OutInstructionWithBalance }, - SriBurn { from: Public, amount: Amount }, + Burn { from: Public, balance: Balance }, + BurnWithInstruction { from: Public, instruction: OutInstructionWithBalance }, Transfer { from: Public, to: Public, balance: Balance }, } @@ -95,7 +97,7 @@ pub mod pallet { // we can unwrap, we are not burning more then what we have // If this errors, it'll halt the runtime however (due to being called at the start of every // block), requiring extra care when reviewing - Self::burn_sri(FEE_ACCOUNT.into(), amount).unwrap(); + Self::burn_internal(FEE_ACCOUNT.into(), Balance { coin, amount }).unwrap(); Weight::zero() // TODO } } @@ -153,8 +155,8 @@ pub mod pallet { Ok(()) } - // Burn `balance` from the specified account. - pub fn burn_internal(from: Public, balance: Balance) -> Result<(), Error> { + /// Burn `balance` from the specified account. + fn burn_internal(from: Public, balance: Balance) -> Result<(), Error> { // don't waste time if amount == 0 if balance.amount.0 == 0 { return Ok(()); @@ -170,24 +172,6 @@ pub mod pallet { Ok(()) } - pub fn burn_sri(from: Public, amount: Amount) -> Result<(), Error> { - Self::burn_internal(from, Balance { coin: Coin::Serai, amount })?; - Self::deposit_event(Event::SriBurn { from, amount }); - Ok(()) - } - - pub fn burn_non_sri( - from: Public, - instruction: OutInstructionWithBalance, - ) -> Result<(), Error> { - if instruction.balance.coin == Coin::Serai { - Err(Error::::SriBurnNotAllowed)?; - } - Self::burn_internal(from, instruction.balance)?; - Self::deposit_event(Event::Burn { from, instruction }); - Ok(()) - } - /// Transfer `balance` from `from` to `to`. pub fn transfer_internal( from: Public, @@ -200,12 +184,6 @@ pub mod pallet { Self::deposit_event(Event::Transfer { from, to, balance }); Ok(()) } - - pub fn minimum_balance(_coin: Coin) -> Amount { - // TODO: use precision here to determine the min amount? - // TODO: this should also match with dex Config MintMinLiquidity type. - Amount(1) - } } #[pallet::call] @@ -218,11 +196,34 @@ pub mod pallet { Ok(()) } + /// Burn `balance` from the caller. #[pallet::call_index(1)] #[pallet::weight((0, DispatchClass::Normal))] // TODO - pub fn burn(origin: OriginFor, instruction: OutInstructionWithBalance) -> DispatchResult { + pub fn burn(origin: OriginFor, balance: Balance) -> DispatchResult { + let from = ensure_signed(origin)?; + Self::burn_internal(from, balance)?; + Self::deposit_event(Event::Burn { from, balance }); + Ok(()) + } + + /// Burn `balance` with `OutInstructionWithBalance` from the caller. + /// Errors if called for SRI or Instance1 instance of this pallet. + #[pallet::call_index(2)] + #[pallet::weight((0, DispatchClass::Normal))] // TODO + pub fn burn_with_instruction( + origin: OriginFor, + instruction: OutInstructionWithBalance, + ) -> DispatchResult { + if instruction.balance.coin == Coin::Serai { + Err(Error::::SriBurnNotAllowed)?; + } + if TypeId::of::() == TypeId::of::() { + Err(Error::::SriBurnNotAllowed)?; + } + let from = ensure_signed(origin)?; - Self::burn_non_sri(from, instruction)?; + Self::burn_internal(from, instruction.balance)?; + Self::deposit_event(Event::BurnWithInstruction { from, instruction }); Ok(()) } } diff --git a/substrate/dex/pallet/Cargo.toml b/substrate/dex/pallet/Cargo.toml index 0fe8cb48b..2dcd461c4 100644 --- a/substrate/dex/pallet/Cargo.toml +++ b/substrate/dex/pallet/Cargo.toml @@ -28,7 +28,6 @@ frame-benchmarking = { git = "https://github.com/serai-dex/substrate", default-f coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false } -dex-primitives = { package = "serai-dex-primitives", path = "../primitives", default-features = false } serai-primitives = { path = "../../primitives", default-features = false } [features] @@ -46,8 +45,6 @@ std = [ "serai-primitives/std", - "dex-primitives/std", - "frame-system/std", "frame-support/std", "frame-benchmarking?/std", @@ -60,8 +57,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", - - "dex-primitives/runtime-benchmarks", ] try-runtime = [ "sp-runtime/try-runtime", diff --git a/substrate/dex/pallet/src/benchmarking.rs b/substrate/dex/pallet/src/benchmarking.rs index adc2f3d26..4fe301f61 100644 --- a/substrate/dex/pallet/src/benchmarking.rs +++ b/substrate/dex/pallet/src/benchmarking.rs @@ -53,24 +53,20 @@ fn create_coin(coin: &Coin) -> (T::AccountId, AccountIdLookupOf) { } fn create_coin_and_pool( - coin1: &Coin, - coin2: &Coin, + coin: &Coin, ) -> (PoolCoinId, T::AccountId, AccountIdLookupOf) { - assert_eq!(*coin1, Coin::native()); + let (caller, caller_lookup) = create_coin::(coin); + assert_ok!(Dex::::create_pool(*coin)); - let (caller, caller_lookup) = create_coin::(coin2); - assert_ok!(Dex::::create_pool(*coin2)); - - (*coin2, caller, caller_lookup) + (*coin, caller, caller_lookup) } benchmarks! { add_liquidity { let coin1 = Coin::native(); let coin2 = Coin::Bitcoin; - let (lp_token, caller, _) = create_coin_and_pool::(&coin1, &coin2); - let ed: u64 = Coins::::minimum_balance(coin1).0; - let add_amount: u64 = 1000 + ed; + let (lp_token, caller, _) = create_coin_and_pool::(&coin2); + let add_amount: u64 = 1000; }: _( SystemOrigin::Signed(caller), coin2, @@ -106,9 +102,8 @@ benchmarks! { remove_liquidity { let coin1 = Coin::native(); let coin2 = Coin::Monero; - let (lp_token, caller, _) = create_coin_and_pool::(&coin1, &coin2); - let ed: u64 = Coins::::minimum_balance(coin1).0; - let add_amount: u64 = 100 * ed; + let (lp_token, caller, _) = create_coin_and_pool::(&coin2); + let add_amount: u64 = 100; let lp_minted = Dex::::calc_lp_amount_for_zero_supply( add_amount, 1000u64 @@ -145,18 +140,16 @@ benchmarks! { let native = Coin::native(); let coin1 = Coin::Bitcoin; let coin2 = Coin::Ether; - let (_, caller, _) = create_coin_and_pool::(&native, &coin1); + let (_, caller, _) = create_coin_and_pool::(&coin1); let (_, _) = create_coin::(&coin2); - let ed: u64 = Coins::::minimum_balance(native).0; - let ed_bump = 2u64; Dex::::add_liquidity( SystemOrigin::Signed(caller).into(), coin1, 200u64, - // TODO: this call otherwise fails with `InsufficientLiquidityMinted`. - // might be again related to their expectance on ed being > 1. - 100 * (ed + ed_bump), + // TODO: this call otherwise fails with `InsufficientLiquidityMinted` if we don't multiply + // with 3. Might be again related to their expectance on ed being > 1. + 100 * 3, 0u64, 0u64, caller, @@ -171,7 +164,7 @@ benchmarks! { SystemOrigin::Signed(caller).into(), coin2, 1000u64, - 500 * ed, + 500, 0u64, 0u64, caller, @@ -192,15 +185,14 @@ benchmarks! { let native = Coin::native(); let coin1 = Coin::Bitcoin; let coin2 = Coin::Ether; - let (_, caller, _) = create_coin_and_pool::(&native, &coin1); + let (_, caller, _) = create_coin_and_pool::(&coin1); let (_, _) = create_coin::(&coin2); - let ed: u64 = Coins::::minimum_balance(native).0; Dex::::add_liquidity( SystemOrigin::Signed(caller).into(), coin1, 500u64, - 1000 * ed, + 1000, 0u64, 0u64, caller, @@ -213,7 +205,7 @@ benchmarks! { SystemOrigin::Signed(caller).into(), coin2, 1000u64, - 500 * ed, + 500, 0u64, 0u64, caller, @@ -226,7 +218,7 @@ benchmarks! { SystemOrigin::Signed(caller), path.clone(), 100u64, - 1000 * ed, + 1000, caller ) verify { diff --git a/substrate/dex/pallet/src/lib.rs b/substrate/dex/pallet/src/lib.rs index 4538c8166..b4a525276 100644 --- a/substrate/dex/pallet/src/lib.rs +++ b/substrate/dex/pallet/src/lib.rs @@ -69,6 +69,7 @@ use frame_support::traits::DefensiveOption; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; +mod types; pub mod weights; #[cfg(test)] @@ -79,22 +80,18 @@ mod mock; use frame_support::ensure; use frame_system::{ - ensure_signed, pallet_prelude::{BlockNumberFor, OriginFor}, + ensure_signed, }; pub use pallet::*; -use sp_arithmetic::traits::Unsigned; -use sp_runtime::{ - traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Ensure, TrailingZeroInput}, - DispatchError, -}; +use sp_runtime::{traits::TrailingZeroInput, DispatchError}; use serai_primitives::{Coin, SubstrateAmount}; use sp_std::prelude::*; -use dex_primitives::*; +pub use types::*; pub use weights::WeightInfo; #[frame_support::pallet] @@ -124,6 +121,9 @@ pub mod pallet { /// LiquidityTokens Pallet as an instance of coins pallet. pub type LiquidityTokens = coins_pallet::Pallet; + /// A type used for amount conversions. + pub type HigherPrecisionBalance = u128; + #[pallet::pallet] pub struct Pallet(_); @@ -136,15 +136,6 @@ pub mod pallet { /// Overarching event type. type RuntimeEvent: From> + IsType<::RuntimeEvent>; - /// A type used for conversions between `SubstrateAmount` and `SubstrateAmount`. - type HigherPrecisionBalance: IntegerSquareRoot - + One - + Ensure - + Unsigned - + From - + From - + TryInto; - /// A % the liquidity providers will take of every swap. Represents 10ths of a percent. #[pallet::constant] type LPFee: Get; @@ -232,15 +223,6 @@ pub mod pallet { /// The amount of the second coin that was received. amount_out: SubstrateAmount, }, - /// An amount has been transferred from one account to another. - Transfer { - /// The account that the coins were transferred from. - from: T::AccountId, - /// The account that the coins were transferred to. - to: T::AccountId, - /// The balance that was transferred. - balance: Balance, - }, } #[pallet::genesis_config] @@ -248,13 +230,13 @@ pub mod pallet { pub struct GenesisConfig { /// Pools to create at launch. pub pools: Vec, - /// field just to have T. TODO: better way to own the T than this? - pub ignore: PhantomData, + /// field just to have T. + pub _ignore: PhantomData, } impl Default for GenesisConfig { fn default() -> Self { - GenesisConfig { pools: Default::default(), ignore: Default::default() } + GenesisConfig { pools: Default::default(), _ignore: Default::default() } } } @@ -279,10 +261,10 @@ pub mod pallet { WrongDesiredAmount, /// Provided amount should be greater than or equal to the existential deposit/coin's /// minimal amount. - AmountOneLessThanMinimal, + AmountCoinLessThanMinimal, /// Provided amount should be greater than or equal to the existential deposit/coin's /// minimal amount. - AmountTwoLessThanMinimal, + AmountSriLessThanMinimal, /// Reserve needs to always be greater than or equal to the existential deposit/coin's /// minimal amount. ReserveLeftLessThanMinimal, @@ -422,10 +404,8 @@ pub mod pallet { } } - Self::validate_minimal_amount(sri_amount.saturating_add(sri_reserve), Coin::Serai) - .map_err(|_| Error::::AmountOneLessThanMinimal)?; - Self::validate_minimal_amount(coin_amount.saturating_add(coin_reserve), coin) - .map_err(|_| Error::::AmountTwoLessThanMinimal)?; + ensure!(sri_amount.saturating_add(sri_reserve) >= 1, Error::::AmountSriLessThanMinimal); + ensure!(coin_amount.saturating_add(coin_reserve) >= 1, Error::::AmountCoinLessThanMinimal); Self::transfer( &sender, @@ -482,7 +462,7 @@ pub mod pallet { sri_min_receive: SubstrateAmount, withdraw_to: T::AccountId, ) -> DispatchResult { - let sender = ensure_signed(origin)?; + let sender = ensure_signed(origin.clone())?; ensure!(coin != Coin::Serai, Error::::EqualCoins); let pool_id = Self::get_pool_id(coin, Coin::Serai).unwrap(); @@ -511,14 +491,12 @@ pub mod pallet { ); let sri_reserve_left = sri_reserve.saturating_sub(sri_amount); let coin_reserve_left = coin_reserve.saturating_sub(coin_amount); - Self::validate_minimal_amount(sri_reserve_left, Coin::Serai) - .map_err(|_| Error::::ReserveLeftLessThanMinimal)?; - Self::validate_minimal_amount(coin_reserve_left, coin) - .map_err(|_| Error::::ReserveLeftLessThanMinimal)?; + + ensure!(sri_reserve_left >= 1, Error::::ReserveLeftLessThanMinimal); + ensure!(coin_reserve_left >= 1, Error::::ReserveLeftLessThanMinimal); // burn the provided lp token amount that includes the fee - // TODO: burn lp_token? uhh another burn function? - LiquidityTokens::::burn_internal(sender, Balance { coin, amount: Amount(lp_token_burn) })?; + LiquidityTokens::::burn(origin, Balance { coin, amount: Amount(lp_token_burn) })?; Self::transfer( &pool_account, @@ -667,14 +645,12 @@ pub mod pallet { balance: Balance, ) -> Result { CoinsPallet::::transfer_internal(*from, *to, balance)?; - - Self::deposit_event(Event::Transfer { from: *from, to: *to, balance }); Ok(balance.amount) } /// Convert a `HigherPrecisionBalance` type to an `SubstrateAmount`. pub(crate) fn convert_hpb_to_coin_balance( - amount: T::HigherPrecisionBalance, + amount: HigherPrecisionBalance, ) -> Result> { amount.try_into().map_err(|_| Error::::Overflow) } @@ -718,8 +694,7 @@ pub mod pallet { let reserve = Self::get_balance(&pool_account, *coin2); let reserve_left = reserve.saturating_sub(*amount_out); - Self::validate_minimal_amount(reserve_left, *coin2) - .map_err(|_| Error::::ReserveLeftLessThanMinimal)?; + ensure!(reserve_left >= 1, Error::::ReserveLeftLessThanMinimal); Self::transfer( &pool_account, @@ -890,14 +865,14 @@ pub mod pallet { amount1: SubstrateAmount, amount2: SubstrateAmount, ) -> Result> { - let amount1 = T::HigherPrecisionBalance::from(amount1); - let amount2 = T::HigherPrecisionBalance::from(amount2); + let amount1 = HigherPrecisionBalance::from(amount1); + let amount2 = HigherPrecisionBalance::from(amount2); let result = amount1 - .checked_mul(&amount2) + .checked_mul(amount2) .ok_or(Error::::Overflow)? .integer_sqrt() - .checked_sub(&T::MintMinLiquidity::get().into()) + .checked_sub(T::MintMinLiquidity::get().into()) .ok_or(Error::::InsufficientLiquidityMinted)?; result.try_into().map_err(|_| Error::::Overflow) @@ -908,15 +883,12 @@ pub mod pallet { b: SubstrateAmount, c: SubstrateAmount, ) -> Result> { - let a = T::HigherPrecisionBalance::from(a); - let b = T::HigherPrecisionBalance::from(b); - let c = T::HigherPrecisionBalance::from(c); + let a = HigherPrecisionBalance::from(a); + let b = HigherPrecisionBalance::from(b); + let c = HigherPrecisionBalance::from(c); - let result = a - .checked_mul(&b) - .ok_or(Error::::Overflow)? - .checked_div(&c) - .ok_or(Error::::Overflow)?; + let result = + a.checked_mul(b).ok_or(Error::::Overflow)?.checked_div(c).ok_or(Error::::Overflow)?; result.try_into().map_err(|_| Error::::Overflow) } @@ -930,27 +902,29 @@ pub mod pallet { reserve_in: SubstrateAmount, reserve_out: SubstrateAmount, ) -> Result> { - let amount_in = T::HigherPrecisionBalance::from(amount_in); - let reserve_in = T::HigherPrecisionBalance::from(reserve_in); - let reserve_out = T::HigherPrecisionBalance::from(reserve_out); + let amount_in = HigherPrecisionBalance::from(amount_in); + let reserve_in = HigherPrecisionBalance::from(reserve_in); + let reserve_out = HigherPrecisionBalance::from(reserve_out); if reserve_in.is_zero() || reserve_out.is_zero() { return Err(Error::::ZeroLiquidity); } let amount_in_with_fee = amount_in - .checked_mul(&(T::HigherPrecisionBalance::from(1000u32) - (T::LPFee::get().into()))) + .checked_mul( + HigherPrecisionBalance::from(1000u32) - HigherPrecisionBalance::from(T::LPFee::get()), + ) .ok_or(Error::::Overflow)?; - let numerator = amount_in_with_fee.checked_mul(&reserve_out).ok_or(Error::::Overflow)?; + let numerator = amount_in_with_fee.checked_mul(reserve_out).ok_or(Error::::Overflow)?; let denominator = reserve_in - .checked_mul(&1000u32.into()) + .checked_mul(1000u32.into()) .ok_or(Error::::Overflow)? - .checked_add(&amount_in_with_fee) + .checked_add(amount_in_with_fee) .ok_or(Error::::Overflow)?; - let result = numerator.checked_div(&denominator).ok_or(Error::::Overflow)?; + let result = numerator.checked_div(denominator).ok_or(Error::::Overflow)?; result.try_into().map_err(|_| Error::::Overflow) } @@ -964,9 +938,9 @@ pub mod pallet { reserve_in: SubstrateAmount, reserve_out: SubstrateAmount, ) -> Result> { - let amount_out = T::HigherPrecisionBalance::from(amount_out); - let reserve_in = T::HigherPrecisionBalance::from(reserve_in); - let reserve_out = T::HigherPrecisionBalance::from(reserve_out); + let amount_out = HigherPrecisionBalance::from(amount_out); + let reserve_in = HigherPrecisionBalance::from(reserve_in); + let reserve_out = HigherPrecisionBalance::from(reserve_out); if reserve_in.is_zero() || reserve_out.is_zero() { Err(Error::::ZeroLiquidity)? @@ -977,32 +951,28 @@ pub mod pallet { } let numerator = reserve_in - .checked_mul(&amount_out) + .checked_mul(amount_out) .ok_or(Error::::Overflow)? - .checked_mul(&1000u32.into()) + .checked_mul(1000u32.into()) .ok_or(Error::::Overflow)?; let denominator = reserve_out - .checked_sub(&amount_out) + .checked_sub(amount_out) .ok_or(Error::::Overflow)? - .checked_mul(&(T::HigherPrecisionBalance::from(1000u32) - T::LPFee::get().into())) + .checked_mul( + HigherPrecisionBalance::from(1000u32) - HigherPrecisionBalance::from(T::LPFee::get()), + ) .ok_or(Error::::Overflow)?; let result = numerator - .checked_div(&denominator) + .checked_div(denominator) .ok_or(Error::::Overflow)? - .checked_add(&One::one()) + .checked_add(One::one()) .ok_or(Error::::Overflow)?; result.try_into().map_err(|_| Error::::Overflow) } - /// Ensure that a `value` meets the minimum balance requirements of an `coin` class. - fn validate_minimal_amount(value: SubstrateAmount, coin: Coin) -> Result<(), ()> { - ensure!(value >= CoinsPallet::::minimum_balance(coin).0, ()); - Ok(()) - } - /// Ensure that a path is valid. fn validate_swap_path( path: &BoundedVec, @@ -1025,14 +995,14 @@ pub mod pallet { } } -impl Swap for Pallet { +impl Swap for Pallet { fn swap_exact_tokens_for_tokens( sender: T::AccountId, path: Vec, - amount_in: T::HigherPrecisionBalance, - amount_out_min: Option, + amount_in: HigherPrecisionBalance, + amount_out_min: Option, send_to: T::AccountId, - ) -> Result { + ) -> Result { let path = path.try_into().map_err(|_| Error::::PathError)?; let amount_out_min = amount_out_min.map(Self::convert_hpb_to_coin_balance).transpose()?; let amount_out = Self::do_swap_exact_tokens_for_tokens( @@ -1048,10 +1018,10 @@ impl Swap for Pallet, - amount_out: T::HigherPrecisionBalance, - amount_in_max: Option, + amount_out: HigherPrecisionBalance, + amount_in_max: Option, send_to: T::AccountId, - ) -> Result { + ) -> Result { let path = path.try_into().map_err(|_| Error::::PathError)?; let amount_in_max = amount_in_max.map(Self::convert_hpb_to_coin_balance).transpose()?; let amount_in = Self::do_swap_tokens_for_exact_tokens( diff --git a/substrate/dex/pallet/src/mock.rs b/substrate/dex/pallet/src/mock.rs index 56524a330..9bc302746 100644 --- a/substrate/dex/pallet/src/mock.rs +++ b/substrate/dex/pallet/src/mock.rs @@ -92,8 +92,6 @@ impl Config for Test { type MaxSwapPathLength = ConstU32<4>; // 100 is good enough when the main currency has 12 decimals. type MintMinLiquidity = ConstU64<100>; - - type HigherPrecisionBalance = u128; } pub(crate) fn new_test_ext() -> sp_io::TestExternalities { @@ -110,7 +108,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { .into_iter() .map(|a| (a, Balance { coin: Coin::Serai, amount: Amount(1 << 60) })) .collect(), - ignore: Default::default(), + _ignore: Default::default(), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/dex/pallet/src/tests.rs b/substrate/dex/pallet/src/tests.rs index ac3a69f32..d517f33f4 100644 --- a/substrate/dex/pallet/src/tests.rs +++ b/substrate/dex/pallet/src/tests.rs @@ -60,10 +60,6 @@ fn pool_balance(owner: PublicKey, token_id: Coin) -> u64 { LiquidityTokens::::balance(owner, token_id).0 } -fn get_ed() -> u64 { - CoinsPallet::::minimum_balance(Coin::native()).0 -} - macro_rules! bvec { ($( $x:tt )*) => { vec![$( $x )*].try_into().unwrap() @@ -183,10 +179,9 @@ fn can_add_liquidity() { let lp_token2 = coin3; assert_ok!(Dex::create_pool(coin3)); - let ed = get_ed(); assert_ok!(CoinsPallet::::mint( user, - Balance { coin: coin1, amount: Amount(10000 * 2 + ed) } + Balance { coin: coin1, amount: Amount(10000 * 2 + 1) } )); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin3, amount: Amount(1000) })); @@ -206,7 +201,7 @@ fn can_add_liquidity() { let pallet_account = Dex::get_pool_account(pool_id); assert_eq!(balance(pallet_account, coin1), 10000); assert_eq!(balance(pallet_account, coin2), 10); - assert_eq!(balance(user, coin1), 10000 + ed); + assert_eq!(balance(user, coin1), 10000 + 1); assert_eq!(balance(user, coin2), 1000 - 10); assert_eq!(pool_balance(user, lp_token1), 216); @@ -226,7 +221,7 @@ fn can_add_liquidity() { let pallet_account = Dex::get_pool_account(pool_id); assert_eq!(balance(pallet_account, coin1), 10000); assert_eq!(balance(pallet_account, coin3), 10); - assert_eq!(balance(user, coin1), ed); + assert_eq!(balance(user, coin1), 1); assert_eq!(balance(user, coin3), 1000 - 10); assert_eq!(pool_balance(user, lp_token2), 216); }); @@ -245,7 +240,7 @@ fn add_tiny_liquidity_leads_to_insufficient_liquidity_minted_error() { assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); assert_noop!( - Dex::add_liquidity(RuntimeOrigin::signed(user), coin2, 1, get_ed(), 1, 1, user), + Dex::add_liquidity(RuntimeOrigin::signed(user), coin2, 1, 1, 1, 1, user), Error::::InsufficientLiquidityMinted ); }); @@ -262,11 +257,7 @@ fn add_tiny_liquidity_directly_to_pool_address() { assert_ok!(Dex::create_pool(coin2)); assert_ok!(Dex::create_pool(coin3)); - let ed = get_ed(); - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(10000 * 2 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(10000 * 2) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(10000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin3, amount: Amount(10000) })); @@ -358,10 +349,7 @@ fn can_not_redeem_more_lp_tokens_than_were_minted() { assert_ok!(Dex::create_pool(coin2)); - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(10000 + get_ed()) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(10000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); assert_ok!(Dex::add_liquidity(RuntimeOrigin::signed(user), coin2, 10, 10000, 10, 10000, user,)); @@ -520,8 +508,8 @@ fn quote_price_exact_tokens_for_tokens_matches_execution() { ); assert_ok!(CoinsPallet::::mint(user2, Balance { coin: coin2, amount: Amount(amount) })); - let prior_dot_balance = 0; - assert_eq!(prior_dot_balance, balance(user2, coin1)); + let prior_sri_balance = 0; + assert_eq!(prior_sri_balance, balance(user2, coin1)); assert_ok!(Dex::swap_exact_tokens_for_tokens( RuntimeOrigin::signed(user2), bvec![coin2, coin1], @@ -530,7 +518,7 @@ fn quote_price_exact_tokens_for_tokens_matches_execution() { user2, )); - assert_eq!(prior_dot_balance + quoted_price, balance(user2, coin1)); + assert_eq!(prior_sri_balance + quoted_price, balance(user2, coin1)); }); } @@ -557,8 +545,8 @@ fn quote_price_tokens_for_exact_tokens_matches_execution() { ); assert_ok!(CoinsPallet::::mint(user2, Balance { coin: coin2, amount: Amount(amount) })); - let prior_dot_balance = 0; - assert_eq!(prior_dot_balance, balance(user2, coin1)); + let prior_sri_balance = 0; + assert_eq!(prior_sri_balance, balance(user2, coin1)); let prior_coin_balance = 49; assert_eq!(prior_coin_balance, balance(user2, coin2)); assert_ok!(Dex::swap_tokens_for_exact_tokens( @@ -569,7 +557,7 @@ fn quote_price_tokens_for_exact_tokens_matches_execution() { user2, )); - assert_eq!(prior_dot_balance + amount, balance(user2, coin1)); + assert_eq!(prior_sri_balance + amount, balance(user2, coin1)); assert_eq!(prior_coin_balance - quoted_price, balance(user2, coin2)); }); } @@ -584,11 +572,7 @@ fn can_swap_with_native() { assert_ok!(Dex::create_pool(coin2)); - let ed = get_ed(); - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(10000 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(10000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); let liquidity1 = 10000; @@ -616,7 +600,7 @@ fn can_swap_with_native() { )); let pallet_account = Dex::get_pool_account(pool_id); - assert_eq!(balance(user, coin1), expect_receive + ed); + assert_eq!(balance(user, coin1), expect_receive); assert_eq!(balance(user, coin2), 1000 - liquidity2 - input_amount); assert_eq!(balance(pallet_account, coin1), liquidity1 - expect_receive); assert_eq!(balance(pallet_account, coin2), liquidity2 + input_amount); @@ -708,11 +692,7 @@ fn check_no_panic_when_try_swap_close_to_empty_pool() { assert_ok!(Dex::create_pool(coin2)); - let ed = get_ed(); - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(10000 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(10000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); let liquidity1 = 10000; @@ -822,10 +802,7 @@ fn swap_should_not_work_if_too_much_slippage() { assert_ok!(Dex::create_pool(coin2)); - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(10000 + get_ed()) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(10000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); let liquidity1 = 10000; @@ -866,11 +843,7 @@ fn can_swap_tokens_for_exact_tokens() { assert_ok!(Dex::create_pool(coin2)); - let ed = get_ed(); - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(20000 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(20000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); let pallet_account = Dex::get_pool_account(pool_id); @@ -901,7 +874,7 @@ fn can_swap_tokens_for_exact_tokens() { user, )); - assert_eq!(balance(user, coin1), 10000 + ed - expect_in); + assert_eq!(balance(user, coin1), 10000 - expect_in); assert_eq!(balance(user, coin2), 1000 - liquidity2 + exchange_out); assert_eq!(balance(pallet_account, coin1), liquidity1 + expect_in); assert_eq!(balance(pallet_account, coin2), liquidity2 - exchange_out); @@ -926,17 +899,10 @@ fn can_swap_tokens_for_exact_tokens_when_not_liquidity_provider() { assert_ok!(Dex::create_pool(coin2)); - let ed = get_ed(); let base1 = 10000; let base2 = 1000; - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(base1 + ed) } - )); - assert_ok!(CoinsPallet::::mint( - user2, - Balance { coin: coin1, amount: Amount(base1 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(base1) })); + assert_ok!(CoinsPallet::::mint(user2, Balance { coin: coin1, amount: Amount(base1) })); assert_ok!(CoinsPallet::::mint(user2, Balance { coin: coin2, amount: Amount(base2) })); let pallet_account = Dex::get_pool_account(pool_id); @@ -956,7 +922,7 @@ fn can_swap_tokens_for_exact_tokens_when_not_liquidity_provider() { user2, )); - assert_eq!(balance(user, coin1), base1 + ed); + assert_eq!(balance(user, coin1), base1); assert_eq!(balance(user, coin2), 0); let exchange_out = 50; @@ -970,7 +936,7 @@ fn can_swap_tokens_for_exact_tokens_when_not_liquidity_provider() { user, )); - assert_eq!(balance(user, coin1), base1 + ed - expect_in); + assert_eq!(balance(user, coin1), base1 - expect_in); assert_eq!(balance(pallet_account, coin1), liquidity1 + expect_in); assert_eq!(balance(user, coin2), exchange_out); assert_eq!(balance(pallet_account, coin2), liquidity2 - exchange_out); @@ -1010,10 +976,7 @@ fn swap_tokens_for_exact_tokens_should_not_work_if_too_much_slippage() { assert_ok!(Dex::create_pool(coin2)); - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(20000 + get_ed()) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(20000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(1000) })); let liquidity1 = 10000; @@ -1055,13 +1018,9 @@ fn swap_exact_tokens_for_tokens_in_multi_hops() { assert_ok!(Dex::create_pool(coin2)); assert_ok!(Dex::create_pool(coin3)); - let ed = get_ed(); let base1 = 10000; let base2 = 10000; - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(base1 * 2 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(base1 * 2) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(base2) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin3, amount: Amount(base2) })); @@ -1147,13 +1106,9 @@ fn swap_tokens_for_exact_tokens_in_multi_hops() { assert_ok!(Dex::create_pool(coin2)); assert_ok!(Dex::create_pool(coin3)); - let ed = get_ed(); let base1 = 10000; let base2 = 10000; - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(base1 * 2 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(base1 * 2) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(base2) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin3, amount: Amount(base2) })); @@ -1273,10 +1228,9 @@ fn cannot_block_pool_creation() { // User 2 is the attacker let attacker = system_address(b"attacker").into(); - let ed = get_ed(); assert_ok!(CoinsPallet::::mint( attacker, - Balance { coin: Coin::native(), amount: Amount(10000 + ed) } + Balance { coin: Coin::native(), amount: Amount(10000) } )); // The target pool the user wants to create is Native <=> Coin(2) @@ -1285,11 +1239,11 @@ fn cannot_block_pool_creation() { // Attacker computes the still non-existing pool account for the target pair let pool_account = Dex::get_pool_account(Dex::get_pool_id(coin2, coin1).unwrap()); - // And transfers the ED to that pool account + // And transfers 1 to that pool account assert_ok!(CoinsPallet::::transfer_internal( attacker, pool_account, - Balance { coin: Coin::native(), amount: Amount(ed) } + Balance { coin: Coin::native(), amount: Amount(1) } )); // Then, the attacker creates 14 tokens and sends one of each to the pool account // skip the coin1 and coin2 coins. @@ -1307,10 +1261,7 @@ fn cannot_block_pool_creation() { // User has to transfer one Coin(2) token to the pool account (otherwise add_liquidity will // fail with `CoinTwoDepositDidNotMeetMinimum`), also transfer native token for the same error. - assert_ok!(CoinsPallet::::mint( - user, - Balance { coin: coin1, amount: Amount(10000 + ed) } - )); + assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin1, amount: Amount(10000) })); assert_ok!(CoinsPallet::::mint(user, Balance { coin: coin2, amount: Amount(10000) })); assert_ok!(CoinsPallet::::transfer_internal( user, diff --git a/substrate/dex/primitives/src/lib.rs b/substrate/dex/pallet/src/types.rs similarity index 96% rename from substrate/dex/primitives/src/lib.rs rename to substrate/dex/pallet/src/types.rs index 698c3ca7b..8be6af560 100644 --- a/substrate/dex/primitives/src/lib.rs +++ b/substrate/dex/pallet/src/types.rs @@ -18,14 +18,11 @@ // It has been forked into a crate distributed under the AGPL 3.0. // Please check the current distribution for up-to-date copyright and licensing information. -#![cfg_attr(not(feature = "std"), no_std)] +use super::*; use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; -use sp_runtime::DispatchError; -use sp_std::vec::Vec; - /// Stores the lp_token coin id a particular pool has been assigned. #[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)] pub struct PoolInfo { diff --git a/substrate/dex/primitives/Cargo.toml b/substrate/dex/primitives/Cargo.toml deleted file mode 100644 index 5f10911aa..000000000 --- a/substrate/dex/primitives/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "serai-dex-primitives" -version = "0.1.0" -description = "Dex pallet primitives" -license = "AGPL-3.0-only" -repository = "https://github.com/serai-dex/serai/tree/develop/substrate/dex/primitives" -authors = ["Parity Technologies , Akil Demir "] -edition = "2021" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } -scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } - -frame-benchmarking = { git = "https://github.com/serai-dex/substrate", default-features = false, optional = true } - -sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } -sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false } - -[features] -default = [ "std" ] -std = [ - "codec/std", - "scale-info/std", - - "frame-benchmarking?/std", - - "sp-runtime/std", - "sp-std/std", -] -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", -] diff --git a/substrate/dex/primitives/LICENSE-AGPL3 b/substrate/dex/primitives/LICENSE-AGPL3 deleted file mode 100644 index f684d0271..000000000 --- a/substrate/dex/primitives/LICENSE-AGPL3 +++ /dev/null @@ -1,15 +0,0 @@ -AGPL-3.0-only license - -Copyright (c) 2023 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 . diff --git a/substrate/dex/primitives/LICENSE-APACHE2 b/substrate/dex/primitives/LICENSE-APACHE2 deleted file mode 100644 index fbb0616d1..000000000 --- a/substrate/dex/primitives/LICENSE-APACHE2 +++ /dev/null @@ -1,211 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - - NOTE - -Individual files contain the following tag instead of the full license -text. - - SPDX-License-Identifier: Apache-2.0 - -This enables machine processing of license information based on the SPDX -License Identifiers that are here available: http://spdx.org/licenses/ \ No newline at end of file diff --git a/substrate/in-instructions/pallet/src/lib.rs b/substrate/in-instructions/pallet/src/lib.rs index 76aa897f5..88fb24719 100644 --- a/substrate/in-instructions/pallet/src/lib.rs +++ b/substrate/in-instructions/pallet/src/lib.rs @@ -179,7 +179,7 @@ pub mod pallet { // do the swap let origin = RawOrigin::Signed(IN_INSTRUCTION_EXECUTOR.into()); Dex::::swap_exact_tokens_for_tokens( - origin.into(), + origin.clone().into(), BoundedVec::try_from(path).unwrap(), instruction.balance.amount.0, out_balance.amount.0, @@ -200,7 +200,7 @@ pub mod pallet { }, balance: Balance { coin: out_balance.coin, amount: coin_balance }, }; - Coins::::burn_non_sri(IN_INSTRUCTION_EXECUTOR.into(), instruction)?; + Coins::::burn_with_instruction(origin.into(), instruction)?; } } } diff --git a/substrate/node/src/chain_spec.rs b/substrate/node/src/chain_spec.rs index 2c834abd4..1c0e4f659 100644 --- a/substrate/node/src/chain_spec.rs +++ b/substrate/node/src/chain_spec.rs @@ -41,12 +41,12 @@ fn testnet_genesis( .into_iter() .map(|a| (a, Balance { coin: Coin::Serai, amount: Amount(1 << 60) })) .collect(), - ignore: Default::default(), + _ignore: Default::default(), }, dex: DexConfig { pools: vec![Coin::Bitcoin, Coin::Ether, Coin::Dai, Coin::Monero], - ignore: Default::default(), + _ignore: Default::default(), }, validator_sets: ValidatorSetsConfig { diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index 01d7faecc..6e1db90ab 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -40,7 +40,6 @@ frame-executive = { git = "https://github.com/serai-dex/substrate", default-feat frame-benchmarking = { git = "https://github.com/serai-dex/substrate", default-features = false, optional = true } serai-primitives = { path = "../primitives", default-features = false } -serai-dex-primitives = { path = "../dex/primitives", default-features = false } pallet-timestamp = { git = "https://github.com/serai-dex/substrate", default-features = false } @@ -96,7 +95,6 @@ std = [ "frame-executive/std", "serai-primitives/std", - "serai-dex-primitives/std", "pallet-timestamp/std", @@ -130,8 +128,6 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", - "dex-pallet/runtime-benchmarks", - "pallet-babe/runtime-benchmarks", "pallet-grandpa/runtime-benchmarks", ] diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 024688a36..d996a68e0 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -252,9 +252,6 @@ impl coins::Config for Runtime { impl dex::Config for Runtime { type RuntimeEvent = RuntimeEvent; - // TODO: Review if this should be u64/u128 or u64/u256 (and rounding in general). - // TODO: do we still need this type? - type HigherPrecisionBalance = u128; type LPFee = ConstU32<3>; // 0.3% type MintMinLiquidity = ConstU64<10000>; diff --git a/tests/coordinator/src/tests/sign.rs b/tests/coordinator/src/tests/sign.rs index 0a8dfffc9..a00935ee9 100644 --- a/tests/coordinator/src/tests/sign.rs +++ b/tests/coordinator/src/tests/sign.rs @@ -275,7 +275,12 @@ async fn sign_test() { serai .publish( &serai - .sign(&serai_pair, &SeraiCoins::burn(out_instruction.clone()), 0, Default::default()) + .sign( + &serai_pair, + &SeraiCoins::burn_with_instruction(out_instruction.clone()), + 0, + Default::default(), + ) .unwrap(), ) .await @@ -293,7 +298,7 @@ async fn sign_test() { let burn_events = serai .as_of(serai.block_by_number(last_serai_block).await.unwrap().unwrap().hash()) .coins() - .burn_events() + .burn_with_instruction_events() .await .unwrap(); @@ -301,7 +306,10 @@ async fn sign_test() { assert_eq!(burn_events.len(), 1); assert_eq!( burn_events[0], - CoinsEvent::Burn { from: serai_addr.into(), instruction: out_instruction.clone() } + CoinsEvent::BurnWithInstruction { + from: serai_addr.into(), + instruction: out_instruction.clone() + } ); break 'outer; } diff --git a/tests/full-stack/src/tests/mint_and_burn.rs b/tests/full-stack/src/tests/mint_and_burn.rs index f545f81a0..65388a748 100644 --- a/tests/full-stack/src/tests/mint_and_burn.rs +++ b/tests/full-stack/src/tests/mint_and_burn.rs @@ -498,7 +498,12 @@ async fn mint_and_burn_test() { serai .publish( &serai - .sign(serai_pair, &SeraiCoins::burn(out_instruction), nonce, Default::default()) + .sign( + serai_pair, + &SeraiCoins::burn_with_instruction(out_instruction), + nonce, + Default::default(), + ) .unwrap(), ) .await