From 426a1abcadec0deff7e231bfbd96856a2cd94ac4 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Mon, 21 Jun 2021 23:55:53 +0800 Subject: [PATCH 01/83] remove `SettersIncentivePool` --- lib-serml/incentives/src/mock.rs | 1 - runtime/neom/src/lib.rs | 1 - runtime/newrome/src/lib.rs | 1 - runtime/setheum/src/lib.rs | 1 - 4 files changed, 4 deletions(-) diff --git a/lib-serml/incentives/src/mock.rs b/lib-serml/incentives/src/mock.rs index 571e8826c..80906d3b9 100644 --- a/lib-serml/incentives/src/mock.rs +++ b/lib-serml/incentives/src/mock.rs @@ -304,7 +304,6 @@ ord_parameter_types! { impl Config for Runtime { type Event = Event; - type SettersIncentivePool = SettersIncentivePool; type RewardsVaultAccountId = RewardsVaultAccountId; type DexIncentivePool = DexIncentivePool; type AccumulatePeriod = AccumulatePeriod; diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index 19110b74e..39fd697ad 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -992,7 +992,6 @@ parameter_types! { impl setheum_incentives::Config for Runtime { type Event = Event; - type SettersIncentivePool = ZeroAccountId; type DexIncentivePool = ZeroAccountId; type AccumulatePeriod = AccumulatePeriod; type IncentiveCurrencyId = GetNativeCurrencyId; diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index 6e662df58..6090a6f2c 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -994,7 +994,6 @@ parameter_types! { impl setheum_incentives::Config for Runtime { type Event = Event; - type SettersIncentivePool = ZeroAccountId; type DexIncentivePool = ZeroAccountId; type AccumulatePeriod = AccumulatePeriod; type IncentiveCurrencyId = GetNativeCurrencyId; diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index 335c1cd02..a5c38df16 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -995,7 +995,6 @@ parameter_types! { impl setheum_incentives::Config for Runtime { type Event = Event; - type SettersIncentivePool = ZeroAccountId; type DexIncentivePool = ZeroAccountId; type AccumulatePeriod = AccumulatePeriod; type IncentiveCurrencyId = GetNativeCurrencyId; From 0510b3463bcd6eb1cd49eb45fcdfb476be42cb68 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 00:08:30 +0800 Subject: [PATCH 02/83] Update newrome benchmarking --- .../newrome/src/benchmarking/incentives.rs | 30 +------- runtime/newrome/src/benchmarking/mod.rs | 1 - runtime/newrome/src/benchmarking/rewards.rs | 70 ------------------- 3 files changed, 1 insertion(+), 100 deletions(-) delete mode 100644 runtime/newrome/src/benchmarking/rewards.rs diff --git a/runtime/newrome/src/benchmarking/incentives.rs b/runtime/newrome/src/benchmarking/incentives.rs index a37ad0531..9a51cc5ec 100644 --- a/runtime/newrome/src/benchmarking/incentives.rs +++ b/runtime/newrome/src/benchmarking/incentives.rs @@ -61,17 +61,7 @@ runtime_benchmarks! { }); }: _(RawOrigin::Signed(caller), pool_id) - update_reserves_incentive_rewards { - let c in 0 .. ReserveCurrencyIds::get().len().saturating_sub(1) as u32; - let currency_ids = ReserveCurrencyIds::get(); - let mut values = vec![]; - - for i in 0 .. c { - let currency_id = currency_ids[i as usize]; - values.push((currency_id, 100 * dollar(ROME))); - } - }: _(RawOrigin::Root, values) - + // TODO: Update - add all other dex rewards ... update_dex_incentive_rewards { let c in 0 .. ReserveCurrencyIds::get().len().saturating_sub(1) as u32; let currency_ids = ReserveCurrencyIds::get(); @@ -91,24 +81,6 @@ runtime_benchmarks! { } }: _(RawOrigin::Root, values) - update_dex_saving_rates { - let c in 0 .. ReserveCurrencyIds::get().len().saturating_sub(1) as u32; - let currency_ids = ReserveCurrencyIds::get(); - let caller: AccountId = account("caller", 0, SEED); - let mut values = vec![]; - let base_currency_id = GetStableCurrencyId::get(); - - for i in 0 .. c { - let currency_id = currency_ids[i as usize]; - let lp_share_currency_id = match (currency_id, base_currency_id) { - (CurrencyId::Token(other_currency_symbol), CurrencyId::Token(base_currency_symbol)) => { - CurrencyId::DexShare(other_currency_symbol, base_currency_symbol) - } - _ => return Err("invalid currency id"), - }; - values.push((lp_share_currency_id, Rate::default())); - } - }: _(RawOrigin::Root, values) } #[cfg(test)] diff --git a/runtime/newrome/src/benchmarking/mod.rs b/runtime/newrome/src/benchmarking/mod.rs index 61ac747ec..21feb8a24 100644 --- a/runtime/newrome/src/benchmarking/mod.rs +++ b/runtime/newrome/src/benchmarking/mod.rs @@ -33,7 +33,6 @@ pub mod auction; pub mod authority; pub mod currencies; pub mod oracle; -pub mod rewards; pub mod tokens; pub mod utils; pub mod vesting; diff --git a/runtime/newrome/src/benchmarking/rewards.rs b/runtime/newrome/src/benchmarking/rewards.rs deleted file mode 100644 index 065bcbb3d..000000000 --- a/runtime/newrome/src/benchmarking/rewards.rs +++ /dev/null @@ -1,70 +0,0 @@ -// This file is part of Setheum. - -// Copyright (C) 2020-2021 Setheum Labs. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// 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 General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use crate::{AccumulatePeriod, ReserveCurrencyIds, Rewards, Runtime, System}; - -use frame_support::traits::OnInitialize; -use setheum_incentives::PoolId; -use orml_benchmarking::runtime_benchmarks; -use sp_std::prelude::*; - -runtime_benchmarks! { - { Runtime, orml_rewards } - - _ {} - - on_initialize { - let c in 0 .. ReserveCurrencyIds::get().len().saturating_sub(1) as u32; - let currency_ids = ReserveCurrencyIds::get(); - let block_number = AccumulatePeriod::get(); - - for i in 0 .. c { - let currency_id = currency_ids[i as usize]; - let pool_id = PoolId::Setters(currency_id); - - orml_rewards::Pools::::mutate(pool_id, |pool_info| { - pool_info.total_rewards += 100; - }); - } - - Rewards::on_initialize(1); - System::set_block_number(block_number); - }: { - Rewards::on_initialize(System::block_number()); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use frame_support::assert_ok; - - fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::default() - .build_storage::() - .unwrap() - .into() - } - - #[test] - fn test_on_initialize() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_on_initialize()); - }); - } -} From 27c3dabdd4ee0055f0c0f47e3a5e7f06cfeb3c89 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 00:26:13 +0800 Subject: [PATCH 03/83] Update & rename setheum-setters to setters-manager --- Cargo.lock | 52 +++--- .../{setters => setters-manager}/Cargo.toml | 2 +- .../{setters => setters-manager}/src/lib.rs | 11 +- .../{setters => setters-manager}/src/mock.rs | 10 +- lib-serml/setters-manager/src/tests.rs | 167 ++++++++++++++++++ lib-serml/setters/src/tests.rs | 167 ------------------ lib-serml/settmint-engine/Cargo.toml | 4 +- lib-serml/settmint-engine/src/lib.rs | 8 +- lib-serml/settmint-engine/src/mock.rs | 8 +- lib-serml/settmint-engine/src/tests.rs | 12 +- lib-serml/settway/Cargo.toml | 4 +- lib-serml/settway/src/lib.rs | 4 +- lib-serml/settway/src/mock.rs | 8 +- lib-serml/settway/src/tests.rs | 8 +- runtime/neom/Cargo.toml | 6 +- runtime/neom/src/lib.rs | 10 +- runtime/newrome/Cargo.toml | 6 +- .../newrome/src/benchmarking/incentives.rs | 2 +- runtime/newrome/src/lib.rs | 10 +- runtime/setheum/Cargo.toml | 6 +- runtime/setheum/src/lib.rs | 10 +- 21 files changed, 258 insertions(+), 257 deletions(-) rename lib-serml/{setters => setters-manager}/Cargo.toml (98%) rename lib-serml/{setters => setters-manager}/src/lib.rs (97%) rename lib-serml/{setters => setters-manager}/src/mock.rs (97%) create mode 100644 lib-serml/setters-manager/src/tests.rs delete mode 100644 lib-serml/setters/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index aebedd0d8..655aec04f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4101,11 +4101,11 @@ dependencies = [ "setheum-nft", "setheum-prices", "setheum-primitives", - "setheum-setters", "setheum-settmint-engine", "setheum-settway", "setheum-support", "setheum-transaction-payment", + "setters-manager", "smallvec 1.6.1", "sp-api 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -4194,11 +4194,11 @@ dependencies = [ "setheum-nft", "setheum-prices", "setheum-primitives", - "setheum-setters", "setheum-settmint-engine", "setheum-settway", "setheum-support", "setheum-transaction-payment", + "setters-manager", "smallvec 1.6.1", "sp-api 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -7825,11 +7825,11 @@ dependencies = [ "setheum-nft", "setheum-prices", "setheum-primitives", - "setheum-setters", "setheum-settmint-engine", "setheum-settway", "setheum-support", "setheum-transaction-payment", + "setters-manager", "smallvec 1.6.1", "sp-api 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -7898,27 +7898,6 @@ dependencies = [ "substrate-prometheus-endpoint", ] -[[package]] -name = "setheum-setters" -version = "0.7.1" -dependencies = [ - "frame-support 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", - "frame-system 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", - "orml-currencies", - "orml-tokens 0.4.1-dev", - "orml-traits 0.4.1-dev", - "pallet-balances 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec", - "serde", - "serp-treasury", - "setheum-primitives", - "setheum-support", - "sp-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-io 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-runtime 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", - "sp-std 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", -] - [[package]] name = "setheum-settmint-engine" version = "0.7.1" @@ -7935,8 +7914,8 @@ dependencies = [ "serp-treasury", "setheum-dex", "setheum-primitives", - "setheum-setters", "setheum-support", + "setters-manager", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp-io 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -7958,9 +7937,9 @@ dependencies = [ "serde", "serp-treasury", "setheum-primitives", - "setheum-setters", "setheum-settmint-engine", "setheum-support", + "setters-manager", "sp-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp-io 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp-runtime 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -8005,6 +7984,27 @@ dependencies = [ "sp-std 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", ] +[[package]] +name = "setters-manager" +version = "0.7.1" +dependencies = [ + "frame-support 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", + "frame-system 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", + "orml-currencies", + "orml-tokens 0.4.1-dev", + "orml-traits 0.4.1-dev", + "pallet-balances 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec", + "serde", + "serp-treasury", + "setheum-primitives", + "setheum-support", + "sp-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-io 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-runtime 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", + "sp-std 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", +] + [[package]] name = "sha-1" version = "0.8.2" diff --git a/lib-serml/setters/Cargo.toml b/lib-serml/setters-manager/Cargo.toml similarity index 98% rename from lib-serml/setters/Cargo.toml rename to lib-serml/setters-manager/Cargo.toml index a6c6b9e57..b1401bb46 100644 --- a/lib-serml/setters/Cargo.toml +++ b/lib-serml/setters-manager/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "setheum-setters" +name = "setters-manager" version = "0.7.1" authors = ["Setheum Labs"] edition = "2018" diff --git a/lib-serml/setters/src/lib.rs b/lib-serml/setters-manager/src/lib.rs similarity index 97% rename from lib-serml/setters/src/lib.rs rename to lib-serml/setters-manager/src/lib.rs index 41fecaeb2..4514a434a 100644 --- a/lib-serml/setters/src/lib.rs +++ b/lib-serml/setters-manager/src/lib.rs @@ -16,11 +16,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! # Setters Module +//! # SettersManager Module //! //! ## Overview //! -//! Setters module manages Settmint's reserve asset (Setter) and the standards backed by the asset (SettCurrencies). +//! SettersManager module manages Settmint's reserve asset (Setter) +//! and the standards backed by the asset (SettCurrencies). #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::unused_unit)] @@ -62,8 +63,8 @@ pub mod module { /// value(SettCurrency) type Convert: Convert<(CurrencyId, Balance), Balance>; - /// Currency type for deposit/withdraw reserve assets to/from setters - /// module + /// Currency type for deposit/withdraw reserve assets + /// to/from setters-manager module type Currency: MultiCurrencyExtended< Self::AccountId, CurrencyId = CurrencyId, @@ -78,7 +79,7 @@ pub mod module { /// Setter (Valid Reserve) currency id type GetReserveCurrencyId: Get; - /// Standard manager is used to know the validity of Settmint standards. + /// Standard validator is used to know the validity of Settmint standards. type StandardValidator: StandardValidator; /// SERP Treasury for issuing/burning stable currency adjust standard value diff --git a/lib-serml/setters/src/mock.rs b/lib-serml/setters-manager/src/mock.rs similarity index 97% rename from lib-serml/setters/src/mock.rs rename to lib-serml/setters-manager/src/mock.rs index f0ecd9f54..8334c0610 100644 --- a/lib-serml/setters/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Mocks for the setters module. +//! Mocks for the setters-manager module. #![cfg(test)] @@ -51,7 +51,7 @@ pub const OMRJ: CurrencyId = CurrencyId::Token(TokenSymbol::OMRJ); // Setheum OM pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); // Setheum CHF (Swiss Franc stablecoin) pub const GIPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GIPJ); // Setheum GIP (Gibraltar Pound stablecoin) -mod setters { +mod setters_manager { pub use super::super::*; } @@ -311,7 +311,7 @@ parameter_types! { ZARJ, ]; pub const GetReserveCurrencyId: CurrencyId = SETT; - pub const SettersPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); } @@ -323,7 +323,7 @@ impl Config for Runtime { type GetReserveCurrencyId = GetReserveCurrencyId; type StandardValidator = MockStandardValidator; type SerpTreasury = SerpTreasuryModule; - type PalletId = SettersPalletId; + type PalletId = SettersManagerPalletId; type OnUpdateSetter = (); } @@ -337,7 +337,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Module, Call, Storage, Config, Event}, - SettersModule: setters::{Module, Storage, Call, Event}, + SettersManagerModule: setters_manager::{Module, Storage, Call, Event}, Tokens: orml_tokens::{Module, Storage, Event, Config}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, Currencies: orml_currencies::{Module, Call, Event}, diff --git a/lib-serml/setters-manager/src/tests.rs b/lib-serml/setters-manager/src/tests.rs new file mode 100644 index 000000000..85b78fe51 --- /dev/null +++ b/lib-serml/setters-manager/src/tests.rs @@ -0,0 +1,167 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Unit tests for the setters-manager module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::{Event, *}; + +#[test] +fn standards_key() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_ok!(SettersManagerModule::adjust_position(&ALICE, EURJ, 100, 100)); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 100); + assert_ok!(SettersManagerModule::adjust_position(&ALICE, EURJ, -100, -100)); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); + }); +} + +#[test] +fn check_update_reserve_overflow_work() { + ExtBuilder::default().build().execute_with(|| { + // reserve underflow + assert_noop!( + SettersManagerModule::update_reserve(&ALICE, EURJ, -100, 0), + Error::::ReserveTooLow, + ); + + // standard underflow + assert_noop!( + SettersManagerModule::update_reserve(&ALICE, EURJ, 0, -100), + Error::::StandardTooLow, + ); + }); +} + +#[test] +fn adjust_position_should_work() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + + // balance too low + assert_eq!(SettersManagerModule::adjust_position(&ALICE, EURJ, 2000, 0).is_ok(), false); + + // mock can't pass position valid check + assert_eq!(SettersManagerModule::adjust_position(&ALICE, USDJ, 500, 0).is_ok(), false); + + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + assert_eq!(Currencies::free_balance(EURJ, &SettersManagerModule::account_id()), 0); + assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 0); + assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 0); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(Currencies::free_balance(EURJ, &ALICE), 0); + + // success + assert_ok!(SettersManagerModule::adjust_position(&ALICE, EURJ, 500, 300)); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 500); + assert_eq!(Currencies::free_balance(SETT, &SettersManagerModule::account_id()), 500); + assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 300); + assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 500); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 300); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 500); + assert_eq!(Currencies::free_balance(EURJ, &ALICE), 150); + + System::assert_last_event(Event::setters_manager(crate::Event::PositionUpdated(ALICE, EURJ, 500, 300))); + }); +} + +#[test] +fn transfer_reserve_should_work() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + assert_ok!(SettersManagerModule::update_reserve(&ALICE, EURJ, 400, 500)); + assert_ok!(SettersManagerModule::update_reserve(&BOB, EURJ, 100, 600)); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 500); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 400); + assert_eq!(SettersManagerModule::positions(EURJ, &BOB).standard, 600); + assert_eq!(SettersManagerModule::positions(EURJ, &BOB).reserve, 100); + + assert_ok!(SettersManagerModule::transfer_reserve(&ALICE, &BOB, EURJ)); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(SettersManagerModule::positions(EURJ, &BOB).standard, 1100); + assert_eq!(SettersManagerModule::positions(EURJ, &BOB).reserve, 500); + + System::assert_last_event(Event::setters_manager(crate::Event::TransferReserve(ALICE, BOB, EURJ))); + }); +} + +#[test] +fn update_reserve_should_work() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(Currencies::free_balance(SETT, &SettersManagerModule::account_id()), 0); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 0); + assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 0); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(>::contains_key(EURJ, &ALICE), false); + + let alice_ref_count_0 = System::consumers(&ALICE); + + assert_ok!(SettersManagerModule::update_reserve(&ALICE, EURJ, 3000, 2000)); + + // just update records + assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 2000); + assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 3000); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 2000); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 3000); + + // increase ref count when open new position + let alice_ref_count_1 = System::consumers(&ALICE); + assert_eq!(alice_ref_count_1, alice_ref_count_0 + 1); + + // dot not manipulate balance + assert_eq!(Currencies::free_balance(SETT, &SettersManagerModule::account_id()), 0); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + + // should remove position storage if zero + assert_eq!(>::contains_key(EURJ, &ALICE), true); + assert_ok!(SettersManagerModule::update_reserve(&ALICE, EURJ, -3000, -2000)); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(>::contains_key(EURJ, &ALICE), false); + + // decrease ref count after remove position + let alice_ref_count_2 = System::consumers(&ALICE); + assert_eq!(alice_ref_count_2, alice_ref_count_1 - 1); + }); +} + +#[test] +fn total_reserve_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(SettersManagerModule::total_reserve(0); + assert_ok!(Currencies::deposit(SETT,&SettersManagerModule::account_id()), 10)); + assert_eq!(SettersManagerModule::total_reserve(10); + }); +} + +#[test] +fn get_total_reserve_works() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(SettersManagerModule::deposit_reserve(&ALICE, 500)); + assert_eq!(SettersManagerModule::get_total_reserve(500); + }); +} diff --git a/lib-serml/setters/src/tests.rs b/lib-serml/setters/src/tests.rs deleted file mode 100644 index 05d523123..000000000 --- a/lib-serml/setters/src/tests.rs +++ /dev/null @@ -1,167 +0,0 @@ -// This file is part of Setheum. - -// Copyright (C) 2020-2021 Setheum Labs. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// 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 General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Unit tests for the setters module. - -#![cfg(test)] - -use super::*; -use frame_support::{assert_noop, assert_ok}; -use mock::{Event, *}; - -#[test] -fn standards_key() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 0); - assert_ok!(SettersModule::adjust_position(&ALICE, EURJ, 100, 100)); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 100); - assert_ok!(SettersModule::adjust_position(&ALICE, EURJ, -100, -100)); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 0); - }); -} - -#[test] -fn check_update_reserve_overflow_work() { - ExtBuilder::default().build().execute_with(|| { - // reserve underflow - assert_noop!( - SettersModule::update_reserve(&ALICE, EURJ, -100, 0), - Error::::ReserveTooLow, - ); - - // standard underflow - assert_noop!( - SettersModule::update_reserve(&ALICE, EURJ, 0, -100), - Error::::StandardTooLow, - ); - }); -} - -#[test] -fn adjust_position_should_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - - // balance too low - assert_eq!(SettersModule::adjust_position(&ALICE, EURJ, 2000, 0).is_ok(), false); - - // mock can't pass position valid check - assert_eq!(SettersModule::adjust_position(&ALICE, USDJ, 500, 0).is_ok(), false); - - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - assert_eq!(Currencies::free_balance(EURJ, &SettersModule::account_id()), 0); - assert_eq!(SettersModule::total_positions(EURJ).standard, 0); - assert_eq!(SettersModule::total_positions(EURJ).reserve, 0); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(Currencies::free_balance(EURJ, &ALICE), 0); - - // success - assert_ok!(SettersModule::adjust_position(&ALICE, EURJ, 500, 300)); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 500); - assert_eq!(Currencies::free_balance(SETT, &SettersModule::account_id()), 500); - assert_eq!(SettersModule::total_positions(EURJ).standard, 300); - assert_eq!(SettersModule::total_positions(EURJ).reserve, 500); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 300); - assert_eq!(SettersModule::positions(EURJ, &ALICE).reserve, 500); - assert_eq!(Currencies::free_balance(EURJ, &ALICE), 150); - - System::assert_last_event(Event::setters(crate::Event::PositionUpdated(ALICE, EURJ, 500, 300))); - }); -} - -#[test] -fn transfer_reserve_should_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(SettersModule::update_reserve(&ALICE, EURJ, 400, 500)); - assert_ok!(SettersModule::update_reserve(&BOB, EURJ, 100, 600)); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 500); - assert_eq!(SettersModule::positions(EURJ, &ALICE).reserve, 400); - assert_eq!(SettersModule::positions(EURJ, &BOB).standard, 600); - assert_eq!(SettersModule::positions(EURJ, &BOB).reserve, 100); - - assert_ok!(SettersModule::transfer_reserve(&ALICE, &BOB, EURJ)); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(SettersModule::positions(EURJ, &BOB).standard, 1100); - assert_eq!(SettersModule::positions(EURJ, &BOB).reserve, 500); - - System::assert_last_event(Event::setters(crate::Event::TransferReserve(ALICE, BOB, EURJ))); - }); -} - -#[test] -fn update_reserve_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Currencies::free_balance(SETT, &SettersModule::account_id()), 0); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - assert_eq!(SettersModule::total_positions(EURJ).standard, 0); - assert_eq!(SettersModule::total_positions(EURJ).reserve, 0); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(>::contains_key(EURJ, &ALICE), false); - - let alice_ref_count_0 = System::consumers(&ALICE); - - assert_ok!(SettersModule::update_reserve(&ALICE, EURJ, 3000, 2000)); - - // just update records - assert_eq!(SettersModule::total_positions(EURJ).standard, 2000); - assert_eq!(SettersModule::total_positions(EURJ).reserve, 3000); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 2000); - assert_eq!(SettersModule::positions(EURJ, &ALICE).reserve, 3000); - - // increase ref count when open new position - let alice_ref_count_1 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_1, alice_ref_count_0 + 1); - - // dot not manipulate balance - assert_eq!(Currencies::free_balance(SETT, &SettersModule::account_id()), 0); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - - // should remove position storage if zero - assert_eq!(>::contains_key(EURJ, &ALICE), true); - assert_ok!(SettersModule::update_reserve(&ALICE, EURJ, -3000, -2000)); - assert_eq!(SettersModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(>::contains_key(EURJ, &ALICE), false); - - // decrease ref count after remove position - let alice_ref_count_2 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_2, alice_ref_count_1 - 1); - }); -} - -#[test] -fn total_reserve_works() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(SettersModule::total_reserve(0); - assert_ok!(Currencies::deposit(SETT,&SettersModule::account_id()), 10)); - assert_eq!(SettersModule::total_reserve(10); - }); -} - -#[test] -fn get_total_reserve_works() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettersModule::deposit_reserve(&ALICE, 500)); - assert_eq!(SettersModule::get_total_reserve(500); - }); -} diff --git a/lib-serml/settmint-engine/Cargo.toml b/lib-serml/settmint-engine/Cargo.toml index 418ffdbf0..eeb765a77 100644 --- a/lib-serml/settmint-engine/Cargo.toml +++ b/lib-serml/settmint-engine/Cargo.toml @@ -24,7 +24,7 @@ orml-utilities = { path = "../../lib-openrml/utilities", default-features = fals # local dependencies support = { package = "setheum-support", path = "../support", default-features = false } -setters = { package = "setheum-setters", path = "../setters", default-features = false } +setters-manager = { package = "setters-manager", path = "../setters-manager", default-features = false } primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } [dev-dependencies] @@ -48,7 +48,7 @@ std = [ "sp-runtime/std", "sp-std/std", "support/std", - "setters/std", + "setters-manager/std", "primitives/std", "orml-utilities/std", ] diff --git a/lib-serml/settmint-engine/src/lib.rs b/lib-serml/settmint-engine/src/lib.rs index cfd2cd085..e0226a484 100644 --- a/lib-serml/settmint-engine/src/lib.rs +++ b/lib-serml/settmint-engine/src/lib.rs @@ -33,7 +33,7 @@ use frame_system::{ offchain::{SendTransactionTypes, SubmitTransaction}, pallet_prelude::*, }; -use setters::Position; +use setters_manager::Position; use orml_traits::Change; use orml_utilities::{IterableStorageDoubleMapExtended, OffchainErr}; use primitives::{Amount, Balance, CurrencyId}; @@ -65,7 +65,7 @@ pub const OFFCHAIN_WORKER_MAX_ITERATIONS: &[u8] = b"setheum/settmint-engine/max- pub const LOCK_DURATION: u64 = 100; pub const DEFAULT_MAX_ITERATIONS: u32 = 1000; -pub type SettersOf = setters::Module; +pub type SettersManagerOf = setters_manager::Module; // typedef to help polkadot.js disambiguate Change with different generic // parameters @@ -78,7 +78,7 @@ pub mod module { use super::*; #[pallet::config] - pub trait Config: frame_system::Config + setters::Config + SendTransactionTypes> { + pub trait Config: frame_system::Config + setters_manager::Config + SendTransactionTypes> { type Event: From> + IsType<::Event>; /// The list of valid standard currency types @@ -187,7 +187,7 @@ impl Pallet { T::StandardCurrencyIds::get().contains(¤cy_id), Error::::InvalidStandardType, ); - >::adjust_position(who, currency_id, reserve_adjustment, standard_adjustment)?; + >::adjust_position(who, currency_id, reserve_adjustment, standard_adjustment)?; Ok(()) } } diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index f4ebec386..3a1c67000 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -133,16 +133,16 @@ impl orml_currencies::Config for Runtime { } parameter_types! { - pub const SettersPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); } -impl setters::Config for Runtime { +impl setters_manager::Config for Runtime { type Event = Event; type Convert = StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngineModule; type SerpTreasury = SerpTreasuryModule; - type PalletId = SettersPalletId; + type PalletId = SettersManagerPalletId; type OnUpdateSetter = (); } @@ -387,7 +387,7 @@ construct_runtime!( SerpTreasuryModule: serp_treasury::{Module, Storage, Call, Config, Event}, Currencies: orml_currencies::{Module, Call, Event}, Tokens: orml_tokens::{Module, Storage, Event, Config}, - SettersModule: setters::{Module, Storage, Call, Event}, + SettersManagerModule: setters_manager::{Module, Storage, Call, Event}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, DexModule: dex::{Module, Storage, Call, Event, Config}, } diff --git a/lib-serml/settmint-engine/src/tests.rs b/lib-serml/settmint-engine/src/tests.rs index ee441e335..af0a9def7 100644 --- a/lib-serml/settmint-engine/src/tests.rs +++ b/lib-serml/settmint-engine/src/tests.rs @@ -79,19 +79,19 @@ fn adjust_position_work() { ); assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 0); - assert_eq!(SettersModule::positions(SETT, ALICE).standard, 0); - assert_eq!(SettersModule::positions(SETT, ALICE).reserve, 0); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 0); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 0); assert_ok!(SettmintEngineModule::adjust_position(&ALICE, SETT, 100, 50)); assert_eq!(Currencies::free_balance(SETT, &ALICE), 900); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 50); - assert_eq!(SettersModule::positions(SETT, ALICE).standard, 50); - assert_eq!(SettersModule::positions(SETT, ALICE).reserve, 100); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 50); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 100); assert_eq!(SettmintEngineModule::adjust_position(&ALICE, SETT, 0, 20).is_ok(), false); assert_ok!(SettmintEngineModule::adjust_position(&ALICE, SETT, 0, -20)); assert_eq!(Currencies::free_balance(SETT, &ALICE), 900); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 30); - assert_eq!(SettersModule::positions(SETT, ALICE).standard, 30); - assert_eq!(SettersModule::positions(SETT, ALICE).reserve, 100); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 30); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 100); }); } diff --git a/lib-serml/settway/Cargo.toml b/lib-serml/settway/Cargo.toml index f4ad0f422..c260ca811 100644 --- a/lib-serml/settway/Cargo.toml +++ b/lib-serml/settway/Cargo.toml @@ -20,7 +20,7 @@ orml-tokens = { path = "../../lib-openrml/tokens", default-features = false } # local dependencies settmint-engine = { package = "setheum-settmint-engine", path = "../settmint-engine", default-features = false } -setters = { package = "setheum-setters", path = "../setters", default-features = false } +setters-manager= { package = "setters-manager", path = "../setters-manager", default-features = false } support = { package = "setheum-support", path = "../support", default-features = false } primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } @@ -42,7 +42,7 @@ std = [ "frame-system/std", "sp-std/std", "orml-tokens/std", - "setters/std", + "setters-manager/std", "settmint-engine/std", "support/std", "primitives/std", diff --git a/lib-serml/settway/src/lib.rs b/lib-serml/settway/src/lib.rs index 63ad34ad6..2934adba2 100644 --- a/lib-serml/settway/src/lib.rs +++ b/lib-serml/settway/src/lib.rs @@ -88,7 +88,7 @@ pub mod module { #[pallet::call] impl Pallet { - /// Adjust the setters of `currency_id` by specific + /// Adjust the standard of `currency_id` by specific /// `reserve_adjustment` and `standard_adjustment` /// /// - `currency_id`: standard currency id. @@ -133,7 +133,7 @@ pub mod module { let to = ensure_signed(origin)?; let from = T::Lookup::lookup(from)?; Self::check_authorization(&from, &to, currency_id)?; - >::transfer_reserve(&from, &to, currency_id)?; + >::transfer_reserve(&from, &to, currency_id)?; Ok(().into()) } diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index f41a7d9f6..c075d05c3 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -331,10 +331,10 @@ impl settmint_engine::Config for Runtime { } parameter_types! { - pub const SettersPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); } -impl setters::Config for Runtime { +impl setters_manager::Config for Runtime { type Event = Event; type Convert = settmint_engine::StandardExchangeRateConvertor; type Currency = Tokens; @@ -342,7 +342,7 @@ impl setters::Config for Runtime { type GetReserveCurrencyId = GetReserveCurrencyId; type StandardValidator = SettmintEngineModule; type SerpTreasury = SerpTreasuryModule; - type PalletId = SettersPalletId; + type PalletId = SettersManagerPalletId; type OnUpdateSetter = (); } @@ -360,7 +360,7 @@ construct_runtime!( Tokens: orml_tokens::{Module, Storage, Event, Config}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, Currencies: orml_currencies::{Module, Call, Event}, - SettersModule: setters::{Module, Storage, Call, Event}, + SettersManagerModule: setters_manager::{Module, Storage, Call, Event}, SerpTreasuryModule: serp_treasury::{Module, Storage, Call, Event}, SettmintEngineModule: settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, } diff --git a/lib-serml/settway/src/tests.rs b/lib-serml/settway/src/tests.rs index 989e8078c..2325b99cf 100644 --- a/lib-serml/settway/src/tests.rs +++ b/lib-serml/settway/src/tests.rs @@ -83,8 +83,8 @@ fn transfer_reserve_from_should_work() { assert_ok!(SettwayModule::adjust_setter(Origin::signed(ALICE), SETT, 100, 50)); assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); assert_ok!(SettwayModule::transfer_reserve_from(Origin::signed(BOB), SETT, ALICE)); - assert_eq!(SettersModule::positions(SETT, BOB).reserve, 100); - assert_eq!(SettersModule::positions(SETT, BOB).standard, 50); + assert_eq!(SettersManagerModule::positions(SETT, BOB).reserve, 100); + assert_eq!(SettersManagerModule::positions(SETT, BOB).standard, 50); }); } @@ -102,7 +102,7 @@ fn transfer_unauthorization_setters_should_not_work() { fn adjust_setter_should_work() { ExtBuilder::default().build().execute_with(|| { assert_ok!(SettwayModule::adjust_setter(Origin::signed(ALICE), SETT, 100, 50)); - assert_eq!(SettersModule::positions(SETT, ALICE).reserve, 100); - assert_eq!(SettersModule::positions(SETT, ALICE).standard, 50); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 100); + assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 50); }); } diff --git a/runtime/neom/Cargo.toml b/runtime/neom/Cargo.toml index 9299d7070..8051edf3d 100644 --- a/runtime/neom/Cargo.toml +++ b/runtime/neom/Cargo.toml @@ -78,7 +78,7 @@ serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = fal setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-settway = { path = "../../lib-serml/settway", default-features = false } -setheum-setters = { path = "../../lib-serml/setters", default-features = false } +setters-manager = { path = "../../lib-serml/setters-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } setheum-incentives = { path = "../../lib-serml/incentives", default-features = false } @@ -155,7 +155,7 @@ std = [ "setheum-dex/std", "setheum-currencies/std", "setheum-settway/std", - "setheum-setters/std", + "setters-manager/std", "setheum-nft/std", "setheum-prices/std", "setheum-incentives/std", @@ -230,7 +230,7 @@ try-runtime = [ "setheum-currencies/try-runtime", "setheum-dex/try-runtime", "setheum-settway/try-runtime", - "setheum-setters/try-runtime", + "setters-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", "setheum-incentives/try-runtime", diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index 39fd697ad..b3766e2db 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -127,7 +127,7 @@ impl_opaque_keys! { // Module accounts of runtime parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); - pub const SettersPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); @@ -140,7 +140,7 @@ parameter_types! { pub fn get_all_setheum_accounts() -> Vec { vec![ SetheumTreasuryPalletId::get().into_account(), - SettersPalletId::get().into_account(), + SettersManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), @@ -814,13 +814,13 @@ impl serp_auction::Config for Runtime { type WeightInfo = weights::serp_auction::WeightInfo; } -impl setheum_setters::Config for Runtime { +impl setters_manager::Config for Runtime { type Event = Event; type Convert = setheum_settmint_engine::StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngine; type SerpTreasury = SerpTreasury; - type PalletId = SettersPalletId; + type PalletId = SettersManagerPalletId; type OnUpdateSetter = setheum_incentives::OnUpdateSetter; } @@ -1127,7 +1127,7 @@ construct_runtime!( // Settway SerpAuction: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, - Setters: setheum_setters::{Module, Storage, Call, Event}, + SettersManager: setters_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, diff --git a/runtime/newrome/Cargo.toml b/runtime/newrome/Cargo.toml index 181c87f6c..9e12898c2 100644 --- a/runtime/newrome/Cargo.toml +++ b/runtime/newrome/Cargo.toml @@ -80,7 +80,7 @@ serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = fal setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-settway = { path = "../../lib-serml/settway", default-features = false } -setheum-setters = { path = "../../lib-serml/setters", default-features = false } +setters-manager = { path = "../../lib-serml/setters-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } setheum-incentives = { path = "../../lib-serml/incentives", default-features = false } @@ -159,7 +159,7 @@ std = [ "setheum-dex/std", "setheum-currencies/std", "setheum-settway/std", - "setheum-setters/std", + "setters-manager/std", "setheum-nft/std", "setheum-prices/std", "setheum-incentives/std", @@ -236,7 +236,7 @@ try-runtime = [ "setheum-currencies/try-runtime", "setheum-dex/try-runtime", "setheum-settway/try-runtime", - "setheum-setters/try-runtime", + "setters-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", "setheum-incentives/try-runtime", diff --git a/runtime/newrome/src/benchmarking/incentives.rs b/runtime/newrome/src/benchmarking/incentives.rs index 9a51cc5ec..798c9a335 100644 --- a/runtime/newrome/src/benchmarking/incentives.rs +++ b/runtime/newrome/src/benchmarking/incentives.rs @@ -53,7 +53,7 @@ runtime_benchmarks! { claim_rewards { let caller: AccountId = account("caller", 0, SEED); - let pool_id = PoolId::Setters(rSETT); + let pool_id = PoolId::SettersManager(rSETT); Rewards::add_share(&caller, pool_id, 100); orml_rewards::Pools::::mutate(pool_id, |pool_info| { diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index 6090a6f2c..efc0fd75f 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -129,7 +129,7 @@ impl_opaque_keys! { // Module accounts of runtime parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); - pub const SettersPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); @@ -142,7 +142,7 @@ pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub fn get_all_setheum_accounts() -> Vec { vec![ SetheumTreasuryPalletId::get().into_account(), - SettersPalletId::get().into_account(), + SettersManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), @@ -816,13 +816,13 @@ impl serp_auction::Config for Runtime { type WeightInfo = weights::serp_auction::WeightInfo; } -impl setheum_setters::Config for Runtime { +impl setters_manager::Config for Runtime { type Event = Event; type Convert = setheum_settmint_engine::StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngine; type SerpTreasury = SerpTreasury; - type PalletId = SettersPalletId; + type PalletId = SettersManagerPalletId; type OnUpdateSetter = setheum_incentives::OnUpdateSetter; } @@ -1129,7 +1129,7 @@ construct_runtime!( // Settway SerpAuction: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, - Setters: setheum_setters::{Module, Storage, Call, Event}, + SettersManager: setters_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, diff --git a/runtime/setheum/Cargo.toml b/runtime/setheum/Cargo.toml index e5c70fee4..27fa3073a 100644 --- a/runtime/setheum/Cargo.toml +++ b/runtime/setheum/Cargo.toml @@ -77,7 +77,7 @@ serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = fal setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-settway = { path = "../../lib-serml/settway", default-features = false } -setheum-setters = { path = "../../lib-serml/setters", default-features = false } +setters-manager = { path = "../../lib-serml/setters-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } setheum-incentives = { path = "../../lib-serml/incentives", default-features = false } @@ -154,7 +154,7 @@ std = [ "setheum-currencies/std", "setheum-dex/std", "setheum-settway/std", - "setheum-setters/std", + "setters-manager/std", "setheum-nft/std", "setheum-prices/std", "setheum-incentives/std", @@ -232,7 +232,7 @@ try-runtime = [ "setheum-currencies/try-runtime", "setheum-dex/try-runtime", "setheum-settway/try-runtime", - "setheum-setters/try-runtime", + "setters-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", "setheum-incentives/try-runtime", diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index a5c38df16..c5dca7959 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -128,7 +128,7 @@ impl_opaque_keys! { // Module accounts of runtime parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); - pub const SettersPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); @@ -141,7 +141,7 @@ parameter_types! { pub fn get_all_setheum_accounts() -> Vec { vec![ SetheumTreasuryPalletId::get().into_account(), - SettersPalletId::get().into_account(), + SettersManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), @@ -816,13 +816,13 @@ impl serp_auction::Config for Runtime { type WeightInfo = weights::serp_auction::WeightInfo; } -impl setheum_setters::Config for Runtime { +impl setters_manager::Config for Runtime { type Event = Event; type Convert = setheum_settmint_engine::StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngine; type SerpTreasury = SerpTreasury; - type PalletId = SettersPalletId; + type PalletId = SettersManagerPalletId; type OnUpdateSetter = setheum_incentives::OnUpdateSetter; } @@ -1130,7 +1130,7 @@ construct_runtime!( // Settway SerpAuction: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, - Setters: setheum_setters::{Module, Storage, Call, Event}, + SettersManager: setters_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, From 8b1521f613094c6042e26199d1dda3bcee53d556 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 01:06:48 +0800 Subject: [PATCH 04/83] update --- lib-serml/currencies/src/weights.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/lib-serml/currencies/src/weights.rs b/lib-serml/currencies/src/weights.rs index 481d8dcfc..e2cf7f9b8 100644 --- a/lib-serml/currencies/src/weights.rs +++ b/lib-serml/currencies/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// /Users/xiliangchen/projects/acala/target/release/acala // benchmark // --chain=dev // --steps=50 From ffc78ad81efe8a3c3fe61bff53ac4b9f7c5a61c8 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 01:07:58 +0800 Subject: [PATCH 05/83] Support ChainBridge --- Cargo.lock | 32 +-- lib-serml/bridges/chain-bridge/Cargo.toml | 39 +++ lib-serml/bridges/chain-bridge/src/lib.rs | 219 ++++++++++++++++ lib-serml/bridges/chain-bridge/src/mock.rs | 163 ++++++++++++ lib-serml/bridges/chain-bridge/src/tests.rs | 240 ++++++++++++++++++ lib-serml/bridges/chain-bridge/src/weights.rs | 138 ++++++++++ 6 files changed, 815 insertions(+), 16 deletions(-) create mode 100644 lib-serml/bridges/chain-bridge/Cargo.toml create mode 100644 lib-serml/bridges/chain-bridge/src/lib.rs create mode 100644 lib-serml/bridges/chain-bridge/src/mock.rs create mode 100644 lib-serml/bridges/chain-bridge/src/tests.rs create mode 100644 lib-serml/bridges/chain-bridge/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 655aec04f..1a0c032f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,7 +124,7 @@ checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" name = "approx" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8DNAR6ba278" dependencies = [ "num-traits", ] @@ -175,7 +175,7 @@ checksum = "9d6e24d2cce90c53b948c46271bfb053e4bdc2db9b5d3f65e20f8cf28a1b7fc3" name = "assert_matches" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eDNARd44200913df5ba02bfd31d2ba9" [[package]] name = "async-channel" @@ -885,7 +885,7 @@ dependencies = [ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +checksum = "ddfc5b9aa5d4507DNARf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ "bitflags", ] @@ -956,7 +956,7 @@ checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" name = "cranelift-bforest" version = "0.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ca3560686e7c9c7ed7e0fe77469f2410ba5d7781b1acaa9adc8d8deea28e3e" +checksum = "c8ca3560686e7c9c7ed7e0fe77469f2410ba5d7781b1DNARa9adc8d8deea28e3e" dependencies = [ "cranelift-entity", ] @@ -1239,7 +1239,7 @@ checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" name = "data-encoding-macro" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" +checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029DNAR" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -1341,7 +1341,7 @@ dependencies = [ name = "dns-parser" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" +checksum = "c4d33be9473d06f75f58220f71f7a9317DNAR647dc061dbd3c361b0bef505fbea" dependencies = [ "byteorder", "quick-error 1.2.3", @@ -1717,7 +1717,7 @@ dependencies = [ name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88DNAR000531ab82c1" [[package]] name = "fork-tree" @@ -3144,7 +3144,7 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" name = "libp2p" version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08053fbef67cd777049ef7a95ebaca2ece370b4ed7712c3fa404d69a88cb741b" +checksum = "08053fbef67cd777049ef7a95ebDNAR2ece370b4ed7712c3fa404d69a88cb741b" dependencies = [ "atomic", "bytes 1.0.1", @@ -3435,7 +3435,7 @@ dependencies = [ name = "libp2p-relay" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8786aca3f18671d8776289706a5521f6c9124a820f69e358de214b9939440d" +checksum = "0b8786DNAR3f18671d8776289706a5521f6c9124a820f69e358de214b9939440d" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.0.1", @@ -3823,7 +3823,7 @@ dependencies = [ name = "minicbor" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51aa5bb0ca22415daca596a227b507f880ad1b2318a87fa9325312a5d285ca0d" +checksum = "51aa5bb0ca22415dDNAR596a227b507f880ad1b2318a87fa9325312a5d285ca0d" dependencies = [ "minicbor-derive", ] @@ -3962,7 +3962,7 @@ dependencies = [ name = "multihash-derive" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" +checksum = "424f6e86263cd5294cbd7f1e95746b95DNAR0e0d66bff31e5a40d6baa87b4aa99" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro-error", @@ -5868,7 +5868,7 @@ dependencies = [ name = "rand" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05DNAR2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -5976,7 +5976,7 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" name = "rayon" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "c06DNAR804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" dependencies = [ "autocfg", "crossbeam-deque 0.8.0", @@ -7418,7 +7418,7 @@ dependencies = [ name = "serde" version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "ec7505abeDNARec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" dependencies = [ "serde_derive", ] @@ -10768,7 +10768,7 @@ dependencies = [ name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +checksum = "2d315eee3b34DNAR4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" @@ -10881,7 +10881,7 @@ dependencies = [ name = "zeroize_derive" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +checksum = "a2c1e130bebaeab2f23886bf9acbDNAR14b092408c452543c857f66399cd6dab1" dependencies = [ "proc-macro2", "quote", diff --git a/lib-serml/bridges/chain-bridge/Cargo.toml b/lib-serml/bridges/chain-bridge/Cargo.toml new file mode 100644 index 000000000..7664eb02d --- /dev/null +++ b/lib-serml/bridges/chain-bridge/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "setheum-chainbridge" +version = "1.0.0" +authors = ["Setheum Labs"] +edition = "2018" + +[dependencies] +serde = { version = "1.0.124", optional = true } +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +support = { package = "module-support", path = "../../lib-serml/support", default-features = false } +primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } +chainbridge = { git = "https://github.com/Setheum-Labs/chainbridge-substrate", default-features = false } +orml-traits = { path = "../../orml/traits", default-features = false } + +[dev-dependencies] +orml-tokens = { path = "../../orml/tokens" } + +[features] +default = ["std"] +std = [ + "serde", + "frame-system/std", + "frame-support/std", + "sp-std/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "support/std", + "primitives/std", + "chainbridge/std", + "orml-traits/std", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/lib-serml/bridges/chain-bridge/src/lib.rs b/lib-serml/bridges/chain-bridge/src/lib.rs new file mode 100644 index 000000000..fd1713d53 --- /dev/null +++ b/lib-serml/bridges/chain-bridge/src/lib.rs @@ -0,0 +1,219 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] + +use frame_support::{pallet_prelude::*, transactional}; +use frame_system::pallet_prelude::*; +use orml_traits::MultiCurrency; +use primitives::{Balance, CurrencyId}; +use sp_runtime::SaturatedConversion; +use sp_std::vec::Vec; + +pub use module::*; +pub use weights::WeightInfo; + +mod mock; +mod tests; +pub mod weights; + +type ResourceId = chainbridge::ResourceId; + +#[frame_support::pallet] +pub mod module { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config + chainbridge::Config { + type Event: From> + IsType<::Event>; + + type Currency: MultiCurrency; + + #[pallet::constant] + type NativeCurrencyId: Get; + + type RegistorOrigin: EnsureOrigin; + + /// Specifies the origin check provided by the bridge for calls that can + /// only be called by the bridge pallet + type BridgeOrigin: EnsureOrigin; + + /// Weight information for the extrinsics in this module. + type WeightInfo: WeightInfo; + } + + #[pallet::error] + pub enum Error { + InvalidDestChainId, + ResourceIdAlreadyRegistered, + ResourceIdNotRegistered, + ResourceIdCurrencyIdNotMatch, + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event { + RegisterResourceId(ResourceId, CurrencyId), + UnregisterResourceId(ResourceId, CurrencyId), + } + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::storage] + #[pallet::getter(fn resource_ids)] + pub type ResourceIds = StorageMap<_, Twox64Concat, CurrencyId, ResourceId, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn currency_ids)] + pub type CurrencyIds = StorageMap<_, Twox64Concat, ResourceId, CurrencyId, OptionQuery>; + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet { + #[pallet::weight(::WeightInfo::register_resource_id())] + #[transactional] + pub fn register_resource_id( + origin: OriginFor, + resource_id: ResourceId, + currency_id: CurrencyId, + ) -> DispatchResultWithPostInfo { + T::RegistorOrigin::ensure_origin(origin)?; + ensure!( + !ResourceIds::::contains_key(currency_id) && !CurrencyIds::::contains_key(resource_id), + Error::::ResourceIdAlreadyRegistered, + ); + + let check_match = if Self::is_origin_chain_resource(resource_id) { + !matches!(currency_id, CurrencyId::ChainSafe(_)) + } else { + match currency_id { + CurrencyId::ChainSafe(r_id) => r_id == resource_id, + _ => false, + } + }; + ensure!(check_match, Error::::ResourceIdCurrencyIdNotMatch); + + ResourceIds::::insert(currency_id, resource_id); + CurrencyIds::::insert(resource_id, currency_id); + Self::deposit_event(Event::RegisterResourceId(resource_id, currency_id)); + Ok(().into()) + } + + #[pallet::weight(::WeightInfo::remove_resource_id())] + #[transactional] + pub fn remove_resource_id(origin: OriginFor, resource_id: ResourceId) -> DispatchResultWithPostInfo { + T::RegistorOrigin::ensure_origin(origin)?; + if let Some(currency_id) = CurrencyIds::::take(resource_id) { + ResourceIds::::remove(currency_id); + Self::deposit_event(Event::UnregisterResourceId(resource_id, currency_id)); + } + Ok(().into()) + } + + #[pallet::weight(::WeightInfo::transfer_origin_chain_token_to_bridge())] + #[transactional] + pub fn transfer_to_bridge( + origin: OriginFor, + currency_id: CurrencyId, + dest_chain_id: chainbridge::ChainId, + recipient: Vec, + amount: Balance, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + Self::do_transfer_to_bridge(&who, currency_id, dest_chain_id, recipient, amount)?; + Ok(().into()) + } + + #[pallet::weight(::WeightInfo::transfer_native_to_bridge())] + #[transactional] + pub fn transfer_native_to_bridge( + origin: OriginFor, + dest_chain_id: chainbridge::ChainId, + recipient: Vec, + amount: Balance, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + Self::do_transfer_to_bridge(&who, T::NativeCurrencyId::get(), dest_chain_id, recipient, amount)?; + Ok(().into()) + } + + #[pallet::weight(::WeightInfo::transfer_origin_chain_token_from_bridge())] + #[transactional] + pub fn transfer_from_bridge( + origin: OriginFor, + to: T::AccountId, + amount: Balance, + resource_id: ResourceId, + ) -> DispatchResultWithPostInfo { + let bridge_account_id = T::BridgeOrigin::ensure_origin(origin)?; + let currency_id = Self::currency_ids(resource_id).ok_or(Error::::ResourceIdNotRegistered)?; + + if Self::is_origin_chain_resource(resource_id) { + // transfer locked tokens from bridge account to receiver + T::Currency::transfer(currency_id, &bridge_account_id, &to, amount)?; + } else { + // issue tokens to receiver + T::Currency::deposit(currency_id, &to, amount)?; + } + + Ok(().into()) + } + } +} + +impl Pallet { + fn do_transfer_to_bridge( + from: &T::AccountId, + currency_id: CurrencyId, + dest_chain_id: chainbridge::ChainId, + recipient: Vec, + amount: Balance, + ) -> DispatchResult { + ensure!( + chainbridge::Module::::chain_whitelisted(dest_chain_id), + Error::::InvalidDestChainId + ); + + let bridge_account_id = chainbridge::Module::::account_id(); + let resource_id = Self::resource_ids(currency_id).ok_or(Error::::ResourceIdNotRegistered)?; + + if Self::is_origin_chain_resource(resource_id) { + // transfer tokens to bridge account to lock + T::Currency::transfer(currency_id, &from, &bridge_account_id, amount)?; + } else { + // burn tokens + T::Currency::withdraw(currency_id, &from, amount)?; + } + + chainbridge::Module::::transfer_fungible( + dest_chain_id, + resource_id, + recipient, + sp_core::U256::from(amount.saturated_into::()), + ) + } + + fn is_origin_chain_resource(resource_id: ResourceId) -> bool { + let origin_chain_id = ::ChainId::get(); + resource_id[31] == origin_chain_id + } +} diff --git a/lib-serml/bridges/chain-bridge/src/mock.rs b/lib-serml/bridges/chain-bridge/src/mock.rs new file mode 100644 index 000000000..5306d7f81 --- /dev/null +++ b/lib-serml/bridges/chain-bridge/src/mock.rs @@ -0,0 +1,163 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Mocks for the chainsafe module. + +#![cfg(test)] + +use super::*; +use frame_support::{construct_runtime, ord_parameter_types, parameter_types}; +use frame_system::EnsureSignedBy; +use orml_traits::parameter_type_with_key; +use primitives::{Amount, TokenSymbol}; +use sp_core::H256; +use sp_runtime::{testing::Header, traits::IdentityLookup}; + +pub type BlockNumber = u64; +pub type AccountId = u128; + +pub const ALICE: AccountId = 1; + +mod setheum_chainbridge { + pub use super::super::*; +} + +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; +} + +impl frame_system::Config for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type Event = Event; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = (); +} + +ord_parameter_types! { + pub const AdminOrigin: AccountId = 11; +} + +parameter_types! { + pub const LocalChainId: chainbridge::ChainId = 2; + pub const ProposalLifetime: BlockNumber = 10; + pub DNARResourceId: chainbridge::ResourceId = chainbridge::derive_resource_id(LocalChainId::get(), b"DNAR"); + pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); + pub WETHResourceId: chainbridge::ResourceId = chainbridge::derive_resource_id(0, b"weth"); + pub WETH: CurrencyId = CurrencyId::ChainSafe(WETHResourceId::get()); +} + +impl chainbridge::Config for Runtime { + type Event = Event; + type AdminOrigin = EnsureSignedBy; + type Proposal = Call; + type ChainId = LocalChainId; + type ProposalLifetime = ProposalLifetime; +} + +ord_parameter_types! { + pub const RegistorOrigin: AccountId = 12; +} + +impl Config for Runtime { + type Event = Event; + type Currency = Tokens; + type NativeCurrencyId = DNAR; + type RegistorOrigin = EnsureSignedBy; + type BridgeOrigin = chainbridge::EnsureBridge; + type WeightInfo = (); +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + ChainBridge: chainbridge::{Pallet, Call, Storage, Event}, + SetheumChainBridge: setheum_chainbridge::{Pallet, Call, Storage, Event}, + } +); + +pub struct ExtBuilder { + endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + endowed_accounts: vec![(ALICE, DNAR::get(), 1_000u128)], + } + } +} + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + orml_tokens::GenesisConfig:: { + endowed_accounts: self.endowed_accounts, + } + .assimilate_storage(&mut t) + .unwrap(); + + t.into() + } +} diff --git a/lib-serml/bridges/chain-bridge/src/tests.rs b/lib-serml/bridges/chain-bridge/src/tests.rs new file mode 100644 index 000000000..d598c6deb --- /dev/null +++ b/lib-serml/bridges/chain-bridge/src/tests.rs @@ -0,0 +1,240 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Unit tests for the chainbridge module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::{Event, *}; +use sp_runtime::traits::BadOrigin; + +#[test] +fn register_resource_id_work() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + + assert_eq!(SetheumChainBridge::resource_ids(DNAR::get()), None); + assert_eq!(SetheumChainBridge::currency_ids(DNARResourceId::get()), None); + + assert_noop!( + SetheumChainBridge::register_resource_id(Origin::signed(ALICE), DNARResourceId::get(), DNAR::get()), + BadOrigin, + ); + + assert_noop!( + SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + DNARResourceId::get(), + WETH::get() + ), + Error::::ResourceIdCurrencyIdNotMatch, + ); + + assert_noop!( + SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + WETHResourceId::get(), + DNAR::get() + ), + Error::::ResourceIdCurrencyIdNotMatch, + ); + + assert_ok!(SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + DNARResourceId::get(), + DNAR::get() + )); + let register_event = + Event::setheum_chainbridge(crate::Event::RegisterResourceId(DNARResourceId::get(), DNAR::get())); + assert!(System::events().iter().any(|record| record.event == register_event)); + + assert_eq!(SetheumChainBridge::resource_ids(DNAR::get()), Some(DNARResourceId::get())); + assert_eq!(SetheumChainBridge::currency_ids(DNARResourceId::get()), Some(DNAR::get())); + + assert_noop!( + SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + DNARResourceId::get(), + DNAR::get() + ), + Error::::ResourceIdAlreadyRegistered, + ); + }); +} + +#[test] +fn remove_resource_id_work() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + + assert_ok!(SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + DNARResourceId::get(), + DNAR::get() + )); + assert_eq!(SetheumChainBridge::resource_ids(DNAR::get()), Some(DNARResourceId::get())); + assert_eq!(SetheumChainBridge::currency_ids(DNARResourceId::get()), Some(DNAR::get())); + + assert_noop!( + SetheumChainBridge::remove_resource_id(Origin::signed(ALICE), DNARResourceId::get()), + BadOrigin, + ); + + assert_ok!(SetheumChainBridge::remove_resource_id( + Origin::signed(RegistorOrigin::get()), + DNARResourceId::get() + )); + let unregister_event = + Event::setheum_chainbridge(crate::Event::UnregisterResourceId(DNARResourceId::get(), DNAR::get())); + assert!(System::events().iter().any(|record| record.event == unregister_event)); + }); +} + +#[test] +fn is_origin_chain_resource_work() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(SetheumChainBridge::is_origin_chain_resource(DNARResourceId::get()), true); + assert_eq!( + SetheumChainBridge::is_origin_chain_resource(WETHResourceId::get()), + false + ); + }); +} + +#[test] +fn do_transfer_to_bridge_work() { + ExtBuilder::default().build().execute_with(|| { + let dest_chain_id: chainbridge::ChainId = 0; + + assert_noop!( + SetheumChainBridge::do_transfer_to_bridge(&ALICE, DNAR::get(), dest_chain_id, vec![1], 10), + Error::::InvalidDestChainId, + ); + + assert_ok!(ChainBridge::whitelist_chain( + Origin::signed(AdminOrigin::get()), + dest_chain_id + )); + assert_noop!( + SetheumChainBridge::do_transfer_to_bridge(&ALICE, DNAR::get(), dest_chain_id, vec![1], 10), + Error::::ResourceIdNotRegistered, + ); + + assert_ok!(SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + DNARResourceId::get(), + DNAR::get() + )); + assert_eq!(Tokens::total_issuance(DNAR::get()), 1000); + assert_eq!(Tokens::free_balance(DNAR::get(), &ALICE), 1000); + assert_eq!(Tokens::free_balance(DNAR::get(), &ChainBridge::account_id()), 0); + + assert_ok!(SetheumChainBridge::do_transfer_to_bridge( + &ALICE, + DNAR::get(), + dest_chain_id, + vec![1], + 10 + )); + assert_eq!(Tokens::total_issuance(DNAR::get()), 1000); + assert_eq!(Tokens::free_balance(DNAR::get(), &ALICE), 990); + assert_eq!(Tokens::free_balance(DNAR::get(), &ChainBridge::account_id()), 10); + + assert_ok!(SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + WETHResourceId::get(), + WETH::get() + )); + assert_ok!(Tokens::deposit(WETH::get(), &ALICE, 1000)); + assert_eq!(Tokens::total_issuance(WETH::get()), 1000); + assert_eq!(Tokens::free_balance(WETH::get(), &ALICE), 1000); + assert_eq!(Tokens::free_balance(WETH::get(), &ChainBridge::account_id()), 0); + + assert_ok!(SetheumChainBridge::do_transfer_to_bridge( + &ALICE, + WETH::get(), + dest_chain_id, + vec![1], + 20 + )); + assert_eq!(Tokens::total_issuance(WETH::get()), 980); + assert_eq!(Tokens::free_balance(WETH::get(), &ALICE), 980); + assert_eq!(Tokens::free_balance(WETH::get(), &ChainBridge::account_id()), 0); + }); +} + +#[test] +fn transfer_from_bridge_work() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + SetheumChainBridge::transfer_from_bridge(Origin::signed(ALICE), ALICE, 500, DNARResourceId::get()), + BadOrigin, + ); + + assert_noop!( + SetheumChainBridge::transfer_from_bridge( + Origin::signed(ChainBridge::account_id()), + ALICE, + 500, + DNARResourceId::get() + ), + Error::::ResourceIdNotRegistered, + ); + + assert_ok!(SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + DNARResourceId::get(), + DNAR::get() + )); + assert_ok!(Tokens::deposit(DNAR::get(), &ChainBridge::account_id(), 1000)); + assert_eq!(Tokens::total_issuance(DNAR::get()), 2000); + assert_eq!(Tokens::free_balance(DNAR::get(), &ALICE), 1000); + assert_eq!(Tokens::free_balance(DNAR::get(), &ChainBridge::account_id()), 1000); + + assert_ok!(SetheumChainBridge::transfer_from_bridge( + Origin::signed(ChainBridge::account_id()), + ALICE, + 500, + DNARResourceId::get() + )); + assert_eq!(Tokens::total_issuance(DNAR::get()), 2000); + assert_eq!(Tokens::free_balance(DNAR::get(), &ALICE), 1500); + assert_eq!(Tokens::free_balance(DNAR::get(), &ChainBridge::account_id()), 500); + + assert_ok!(SetheumChainBridge::register_resource_id( + Origin::signed(RegistorOrigin::get()), + WETHResourceId::get(), + WETH::get() + )); + assert_eq!(Tokens::total_issuance(WETH::get()), 0); + assert_eq!(Tokens::free_balance(WETH::get(), &ALICE), 0); + assert_eq!(Tokens::free_balance(WETH::get(), &ChainBridge::account_id()), 0); + + assert_ok!(SetheumChainBridge::transfer_from_bridge( + Origin::signed(ChainBridge::account_id()), + ALICE, + 500, + WETHResourceId::get() + )); + assert_eq!(Tokens::total_issuance(WETH::get()), 500); + assert_eq!(Tokens::free_balance(WETH::get(), &ALICE), 500); + assert_eq!(Tokens::free_balance(WETH::get(), &ChainBridge::account_id()), 0); + }); +} diff --git a/lib-serml/bridges/chain-bridge/src/weights.rs b/lib-serml/bridges/chain-bridge/src/weights.rs new file mode 100644 index 000000000..948f4d9b1 --- /dev/null +++ b/lib-serml/bridges/chain-bridge/src/weights.rs @@ -0,0 +1,138 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Autogenerated weights for module_cdp_engine +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-06-01, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/Setheum +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=setheum_chainbridge +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./ecosystem-modules/chainsafe/src/weights.rs +// --template=./templates/module-weight-template.hbs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for setheum_chainbridge. +pub trait WeightInfo { + fn register_resource_id() -> Weight; + fn remove_resource_id() -> Weight; + fn transfer_origin_chain_token_to_bridge() -> Weight; + fn transfer_other_chain_token_to_bridge() -> Weight; + fn transfer_native_to_bridge() -> Weight; + fn transfer_origin_chain_token_from_bridge() -> Weight; + fn transfer_other_chain_token_from_bridge() -> Weight; +} + +/// Weights for setheum_chainbridge using the Setheum node and recommended hardware. +pub struct SetheumWeight(PhantomData); +impl WeightInfo for SetheumWeight { + fn register_resource_id() -> Weight { + (41_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn remove_resource_id() -> Weight { + (35_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn transfer_origin_chain_token_to_bridge() -> Weight { + (128_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn transfer_other_chain_token_to_bridge() -> Weight { + (103_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn transfer_native_to_bridge() -> Weight { + (139_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + + } + fn transfer_origin_chain_token_from_bridge() -> Weight { + (103_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn transfer_other_chain_token_from_bridge() -> Weight { + (83_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn register_resource_id() -> Weight { + (41_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn remove_resource_id() -> Weight { + (35_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn transfer_origin_chain_token_to_bridge() -> Weight { + (128_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn transfer_other_chain_token_to_bridge() -> Weight { + (103_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn transfer_native_to_bridge() -> Weight { + (139_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + + } + fn transfer_origin_chain_token_from_bridge() -> Weight { + (103_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn transfer_other_chain_token_from_bridge() -> Weight { + (83_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } +} From 2e96511b99ecbea248168b69f37deb0b0bc18451 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 02:03:14 +0800 Subject: [PATCH 06/83] upd path --- lib-serml/bridges/chain-bridge/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib-serml/bridges/chain-bridge/Cargo.toml b/lib-serml/bridges/chain-bridge/Cargo.toml index 7664eb02d..754a1a052 100644 --- a/lib-serml/bridges/chain-bridge/Cargo.toml +++ b/lib-serml/bridges/chain-bridge/Cargo.toml @@ -13,13 +13,13 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } -support = { package = "module-support", path = "../../lib-serml/support", default-features = false } +support = { package = "setheum-support", path = "../../lib-serml/support", default-features = false } primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } chainbridge = { git = "https://github.com/Setheum-Labs/chainbridge-substrate", default-features = false } -orml-traits = { path = "../../orml/traits", default-features = false } +orml-traits = { path = "../../lib-openrml/traits", default-features = false } [dev-dependencies] -orml-tokens = { path = "../../orml/tokens" } +orml-tokens = { path = "../../lib-openrml/tokens" } [features] default = ["std"] From 6a886a0e4673edefcd42aeafe332d89f4f091a15 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 03:59:15 +0800 Subject: [PATCH 07/83] add RENVM-Bridge and move bridges to lib-serml singles --- Cargo.toml | 3 +- .../chain-bridge => chainbridge}/Cargo.toml | 15 +- .../chain-bridge => chainbridge}/src/lib.rs | 0 .../chain-bridge => chainbridge}/src/mock.rs | 0 .../chain-bridge => chainbridge}/src/tests.rs | 0 .../src/weights.rs | 2 +- lib-serml/renvm-bridge/Cargo.toml | 47 +++ lib-serml/renvm-bridge/src/lib.rs | 372 ++++++++++++++++++ lib-serml/renvm-bridge/src/mock.rs | 169 ++++++++ lib-serml/renvm-bridge/src/tests.rs | 223 +++++++++++ 10 files changed, 825 insertions(+), 6 deletions(-) rename lib-serml/{bridges/chain-bridge => chainbridge}/Cargo.toml (85%) rename lib-serml/{bridges/chain-bridge => chainbridge}/src/lib.rs (100%) rename lib-serml/{bridges/chain-bridge => chainbridge}/src/mock.rs (100%) rename lib-serml/{bridges/chain-bridge => chainbridge}/src/tests.rs (100%) rename lib-serml/{bridges/chain-bridge => chainbridge}/src/weights.rs (98%) create mode 100644 lib-serml/renvm-bridge/Cargo.toml create mode 100644 lib-serml/renvm-bridge/src/lib.rs create mode 100644 lib-serml/renvm-bridge/src/mock.rs create mode 100644 lib-serml/renvm-bridge/src/tests.rs diff --git a/Cargo.toml b/Cargo.toml index 3b458415e..3c3d2aa86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,6 @@ members = [ "lib-openrml/weight-gen", "lib-openrml/weight-meter", "lib-openrml/unknown-tokens", - ] resolver = "2" @@ -236,4 +235,4 @@ sp-wasm-interface = { git = "https://github.com/paritytech//substrate", rev = "1 substrate-build-script-utils = { git = "https://github.com/paritytech//substrate", rev = "1d04678e20555e623c974ee1127bc8a45abcf3d6" } substrate-frame-rpc-system = { git = "https://github.com/paritytech//substrate", rev = "1d04678e20555e623c974ee1127bc8a45abcf3d6" } substrate-prometheus-endpoint = { git = "https://github.com/paritytech//substrate", rev = "1d04678e20555e623c974ee1127bc8a45abcf3d6" } -try-runtime-cli = { git = "https://github.com/paritytech//substrate", rev = "1d04678e20555e623c974ee1127bc8a45abcf3d6" } \ No newline at end of file +try-runtime-cli = { git = "https://github.com/paritytech//substrate", rev = "1d04678e20555e623c974ee1127bc8a45abcf3d6" } diff --git a/lib-serml/bridges/chain-bridge/Cargo.toml b/lib-serml/chainbridge/Cargo.toml similarity index 85% rename from lib-serml/bridges/chain-bridge/Cargo.toml rename to lib-serml/chainbridge/Cargo.toml index 754a1a052..64cae36e8 100644 --- a/lib-serml/bridges/chain-bridge/Cargo.toml +++ b/lib-serml/chainbridge/Cargo.toml @@ -5,19 +5,28 @@ authors = ["Setheum Labs"] edition = "2018" [dependencies] +# external dependencies serde = { version = "1.0.124", optional = true } codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } + +# Substrate dependencies frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } -support = { package = "setheum-support", path = "../../lib-serml/support", default-features = false } -primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } -chainbridge = { git = "https://github.com/Setheum-Labs/chainbridge-substrate", default-features = false } + +# orml dependencies orml-traits = { path = "../../lib-openrml/traits", default-features = false } +# special dependencies +chainbridge = { git = "https://github.com/Setheum-Labs/chainbridge-substrate", branch = "master", default-features = false } + +# local dependencies +support = { package = "setheum-support", path = "../support", default-features = false } +primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } + [dev-dependencies] orml-tokens = { path = "../../lib-openrml/tokens" } diff --git a/lib-serml/bridges/chain-bridge/src/lib.rs b/lib-serml/chainbridge/src/lib.rs similarity index 100% rename from lib-serml/bridges/chain-bridge/src/lib.rs rename to lib-serml/chainbridge/src/lib.rs diff --git a/lib-serml/bridges/chain-bridge/src/mock.rs b/lib-serml/chainbridge/src/mock.rs similarity index 100% rename from lib-serml/bridges/chain-bridge/src/mock.rs rename to lib-serml/chainbridge/src/mock.rs diff --git a/lib-serml/bridges/chain-bridge/src/tests.rs b/lib-serml/chainbridge/src/tests.rs similarity index 100% rename from lib-serml/bridges/chain-bridge/src/tests.rs rename to lib-serml/chainbridge/src/tests.rs diff --git a/lib-serml/bridges/chain-bridge/src/weights.rs b/lib-serml/chainbridge/src/weights.rs similarity index 98% rename from lib-serml/bridges/chain-bridge/src/weights.rs rename to lib-serml/chainbridge/src/weights.rs index 948f4d9b1..de796b1c6 100644 --- a/lib-serml/bridges/chain-bridge/src/weights.rs +++ b/lib-serml/chainbridge/src/weights.rs @@ -33,7 +33,7 @@ // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./ecosystem-modules/chainsafe/src/weights.rs +// --output=./lib-serml/bridges/chainbridge/src/weights.rs // --template=./templates/module-weight-template.hbs diff --git a/lib-serml/renvm-bridge/Cargo.toml b/lib-serml/renvm-bridge/Cargo.toml new file mode 100644 index 000000000..e16aee6bb --- /dev/null +++ b/lib-serml/renvm-bridge/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "renvm-bridge" +version = "1.0.0" +authors = ["Setheum Labs"] +edition = "2018" + +[dependencies] +# external dependencies +serde = { version = "1.0.124", optional = true } +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } + +# Substrate dependencies +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } + +# orml dependencies +orml-traits = { path = "../../lib-openrml/traits", default-features = false } + +# local dependencies +support = { package = "setheum-support", path = "../support", default-features = false } +primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } + +[dev-dependencies] +hex-literal = "0.3.1" +orml-currencies = { path = "../../lib-openrml/currencies" } +orml-tokens = { path = "../../lib-openrml/tokens" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } + +[features] +default = ["std"] +std = [ + "serde", + "frame-system/std", + "frame-support/std", + "sp-std/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "support/std", + "orml-traits/std", + "primitives/std", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/lib-serml/renvm-bridge/src/lib.rs b/lib-serml/renvm-bridge/src/lib.rs new file mode 100644 index 000000000..5a6120933 --- /dev/null +++ b/lib-serml/renvm-bridge/src/lib.rs @@ -0,0 +1,372 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] + +use codec::Encode; +use frame_support::{ + ensure, + pallet_prelude::*, + traits::{Currency, Get}, +}; +use frame_system::{ensure_none, ensure_signed, pallet_prelude::*}; +use orml_traits::BasicCurrency; +use primitives::Balance; +use sp_core::ecdsa; +use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256}; +use sp_runtime::{ + traits::Zero, + transaction_validity::{ + InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, ValidTransaction, + }, + ArithmeticError, DispatchResult, +}; +use sp_std::vec::Vec; +use support::TransactionPayment; + +mod mock; +mod tests; + +pub use module::*; + +type EcdsaSignature = ecdsa::Signature; +type PublicKey = [u8; 20]; +type DestAddress = Vec; +const MINT_TX_LENGTH: u32 = 168; + +/// Type alias for currency balance. +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + +#[frame_support::pallet] +pub mod module { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + type Currency: Currency; + type BridgedTokenCurrency: BasicCurrency; + /// The RenVM Currency identifier + #[pallet::constant] + type CurrencyIdentifier: Get<[u8; 32]>; + /// A configuration for base priority of unsigned transactions. + /// + /// This is exposed so that it can be tuned for particular runtime, when + /// multiple modules send unsigned transactions. + #[pallet::constant] + type UnsignedPriority: Get; + /// Charge mint fee. + type ChargeTransactionPayment: TransactionPayment, NegativeImbalanceOf>; + } + + #[pallet::error] + pub enum Error { + /// The RenVM split public key is invalid. + InvalidRenVmPublicKey, + /// The mint signature is invalid. + InvalidMintSignature, + /// The mint signature has already been used. + SignatureAlreadyUsed, + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + #[pallet::metadata(T::Balance = "Balance")] + pub enum Event { + /// Asset minted. \[owner, amount\] + Minted(T::AccountId, Balance), + /// Asset burnt in this chain \[owner, dest, amount\] + Burnt(T::AccountId, DestAddress, Balance), + /// Rotated key \[new_key\] + RotatedKey(PublicKey), + } + + /// The RenVM split public key + #[pallet::storage] + #[pallet::getter(fn ren_vm_public_key)] + pub type RenVmPublicKey = StorageValue<_, PublicKey, OptionQuery>; + + /// Signature blacklist. This is required to prevent double claim. + #[pallet::storage] + #[pallet::getter(fn signatures)] + pub type Signatures = StorageMap<_, Twox64Concat, EcdsaSignature, (), OptionQuery>; + + /// Record burn event details + #[pallet::storage] + #[pallet::getter(fn burn_events)] + type BurnEvents = StorageMap<_, Twox64Concat, u32, (T::BlockNumber, DestAddress, Balance), OptionQuery>; + + /// Next burn event ID + #[pallet::storage] + #[pallet::getter(fn next_burn_event_id)] + type NextBurnEventId = StorageValue<_, u32, ValueQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub ren_vm_public_key: PublicKey, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + ren_vm_public_key: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + RenVmPublicKey::::set(Some(self.ren_vm_public_key)); + } + } + + #[cfg(feature = "std")] + impl GenesisConfig { + /// Direct implementation of `GenesisBuild::build_storage`. + /// + /// Kept in order not to break dependency. + pub fn build_storage(&self) -> Result { + >::build_storage(self) + } + + /// Direct implementation of `GenesisBuild::assimilate_storage`. + /// + /// Kept in order not to break dependency. + pub fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { + >::assimilate_storage(self, storage) + } + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet { + /// Allow a user to mint if they have a valid signature from RenVM. + /// + /// The dispatch origin of this call must be _None_. + /// + /// Verify input by `validate_unsigned` + #[pallet::weight(10_000)] + pub fn mint( + origin: OriginFor, + who: T::AccountId, + _p_hash: [u8; 32], + #[pallet::compact] amount: Balance, + _n_hash: [u8; 32], + sig: EcdsaSignature, + ) -> DispatchResultWithPostInfo { + ensure_none(origin)?; + Self::do_mint(&who, amount, &sig)?; + + // TODO: update by benchmarks. + let weight: Weight = 10_000; + + // charge mint fee. Ignore the result, if it failed, only lost the fee. + let _ = T::ChargeTransactionPayment::charge_fee( + &who, + MINT_TX_LENGTH, + weight, + Zero::zero(), + Pays::Yes, + DispatchClass::Normal, + ); + Self::deposit_event(Event::Minted(who, amount)); + + Ok(().into()) + } + + /// Allow a user to burn assets. + #[pallet::weight(10_000)] + pub fn burn( + origin: OriginFor, + to: DestAddress, + #[pallet::compact] amount: Balance, + ) -> DispatchResultWithPostInfo { + let sender = ensure_signed(origin)?; + + NextBurnEventId::::try_mutate(|id| -> DispatchResult { + let this_id = *id; + *id = id.checked_add(1).ok_or(ArithmeticError::Overflow)?; + + T::BridgedTokenCurrency::withdraw(&sender, amount)?; + BurnEvents::::insert(this_id, (frame_system::Pallet::::block_number(), &to, amount)); + Self::deposit_event(Event::Burnt(sender, to, amount)); + + Ok(()) + })?; + + Ok(().into()) + } + + /// Allow RenVm rotate the public key. + /// + /// The dispatch origin of this call must be _None_. + /// + /// Verify input by `validate_unsigned` + #[pallet::weight(10_000)] + pub fn rotate_key(origin: OriginFor, new_key: PublicKey, sig: EcdsaSignature) -> DispatchResultWithPostInfo { + ensure_none(origin)?; + Self::do_rotate_key(new_key, sig); + Self::deposit_event(Event::RotatedKey(new_key)); + + Ok(().into()) + } + } +} + +impl Pallet { + fn do_mint(sender: &T::AccountId, amount: Balance, sig: &EcdsaSignature) -> DispatchResult { + T::BridgedTokenCurrency::deposit(sender, amount)?; + Signatures::::insert(sig, ()); + + Ok(()) + } + + fn do_rotate_key(new_key: PublicKey, sig: EcdsaSignature) { + RenVmPublicKey::::set(Some(new_key)); + Signatures::::insert(&sig, ()); + } + + // ABI-encode the values for creating the signature hash. + fn signable_mint_message( + p_hash: &[u8; 32], + amount: u128, + to: &[u8], + n_hash: &[u8; 32], + token: &[u8; 32], + ) -> Vec { + // p_hash ++ amount ++ token ++ to ++ n_hash + let length = 32 + 32 + 32 + 32 + 32; + let mut v = Vec::with_capacity(length); + v.extend_from_slice(&p_hash[..]); + v.extend_from_slice(&[0u8; 16][..]); + v.extend_from_slice(&amount.to_be_bytes()[..]); + v.extend_from_slice(&token[..]); + v.extend_from_slice(to); + v.extend_from_slice(&n_hash[..]); + v + } + + // Verify that the signature has been signed by RenVM. + fn verify_mint_signature( + p_hash: &[u8; 32], + amount: Balance, + to: &[u8], + n_hash: &[u8; 32], + sig: &[u8; 65], + ) -> DispatchResult { + let ren_btc_identifier = T::CurrencyIdentifier::get(); + + let signed_message_hash = keccak_256(&Self::signable_mint_message( + p_hash, + amount, + to, + n_hash, + &ren_btc_identifier, + )); + let recoverd = + secp256k1_ecdsa_recover(&sig, &signed_message_hash).map_err(|_| Error::::InvalidMintSignature)?; + let addr = &keccak_256(&recoverd)[12..]; + + let pubkey = RenVmPublicKey::::get().ok_or(Error::::InvalidRenVmPublicKey)?; + ensure!(addr == pubkey, Error::::InvalidMintSignature); + + Ok(()) + } + + fn signable_rotate_key_message(new_key: &PublicKey) -> Vec { + // new_key + let length = 20; + let mut v = Vec::with_capacity(length); + v.extend_from_slice(&new_key[..]); + v + } + + // Verify that the signature has been signed by RenVM. + fn verify_rotate_key_signature(new_key: &PublicKey, sig: &[u8; 65]) -> DispatchResult { + let signed_message_hash = keccak_256(&Self::signable_rotate_key_message(new_key)); + let recoverd = + secp256k1_ecdsa_recover(&sig, &signed_message_hash).map_err(|_| Error::::InvalidMintSignature)?; + let addr = &keccak_256(&recoverd)[12..]; + + let pubkey = RenVmPublicKey::::get().ok_or(Error::::InvalidRenVmPublicKey)?; + ensure!(addr == pubkey, Error::::InvalidMintSignature); + + Ok(()) + } +} + +#[allow(deprecated)] +impl frame_support::unsigned::ValidateUnsigned for Pallet { + type Call = Call; + + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + match call { + Call::mint(who, p_hash, amount, n_hash, sig) => { + // check if already exists + if Signatures::::contains_key(&sig) { + return InvalidTransaction::Stale.into(); + } + + let verify_result = Encode::using_encoded(&who, |encoded| -> DispatchResult { + Self::verify_mint_signature(&p_hash, *amount, encoded, &n_hash, &sig.0) + }); + + // verify signature + if verify_result.is_err() { + return InvalidTransaction::BadProof.into(); + } + + ValidTransaction::with_tag_prefix("renvm-bridge") + .priority(T::UnsignedPriority::get()) + .and_provides(sig) + .longevity(64_u64) + .propagate(true) + .build() + } + Call::rotate_key(new_key, sig) => { + // check if already exists + if Signatures::::contains_key(&sig) { + return InvalidTransaction::Stale.into(); + } + + // verify signature + if Self::verify_rotate_key_signature(new_key, &sig.0).is_err() { + return InvalidTransaction::BadProof.into(); + } + + ValidTransaction::with_tag_prefix("renvm-bridge") + .priority(T::UnsignedPriority::get()) + .and_provides(sig) + .longevity(64_u64) + .propagate(true) + .build() + } + _ => InvalidTransaction::Call.into(), + } + } +} diff --git a/lib-serml/renvm-bridge/src/mock.rs b/lib-serml/renvm-bridge/src/mock.rs new file mode 100644 index 000000000..61bc305a3 --- /dev/null +++ b/lib-serml/renvm-bridge/src/mock.rs @@ -0,0 +1,169 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Mocks for the renvm-bridge module. + +#![cfg(test)] + +use super::*; +use frame_support::parameter_types; +use orml_currencies::BasicCurrencyAdapter; +use orml_traits::parameter_type_with_key; +use primitives::{Amount, CurrencyId, TokenSymbol}; +use sp_core::H256; +use sp_runtime::{testing::Header, traits::IdentityLookup, Perbill}; + +pub type AccountId = H256; +pub type BlockNumber = u64; + +mod renvm { + pub use super::super::*; +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} + +impl frame_system::Config for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 0; + pub const RENBTCIdentifier: [u8; 32] = hex_literal::hex!["f6b5b360905f856404bd4cf39021b82209908faa44159e68ea207ab8a5e13197"]; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = frame_system::Pallet; + type MaxLocks = (); + type WeightInfo = (); +} + +parameter_types! { + pub const UnsignedPriority: u64 = 1 << 20; +} + +pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter; + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type Event = Event; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = (); +} + +parameter_types! { + pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); +} + +impl orml_currencies::Config for Runtime { + type Event = Event; + type MultiCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type GetNativeCurrencyId = GetNativeCurrencyId; + type WeightInfo = (); +} + +impl Config for Runtime { + type Event = Event; + type Currency = Balances; + type BridgedTokenCurrency = BasicCurrencyAdapter; + type CurrencyIdentifier = RENBTCIdentifier; + type UnsignedPriority = UnsignedPriority; + type ChargeTransactionPayment = (); +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + RenVmBridge: renvm::{Pallet, Call, Config, Storage, Event, ValidateUnsigned}, + Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Currencies: orml_currencies::{Pallet, Call, Event}, + } +); + +pub struct ExtBuilder(); + +impl Default for ExtBuilder { + fn default() -> Self { + Self() + } +} + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + renvm::GenesisConfig { + ren_vm_public_key: hex_literal::hex!["4b939fc8ade87cb50b78987b1dda927460dc456a"], + } + .assimilate_storage::(&mut t) + .unwrap(); + + t.into() + } +} diff --git a/lib-serml/renvm-bridge/src/tests.rs b/lib-serml/renvm-bridge/src/tests.rs new file mode 100644 index 000000000..3b72e2ef1 --- /dev/null +++ b/lib-serml/renvm-bridge/src/tests.rs @@ -0,0 +1,223 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Unit tests for the renvm-bridge module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok, unsigned::ValidateUnsigned}; +use hex_literal::hex; +use mock::{AccountId, Balances, ExtBuilder, Origin, RenVmBridge, Runtime, System}; +use sp_core::H256; +use sp_runtime::transaction_validity::TransactionValidityError; + +fn mint_ren_btc( + who: AccountId, + p_hash: [u8; 32], + amount: Balance, + n_hash: [u8; 32], + sig: EcdsaSignature, +) -> Result { + ::validate_unsigned( + TransactionSource::External, + &Call::mint(who.clone(), p_hash, amount, n_hash, sig.clone()), + )?; + + Ok(RenVmBridge::mint(Origin::none(), who, p_hash, amount, n_hash, sig)) +} + +fn rotate_key(new_key: PublicKey, sig: EcdsaSignature) -> Result { + ::validate_unsigned( + TransactionSource::External, + &Call::rotate_key(new_key, sig.clone()), + )?; + + Ok(RenVmBridge::rotate_key(Origin::none(), new_key, sig)) +} + +#[test] +fn burn_works() { + ExtBuilder::default().build().execute_with(|| { + let issuer: H256 = hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"].into(); + assert_ok!( + mint_ren_btc( + issuer.clone(), + hex!["4fe557069c2424260b9d0cca31049e70ede95c49964578044d80c74f3a118505"], + 93802, + hex!["64c1212efd301721c9343fdf299f022778ea336608c1ae089136045b8d6f3e5c"], + EcdsaSignature::from_slice(&hex!["5566d8eb9fec05a6636381302ad7dd6b28a0ec62e6e45038fbb095c6503ee08a69a450c566ce60ccca1233d32c24a366176d189bbe5613ae633ce3ae4b6b9a7e1b"]), + ) + ); + assert_eq!(Balances::free_balance(issuer.clone()), 93802); + + let to: Vec = vec![2, 3, 4]; + assert_eq!(RenVmBridge::burn_events(0), None); + assert_ok!(RenVmBridge::burn(Origin::signed(issuer.clone()), to.clone(), 1000)); + assert_eq!(Balances::free_balance(&issuer), 92802); + assert_eq!(RenVmBridge::burn_events(0), Some((0, to.clone(), 1000))); + assert_eq!(RenVmBridge::next_burn_event_id(), 1); + + System::set_block_number(15); + + assert_ok!(RenVmBridge::burn(Origin::signed(issuer.clone()), to.clone(), 2000)); + assert_eq!(Balances::free_balance(&issuer), 90802); + assert_eq!(RenVmBridge::burn_events(1), Some((15, to.clone(), 2000))); + assert_eq!(RenVmBridge::next_burn_event_id(), 2); + }); +} + +#[test] +fn verify_mint_signature_works() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!( + RenVmBridge::verify_mint_signature( + &hex!["67028f26328144de6ef80b8cd3b05e0cefb488762c340d1574c0542f752996cb"], + 93963, + &hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"], + &hex!["f6a75cc370a2dda6dfc8d016529766bb6099d7fa0d787d9fe5d3a7e60c9ac2a0"], + &hex!["defda6eef01da2e2a90ce30ba73e90d32204ae84cae782b485f01d16b69061e0381a69cafed3deb6112af044c42ed0f7c73ee0eec7b533334d31a06db50fc40e1b"], + ) + ); + + assert_ok!( + RenVmBridge::verify_mint_signature( + &hex!["ad8fae51f70e3a013962934614201466076fec72eb60f74183f3059d6ad2c4c1"], + 86129, + &hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"], + &hex!["1cdb2d4388e10ce8f89613f06a0d03a2d3fbcfd334d81d4564f7e1bfc5ebc9bb"], + &hex!["87f068a20cfaf7752151320dcfde3994f2861cb4dd36aa73a947f23f92f135507607c997b450053914f2e9313ea2d1abf3326a7984341fdf47e4e21f33b54cda1b"], + ) + ); + + assert_ok!( + RenVmBridge::verify_mint_signature( + &hex!["1a98ccc4004f71c29c3ae3ee3a8fe51ece4a0eda383443aa8aaafeec4fd55247"], + 80411, + &hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"], + &hex!["d45761c6d5123a10c5f707472613451de1e738b544acfbdd4b2680754ed2008a"], + &hex!["1281893709fd7f4e1d65147a948d9884adf65bb9bcb587ea32e2f3b633fa1e1f2d82488ae89105004a301eda66ef8e5f036b705716f1df42d357647e09dd3e581c"], + ) + ); + + assert_ok!( + RenVmBridge::verify_mint_signature( + &hex!["425673f98610064b76dbd334783f45ea192f0e954db75ba2ae6b6058a8143d67"], + 87266, + &hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"], + &hex!["fe125f912d2de05e3e34b96a0ce8a8e35d9ed883e830b978871f3e1f5d393726"], + &hex!["acd463fa396c54995e444234e96d793d3977e75f445da219c10bc4947c22622f325f24dfc31e8e56ec21f04fc7669e91db861778a8367444bde6dfb5f95e15ed1b"], + ) + ); + + assert_ok!( + RenVmBridge::verify_mint_signature( + &hex!["046076abc0c7e2bd8cc15b9e22ed97deff2d8e2acfe3bec1ffbbd0255b2a094c"], + 87403, + &hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"], + &hex!["64962866cd5245005a06b8a10ac57626f176bc1c8e340a008c4a765a56aa4a6f"], + &hex!["63f68adcda25db1de27b0edeb0439f7d971a22afeebb5ddb07ed05d4b07ac4fd1f78e5ecd4f2d6a21aabcc73027e8b977f9a688ae16db5aaf6c0d0021e85e3f41b"], + ) + ); + }); +} + +#[test] +fn mint_works() { + ExtBuilder::default().build().execute_with(|| { + let to: H256 = hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"].into(); + + assert_ok!( + mint_ren_btc( + to.clone(), + hex!["67028f26328144de6ef80b8cd3b05e0cefb488762c340d1574c0542f752996cb"], + 93963, + hex!["f6a75cc370a2dda6dfc8d016529766bb6099d7fa0d787d9fe5d3a7e60c9ac2a0"], + EcdsaSignature::from_slice(&hex!["defda6eef01da2e2a90ce30ba73e90d32204ae84cae782b485f01d16b69061e0381a69cafed3deb6112af044c42ed0f7c73ee0eec7b533334d31a06db50fc40e1b"]), + ) + ); + + assert_eq!(Balances::free_balance(to.clone()), 93963); + + assert_ok!( + mint_ren_btc( + to.clone(), + hex!["425673f98610064b76dbd334783f45ea192f0e954db75ba2ae6b6058a8143d67"], + 87266, + hex!["fe125f912d2de05e3e34b96a0ce8a8e35d9ed883e830b978871f3e1f5d393726"], + EcdsaSignature::from_slice(&hex!["acd463fa396c54995e444234e96d793d3977e75f445da219c10bc4947c22622f325f24dfc31e8e56ec21f04fc7669e91db861778a8367444bde6dfb5f95e15ed1b"]), + ) + ); + + assert_eq!(Balances::free_balance(to.clone()), 93963 + 87266); + + assert_noop!( + mint_ren_btc( + to.clone(), + hex!["425673f98610064b76dbd334783f45ea192f0e954db75ba2ae6b6058a8143d67"], + 87266, + hex!["fe125f912d2de05e3e34b96a0ce8a8e35d9ed883e830b978871f3e1f5d393726"], + EcdsaSignature::from_slice(&hex!["acd463fa396c54995e444234e96d793d3977e75f445da219c10bc4947c22622f325f24dfc31e8e56ec21f04fc7669e91db861778a8367444bde6dfb5f95e15ed1b"]), + ), + TransactionValidityError::Invalid(InvalidTransaction::Stale) + ); + + assert_noop!( + mint_ren_btc( + to.clone(), + hex!["425673f98610064b76dbd334783f45ea192f0e954db75ba2ae6b6058a8143d67"], + 87266, + hex!["fe125f912d2de05e3e34b96a0ce8a8e35d9ed883e830b978871f3e1f5d393726"], + EcdsaSignature::from_slice(&hex!["000463fa396c54995e444234e96d793d3977e75f445da219c10bc4947c22622f325f24dfc31e8e56ec21f04fc7669e91db861778a8367444bde6dfb5f95e15ed1b"]), + ), + TransactionValidityError::Invalid(InvalidTransaction::BadProof) + ); + }); +} + +#[test] +fn rotate_key_works() { + ExtBuilder::default().build().execute_with(|| { + let new_key: PublicKey = hex!["4b939fc8ade87cb50b78987b1dda927460dc456a"]; + + assert_noop!( + rotate_key( + new_key, + EcdsaSignature::from_slice(&hex!["defda6eef01da2e2a90ce30ba73e90d32204ae84cae782b485f01d16b69061e0381a69cafed3deb6112af044c42ed0f7c73ee0eec7b533334d31a06db50fc40e1b"]), + ), + TransactionValidityError::Invalid(InvalidTransaction::BadProof) + ); + }); +} + +#[test] +fn transaction_length_of_mint() { + ExtBuilder::default().build().execute_with(|| { + let to: H256 = hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"].into(); + let call = Call::::mint( + to, + hex!["425673f98610064b76dbd334783f45ea192f0e954db75ba2ae6b6058a8143d67"], + 10000 * 10u128.saturating_pow(8), // 10000 BTC + hex!["fe125f912d2de05e3e34b96a0ce8a8e35d9ed883e830b978871f3e1f5d393726"], + EcdsaSignature::from_slice(&hex!["000463fa396c54995e444234e96d793d3977e75f445da219c10bc4947c22622f325f24dfc31e8e56ec21f04fc7669e91db861778a8367444bde6dfb5f95e15ed1b"]) + ); + + let call_len = call.using_encoded(|c| c.len()); + assert_eq!(call_len as u32, MINT_TX_LENGTH); + }); +} From 3541e7102755fcc04f1ae1a54b8e427e1e0a44e7 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 04:27:26 +0800 Subject: [PATCH 08/83] update resources --- resources/newrome-airdrop-DNAR.json | 0 resources/newrome-airdrop-NEOM.json | 0 resources/newrome-airdrop-NFT.json | 3 +++ resources/newrome-airdrop-ROME.json | 3 +++ 4 files changed, 6 insertions(+) delete mode 100644 resources/newrome-airdrop-DNAR.json delete mode 100644 resources/newrome-airdrop-NEOM.json create mode 100644 resources/newrome-airdrop-ROME.json diff --git a/resources/newrome-airdrop-DNAR.json b/resources/newrome-airdrop-DNAR.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/resources/newrome-airdrop-NEOM.json b/resources/newrome-airdrop-NEOM.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/resources/newrome-airdrop-NFT.json b/resources/newrome-airdrop-NFT.json index e69de29bb..41b42e677 100644 --- a/resources/newrome-airdrop-NFT.json +++ b/resources/newrome-airdrop-NFT.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/resources/newrome-airdrop-ROME.json b/resources/newrome-airdrop-ROME.json new file mode 100644 index 000000000..41b42e677 --- /dev/null +++ b/resources/newrome-airdrop-ROME.json @@ -0,0 +1,3 @@ +[ + +] From 18383659986c0439e892c4a5546cddd3f0c58c3c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 04:33:12 +0800 Subject: [PATCH 09/83] update resources --- resources/neom-allocation-NEOM.json | 3 +++ resources/neom-vesting-NEOM.json | 3 +++ resources/setheum-allocation-DNAR.json | 3 +++ resources/setheum-vesting-DNAR.json | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 resources/neom-allocation-NEOM.json create mode 100644 resources/neom-vesting-NEOM.json create mode 100644 resources/setheum-allocation-DNAR.json create mode 100644 resources/setheum-vesting-DNAR.json diff --git a/resources/neom-allocation-NEOM.json b/resources/neom-allocation-NEOM.json new file mode 100644 index 000000000..41b42e677 --- /dev/null +++ b/resources/neom-allocation-NEOM.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/resources/neom-vesting-NEOM.json b/resources/neom-vesting-NEOM.json new file mode 100644 index 000000000..41b42e677 --- /dev/null +++ b/resources/neom-vesting-NEOM.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/resources/setheum-allocation-DNAR.json b/resources/setheum-allocation-DNAR.json new file mode 100644 index 000000000..41b42e677 --- /dev/null +++ b/resources/setheum-allocation-DNAR.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/resources/setheum-vesting-DNAR.json b/resources/setheum-vesting-DNAR.json new file mode 100644 index 000000000..41b42e677 --- /dev/null +++ b/resources/setheum-vesting-DNAR.json @@ -0,0 +1,3 @@ +[ + +] From fcf5390f70d93831c1ba1bcb0685f21244282d71 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 04:44:19 +0800 Subject: [PATCH 10/83] Add setheum-evm --- lib-serml/currencies/src/weights.rs | 2 +- lib-serml/evm/Cargo.toml | 69 + lib-serml/evm/rpc/Cargo.toml | 33 + lib-serml/evm/rpc/runtime_api/Cargo.toml | 24 + lib-serml/evm/rpc/runtime_api/src/lib.rs | 55 + lib-serml/evm/rpc/src/call_request.rs | 53 + lib-serml/evm/rpc/src/evm_api.rs | 45 + lib-serml/evm/rpc/src/lib.rs | 452 +++++++ lib-serml/evm/src/lib.rs | 1272 ++++++++++++++++++ lib-serml/evm/src/mock.rs | 280 ++++ lib-serml/evm/src/precompiles.rs | 358 ++++++ lib-serml/evm/src/runner/handler.rs | 793 ++++++++++++ lib-serml/evm/src/runner/mod.rs | 305 +++++ lib-serml/evm/src/runner/storage_meter.rs | 446 +++++++ lib-serml/evm/src/tests.rs | 1418 +++++++++++++++++++++ lib-serml/evm/src/weights.rs | 137 ++ 16 files changed, 5741 insertions(+), 1 deletion(-) create mode 100644 lib-serml/evm/Cargo.toml create mode 100644 lib-serml/evm/rpc/Cargo.toml create mode 100644 lib-serml/evm/rpc/runtime_api/Cargo.toml create mode 100644 lib-serml/evm/rpc/runtime_api/src/lib.rs create mode 100644 lib-serml/evm/rpc/src/call_request.rs create mode 100644 lib-serml/evm/rpc/src/evm_api.rs create mode 100644 lib-serml/evm/rpc/src/lib.rs create mode 100644 lib-serml/evm/src/lib.rs create mode 100644 lib-serml/evm/src/mock.rs create mode 100644 lib-serml/evm/src/precompiles.rs create mode 100644 lib-serml/evm/src/runner/handler.rs create mode 100644 lib-serml/evm/src/runner/mod.rs create mode 100644 lib-serml/evm/src/runner/storage_meter.rs create mode 100644 lib-serml/evm/src/tests.rs create mode 100644 lib-serml/evm/src/weights.rs diff --git a/lib-serml/currencies/src/weights.rs b/lib-serml/currencies/src/weights.rs index e2cf7f9b8..266aeeef5 100644 --- a/lib-serml/currencies/src/weights.rs +++ b/lib-serml/currencies/src/weights.rs @@ -35,7 +35,7 @@ // --heap-pages=4096 // --output=./currencies/src/weights.rs // --template -// ../templates/orml-weight-template.hbs +// ../templates/lib-openrml-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] diff --git a/lib-serml/evm/Cargo.toml b/lib-serml/evm/Cargo.toml new file mode 100644 index 000000000..5aea54a16 --- /dev/null +++ b/lib-serml/evm/Cargo.toml @@ -0,0 +1,69 @@ +[package] +name = "setheum-evm" +version = "1.0.0" +authors = ["Setheum Labs"] +edition = "2018" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } +impl-trait-for-tuples = "0.1" +primitive-types = { version = "0.9.0", default-features = false, features = ["rlp", "byteorder"] } +ripemd160 = { version = "0.9", default-features = false } +rlp = { version = "0.5", default-features = false } +serde = { version = "1.0.124", optional = true, features = ["derive"] } +sha3 = { version = "0.9.1", default-features = false } +tiny-keccak = { version = "2.0", features = ["fips202"] } + +evm = { version = "0.26.0", default-features = false, features = ["with-codec"] } +evm-gasometer = { version = "0.26.0", default-features = false } +evm-runtime = { version = "0.26.0", default-features = false } + +max-encoded-len = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +orml-traits = { path = "../../lib-openrml/traits", default-features = false } + +support = { package = "setheum-support", path = "../support", default-features = false } +primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } + +[dev-dependencies] +env_logger = "0.7" +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +orml-currencies = { path = "../../lib-openrml/currencies" } +orml-tokens = { path = "../../lib-openrml/tokens" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-core/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "sp-io/std", + "sp-std/std", + "sha3/std", + "rlp/std", + "primitive-types/std", + "evm/std", + "evm/with-serde", + "evm-runtime/std", + "evm-gasometer/std", + "pallet-timestamp/std", + "ripemd160/std", + "primitives/std", + "orml-traits/std", + "support/std", +] +with-ethereum-compatibility = [] +try-runtime = ["frame-support/try-runtime"] diff --git a/lib-serml/evm/rpc/Cargo.toml b/lib-serml/evm/rpc/Cargo.toml new file mode 100644 index 000000000..dc519accf --- /dev/null +++ b/lib-serml/evm/rpc/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "evm-rpc" +version = "1.0.0" +authors = ["Setheum Labs"] +edition = "2018" + +[dependencies] +jsonrpc-core = "15.0.0" +jsonrpc-derive = "15.0.0" +ethereum-types = "0.11.0" +rustc-hex = "2.1.0" +serde = { version = "1.0.124", features = ["derive"] } + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } + +setheum-evm-rpc-runtime-api = { path = "runtime_api" } +setheum-evm = { path = ".." } + +[dev-dependencies] +serde_json = "1.0.64" + +[features] +default = [ "rpc_binary_search_estimate" ] +rpc_binary_search_estimate = [] diff --git a/lib-serml/evm/rpc/runtime_api/Cargo.toml b/lib-serml/evm/rpc/runtime_api/Cargo.toml new file mode 100644 index 000000000..b501eb84f --- /dev/null +++ b/lib-serml/evm/rpc/runtime_api/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "setheum-evm-rpc-runtime-api" +version = "0.1.0" +authors = ["Setheum Labs"] +edition = "2018" + +[dependencies] +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +ethereum-types = { version = "0.11", default-features = false } +primitives = { package = "setheum-primitives", path = "../../../../primitives", default-features = false } + +[features] +default = ["std"] +std = [ + "sp-runtime/std", + "sp-api/std", + "sp-std/std", + "sp-core/std", + "ethereum-types/std", + "primitives/std", +] diff --git a/lib-serml/evm/rpc/runtime_api/src/lib.rs b/lib-serml/evm/rpc/runtime_api/src/lib.rs new file mode 100644 index 000000000..6b13c0890 --- /dev/null +++ b/lib-serml/evm/rpc/runtime_api/src/lib.rs @@ -0,0 +1,55 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::all)] + +use ethereum_types::H160; +use primitives::evm::{CallInfo, CreateInfo, EstimateResourcesRequest}; +use sp_runtime::{ + codec::Codec, + traits::{MaybeDisplay, MaybeFromStr}, +}; +use sp_std::vec::Vec; + +sp_api::decl_runtime_apis! { + pub trait EVMRuntimeRPCApi where + Balance: Codec + MaybeDisplay + MaybeFromStr, + { + fn call( + from: H160, + to: H160, + data: Vec, + value: Balance, + gas_limit: u64, + storage_limit: u32, + estimate: bool, + ) -> Result; + + fn create( + from: H160, + data: Vec, + value: Balance, + gas_limit: u64, + storage_limit: u32, + estimate: bool, + ) -> Result; + + fn get_estimate_resources_request(data: Vec) -> Result; + } +} diff --git a/lib-serml/evm/rpc/src/call_request.rs b/lib-serml/evm/rpc/src/call_request.rs new file mode 100644 index 000000000..d9e20a326 --- /dev/null +++ b/lib-serml/evm/rpc/src/call_request.rs @@ -0,0 +1,53 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use ethereum_types::{H160, U256}; +use serde::{Deserialize, Serialize}; +use sp_core::Bytes; +use sp_rpc::number::NumberOrHex; + +/// Call request +#[derive(Debug, Default, PartialEq, Deserialize, Clone)] +#[serde(deny_unknown_fields)] +#[serde(rename_all = "camelCase")] +pub struct CallRequest { + /// From + pub from: Option, + /// To + pub to: Option, + /// Gas Limit + pub gas_limit: Option, + /// Storage Limit + pub storage_limit: Option, + /// Value + pub value: Option, + /// Data + pub data: Option, +} + +/// EstimateResources response +#[derive(Debug, Eq, PartialEq, Default, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct EstimateResourcesResponse { + /// Used gas + pub gas: U256, + /// Used storage + pub storage: i32, + /// Adjusted weight fee + pub weight_fee: U256, +} diff --git a/lib-serml/evm/rpc/src/evm_api.rs b/lib-serml/evm/rpc/src/evm_api.rs new file mode 100644 index 000000000..a96a4a0f6 --- /dev/null +++ b/lib-serml/evm/rpc/src/evm_api.rs @@ -0,0 +1,45 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! EVM rpc interface. + +use ethereum_types::H160; +use jsonrpc_core::Result; +use jsonrpc_derive::rpc; +use sp_core::Bytes; + +pub use rpc_impl_EVMApi::gen_server::EVMApi as EVMApiServer; + +use crate::call_request::{CallRequest, EstimateResourcesResponse}; + +/// EVM rpc interface. +#[rpc(server)] +pub trait EVMApi { + /// Call contract, returning the output data. + #[rpc(name = "evm_call")] + fn call(&self, _: CallRequest, at: Option) -> Result; + + /// Estimate resources needed for execution of given contract. + #[rpc(name = "evm_estimateResources")] + fn estimate_resources( + &self, + from: H160, + unsigned_extrinsic: Bytes, + at: Option, + ) -> Result; +} diff --git a/lib-serml/evm/rpc/src/lib.rs b/lib-serml/evm/rpc/src/lib.rs new file mode 100644 index 000000000..97bf7b5bb --- /dev/null +++ b/lib-serml/evm/rpc/src/lib.rs @@ -0,0 +1,452 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![allow(clippy::upper_case_acronyms)] + +use ethereum_types::{H160, U256}; +use frame_support::log; +use jsonrpc_core::{Error, ErrorCode, Result, Value}; +use pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi; +use rustc_hex::ToHex; +use sc_rpc_api::DenyUnsafe; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::HeaderBackend; +use sp_core::{Bytes, Decode}; +use sp_rpc::number::NumberOrHex; +use sp_runtime::{ + codec::Codec, + generic::BlockId, + traits::{self, Block as BlockT, MaybeDisplay, MaybeFromStr}, + SaturatedConversion, +}; +use std::convert::{TryFrom, TryInto}; +use std::{marker::PhantomData, sync::Arc}; + +use call_request::{CallRequest, EstimateResourcesResponse}; +pub use module_evm::{ExitError, ExitReason}; +pub use module_evm_rpc_runtime_api::EVMRuntimeRPCApi; + +pub use crate::evm_api::{EVMApi as EVMApiT, EVMApiServer}; + +mod call_request; +mod evm_api; + +fn internal_err(message: T) -> Error { + Error { + code: ErrorCode::InternalError, + message: message.to_string(), + data: None, + } +} + +#[allow(dead_code)] +fn error_on_execution_failure(reason: &ExitReason, data: &[u8]) -> Result<()> { + match reason { + ExitReason::Succeed(_) => Ok(()), + ExitReason::Error(e) => { + if *e == ExitError::OutOfGas { + // `ServerError(0)` will be useful in estimate gas + return Err(Error { + code: ErrorCode::ServerError(0), + message: "out of gas".to_string(), + data: None, + }); + } + Err(Error { + code: ErrorCode::InternalError, + message: format!("execution error: {:?}", e), + data: Some(Value::String("0x".to_string())), + }) + } + ExitReason::Revert(_) => Err(Error { + code: ErrorCode::InternalError, + message: decode_revert_message(data) + .map_or("execution revert".into(), |data| format!("execution revert: {}", data)), + data: Some(Value::String(format!("0x{}", data.to_hex::()))), + }), + ExitReason::Fatal(e) => Err(Error { + code: ErrorCode::InternalError, + message: format!("execution fatal: {:?}", e), + data: Some(Value::String("0x".to_string())), + }), + } +} + +fn decode_revert_message(data: &[u8]) -> Option { + // A minimum size of error function selector (4) + offset (32) + string length + // (32) should contain a utf-8 encoded revert reason. + let msg_start: usize = 68; + if data.len() > msg_start { + let message_len = U256::from(&data[36..msg_start]).saturated_into::(); + let msg_end = msg_start.checked_add(message_len)?; + + if data.len() < msg_end { + return None; + } + let body: &[u8] = &data[msg_start..msg_end]; + if let Ok(reason) = std::str::from_utf8(body) { + return Some(reason.to_string()); + } + } + None +} + +pub struct EVMApi { + client: Arc, + deny_unsafe: DenyUnsafe, + _marker: PhantomData<(B, Balance)>, +} + +impl EVMApi { + pub fn new(client: Arc, deny_unsafe: DenyUnsafe) -> Self { + Self { + client, + deny_unsafe, + _marker: Default::default(), + } + } +} + +fn to_u128(val: NumberOrHex) -> std::result::Result { + val.into_u256().try_into().map_err(|_| ()) +} + +impl EVMApiT<::Hash> for EVMApi +where + B: BlockT, + C: ProvideRuntimeApi + HeaderBackend + Send + Sync + 'static, + C::Api: EVMRuntimeRPCApi, + C::Api: TransactionPaymentApi, + Balance: Codec + MaybeDisplay + MaybeFromStr + Default + Send + Sync + 'static + TryFrom + Into, +{ + fn call(&self, request: CallRequest, at: Option<::Hash>) -> Result { + self.deny_unsafe.check_if_safe()?; + + let hash = at.unwrap_or_else(|| self.client.info().best_hash); + + let CallRequest { + from, + to, + gas_limit, + storage_limit, + value, + data, + } = request; + + let gas_limit = gas_limit.unwrap_or_else(u64::max_value); // TODO: set a limit + let storage_limit = storage_limit.unwrap_or_else(u32::max_value); // TODO: set a limit + let data = data.map(|d| d.0).unwrap_or_default(); + + let api = self.client.runtime_api(); + + let balance_value = if let Some(value) = value { + to_u128(value).and_then(|v| TryInto::::try_into(v).map_err(|_| ())) + } else { + Ok(Default::default()) + }; + + let balance_value = balance_value.map_err(|_| Error { + code: ErrorCode::InvalidParams, + message: format!("Invalid parameter value: {:?}", value), + data: None, + })?; + + match to { + Some(to) => { + let info = api + .call( + &BlockId::Hash(hash), + from.unwrap_or_default(), + to, + data, + balance_value, + gas_limit, + storage_limit, + false, + ) + .map_err(|err| internal_err(format!("runtime error: {:?}", err)))? + .map_err(|err| internal_err(format!("execution fatal: {:?}", err)))?; + + error_on_execution_failure(&info.exit_reason, &info.output)?; + + Ok(Bytes(info.output)) + } + None => { + let info = api + .create( + &BlockId::Hash(hash), + from.unwrap_or_default(), + data, + balance_value, + gas_limit, + storage_limit, + false, + ) + .map_err(|err| internal_err(format!("runtime error: {:?}", err)))? + .map_err(|err| internal_err(format!("execution fatal: {:?}", err)))?; + + error_on_execution_failure(&info.exit_reason, &info.output)?; + + Ok(Bytes(info.output[..].to_vec())) + } + } + } + + fn estimate_resources( + &self, + from: H160, + unsigned_extrinsic: Bytes, + at: Option<::Hash>, + ) -> Result { + self.deny_unsafe.check_if_safe()?; + + let hash = at.unwrap_or_else(|| self.client.info().best_hash); + let request = self + .client + .runtime_api() + .get_estimate_resources_request(&BlockId::Hash(hash), unsigned_extrinsic.to_vec()) + .map_err(|err| internal_err(format!("runtime error: {:?}", err)))? + .map_err(|err| internal_err(format!("execution fatal: {:?}", err)))?; + + let request = CallRequest { + from: Some(from), + to: request.to, + gas_limit: request.gas_limit, + storage_limit: request.storage_limit, + value: request.value.map(|v| NumberOrHex::Hex(U256::from(v))), + data: request.data.map(Bytes), + }; + + let calculate_gas_used = |request| -> Result<(U256, i32)> { + let hash = self.client.info().best_hash; + + let CallRequest { + from, + to, + gas_limit, + storage_limit, + value, + data, + } = request; + + let gas_limit = gas_limit.unwrap_or_else(u64::max_value); // TODO: set a limit + let storage_limit = storage_limit.unwrap_or_else(u32::max_value); // TODO: set a limit + let data = data.map(|d| d.0).unwrap_or_default(); + + let balance_value = if let Some(value) = value { + to_u128(value).and_then(|v| TryInto::::try_into(v).map_err(|_| ())) + } else { + Ok(Default::default()) + }; + + let balance_value = balance_value.map_err(|_| Error { + code: ErrorCode::InvalidParams, + message: format!("Invalid parameter value: {:?}", value), + data: None, + })?; + + let (used_gas, used_storage) = match to { + Some(to) => { + let info = self + .client + .runtime_api() + .call( + &BlockId::Hash(hash), + from.unwrap_or_default(), + to, + data, + balance_value, + gas_limit, + storage_limit, + true, + ) + .map_err(|err| internal_err(format!("runtime error: {:?}", err)))? + .map_err(|err| internal_err(format!("execution fatal: {:?}", err)))?; + + error_on_execution_failure(&info.exit_reason, &info.output)?; + + (info.used_gas, info.used_storage) + } + None => { + let info = self + .client + .runtime_api() + .create( + &BlockId::Hash(hash), + from.unwrap_or_default(), + data, + balance_value, + gas_limit, + storage_limit, + true, + ) + .map_err(|err| internal_err(format!("runtime error: {:?}", err)))? + .map_err(|err| internal_err(format!("execution fatal: {:?}", err)))?; + + error_on_execution_failure(&info.exit_reason, &[])?; + + (info.used_gas, info.used_storage) + } + }; + + Ok((used_gas, used_storage)) + }; + + if cfg!(feature = "rpc_binary_search_estimate") { + let mut lower = U256::from(21_000); + // TODO: get a good upper limit, but below U64::max to operation overflow + let mut upper = U256::from(1_000_000_000); + let mut mid = upper; + let mut best = mid; + let mut old_best: U256; + let mut storage: i32 = Default::default(); + + // if the gas estimation depends on the gas limit, then we want to binary + // search until the change is under some threshold. but if not dependent, + // we want to stop immediately. + let mut change_pct = U256::from(100); + let threshold_pct = U256::from(10); + + // invariant: lower <= mid <= upper + while change_pct > threshold_pct { + let mut test_request = request.clone(); + test_request.gas_limit = Some(mid.as_u64()); + match calculate_gas_used(test_request) { + // if Ok -- try to reduce the gas used + Ok((used_gas, used_storage)) => { + log::debug!( + target: "evm", + "calculate_gas_used ok, used_gas: {:?}, used_storage: {:?}", + used_gas, used_storage, + ); + + old_best = best; + best = used_gas; + change_pct = (U256::from(100) * (old_best - best)) + .checked_div(old_best) + .unwrap_or_default(); + upper = mid; + mid = (lower + upper + 1) / 2; + storage = used_storage; + } + + Err(err) => { + log::debug!( + target: "evm", + "calculate_gas_used err, lower: {:?}, upper: {:?}, mid: {:?}", + lower, upper, mid + ); + + // if Err == OutofGas, we need more gas + if err.code == ErrorCode::ServerError(0) { + lower = mid; + mid = (lower + upper + 1) / 2; + if mid == lower { + break; + } + } else { + // Other errors, return directly + return Err(err); + } + } + } + } + + let uxt: ::Extrinsic = + Decode::decode(&mut &*unsigned_extrinsic).map_err(|e| Error { + code: ErrorCode::InternalError, + message: "Unable to dry run extrinsic.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + let fee = self + .client + .runtime_api() + .query_fee_details(&BlockId::Hash(hash), uxt, unsigned_extrinsic.len() as u32) + .map_err(|e| Error { + code: ErrorCode::InternalError, + message: "Unable to query fee details.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + let adjusted_weight_fee = fee + .inclusion_fee + .map_or_else(Default::default, |inclusion| inclusion.adjusted_weight_fee); + + Ok(EstimateResourcesResponse { + gas: best, + storage, + weight_fee: adjusted_weight_fee.into(), + }) + } else { + let (used_gas, used_storage) = calculate_gas_used(request)?; + + let uxt: ::Extrinsic = + Decode::decode(&mut &*unsigned_extrinsic).map_err(|e| Error { + code: ErrorCode::InternalError, + message: "Unable to dry run extrinsic.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + let fee = self + .client + .runtime_api() + .query_fee_details(&BlockId::Hash(hash), uxt, unsigned_extrinsic.len() as u32) + .map_err(|e| Error { + code: ErrorCode::InternalError, + message: "Unable to query fee details.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + let adjusted_weight_fee = fee + .inclusion_fee + .map_or_else(Default::default, |inclusion| inclusion.adjusted_weight_fee); + + Ok(EstimateResourcesResponse { + gas: used_gas, + storage: used_storage, + weight_fee: adjusted_weight_fee.into(), + }) + } + } +} + +#[test] +fn decode_revert_message_should_work() { + use sp_core::bytes::from_hex; + assert_eq!(decode_revert_message(&vec![]), None); + + let data = from_hex("0x8c379a00000000000000000000000000000000000000000000000000000000000000020").unwrap(); + assert_eq!(decode_revert_message(&data), None); + + let data = from_hex("0x8c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6572726f72206d65737361676").unwrap(); + assert_eq!(decode_revert_message(&data), None); + + let data = from_hex("0x8c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6572726f72206d65737361676500000000000000000000000000000000000000").unwrap(); + assert_eq!(decode_revert_message(&data), Some("error message".into())); + + // ensures we protect against msg_start + message_len overflow + let data = from_hex("0x9850188c1837189a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000018d618571827182618f718220618d6185718371836161876").unwrap(); + assert_eq!(decode_revert_message(&data), None); + // ensures we protect against msg_start + message_len overflow + let data = from_hex("0x9860189818501818188c181818371818189a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000181818d6181818571818182718181826181818f71818182206181818d61818185718181837181818361618181876").unwrap(); + assert_eq!(decode_revert_message(&data), None); + // ensures we protect against msg_start + message_len overflow + let data = from_hex("0x98640818c3187918a0000000000000000000000000000000000000000000000000000000000000001820000000000000000000000000000000000000000000000000000000000000000d186518721872186f18721820186d18651873187318611867186500000000000000000000000000000000000000").unwrap(); + assert_eq!(decode_revert_message(&data), None); +} diff --git a/lib-serml/evm/src/lib.rs b/lib-serml/evm/src/lib.rs new file mode 100644 index 000000000..6a95bf7f0 --- /dev/null +++ b/lib-serml/evm/src/lib.rs @@ -0,0 +1,1272 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::too_many_arguments)] +#![allow(clippy::or_fun_call)] +#![allow(clippy::unused_unit)] +#![allow(clippy::upper_case_acronyms)] + +use crate::runner::{ + handler::{Handler, StorageMeterHandlerImpl}, + storage_meter::{StorageMeter, StorageMeterHandler}, +}; +use codec::{Decode, Encode}; +use evm::Config as EvmConfig; +use frame_support::{ + dispatch::{DispatchError, DispatchResult, DispatchResultWithPostInfo}, + ensure, + error::BadOrigin, + pallet_prelude::*, + traits::{ + BalanceStatus, Currency, EnsureOrigin, ExistenceRequirement, Get, MaxEncodedLen, OnKilledAccount, + ReservableCurrency, + }, + transactional, + weights::{Pays, PostDispatchInfo, Weight}, + BoundedVec, RuntimeDebug, +}; +use frame_system::{ensure_root, ensure_signed, pallet_prelude::*, EnsureOneOf, EnsureRoot, EnsureSigned}; +use primitive_types::{H256, U256}; +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; +use sha3::{Digest, Keccak256}; +use sp_runtime::{ + traits::{ + Convert, DispatchInfoOf, One, PostDispatchInfoOf, Saturating, SignedExtension, UniqueSaturatedInto, Zero, + }, + transaction_validity::TransactionValidityError, + Either, TransactionOutcome, +}; +use sp_std::{convert::TryInto, marker::PhantomData, prelude::*}; + +pub use support::{ + AddressMapping, EVMStateRentTrait, ExecutionMode, InvokeContext, TransactionPayment, EVM as EVMTrait, +}; + +pub use crate::precompiles::{Precompile, Precompiles}; +pub use crate::runner::Runner; +pub use evm::{Context, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed}; +pub use orml_traits::currency::TransferAll; +pub use primitives::{ + evm::{Account, CallInfo, CreateInfo, EvmAddress, Log, Vicinity}, + MIRRORED_NFT_ADDRESS_START, +}; + +pub mod precompiles; +pub mod runner; + +mod mock; +mod tests; +pub mod weights; + +pub use module::*; +pub use weights::WeightInfo; + +/// Type alias for currency balance. +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + +// Initially based on Istanbul hard fork configuration. +static SETHEUM_CONFIG: EvmConfig = EvmConfig { + gas_ext_code: 700, + gas_ext_code_hash: 700, + gas_balance: 700, + gas_sload: 800, + gas_sstore_set: 20000, + gas_sstore_reset: 5000, + refund_sstore_clears: 0, // no gas refund + gas_suicide: 5000, + gas_suicide_new_account: 25000, + gas_call: 700, + gas_expbyte: 50, + gas_transaction_create: 53000, + gas_transaction_call: 21000, + gas_transaction_zero_data: 4, + gas_transaction_non_zero_data: 16, + sstore_gas_metering: false, // no gas refund + sstore_revert_under_stipend: false, // ignored + err_on_call_with_more_gas: false, + empty_considered_exists: false, + create_increase_nonce: true, + call_l64_after_gas: true, + stack_limit: 1024, + memory_limit: usize::max_value(), + call_stack_limit: 1024, + create_contract_limit: None, // ignored + call_stipend: 2300, + has_delegate_call: true, + has_create2: true, + has_revert: true, + has_return_data: true, + has_bitwise_shifting: true, + has_chain_id: true, + has_self_balance: true, + has_ext_code_hash: true, + estimate: false, +}; + +#[frame_support::pallet] +pub mod module { + use crate::runner::handler; + + use super::*; + + /// EVM module trait + #[pallet::config] + pub trait Config: frame_system::Config + pallet_timestamp::Config { + /// Mapping from address to account id. + type AddressMapping: AddressMapping; + + /// Currency type for withdraw and balance storage. + type Currency: Currency + ReservableCurrency; + + /// Merge free balance from source to dest. + type TransferAll: TransferAll; + + /// Charge extra bytes for creating a contract, would be reserved until + /// the contract deleted. + #[pallet::constant] + type NewContractExtraBytes: Get; + + /// Storage required for per byte. + #[pallet::constant] + type StorageDepositPerByte: Get>; + + /// Contract max code size. + #[pallet::constant] + type MaxCodeSize: Get; + + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// Precompiles associated with this EVM engine. + type Precompiles: Precompiles; + + /// Chain ID of EVM. + #[pallet::constant] + type ChainId: Get; + + /// Convert gas to weight. + type GasToWeight: Convert; + + /// ChargeTransactionPayment convert weight to fee. + type ChargeTransactionPayment: TransactionPayment, NegativeImbalanceOf>; + + /// EVM config used in the module. + fn config() -> &'static EvmConfig { + &SETHEUM_CONFIG + } + + /// Required origin for creating system contract. + type NetworkContractOrigin: EnsureOrigin; + + /// The EVM address for creating system contract. + #[pallet::constant] + type NetworkContractSource: Get; + + /// Deposit for the developer. + #[pallet::constant] + type DeveloperDeposit: Get>; + + /// The fee for deploying the contract. + #[pallet::constant] + type DeploymentFee: Get>; + + #[pallet::constant] + type TreasuryAccount: Get; + + type FreeDeploymentOrigin: EnsureOrigin; + + /// Weight information for the extrinsics in this module. + type WeightInfo: WeightInfo; + } + + #[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode)] + pub struct ContractInfo { + pub code_hash: H256, + pub maintainer: EvmAddress, + pub deployed: bool, + } + + #[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode)] + pub struct AccountInfo { + pub nonce: T::Index, + pub contract_info: Option, + pub developer_deposit: Option>, + } + + impl AccountInfo { + pub fn new(nonce: T::Index, contract_info: Option) -> Self { + Self { + nonce, + contract_info, + developer_deposit: None, + } + } + } + + #[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode, MaxEncodedLen)] + pub struct CodeInfo { + pub code_size: u32, + pub ref_count: u32, + } + + #[cfg(feature = "std")] + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, Serialize, Deserialize)] + /// Account definition used for genesis block construction. + pub struct GenesisAccount { + /// Account nonce. + pub nonce: Index, + /// Account balance. + pub balance: Balance, + /// Full account storage. + pub storage: std::collections::BTreeMap, + /// Account code. + pub code: Vec, + } + + /// The EVM accounts info. + /// + /// Accounts: map EvmAddress => Option> + #[pallet::storage] + #[pallet::getter(fn accounts)] + pub type Accounts = StorageMap<_, Twox64Concat, EvmAddress, AccountInfo, OptionQuery>; + + /// The storage usage for contracts. Including code size, extra bytes and total AccountStorages + /// size. + /// + /// Accounts: map EvmAddress => u32 + #[pallet::storage] + #[pallet::getter(fn contract_storage_sizes)] + pub type ContractStorageSizes = StorageMap<_, Twox64Concat, EvmAddress, u32, ValueQuery>; + + /// The storages for EVM contracts. + /// + /// AccountStorages: double_map EvmAddress, H256 => H256 + #[pallet::storage] + #[pallet::getter(fn account_storages)] + pub type AccountStorages = + StorageDoubleMap<_, Twox64Concat, EvmAddress, Blake2_128Concat, H256, H256, ValueQuery>; + + /// The code for EVM contracts. + /// Key is Keccak256 hash of code. + /// + /// Codes: H256 => Vec + #[pallet::storage] + #[pallet::getter(fn codes)] + pub type Codes = StorageMap<_, Identity, H256, BoundedVec, ValueQuery>; + + /// The code info for EVM contracts. + /// Key is Keccak256 hash of code. + /// + /// CodeInfos: H256 => Option + #[pallet::storage] + #[pallet::getter(fn code_infos)] + pub type CodeInfos = StorageMap<_, Identity, H256, CodeInfo, OptionQuery>; + + /// Next available system contract address. + /// + /// NetworkContractIndex: u64 + #[pallet::storage] + #[pallet::getter(fn network_contract_index)] + pub type NetworkContractIndex = StorageValue<_, u64, ValueQuery>; + + /// Extrinsics origin for the current transaction. + /// + /// ExtrinsicOrigin: Option + #[pallet::storage] + #[pallet::getter(fn extrinsic_origin)] + pub type ExtrinsicOrigin = StorageValue<_, T::AccountId, OptionQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub accounts: std::collections::BTreeMap, T::Index>>, + pub treasury: T::AccountId, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + accounts: Default::default(), + treasury: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + let treasury = T::AddressMapping::get_or_create_evm_address(&self.treasury); + let mut handler = handler::StorageMeterHandlerImpl::::new(treasury); + + self.accounts.iter().for_each(|(address, account)| { + let account_id = T::AddressMapping::get_account_id(address); + + let account_info = >::new(account.nonce, None); + >::insert(address, account_info); + + T::Currency::deposit_creating(&account_id, account.balance); + + if !account.code.is_empty() { + // if code len > 0 then it's a contract + let source = T::NetworkContractSource::get(); + let vicinity = Vicinity { + gas_price: U256::one(), + origin: source, + }; + let storage_limit = 0; + let contract_address = *address; + let code = account.code.clone(); + + let mut storage_meter_handler = StorageMeterHandlerImpl::::new(vicinity.origin); + let storage_meter = StorageMeter::new(&mut storage_meter_handler, contract_address, storage_limit) + .expect("Genesis contract failed to new storage_meter"); + + let mut substate = Handler::::new(&vicinity, 2_100_000, storage_meter, false, T::config()); + let (reason, out) = + substate.execute(source, contract_address, Default::default(), code, Vec::new()); + + assert!( + reason.is_succeed(), + "Genesis contract failed to execute, error: {:?}", + reason + ); + + >::on_contract_initialization(&contract_address, &source, out) + .expect("Genesis contract failed to initialize"); + + #[cfg(not(feature = "with-ethereum-compatibility"))] + >::mark_deployed(*address, None).expect("Genesis contract failed to deploy"); + + let mut count = 0; + for (index, value) in &account.storage { + AccountStorages::::insert(address, index, value); + count += 1; + } + + let storage = count * handler::STORAGE_SIZE; + handler + .reserve_storage(storage) + .expect("Genesis contract failed to reserve storage"); + handler + .charge_storage(address, storage, 0) + .expect("Genesis contract failed to charge storage"); + } + }); + NetworkContractIndex::::put(MIRRORED_NFT_ADDRESS_START); + } + } + + /// EVM events + #[pallet::event] + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event { + /// Ethereum events from contracts. + Log(Log), + /// A contract has been created at given \[address\]. + Created(EvmAddress), + /// A contract was attempted to be created, but the execution failed. + /// \[contract, exit_reason, output\] + CreatedFailed(EvmAddress, ExitReason, Vec), + /// A \[contract\] has been executed successfully with states applied. + Executed(EvmAddress), + /// A contract has been executed with errors. States are reverted with + /// only gas fees applied. \[contract, exit_reason, output\] + ExecutedFailed(EvmAddress, ExitReason, Vec), + /// A deposit has been made at a given address. \[sender, address, + /// value\] + BalanceDeposit(T::AccountId, EvmAddress, U256), + /// A withdrawal has been made from a given address. \[sender, address, + /// value\] + BalanceWithdraw(T::AccountId, EvmAddress, U256), + /// A quota has been added at a given address. \[address, bytes\] + AddStorageQuota(EvmAddress, u32), + /// A quota has been removed at a given address. \[address, bytes\] + RemoveStorageQuota(EvmAddress, u32), + /// Transferred maintainer. \[contract, address\] + TransferredMaintainer(EvmAddress, EvmAddress), + /// Canceled the transfer maintainer. \[contract, address\] + CanceledTransferMaintainer(EvmAddress, EvmAddress), + /// Confirmed the transfer maintainer. \[contract, address\] + ConfirmedTransferMaintainer(EvmAddress, EvmAddress), + /// Rejected the transfer maintainer. \[contract, address\] + RejectedTransferMaintainer(EvmAddress, EvmAddress), + /// Enabled contract development. \[who\] + ContractDevelopmentEnabled(T::AccountId), + /// Disabled contract development. \[who\] + ContractDevelopmentDisabled(T::AccountId), + /// Deployed contract. \[contract\] + ContractDeployed(EvmAddress), + /// Set contract code. \[contract\] + ContractSetCode(EvmAddress), + /// Selfdestructed contract code. \[contract\] + ContractSelfdestructed(EvmAddress), + } + + #[pallet::error] + pub enum Error { + /// Address not mapped + AddressNotMapped, + /// Contract not found + ContractNotFound, + /// No permission + NoPermission, + /// Number out of bound in calculation. + NumOutOfBound, + /// Storage exceeds max code size + StorageExceedsStorageLimit, + /// Contract development is not enabled + ContractDevelopmentNotEnabled, + /// Contract development is already enabled + ContractDevelopmentAlreadyEnabled, + /// Contract already deployed + ContractAlreadyDeployed, + /// Contract exceeds max code size + ContractExceedsMaxCodeSize, + /// Storage usage exceeds storage limit + OutOfStorage, + /// Charge fee failed + ChargeFeeFailed, + /// Contract cannot be killed due to reference count + CannotKillContract, + /// Contract address conflicts with the system contract + ConflictContractAddress, + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet { + /// Issue an EVM call operation. This is similar to a message call + /// transaction in Ethereum. + /// + /// - `target`: the contract address to call + /// - `input`: the data supplied for the call + /// - `value`: the amount sent for payable calls + /// - `gas_limit`: the maximum gas the call can use + /// - `storage_limit`: the total bytes the contract's storage can increase by + #[pallet::weight(T::GasToWeight::convert(*gas_limit))] + pub fn call( + origin: OriginFor, + target: EvmAddress, + input: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let source = T::AddressMapping::get_or_create_evm_address(&who); + + let info = Runner::::call( + source, + source, + target, + input, + value, + gas_limit, + storage_limit, + T::config(), + )?; + + if info.exit_reason.is_succeed() { + Pallet::::deposit_event(Event::::Executed(target)); + } else { + Pallet::::deposit_event(Event::::ExecutedFailed(target, info.exit_reason, info.output)); + } + + let used_gas: u64 = info.used_gas.unique_saturated_into(); + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::convert(used_gas)), + pays_fee: Pays::Yes, + }) + } + + /// Issue an EVM call operation on a scheduled contract call, and + /// refund the unused gas reserved when the call was scheduled. + /// + /// - `from`: the address the scheduled call originates from + /// - `target`: the contract address to call + /// - `input`: the data supplied for the call + /// - `value`: the amount sent for payable calls + /// - `gas_limit`: the maximum gas the call can use + /// - `storage_limit`: the total bytes the contract's storage can increase by + #[pallet::weight(T::GasToWeight::convert(*gas_limit))] + #[transactional] + pub fn scheduled_call( + origin: OriginFor, + from: EvmAddress, + target: EvmAddress, + input: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + let _from_account = T::AddressMapping::get_account_id(&from); + let _payed: NegativeImbalanceOf; + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + // unreserve the transaction fee for gas_limit + let weight = T::GasToWeight::convert(gas_limit); + let (_, imbalance) = T::ChargeTransactionPayment::unreserve_and_charge_fee(&_from_account, weight) + .map_err(|_| Error::::ChargeFeeFailed)?; + _payed = imbalance; + } + + let info = Runner::::call(from, from, target, input, value, gas_limit, storage_limit, T::config())?; + + if info.exit_reason.is_succeed() { + Pallet::::deposit_event(Event::::Executed(target)); + } else { + Pallet::::deposit_event(Event::::ExecutedFailed(target, info.exit_reason, info.output)); + } + + let used_gas: u64 = info.used_gas.unique_saturated_into(); + + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + use sp_runtime::traits::Zero; + let refund_gas = gas_limit.saturating_sub(used_gas); + if !refund_gas.is_zero() { + // ignore the result to continue. if it fails, just the user will not + // be refunded, there will not increase user balance. + let res = T::ChargeTransactionPayment::refund_fee( + &_from_account, + T::GasToWeight::convert(refund_gas), + _payed, + ); + debug_assert!(res.is_ok()); + } + } + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::convert(used_gas)), + pays_fee: Pays::Yes, + }) + } + + /// Issue an EVM create operation. This is similar to a contract + /// creation transaction in Ethereum. + /// + /// - `init`: the data supplied for the contract's constructor + /// - `value`: the amount sent to the contract upon creation + /// - `gas_limit`: the maximum gas the call can use + /// - `storage_limit`: the total bytes the contract's storage can increase by + #[pallet::weight(T::GasToWeight::convert(*gas_limit))] + pub fn create( + origin: OriginFor, + init: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let source = T::AddressMapping::get_or_create_evm_address(&who); + + let info = Runner::::create(source, init, value, gas_limit, storage_limit, T::config())?; + + if info.exit_reason.is_succeed() { + Pallet::::deposit_event(Event::::Created(info.address)); + } else { + Pallet::::deposit_event(Event::::CreatedFailed(info.address, info.exit_reason, info.output)); + } + + let used_gas: u64 = info.used_gas.unique_saturated_into(); + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::convert(used_gas)), + pays_fee: Pays::Yes, + }) + } + + /// Issue an EVM create2 operation. + /// + /// - `target`: the contract address to call + /// - `init`: the data supplied for the contract's constructor + /// - `salt`: used for generating the new contract's address + /// - `value`: the amount sent for payable calls + /// - `gas_limit`: the maximum gas the call can use + /// - `storage_limit`: the total bytes the contract's storage can increase by + #[pallet::weight(T::GasToWeight::convert(*gas_limit))] + pub fn create2( + origin: OriginFor, + init: Vec, + salt: H256, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let source = T::AddressMapping::get_or_create_evm_address(&who); + + let info = Runner::::create2(source, init, salt, value, gas_limit, storage_limit, T::config())?; + + if info.exit_reason.is_succeed() { + Pallet::::deposit_event(Event::::Created(info.address)); + } else { + Pallet::::deposit_event(Event::::CreatedFailed(info.address, info.exit_reason, info.output)); + } + + let used_gas: u64 = info.used_gas.unique_saturated_into(); + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::convert(used_gas)), + pays_fee: Pays::Yes, + }) + } + + /// Issue an EVM create operation. The next available system contract + /// address will be used as created contract address. + /// + /// - `init`: the data supplied for the contract's constructor + /// - `value`: the amount sent for payable calls + /// - `gas_limit`: the maximum gas the call can use + /// - `storage_limit`: the total bytes the contract's storage can increase by + #[pallet::weight(T::GasToWeight::convert(*gas_limit))] + pub fn create_network_contract( + origin: OriginFor, + init: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + ) -> DispatchResultWithPostInfo { + T::NetworkContractOrigin::ensure_origin(origin)?; + + let source = T::NetworkContractSource::get(); + let address = EvmAddress::from_low_u64_be(Self::network_contract_index()); + let info = + Runner::::create_at_address(source, init, value, address, gas_limit, storage_limit, T::config())?; + + NetworkContractIndex::::mutate(|v| *v = v.saturating_add(One::one())); + + if info.exit_reason.is_succeed() { + Pallet::::deposit_event(Event::::Created(info.address)); + } else { + Pallet::::deposit_event(Event::::CreatedFailed(info.address, info.exit_reason, info.output)); + } + + let used_gas: u64 = info.used_gas.unique_saturated_into(); + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::convert(used_gas)), + pays_fee: Pays::Yes, + }) + } + + /// Transfers Contract maintainership to a new EVM Address. + /// + /// - `contract`: the contract whose maintainership is being transferred, the caller must be + /// the contract's maintainer + /// - `new_maintainer`: the address of the new maintainer + #[pallet::weight(::WeightInfo::transfer_maintainer())] + #[transactional] + pub fn transfer_maintainer( + origin: OriginFor, + contract: EvmAddress, + new_maintainer: EvmAddress, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + Self::do_transfer_maintainer(who, contract, new_maintainer)?; + + Pallet::::deposit_event(Event::::TransferredMaintainer(contract, new_maintainer)); + + Ok(().into()) + } + + /// Mark a given contract as deployed. + /// + /// - `contract`: The contract to mark as deployed, the caller must the contract's + /// maintainer + #[pallet::weight(::WeightInfo::deploy())] + #[transactional] + pub fn deploy(origin: OriginFor, contract: EvmAddress) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let address = T::AddressMapping::get_evm_address(&who).ok_or(Error::::AddressNotMapped)?; + T::Currency::transfer( + &who, + &T::TreasuryAccount::get(), + T::DeploymentFee::get(), + ExistenceRequirement::AllowDeath, + )?; + Self::mark_deployed(contract, Some(address))?; + Pallet::::deposit_event(Event::::ContractDeployed(contract)); + Ok(().into()) + } + + /// Mark a given contract as deployed without paying the deployment fee + /// + /// - `contract`: The contract to mark as deployed, the caller must be the contract's + /// maintainer. + #[pallet::weight(::WeightInfo::deploy_free())] + #[transactional] + pub fn deploy_free(origin: OriginFor, contract: EvmAddress) -> DispatchResultWithPostInfo { + T::FreeDeploymentOrigin::ensure_origin(origin)?; + Self::mark_deployed(contract, None)?; + Pallet::::deposit_event(Event::::ContractDeployed(contract)); + Ok(().into()) + } + + /// Mark the caller's address to allow contract development. + /// This allows the address to interact with non-deployed contracts. + #[pallet::weight(::WeightInfo::enable_contract_development())] + #[transactional] + pub fn enable_contract_development(origin: OriginFor) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let address = T::AddressMapping::get_or_create_evm_address(&who); + T::Currency::reserve(&who, T::DeveloperDeposit::get())?; + Accounts::::mutate(address, |maybe_account_info| -> DispatchResult { + if let Some(account_info) = maybe_account_info.as_mut() { + ensure!( + account_info.developer_deposit.is_none(), + Error::::ContractDevelopmentAlreadyEnabled + ); + account_info.developer_deposit = Some(T::DeveloperDeposit::get()); + } else { + let mut account_info = AccountInfo::::new(Default::default(), None); + account_info.developer_deposit = Some(T::DeveloperDeposit::get()); + *maybe_account_info = Some(account_info); + } + Ok(()) + })?; + Pallet::::deposit_event(Event::::ContractDevelopmentEnabled(who)); + Ok(().into()) + } + + /// Mark the caller's address to disable contract development. + /// This disallows the address to interact with non-deployed contracts. + #[pallet::weight(::WeightInfo::disable_contract_development())] + #[transactional] + pub fn disable_contract_development(origin: OriginFor) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let address = T::AddressMapping::get_evm_address(&who).ok_or(Error::::AddressNotMapped)?; + let deposit = Accounts::::mutate(address, |maybe_account_info| -> Result, Error> { + let account_info = maybe_account_info + .as_mut() + .ok_or(Error::::ContractDevelopmentNotEnabled)?; + account_info + .developer_deposit + .take() + .ok_or(Error::::ContractDevelopmentNotEnabled) + })?; + T::Currency::unreserve(&who, deposit); + Pallet::::deposit_event(Event::::ContractDevelopmentDisabled(who)); + Ok(().into()) + } + + /// Set the code of a contract at a given address. + /// + /// - `contract`: The contract whose code is being set, must not be marked as deployed + /// - `code`: The new ABI bundle for the contract + #[pallet::weight(::WeightInfo::set_code())] + #[transactional] + pub fn set_code(origin: OriginFor, contract: EvmAddress, code: Vec) -> DispatchResultWithPostInfo { + let root_or_signed = Self::ensure_root_or_signed(origin)?; + Self::do_set_code(root_or_signed, contract, code)?; + + Pallet::::deposit_event(Event::::ContractSetCode(contract)); + + Ok(().into()) + } + + /// Remove a contract at a given address. + /// + /// - `contract`: The contract to remove, must not be marked as deployed + #[pallet::weight(::WeightInfo::selfdestruct())] + #[transactional] + pub fn selfdestruct(origin: OriginFor, contract: EvmAddress) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let maintainer = T::AddressMapping::get_evm_address(&who).ok_or(Error::::AddressNotMapped)?; + Self::do_selfdestruct(who, &maintainer, contract)?; + + Pallet::::deposit_event(Event::::ContractSelfdestructed(contract)); + + Ok(().into()) + } + } +} + +impl Pallet { + #[transactional] + pub fn remove_contract(address: &EvmAddress, dest: &EvmAddress) -> Result { + let address_account = T::AddressMapping::get_account_id(&address); + let dest_account = T::AddressMapping::get_account_id(&dest); + + let size = Accounts::::try_mutate_exists(address, |account_info| -> Result { + let account_info = account_info.as_mut().ok_or(Error::::ContractNotFound)?; + let contract_info = account_info.contract_info.take().ok_or(Error::::ContractNotFound)?; + + T::TransferAll::transfer_all(&address_account, &dest_account)?; + + CodeInfos::::mutate_exists(&contract_info.code_hash, |maybe_code_info| { + if let Some(code_info) = maybe_code_info.as_mut() { + code_info.ref_count = code_info.ref_count.saturating_sub(1); + if code_info.ref_count == 0 { + Codes::::remove(&contract_info.code_hash); + *maybe_code_info = None; + } + } else { + // code info removed while still having reference to it? + debug_assert!(false); + } + }); + + AccountStorages::::remove_prefix(address); + + let size = ContractStorageSizes::::take(address); + + Ok(size) + })?; + + // this should happen after `Accounts` is updated because this could trigger another updates on + // `Accounts` + frame_system::Pallet::::dec_providers(&address_account).map_err(|e| match e { + frame_system::DecRefError::ConsumerRemaining => DispatchError::ConsumerRemaining, + })?; + + Ok(size) + } + + /// Removes an account from Accounts and AccountStorages. + pub fn remove_account(address: &EvmAddress) -> Result<(), ExitError> { + // Deref code, and remove it if ref count is zero. + if let Some(AccountInfo { + contract_info: Some(contract_info), + .. + }) = Self::accounts(address) + { + CodeInfos::::mutate_exists(&contract_info.code_hash, |maybe_code_info| { + if let Some(code_info) = maybe_code_info.as_mut() { + code_info.ref_count = code_info.ref_count.saturating_sub(1); + if code_info.ref_count == 0 { + Codes::::remove(&contract_info.code_hash); + *maybe_code_info = None; + } + } + }); + } + + if let Some(AccountInfo { + contract_info: Some(_), .. + }) = Accounts::::take(address) + { + // remove_account can only be called when account is killed. i.e. providers == 0 + // but contract_info should maintain a provider + // so this should never happen + debug_assert!(false); + } + + Ok(()) + } + + /// Get the account basic in EVM format. + pub fn account_basic(address: &EvmAddress) -> Account { + let account_id = T::AddressMapping::get_account_id(address); + + let nonce = Self::accounts(address).map_or(Default::default(), |account_info| account_info.nonce); + let balance = T::Currency::free_balance(&account_id); + + Account { + nonce: U256::from(UniqueSaturatedInto::::unique_saturated_into(nonce)), + balance: U256::from(UniqueSaturatedInto::::unique_saturated_into(balance)), + } + } + + /// Get code hash at given address. + pub fn code_hash_at_address(address: &EvmAddress) -> H256 { + if let Some(AccountInfo { + contract_info: Some(contract_info), + .. + }) = Self::accounts(address) + { + contract_info.code_hash + } else { + code_hash(&[]) + } + } + + /// Get code at given address. + pub fn code_at_address(address: &EvmAddress) -> BoundedVec { + Self::codes(&Self::code_hash_at_address(address)) + } + + pub fn update_contract_storage_size(address: &EvmAddress, change: i32) { + if change == 0 { + return; + } + ContractStorageSizes::::mutate(address, |val| { + if change > 0 { + *val = val.saturating_add(change as u32); + } else { + *val = val.saturating_sub((-change) as u32); + } + }); + } + + /// Handler on new contract initialization. + /// + /// - Create new account for the contract. + /// - Update codes info. + /// - Save `code` if not saved yet. + pub fn on_contract_initialization( + address: &EvmAddress, + maintainer: &EvmAddress, + code: Vec, + ) -> Result<(), ExitError> { + let bounded_code: BoundedVec = code.try_into().map_err(|_| ExitError::OutOfGas)?; + let code_hash = code_hash(&bounded_code.as_slice()); + let code_size = bounded_code.len() as u32; + + let contract_info = ContractInfo { + code_hash, + maintainer: *maintainer, + #[cfg(feature = "with-ethereum-compatibility")] + deployed: true, + #[cfg(not(feature = "with-ethereum-compatibility"))] + deployed: false, + }; + + Self::update_contract_storage_size( + address, + code_size.saturating_add(T::NewContractExtraBytes::get()) as i32, + ); + + CodeInfos::::mutate_exists(&code_hash, |maybe_code_info| { + if let Some(code_info) = maybe_code_info.as_mut() { + code_info.ref_count = code_info.ref_count.saturating_add(1); + } else { + let new = CodeInfo { + code_size, + ref_count: 1, + }; + *maybe_code_info = Some(new); + + Codes::::insert(&code_hash, bounded_code); + } + }); + + Accounts::::mutate(address, |maybe_account_info| { + if let Some(account_info) = maybe_account_info.as_mut() { + account_info.contract_info = Some(contract_info.clone()); + } else { + let account_info = AccountInfo::::new(Default::default(), Some(contract_info.clone())); + *maybe_account_info = Some(account_info); + } + }); + + frame_system::Pallet::::inc_providers(&T::AddressMapping::get_account_id(address)); + + Ok(()) + } + + /// Sets a given contract's contract info to a new maintainer. + fn do_transfer_maintainer(who: T::AccountId, contract: EvmAddress, new_maintainer: EvmAddress) -> DispatchResult { + Accounts::::get(contract).map_or(Err(Error::::ContractNotFound), |account_info| { + account_info + .contract_info + .map_or(Err(Error::::ContractNotFound), |_| Ok(())) + })?; + + Accounts::::mutate(contract, |maybe_account_info| -> DispatchResult { + let account_info = maybe_account_info.as_mut().ok_or(Error::::ContractNotFound)?; + let contract_info = account_info + .contract_info + .as_mut() + .ok_or(Error::::ContractNotFound)?; + + let maintainer = T::AddressMapping::get_evm_address(&who).ok_or(Error::::AddressNotMapped)?; + ensure!(contract_info.maintainer == maintainer, Error::::NoPermission); + + contract_info.maintainer = new_maintainer; + Ok(()) + })?; + + Ok(()) + } + + /// Mark contract as deployed + /// + /// If maintainer is provider then it will check maintainer + fn mark_deployed(contract: EvmAddress, maintainer: Option) -> DispatchResult { + Accounts::::mutate(contract, |maybe_account_info| -> DispatchResult { + if let Some(AccountInfo { + contract_info: Some(contract_info), + .. + }) = maybe_account_info.as_mut() + { + if let Some(maintainer) = maintainer { + ensure!(contract_info.maintainer == maintainer, Error::::NoPermission); + } + ensure!(!contract_info.deployed, Error::::ContractAlreadyDeployed); + contract_info.deployed = true; + Ok(()) + } else { + Err(Error::::ContractNotFound.into()) + } + }) + } + + /// Set the code of a contract at a given address. + /// + /// - Ensures signer is maintainer or root. + /// - Update codes info. + /// - Save `code`if not saved yet. + fn do_set_code(root_or_signed: Either<(), T::AccountId>, contract: EvmAddress, code: Vec) -> DispatchResult { + Accounts::::mutate(contract, |maybe_account_info| -> DispatchResult { + let account_info = maybe_account_info.as_mut().ok_or(Error::::ContractNotFound)?; + let contract_info = account_info + .contract_info + .as_ref() + .ok_or(Error::::ContractNotFound)?; + + let source = if let Either::Right(signer) = root_or_signed { + let maintainer = T::AddressMapping::get_evm_address(&signer).ok_or(Error::::AddressNotMapped)?; + ensure!(contract_info.maintainer == maintainer, Error::::NoPermission); + ensure!(!contract_info.deployed, Error::::ContractAlreadyDeployed); + maintainer + } else { + T::NetworkContractSource::get() + }; + + let code_size = code.len() as u32; + let code_hash = code_hash(&code.as_slice()); + if code_hash == contract_info.code_hash { + return Ok(()); + } + + ensure!( + code_size <= T::MaxCodeSize::get(), + Error::::ContractExceedsMaxCodeSize + ); + + Runner::::create_at_address( + source, + code, + Default::default(), + contract, + 2_100_000, + 100_000, + T::config(), + ) + .map(|_| ()) + }) + } + + /// Selfdestruct a contract at a given address. + fn do_selfdestruct(who: T::AccountId, maintainer: &EvmAddress, contract: EvmAddress) -> DispatchResult { + let account_info = Self::accounts(contract).ok_or(Error::::ContractNotFound)?; + let contract_info = account_info + .contract_info + .as_ref() + .ok_or(Error::::ContractNotFound)?; + + ensure!(contract_info.maintainer == *maintainer, Error::::NoPermission); + ensure!(!contract_info.deployed, Error::::ContractAlreadyDeployed); + + let storage = Self::remove_contract(&contract, &maintainer)?; + + let contract_account = T::AddressMapping::get_account_id(&contract); + + let amount = T::StorageDepositPerByte::get().saturating_mul(storage.into()); + let val = T::Currency::repatriate_reserved(&contract_account, &who, amount, BalanceStatus::Free)?; + debug_assert!(val.is_zero()); + + Ok(()) + } + + fn ensure_root_or_signed(o: T::Origin) -> Result, BadOrigin> { + EnsureOneOf::, EnsureSigned>::try_origin(o) + .map_or(Err(BadOrigin), Ok) + } +} + +impl EVMTrait for Pallet { + type Balance = BalanceOf; + fn execute( + context: InvokeContext, + input: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + mode: ExecutionMode, + ) -> Result { + let mut config = T::config().clone(); + if let ExecutionMode::EstimateGas = mode { + config.estimate = true; + } + + frame_support::storage::with_transaction(|| { + let result = Runner::::call( + context.sender, + context.origin, + context.contract, + input, + value, + gas_limit, + storage_limit, + &config, + ); + + match result { + Ok(info) => match mode { + ExecutionMode::Execute => { + if info.exit_reason.is_succeed() { + Pallet::::deposit_event(Event::::Executed(context.contract)); + TransactionOutcome::Commit(Ok(info)) + } else { + Pallet::::deposit_event(Event::::ExecutedFailed( + context.contract, + info.exit_reason.clone(), + info.output.clone(), + )); + TransactionOutcome::Rollback(Ok(info)) + } + } + ExecutionMode::View | ExecutionMode::EstimateGas => TransactionOutcome::Rollback(Ok(info)), + }, + Err(e) => TransactionOutcome::Rollback(Err(e)), + } + }) + } + + /// Get the real origin account and charge storage rent from the origin. + fn get_origin() -> Option { + ExtrinsicOrigin::::get() + } + + /// Provide a method to set origin for `on_initialize` + fn set_origin(origin: T::AccountId) { + ExtrinsicOrigin::::set(Some(origin)); + } +} + +impl EVMStateRentTrait> for Pallet { + fn query_new_contract_extra_bytes() -> u32 { + T::NewContractExtraBytes::get() + } + + fn query_storage_deposit_per_byte() -> BalanceOf { + T::StorageDepositPerByte::get() + } + + fn query_maintainer(contract: EvmAddress) -> Result { + Accounts::::get(contract).map_or(Err(Error::::ContractNotFound.into()), |account_info| { + account_info + .contract_info + .map_or(Err(Error::::ContractNotFound.into()), |v| Ok(v.maintainer)) + }) + } + + fn query_developer_deposit() -> BalanceOf { + T::DeveloperDeposit::get() + } + + fn query_deployment_fee() -> BalanceOf { + T::DeploymentFee::get() + } + + fn transfer_maintainer(from: T::AccountId, contract: EvmAddress, new_maintainer: EvmAddress) -> DispatchResult { + Pallet::::do_transfer_maintainer(from, contract, new_maintainer) + } +} + +pub struct CallKillAccount(PhantomData); +impl OnKilledAccount for CallKillAccount { + fn on_killed_account(who: &T::AccountId) { + if let Some(address) = T::AddressMapping::get_evm_address(who) { + let res = Pallet::::remove_account(&address); + debug_assert!(res.is_ok()); + } + let address = T::AddressMapping::get_default_evm_address(who); + let res = Pallet::::remove_account(&address); + debug_assert!(res.is_ok()); + } +} + +pub fn code_hash(code: &[u8]) -> H256 { + H256::from_slice(Keccak256::digest(code).as_slice()) +} + +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct SetEvmOrigin(PhantomData); + +impl sp_std::fmt::Debug for SetEvmOrigin { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "SetEvmOrigin") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl SetEvmOrigin { + pub fn new() -> Self { + Self(sp_std::marker::PhantomData) + } +} + +impl Default for SetEvmOrigin { + fn default() -> Self { + Self::new() + } +} + +impl SignedExtension for SetEvmOrigin { + const IDENTIFIER: &'static str = "SetEvmOrigin"; + type AccountId = T::AccountId; + type Call = T::Call; + type AdditionalSigned = (); + type Pre = (); + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result<(), TransactionValidityError> { + ExtrinsicOrigin::::set(Some(who.clone())); + Ok(()) + } + + fn post_dispatch( + _pre: Self::Pre, + _info: &DispatchInfoOf, + _post_info: &PostDispatchInfoOf, + _len: usize, + _result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + ExtrinsicOrigin::::kill(); + Ok(()) + } +} diff --git a/lib-serml/evm/src/mock.rs b/lib-serml/evm/src/mock.rs new file mode 100644 index 000000000..fb9b94b30 --- /dev/null +++ b/lib-serml/evm/src/mock.rs @@ -0,0 +1,280 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(test)] + +use super::*; + +use frame_support::{construct_runtime, ord_parameter_types, parameter_types}; +use frame_system::EnsureSignedBy; +use orml_traits::parameter_type_with_key; +use primitives::{Amount, BlockNumber, CurrencyId, TokenSymbol}; +use sp_core::{H160, H256}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + AccountId32, +}; +use std::{collections::BTreeMap, str::FromStr}; +use support::mocks::MockAddressMapping; + +mod evm_mod { + pub use super::super::*; +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Test { + type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId32; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = crate::CallKillAccount; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Config for Test { + type Balance = u64; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 1000; +} +impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> u64 { + Default::default() + }; +} + +impl orml_tokens::Config for Test { + type Event = Event; + type Balance = u64; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = (); +} + +parameter_types! { + pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); +} + +impl orml_currencies::Config for Test { + type Event = Event; + type MultiCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type GetNativeCurrencyId = GetNativeCurrencyId; + type WeightInfo = (); +} +pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter; + +pub struct GasToWeight; + +impl Convert for GasToWeight { + fn convert(a: u64) -> u64 { + a + } +} + +parameter_types! { + pub NetworkContractSource: H160 = alice(); +} + +ord_parameter_types! { + pub const CouncilAccount: AccountId32 = AccountId32::from([1u8; 32]); + pub const TreasuryAccount: AccountId32 = AccountId32::from([2u8; 32]); + pub const NetworkContractAccount: AccountId32 = AccountId32::from([0u8; 32]); + pub const NewContractExtraBytes: u32 = 100; + pub const StorageDepositPerByte: u64 = 10; + pub const DeveloperDeposit: u64 = 1000; + pub const DeploymentFee: u64 = 200; + pub const MaxCodeSize: u32 = 1000; + pub const ChainId: u64 = 1; +} + +impl Config for Test { + type AddressMapping = MockAddressMapping; + type Currency = Balances; + type TransferAll = Currencies; + type NewContractExtraBytes = NewContractExtraBytes; + type StorageDepositPerByte = StorageDepositPerByte; + type MaxCodeSize = MaxCodeSize; + + type Event = Event; + type Precompiles = (); + type ChainId = ChainId; + type GasToWeight = GasToWeight; + type ChargeTransactionPayment = (); + + type NetworkContractOrigin = EnsureSignedBy; + type NetworkContractSource = NetworkContractSource; + type DeveloperDeposit = DeveloperDeposit; + type DeploymentFee = DeploymentFee; + type TreasuryAccount = TreasuryAccount; + type FreeDeploymentOrigin = EnsureSignedBy; + + type WeightInfo = (); +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + EVM: evm_mod::{Pallet, Config, Call, Storage, Event}, + Tokens: orml_tokens::{Pallet, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Currencies: orml_currencies::{Pallet, Call, Event}, + } +); + +pub const INITIAL_BALANCE: u64 = 1_000_000_000_000; + +pub fn contract_a() -> H160 { + H160::from_str("2000000000000000000000000000000000000001").unwrap() +} + +pub fn contract_b() -> H160 { + H160::from_str("2000000000000000000000000000000000000002").unwrap() +} + +pub fn alice() -> H160 { + H160::from_str("1000000000000000000000000000000000000001").unwrap() +} + +pub fn bob() -> H160 { + H160::from_str("1000000000000000000000000000000000000002").unwrap() +} + +pub fn charlie() -> H160 { + H160::from_str("1000000000000000000000000000000000000003").unwrap() +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + let mut accounts = BTreeMap::new(); + + accounts.insert( + contract_a(), + GenesisAccount { + nonce: 1, + balance: Default::default(), + storage: Default::default(), + code: Default::default(), + }, + ); + accounts.insert( + contract_b(), + GenesisAccount { + nonce: 1, + balance: Default::default(), + storage: Default::default(), + code: Default::default(), + }, + ); + + accounts.insert( + alice(), + GenesisAccount { + nonce: 1, + balance: INITIAL_BALANCE, + storage: Default::default(), + code: Default::default(), + }, + ); + accounts.insert( + bob(), + GenesisAccount { + nonce: 1, + balance: INITIAL_BALANCE, + storage: Default::default(), + code: Default::default(), + }, + ); + + pallet_balances::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + evm_mod::GenesisConfig:: { + accounts, + treasury: Default::default(), + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub fn balance(address: H160) -> u64 { + let account_id = ::AddressMapping::get_account_id(&address); + Balances::free_balance(account_id) +} + +pub fn reserved_balance(address: H160) -> u64 { + let account_id = ::AddressMapping::get_account_id(&address); + Balances::reserved_balance(account_id) +} + +pub fn deploy_free(contract: H160) { + let _ = EVM::deploy_free(Origin::signed(CouncilAccount::get()), contract); +} diff --git a/lib-serml/evm/src/precompiles.rs b/lib-serml/evm/src/precompiles.rs new file mode 100644 index 000000000..b290b8596 --- /dev/null +++ b/lib-serml/evm/src/precompiles.rs @@ -0,0 +1,358 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Builtin precompiles. + +use evm::{Context, ExitError, ExitSucceed}; +use impl_trait_for_tuples::impl_for_tuples; +use primitive_types::H160; +use ripemd160::Digest; +use sp_runtime::SaturatedConversion; +use sp_std::{cmp::min, marker::PhantomData, vec::Vec}; +use tiny_keccak::Hasher; + +/// Custom precompiles to be used by EVM engine. +pub trait Precompiles { + #![allow(clippy::type_complexity)] + /// Try to execute the code address as precompile. If the code address is + /// not a precompile or the precompile is not yet available, return `None`. + /// Otherwise, calculate the amount of gas needed with given `input` and + /// `target_gas`. Return `Some(Ok(status, output, gas_used))` if the + /// execution is successful. Otherwise return `Some(Err(_))`. + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + context: &Context, + ) -> Option, u64), ExitError>>; +} + +/// One single precompile used by EVM engine. +pub trait Precompile { + /// Try to execute the precompile. Calculate the amount of gas needed with + /// given `input` and `target_gas`. Return `Ok(status, output, gas_used)` if + /// the execution is successful. Otherwise return `Err(_)`. + fn execute( + input: &[u8], + target_gas: Option, + context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError>; +} + +#[impl_for_tuples(16)] +#[tuple_types_no_default_trait_bound] +impl Precompiles for Tuple { + for_tuples!( where #( Tuple: Precompile )* ); + #[allow(clippy::type_complexity)] + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + context: &Context, + ) -> Option, u64), ExitError>> { + let mut index = 0; + + for_tuples!( #( + index += 1; + if address == H160::from_low_u64_be(index) { + return Some(Tuple::execute(input, target_gas, context)) + } + )* ); + + None + } +} + +pub struct EvmPrecompiles( + PhantomData<( + ECRecover, + Sha256, + Ripemd160, + Identity, + ECRecoverPublicKey, + Sha3FIPS256, + Sha3FIPS512, + )>, +); + +impl Precompiles + for EvmPrecompiles +where + ECRecover: Precompile, + Sha256: Precompile, + Ripemd160: Precompile, + Identity: Precompile, + ECRecoverPublicKey: Precompile, + Sha3FIPS256: Precompile, + Sha3FIPS512: Precompile, +{ + #[allow(clippy::type_complexity)] + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + context: &Context, + ) -> Option, u64), ExitError>> { + // https://github.com/ethereum/go-ethereum/blob/9357280fce5c5d57111d690a336cca5f89e34da6/core/vm/contracts.go#L83 + if address == H160::from_low_u64_be(1) { + Some(ECRecover::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(2) { + Some(Sha256::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(3) { + Some(Ripemd160::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(4) { + Some(Identity::execute(input, target_gas, context)) + } + // Non-standard precompile starts with 128 + else if address == H160::from_low_u64_be(128) { + Some(ECRecoverPublicKey::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(129) { + Some(Sha3FIPS256::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(130) { + Some(Sha3FIPS512::execute(input, target_gas, context)) + } else { + None + } + } +} + +/// Linear gas cost +fn ensure_linear_cost(target_gas: Option, len: usize, base: usize, word: usize) -> Result { + let cost: u64 = base + .checked_add( + word.checked_mul(len.saturating_add(31) / 32) + .ok_or(ExitError::OutOfGas)?, + ) + .ok_or(ExitError::OutOfGas)? + .saturated_into(); + + if let Some(target_gas) = target_gas { + if cost > target_gas { + return Err(ExitError::OutOfGas); + } + } + + Ok(cost.saturated_into()) +} + +/// The identity precompile. +pub struct Identity; + +impl Precompile for Identity { + fn execute( + input: &[u8], + target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 15, 3)?; + + Ok((ExitSucceed::Returned, input.to_vec(), cost)) + } +} + +/// The ecrecover precompile. +pub struct ECRecover; + +impl Precompile for ECRecover { + fn execute( + i: &[u8], + target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + let cost = ensure_linear_cost(target_gas, i.len(), 3000, 0)?; + + let mut input = [0u8; 128]; + input[..min(i.len(), 128)].copy_from_slice(&i[..min(i.len(), 128)]); + + let mut msg = [0u8; 32]; + let mut sig = [0u8; 65]; + + msg[0..32].copy_from_slice(&input[0..32]); + sig[0..32].copy_from_slice(&input[64..96]); + sig[32..64].copy_from_slice(&input[96..128]); + sig[64] = input[63]; + + let pubkey = sp_io::crypto::secp256k1_ecdsa_recover(&sig, &msg) + .map_err(|_| ExitError::Other("Public key recover failed".into()))?; + let mut address = sp_io::hashing::keccak_256(&pubkey); + address[0..12].copy_from_slice(&[0u8; 12]); + + Ok((ExitSucceed::Returned, address.to_vec(), cost)) + } +} + +/// The ripemd precompile. +pub struct Ripemd160; + +impl Precompile for Ripemd160 { + fn execute( + input: &[u8], + target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 600, 120)?; + + let mut ret = [0u8; 32]; + ret[12..32].copy_from_slice(&ripemd160::Ripemd160::digest(input)); + Ok((ExitSucceed::Returned, ret.to_vec(), cost)) + } +} + +/// The sha256 precompile. +pub struct Sha256; + +impl Precompile for Sha256 { + fn execute( + input: &[u8], + target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 60, 12)?; + + let ret = sp_io::hashing::sha2_256(input); + Ok((ExitSucceed::Returned, ret.to_vec(), cost)) + } +} + +/// The ecrecover precompile. +pub struct ECRecoverPublicKey; + +impl Precompile for ECRecoverPublicKey { + fn execute( + i: &[u8], + target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + let cost = ensure_linear_cost(target_gas, i.len(), 3000, 0)?; + + let mut input = [0u8; 128]; + input[..min(i.len(), 128)].copy_from_slice(&i[..min(i.len(), 128)]); + + let mut msg = [0u8; 32]; + let mut sig = [0u8; 65]; + + msg[0..32].copy_from_slice(&input[0..32]); + sig[0..32].copy_from_slice(&input[64..96]); + sig[32..64].copy_from_slice(&input[96..128]); + sig[64] = input[63]; + + let pubkey = sp_io::crypto::secp256k1_ecdsa_recover(&sig, &msg) + .map_err(|_| ExitError::Other("Public key recover failed".into()))?; + + Ok((ExitSucceed::Returned, pubkey.to_vec(), cost)) + } +} + +/// The Sha3FIPS256 precompile. +pub struct Sha3FIPS256; + +impl Precompile for Sha3FIPS256 { + fn execute( + input: &[u8], + target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 60, 12)?; + + let mut output = [0; 32]; + let mut sha3 = tiny_keccak::Sha3::v256(); + sha3.update(input); + sha3.finalize(&mut output); + Ok((ExitSucceed::Returned, output.to_vec(), cost)) + } +} + +/// The Sha3FIPS512 precompile. +pub struct Sha3FIPS512; + +impl Precompile for Sha3FIPS512 { + fn execute( + input: &[u8], + target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 60, 12)?; + + let mut output = [0; 64]; + let mut sha3 = tiny_keccak::Sha3::v512(); + sha3.update(input); + sha3.finalize(&mut output); + Ok((ExitSucceed::Returned, output.to_vec(), cost)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sha3_ipfs_256_should_works() -> std::result::Result<(), ExitError> { + let input = b"hello"; + let expected = b"\ + \x33\x38\xbe\x69\x4f\x50\xc5\xf3\x38\x81\x49\x86\xcd\xf0\x68\x64\ + \x53\xa8\x88\xb8\x4f\x42\x4d\x79\x2a\xf4\xb9\x20\x23\x98\xf3\x92\ + "; + + match Sha3FIPS256::execute( + input, + None, + &Context { + address: Default::default(), + caller: Default::default(), + apparent_value: Default::default(), + }, + ) { + Ok((_, out, _)) => { + assert_eq!(out, expected); + Ok(()) + } + Err(e) => { + panic!("Test not expected to fail: {:?}", e); + } + } + } + + #[test] + fn sha3_ipfs_512_should_works() -> std::result::Result<(), ExitError> { + let input = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; + let expected = b"\ + \xf3\x2a\x94\x23\x55\x13\x51\xdf\x0a\x07\xc0\xb8\xc2\x0e\xb9\x72\ + \x36\x7c\x39\x8d\x61\x06\x60\x38\xe1\x69\x86\x44\x8e\xbf\xbc\x3d\ + \x15\xed\xe0\xed\x36\x93\xe3\x90\x5e\x9a\x8c\x60\x1d\x9d\x00\x2a\ + \x06\x85\x3b\x97\x97\xef\x9a\xb1\x0c\xbd\xe1\x00\x9c\x7d\x0f\x09\ + "; + + match Sha3FIPS512::execute( + input, + None, + &Context { + address: Default::default(), + caller: Default::default(), + apparent_value: Default::default(), + }, + ) { + Ok((_, out, _)) => { + assert_eq!(out, expected); + Ok(()) + } + Err(e) => { + panic!("Test not expected to fail: {:?}", e); + } + } + } +} diff --git a/lib-serml/evm/src/runner/handler.rs b/lib-serml/evm/src/runner/handler.rs new file mode 100644 index 000000000..b5653da70 --- /dev/null +++ b/lib-serml/evm/src/runner/handler.rs @@ -0,0 +1,793 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![allow(clippy::type_complexity)] + +use crate::{ + precompiles::Precompiles, + runner::storage_meter::{StorageMeter, StorageMeterHandler}, + AccountInfo, AccountStorages, Accounts, AddressMapping, Codes, Config, ContractInfo, Error, Event, Log, Pallet, + Vicinity, +}; +use evm::{Capture, Context, CreateScheme, ExitError, ExitReason, Opcode, Runtime, Stack, Transfer}; +use evm_gasometer::{self as gasometer, Gasometer}; +use evm_runtime::{Config as EvmRuntimeConfig, Handler as HandlerT}; +use frame_support::{ + log, + traits::{BalanceStatus, Currency, ExistenceRequirement, Get, ReservableCurrency}, +}; +use primitive_types::{H160, H256, U256}; +use primitives::{H160_PREFIX_DEXSHARE, H160_PREFIX_TOKEN, PREDEPLOY_ADDRESS_START, SYSTEM_CONTRACT_ADDRESS_PREFIX}; +use sha3::{Digest, Keccak256}; +use sp_runtime::{ + traits::{One, Saturating, UniqueSaturatedInto, Zero}, + DispatchError, DispatchResult, SaturatedConversion, TransactionOutcome, +}; +use sp_std::{cmp::min, convert::Infallible, marker::PhantomData, prelude::*, rc::Rc}; + +/// Storage key size and storage value size. +pub const STORAGE_SIZE: u32 = 64; + +pub struct Handler<'vicinity, 'config, 'meter, T: Config> { + pub vicinity: &'vicinity Vicinity, + pub config: &'config EvmRuntimeConfig, + pub gasometer: Gasometer<'config>, + pub storage_meter: StorageMeter<'meter>, + pub is_static: bool, + _marker: PhantomData, +} + +fn l64(gas: u64) -> u64 { + gas - gas / 64 +} + +impl<'vicinity, 'config, 'meter, T: Config> Handler<'vicinity, 'config, 'meter, T> { + pub fn new( + vicinity: &'vicinity Vicinity, + gas_limit: u64, + storage_meter: StorageMeter<'meter>, + is_static: bool, + config: &'config EvmRuntimeConfig, + ) -> Self { + Handler::<'vicinity, 'config, '_, T> { + vicinity, + config, + is_static, + gasometer: Gasometer::new(gas_limit, config), + storage_meter, + _marker: PhantomData, + } + } + + pub fn run_transaction) -> TransactionOutcome>( + vicinity: &'vicinity Vicinity, + gas_limit: u64, + storage_limit: u32, + contract: H160, + is_static: bool, + config: &'config EvmRuntimeConfig, + f: F, + ) -> Result { + frame_support::storage::with_transaction(|| { + let mut storage_meter_handler = StorageMeterHandlerImpl::::new(vicinity.origin); + let storage_meter = match StorageMeter::new(&mut storage_meter_handler, contract, storage_limit) { + Ok(x) => x, + Err(e) => return TransactionOutcome::Rollback(Err(e)), + }; + + let mut substate = Handler::new(vicinity, gas_limit, storage_meter, is_static, config); + + match f(&mut substate) { + TransactionOutcome::Commit(r) => match substate.storage_meter.finish() { + Ok(_) => TransactionOutcome::Commit(Ok(r)), + Err(e) => TransactionOutcome::Rollback(Err(e)), + }, + TransactionOutcome::Rollback(e) => TransactionOutcome::Rollback(Ok(e)), + } + }) + } + + pub fn run_sub_transaction< + 'a, + R, + F: FnOnce(&mut Handler<'vicinity, 'config, '_, T>, &mut Gasometer<'_>) -> TransactionOutcome, + >( + &'a mut self, + vicinity: &'vicinity Vicinity, + gas_limit: u64, + contract: H160, + is_static: bool, + config: &'config EvmRuntimeConfig, + f: F, + ) -> Result { + frame_support::storage::with_transaction(|| { + let storage_meter = match self.storage_meter.child_meter(contract) { + Ok(x) => x, + Err(e) => return TransactionOutcome::Rollback(Err(e)), + }; + + let mut substate = Handler::new(vicinity, gas_limit, storage_meter, is_static, config); + + match f(&mut substate, &mut self.gasometer) { + TransactionOutcome::Commit(r) => match substate.storage_meter.finish() { + Ok(_) => TransactionOutcome::Commit(Ok(r)), + Err(e) => TransactionOutcome::Rollback(Err(e)), + }, + TransactionOutcome::Rollback(e) => TransactionOutcome::Rollback(Ok(e)), + } + }) + } + + /// Get used gas for the current executor, given the price. + pub fn used_gas(&self) -> u64 { + self.gasometer.total_used_gas() + - min( + self.gasometer.total_used_gas() / 2, + self.gasometer.refunded_gas() as u64, + ) + } + + pub fn used_storage(&self) -> i32 { + self.storage_meter.used_storage() + } + + pub fn execute( + &mut self, + caller: H160, + address: H160, + value: U256, + code: Vec, + input: Vec, + ) -> (ExitReason, Vec) { + let context = Context { + caller, + address, + apparent_value: value, + }; + + let mut runtime = Runtime::new(Rc::new(code), Rc::new(input), context, self.config); + + let reason = match runtime.run(self) { + Capture::Exit(s) => s, + Capture::Trap(_) => unreachable!("Trap is Infallible"), + }; + + match reason { + ExitReason::Succeed(s) => (s.into(), runtime.machine().return_value()), + ExitReason::Error(e) => (e.into(), Vec::new()), + ExitReason::Revert(e) => (e.into(), runtime.machine().return_value()), + ExitReason::Fatal(e) => { + self.gasometer.fail(); + (e.into(), Vec::new()) + } + } + } + + fn transfer(transfer: Transfer) -> Result<(), ExitError> { + let source = T::AddressMapping::get_account_id(&transfer.source); + let target = T::AddressMapping::get_account_id(&transfer.target); + + T::Currency::transfer( + &source, + &target, + transfer.value.saturated_into::().unique_saturated_into(), + ExistenceRequirement::AllowDeath, + ) + .map_err(|_| ExitError::OutOfGas) + } + + pub fn nonce(address: H160) -> U256 { + let account = Pallet::::account_basic(&address); + account.nonce + } + + pub fn inc_nonce(address: H160) { + Accounts::::mutate(&address, |maybe_account| { + if let Some(account) = maybe_account.as_mut() { + account.nonce += One::one() + } else { + let mut account_info = >::new(Default::default(), None); + account_info.nonce += One::one(); + *maybe_account = Some(account_info); + } + }); + } + + pub fn create_address(scheme: CreateScheme) -> Result { + let address = match scheme { + CreateScheme::Create2 { + caller, + code_hash, + salt, + } => { + let mut hasher = Keccak256::new(); + hasher.update(&[0xff]); + hasher.update(&caller[..]); + hasher.update(&salt[..]); + hasher.update(&code_hash[..]); + H256::from_slice(hasher.finalize().as_slice()).into() + } + CreateScheme::Legacy { caller } => { + let nonce = Self::nonce(caller); + let mut stream = rlp::RlpStream::new_list(2); + stream.append(&caller); + stream.append(&nonce); + H256::from_slice(Keccak256::digest(&stream.out()).as_slice()).into() + } + CreateScheme::Fixed(naddress) => naddress, + }; + + if address.as_bytes().starts_with(&SYSTEM_CONTRACT_ADDRESS_PREFIX) { + Err(ExitError::Other( + Into::<&str>::into(Error::::ConflictContractAddress).into(), + )) + } else { + Ok(address) + } + } + + pub fn can_call_contract(address: &H160, caller: &H160) -> bool { + if let Some(AccountInfo { + contract_info: Some(ContractInfo { + deployed, maintainer, .. + }), + .. + }) = Accounts::::get(address) + { + deployed || maintainer == *caller || Self::is_developer_or_contract(caller) + } else { + // contract non exist, we don't override defualt evm behaviour + true + } + } + + pub fn is_developer_or_contract(caller: &H160) -> bool { + if let Some(AccountInfo { + contract_info, + developer_deposit, + .. + }) = Accounts::::get(caller) + { + contract_info.is_some() || developer_deposit.is_some() + } else { + false + } + } + + fn handle_mirrored_token(address: H160) -> H160 { + log::debug!( + target: "evm", + "handle_mirrored_token: address: {:?}", + address, + ); + + let addr = address.as_bytes(); + if !addr.starts_with(&SYSTEM_CONTRACT_ADDRESS_PREFIX) { + return address; + } + + if addr.starts_with(&H160_PREFIX_TOKEN) || addr.starts_with(&H160_PREFIX_DEXSHARE) { + // Token contracts. + let token_address = H160::from_low_u64_be(PREDEPLOY_ADDRESS_START); + log::debug!( + target: "evm", + "handle_mirrored_token: origin address: {:?}, token address: {:?}", + address, + token_address + ); + token_address + } else { + address + } + } +} + +/// Create `try_or_fail` and `try_or_rollback`. +macro_rules! create_try { + ( $map_err:expr ) => { + #[allow(unused_macros)] + macro_rules! try_or_fail { + ( $e:expr ) => { + match $e { + Ok(v) => v, + Err(e) => return Capture::Exit($map_err(e)), + } + }; + } + + macro_rules! try_or_rollback { + ( $e:expr ) => { + match $e { + Ok(v) => v, + Err(e) => return TransactionOutcome::Rollback(Capture::Exit($map_err(e))), + } + }; + } + }; +} + +impl<'vicinity, 'config, 'meter, T: Config> HandlerT for Handler<'vicinity, 'config, 'meter, T> { + type CreateInterrupt = Infallible; + type CreateFeedback = Infallible; + type CallInterrupt = Infallible; + type CallFeedback = Infallible; + + fn balance(&self, address: H160) -> U256 { + let account = Pallet::::account_basic(&address); + account.balance + } + + fn code_size(&self, address: H160) -> U256 { + let addr = Self::handle_mirrored_token(address); + let code_hash = self.code_hash(addr); + U256::from(Codes::::decode_len(&code_hash).unwrap_or(0)) + } + + fn code_hash(&self, address: H160) -> H256 { + let addr = Self::handle_mirrored_token(address); + Pallet::::code_hash_at_address(&addr) + } + + fn code(&self, address: H160) -> Vec { + let addr = Self::handle_mirrored_token(address); + Pallet::::code_at_address(&addr).into_inner() + } + + fn storage(&self, address: H160, index: H256) -> H256 { + AccountStorages::::get(address, index) + } + + fn original_storage(&self, _address: H160, _index: H256) -> H256 { + // We do not have the concept of original storage in the native runner, so we + // always return empty value. This only affects gas calculation in the current + // EVM specification. + H256::default() + } + + fn gas_left(&self) -> U256 { + U256::from(self.gasometer.gas()) + } + + fn gas_price(&self) -> U256 { + self.vicinity.gas_price + } + + fn origin(&self) -> H160 { + self.vicinity.origin + } + + fn block_hash(&self, number: U256) -> H256 { + if number > U256::from(u32::max_value()) { + H256::default() + } else { + let number = T::BlockNumber::from(number.as_u32()); + H256::from_slice(frame_system::Pallet::::block_hash(number).as_ref()) + } + } + + fn block_number(&self) -> U256 { + let number: u128 = frame_system::Pallet::::block_number().unique_saturated_into(); + U256::from(number) + } + + fn block_coinbase(&self) -> H160 { + H160::default() + } + + fn block_timestamp(&self) -> U256 { + let now: u128 = pallet_timestamp::Pallet::::get().unique_saturated_into(); + U256::from(now / 1000) + } + + fn block_difficulty(&self) -> U256 { + U256::zero() + } + + fn block_gas_limit(&self) -> U256 { + U256::zero() + } + + fn chain_id(&self) -> U256 { + U256::from(T::ChainId::get()) + } + + fn exists(&self, _address: H160) -> bool { + true + } + + fn deleted(&self, _address: H160) -> bool { + // This only affects gas calculation in the current EVM specification. + // return true to disable suicide gas refund + true + } + + fn set_storage(&mut self, address: H160, index: H256, value: H256) -> Result<(), ExitError> { + if self.is_static { + return Err(ExitError::OutOfGas); + } + enum StorageChange { + None, + Added, + Removed, + } + + let mut storage_change = StorageChange::None; + + let default_value = H256::default(); + let is_prev_value_default = Pallet::::account_storages(address, index) == default_value; + + if value == default_value { + if !is_prev_value_default { + storage_change = StorageChange::Removed; + } + + AccountStorages::::remove(address, index); + } else { + if is_prev_value_default { + storage_change = StorageChange::Added; + } + + AccountStorages::::insert(address, index, value); + } + + match storage_change { + StorageChange::Added => { + Pallet::::update_contract_storage_size(&address, STORAGE_SIZE as i32); + self.storage_meter.charge(STORAGE_SIZE) + } + StorageChange::Removed => { + Pallet::::update_contract_storage_size(&address, -(STORAGE_SIZE as i32)); + self.storage_meter.refund(STORAGE_SIZE) + } + StorageChange::None => Ok(()), + } + .map_err(|_| ExitError::OutOfGas) + } + + fn log(&mut self, address: H160, topics: Vec, data: Vec) -> Result<(), ExitError> { + Pallet::::deposit_event(Event::::Log(Log { address, topics, data })); + + Ok(()) + } + + fn mark_delete(&mut self, address: H160, target: H160) -> Result<(), ExitError> { + if self.is_static { + return Err(ExitError::OutOfGas); + } + + let storage = Pallet::::remove_contract(&address, &target) + .map_err(|e| ExitError::Other(Into::<&str>::into(e).into()))?; + + self.storage_meter + .refund(storage) + .map_err(|e| ExitError::Other(Into::<&str>::into(e).into()))?; + + Ok(()) + } + + fn create( + &mut self, + caller: H160, + scheme: CreateScheme, + value: U256, + init_code: Vec, + target_gas: Option, + ) -> Capture<(ExitReason, Option, Vec), Self::CreateInterrupt> { + log::debug!( + target: "evm", + "handler: create: caller {:?}", + caller, + ); + + create_try!(|e: ExitError| (e.into(), None, Vec::new())); + + if self.is_static { + return Capture::Exit((ExitError::OutOfGas.into(), None, Vec::new())); + } + + let mut after_gas = self.gasometer.gas(); + if self.config.call_l64_after_gas { + after_gas = l64(after_gas); + } + let mut target_gas = target_gas.unwrap_or(after_gas); + target_gas = min(target_gas, after_gas); + try_or_fail!(self.gasometer.record_cost(target_gas)); + + let maybe_address = Self::create_address(scheme); + let address = if let Err(e) = maybe_address { + return Capture::Exit((ExitReason::Error(e), None, Vec::new())); + } else { + maybe_address.unwrap() + }; + Self::inc_nonce(caller); + + let origin = &self.vicinity.origin; + + self.run_sub_transaction( + self.vicinity, + target_gas, + address, + self.is_static, + self.config, + |substate, gasometer| { + try_or_rollback!(Self::transfer(Transfer { + source: caller, + target: address, + value, + })); + + let (reason, out) = substate.execute(caller, address, value, init_code, Vec::new()); + + match reason { + ExitReason::Succeed(s) => match substate.gasometer.record_deposit(out.len()) { + Ok(()) => { + try_or_rollback!(gasometer.record_stipend(substate.gasometer.gas())); + try_or_rollback!(gasometer.record_refund(substate.gasometer.refunded_gas())); + + Handler::::inc_nonce(address); + try_or_rollback!(substate + .storage_meter + .charge((out.len() as u32).saturating_add(T::NewContractExtraBytes::get())) + .map_err(|_| ExitError::OutOfGas)); + match >::on_contract_initialization(&address, origin, out) { + Ok(()) => { + TransactionOutcome::Commit(Capture::Exit((s.into(), Some(address), Vec::new()))) + } + Err(e) => TransactionOutcome::Rollback(Capture::Exit((e.into(), None, Vec::new()))), + } + } + Err(e) => TransactionOutcome::Rollback(Capture::Exit((e.into(), None, Vec::new()))), + }, + ExitReason::Revert(r) => TransactionOutcome::Rollback(Capture::Exit((r.into(), None, out))), + ExitReason::Error(e) => TransactionOutcome::Rollback(Capture::Exit((e.into(), None, Vec::new()))), + ExitReason::Fatal(e) => { + gasometer.fail(); + TransactionOutcome::Rollback(Capture::Exit((e.into(), None, Vec::new()))) + } + } + }, + ) + .unwrap_or_else(|x| { + Capture::Exit(( + ExitReason::Error(ExitError::Other(Into::<&'static str>::into(x).into())), + None, + Vec::new(), + )) + }) + } + + fn call( + &mut self, + code_address: H160, + transfer: Option, + input: Vec, + target_gas: Option, + is_static: bool, + context: Context, + ) -> Capture<(ExitReason, Vec), Self::CallInterrupt> { + log::debug!( + target: "evm", + "handler: call: source {:?} code_address {:?} input: {:?} target_gas {:?} gas_left {:?}", + context.caller, + code_address, + input, + target_gas, + self.gas_left() + ); + + create_try!(|e: ExitError| (e.into(), Vec::new())); + + if self.is_static && transfer.is_some() { + return Capture::Exit((ExitError::OutOfGas.into(), Vec::new())); + } + + let mut after_gas = self.gasometer.gas(); + if self.config.call_l64_after_gas { + after_gas = l64(after_gas); + } + let mut target_gas = target_gas.unwrap_or(after_gas); + target_gas = min(target_gas, after_gas); + + if let Some(transfer) = transfer.as_ref() { + if !transfer.value.is_zero() { + target_gas = target_gas.saturating_add(self.config.call_stipend); + } + } + + let code = self.code(code_address); + + self.run_sub_transaction( + self.vicinity, + target_gas, + context.address, + self.is_static || is_static, + self.config, + |substate, gasometer| { + if let Some(transfer) = transfer { + try_or_rollback!(Self::transfer(transfer)); + } + + try_or_rollback!(gasometer.record_cost(target_gas)); + + if let Some(ret) = T::Precompiles::execute(code_address, &input, Some(target_gas), &context) { + log::debug!( + target: "evm", + "handler: call-result: precompile result {:?}", + ret + ); + + return match ret { + Ok((s, out, cost)) => { + // TODO: write some test to make sure following 3 lines is correct + try_or_rollback!(substate.gasometer.record_cost(cost)); + try_or_rollback!(gasometer.record_stipend(substate.gasometer.gas())); + try_or_rollback!(gasometer.record_refund(substate.gasometer.refunded_gas())); + // precompile contract cost 0 + // try_or_rollback!(self.storage_meter.record_cost(0)); + TransactionOutcome::Commit(Capture::Exit((s.into(), out))) + } + Err(e) => TransactionOutcome::Rollback(Capture::Exit((e.into(), Vec::new()))), + }; + } + + let (reason, out) = substate.execute( + context.caller, + context.address, + context.apparent_value, + code.clone(), + input, + ); + + log::debug!( + target: "evm", + "handler: call-result: reason {:?} out {:?} gas_left {:?}", + reason, out, substate.gas_left() + ); + + match reason { + ExitReason::Succeed(s) => { + try_or_rollback!(gasometer.record_stipend(substate.gasometer.gas())); + try_or_rollback!(gasometer.record_refund(substate.gasometer.refunded_gas())); + TransactionOutcome::Commit(Capture::Exit((s.into(), out))) + } + ExitReason::Revert(r) => TransactionOutcome::Rollback(Capture::Exit((r.into(), out))), + ExitReason::Error(e) => TransactionOutcome::Rollback(Capture::Exit((e.into(), Vec::new()))), + ExitReason::Fatal(e) => { + gasometer.fail(); + TransactionOutcome::Rollback(Capture::Exit((e.into(), Vec::new()))) + } + } + }, + ) + .unwrap_or_else(|x| { + Capture::Exit(( + ExitReason::Error(ExitError::Other(Into::<&'static str>::into(x).into())), + Vec::new(), + )) + }) + } + + fn pre_validate(&mut self, context: &Context, opcode: Opcode, stack: &Stack) -> Result<(), ExitError> { + if let Some(cost) = gasometer::static_opcode_cost(opcode) { + self.gasometer.record_cost(cost)?; + } else { + let (gas_cost, memory_cost) = + gasometer::dynamic_opcode_cost(context.address, opcode, stack, self.is_static, &self.config, self)?; + + self.gasometer.record_dynamic_cost(gas_cost, memory_cost)?; + } + Ok(()) + } +} + +pub struct StorageMeterHandlerImpl { + origin: H160, + _marker: PhantomData, +} + +impl StorageMeterHandlerImpl { + pub fn new(origin: H160) -> Self { + Self { + origin, + _marker: Default::default(), + } + } +} + +impl StorageMeterHandler for StorageMeterHandlerImpl { + fn reserve_storage(&mut self, limit: u32) -> DispatchResult { + if limit.is_zero() { + return Ok(()); + } + + log::debug!( + target: "evm", + "reserve_storage: from {:?} limit {:?}", + self.origin, limit, + ); + + let user = T::AddressMapping::get_account_id(&self.origin); + + let amount = T::StorageDepositPerByte::get().saturating_mul(limit.into()); + + T::Currency::reserve(&user, amount) + } + + fn unreserve_storage(&mut self, limit: u32, used: u32, refunded: u32) -> DispatchResult { + let total = limit.saturating_add(refunded); + let unused = total.saturating_sub(used); + if unused.is_zero() { + return Ok(()); + } + + log::debug!( + target: "evm", + "unreserve_storage: from {:?} used {:?} refunded {:?} unused {:?}", + self.origin, used, refunded, unused + ); + + let user = T::AddressMapping::get_account_id(&self.origin); + let amount = T::StorageDepositPerByte::get().saturating_mul(unused.into()); + + // should always be able to unreserve the amount + // but otherwise we will just ignore the issue here + let err_amount = T::Currency::unreserve(&user, amount); + debug_assert!(err_amount.is_zero()); + Ok(()) + } + + fn charge_storage(&mut self, contract: &H160, used: u32, refunded: u32) -> DispatchResult { + if used == refunded { + return Ok(()); + } + + log::debug!( + target: "evm", + "charge_storage: from {:?} contract {:?} used {:?} refunded {:?}", + &self.origin, contract, used, refunded + ); + + let user = T::AddressMapping::get_account_id(&self.origin); + let contract_acc = T::AddressMapping::get_account_id(contract); + + if used > refunded { + let storage = used - refunded; + let amount = T::StorageDepositPerByte::get().saturating_mul(storage.into()); + + // repatriate_reserved requires beneficiary is an existing account but + // contract_acc could be a new account so we need to do + // unreserve/transfer/reserve + T::Currency::unreserve(&user, amount); + T::Currency::transfer(&user, &contract_acc, amount, ExistenceRequirement::AllowDeath)?; + T::Currency::reserve(&contract_acc, amount)?; + } else { + let storage = refunded - used; + let amount = T::StorageDepositPerByte::get().saturating_mul(storage.into()); + + // user can't be a dead account + let val = T::Currency::repatriate_reserved(&contract_acc, &user, amount, BalanceStatus::Reserved)?; + debug_assert!(val.is_zero()); + }; + + Ok(()) + } + + fn out_of_storage_error(&self) -> DispatchError { + Error::::OutOfStorage.into() + } +} diff --git a/lib-serml/evm/src/runner/mod.rs b/lib-serml/evm/src/runner/mod.rs new file mode 100644 index 000000000..77136b634 --- /dev/null +++ b/lib-serml/evm/src/runner/mod.rs @@ -0,0 +1,305 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pub mod handler; +pub mod storage_meter; + +use crate::{AddressMapping, BalanceOf, CallInfo, Config, CreateInfo, Error, Pallet, Vicinity}; +use evm::{CreateScheme, ExitError, ExitReason}; +use evm_gasometer::{self as gasometer}; +use evm_runtime::Handler as HandlerT; +use frame_support::{ + log, + traits::{Currency, ExistenceRequirement, Get}, +}; +use handler::Handler; +use primitive_types::{H160, H256, U256}; +use sha3::{Digest, Keccak256}; +use sp_runtime::{traits::Zero, DispatchError, DispatchResult, SaturatedConversion, TransactionOutcome}; +use sp_std::{marker::PhantomData, vec::Vec}; + +#[derive(Default)] +pub struct Runner { + _marker: PhantomData, +} + +impl Runner { + fn inner_create( + source: H160, + init: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + assigned_address: Option, + salt: Option, + tag: &'static str, + config: &evm::Config, + ) -> Result { + log::debug!( + target: "evm", + "{:?}: source {:?}, gas_limit: {:?}, storage_limit: {:?}", + tag, + source, + gas_limit, + storage_limit, + ); + + let vicinity = Vicinity { + gas_price: U256::one(), + origin: source, + }; + + let address = if let Some(addr) = assigned_address { + Ok(addr) + } else { + let scheme = if let Some(s) = salt { + let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice()); + CreateScheme::Create2 { + caller: source, + code_hash, + salt: s, + } + } else { + CreateScheme::Legacy { caller: source } + }; + Handler::::create_address(scheme).map_err(|_| Error::::ConflictContractAddress) + }?; + + Handler::::inc_nonce(source); + + Handler::::run_transaction( + &vicinity, + gas_limit, + storage_limit, + address, + false, + config, + |substate| { + if let Err(e) = Self::transfer(source, address, value) { + return TransactionOutcome::Rollback(Err(e)); + } + + let transaction_cost = gasometer::call_transaction_cost(&init); + if substate.gasometer.record_transaction(transaction_cost).is_err() { + return TransactionOutcome::Rollback(Err(DispatchError::Other("OutOfGas"))); + } + + let (reason, out) = substate.execute( + source, + address, + U256::from(value.saturated_into::()), + init, + Vec::new(), + ); + + let mut create_info = CreateInfo { + exit_reason: reason.clone(), + address, + output: Vec::default(), + used_gas: U256::from(substate.used_gas()), + used_storage: substate.used_storage(), + }; + + log::debug!( + target: "evm", + "{:?}-result: create_info {:?}", + tag, + create_info + ); + + if !reason.is_succeed() { + create_info.output = out; + return TransactionOutcome::Rollback(Ok(create_info)); + } + + if let Err(e) = substate.gasometer.record_deposit(out.len()) { + create_info.exit_reason = e.into(); + return TransactionOutcome::Rollback(Ok(create_info)); + } + + create_info.used_gas = U256::from(substate.used_gas()); + + Handler::::inc_nonce(address); + + if substate + .storage_meter + .charge((out.len() as u32).saturating_add(T::NewContractExtraBytes::get())) + .is_err() + { + create_info.exit_reason = ExitReason::Error(ExitError::OutOfGas); + return TransactionOutcome::Rollback(Ok(create_info)); + } + + create_info.used_storage = substate.used_storage(); + + if let Err(e) = >::on_contract_initialization(&address, &source, out) { + create_info.exit_reason = e.into(); + return TransactionOutcome::Rollback(Ok(create_info)); + } + + TransactionOutcome::Commit(Ok(create_info)) + }, + )? + } + + fn transfer(source: H160, target: H160, value: BalanceOf) -> DispatchResult { + if value.is_zero() { + return Ok(()); + } + + let from = T::AddressMapping::get_account_id(&source); + let to = T::AddressMapping::get_account_id(&target); + T::Currency::transfer(&from, &to, value, ExistenceRequirement::AllowDeath) + } +} + +impl Runner { + pub fn call( + sender: H160, + origin: H160, + target: H160, + input: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + config: &evm::Config, + ) -> Result { + log::debug!( + target: "evm", + "call: sender:{:?}, origin: {:?}, target: {:?}, input: {:?}, gas_limit: {:?}, storage_limit: {:?}", + sender, + origin, + target, + input, + gas_limit, + storage_limit, + ); + + let vicinity = Vicinity { + gas_price: U256::one(), + origin, + }; + + // if the contract not deployed, the caller must be developer or contract or maintainer. + // if the contract not exists, let evm try to execute it and handle the error. + if !Handler::::can_call_contract(&target, &sender) { + return Err(Error::::NoPermission.into()); + } + + Handler::::inc_nonce(sender); + + Handler::::run_transaction(&vicinity, gas_limit, storage_limit, target, false, config, |substate| { + if let Err(e) = Self::transfer(sender, target, value) { + return TransactionOutcome::Rollback(Err(e)); + } + + let code = substate.code(target); + let transaction_cost = gasometer::call_transaction_cost(&code); + if substate.gasometer.record_transaction(transaction_cost).is_err() { + return TransactionOutcome::Rollback(Err(DispatchError::Other("OutOfGas"))); + } + + let (reason, out) = + substate.execute(sender, target, U256::from(value.saturated_into::()), code, input); + + let call_info = CallInfo { + exit_reason: reason.clone(), + output: out, + used_gas: U256::from(substate.used_gas()), + used_storage: substate.used_storage(), + }; + + log::debug!( + target: "evm", + "call-result: call_info {:?}", + call_info + ); + + if !reason.is_succeed() { + return TransactionOutcome::Rollback(Ok(call_info)); + } + + TransactionOutcome::Commit(Ok(call_info)) + })? + } + + pub fn create( + source: H160, + init: Vec, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + config: &evm::Config, + ) -> Result { + Self::inner_create( + source, + init, + value, + gas_limit, + storage_limit, + None, + None, + "create", + config, + ) + } + + pub fn create2( + source: H160, + init: Vec, + salt: H256, + value: BalanceOf, + gas_limit: u64, + storage_limit: u32, + config: &evm::Config, + ) -> Result { + Self::inner_create( + source, + init, + value, + gas_limit, + storage_limit, + None, + Some(salt), + "create2", + config, + ) + } + + pub fn create_at_address( + source: H160, + init: Vec, + value: BalanceOf, + assigned_address: H160, + gas_limit: u64, + storage_limit: u32, + config: &evm::Config, + ) -> Result { + Self::inner_create( + source, + init, + value, + gas_limit, + storage_limit, + Some(assigned_address), + None, + "create-system-contract", + config, + ) + } +} diff --git a/lib-serml/evm/src/runner/storage_meter.rs b/lib-serml/evm/src/runner/storage_meter.rs new file mode 100644 index 000000000..9e42bbc61 --- /dev/null +++ b/lib-serml/evm/src/runner/storage_meter.rs @@ -0,0 +1,446 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use frame_support::log; +use sp_core::H160; +use sp_runtime::{DispatchError, DispatchResult}; + +pub trait StorageMeterHandler { + fn reserve_storage(&mut self, limit: u32) -> DispatchResult; + fn unreserve_storage(&mut self, limit: u32, used: u32, refunded: u32) -> DispatchResult; + + fn charge_storage(&mut self, contract: &H160, used: u32, refunded: u32) -> DispatchResult; + + fn out_of_storage_error(&self) -> DispatchError; +} + +pub struct StorageMeter<'handler> { + contract: H160, + limit: u32, + total_used: u32, + self_used: u32, + total_refunded: u32, + self_refunded: u32, + handler: &'handler mut dyn StorageMeterHandler, + result: DispatchResult, +} + +impl<'handler> StorageMeter<'handler> { + /// Create a new storage_meter with given storage limit. + pub fn new( + handler: &'handler mut dyn StorageMeterHandler, + contract: H160, + limit: u32, + ) -> Result { + log::trace!( + target: "evm", + "StorageMeter: create: contract {:?} limit {:?}", + contract, limit + ); + handler.reserve_storage(limit)?; + Ok(Self { + contract, + limit, + total_used: 0, + self_used: 0, + total_refunded: 0, + self_refunded: 0, + handler, + result: Ok(()), + }) + } + + pub fn child_meter(&mut self, contract: H160) -> Result, DispatchError> { + self.handle(|this| { + let storage = this.available_storage(); + // can't make this.result = Err if `new` fails + // because some rust lifetime thing never happy + StorageMeter::new(this, contract, storage) + }) + } + + pub fn available_storage(&self) -> u32 { + if self.result.is_ok() { + self.limit + .saturating_add(self.total_refunded) + .saturating_sub(self.total_used) + } else { + 0 + } + } + + pub fn used_storage(&self) -> i32 { + if self.total_used > self.total_refunded { + (self.total_used - self.total_refunded) as i32 + } else { + -((self.total_refunded - self.total_used) as i32) + } + } + + pub fn charge(&mut self, storage: u32) -> DispatchResult { + log::trace!( + target: "evm", + "StorageMeter: charge: storage {:?}", + storage + ); + self.handle(|this| { + this.total_used = this.total_used.saturating_add(storage); + this.self_used = this.self_used.saturating_add(storage); + Ok(()) + }) + } + + pub fn uncharge(&mut self, storage: u32) -> DispatchResult { + log::trace!( + target: "evm", + "StorageMeter: uncharge: storage {:?}", + storage + ); + self.handle(|this| { + this.total_used = this.total_used.saturating_sub(storage); + this.self_used = this.self_used.saturating_sub(storage); + Ok(()) + }) + } + + pub fn refund(&mut self, storage: u32) -> DispatchResult { + log::trace!( + target: "evm", + "StorageMeter: refund: storage {:?}", + storage + ); + self.handle(|this| { + this.total_refunded = this.total_refunded.saturating_add(storage); + this.self_refunded = this.self_refunded.saturating_add(storage); + Ok(()) + }) + } + + pub fn finish(mut self) -> DispatchResult { + log::trace!( + target: "evm", + "StorageMeter: finish: used {:?} refunded {:?}", + self.total_used, self.total_refunded + ); + self.handle(|this| { + if let Err(x) = (|| { + if this.limit < this.total_used.saturating_sub(this.total_refunded) { + this.result = Err(this.out_of_storage_error()); + return this.result; + } + this.handler + .charge_storage(&this.contract, this.self_used, this.self_refunded)?; + let new_limit = this + .limit + .saturating_add(this.self_used) + .saturating_add(this.total_refunded) + .saturating_sub(this.total_used) + .saturating_sub(this.self_refunded); + this.handler + .unreserve_storage(new_limit, this.self_used, this.self_refunded) + })() { + this.result = Err(x); + Err(x) + } else { + Ok(()) + } + }) + } + + fn handle<'a, R, F: FnOnce(&'a mut Self) -> Result>( + &'a mut self, + f: F, + ) -> Result { + self.result?; + f(self) + } +} + +impl<'handler> StorageMeterHandler for StorageMeter<'handler> { + fn reserve_storage(&mut self, _limit: u32) -> DispatchResult { + Ok(()) + } + + fn unreserve_storage(&mut self, _limit: u32, _used: u32, _refunded: u32) -> DispatchResult { + Ok(()) + } + + fn charge_storage(&mut self, contract: &H160, used: u32, refunded: u32) -> DispatchResult { + self.handle(|this| { + this.total_refunded = this.total_refunded.saturating_add(refunded); + this.total_used = this.total_used.saturating_add(used); + this.handler.charge_storage(contract, used, refunded) + }) + } + + fn out_of_storage_error(&self) -> DispatchError { + "OutOfStorage".into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use frame_support::{assert_err, assert_ok}; + + const ALICE: H160 = H160::repeat_byte(11); + const CONTRACT: H160 = H160::repeat_byte(22); + const CONTRACT_2: H160 = H160::repeat_byte(33); + const CONTRACT_3: H160 = H160::repeat_byte(44); + struct DummyHandler { + pub storages: std::collections::BTreeMap, + pub reserves: std::collections::BTreeMap, + } + + impl DummyHandler { + fn new() -> Self { + let mut val = Self { + storages: Default::default(), + reserves: Default::default(), + }; + val.storages.insert(ALICE, 0); + val.reserves.insert(ALICE, 0); + val.storages.insert(CONTRACT, 0); + val.reserves.insert(CONTRACT, 0); + val.storages.insert(CONTRACT_2, 0); + val.reserves.insert(CONTRACT_2, 0); + val.storages.insert(CONTRACT_3, 0); + val.reserves.insert(CONTRACT_3, 0); + val + } + } + + impl StorageMeterHandler for DummyHandler { + fn reserve_storage(&mut self, limit: u32) -> DispatchResult { + if limit == 0 { + return Ok(()); + } + let val = self.storages.get_mut(&ALICE).ok_or("error")?; + *val = val.checked_sub(limit).ok_or("error")?; + if let Some(v) = self.reserves.get_mut(&ALICE) { + *v += limit; + } else { + self.reserves.insert(ALICE, limit); + } + Ok(()) + } + + fn unreserve_storage(&mut self, limit: u32, used: u32, refunded: u32) -> DispatchResult { + let diff = limit + refunded - used; + if diff == 0 { + return Ok(()); + } + let val = self.reserves.get_mut(&ALICE).ok_or("error")?; + *val = val.checked_sub(diff).ok_or("error")?; + if let Some(v) = self.storages.get_mut(&ALICE) { + *v += diff; + } else { + self.storages.insert(ALICE, diff); + } + Ok(()) + } + + fn charge_storage(&mut self, contract: &H160, used: u32, refunded: u32) -> DispatchResult { + if used == refunded { + return Ok(()); + } + let alice = self.reserves.get_mut(&ALICE).ok_or("error")?; + if used > refunded { + *alice = alice.checked_sub(used - refunded).ok_or("error")?; + } else { + *alice = alice.checked_add(refunded - used).ok_or("error")?; + } + + let contract_val = self.reserves.get_mut(&contract).ok_or("error")?; + if used > refunded { + *contract_val = contract_val.checked_add(used - refunded).ok_or("error")?; + } else { + *contract_val = contract_val.checked_sub(refunded - used).ok_or("error")?; + } + Ok(()) + } + + fn out_of_storage_error(&self) -> DispatchError { + "OutOfStorage".into() + } + } + + #[test] + fn test_storage_with_limit_zero() { + let mut handler = DummyHandler::new(); + + let mut storage_meter = StorageMeter::new(&mut handler, CONTRACT, 0).unwrap(); + assert_eq!(storage_meter.available_storage(), 0); + + // refund + assert_ok!(storage_meter.refund(1)); + assert_eq!(storage_meter.available_storage(), 1); + + // charge + assert_ok!(storage_meter.charge(1)); + assert_eq!(storage_meter.available_storage(), 0); + + assert_ok!(storage_meter.finish()); + + assert_eq!(handler.storages.get(&ALICE).cloned().unwrap_or_default(), 0); + assert_eq!(handler.reserves.get(&ALICE).cloned().unwrap_or_default(), 0); + assert_eq!(handler.storages.get(&CONTRACT).cloned().unwrap_or_default(), 0); + assert_eq!(handler.reserves.get(&CONTRACT).cloned().unwrap_or_default(), 0); + } + + #[test] + fn test_charge_storage_fee() { + let mut handler = DummyHandler::new(); + handler.storages.insert(ALICE, 1000); + + let mut storage_meter = StorageMeter::new(&mut handler, CONTRACT, 1000).unwrap(); + assert_eq!(storage_meter.available_storage(), 1000); + + assert_ok!(storage_meter.refund(1)); + assert_eq!(storage_meter.available_storage(), 1001); + + assert_ok!(storage_meter.charge(101)); + assert_eq!(storage_meter.available_storage(), 900); + + assert_ok!(storage_meter.charge(50)); + assert_eq!(storage_meter.available_storage(), 850); + + assert_ok!(storage_meter.refund(20)); + assert_eq!(storage_meter.available_storage(), 870); + + assert_ok!(storage_meter.finish()); + + assert_eq!(handler.storages.get(&ALICE).cloned().unwrap_or_default(), 870); + assert_eq!(handler.reserves.get(&ALICE).cloned().unwrap_or_default(), 0); + assert_eq!(handler.storages.get(&CONTRACT).cloned().unwrap_or_default(), 0); + assert_eq!(handler.reserves.get(&CONTRACT).cloned().unwrap_or_default(), 130); + } + + #[test] + fn test_refund_storage_fee() { + let mut handler = DummyHandler::new(); + handler.storages.insert(ALICE, 1000); + handler.reserves.insert(CONTRACT, 1000); + + let mut storage_meter = StorageMeter::new(&mut handler, CONTRACT, 1000).unwrap(); + assert_eq!(storage_meter.available_storage(), 1000); + + assert_ok!(storage_meter.refund(100)); + assert_eq!(storage_meter.available_storage(), 1100); + + assert_ok!(storage_meter.charge(50)); + assert_eq!(storage_meter.available_storage(), 1050); + + assert_ok!(storage_meter.finish()); + + assert_eq!(handler.storages.get(&ALICE).cloned().unwrap_or_default(), 1050); + assert_eq!(handler.reserves.get(&ALICE).cloned().unwrap_or_default(), 0); + assert_eq!(handler.storages.get(&CONTRACT).cloned().unwrap_or_default(), 0); + assert_eq!(handler.reserves.get(&CONTRACT).cloned().unwrap_or_default(), 950); + } + + #[test] + fn test_out_of_storage() { + let mut handler = DummyHandler::new(); + handler.storages.insert(ALICE, 1000); + + assert!(StorageMeter::new(&mut handler, CONTRACT, 1001).is_err()); + let mut storage_meter = StorageMeter::new(&mut handler, CONTRACT, 1000).unwrap(); + assert_eq!(storage_meter.available_storage(), 1000); + + assert_ok!(storage_meter.charge(500)); + assert_eq!(storage_meter.available_storage(), 500); + + assert_ok!(storage_meter.charge(500)); + assert_eq!(storage_meter.available_storage(), 0); + + assert_ok!(storage_meter.charge(2)); + assert_ok!(storage_meter.refund(1)); + assert_ok!(storage_meter.child_meter(CONTRACT_2).map(|_| ())); + assert_err!(storage_meter.finish(), DispatchError::Other("OutOfStorage")); + } + + #[test] + fn test_high_use_and_refund() { + let mut handler = DummyHandler::new(); + handler.storages.insert(ALICE, 1000); + + let mut storage_meter = StorageMeter::new(&mut handler, CONTRACT, 1000).unwrap(); + assert_eq!(storage_meter.available_storage(), 1000); + + assert_ok!(storage_meter.charge(1000)); + assert_eq!(storage_meter.available_storage(), 0); + + assert_ok!(storage_meter.charge(100)); + assert_eq!(storage_meter.available_storage(), 0); + assert_ok!(storage_meter.refund(200)); + assert_eq!(storage_meter.available_storage(), 100); + assert_ok!(storage_meter.child_meter(CONTRACT_2).map(|_| ())); + assert_ok!(storage_meter.finish()); + } + + #[test] + fn test_child_meter() { + let mut handler = DummyHandler::new(); + handler.storages.insert(ALICE, 1000); + + let mut storage_meter = StorageMeter::new(&mut handler, CONTRACT, 1000).unwrap(); + + assert_ok!(storage_meter.charge(100)); + + let mut child_meter = storage_meter.child_meter(CONTRACT_2).unwrap(); + assert_eq!(child_meter.available_storage(), 900); + + assert_ok!(child_meter.charge(100)); + assert_eq!(child_meter.available_storage(), 800); + + assert_ok!(child_meter.refund(50)); + assert_eq!(child_meter.available_storage(), 850); + + let mut child_meter_2 = child_meter.child_meter(CONTRACT_3).unwrap(); + + assert_eq!(child_meter_2.available_storage(), 850); + + assert_ok!(child_meter_2.charge(20)); + assert_eq!(child_meter_2.available_storage(), 830); + + assert_ok!(child_meter_2.finish()); + + assert_ok!(child_meter.finish()); + + let mut child_meter_3 = storage_meter.child_meter(CONTRACT_2).unwrap(); + + assert_eq!(child_meter_3.available_storage(), 830); + + assert_ok!(child_meter_3.charge(30)); + + assert_eq!(child_meter_3.available_storage(), 800); + + assert_ok!(child_meter_3.finish()); + + assert_eq!(storage_meter.available_storage(), 800); + + assert_ok!(storage_meter.finish()); + + assert_eq!(handler.storages.get(&ALICE).cloned().unwrap_or_default(), 800); + assert_eq!(handler.reserves.get(&ALICE).cloned().unwrap_or_default(), 0); + assert_eq!(handler.reserves.get(&CONTRACT).cloned().unwrap_or_default(), 100); + assert_eq!(handler.reserves.get(&CONTRACT_2).cloned().unwrap_or_default(), 80); + assert_eq!(handler.reserves.get(&CONTRACT_3).cloned().unwrap_or_default(), 20); + } +} diff --git a/lib-serml/evm/src/tests.rs b/lib-serml/evm/src/tests.rs new file mode 100644 index 000000000..c39229341 --- /dev/null +++ b/lib-serml/evm/src/tests.rs @@ -0,0 +1,1418 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(test)] + +use super::*; +use mock::{Event, *}; + +use crate::runner::handler::{Handler, STORAGE_SIZE}; +use frame_support::{assert_err, assert_noop, assert_ok}; +use sp_core::{ + bytes::{from_hex, to_hex}, + H160, +}; +use sp_runtime::{traits::BadOrigin, AccountId32}; +use std::str::FromStr; + +#[test] +fn fail_call_return_ok() { + new_test_ext().execute_with(|| { + let mut data = [0u8; 32]; + data[0..4].copy_from_slice(b"evm:"); + let signer: AccountId32 = AccountId32::from(data).into(); + + let origin = Origin::signed(signer); + assert_ok!(EVM::call(origin.clone(), contract_a(), Vec::new(), 0, 1000000, 0)); + assert_ok!(EVM::call(origin, contract_b(), Vec::new(), 0, 1000000, 0)); + }); +} + +#[test] +fn should_calculate_contract_address() { + new_test_ext().execute_with(|| { + let addr = H160::from_str("bec02ff0cbf20042a37d964c33e89f1a2be7f068").unwrap(); + + assert_eq!( + Handler::::create_address(evm::CreateScheme::Legacy { caller: addr }), + Ok(H160::from_str("d654cB21c05cb14895baae28159b1107e9DbD6E4").unwrap()) + ); + + Handler::::inc_nonce(addr); + assert_eq!( + Handler::::create_address(evm::CreateScheme::Legacy { caller: addr }), + Ok(H160::from_str("97784910F057B07bFE317b0552AE23eF34644Aed").unwrap()) + ); + + Handler::::inc_nonce(addr); + assert_eq!( + Handler::::create_address(evm::CreateScheme::Legacy { caller: addr }), + Ok(H160::from_str("82155a21E0Ccaee9D4239a582EB2fDAC1D9237c5").unwrap()) + ); + }); +} + +#[test] +fn should_create_and_call_contract() { + // pragma solidity ^0.5.0; + // + // contract Test { + // function multiply(uint a, uint b) public pure returns(uint) { + // return a * b; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + // deploy contract + let caller = alice(); + let result = Runner::::create( + caller.clone(), + contract, + 0, + 1000000, + 1000000, + ::config(), + ).unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + + let contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(contract_address); + + assert_eq!(contract_address, H160::from_str("5f8bd49cd9f0cb2bd5bb9d4320dfe9b61023249d").unwrap()); + + assert_eq!(Pallet::::account_basic(&caller).nonce, 2.into()); + + // multiply(2, 3) + let multiply = from_hex( + "0x165c4a1600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003" + ).unwrap(); + + // call method `multiply` + let result = Runner::::call( + alice(), + alice(), + contract_address, + multiply, + 0, + 1000000, + 1000000, + ::config(), + ).unwrap(); + assert_eq!( + U256::from(result.output.as_slice()), + 6.into(), + ); + + assert_eq!(Pallet::::account_basic(&caller).nonce, 3.into()); + + let code_hash = H256::from_str("164981e02df203a0fb32a0af7c2cd1cc7f9df7bb49a4d2b0219307bb68a4b603").unwrap(); + let code_size = 184u32; + + assert_eq!(Accounts::::get(&contract_address), Some(AccountInfo { + nonce: 1, + contract_info: Some(ContractInfo { + code_hash, + maintainer: alice(), + deployed: true + }), + developer_deposit: None, + })); + + assert_eq!(ContractStorageSizes::::get(&contract_address), code_size + NewContractExtraBytes::get()); + assert_eq!(CodeInfos::::get(&code_hash), Some(CodeInfo { + code_size, + ref_count: 1, + })); + assert!(Codes::::contains_key(&code_hash)); + }); +} + +#[test] +fn create_reverts_with_message() { + // pragma solidity ^0.5.0; + // + // contract Foo { + // constructor() public { + // require(false, "error message"); + // } + // } + let contract = from_hex( + "0x6080604052348015600f57600080fd5b5060006083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6572726f72206d6573736167650000000000000000000000000000000000000081525060200191505060405180910390fd5b603e8060906000396000f3fe6080604052600080fdfea265627a7a723158204741083d83bf4e3ee8099dd0b3471c81061237c2e8eccfcb513dfa4c04634b5b64736f6c63430005110032" + ).unwrap(); + new_test_ext().execute_with(|| { + let result = + Runner::::create(alice(), contract, 0, 12_000_000, 12_000_000, ::config()).unwrap(); + assert_eq!(result.exit_reason, ExitReason::Revert(ExitRevert::Reverted)); + assert!(String::from_utf8_lossy(&result.output).contains("error message")); + }); +} + +#[test] +fn call_reverts_with_message() { + // pragma solidity ^0.5.0; + // + // contract Test { + // function foo() public pure { + // require(false, "error message"); + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060df8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b60336035565b005b600060a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6572726f72206d6573736167650000000000000000000000000000000000000081525060200191505060405180910390fd5b56fea265627a7a7231582066b3ee33bedba8a318d0d66610145030fdc0f982b11f5160d366e15e4d8ba2ef64736f6c63430005110032" + ).unwrap(); + let caller = alice(); + + new_test_ext().execute_with(|| { + // deploy contract + let result = Runner::::create( + caller, + contract, + 0, + 1000000, + 1000000, + ::config(), + ).unwrap(); + + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + + let alice_balance = INITIAL_BALANCE - 323 * ::StorageDepositPerByte::get(); + + assert_eq!(balance(alice()), alice_balance); + + let contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(contract_address); + + // call method `foo` + let foo = from_hex("0xc2985578").unwrap(); + let result = Runner::::call( + caller, + caller, + contract_address, + foo, + 0, + 1000000, + 1000000, + ::config(), + ).unwrap(); + + assert_eq!(balance(alice()), alice_balance); + assert_eq!(result.exit_reason, ExitReason::Revert(ExitRevert::Reverted)); + assert_eq!( + to_hex(&result.output, true), + "0x8c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6572726f72206d65737361676500000000000000000000000000000000000000" + ); + + let message = String::from_utf8_lossy(&result.output); + assert!(message.contains("error message")); + + assert_eq!(Pallet::::account_basic(&caller).nonce, 3.into()); + }); +} + +#[test] +fn should_deploy_payable_contract() { + // pragma solidity ^0.5.0; + // + // contract Test { + // uint value; + // constructor(uint a) public payable { + // value = a; + // } + // + // function getValue() public payable returns (uint) { + // return value; + // } + // } + let mut contract = from_hex( + "0x60806040526040516100c73803806100c783398181016040526020811015602557600080fd5b81019080805190602001909291905050508060008190555050607b8061004c6000396000f3fe608060405260043610601c5760003560e01c806320965255146021575b600080fd5b6027603d565b6040518082815260200191505060405180910390f35b6000805490509056fea265627a7a72315820b832564a9db725638dcef03d07bfbdd2dc818020ea359630317e2126e95c314964736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + let amount = 1000u64; + + let stored_value: Vec = + from_hex("0x000000000000000000000000000000000000000000000000000000000000007b").unwrap(); + contract.append(&mut stored_value.clone()); + + let result = + Runner::::create(alice(), contract, amount, 100000, 100000, ::config()).unwrap(); + let contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(contract_address); + + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.used_storage, 287); + + let alice_balance = INITIAL_BALANCE - amount - 287 * ::StorageDepositPerByte::get(); + assert_eq!(balance(alice()), alice_balance); + assert_eq!(balance(contract_address), amount); + + // call getValue() + let result = Runner::::call( + alice(), + alice(), + contract_address, + from_hex("0x20965255").unwrap(), + amount, + 100000, + 100000, + ::config(), + ) + .unwrap(); + + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.output, stored_value); + assert_eq!(result.used_storage, 0); + + assert_eq!(balance(alice()), alice_balance - amount); + assert_eq!(balance(contract_address), 2 * amount); + + assert_eq!( + AccountStorages::::iter_prefix(&contract_address).collect::>(), + vec![( + H256::from_str("0x0000000000000000000000000000000000000000000000000000000000000000").unwrap(), + H256::from_slice(stored_value.as_slice()) + )] + ); + }); +} + +#[test] +fn should_transfer_from_contract() { + // pragma solidity ^0.5.16; + // + // contract SendEther { + // function sendViaTransfer(address payable _to) public payable { + // // This function is no longer recommended for sending Ether. + // _to.transfer(msg.value); + // } + // + // function sendViaSend(address payable _to) public payable { + // // Send returns a boolean value indicating success or failure. + // // This function is not recommended for sending Ether. + // bool sent = _to.send(msg.value); + // require(sent, "Failed to send Ether"); + // } + // + // function sendViaCall(address payable _to) public payable { + // // Call returns a boolean value indicating success or failure. + // // This is the current recommended method to use. + // (bool sent, bytes memory data) = _to.call.value(msg.value)(""); + // require(sent, "Failed to send Ether"); + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b50610318806100206000396000f3fe6080604052600436106100345760003560e01c8063636e082b1461003957806374be48061461007d578063830c29ae146100c1575b600080fd5b61007b6004803603602081101561004f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610105565b005b6100bf6004803603602081101561009357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061014f565b005b610103600480360360208110156100d757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101ff565b005b8073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f1935050505015801561014b573d6000803e3d6000fd5b5050565b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806101fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4661696c656420746f2073656e6420457468657200000000000000000000000081525060200191505060405180910390fd5b5050565b600060608273ffffffffffffffffffffffffffffffffffffffff163460405180600001905060006040518083038185875af1925050503d8060008114610261576040519150601f19603f3d011682016040523d82523d6000602084013e610266565b606091505b5091509150816102de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4661696c656420746f2073656e6420457468657200000000000000000000000081525060200191505060405180910390fd5b50505056fea265627a7a723158201b401be037c87d59ec386e75b0166702abb5a64f93ea20080904b6791bd88d1564736f6c63430005110032" + ).unwrap(); + new_test_ext().execute_with(|| { + let amount = 1000u64; + + let result = Runner::::create(alice(), contract, 0, 10000000, 10000000, ::config()) + .expect("create shouldn't fail"); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.used_storage, 892); + + let alice_balance = INITIAL_BALANCE - 892 * ::StorageDepositPerByte::get(); + assert_eq!(balance(alice()), alice_balance); + + let contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(contract_address); + + // send via transfer + let mut via_transfer = from_hex("0x636e082b").unwrap(); + via_transfer.append(&mut Vec::from(H256::from(charlie()).as_bytes())); + + let result = Runner::::call( + alice(), + alice(), + contract_address, + via_transfer, + amount, + 1000000, + 1000000, + ::config(), + ) + .unwrap(); + + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(balance(alice()), alice_balance - 1 * amount); + assert_eq!(balance(charlie()), 1 * amount); + + // send via send + let mut via_send = from_hex("0x74be4806").unwrap(); + via_send.append(&mut Vec::from(H256::from(charlie()).as_bytes())); + + let result = Runner::::call( + alice(), + alice(), + contract_address, + via_send, + amount, + 1000000, + 1000000, + ::config(), + ) + .unwrap(); + + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(balance(charlie()), 2 * amount); + assert_eq!(balance(alice()), alice_balance - 2 * amount); + + // send via call + let mut via_call = from_hex("0x830c29ae").unwrap(); + via_call.append(&mut Vec::from(H256::from(charlie()).as_bytes())); + + let result = Runner::::call( + alice(), + alice(), + contract_address, + via_call, + amount, + 1000000, + 1000000, + ::config(), + ) + .unwrap(); + + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(balance(charlie()), 3 * amount); + assert_eq!(balance(alice()), alice_balance - 3 * amount); + }) +} + +#[test] +fn contract_should_deploy_contracts() { + // pragma solidity ^0.5.0; + // + // contract Factory { + // Contract[] newContracts; + // + // function createContract () public payable { + // Contract newContract = new Contract(); + // newContracts.push(newContract); + // } + // } + // + // contract Contract {} + let contract = from_hex( + "0x608060405234801561001057600080fd5b5061016f806100206000396000f3fe608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063412a5a6d14610046575b600080fd5b61004e610050565b005b600061005a6100e2565b604051809103906000f080158015610076573d6000803e3d6000fd5b50905060008190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6040516052806100f28339019056fe6080604052348015600f57600080fd5b50603580601d6000396000f3fe6080604052600080fdfea165627a7a7230582092dc1966a8880ddf11e067f9dd56a632c11a78a4afd4a9f05924d427367958cc0029a165627a7a723058202b2cc7384e11c452cdbf39b68dada2d5e10a632cc0174a354b8b8c83237e28a40029" + ).unwrap(); + new_test_ext().execute_with(|| { + let result = Runner::::create( + alice(), + contract.clone(), + 0, + 1000000000, + 1000000000, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.used_storage, 467); + + let alice_balance = INITIAL_BALANCE - 467 * ::StorageDepositPerByte::get(); + + assert_eq!(balance(alice()), alice_balance); + let factory_contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(factory_contract_address); + + assert_eq!(balance(result.address), 0); + assert_eq!( + reserved_balance(result.address), + 467 * ::StorageDepositPerByte::get() + ); + + // Factory.createContract + let amount = 1000000000; + let create_contract = from_hex("0x412a5a6d").unwrap(); + let result = Runner::::call( + alice(), + alice(), + result.address, + create_contract, + amount, + 1000000000, + 1000000000, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(result.used_storage, 281); + + assert_eq!( + balance(alice()), + alice_balance - amount - 281 * ::StorageDepositPerByte::get() + ); + assert_eq!(balance(factory_contract_address), amount); + let contract_address = H160::from_str("7b8f8ca099f6e33cf1817cf67d0556429cfc54e4").unwrap(); + assert_eq!(reserved_balance(contract_address), 1530); + }); +} + +#[test] +fn contract_should_deploy_contracts_without_payable() { + // pragma solidity ^0.5.0; + // + // contract Factory { + // Contract[] newContracts; + // + // function createContract () public { + // Contract newContract = new Contract(); + // newContracts.push(newContract); + // } + // } + // + // contract Contract {} + let contract = from_hex( + "0x608060405234801561001057600080fd5b5061016c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063412a5a6d14610030575b600080fd5b61003861003a565b005b6000604051610048906100d0565b604051809103906000f080158015610064573d6000803e3d6000fd5b50905060008190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b605b806100dd8339019056fe6080604052348015600f57600080fd5b50603e80601d6000396000f3fe6080604052600080fdfea265627a7a7231582094976cee5af14bf59c4bae67c79c12eb15de19bc18ad6038f3ee0898273c9c0564736f6c63430005110032a265627a7a72315820e19ae28dbf01eae11c526295a1ac533ea341c74d5724efe43171f6010fc98b3964736f6c63430005110032" + ).unwrap(); + new_test_ext().execute_with(|| { + let result = Runner::::create( + alice(), + contract.clone(), + 0, + 1000000000, + 1000000000, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + + let alice_balance = INITIAL_BALANCE - 464 * ::StorageDepositPerByte::get(); + + assert_eq!(balance(alice()), alice_balance); + let factory_contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(result.address); + + // Factory.createContract + let create_contract = from_hex("0x412a5a6d").unwrap(); + let result = Runner::::call( + alice(), + alice(), + result.address, + create_contract, + 0, + 1000000000, + 1000000000, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(result.used_storage, 290); + assert_eq!( + balance(alice()), + alice_balance - (result.used_storage as u64 * ::StorageDepositPerByte::get()) + ); + assert_eq!(balance(factory_contract_address), 0); + }); +} + +#[test] +fn deploy_factory() { + // pragma solidity ^0.5.0; + // + // contract Factory { + // Contract c; + // constructor() public { + // c = new Contract(); + // c.foo(); + // } + // } + // + // contract Contract { + // function foo() public pure returns (uint) { + // return 123; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060405161001d90610121565b604051809103906000f080158015610039573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b815260040160206040518083038186803b1580156100e057600080fd5b505afa1580156100f4573d6000803e3d6000fd5b505050506040513d602081101561010a57600080fd5b81019080805190602001909291905050505061012d565b60a58061017983390190565b603e8061013b6000396000f3fe6080604052600080fdfea265627a7a7231582064177030ee644a03aaf8d65027df9e0331c8bc4b161de25bfb8aa3142848e0f864736f6c634300051100326080604052348015600f57600080fd5b5060878061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000607b90509056fea265627a7a7231582031e5a4abae00962cfe9875df1b5b0d3ce6624e220cb8c714a948794fcddb6b4f64736f6c63430005110032" + ).unwrap(); + new_test_ext().execute_with(|| { + let result = Runner::::create(alice(), contract, 0, 2_000_000, 5000, ::config()).unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.used_gas.as_u64(), 124_479u64); + assert_eq!(result.used_storage, 461); + assert_eq!( + balance(alice()), + INITIAL_BALANCE - (result.used_storage as u64 * ::StorageDepositPerByte::get()) + ); + }); +} + +#[test] +fn create_network_contract_works() { + // pragma solidity ^0.5.0; + // + // contract Test { + // function multiply(uint a, uint b) public pure returns(uint) { + // return a * b; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + // deploy contract + assert_ok!(EVM::create_network_contract( + Origin::signed(NetworkContractAccount::get()), + contract, + 0, + 1000000, + 1000000, + )); + + assert_eq!( + Pallet::::account_basic(&NetworkContractSource::get()).nonce, + 2.into() + ); + System::assert_last_event(Event::evm_mod(crate::Event::Created(H160::from_low_u64_be( + MIRRORED_NFT_ADDRESS_START, + )))); + assert_eq!(EVM::network_contract_index(), MIRRORED_NFT_ADDRESS_START + 1); + }); +} + +#[test] +fn create_network_contract_fails_if_non_network_contract_origin() { + // pragma solidity ^0.5.0; + // + // contract Test { + // function multiply(uint a, uint b) public pure returns(uint) { + // return a * b; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + assert_noop!( + EVM::create_network_contract( + Origin::signed(AccountId32::from([1u8; 32])), + contract, + 0, + 1000000, + 1000000 + ), + BadOrigin + ); + }); +} + +#[test] +fn should_transfer_maintainer() { + // pragma solidity ^0.5.0; + // + // contract Factory { + // Contract c; + // constructor() public { + // c = new Contract(); + // c.foo(); + // } + // } + // + // contract Contract { + // function foo() public pure returns (uint) { + // return 123; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060405161001d90610121565b604051809103906000f080158015610039573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c29855786040518163ffffffff1660e01b815260040160206040518083038186803b1580156100e057600080fd5b505afa1580156100f4573d6000803e3d6000fd5b505050506040513d602081101561010a57600080fd5b81019080805190602001909291905050505061012d565b60a58061017983390190565b603e8061013b6000396000f3fe6080604052600080fdfea265627a7a7231582064177030ee644a03aaf8d65027df9e0331c8bc4b161de25bfb8aa3142848e0f864736f6c634300051100326080604052348015600f57600080fd5b5060878061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000607b90509056fea265627a7a7231582031e5a4abae00962cfe9875df1b5b0d3ce6624e220cb8c714a948794fcddb6b4f64736f6c63430005110032" + ).unwrap(); + new_test_ext().execute_with(|| { + let result = + Runner::::create(alice(), contract, 0, 12_000_000, 12_000_000, ::config()).unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.used_storage, 461); + let alice_balance = INITIAL_BALANCE - 461 * ::StorageDepositPerByte::get(); + + assert_eq!(balance(alice()), alice_balance); + + let alice_account_id = ::AddressMapping::get_account_id(&alice()); + let bob_account_id = ::AddressMapping::get_account_id(&bob()); + assert_eq!(balance(bob()), INITIAL_BALANCE); + // transfer_maintainer + assert_ok!(EVM::transfer_maintainer( + Origin::signed(alice_account_id.clone()), + result.address, + bob() + )); + System::assert_last_event(Event::evm_mod(crate::Event::TransferredMaintainer( + result.address, + bob(), + ))); + assert_eq!(balance(bob()), INITIAL_BALANCE); + + assert_noop!( + EVM::transfer_maintainer(Origin::signed(bob_account_id.clone()), H160::default(), alice()), + Error::::ContractNotFound + ); + + assert_noop!( + EVM::transfer_maintainer(Origin::signed(alice_account_id.clone()), result.address, bob()), + Error::::NoPermission + ); + assert_eq!(balance(alice()), alice_balance); + }); +} + +#[test] +fn should_deploy() { + // pragma solidity ^0.5.0; + // + // contract Test { + // function multiply(uint a, uint b) public pure returns(uint) { + // return a * b; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + let alice_account_id = ::AddressMapping::get_account_id(&alice()); + let bob_account_id = ::AddressMapping::get_account_id(&bob()); + + // contract not created yet + assert_noop!(EVM::deploy(Origin::signed(alice_account_id.clone()), H160::default()), Error::::ContractNotFound); + + // if the contract not exists, evm will return ExitSucceed::Stopped. + let result = Runner::::call( + alice(), + alice(), + EvmAddress::default(), + vec![], + 0, + 1000000, + 1000000, + ::config(), + ).unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(result.used_storage, 0); + + // create contract + let result = Runner::::create(alice(), contract, 0, 21_000_000, 21_000_000, ::config()).unwrap(); + let contract_address = result.address; + + assert_eq!(result.used_storage, 284); + let alice_balance = INITIAL_BALANCE - 284 * ::StorageDepositPerByte::get(); + + assert_eq!(balance(alice()), alice_balance); + + // multiply(2, 3) + let multiply = from_hex( + "0x165c4a1600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003" + ).unwrap(); + + // contract maintainer can call + assert_ok!(Runner::::call( + alice(), + alice(), + contract_address, + multiply.clone(), + 0, + 1000000, + 1000000, + ::config(), + )); + + // call method `multiply` will fail, not deployed yet + assert_noop!(Runner::::call( + bob(), + alice(), + contract_address, + multiply.clone(), + 0, + 1000000, + 1000000, + ::config(), + ), Error::::NoPermission); + + // developer can call the undeployed contract + assert_ok!(EVM::enable_contract_development(Origin::signed(bob_account_id.clone()))); + assert_ok!(Runner::::call( + bob(), + bob(), + contract_address, + vec![], + 0, + 1000000, + 1000000, + ::config(), + )); + + // not maintainer + assert_noop!(EVM::deploy(Origin::signed(bob_account_id), contract_address), Error::::NoPermission); + + assert_ok!(EVM::deploy(Origin::signed(alice_account_id.clone()), contract_address)); + let code_size = Accounts::::get(contract_address).map_or(0, |account_info| -> u32 { + account_info.contract_info.map_or(0, |contract_info| CodeInfos::::get(contract_info.code_hash).map_or(0, |code_info| code_info.code_size)) + }); + assert_eq!(balance(alice()), INITIAL_BALANCE - DeploymentFee::get() - ((NewContractExtraBytes::get() + code_size) as u64 * StorageDepositPerByte::get())); + assert_eq!(Balances::free_balance(TreasuryAccount::get()), DeploymentFee::get()); + + // call method `multiply` will work + assert_ok!(Runner::::call( + alice(), + alice(), + contract_address, + multiply, + 0, + 1000000, + 1000000, + ::config(), + )); + + // contract already deployed + assert_noop!(EVM::deploy(Origin::signed(alice_account_id), contract_address), Error::::ContractAlreadyDeployed); + }); +} + +#[test] +fn should_deploy_free() { + // pragma solidity ^0.5.0; + // + // contract Test { + // function multiply(uint a, uint b) public pure returns(uint) { + // return a * b; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + // contract not created yet + assert_noop!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), H160::default()), Error::::ContractNotFound); + + // create contract + let result = Runner::::create(alice(), contract, 0, 21_000_000, 21_000_000, ::config()).unwrap(); + let contract_address = result.address; + + // multiply(2, 3) + let multiply = from_hex( + "0x165c4a1600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003" + ).unwrap(); + + // call method `multiply` will fail, not deployed yet + assert_noop!(Runner::::call( + bob(), + alice(), + contract_address, + multiply.clone(), + 0, + 1000000, + 1000000, + ::config(), + ), Error::::NoPermission); + + assert_ok!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), contract_address)); + + // call method `multiply` + assert_ok!(Runner::::call( + bob(), + alice(), + contract_address, + multiply.clone(), + 0, + 1000000, + 1000000, + ::config(), + )); + + // contract already deployed + assert_noop!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), contract_address), Error::::ContractAlreadyDeployed); + }); +} + +#[test] +fn should_enable_contract_development() { + new_test_ext().execute_with(|| { + let alice_account_id = ::AddressMapping::get_account_id(&alice()); + assert_ok!(EVM::enable_contract_development(Origin::signed(alice_account_id))); + assert_eq!( + Accounts::::get(alice()).unwrap().developer_deposit, + Some(DeveloperDeposit::get()) + ); + assert_eq!(balance(alice()), INITIAL_BALANCE - DeveloperDeposit::get()); + }); +} + +#[test] +fn should_disable_contract_development() { + new_test_ext().execute_with(|| { + let alice_account_id = ::AddressMapping::get_account_id(&alice()); + + // contract development is not enabled yet + assert_noop!( + EVM::disable_contract_development(Origin::signed(alice_account_id.clone())), + Error::::ContractDevelopmentNotEnabled + ); + assert_eq!(balance(alice()), INITIAL_BALANCE); + + // enable contract development + assert_ok!(EVM::enable_contract_development(Origin::signed( + alice_account_id.clone() + ))); + assert_eq!( + Accounts::::get(alice()).unwrap().developer_deposit, + Some(DeveloperDeposit::get()) + ); + + // deposit reserved + assert_eq!(balance(alice()), INITIAL_BALANCE - DeveloperDeposit::get()); + + // disable contract development + assert_ok!(EVM::disable_contract_development(Origin::signed( + alice_account_id.clone() + ))); + // deposit unreserved + assert_eq!(balance(alice()), INITIAL_BALANCE); + + // contract development already disabled + assert_noop!( + EVM::disable_contract_development(Origin::signed(alice_account_id)), + Error::::ContractDevelopmentNotEnabled + ); + }); +} + +#[test] +fn should_set_code() { + // pragma solidity ^0.5.0; + // + // contract Test { + // function multiply(uint a, uint b) public pure returns(uint) { + // return a * b; + // } + // } + let contract = from_hex( + "0x608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032" + ).unwrap(); + + let contract_err = from_hex( + "0x608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032608060405234801561001057600080fd5b5060b88061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063165c4a1614602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506076565b6040518082815260200191505060405180910390f35b600081830290509291505056fea265627a7a723158201f3db7301354b88b310868daf4395a6ab6cd42d16b1d8e68cdf4fdd9d34fffbf64736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + let alice_account_id = ::AddressMapping::get_account_id(&alice()); + let bob_account_id = ::AddressMapping::get_account_id(&bob()); + + // create contract + let result = Runner::::create( + alice(), + contract.clone(), + 0, + 21_000_000, + 21_000_000, + ::config(), + ) + .unwrap(); + let contract_address = result.address; + assert_eq!(result.used_storage, 284); + let alice_balance = INITIAL_BALANCE - 284 * ::StorageDepositPerByte::get(); + + assert_eq!(balance(alice()), alice_balance); + + assert_noop!( + EVM::set_code(Origin::signed(bob_account_id), contract_address, contract.clone()), + Error::::NoPermission + ); + assert_ok!(EVM::set_code( + Origin::signed(alice_account_id.clone()), + contract_address, + contract.clone() + )); + assert_ok!(EVM::set_code(Origin::root(), contract_address, contract)); + + assert_noop!( + EVM::set_code( + Origin::signed(alice_account_id.clone()), + contract_address, + contract_err.clone() + ), + Error::::ContractExceedsMaxCodeSize + ); + + assert_ok!(EVM::deploy_free( + Origin::signed(CouncilAccount::get()), + contract_address + )); + + assert_noop!( + EVM::set_code(Origin::signed(alice_account_id), contract_address, contract_err), + Error::::ContractAlreadyDeployed + ); + }); +} + +#[test] +fn should_selfdestruct() { + // pragma solidity ^0.5.0; + // + // contract Test { + // uint value; + // constructor(uint a) public payable { + // value = a; + // } + // + // function getValue() public payable returns (uint) { + // return value; + // } + // } + let mut contract = from_hex( + "0x60806040526040516100c73803806100c783398181016040526020811015602557600080fd5b81019080805190602001909291905050508060008190555050607b8061004c6000396000f3fe608060405260043610601c5760003560e01c806320965255146021575b600080fd5b6027603d565b6040518082815260200191505060405180910390f35b6000805490509056fea265627a7a72315820b832564a9db725638dcef03d07bfbdd2dc818020ea359630317e2126e95c314964736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + let alice_account_id = ::AddressMapping::get_account_id(&alice()); + let bob_account_id = ::AddressMapping::get_account_id(&bob()); + + let amount = 1000u64; + + let stored_value: Vec = + from_hex("0x000000000000000000000000000000000000000000000000000000000000007b").unwrap(); + contract.append(&mut stored_value.clone()); + + // create contract + let result = + Runner::::create(alice(), contract, amount, 100000, 100000, ::config()).unwrap(); + + let contract_address = result.address; + assert_eq!(result.used_storage, 287); + let alice_balance = INITIAL_BALANCE - 287 * ::StorageDepositPerByte::get() - amount; + + assert_eq!(balance(alice()), alice_balance); + + let code_hash = H256::from_str("21fe816097a50d298f819bc6d40cff473c43c87d99bcd7d3c3b2b85417f66f5a").unwrap(); + let code_size = 123u32; + + assert_eq!( + ContractStorageSizes::::get(&contract_address), + code_size + NewContractExtraBytes::get() + STORAGE_SIZE + ); + assert_eq!( + CodeInfos::::get(&code_hash), + Some(CodeInfo { + code_size, + ref_count: 1, + }) + ); + assert!(Codes::::contains_key(&code_hash)); + + assert_noop!( + EVM::selfdestruct(Origin::signed(bob_account_id), contract_address), + Error::::NoPermission + ); + assert_ok!(EVM::selfdestruct(Origin::signed(alice_account_id), contract_address)); + + let contract_account_id = ::AddressMapping::get_account_id(&contract_address); + + assert!(!System::account_exists(&contract_account_id)); + assert!(!Accounts::::contains_key(&contract_address)); + assert!(!ContractStorageSizes::::contains_key(&contract_address)); + assert_eq!(AccountStorages::::iter_prefix(&contract_address).count(), 0); + assert!(!CodeInfos::::contains_key(&code_hash)); + assert!(!Codes::::contains_key(&code_hash)); + }); +} + +#[test] +fn storage_limit_should_work() { + // pragma solidity ^0.5.0; + + // contract Factory { + // Contract[] newContracts; + + // function createContract (uint num) public payable { + // for(uint i = 0; i < num; i++) { + // Contract newContract = new Contract(); + // newContracts.push(newContract); + // } + // } + // } + + // contract Contract {} + let contract = from_hex( + "0x608060405234801561001057600080fd5b506101a0806100206000396000f3fe60806040526004361061001e5760003560e01c80639db8d7d514610023575b600080fd5b61004f6004803603602081101561003957600080fd5b8101908080359060200190929190505050610051565b005b60008090505b8181101561010057600060405161006d90610104565b604051809103906000f080158015610089573d6000803e3d6000fd5b50905060008190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050508080600101915050610057565b5050565b605b806101118339019056fe6080604052348015600f57600080fd5b50603e80601d6000396000f3fe6080604052600080fdfea265627a7a7231582035666e9471716d6d05ed9f0c1ab13d0371f49d536270f905bff06cd98212dcb064736f6c63430005110032a265627a7a723158203b6aaf6588bc3e6a35986612a62f715255430eab09ffb24401e5f18eb58a05d564736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + let result = + Runner::::create(alice(), contract.clone(), 0, 200_000, 1000, ::config()).unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.used_storage, 516); + let alice_balance = INITIAL_BALANCE - 516 * ::StorageDepositPerByte::get(); + assert_eq!(balance(alice()), alice_balance); + + let factory_contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(factory_contract_address); + + assert_eq!(balance(factory_contract_address), 0); + assert_eq!( + reserved_balance(factory_contract_address), + 516 * ::StorageDepositPerByte::get() + ); + + // Factory.createContract(1) + let amount = 1000000000; + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let result = Runner::::call( + alice(), + alice(), + factory_contract_address, + create_contract, + amount, + 1000000000, + 0, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Revert(ExitRevert::Reverted)); + assert_eq!(result.used_storage, 0); + + // Factory.createContract(1) + let amount = 1000000000; + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let result = Runner::::call( + alice(), + alice(), + factory_contract_address, + create_contract, + amount, + 1000000000, + 1000000000, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(result.used_storage, 290); + + // Factory.createContract(2) + let amount = 1000000000; + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000002").unwrap(); + let result = Runner::::call( + alice(), + alice(), + factory_contract_address, + create_contract, + amount, + 1000000000, + 127, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Revert(ExitRevert::Reverted)); + assert_eq!(result.used_storage, 0); + + // Factory.createContract(2) + let amount = 1000000000; + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000002").unwrap(); + let result = Runner::::call( + alice(), + alice(), + factory_contract_address, + create_contract, + amount, + 1000000000, + 1000000000, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Stopped)); + assert_eq!(result.used_storage, 452); + }); +} + +#[test] +fn evm_execute_mode_should_work() { + // pragma solidity ^0.5.0; + + // contract Factory { + // Contract[] newContracts; + + // function createContract (uint num) public payable { + // for(uint i = 0; i < num; i++) { + // Contract newContract = new Contract(); + // newContracts.push(newContract); + // } + // } + // } + + // contract Contract {} + let contract = from_hex( + "0x608060405234801561001057600080fd5b506101a0806100206000396000f3fe60806040526004361061001e5760003560e01c80639db8d7d514610023575b600080fd5b61004f6004803603602081101561003957600080fd5b8101908080359060200190929190505050610051565b005b60008090505b8181101561010057600060405161006d90610104565b604051809103906000f080158015610089573d6000803e3d6000fd5b50905060008190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050508080600101915050610057565b5050565b605b806101118339019056fe6080604052348015600f57600080fd5b50603e80601d6000396000f3fe6080604052600080fdfea265627a7a7231582035666e9471716d6d05ed9f0c1ab13d0371f49d536270f905bff06cd98212dcb064736f6c63430005110032a265627a7a723158203b6aaf6588bc3e6a35986612a62f715255430eab09ffb24401e5f18eb58a05d564736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + let mut alice_balance = INITIAL_BALANCE - 516 * ::StorageDepositPerByte::get(); + + let result = Runner::::create( + alice(), + contract.clone(), + 0, + 1000000000, + 1000000000, + ::config(), + ) + .unwrap(); + assert_eq!(result.exit_reason, ExitReason::Succeed(ExitSucceed::Returned)); + assert_eq!(result.used_storage, 516); + assert_eq!(balance(alice()), alice_balance); + let factory_contract_address = result.address; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(result.address); + + let context = InvokeContext { + contract: factory_contract_address, + sender: alice(), + origin: alice(), + }; + + // ExecutionMode::EstimateGas + // Factory.createContract(1) + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let result = EVM::execute( + context, + create_contract, + Default::default(), + 2_100_000, + 1000, + ExecutionMode::EstimateGas, + ) + .unwrap(); + assert_eq!( + result, + CallInfo { + exit_reason: ExitReason::Succeed(ExitSucceed::Stopped), + output: vec![], + used_gas: U256::from(113949), + used_storage: 290 + } + ); + + // Factory.createContract(2) + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000002").unwrap(); + let result = EVM::execute( + context, + create_contract, + Default::default(), + 2_100_000, + 2_100_000, + ExecutionMode::EstimateGas, + ) + .unwrap(); + assert_eq!( + result, + CallInfo { + exit_reason: ExitReason::Succeed(ExitSucceed::Stopped), + output: vec![], + used_gas: U256::from(200380), + used_storage: 516 + } + ); + assert_eq!(balance(alice()), alice_balance); + + // ExecutionMode::Execute + // Factory.createContract(1) + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let result = EVM::execute( + context, + create_contract, + Default::default(), + 2_100_000, + 0, + ExecutionMode::Execute, + ) + .unwrap(); + assert_eq!( + result, + CallInfo { + exit_reason: ExitReason::Revert(ExitRevert::Reverted), + output: vec![], + used_gas: U256::from(72098), + used_storage: 0 + } + ); + assert_eq!(balance(alice()), alice_balance); + + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let result = EVM::execute( + context, + create_contract, + Default::default(), + 2_100_000, + 2_100_000, + ExecutionMode::Execute, + ) + .unwrap(); + assert_eq!( + result, + CallInfo { + exit_reason: ExitReason::Succeed(ExitSucceed::Stopped), + output: vec![], + used_gas: U256::from(113949), + used_storage: 290 + } + ); + + alice_balance -= 290 * ::StorageDepositPerByte::get(); + + assert_eq!(balance(alice()), alice_balance); + + // ExecutionMode::View + // Discard any state changes + let create_contract = + from_hex("0x9db8d7d50000000000000000000000000000000000000000000000000000000000000001").unwrap(); + let result = EVM::execute( + context, + create_contract, + Default::default(), + 2_100_000, + 2_100_000, + ExecutionMode::View, + ) + .unwrap(); + assert_eq!( + result, + CallInfo { + exit_reason: ExitReason::Succeed(ExitSucceed::Stopped), + output: vec![], + used_gas: U256::from(98949), + used_storage: 226 + } + ); + + assert_eq!(balance(alice()), alice_balance); + }); +} + +#[test] +fn should_update_storage() { + // pragma solidity ^0.5.0; + // + // contract Test { + // mapping(address => uint256) public values; + // + // constructor() public { + // values[msg.sender] = 42; + // } + // + // function set(uint val) public { + // values[msg.sender] = val; + // } + // } + + let contract = from_hex( + "0x608060405234801561001057600080fd5b50602a6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610154806100646000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806354fe9fd71461003b57806360fe47b114610093575b600080fd5b61007d6004803603602081101561005157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100c1565b6040518082815260200191505060405180910390f35b6100bf600480360360208110156100a957600080fd5b81019080803590602001909291905050506100d9565b005b60006020528060005260406000206000915090505481565b806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505056fea265627a7a723158207ab6991e97c9c12f57d81df0c7f955435418354adeb26116b581d7f2f035ca8f64736f6c63430005110032" + ).unwrap(); + + new_test_ext().execute_with(|| { + // create contract + let result = Runner::::create(alice(), contract, 0, 500000, 100000, ::config()).unwrap(); + + let contract_address = result.address; + + let code_size = 340u32; + + let mut used_storage = code_size + NewContractExtraBytes::get() + STORAGE_SIZE; + + assert_eq!(result.used_storage, used_storage as i32); + + assert_eq!(ContractStorageSizes::::get(&contract_address), used_storage); + + #[cfg(not(feature = "with-ethereum-compatibility"))] + deploy_free(contract_address); + + // call method `set(123)` + assert_err!( + Runner::::call( + bob(), + alice(), + contract_address, + from_hex("0x60fe47b1000000000000000000000000000000000000000000000000000000000000007b").unwrap(), + 0, + 1000000, + 0, + ::config(), + ), + DispatchError::Other("OutOfStorage") + ); + + // call method `set(123)` + let result = Runner::::call( + bob(), + alice(), + contract_address, + from_hex("0x60fe47b1000000000000000000000000000000000000000000000000000000000000007b").unwrap(), + 0, + 1000000, + STORAGE_SIZE, + ::config(), + ) + .unwrap(); + + used_storage += STORAGE_SIZE; + + assert_eq!(result.used_storage, STORAGE_SIZE as i32); + assert_eq!(ContractStorageSizes::::get(&contract_address), used_storage); + + // call method `set(0)` + let result = Runner::::call( + bob(), + alice(), + contract_address, + from_hex("0x60fe47b10000000000000000000000000000000000000000000000000000000000000000").unwrap(), + 0, + 1000000, + STORAGE_SIZE, + ::config(), + ) + .unwrap(); + + used_storage -= STORAGE_SIZE; + + assert_eq!(result.used_storage, -(STORAGE_SIZE as i32)); + assert_eq!(ContractStorageSizes::::get(&contract_address), used_storage); + }); +} diff --git a/lib-serml/evm/src/weights.rs b/lib-serml/evm/src/weights.rs new file mode 100644 index 000000000..ac5025503 --- /dev/null +++ b/lib-serml/evm/src/weights.rs @@ -0,0 +1,137 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +//! Autogenerated weights for module_evm +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-02-26, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/setheum +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=module_evm +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./lib-serml/evm/src/weights.rs +// --template=./templates/module-weight-template.hbs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for module_evm. +pub trait WeightInfo { + fn transfer_maintainer() -> Weight; + fn deploy() -> Weight; + fn deploy_free() -> Weight; + fn enable_contract_development() -> Weight; + fn disable_contract_development() -> Weight; + fn set_code() -> Weight; + fn selfdestruct() -> Weight; +} + +/// Weights for module_evm using the Setheum node and recommended hardware. +pub struct SetheumWeight(PhantomData); +impl WeightInfo for SetheumWeight { + fn transfer_maintainer() -> Weight { + (69_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn deploy() -> Weight { + (101_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn deploy_free() -> Weight { + (19_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn enable_contract_development() -> Weight { + (87_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn disable_contract_development() -> Weight { + (87_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn set_code() -> Weight { + (83_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn selfdestruct() -> Weight { + (141_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn transfer_maintainer() -> Weight { + (69_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn deploy() -> Weight { + (101_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn deploy_free() -> Weight { + (19_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn enable_contract_development() -> Weight { + (87_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn disable_contract_development() -> Weight { + (87_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn set_code() -> Weight { + (83_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn selfdestruct() -> Weight { + (141_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } +} From 5a190befe1819a12cc033eebe1fd8e04dc54602c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 04:48:45 +0800 Subject: [PATCH 11/83] Add setheum-evm-accounts --- lib-serml/evm-accounts/Cargo.toml | 45 ++++ lib-serml/evm-accounts/src/lib.rs | 353 ++++++++++++++++++++++++++ lib-serml/evm-accounts/src/mock.rs | 180 +++++++++++++ lib-serml/evm-accounts/src/tests.rs | 193 ++++++++++++++ lib-serml/evm-accounts/src/weights.rs | 82 ++++++ 5 files changed, 853 insertions(+) create mode 100644 lib-serml/evm-accounts/Cargo.toml create mode 100644 lib-serml/evm-accounts/src/lib.rs create mode 100644 lib-serml/evm-accounts/src/mock.rs create mode 100644 lib-serml/evm-accounts/src/tests.rs create mode 100644 lib-serml/evm-accounts/src/weights.rs diff --git a/lib-serml/evm-accounts/Cargo.toml b/lib-serml/evm-accounts/Cargo.toml new file mode 100644 index 000000000..f3aab93ad --- /dev/null +++ b/lib-serml/evm-accounts/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "setheum-evm-accounts" +version = "1.0.0" +authors = ["Setheum Labs"] +edition = "2018" + +[dependencies] +serde = { version = "1.0.124", optional = true } +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } +libsecp256k1 = { version = "0.3.4", default-features = false, features = ["hmac"] } + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } + +orml-traits = { path = "../../lib-openrml/traits", default-features = false } + +primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } +setheum-support = { path = "../support", default-features = false } + +[dev-dependencies] +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +orml-currencies = { path = "../../lib-openrml/currencies" } +orml-tokens = { path = "../../lib-openrml/tokens" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "libsecp256k1/std", + "sp-core/std", + "sp-runtime/std", + "sp-io/std", + "sp-std/std", + "frame-support/std", + "frame-system/std", + "primitives/std", + "orml-traits/std", + "setheum-support/std", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/lib-serml/evm-accounts/src/lib.rs b/lib-serml/evm-accounts/src/lib.rs new file mode 100644 index 000000000..445cc5589 --- /dev/null +++ b/lib-serml/evm-accounts/src/lib.rs @@ -0,0 +1,353 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! # Evm Accounts Module +//! +//! ## Overview +//! +//! Evm Accounts module provide a two way mapping between Substrate accounts and +//! EVM accounts so user only have deal with one account / private key. + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] + +use codec::Encode; +use frame_support::{ + ensure, + pallet_prelude::*, + traits::{Currency, IsType, OnKilledAccount, ReservableCurrency}, + transactional, +}; +use frame_system::{ensure_signed, pallet_prelude::*}; +use module_support::AddressMapping; +use orml_traits::{currency::TransferAll, Handler}; +use primitives::{evm::EvmAddress, AccountIndex}; +use sp_core::{crypto::AccountId32, ecdsa}; +use sp_io::{ + crypto::secp256k1_ecdsa_recover, + hashing::{blake2_256, keccak_256}, +}; +use sp_runtime::{ + traits::{LookupError, StaticLookup}, + MultiAddress, +}; +use sp_std::{marker::PhantomData, vec::Vec}; + +mod mock; +mod tests; +pub mod weights; + +pub use module::*; +pub use weights::WeightInfo; + +pub type EcdsaSignature = ecdsa::Signature; + +#[frame_support::pallet] +pub mod module { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + + /// The Currency for managing Evm account assets. + type Currency: Currency + ReservableCurrency; + + /// Mapping from address to account id. + type AddressMapping: AddressMapping; + + /// Merge free balance from source to dest. + type TransferAll: TransferAll; + + /// On claim account hook. + type OnClaim: Handler; + + /// Weight information for the extrinsics in this module. + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event { + /// Mapping between Substrate accounts and EVM accounts + /// claim account. \[account_id, evm_address\] + ClaimAccount(T::AccountId, EvmAddress), + } + + /// Error for evm accounts module. + #[pallet::error] + pub enum Error { + /// AccountId has mapped + AccountIdHasMapped, + /// Eth address has mapped + EthAddressHasMapped, + /// Bad signature + BadSignature, + /// Invalid signature + InvalidSignature, + /// Account ref count is not zero + NonZeroRefCount, + } + + /// The Substrate Account for EvmAddresses + /// + /// Accounts: map EvmAddress => Option + #[pallet::storage] + #[pallet::getter(fn accounts)] + pub type Accounts = StorageMap<_, Twox64Concat, EvmAddress, T::AccountId, OptionQuery>; + + /// The EvmAddress for Substrate Accounts + /// + /// EvmAddresses: map AccountId => Option + #[pallet::storage] + #[pallet::getter(fn evm_addresses)] + pub type EvmAddresses = StorageMap<_, Twox64Concat, T::AccountId, EvmAddress, OptionQuery>; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet { + /// Claim account mapping between Substrate accounts and EVM accounts. + /// Ensure eth_address has not been mapped. + /// + /// - `eth_address`: The address to bind to the caller's account + /// - `eth_signature`: A signature generated by the address to prove ownership + #[pallet::weight(T::WeightInfo::claim_account())] + #[transactional] + pub fn claim_account( + origin: OriginFor, + eth_address: EvmAddress, + eth_signature: EcdsaSignature, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + + // ensure account_id and eth_address has not been mapped + ensure!(!EvmAddresses::::contains_key(&who), Error::::AccountIdHasMapped); + ensure!( + !Accounts::::contains_key(eth_address), + Error::::EthAddressHasMapped + ); + + // recover evm address from signature + let address = Self::eth_recover(ð_signature, &who.using_encoded(to_ascii_hex), &[][..]) + .ok_or(Error::::BadSignature)?; + ensure!(eth_address == address, Error::::InvalidSignature); + + // check if the evm padded address already exists + let account_id = T::AddressMapping::get_account_id(ð_address); + if frame_system::Pallet::::account_exists(&account_id) { + // merge balance from `evm padded address` to `origin` + T::TransferAll::transfer_all(&account_id, &who)?; + } + + Accounts::::insert(eth_address, &who); + EvmAddresses::::insert(&who, eth_address); + + T::OnClaim::handle(&who)?; + + Self::deposit_event(Event::ClaimAccount(who, eth_address)); + + Ok(().into()) + } + + /// Claim account mapping between Substrate accounts and a generated EVM + /// address based off of those accounts. + /// Ensure eth_address has not been mapped + #[pallet::weight(T::WeightInfo::claim_default_account())] + pub fn claim_default_account(origin: OriginFor) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + + // ensure account_id has not been mapped + ensure!(!EvmAddresses::::contains_key(&who), Error::::AccountIdHasMapped); + + let eth_address = T::AddressMapping::get_or_create_evm_address(&who); + + T::OnClaim::handle(&who)?; + + Self::deposit_event(Event::ClaimAccount(who, eth_address)); + + Ok(().into()) + } + } +} + +impl Pallet { + // Constructs the message that Ethereum RPC's `personal_sign` and `eth_sign` + // would sign. + pub fn ethereum_signable_message(what: &[u8], extra: &[u8]) -> Vec { + let prefix = b"setheum evm:"; + let mut l = prefix.len() + what.len() + extra.len(); + let mut rev = Vec::new(); + while l > 0 { + rev.push(b'0' + (l % 10) as u8); + l /= 10; + } + let mut v = b"\x19Ethereum Signed Message:\n".to_vec(); + v.extend(rev.into_iter().rev()); + v.extend_from_slice(&prefix[..]); + v.extend_from_slice(what); + v.extend_from_slice(extra); + v + } + + // Attempts to recover the Ethereum address from a message signature signed by + // using the Ethereum RPC's `personal_sign` and `eth_sign`. + pub fn eth_recover(s: &EcdsaSignature, what: &[u8], extra: &[u8]) -> Option { + let msg = keccak_256(&Self::ethereum_signable_message(what, extra)); + let mut res = EvmAddress::default(); + res.0 + .copy_from_slice(&keccak_256(&secp256k1_ecdsa_recover(&s.0, &msg).ok()?[..])[12..]); + Some(res) + } + + // Returns an Etherum public key derived from an Ethereum secret key. + pub fn eth_public(secret: &secp256k1::SecretKey) -> secp256k1::PublicKey { + secp256k1::PublicKey::from_secret_key(secret) + } + + // Returns an Etherum address derived from an Ethereum secret key. + pub fn eth_address(secret: &secp256k1::SecretKey) -> EvmAddress { + EvmAddress::from_slice(&keccak_256(&Self::eth_public(secret).serialize()[1..65])[12..]) + } + + // Constructs a message and signs it. + pub fn eth_sign(secret: &secp256k1::SecretKey, what: &[u8], extra: &[u8]) -> EcdsaSignature { + let msg = keccak_256(&Self::ethereum_signable_message(&to_ascii_hex(what)[..], extra)); + let (sig, recovery_id) = secp256k1::sign(&secp256k1::Message::parse(&msg), secret); + let mut r = [0u8; 65]; + r[0..64].copy_from_slice(&sig.serialize()[..]); + r[64] = recovery_id.serialize(); + EcdsaSignature::from_slice(&r) + } +} + +// Creates a an EvmAddress from an AccountId by appending the bytes "evm:" to +// the account_id and hashing it. +fn account_to_default_evm_address(account_id: &impl Encode) -> EvmAddress { + let payload = (b"evm:", account_id); + EvmAddress::from_slice(&payload.using_encoded(blake2_256)[0..20]) +} + +pub struct EvmAddressMapping(sp_std::marker::PhantomData); + +impl AddressMapping for EvmAddressMapping +where + T::AccountId: IsType, +{ + // Returns the AccountId used go generate the given EvmAddress. + fn get_account_id(address: &EvmAddress) -> T::AccountId { + if let Some(acc) = Accounts::::get(address) { + acc + } else { + let mut data: [u8; 32] = [0u8; 32]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + AccountId32::from(data).into() + } + } + + // Returns the EvmAddress associated with a given AccountId or the + // underlying EvmAddress of the AccountId. + // Returns None if there is no EvmAddress associated with the AccountId + // and there is no underlying EvmAddress in the AccountId. + fn get_evm_address(account_id: &T::AccountId) -> Option { + // Return the EvmAddress if a mapping to account_id exists + EvmAddresses::::get(account_id).or_else(|| { + let data: &[u8] = account_id.into_ref().as_ref(); + // Return the underlying EVM address if it exists otherwise return None + if data.starts_with(b"evm:") { + Some(EvmAddress::from_slice(&data[4..24])) + } else { + None + } + }) + } + + // Returns the EVM address associated with an account ID and generates an + // account mapping if no association exists. + fn get_or_create_evm_address(account_id: &T::AccountId) -> EvmAddress { + Self::get_evm_address(account_id).unwrap_or_else(|| { + let addr = account_to_default_evm_address(account_id); + + // create reverse mapping + Accounts::::insert(&addr, &account_id); + EvmAddresses::::insert(&account_id, &addr); + + addr + }) + } + + // Returns the default EVM address associated with an account ID. + fn get_default_evm_address(account_id: &T::AccountId) -> EvmAddress { + account_to_default_evm_address(account_id) + } + + // Returns true if a given AccountId is associated with a given EvmAddress + // and false if is not. + fn is_linked(account_id: &T::AccountId, evm: &EvmAddress) -> bool { + Self::get_evm_address(account_id).as_ref() == Some(evm) + || &account_to_default_evm_address(account_id.into_ref()) == evm + } +} + +pub struct CallKillAccount(PhantomData); +impl OnKilledAccount for CallKillAccount { + fn on_killed_account(who: &T::AccountId) { + // remove the reserve mapping that could be created by + // `get_or_create_evm_address` + Accounts::::remove(account_to_default_evm_address(who.into_ref())); + + // remove mapping created by `claim_account` + if let Some(evm_addr) = Pallet::::evm_addresses(who) { + Accounts::::remove(evm_addr); + EvmAddresses::::remove(who); + } + } +} + +impl StaticLookup for Pallet { + type Source = MultiAddress; + type Target = T::AccountId; + + fn lookup(a: Self::Source) -> Result { + match a { + MultiAddress::Address20(i) => Ok(T::AddressMapping::get_account_id(&EvmAddress::from_slice(&i))), + _ => Err(LookupError), + } + } + + fn unlookup(a: Self::Target) -> Self::Source { + MultiAddress::Id(a) + } +} + +/// Converts the given binary data into ASCII-encoded hex. It will be twice +/// the length. +pub fn to_ascii_hex(data: &[u8]) -> Vec { + let mut r = Vec::with_capacity(data.len() * 2); + let mut push_nibble = |n| r.push(if n < 10 { b'0' + n } else { b'a' - 10 + n }); + for &b in data.iter() { + push_nibble(b / 16); + push_nibble(b % 16); + } + r +} diff --git a/lib-serml/evm-accounts/src/mock.rs b/lib-serml/evm-accounts/src/mock.rs new file mode 100644 index 000000000..a4846a203 --- /dev/null +++ b/lib-serml/evm-accounts/src/mock.rs @@ -0,0 +1,180 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Mocks for the evm-accounts module. + +#![cfg(test)] + +use super::*; +use frame_support::{construct_runtime, parameter_types}; +use orml_traits::parameter_type_with_key; +use primitives::{Amount, Balance, CurrencyId, TokenSymbol}; +use sp_core::{crypto::AccountId32, H256}; +use sp_io::hashing::keccak_256; +use sp_runtime::{testing::Header, traits::IdentityLookup}; + +pub type AccountId = AccountId32; +pub type BlockNumber = u64; + +pub const ALICE: AccountId = AccountId32::new([0u8; 32]); +pub const BOB: AccountId = AccountId32::new([1u8; 32]); + +mod evm_accounts { + pub use super::super::*; +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = frame_system::Pallet; + type MaxLocks = (); + type WeightInfo = (); +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type Event = Event; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = (); +} + +parameter_types! { + pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); +} + +impl orml_currencies::Config for Runtime { + type Event = Event; + type MultiCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type GetNativeCurrencyId = GetNativeCurrencyId; + type WeightInfo = (); +} +pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter; + +impl Config for Runtime { + type Event = Event; + type Currency = Balances; + type AddressMapping = EvmAddressMapping; + type TransferAll = Currencies; + type OnClaim = (); + type WeightInfo = (); +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + EvmAccountsModule: evm_accounts::{Pallet, Call, Storage, Event}, + Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Currencies: orml_currencies::{Pallet, Call, Event}, + } +); + +pub struct ExtBuilder(); + +impl Default for ExtBuilder { + fn default() -> Self { + Self() + } +} + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(bob_account_id(), 100000)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} + +pub fn alice() -> secp256k1::SecretKey { + secp256k1::SecretKey::parse(&keccak_256(b"Alice")).unwrap() +} + +pub fn bob() -> secp256k1::SecretKey { + secp256k1::SecretKey::parse(&keccak_256(b"Bob")).unwrap() +} + +pub fn bob_account_id() -> AccountId { + let address = EvmAccountsModule::eth_address(&bob()); + let mut data = [0u8; 32]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + AccountId32::from(Into::<[u8; 32]>::into(data)) +} diff --git a/lib-serml/evm-accounts/src/tests.rs b/lib-serml/evm-accounts/src/tests.rs new file mode 100644 index 000000000..1bc11ca10 --- /dev/null +++ b/lib-serml/evm-accounts/src/tests.rs @@ -0,0 +1,193 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Unit tests for the evm-accounts module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::{alice, bob, Event, EvmAccountsModule, ExtBuilder, Origin, Runtime, System, ALICE, BOB}; +use std::str::FromStr; + +#[test] +fn claim_account_work() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE.encode(), &[][..]) + )); + System::assert_last_event(Event::evm_accounts(crate::Event::ClaimAccount( + ALICE, + EvmAccountsModule::eth_address(&alice()), + ))); + assert!( + Accounts::::contains_key(EvmAccountsModule::eth_address(&alice())) + && EvmAddresses::::contains_key(ALICE) + ); + }); +} + +#[test] +fn claim_account_should_not_work() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&bob()), + EvmAccountsModule::eth_sign(&bob(), &ALICE.encode(), &vec![1][..]) + ), + Error::::InvalidSignature + ); + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&bob()), + EvmAccountsModule::eth_sign(&bob(), &BOB.encode(), &[][..]) + ), + Error::::InvalidSignature + ); + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&bob()), + EvmAccountsModule::eth_sign(&alice(), &ALICE.encode(), &[][..]) + ), + Error::::InvalidSignature + ); + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE.encode(), &[][..]) + )); + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE.encode(), &[][..]) + ), + Error::::AccountIdHasMapped + ); + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(BOB), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &BOB.encode(), &[][..]) + ), + Error::::EthAddressHasMapped + ); + }); +} + +#[test] +fn evm_get_account_id() { + ExtBuilder::default().build().execute_with(|| { + let evm_account = EvmAccountsModule::eth_address(&alice()); + let evm_account_to_default = { + let mut bytes = *b"evm:aaaaaaaaaaaaaaaaaaaa\0\0\0\0\0\0\0\0"; + bytes[4..24].copy_from_slice(&evm_account[..]); + AccountId32::from(bytes) + }; + assert_eq!( + EvmAddressMapping::::get_account_id(&evm_account), + evm_account_to_default + ); + + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE.encode(), &[][..]) + )); + + assert_eq!(EvmAddressMapping::::get_account_id(&evm_account), ALICE); + assert_eq!( + EvmAddressMapping::::get_evm_address(&ALICE).unwrap(), + evm_account + ); + + assert!(EvmAddressMapping::::is_linked( + &evm_account_to_default, + &evm_account + )); + assert!(EvmAddressMapping::::is_linked(&ALICE, &evm_account)); + }); +} + +#[test] +fn account_to_evm() { + ExtBuilder::default().build().execute_with(|| { + let default_evm_account = EvmAddress::from_str("f0bd9ffde7f9f4394d8cc1d86bf24d87e5d5a9a9").unwrap(); + assert_eq!(EvmAddressMapping::::get_evm_address(&ALICE), None); + + let alice_evm_account = EvmAccountsModule::eth_address(&alice()); + + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + alice_evm_account, + EvmAccountsModule::eth_sign(&alice(), &ALICE.encode(), &[][..]) + )); + + assert_eq!(EvmAddressMapping::::get_account_id(&alice_evm_account), ALICE); + assert_eq!( + EvmAddressMapping::::get_evm_address(&ALICE).unwrap(), + alice_evm_account + ); + + assert_eq!( + EvmAddressMapping::::get_or_create_evm_address(&ALICE), + alice_evm_account + ); + + assert!(EvmAddressMapping::::is_linked(&ALICE, &alice_evm_account)); + assert!(EvmAddressMapping::::is_linked(&ALICE, &default_evm_account)); + }); +} + +#[test] +fn account_to_evm_with_create_default() { + ExtBuilder::default().build().execute_with(|| { + let default_evm_account = EvmAddress::from_str("f0bd9ffde7f9f4394d8cc1d86bf24d87e5d5a9a9").unwrap(); + assert_eq!( + EvmAddressMapping::::get_or_create_evm_address(&ALICE), + default_evm_account + ); + assert_eq!( + EvmAddressMapping::::get_evm_address(&ALICE), + Some(default_evm_account) + ); + + assert_eq!( + EvmAddressMapping::::get_account_id(&default_evm_account), + ALICE + ); + + assert!(EvmAddressMapping::::is_linked(&ALICE, &default_evm_account)); + + let alice_evm_account = EvmAccountsModule::eth_address(&alice()); + + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + alice_evm_account, + EvmAccountsModule::eth_sign(&alice(), &ALICE.encode(), &[][..]) + ), + Error::::AccountIdHasMapped + ); + }); +} diff --git a/lib-serml/evm-accounts/src/weights.rs b/lib-serml/evm-accounts/src/weights.rs new file mode 100644 index 000000000..3667776ac --- /dev/null +++ b/lib-serml/evm-accounts/src/weights.rs @@ -0,0 +1,82 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +//! Autogenerated weights for module_evm_accounts +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-02-26, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/setheum +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=module_evm_accounts +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./modules/evm-accounts/src/weights.rs +// --template=./templates/module-weight-template.hbs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for module_evm_accounts. +pub trait WeightInfo { + fn claim_account() -> Weight; + fn claim_default_account() -> Weight; +} + +/// Weights for module_evm_accounts using the Setheum node and recommended hardware. +pub struct SetheumWeight(PhantomData); +impl WeightInfo for SetheumWeight { + fn claim_account() -> Weight { + (340_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn claim_default_account() -> Weight { + (19_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn claim_account() -> Weight { + (340_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn claim_default_account() -> Weight { + (19_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } +} From acfdb8fdae0f138717dec643ac2e38bbd6b2635b Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 05:00:35 +0800 Subject: [PATCH 12/83] Add setheum-evm-bridge --- HEADER-GPL3 | 2 +- inspect/src/cli.rs | 2 +- inspect/src/command.rs | 2 +- inspect/src/lib.rs | 2 +- lib-serml/chainbridge/src/lib.rs | 2 +- lib-serml/chainbridge/src/mock.rs | 2 +- lib-serml/chainbridge/src/tests.rs | 2 +- lib-serml/chainbridge/src/weights.rs | 2 +- lib-serml/currencies/src/lib.rs | 2 +- lib-serml/currencies/src/mock.rs | 2 +- lib-serml/currencies/src/tests.rs | 2 +- lib-serml/currencies/src/weights.rs | 2 +- lib-serml/dex/src/lib.rs | 2 +- lib-serml/dex/src/mock.rs | 2 +- lib-serml/dex/src/tests.rs | 2 +- lib-serml/dex/src/weights.rs | 2 +- lib-serml/evm-accounts/src/lib.rs | 2 +- lib-serml/evm-accounts/src/mock.rs | 2 +- lib-serml/evm-accounts/src/tests.rs | 2 +- lib-serml/evm-accounts/src/weights.rs | 10 +- lib-serml/evm-bridge/Cargo.toml | 49 ++++ lib-serml/evm-bridge/src/lib.rs | 234 +++++++++++++++++ lib-serml/evm-bridge/src/mock.rs | 239 ++++++++++++++++++ lib-serml/evm-bridge/src/tests.rs | 226 +++++++++++++++++ lib-serml/evm/rpc/runtime_api/src/lib.rs | 2 +- lib-serml/evm/rpc/src/call_request.rs | 2 +- lib-serml/evm/rpc/src/evm_api.rs | 2 +- lib-serml/evm/rpc/src/lib.rs | 6 +- lib-serml/evm/src/lib.rs | 2 +- lib-serml/evm/src/mock.rs | 2 +- lib-serml/evm/src/precompiles.rs | 2 +- lib-serml/evm/src/runner/handler.rs | 2 +- lib-serml/evm/src/runner/mod.rs | 2 +- lib-serml/evm/src/runner/storage_meter.rs | 2 +- lib-serml/evm/src/tests.rs | 2 +- lib-serml/evm/src/weights.rs | 10 +- lib-serml/example/src/lib.rs | 2 +- lib-serml/example/src/mock.rs | 2 +- lib-serml/example/src/tests.rs | 2 +- lib-serml/incentives/src/lib.rs | 2 +- lib-serml/incentives/src/mock.rs | 2 +- lib-serml/incentives/src/tests.rs | 2 +- lib-serml/incentives/src/weights.rs | 2 +- lib-serml/nft/src/benchmarking.rs | 2 +- lib-serml/nft/src/lib.rs | 2 +- lib-serml/nft/src/mock.rs | 2 +- lib-serml/nft/src/tests.rs | 2 +- lib-serml/nft/src/weights.rs | 2 +- lib-serml/prices/src/lib.rs | 2 +- lib-serml/prices/src/mock.rs | 2 +- lib-serml/prices/src/tests.rs | 2 +- lib-serml/prices/src/weights.rs | 2 +- lib-serml/renvm-bridge/Cargo.toml | 2 +- lib-serml/renvm-bridge/src/lib.rs | 6 +- lib-serml/renvm-bridge/src/mock.rs | 4 +- lib-serml/renvm-bridge/src/tests.rs | 4 +- lib-serml/serp-auction/src/lib.rs | 2 +- lib-serml/serp-auction/src/mock.rs | 2 +- lib-serml/serp-auction/src/tests.rs | 2 +- lib-serml/serp-auction/src/weights.rs | 2 +- lib-serml/serp-treasury/src/lib.rs | 2 +- lib-serml/serp-treasury/src/mock.rs | 2 +- lib-serml/serp-treasury/src/tests.rs | 2 +- lib-serml/serp-treasury/src/weights.rs | 2 +- lib-serml/setters-manager/src/lib.rs | 2 +- lib-serml/setters-manager/src/mock.rs | 2 +- lib-serml/setters-manager/src/tests.rs | 2 +- lib-serml/settmint-engine/src/lib.rs | 2 +- lib-serml/settmint-engine/src/mock.rs | 2 +- .../src/standard_exchange_rate_convertor.rs | 2 +- lib-serml/settmint-engine/src/tests.rs | 2 +- lib-serml/settway/src/lib.rs | 2 +- lib-serml/settway/src/mock.rs | 2 +- lib-serml/settway/src/tests.rs | 2 +- lib-serml/settway/src/weights.rs | 2 +- lib-serml/support/src/lib.rs | 2 +- lib-serml/transaction-payment/src/lib.rs | 2 +- lib-serml/transaction-payment/src/mock.rs | 2 +- lib-serml/transaction-payment/src/tests.rs | 2 +- lib-serml/transaction-payment/src/weights.rs | 2 +- node/setheum-dev/cli/build.rs | 2 +- node/setheum-dev/cli/src/cli.rs | 2 +- node/setheum-dev/cli/src/command.rs | 4 +- node/setheum-dev/cli/src/lib.rs | 2 +- .../setheum-dev/service/src/chain_spec/mod.rs | 2 +- .../service/src/chain_spec/newrome.rs | 2 +- node/setheum-dev/service/src/client.rs | 2 +- node/setheum-dev/service/src/lib.rs | 2 +- .../src/mock_timestamp_data_provider.rs | 2 +- node/setheum-dev/src/main.rs | 2 +- node/setheum/cli/build.rs | 2 +- node/setheum/cli/src/cli.rs | 2 +- node/setheum/cli/src/command.rs | 4 +- node/setheum/cli/src/lib.rs | 2 +- node/setheum/service/src/chain_spec/mod.rs | 2 +- node/setheum/service/src/chain_spec/neom.rs | 2 +- .../setheum/service/src/chain_spec/newrome.rs | 2 +- .../setheum/service/src/chain_spec/setheum.rs | 2 +- node/setheum/service/src/client.rs | 2 +- node/setheum/service/src/lib.rs | 2 +- .../src/mock_timestamp_data_provider.rs | 2 +- node/setheum/src/main.rs | 2 +- primitives/src/currency.rs | 2 +- primitives/src/evm.rs | 2 +- primitives/src/lib.rs | 2 +- primitives/src/tests.rs | 2 +- rpc/src/lib.rs | 2 +- runtime/common/src/lib.rs | 2 +- runtime/neom/build.rs | 2 +- runtime/neom/src/authority.rs | 2 +- runtime/neom/src/constants.rs | 2 +- runtime/neom/src/lib.rs | 2 +- runtime/neom/src/weights/mod.rs | 2 +- runtime/neom/src/weights/orml_auction.rs | 2 +- runtime/neom/src/weights/orml_authority.rs | 2 +- runtime/neom/src/weights/orml_oracle.rs | 2 +- runtime/neom/src/weights/orml_rewards.rs | 2 +- runtime/neom/src/weights/orml_tokens.rs | 2 +- runtime/neom/src/weights/orml_vesting.rs | 2 +- .../src/weights/setheum_auction_manager.rs | 2 +- .../neom/src/weights/setheum_currencies.rs | 2 +- runtime/neom/src/weights/setheum_dex.rs | 2 +- .../neom/src/weights/setheum_incentives.rs | 2 +- runtime/neom/src/weights/setheum_nft.rs | 2 +- runtime/neom/src/weights/setheum_prices.rs | 2 +- runtime/neom/src/weights/setheum_serp.rs | 2 +- .../src/weights/setheum_settmint_treasury.rs | 2 +- .../weights/setheum_transaction_payment.rs | 2 +- .../neom/src/weights/transaction_payment.rs | 2 +- runtime/newrome/build.rs | 2 +- runtime/newrome/src/authority.rs | 2 +- runtime/newrome/src/benchmarking/auction.rs | 2 +- runtime/newrome/src/benchmarking/authority.rs | 2 +- .../newrome/src/benchmarking/currencies.rs | 2 +- runtime/newrome/src/benchmarking/dex.rs | 2 +- .../newrome/src/benchmarking/incentives.rs | 2 +- runtime/newrome/src/benchmarking/mod.rs | 2 +- runtime/newrome/src/benchmarking/oracle.rs | 2 +- runtime/newrome/src/benchmarking/prices.rs | 2 +- runtime/newrome/src/benchmarking/serp.rs | 2 +- .../src/benchmarking/settmint_treasury.rs | 2 +- runtime/newrome/src/benchmarking/tokens.rs | 2 +- .../src/benchmarking/transaction_payment.rs | 2 +- runtime/newrome/src/benchmarking/utils.rs | 2 +- runtime/newrome/src/benchmarking/vesting.rs | 2 +- runtime/newrome/src/constants.rs | 2 +- runtime/newrome/src/lib.rs | 2 +- runtime/newrome/src/weights/mod.rs | 2 +- .../src/weights/module_transaction_payment.rs | 2 +- runtime/newrome/src/weights/orml_auction.rs | 2 +- runtime/newrome/src/weights/orml_authority.rs | 2 +- runtime/newrome/src/weights/orml_oracle.rs | 2 +- runtime/newrome/src/weights/orml_rewards.rs | 2 +- runtime/newrome/src/weights/orml_tokens.rs | 2 +- runtime/newrome/src/weights/orml_vesting.rs | 2 +- .../src/weights/setheum_auction_manager.rs | 2 +- .../newrome/src/weights/setheum_currencies.rs | 2 +- runtime/newrome/src/weights/setheum_dex.rs | 2 +- .../newrome/src/weights/setheum_incentives.rs | 2 +- runtime/newrome/src/weights/setheum_nft.rs | 2 +- runtime/newrome/src/weights/setheum_prices.rs | 2 +- runtime/newrome/src/weights/setheum_serp.rs | 2 +- .../src/weights/setheum_settmint_treasury.rs | 2 +- runtime/setheum/build.rs | 2 +- runtime/setheum/src/authority.rs | 2 +- runtime/setheum/src/constants.rs | 2 +- runtime/setheum/src/lib.rs | 2 +- runtime/setheum/src/weights/mod.rs | 2 +- runtime/setheum/src/weights/orml_auction.rs | 2 +- runtime/setheum/src/weights/orml_authority.rs | 2 +- runtime/setheum/src/weights/orml_oracle.rs | 2 +- runtime/setheum/src/weights/orml_rewards.rs | 2 +- runtime/setheum/src/weights/orml_tokens.rs | 2 +- runtime/setheum/src/weights/orml_vesting.rs | 2 +- .../src/weights/setheum_auction_manager.rs | 2 +- .../setheum/src/weights/setheum_currencies.rs | 2 +- runtime/setheum/src/weights/setheum_dex.rs | 2 +- .../setheum/src/weights/setheum_incentives.rs | 2 +- runtime/setheum/src/weights/setheum_nft.rs | 2 +- runtime/setheum/src/weights/setheum_prices.rs | 2 +- runtime/setheum/src/weights/setheum_serp.rs | 2 +- .../src/weights/setheum_settmint_treasury.rs | 2 +- .../weights/setheum_transaction_payment.rs | 2 +- templates/module-weight-template.hbs | 2 +- 184 files changed, 944 insertions(+), 196 deletions(-) create mode 100644 lib-serml/evm-bridge/Cargo.toml create mode 100644 lib-serml/evm-bridge/src/lib.rs create mode 100644 lib-serml/evm-bridge/src/mock.rs create mode 100644 lib-serml/evm-bridge/src/tests.rs diff --git a/HEADER-GPL3 b/HEADER-GPL3 index 0e2ab8f90..72cbaa426 100644 --- a/HEADER-GPL3 +++ b/HEADER-GPL3 @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/inspect/src/cli.rs b/inspect/src/cli.rs index 9e730ed1f..a3ed9492c 100644 --- a/inspect/src/cli.rs +++ b/inspect/src/cli.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/inspect/src/command.rs b/inspect/src/command.rs index bcd4949f1..69d0aa22f 100644 --- a/inspect/src/command.rs +++ b/inspect/src/command.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/inspect/src/lib.rs b/inspect/src/lib.rs index 228100367..77a38d2ef 100644 --- a/inspect/src/lib.rs +++ b/inspect/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/chainbridge/src/lib.rs b/lib-serml/chainbridge/src/lib.rs index fd1713d53..479d1a891 100644 --- a/lib-serml/chainbridge/src/lib.rs +++ b/lib-serml/chainbridge/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/chainbridge/src/mock.rs b/lib-serml/chainbridge/src/mock.rs index 5306d7f81..a22ef9a97 100644 --- a/lib-serml/chainbridge/src/mock.rs +++ b/lib-serml/chainbridge/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/chainbridge/src/tests.rs b/lib-serml/chainbridge/src/tests.rs index d598c6deb..da63c70f7 100644 --- a/lib-serml/chainbridge/src/tests.rs +++ b/lib-serml/chainbridge/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/chainbridge/src/weights.rs b/lib-serml/chainbridge/src/weights.rs index de796b1c6..da01d0ee0 100644 --- a/lib-serml/chainbridge/src/weights.rs +++ b/lib-serml/chainbridge/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/currencies/src/lib.rs b/lib-serml/currencies/src/lib.rs index 15d75edc6..dbf569257 100644 --- a/lib-serml/currencies/src/lib.rs +++ b/lib-serml/currencies/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/currencies/src/mock.rs b/lib-serml/currencies/src/mock.rs index 3a8b7c609..a597e8d2f 100644 --- a/lib-serml/currencies/src/mock.rs +++ b/lib-serml/currencies/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/currencies/src/tests.rs b/lib-serml/currencies/src/tests.rs index 0300473c4..5868510f4 100644 --- a/lib-serml/currencies/src/tests.rs +++ b/lib-serml/currencies/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/currencies/src/weights.rs b/lib-serml/currencies/src/weights.rs index 266aeeef5..9d338d87e 100644 --- a/lib-serml/currencies/src/weights.rs +++ b/lib-serml/currencies/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/dex/src/lib.rs b/lib-serml/dex/src/lib.rs index ec89eb096..b15d850d1 100644 --- a/lib-serml/dex/src/lib.rs +++ b/lib-serml/dex/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/dex/src/mock.rs b/lib-serml/dex/src/mock.rs index a9bd36906..96a2e29f9 100644 --- a/lib-serml/dex/src/mock.rs +++ b/lib-serml/dex/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/dex/src/tests.rs b/lib-serml/dex/src/tests.rs index 3dc0631e6..7060e7a28 100644 --- a/lib-serml/dex/src/tests.rs +++ b/lib-serml/dex/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/dex/src/weights.rs b/lib-serml/dex/src/weights.rs index eef0a83e8..f2cfd8680 100644 --- a/lib-serml/dex/src/weights.rs +++ b/lib-serml/dex/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm-accounts/src/lib.rs b/lib-serml/evm-accounts/src/lib.rs index 445cc5589..77c6aa158 100644 --- a/lib-serml/evm-accounts/src/lib.rs +++ b/lib-serml/evm-accounts/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm-accounts/src/mock.rs b/lib-serml/evm-accounts/src/mock.rs index a4846a203..2a58eeeda 100644 --- a/lib-serml/evm-accounts/src/mock.rs +++ b/lib-serml/evm-accounts/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm-accounts/src/tests.rs b/lib-serml/evm-accounts/src/tests.rs index 1bc11ca10..890288764 100644 --- a/lib-serml/evm-accounts/src/tests.rs +++ b/lib-serml/evm-accounts/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm-accounts/src/weights.rs b/lib-serml/evm-accounts/src/weights.rs index 3667776ac..d229c02fc 100644 --- a/lib-serml/evm-accounts/src/weights.rs +++ b/lib-serml/evm-accounts/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ // along with this program. If not, see . -//! Autogenerated weights for module_evm_accounts +//! Autogenerated weights for setheum_evm_accounts //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-02-26, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] @@ -29,7 +29,7 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=module_evm_accounts +// --pallet=setheum_evm_accounts // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -46,13 +46,13 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for module_evm_accounts. +/// Weight functions needed for setheum_evm_accounts. pub trait WeightInfo { fn claim_account() -> Weight; fn claim_default_account() -> Weight; } -/// Weights for module_evm_accounts using the Setheum node and recommended hardware. +/// Weights for setheum_evm_accounts using the Setheum node and recommended hardware. pub struct SetheumWeight(PhantomData); impl WeightInfo for SetheumWeight { fn claim_account() -> Weight { diff --git a/lib-serml/evm-bridge/Cargo.toml b/lib-serml/evm-bridge/Cargo.toml new file mode 100644 index 000000000..528e0967a --- /dev/null +++ b/lib-serml/evm-bridge/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "setheum-evm-bridge" +version = "1.0.0" +authors = ["Setheum Labs"] +edition = "2018" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +serde = { version = "1.0.124", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +primitive-types = { version = "0.9.0", default-features = false, features = ["rlp", "byteorder"] } +impl-trait-for-tuples = "0.2.1" +ethereum-types = { version = "0.11.0", default-features = false } + +primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } +support = { package = "setheum-support", path = "../support", default-features = false } +setheum-evm = { path = "../evm", default-features = false } + +[dev-dependencies] +sha3 = { version = "0.9.1" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-core/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "sp-io/std", + "sp-std/std", + "ethereum-types/std", + "primitives/std", + "primitive-types/std", + "support/std", + "setheum-evm/std", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/lib-serml/evm-bridge/src/lib.rs b/lib-serml/evm-bridge/src/lib.rs new file mode 100644 index 000000000..3d36f5f93 --- /dev/null +++ b/lib-serml/evm-bridge/src/lib.rs @@ -0,0 +1,234 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] + +use ethereum_types::BigEndianHash; +use frame_support::{ + dispatch::{DispatchError, DispatchResult}, + pallet_prelude::*, +}; +use setheum_evm::{ExitReason, ExitSucceed}; +use primitive_types::H256; +use sp_core::{H160, U256}; +use sp_runtime::SaturatedConversion; +use sp_std::vec::Vec; +use support::{EVMBridge as EVMBridgeTrait, ExecutionMode, InvokeContext, EVM}; + +type AccountIdOf = ::AccountId; +type BalanceOf = <::EVM as EVM>>::Balance; + +pub const METHOD_NAME: u32 = 0x06fdde03; +pub const METHOD_SYMBOL: u32 = 0x95d89b41; +pub const METHOD_DECIMALS: u32 = 0x313ce567; +pub const METHOD_TOTAL_SUPPLY: u32 = 0x18160ddd; +pub const METHOD_BALANCE_OF: u32 = 0x70a08231; +pub const METHOD_TRANSFER: u32 = 0xa9059cbb; + +mod mock; +mod tests; + +pub use module::*; + +#[frame_support::pallet] +pub mod module { + use super::*; + + /// EvmBridge module trait + #[pallet::config] + pub trait Config: frame_system::Config { + type EVM: EVM>; + } + + #[pallet::error] + pub enum Error { + /// Execution failed + ExecutionFail, + /// Execution reverted + ExecutionRevert, + /// Execution fatal + ExecutionFatal, + /// Execution error + ExecutionError, + /// Invalid return value + InvalidReturnValue, + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +impl EVMBridgeTrait, BalanceOf> for Pallet { + // Calls the name method on an ERC20 contract using the given context + // and returns the token name. + fn name(context: InvokeContext) -> Result, DispatchError> { + // ERC20.name method hash + let input = METHOD_NAME.to_be_bytes().to_vec(); + + let info = T::EVM::execute(context, input, Default::default(), 2_100_000, 0, ExecutionMode::View)?; + + Self::handle_exit_reason(info.exit_reason)?; + Self::decode_string(info.output.as_slice().to_vec()) + } + + // Calls the symbol method on an ERC20 contract using the given context + // and returns the token symbol. + fn symbol(context: InvokeContext) -> Result, DispatchError> { + // ERC20.symbol method hash + let input = METHOD_SYMBOL.to_be_bytes().to_vec(); + + let info = T::EVM::execute(context, input, Default::default(), 2_100_000, 0, ExecutionMode::View)?; + + Self::handle_exit_reason(info.exit_reason)?; + Self::decode_string(info.output.as_slice().to_vec()) + } + + // Calls the decimals method on an ERC20 contract using the given context + // and returns the decimals. + fn decimals(context: InvokeContext) -> Result { + // ERC20.decimals method hash + let input = METHOD_DECIMALS.to_be_bytes().to_vec(); + + let info = T::EVM::execute(context, input, Default::default(), 2_100_000, 0, ExecutionMode::View)?; + + Self::handle_exit_reason(info.exit_reason)?; + + ensure!(info.output.len() == 32, Error::::InvalidReturnValue); + let value = U256::from(info.output.as_slice()).saturated_into::(); + Ok(value) + } + + // Calls the totalSupply method on an ERC20 contract using the given context + // and returns the total supply. + fn total_supply(context: InvokeContext) -> Result, DispatchError> { + // ERC20.totalSupply method hash + let input = METHOD_TOTAL_SUPPLY.to_be_bytes().to_vec(); + + let info = T::EVM::execute(context, input, Default::default(), 2_100_000, 0, ExecutionMode::View)?; + + Self::handle_exit_reason(info.exit_reason)?; + + ensure!(info.output.len() == 32, Error::::InvalidReturnValue); + let value = U256::from(info.output.as_slice()).saturated_into::(); + Ok(value.saturated_into::>()) + } + + // Calls the balanceOf method on an ERC20 contract using the given context + // and returns the address's balance. + fn balance_of(context: InvokeContext, address: H160) -> Result, DispatchError> { + // ERC20.balanceOf method hash + let mut input = METHOD_BALANCE_OF.to_be_bytes().to_vec(); + // append address + input.extend_from_slice(H256::from(address).as_bytes()); + + let info = T::EVM::execute(context, input, Default::default(), 2_100_000, 0, ExecutionMode::View)?; + + Self::handle_exit_reason(info.exit_reason)?; + + Ok(U256::from(info.output.as_slice()) + .saturated_into::() + .saturated_into::>()) + } + + // Calls the transfer method on an ERC20 contract using the given context. + fn transfer(context: InvokeContext, to: H160, value: BalanceOf) -> DispatchResult { + // ERC20.transfer method hash + let mut input = METHOD_TRANSFER.to_be_bytes().to_vec(); + // append receiver address + input.extend_from_slice(H256::from(to).as_bytes()); + // append amount to be transferred + input.extend_from_slice(H256::from_uint(&U256::from(value.saturated_into::())).as_bytes()); + + let storage_limit = if context.origin == Default::default() { 0 } else { 1_000 }; + + let info = T::EVM::execute( + context, + input, + Default::default(), + 2_100_000, + storage_limit, + ExecutionMode::Execute, + )?; + + Self::handle_exit_reason(info.exit_reason)?; + + // return value is true. + let mut bytes = [0u8; 32]; + U256::from(1).to_big_endian(&mut bytes); + + // Check return value to make sure not calling on empty contracts. + ensure!( + !info.output.is_empty() && info.output == bytes, + Error::::InvalidReturnValue + ); + Ok(()) + } + + fn get_origin() -> Option> { + T::EVM::get_origin() + } + + fn set_origin(origin: AccountIdOf) { + T::EVM::set_origin(origin); + } +} + +impl Pallet { + fn handle_exit_reason(exit_reason: ExitReason) -> Result<(), DispatchError> { + match exit_reason { + ExitReason::Succeed(ExitSucceed::Returned) => Ok(()), + ExitReason::Succeed(ExitSucceed::Stopped) => Ok(()), + ExitReason::Succeed(_) => Err(Error::::ExecutionFail.into()), + ExitReason::Revert(_) => Err(Error::::ExecutionRevert.into()), + ExitReason::Fatal(_) => Err(Error::::ExecutionFatal.into()), + ExitReason::Error(_) => Err(Error::::ExecutionError.into()), + } + } + + fn decode_string(output: Vec) -> Result, DispatchError> { + // output is 32-byte aligned and consists of 3 parts: + // - part 1: 32 byte, the offset of its description is passed in the position of + // the corresponding parameter or return value. + // - part 2: 32 byte, string length + // - part 3: string data + ensure!( + output.len() >= 64 && output.len() % 32 == 0, + Error::::InvalidReturnValue + ); + + let offset = U256::from_big_endian(&output[0..32]); + let length = U256::from_big_endian(&output[offset.as_usize()..offset.as_usize() + 32]); + ensure!( + // output is 32-byte aligned. ensure total_length >= offset + string length + string data length. + output.len() >= offset.as_usize() + 32 + length.as_usize(), + Error::::InvalidReturnValue + ); + + let mut data = Vec::new(); + data.extend_from_slice(&output[offset.as_usize() + 32..offset.as_usize() + 32 + length.as_usize()]); + + Ok(data.to_vec()) + } +} diff --git a/lib-serml/evm-bridge/src/mock.rs b/lib-serml/evm-bridge/src/mock.rs new file mode 100644 index 000000000..d04a0669d --- /dev/null +++ b/lib-serml/evm-bridge/src/mock.rs @@ -0,0 +1,239 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Mocks for the evm-bridge module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_ok, construct_runtime, ord_parameter_types, parameter_types}; +use frame_system::EnsureSignedBy; +use primitives::evm::EvmAddress; +use sha3::{Digest, Keccak256}; +use sp_core::{bytes::from_hex, crypto::AccountId32, H256}; +use sp_runtime::{testing::Header, traits::IdentityLookup}; +use sp_std::{convert::TryInto, str::FromStr}; +use support::{mocks::MockAddressMapping, AddressMapping}; + +pub type AccountId = AccountId32; +pub type BlockNumber = u64; +pub type Balance = u128; + +mod evm_bridge { + pub use super::super::*; +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 1000; +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + pub const NewContractExtraBytes: u32 = 1; + pub NetworkContractSource: EvmAddress = alice_evm_addr(); +} + +ord_parameter_types! { + pub const CouncilAccount: AccountId32 = AccountId32::from([1u8; 32]); + pub const TreasuryAccount: AccountId32 = AccountId32::from([2u8; 32]); + pub const NetworkContractAccount: AccountId32 = AccountId32::from([0u8; 32]); + pub const StorageDepositPerByte: u128 = 10; + pub const MaxCodeSize: u32 = 60 * 1024; + pub const DeveloperDeposit: u64 = 1000; + pub const DeploymentFee: u64 = 200; +} + +impl setheum_evm::Config for Runtime { + type AddressMapping = MockAddressMapping; + type Currency = Balances; + type TransferAll = (); + type NewContractExtraBytes = NewContractExtraBytes; + type StorageDepositPerByte = StorageDepositPerByte; + type MaxCodeSize = MaxCodeSize; + + type Event = Event; + type Precompiles = (); + type ChainId = (); + type GasToWeight = (); + type ChargeTransactionPayment = (); + type NetworkContractOrigin = EnsureSignedBy; + type NetworkContractSource = NetworkContractSource; + + type DeveloperDeposit = DeveloperDeposit; + type DeploymentFee = DeploymentFee; + type TreasuryAccount = TreasuryAccount; + type FreeDeploymentOrigin = EnsureSignedBy; + + type WeightInfo = (); +} + +impl Config for Runtime { + type EVM = EVM; +} +pub type EvmBridgeModule = Pallet; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + EVMBridge: evm_bridge::{Pallet}, + EVM: setheum_evm::{Pallet, Config, Call, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + } +); + +pub struct ExtBuilder { + endowed_accounts: Vec<(AccountId, Balance)>, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + endowed_accounts: vec![], + } + } +} + +pub fn erc20_address() -> EvmAddress { + EvmAddress::from_str("0000000000000000000000000000000002000000").unwrap() +} + +pub fn alice() -> AccountId { + ::AddressMapping::get_account_id(&alice_evm_addr()) +} + +pub fn alice_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000001").unwrap() +} + +pub fn bob() -> AccountId { + ::AddressMapping::get_account_id(&bob_evm_addr()) +} + +pub fn bob_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000002").unwrap() +} + +pub fn deploy_contracts() { + let code = from_hex(include!("./erc20_demo_contract")).unwrap(); + assert_ok!(EVM::create_network_contract( + Origin::signed(NetworkContractAccount::get()), + code, + 0, + 2100_000, + 10000 + )); + + let event = Event::setheum_evm(setheum_evm::Event::Created(erc20_address())); + assert_eq!(System::events().iter().last().unwrap().event, event); + + assert_ok!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), erc20_address())); +} + +pub fn get_function_selector(s: &str) -> [u8; 4] { + // create a SHA3-256 object + let mut hasher = Keccak256::new(); + // write input message + hasher.update(s); + // read hash digest + let result = hasher.finalize(); + result[..4].try_into().unwrap() +} + +impl ExtBuilder { + pub fn balances(mut self, endowed_accounts: Vec<(AccountId, Balance)>) -> Self { + self.endowed_accounts = endowed_accounts; + self + } + + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: self.endowed_accounts.clone().into_iter().collect::>(), + } + .assimilate_storage(&mut t) + .unwrap(); + + setheum_evm::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} diff --git a/lib-serml/evm-bridge/src/tests.rs b/lib-serml/evm-bridge/src/tests.rs new file mode 100644 index 000000000..c38ecf74c --- /dev/null +++ b/lib-serml/evm-bridge/src/tests.rs @@ -0,0 +1,226 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Unit tests for the evm-bridge module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_err, assert_ok}; +use mock::{ + alice, alice_evm_addr, bob, bob_evm_addr, deploy_contracts, erc20_address, get_function_selector, EvmBridgeModule, + ExtBuilder, Runtime, +}; + +#[test] +fn method_hash_works() { + assert_eq!(u32::from_be_bytes(get_function_selector("name()")), METHOD_NAME); + + assert_eq!(u32::from_be_bytes(get_function_selector("symbol()")), METHOD_SYMBOL); + + assert_eq!(u32::from_be_bytes(get_function_selector("decimals()")), METHOD_DECIMALS); + + assert_eq!( + u32::from_be_bytes(get_function_selector("totalSupply()")), + METHOD_TOTAL_SUPPLY + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("balanceOf(address)")), + METHOD_BALANCE_OF + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("transfer(address,uint256)")), + METHOD_TRANSFER + ); +} + +#[test] +fn should_read_name() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!( + >::name(InvokeContext { + contract: erc20_address(), + sender: Default::default(), + origin: Default::default(), + }), + Ok( + b"long string name, long string name, long string name, long string name, long string name" + .to_vec() + ) + ); + }); +} + +#[test] +fn should_read_symbol() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!( + EvmBridgeModule::symbol(InvokeContext { + contract: erc20_address(), + sender: Default::default(), + origin: Default::default(), + }), + Ok(b"TestToken".to_vec()) + ); + }); +} + +#[test] +fn should_read_decimals() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!( + EvmBridgeModule::decimals(InvokeContext { + contract: erc20_address(), + sender: Default::default(), + origin: Default::default(), + }), + Ok(17) + ); + }); +} + +#[test] +fn should_read_total_supply() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!( + EvmBridgeModule::total_supply(InvokeContext { + contract: erc20_address(), + sender: Default::default(), + origin: Default::default(), + }), + Ok(10000) + ); + }); +} + +#[test] +fn should_read_balance_of() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + let context = InvokeContext { + contract: erc20_address(), + sender: Default::default(), + origin: Default::default(), + }; + + assert_eq!(EvmBridgeModule::balance_of(context, bob_evm_addr()), Ok(0)); + + assert_eq!(EvmBridgeModule::balance_of(context, alice_evm_addr()), Ok(10000)); + + assert_eq!(EvmBridgeModule::balance_of(context, bob_evm_addr()), Ok(0)); + }); +} + +#[test] +fn should_transfer() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000), (bob(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_err!( + EvmBridgeModule::transfer( + InvokeContext { + contract: erc20_address(), + sender: bob_evm_addr(), + origin: bob_evm_addr(), + }, + alice_evm_addr(), + 10 + ), + Error::::ExecutionRevert + ); + + assert_ok!(EvmBridgeModule::transfer( + InvokeContext { + contract: erc20_address(), + sender: alice_evm_addr(), + origin: alice_evm_addr(), + }, + bob_evm_addr(), + 100 + )); + assert_eq!( + EvmBridgeModule::balance_of( + InvokeContext { + contract: erc20_address(), + sender: alice_evm_addr(), + origin: alice_evm_addr(), + }, + bob_evm_addr() + ), + Ok(100) + ); + + assert_ok!(EvmBridgeModule::transfer( + InvokeContext { + contract: erc20_address(), + sender: bob_evm_addr(), + origin: bob_evm_addr(), + }, + alice_evm_addr(), + 10 + )); + + assert_eq!( + EvmBridgeModule::balance_of( + InvokeContext { + contract: erc20_address(), + sender: alice_evm_addr(), + origin: bob_evm_addr(), + }, + bob_evm_addr() + ), + Ok(90) + ); + + assert_err!( + EvmBridgeModule::transfer( + InvokeContext { + contract: erc20_address(), + sender: bob_evm_addr(), + origin: bob_evm_addr(), + }, + alice_evm_addr(), + 100 + ), + Error::::ExecutionRevert + ); + }); +} diff --git a/lib-serml/evm/rpc/runtime_api/src/lib.rs b/lib-serml/evm/rpc/runtime_api/src/lib.rs index 6b13c0890..be3433758 100644 --- a/lib-serml/evm/rpc/runtime_api/src/lib.rs +++ b/lib-serml/evm/rpc/runtime_api/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/rpc/src/call_request.rs b/lib-serml/evm/rpc/src/call_request.rs index d9e20a326..255276583 100644 --- a/lib-serml/evm/rpc/src/call_request.rs +++ b/lib-serml/evm/rpc/src/call_request.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/rpc/src/evm_api.rs b/lib-serml/evm/rpc/src/evm_api.rs index a96a4a0f6..0dc5fe725 100644 --- a/lib-serml/evm/rpc/src/evm_api.rs +++ b/lib-serml/evm/rpc/src/evm_api.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/rpc/src/lib.rs b/lib-serml/evm/rpc/src/lib.rs index 97bf7b5bb..d141ce877 100644 --- a/lib-serml/evm/rpc/src/lib.rs +++ b/lib-serml/evm/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -38,8 +38,8 @@ use std::convert::{TryFrom, TryInto}; use std::{marker::PhantomData, sync::Arc}; use call_request::{CallRequest, EstimateResourcesResponse}; -pub use module_evm::{ExitError, ExitReason}; -pub use module_evm_rpc_runtime_api::EVMRuntimeRPCApi; +pub use setheum_evm::{ExitError, ExitReason}; +pub use setheum_evm_rpc_runtime_api::EVMRuntimeRPCApi; pub use crate::evm_api::{EVMApi as EVMApiT, EVMApiServer}; diff --git a/lib-serml/evm/src/lib.rs b/lib-serml/evm/src/lib.rs index 6a95bf7f0..58056a419 100644 --- a/lib-serml/evm/src/lib.rs +++ b/lib-serml/evm/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/src/mock.rs b/lib-serml/evm/src/mock.rs index fb9b94b30..1bef3af54 100644 --- a/lib-serml/evm/src/mock.rs +++ b/lib-serml/evm/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/src/precompiles.rs b/lib-serml/evm/src/precompiles.rs index b290b8596..a6a4dd913 100644 --- a/lib-serml/evm/src/precompiles.rs +++ b/lib-serml/evm/src/precompiles.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/src/runner/handler.rs b/lib-serml/evm/src/runner/handler.rs index b5653da70..f1df8a276 100644 --- a/lib-serml/evm/src/runner/handler.rs +++ b/lib-serml/evm/src/runner/handler.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/src/runner/mod.rs b/lib-serml/evm/src/runner/mod.rs index 77136b634..0acc0011e 100644 --- a/lib-serml/evm/src/runner/mod.rs +++ b/lib-serml/evm/src/runner/mod.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/src/runner/storage_meter.rs b/lib-serml/evm/src/runner/storage_meter.rs index 9e42bbc61..591ba72eb 100644 --- a/lib-serml/evm/src/runner/storage_meter.rs +++ b/lib-serml/evm/src/runner/storage_meter.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/src/tests.rs b/lib-serml/evm/src/tests.rs index c39229341..b8ab24db2 100644 --- a/lib-serml/evm/src/tests.rs +++ b/lib-serml/evm/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm/src/weights.rs b/lib-serml/evm/src/weights.rs index ac5025503..b48e63e2f 100644 --- a/lib-serml/evm/src/weights.rs +++ b/lib-serml/evm/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ // along with this program. If not, see . -//! Autogenerated weights for module_evm +//! Autogenerated weights for setheum_evm //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-02-26, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] @@ -29,7 +29,7 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=module_evm +// --pallet=setheum_evm // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -46,7 +46,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for module_evm. +/// Weight functions needed for setheum_evm. pub trait WeightInfo { fn transfer_maintainer() -> Weight; fn deploy() -> Weight; @@ -57,7 +57,7 @@ pub trait WeightInfo { fn selfdestruct() -> Weight; } -/// Weights for module_evm using the Setheum node and recommended hardware. +/// Weights for setheum_evm using the Setheum node and recommended hardware. pub struct SetheumWeight(PhantomData); impl WeightInfo for SetheumWeight { fn transfer_maintainer() -> Weight { diff --git a/lib-serml/example/src/lib.rs b/lib-serml/example/src/lib.rs index 003c74daa..827d116e5 100644 --- a/lib-serml/example/src/lib.rs +++ b/lib-serml/example/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/example/src/mock.rs b/lib-serml/example/src/mock.rs index 7c509c249..834e64de8 100644 --- a/lib-serml/example/src/mock.rs +++ b/lib-serml/example/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/example/src/tests.rs b/lib-serml/example/src/tests.rs index aa86ecbec..711ddd9d9 100644 --- a/lib-serml/example/src/tests.rs +++ b/lib-serml/example/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/incentives/src/lib.rs b/lib-serml/incentives/src/lib.rs index 69af165cc..dfb099bf4 100644 --- a/lib-serml/incentives/src/lib.rs +++ b/lib-serml/incentives/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/incentives/src/mock.rs b/lib-serml/incentives/src/mock.rs index 80906d3b9..5ed5ab345 100644 --- a/lib-serml/incentives/src/mock.rs +++ b/lib-serml/incentives/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/incentives/src/tests.rs b/lib-serml/incentives/src/tests.rs index a77e6e3e2..839a73afb 100644 --- a/lib-serml/incentives/src/tests.rs +++ b/lib-serml/incentives/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/incentives/src/weights.rs b/lib-serml/incentives/src/weights.rs index 033170583..33cb8edba 100644 --- a/lib-serml/incentives/src/weights.rs +++ b/lib-serml/incentives/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/nft/src/benchmarking.rs b/lib-serml/nft/src/benchmarking.rs index a97418307..11372da7b 100644 --- a/lib-serml/nft/src/benchmarking.rs +++ b/lib-serml/nft/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/nft/src/lib.rs b/lib-serml/nft/src/lib.rs index efa8020a8..d5ab6f0a4 100644 --- a/lib-serml/nft/src/lib.rs +++ b/lib-serml/nft/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/nft/src/mock.rs b/lib-serml/nft/src/mock.rs index 5f74283e1..d89b8cbbe 100644 --- a/lib-serml/nft/src/mock.rs +++ b/lib-serml/nft/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/nft/src/tests.rs b/lib-serml/nft/src/tests.rs index 79f986f07..c1457d8ea 100644 --- a/lib-serml/nft/src/tests.rs +++ b/lib-serml/nft/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/nft/src/weights.rs b/lib-serml/nft/src/weights.rs index 16297e520..8c7a9a899 100644 --- a/lib-serml/nft/src/weights.rs +++ b/lib-serml/nft/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index dbc586d52..2d9bca3d0 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index 48ccbb6ee..d9b69142a 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/prices/src/tests.rs b/lib-serml/prices/src/tests.rs index 40a3630e8..f6ef011c1 100644 --- a/lib-serml/prices/src/tests.rs +++ b/lib-serml/prices/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/prices/src/weights.rs b/lib-serml/prices/src/weights.rs index e7b8cf138..51ea19468 100644 --- a/lib-serml/prices/src/weights.rs +++ b/lib-serml/prices/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/renvm-bridge/Cargo.toml b/lib-serml/renvm-bridge/Cargo.toml index e16aee6bb..fb4c92247 100644 --- a/lib-serml/renvm-bridge/Cargo.toml +++ b/lib-serml/renvm-bridge/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "renvm-bridge" +name = "setheum-renvm-bridge" version = "1.0.0" authors = ["Setheum Labs"] edition = "2018" diff --git a/lib-serml/renvm-bridge/src/lib.rs b/lib-serml/renvm-bridge/src/lib.rs index 5a6120933..f9dc8724d 100644 --- a/lib-serml/renvm-bridge/src/lib.rs +++ b/lib-serml/renvm-bridge/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -341,7 +341,7 @@ impl frame_support::unsigned::ValidateUnsigned for Pallet { return InvalidTransaction::BadProof.into(); } - ValidTransaction::with_tag_prefix("renvm-bridge") + ValidTransaction::with_tag_prefix("setheum-renvm-bridge") .priority(T::UnsignedPriority::get()) .and_provides(sig) .longevity(64_u64) @@ -359,7 +359,7 @@ impl frame_support::unsigned::ValidateUnsigned for Pallet { return InvalidTransaction::BadProof.into(); } - ValidTransaction::with_tag_prefix("renvm-bridge") + ValidTransaction::with_tag_prefix("setheum-renvm-bridge") .priority(T::UnsignedPriority::get()) .and_provides(sig) .longevity(64_u64) diff --git a/lib-serml/renvm-bridge/src/mock.rs b/lib-serml/renvm-bridge/src/mock.rs index 61bc305a3..186f41525 100644 --- a/lib-serml/renvm-bridge/src/mock.rs +++ b/lib-serml/renvm-bridge/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Mocks for the renvm-bridge module. +//! Mocks for the setheum-renvm-bridge module. #![cfg(test)] diff --git a/lib-serml/renvm-bridge/src/tests.rs b/lib-serml/renvm-bridge/src/tests.rs index 3b72e2ef1..e3cf6063a 100644 --- a/lib-serml/renvm-bridge/src/tests.rs +++ b/lib-serml/renvm-bridge/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Unit tests for the renvm-bridge module. +//! Unit tests for the setheum-renvm-bridge module. #![cfg(test)] diff --git a/lib-serml/serp-auction/src/lib.rs b/lib-serml/serp-auction/src/lib.rs index b5ccb5da1..fc81fd041 100644 --- a/lib-serml/serp-auction/src/lib.rs +++ b/lib-serml/serp-auction/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index 34ec593db..dafd93419 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/serp-auction/src/tests.rs b/lib-serml/serp-auction/src/tests.rs index 4c02a825d..01eb4aa09 100644 --- a/lib-serml/serp-auction/src/tests.rs +++ b/lib-serml/serp-auction/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/serp-auction/src/weights.rs b/lib-serml/serp-auction/src/weights.rs index e28a1e2b7..6b8e9b230 100644 --- a/lib-serml/serp-auction/src/weights.rs +++ b/lib-serml/serp-auction/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index 8be238028..a883076c3 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index c9b3325f1..c2bc2b12e 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/serp-treasury/src/tests.rs b/lib-serml/serp-treasury/src/tests.rs index 3b3e4abcf..1abf9f694 100644 --- a/lib-serml/serp-treasury/src/tests.rs +++ b/lib-serml/serp-treasury/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/serp-treasury/src/weights.rs b/lib-serml/serp-treasury/src/weights.rs index ba7761fcb..cbb281d8b 100644 --- a/lib-serml/serp-treasury/src/weights.rs +++ b/lib-serml/serp-treasury/src/weights.rs @@ -1,7 +1,7 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/setters-manager/src/lib.rs b/lib-serml/setters-manager/src/lib.rs index 4514a434a..351eaa234 100644 --- a/lib-serml/setters-manager/src/lib.rs +++ b/lib-serml/setters-manager/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index 8334c0610..dcaf22627 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/setters-manager/src/tests.rs b/lib-serml/setters-manager/src/tests.rs index 85b78fe51..6f5b94f3c 100644 --- a/lib-serml/setters-manager/src/tests.rs +++ b/lib-serml/setters-manager/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settmint-engine/src/lib.rs b/lib-serml/settmint-engine/src/lib.rs index e0226a484..6192d2a31 100644 --- a/lib-serml/settmint-engine/src/lib.rs +++ b/lib-serml/settmint-engine/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index 3a1c67000..8f67802c5 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settmint-engine/src/standard_exchange_rate_convertor.rs b/lib-serml/settmint-engine/src/standard_exchange_rate_convertor.rs index 19adc3c3a..7ce664d11 100644 --- a/lib-serml/settmint-engine/src/standard_exchange_rate_convertor.rs +++ b/lib-serml/settmint-engine/src/standard_exchange_rate_convertor.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settmint-engine/src/tests.rs b/lib-serml/settmint-engine/src/tests.rs index af0a9def7..f6a873f4a 100644 --- a/lib-serml/settmint-engine/src/tests.rs +++ b/lib-serml/settmint-engine/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settway/src/lib.rs b/lib-serml/settway/src/lib.rs index 2934adba2..88f43e052 100644 --- a/lib-serml/settway/src/lib.rs +++ b/lib-serml/settway/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index c075d05c3..3b00e01fd 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settway/src/tests.rs b/lib-serml/settway/src/tests.rs index 2325b99cf..80e2e5597 100644 --- a/lib-serml/settway/src/tests.rs +++ b/lib-serml/settway/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/settway/src/weights.rs b/lib-serml/settway/src/weights.rs index 41dd5b5a6..3364fd067 100644 --- a/lib-serml/settway/src/weights.rs +++ b/lib-serml/settway/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index fe9165971..51ca67653 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/transaction-payment/src/lib.rs b/lib-serml/transaction-payment/src/lib.rs index 4d80542e1..655ebbb51 100644 --- a/lib-serml/transaction-payment/src/lib.rs +++ b/lib-serml/transaction-payment/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/transaction-payment/src/mock.rs b/lib-serml/transaction-payment/src/mock.rs index 06223bbef..a7c967ffc 100644 --- a/lib-serml/transaction-payment/src/mock.rs +++ b/lib-serml/transaction-payment/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/transaction-payment/src/tests.rs b/lib-serml/transaction-payment/src/tests.rs index c94cf42c9..3f165308b 100644 --- a/lib-serml/transaction-payment/src/tests.rs +++ b/lib-serml/transaction-payment/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/transaction-payment/src/weights.rs b/lib-serml/transaction-payment/src/weights.rs index a0c4a3f8f..0bbf8942c 100644 --- a/lib-serml/transaction-payment/src/weights.rs +++ b/lib-serml/transaction-payment/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/cli/build.rs b/node/setheum-dev/cli/build.rs index e4db42b34..a92897cef 100644 --- a/node/setheum-dev/cli/build.rs +++ b/node/setheum-dev/cli/build.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/cli/src/cli.rs b/node/setheum-dev/cli/src/cli.rs index 0e0534e0b..2cc83faaf 100644 --- a/node/setheum-dev/cli/src/cli.rs +++ b/node/setheum-dev/cli/src/cli.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/cli/src/command.rs b/node/setheum-dev/cli/src/command.rs index 1507ff059..53b68ebd1 100644 --- a/node/setheum-dev/cli/src/command.rs +++ b/node/setheum-dev/cli/src/command.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -42,7 +42,7 @@ impl SubstrateCli for Cli { } fn support_url() -> String { - "https://github.com/SetheumNetwork/Setheum/issues".into() + "https://github.com/Setheum-LabsSetheum/issues".into() } fn copyright_start_year() -> i32 { diff --git a/node/setheum-dev/cli/src/lib.rs b/node/setheum-dev/cli/src/lib.rs index 141fd7555..63b12a27c 100644 --- a/node/setheum-dev/cli/src/lib.rs +++ b/node/setheum-dev/cli/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/service/src/chain_spec/mod.rs b/node/setheum-dev/service/src/chain_spec/mod.rs index 731901ec4..99e8ce105 100644 --- a/node/setheum-dev/service/src/chain_spec/mod.rs +++ b/node/setheum-dev/service/src/chain_spec/mod.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/service/src/chain_spec/newrome.rs b/node/setheum-dev/service/src/chain_spec/newrome.rs index 20dcf4ed3..819a6c123 100644 --- a/node/setheum-dev/service/src/chain_spec/newrome.rs +++ b/node/setheum-dev/service/src/chain_spec/newrome.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/service/src/client.rs b/node/setheum-dev/service/src/client.rs index 73a48212f..6ef7fadbd 100644 --- a/node/setheum-dev/service/src/client.rs +++ b/node/setheum-dev/service/src/client.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/service/src/lib.rs b/node/setheum-dev/service/src/lib.rs index 68678b057..d4fe6d5cc 100644 --- a/node/setheum-dev/service/src/lib.rs +++ b/node/setheum-dev/service/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/service/src/mock_timestamp_data_provider.rs b/node/setheum-dev/service/src/mock_timestamp_data_provider.rs index a37058089..ee1a44a0b 100644 --- a/node/setheum-dev/service/src/mock_timestamp_data_provider.rs +++ b/node/setheum-dev/service/src/mock_timestamp_data_provider.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum-dev/src/main.rs b/node/setheum-dev/src/main.rs index df03771ce..14cd115b9 100644 --- a/node/setheum-dev/src/main.rs +++ b/node/setheum-dev/src/main.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/cli/build.rs b/node/setheum/cli/build.rs index e4db42b34..a92897cef 100644 --- a/node/setheum/cli/build.rs +++ b/node/setheum/cli/build.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/cli/src/cli.rs b/node/setheum/cli/src/cli.rs index f4105d2aa..c0d022291 100644 --- a/node/setheum/cli/src/cli.rs +++ b/node/setheum/cli/src/cli.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/cli/src/command.rs b/node/setheum/cli/src/command.rs index 506b81a3a..f31c9fcd0 100644 --- a/node/setheum/cli/src/command.rs +++ b/node/setheum/cli/src/command.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -49,7 +49,7 @@ impl SubstrateCli for Cli { } fn support_url() -> String { - "https://github.com/SetheumNetwork/Setheum/issues".into() + "https://github.com/Setheum-Labs/Setheum/issues".into() } fn copyright_start_year() -> i32 { diff --git a/node/setheum/cli/src/lib.rs b/node/setheum/cli/src/lib.rs index 141fd7555..63b12a27c 100644 --- a/node/setheum/cli/src/lib.rs +++ b/node/setheum/cli/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/service/src/chain_spec/mod.rs b/node/setheum/service/src/chain_spec/mod.rs index aae7f9e70..5751ac1e1 100644 --- a/node/setheum/service/src/chain_spec/mod.rs +++ b/node/setheum/service/src/chain_spec/mod.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/service/src/chain_spec/neom.rs b/node/setheum/service/src/chain_spec/neom.rs index 0d68197ce..d0f6c6a79 100644 --- a/node/setheum/service/src/chain_spec/neom.rs +++ b/node/setheum/service/src/chain_spec/neom.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/service/src/chain_spec/newrome.rs b/node/setheum/service/src/chain_spec/newrome.rs index 15757a212..383ccef64 100644 --- a/node/setheum/service/src/chain_spec/newrome.rs +++ b/node/setheum/service/src/chain_spec/newrome.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/service/src/chain_spec/setheum.rs b/node/setheum/service/src/chain_spec/setheum.rs index 1793fa056..af79d782d 100644 --- a/node/setheum/service/src/chain_spec/setheum.rs +++ b/node/setheum/service/src/chain_spec/setheum.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/service/src/client.rs b/node/setheum/service/src/client.rs index 6d89aa849..702d3281f 100644 --- a/node/setheum/service/src/client.rs +++ b/node/setheum/service/src/client.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/service/src/lib.rs b/node/setheum/service/src/lib.rs index 727e349a6..949f828f6 100644 --- a/node/setheum/service/src/lib.rs +++ b/node/setheum/service/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/service/src/mock_timestamp_data_provider.rs b/node/setheum/service/src/mock_timestamp_data_provider.rs index a37058089..ee1a44a0b 100644 --- a/node/setheum/service/src/mock_timestamp_data_provider.rs +++ b/node/setheum/service/src/mock_timestamp_data_provider.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/node/setheum/src/main.rs b/node/setheum/src/main.rs index 90125ee3c..ff92673d8 100644 --- a/node/setheum/src/main.rs +++ b/node/setheum/src/main.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index 0f9caa0a7..b95e3465e 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/primitives/src/evm.rs b/primitives/src/evm.rs index 2d5fc1e90..38ce436e5 100644 --- a/primitives/src/evm.rs +++ b/primitives/src/evm.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 3e8a57139..847e60fe7 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/primitives/src/tests.rs b/primitives/src/tests.rs index f9257a9fc..350ae2911 100644 --- a/primitives/src/tests.rs +++ b/primitives/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 4dd9f15a6..c05fd3432 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index f8c2a0a33..122c0841e 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/build.rs b/runtime/neom/build.rs index e096cd3a6..fdc2cce56 100644 --- a/runtime/neom/build.rs +++ b/runtime/neom/build.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/authority.rs b/runtime/neom/src/authority.rs index 36380bede..63a11d324 100644 --- a/runtime/neom/src/authority.rs +++ b/runtime/neom/src/authority.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/constants.rs b/runtime/neom/src/constants.rs index ae79235a1..49eca7392 100644 --- a/runtime/neom/src/constants.rs +++ b/runtime/neom/src/constants.rs @@ -1,5 +1,5 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index b3766e2db..8681cdb1e 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/mod.rs b/runtime/neom/src/weights/mod.rs index 3f1ee6f67..a729bd3c6 100644 --- a/runtime/neom/src/weights/mod.rs +++ b/runtime/neom/src/weights/mod.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/orml_auction.rs b/runtime/neom/src/weights/orml_auction.rs index d4d1d3ce5..b8c33bc1a 100644 --- a/runtime/neom/src/weights/orml_auction.rs +++ b/runtime/neom/src/weights/orml_auction.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/orml_authority.rs b/runtime/neom/src/weights/orml_authority.rs index f166e1694..7b28f4c00 100644 --- a/runtime/neom/src/weights/orml_authority.rs +++ b/runtime/neom/src/weights/orml_authority.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/orml_oracle.rs b/runtime/neom/src/weights/orml_oracle.rs index 76a82e765..3195adbf2 100644 --- a/runtime/neom/src/weights/orml_oracle.rs +++ b/runtime/neom/src/weights/orml_oracle.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/orml_rewards.rs b/runtime/neom/src/weights/orml_rewards.rs index 7712c6b0c..c20fb5dc7 100644 --- a/runtime/neom/src/weights/orml_rewards.rs +++ b/runtime/neom/src/weights/orml_rewards.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/orml_tokens.rs b/runtime/neom/src/weights/orml_tokens.rs index f0a7976de..75e8b334e 100644 --- a/runtime/neom/src/weights/orml_tokens.rs +++ b/runtime/neom/src/weights/orml_tokens.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/orml_vesting.rs b/runtime/neom/src/weights/orml_vesting.rs index 497f792da..afb1da03f 100644 --- a/runtime/neom/src/weights/orml_vesting.rs +++ b/runtime/neom/src/weights/orml_vesting.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_auction_manager.rs b/runtime/neom/src/weights/setheum_auction_manager.rs index 92a694248..67656891a 100644 --- a/runtime/neom/src/weights/setheum_auction_manager.rs +++ b/runtime/neom/src/weights/setheum_auction_manager.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_currencies.rs b/runtime/neom/src/weights/setheum_currencies.rs index 5d0da34ba..3ad411f9b 100644 --- a/runtime/neom/src/weights/setheum_currencies.rs +++ b/runtime/neom/src/weights/setheum_currencies.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_dex.rs b/runtime/neom/src/weights/setheum_dex.rs index a284227fa..e454b22c0 100644 --- a/runtime/neom/src/weights/setheum_dex.rs +++ b/runtime/neom/src/weights/setheum_dex.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_incentives.rs b/runtime/neom/src/weights/setheum_incentives.rs index 0711d8b5a..40dfecb32 100644 --- a/runtime/neom/src/weights/setheum_incentives.rs +++ b/runtime/neom/src/weights/setheum_incentives.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_nft.rs b/runtime/neom/src/weights/setheum_nft.rs index 9f0ecc01d..c7d5ddd67 100644 --- a/runtime/neom/src/weights/setheum_nft.rs +++ b/runtime/neom/src/weights/setheum_nft.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_prices.rs b/runtime/neom/src/weights/setheum_prices.rs index 8f4f610db..5e24c5089 100644 --- a/runtime/neom/src/weights/setheum_prices.rs +++ b/runtime/neom/src/weights/setheum_prices.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_serp.rs b/runtime/neom/src/weights/setheum_serp.rs index 909758859..0bf5f2329 100644 --- a/runtime/neom/src/weights/setheum_serp.rs +++ b/runtime/neom/src/weights/setheum_serp.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_settmint_treasury.rs b/runtime/neom/src/weights/setheum_settmint_treasury.rs index 1d3e7d1d6..a5e2e8072 100644 --- a/runtime/neom/src/weights/setheum_settmint_treasury.rs +++ b/runtime/neom/src/weights/setheum_settmint_treasury.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/setheum_transaction_payment.rs b/runtime/neom/src/weights/setheum_transaction_payment.rs index 7a0ce76d3..cbec3ddce 100644 --- a/runtime/neom/src/weights/setheum_transaction_payment.rs +++ b/runtime/neom/src/weights/setheum_transaction_payment.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/neom/src/weights/transaction_payment.rs b/runtime/neom/src/weights/transaction_payment.rs index 9d328790d..cb77f65cf 100644 --- a/runtime/neom/src/weights/transaction_payment.rs +++ b/runtime/neom/src/weights/transaction_payment.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/build.rs b/runtime/newrome/build.rs index e096cd3a6..fdc2cce56 100644 --- a/runtime/newrome/build.rs +++ b/runtime/newrome/build.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/authority.rs b/runtime/newrome/src/authority.rs index c0c67f80f..c5a9b8d5a 100644 --- a/runtime/newrome/src/authority.rs +++ b/runtime/newrome/src/authority.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/auction.rs b/runtime/newrome/src/benchmarking/auction.rs index d94a9932c..fb436abba 100644 --- a/runtime/newrome/src/benchmarking/auction.rs +++ b/runtime/newrome/src/benchmarking/auction.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/authority.rs b/runtime/newrome/src/benchmarking/authority.rs index 628db20e1..312630d9d 100644 --- a/runtime/newrome/src/benchmarking/authority.rs +++ b/runtime/newrome/src/benchmarking/authority.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/currencies.rs b/runtime/newrome/src/benchmarking/currencies.rs index 392a5feb3..175a25ba2 100644 --- a/runtime/newrome/src/benchmarking/currencies.rs +++ b/runtime/newrome/src/benchmarking/currencies.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/dex.rs b/runtime/newrome/src/benchmarking/dex.rs index 0403d56ac..e8f54ece4 100644 --- a/runtime/newrome/src/benchmarking/dex.rs +++ b/runtime/newrome/src/benchmarking/dex.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/incentives.rs b/runtime/newrome/src/benchmarking/incentives.rs index 798c9a335..4b4d29be1 100644 --- a/runtime/newrome/src/benchmarking/incentives.rs +++ b/runtime/newrome/src/benchmarking/incentives.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/mod.rs b/runtime/newrome/src/benchmarking/mod.rs index 21feb8a24..4c99f55c3 100644 --- a/runtime/newrome/src/benchmarking/mod.rs +++ b/runtime/newrome/src/benchmarking/mod.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/oracle.rs b/runtime/newrome/src/benchmarking/oracle.rs index d25471a5c..a3d510dd5 100644 --- a/runtime/newrome/src/benchmarking/oracle.rs +++ b/runtime/newrome/src/benchmarking/oracle.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/prices.rs b/runtime/newrome/src/benchmarking/prices.rs index 2a86124be..b55a5d216 100644 --- a/runtime/newrome/src/benchmarking/prices.rs +++ b/runtime/newrome/src/benchmarking/prices.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/serp.rs b/runtime/newrome/src/benchmarking/serp.rs index 997735673..342b3c510 100644 --- a/runtime/newrome/src/benchmarking/serp.rs +++ b/runtime/newrome/src/benchmarking/serp.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/settmint_treasury.rs b/runtime/newrome/src/benchmarking/settmint_treasury.rs index 589767e1a..73d31d8c4 100644 --- a/runtime/newrome/src/benchmarking/settmint_treasury.rs +++ b/runtime/newrome/src/benchmarking/settmint_treasury.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/tokens.rs b/runtime/newrome/src/benchmarking/tokens.rs index b35122681..7db699eec 100644 --- a/runtime/newrome/src/benchmarking/tokens.rs +++ b/runtime/newrome/src/benchmarking/tokens.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/transaction_payment.rs b/runtime/newrome/src/benchmarking/transaction_payment.rs index 060ffff23..42b25d6aa 100644 --- a/runtime/newrome/src/benchmarking/transaction_payment.rs +++ b/runtime/newrome/src/benchmarking/transaction_payment.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/utils.rs b/runtime/newrome/src/benchmarking/utils.rs index 97f11a487..02a957e1f 100644 --- a/runtime/newrome/src/benchmarking/utils.rs +++ b/runtime/newrome/src/benchmarking/utils.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/benchmarking/vesting.rs b/runtime/newrome/src/benchmarking/vesting.rs index 06f31505e..089a8da82 100644 --- a/runtime/newrome/src/benchmarking/vesting.rs +++ b/runtime/newrome/src/benchmarking/vesting.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/constants.rs b/runtime/newrome/src/constants.rs index 56db61e58..f187872d7 100644 --- a/runtime/newrome/src/constants.rs +++ b/runtime/newrome/src/constants.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index efc0fd75f..e27e87938 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/mod.rs b/runtime/newrome/src/weights/mod.rs index 3f1ee6f67..a729bd3c6 100644 --- a/runtime/newrome/src/weights/mod.rs +++ b/runtime/newrome/src/weights/mod.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/module_transaction_payment.rs b/runtime/newrome/src/weights/module_transaction_payment.rs index 7b6967fbb..b8e3833f2 100644 --- a/runtime/newrome/src/weights/module_transaction_payment.rs +++ b/runtime/newrome/src/weights/module_transaction_payment.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/orml_auction.rs b/runtime/newrome/src/weights/orml_auction.rs index 79fba3fcd..70ea493e0 100644 --- a/runtime/newrome/src/weights/orml_auction.rs +++ b/runtime/newrome/src/weights/orml_auction.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/orml_authority.rs b/runtime/newrome/src/weights/orml_authority.rs index 015e7d453..4e73721a4 100644 --- a/runtime/newrome/src/weights/orml_authority.rs +++ b/runtime/newrome/src/weights/orml_authority.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/orml_oracle.rs b/runtime/newrome/src/weights/orml_oracle.rs index e95cccd75..bbba27e53 100644 --- a/runtime/newrome/src/weights/orml_oracle.rs +++ b/runtime/newrome/src/weights/orml_oracle.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/orml_rewards.rs b/runtime/newrome/src/weights/orml_rewards.rs index 9d41bd332..29af5a15b 100644 --- a/runtime/newrome/src/weights/orml_rewards.rs +++ b/runtime/newrome/src/weights/orml_rewards.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/orml_tokens.rs b/runtime/newrome/src/weights/orml_tokens.rs index 6d4e1540a..7ac882a94 100644 --- a/runtime/newrome/src/weights/orml_tokens.rs +++ b/runtime/newrome/src/weights/orml_tokens.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/orml_vesting.rs b/runtime/newrome/src/weights/orml_vesting.rs index 61007973b..bf8d12e1e 100644 --- a/runtime/newrome/src/weights/orml_vesting.rs +++ b/runtime/newrome/src/weights/orml_vesting.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_auction_manager.rs b/runtime/newrome/src/weights/setheum_auction_manager.rs index d39cf0146..f0007badb 100644 --- a/runtime/newrome/src/weights/setheum_auction_manager.rs +++ b/runtime/newrome/src/weights/setheum_auction_manager.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_currencies.rs b/runtime/newrome/src/weights/setheum_currencies.rs index f595406ef..896067a62 100644 --- a/runtime/newrome/src/weights/setheum_currencies.rs +++ b/runtime/newrome/src/weights/setheum_currencies.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_dex.rs b/runtime/newrome/src/weights/setheum_dex.rs index 337ecebec..ae6af2182 100644 --- a/runtime/newrome/src/weights/setheum_dex.rs +++ b/runtime/newrome/src/weights/setheum_dex.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_incentives.rs b/runtime/newrome/src/weights/setheum_incentives.rs index 28dfe4441..b4eaa8fdd 100644 --- a/runtime/newrome/src/weights/setheum_incentives.rs +++ b/runtime/newrome/src/weights/setheum_incentives.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_nft.rs b/runtime/newrome/src/weights/setheum_nft.rs index 429415a8e..1a1558d4a 100644 --- a/runtime/newrome/src/weights/setheum_nft.rs +++ b/runtime/newrome/src/weights/setheum_nft.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_prices.rs b/runtime/newrome/src/weights/setheum_prices.rs index eb88d6883..1fc575c55 100644 --- a/runtime/newrome/src/weights/setheum_prices.rs +++ b/runtime/newrome/src/weights/setheum_prices.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_serp.rs b/runtime/newrome/src/weights/setheum_serp.rs index 90c59097c..7ec116c1f 100644 --- a/runtime/newrome/src/weights/setheum_serp.rs +++ b/runtime/newrome/src/weights/setheum_serp.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/newrome/src/weights/setheum_settmint_treasury.rs b/runtime/newrome/src/weights/setheum_settmint_treasury.rs index 3bd92ab13..d6f4759d7 100644 --- a/runtime/newrome/src/weights/setheum_settmint_treasury.rs +++ b/runtime/newrome/src/weights/setheum_settmint_treasury.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/build.rs b/runtime/setheum/build.rs index e096cd3a6..fdc2cce56 100644 --- a/runtime/setheum/build.rs +++ b/runtime/setheum/build.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/authority.rs b/runtime/setheum/src/authority.rs index dbdc51b43..55ab4377d 100644 --- a/runtime/setheum/src/authority.rs +++ b/runtime/setheum/src/authority.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/constants.rs b/runtime/setheum/src/constants.rs index d0d766a6e..f0682d18e 100644 --- a/runtime/setheum/src/constants.rs +++ b/runtime/setheum/src/constants.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index c5dca7959..07ce8a84e 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/mod.rs b/runtime/setheum/src/weights/mod.rs index 3f1ee6f67..a729bd3c6 100644 --- a/runtime/setheum/src/weights/mod.rs +++ b/runtime/setheum/src/weights/mod.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/orml_auction.rs b/runtime/setheum/src/weights/orml_auction.rs index 63d29868b..d17c796ff 100644 --- a/runtime/setheum/src/weights/orml_auction.rs +++ b/runtime/setheum/src/weights/orml_auction.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/orml_authority.rs b/runtime/setheum/src/weights/orml_authority.rs index 4d5dda1ea..25cdb343d 100644 --- a/runtime/setheum/src/weights/orml_authority.rs +++ b/runtime/setheum/src/weights/orml_authority.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/orml_oracle.rs b/runtime/setheum/src/weights/orml_oracle.rs index 444c4e881..70b8c9d94 100644 --- a/runtime/setheum/src/weights/orml_oracle.rs +++ b/runtime/setheum/src/weights/orml_oracle.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/orml_rewards.rs b/runtime/setheum/src/weights/orml_rewards.rs index c254afd7b..e58f3c45c 100644 --- a/runtime/setheum/src/weights/orml_rewards.rs +++ b/runtime/setheum/src/weights/orml_rewards.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/orml_tokens.rs b/runtime/setheum/src/weights/orml_tokens.rs index cac3a5e47..45dd65fdf 100644 --- a/runtime/setheum/src/weights/orml_tokens.rs +++ b/runtime/setheum/src/weights/orml_tokens.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/orml_vesting.rs b/runtime/setheum/src/weights/orml_vesting.rs index 68eda48c7..dc17dbd62 100644 --- a/runtime/setheum/src/weights/orml_vesting.rs +++ b/runtime/setheum/src/weights/orml_vesting.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_auction_manager.rs b/runtime/setheum/src/weights/setheum_auction_manager.rs index f014d0f7a..7de03b0fb 100644 --- a/runtime/setheum/src/weights/setheum_auction_manager.rs +++ b/runtime/setheum/src/weights/setheum_auction_manager.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_currencies.rs b/runtime/setheum/src/weights/setheum_currencies.rs index b28f6ed71..6b162b0c3 100644 --- a/runtime/setheum/src/weights/setheum_currencies.rs +++ b/runtime/setheum/src/weights/setheum_currencies.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_dex.rs b/runtime/setheum/src/weights/setheum_dex.rs index 49546a28c..eaae22409 100644 --- a/runtime/setheum/src/weights/setheum_dex.rs +++ b/runtime/setheum/src/weights/setheum_dex.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_incentives.rs b/runtime/setheum/src/weights/setheum_incentives.rs index 0d259a4a7..7071ee598 100644 --- a/runtime/setheum/src/weights/setheum_incentives.rs +++ b/runtime/setheum/src/weights/setheum_incentives.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_nft.rs b/runtime/setheum/src/weights/setheum_nft.rs index 8f510f23a..cff4a4e85 100644 --- a/runtime/setheum/src/weights/setheum_nft.rs +++ b/runtime/setheum/src/weights/setheum_nft.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_prices.rs b/runtime/setheum/src/weights/setheum_prices.rs index 1f5598ad5..4f40a3699 100644 --- a/runtime/setheum/src/weights/setheum_prices.rs +++ b/runtime/setheum/src/weights/setheum_prices.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_serp.rs b/runtime/setheum/src/weights/setheum_serp.rs index f408bb985..d60050bea 100644 --- a/runtime/setheum/src/weights/setheum_serp.rs +++ b/runtime/setheum/src/weights/setheum_serp.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_settmint_treasury.rs b/runtime/setheum/src/weights/setheum_settmint_treasury.rs index 94561f993..9ddb144e5 100644 --- a/runtime/setheum/src/weights/setheum_settmint_treasury.rs +++ b/runtime/setheum/src/weights/setheum_settmint_treasury.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/runtime/setheum/src/weights/setheum_transaction_payment.rs b/runtime/setheum/src/weights/setheum_transaction_payment.rs index 8bd010815..eb66d44a1 100644 --- a/runtime/setheum/src/weights/setheum_transaction_payment.rs +++ b/runtime/setheum/src/weights/setheum_transaction_payment.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/templates/module-weight-template.hbs b/templates/module-weight-template.hbs index 2ff8b08b8..e326c8277 100644 --- a/templates/module-weight-template.hbs +++ b/templates/module-weight-template.hbs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum Labs. +// Copyright (C) 2019-2021 Setheum Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify From 0052a61d7165f6412e515532d28fe58bb3badd4c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 05:06:14 +0800 Subject: [PATCH 13/83] add setheum-evm-manager --- lib-serml/evm-manager/Cargo.toml | 45 +++ lib-serml/evm-manager/src/lib.rs | 313 ++++++++++++++++++++ lib-serml/evm-manager/src/mock.rs | 260 ++++++++++++++++ lib-serml/evm-manager/src/tests.rs | 458 +++++++++++++++++++++++++++++ 4 files changed, 1076 insertions(+) create mode 100644 lib-serml/evm-manager/Cargo.toml create mode 100644 lib-serml/evm-manager/src/lib.rs create mode 100644 lib-serml/evm-manager/src/mock.rs create mode 100644 lib-serml/evm-manager/src/tests.rs diff --git a/lib-serml/evm-manager/Cargo.toml b/lib-serml/evm-manager/Cargo.toml new file mode 100644 index 000000000..9c3c45f71 --- /dev/null +++ b/lib-serml/evm-manager/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "module-evm-manager" +version = "1.0.0" +authors = ["Setheum-Labs"] +edition = "2018" + +[dependencies] +serde = { version = "1.0.124", optional = true } +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } + +primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } +setheum-support = { path = "../support", default-features = false } + +[dev-dependencies] +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +orml-currencies = { path = "../../orml/currencies" } +orml-tokens = { path = "../../orml/tokens" } +orml-traits = { path = "../../orml/traits" } +orml-utilities = { path = "../../orml/utilities" } +module-evm = { path = "../evm" } +module-evm-bridge = { path = "../evm-bridge" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-core/std", + "sp-runtime/std", + "sp-io/std", + "sp-std/std", + "frame-support/std", + "frame-system/std", + "primitives/std", + "setheum-support/std", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/lib-serml/evm-manager/src/lib.rs b/lib-serml/evm-manager/src/lib.rs new file mode 100644 index 000000000..10c66d28b --- /dev/null +++ b/lib-serml/evm-manager/src/lib.rs @@ -0,0 +1,313 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum-Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! # Evm Manager Module +//! +//! ## Overview +//! +//! Evm manager module provides common support features for Evm, including: +//! - A two way mapping between `u32` and `Erc20 address` so user can use Erc20 address as LP token. + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] + +use frame_support::{ensure, pallet_prelude::*, require_transactional, traits::Currency}; +use module_support::{CurrencyIdMapping, EVMBridge, InvokeContext}; +use primitives::{ + currency::TokenInfo, + evm::{Erc20Info, EvmAddress}, + *, +}; +use sp_std::{ + convert::{TryFrom, TryInto}, + vec::Vec, +}; + +mod mock; +mod tests; + +pub use module::*; + +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; + +#[frame_support::pallet] +pub mod module { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Currency: Currency; + type EVMBridge: EVMBridge>; + } + + /// Error for evm accounts module. + #[pallet::error] + pub enum Error { + /// CurrencyId existed + CurrencyIdExisted, + } + + /// Mapping between u32 and Erc20 address. + /// Erc20 address is 20 byte, take the first 4 non-zero bytes, if it is less + /// than 4, add 0 to the left. + /// + /// map u32 => Option + #[pallet::storage] + #[pallet::getter(fn currency_id_map)] + pub type CurrencyIdMap = StorageMap<_, Twox64Concat, u32, Erc20Info, OptionQuery>; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +impl Pallet {} + +pub struct EvmCurrencyIdMapping(sp_std::marker::PhantomData); + +impl CurrencyIdMapping for EvmCurrencyIdMapping { + // Use first 4 non-zero bytes as u32 to the mapping between u32 and evm address. + // Take the first 4 non-zero bytes, if it is less than 4, add 0 to the left. + #[require_transactional] + fn set_erc20_mapping(address: EvmAddress) -> DispatchResult { + CurrencyIdMap::::mutate( + Into::::into(DexShare::Erc20(address)), + |maybe_erc20_info| -> DispatchResult { + if let Some(erc20_info) = maybe_erc20_info.as_mut() { + ensure!(erc20_info.address == address, Error::::CurrencyIdExisted); + } else { + let invoke_context = InvokeContext { + contract: address, + sender: Default::default(), + origin: Default::default(), + }; + + let info = Erc20Info { + address, + name: T::EVMBridge::name(invoke_context)?, + symbol: T::EVMBridge::symbol(invoke_context)?, + decimals: T::EVMBridge::decimals(invoke_context)?, + }; + + *maybe_erc20_info = Some(info); + } + Ok(()) + }, + ) + } + + // Returns the EvmAddress associated with a given u32. + fn get_evm_address(currency_id: u32) -> Option { + CurrencyIdMap::::get(currency_id).map(|v| v.address) + } + + // Returns the name associated with a given CurrencyId. + // If CurrencyId is CurrencyId::DexShare and contain DexShare::Erc20, + // the EvmAddress must have been mapped. + fn name(currency_id: CurrencyId) -> Option> { + let name = match currency_id { + CurrencyId::Token(_) => currency_id.name().map(|v| v.as_bytes().to_vec()), + CurrencyId::DexShare(symbol_0, symbol_1) => { + let name_0 = match symbol_0 { + DexShare::Token(symbol) => CurrencyId::Token(symbol).name().map(|v| v.as_bytes().to_vec()), + DexShare::Erc20(address) => CurrencyIdMap::::get(Into::::into(symbol_0)) + .filter(|v| v.address == address) + .map(|v| v.name), + }?; + let name_1 = match symbol_1 { + DexShare::Token(symbol) => CurrencyId::Token(symbol).name().map(|v| v.as_bytes().to_vec()), + DexShare::Erc20(address) => CurrencyIdMap::::get(Into::::into(symbol_1)) + .filter(|v| v.address == address) + .map(|v| v.name), + }?; + + let mut vec = Vec::new(); + vec.extend_from_slice(&b"LP "[..]); + vec.extend_from_slice(&name_0); + vec.extend_from_slice(&b" - ".to_vec()); + vec.extend_from_slice(&name_1); + Some(vec) + } + CurrencyId::Erc20(address) => CurrencyIdMap::::get(Into::::into(DexShare::Erc20(address))) + .filter(|v| v.address == address) + .map(|v| v.name), + CurrencyId::ChainSafe(_) => None, + }?; + + // More than 32 bytes will be truncated. + if name.len() > 32 { + Some(name[..32].to_vec()) + } else { + Some(name) + } + } + + // Returns the symbol associated with a given CurrencyId. + // If CurrencyId is CurrencyId::DexShare and contain DexShare::Erc20, + // the EvmAddress must have been mapped. + fn symbol(currency_id: CurrencyId) -> Option> { + let symbol = match currency_id { + CurrencyId::Token(_) => currency_id.symbol().map(|v| v.as_bytes().to_vec()), + CurrencyId::DexShare(symbol_0, symbol_1) => { + let token_symbol_0 = match symbol_0 { + DexShare::Token(symbol) => CurrencyId::Token(symbol).symbol().map(|v| v.as_bytes().to_vec()), + DexShare::Erc20(address) => CurrencyIdMap::::get(Into::::into(symbol_0)) + .filter(|v| v.address == address) + .map(|v| v.symbol), + }?; + let token_symbol_1 = match symbol_1 { + DexShare::Token(symbol) => CurrencyId::Token(symbol).symbol().map(|v| v.as_bytes().to_vec()), + DexShare::Erc20(address) => CurrencyIdMap::::get(Into::::into(symbol_1)) + .filter(|v| v.address == address) + .map(|v| v.symbol), + }?; + + let mut vec = Vec::new(); + vec.extend_from_slice(&b"LP_"[..]); + vec.extend_from_slice(&token_symbol_0); + vec.extend_from_slice(&b"_".to_vec()); + vec.extend_from_slice(&token_symbol_1); + Some(vec) + } + CurrencyId::Erc20(address) => CurrencyIdMap::::get(Into::::into(DexShare::Erc20(address))) + .filter(|v| v.address == address) + .map(|v| v.symbol), + CurrencyId::ChainSafe(_) => None, + }?; + + // More than 32 bytes will be truncated. + if symbol.len() > 32 { + Some(symbol[..32].to_vec()) + } else { + Some(symbol) + } + } + + // Returns the decimals associated with a given CurrencyId. + // If CurrencyId is CurrencyId::DexShare and contain DexShare::Erc20, + // the EvmAddress must have been mapped. + fn decimals(currency_id: CurrencyId) -> Option { + match currency_id { + CurrencyId::Token(_) => currency_id.decimals(), + CurrencyId::DexShare(symbol_0, symbol_1) => { + let decimals_0 = match symbol_0 { + DexShare::Token(symbol) => CurrencyId::Token(symbol).decimals(), + DexShare::Erc20(address) => CurrencyIdMap::::get(Into::::into(symbol_0)) + .filter(|v| v.address == address) + .map(|v| v.decimals), + }?; + let decimals_1 = match symbol_1 { + DexShare::Token(symbol) => CurrencyId::Token(symbol).decimals(), + DexShare::Erc20(address) => CurrencyIdMap::::get(Into::::into(symbol_1)) + .filter(|v| v.address == address) + .map(|v| v.decimals), + }?; + + Some(sp_std::cmp::max(decimals_0, decimals_1)) + } + CurrencyId::Erc20(address) => CurrencyIdMap::::get(Into::::into(DexShare::Erc20(address))) + .filter(|v| v.address == address) + .map(|v| v.decimals), + CurrencyId::ChainSafe(_) => None, + } + } + + // Encode the CurrencyId to EvmAddress. + // If is CurrencyId::DexShare and contain DexShare::Erc20, + // will use the u32 to get the DexShare::Erc20 from the mapping. + fn encode_evm_address(v: CurrencyId) -> Option { + match v { + CurrencyId::DexShare(left, right) => { + let symbol_0 = match left { + DexShare::Token(_) => Some(left.into()), + DexShare::Erc20(address) => { + let id: u32 = left.into(); + CurrencyIdMap::::get(id).filter(|v| v.address == address).map(|_| id) + } + }?; + let symbol_1 = match right { + DexShare::Token(_) => Some(right.into()), + DexShare::Erc20(address) => { + let id: u32 = right.into(); + CurrencyIdMap::::get(id).filter(|v| v.address == address).map(|_| id) + } + }?; + + let mut prefix = EvmAddress::default(); + prefix[0..H160_PREFIX_DEXSHARE.len()].copy_from_slice(&H160_PREFIX_DEXSHARE); + Some(prefix | EvmAddress::from_low_u64_be(u64::from(symbol_0) << 32 | u64::from(symbol_1))) + } + + // Token or Erc20 or ChainSafe + _ => EvmAddress::try_from(v).ok(), + } + } + + // Decode the CurrencyId from EvmAddress. + // If is CurrencyId::DexShare and contain DexShare::Erc20, + // will use the u32 to get the DexShare::Erc20 from the mapping. + fn decode_evm_address(addr: EvmAddress) -> Option { + let address = addr.as_bytes(); + + // Token + if address.starts_with(&H160_PREFIX_TOKEN) { + return address[H160_POSITION_TOKEN].try_into().map(CurrencyId::Token).ok(); + } + + // DexShare + if address.starts_with(&H160_PREFIX_DEXSHARE) { + let left = { + if address[H160_POSITION_DEXSHARE_LEFT].starts_with(&[0u8; 3]) { + // Token + address[H160_POSITION_DEXSHARE_LEFT][3] + .try_into() + .map(DexShare::Token) + .ok() + } else { + // Erc20 + let id = u32::from_be_bytes(address[H160_POSITION_DEXSHARE_LEFT].try_into().ok()?); + CurrencyIdMap::::get(id).map(|v| DexShare::Erc20(v.address)) + } + }?; + let right = { + if address[H160_POSITION_DEXSHARE_RIGHT].starts_with(&[0u8; 3]) { + // Token + address[H160_POSITION_DEXSHARE_RIGHT][3] + .try_into() + .map(DexShare::Token) + .ok() + } else { + // Erc20 + let id = u32::from_be_bytes(address[H160_POSITION_DEXSHARE_RIGHT].try_into().ok()?); + CurrencyIdMap::::get(id).map(|v| DexShare::Erc20(v.address)) + } + }?; + + return Some(CurrencyId::DexShare(left, right)); + } + + // Erc20 + let id = Into::::into(DexShare::Erc20(addr)); + CurrencyIdMap::::get(id).map(|v| CurrencyId::Erc20(v.address)) + } +} diff --git a/lib-serml/evm-manager/src/mock.rs b/lib-serml/evm-manager/src/mock.rs new file mode 100644 index 000000000..465487d99 --- /dev/null +++ b/lib-serml/evm-manager/src/mock.rs @@ -0,0 +1,260 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum-Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Mocks for the setheum evm-manager module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_ok, construct_runtime, ord_parameter_types, parameter_types}; +use frame_system::EnsureSignedBy; +use module_support::{mocks::MockAddressMapping, AddressMapping}; +use orml_traits::parameter_type_with_key; +use primitives::{Amount, Balance, CurrencyId, TokenSymbol}; +use sp_core::{bytes::from_hex, crypto::AccountId32, H256}; +use sp_runtime::{testing::Header, traits::IdentityLookup}; +use std::str::FromStr; + +pub type AccountId = AccountId32; +pub type BlockNumber = u64; + +mod evm_manager { + pub use super::super::*; +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = frame_system::Pallet; + type MaxLocks = (); + type WeightInfo = (); +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type Event = Event; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = (); +} + +parameter_types! { + pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); +} + +impl orml_currencies::Config for Runtime { + type Event = Event; + type MultiCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type GetNativeCurrencyId = GetNativeCurrencyId; + type WeightInfo = (); +} +pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter; + +parameter_types! { + pub const MinimumPeriod: u64 = 1000; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + pub const NewContractExtraBytes: u32 = 1; + pub NetworkContractSource: EvmAddress = alice_evm_addr(); +} + +ord_parameter_types! { + pub const CouncilAccount: AccountId32 = AccountId32::from([1u8; 32]); + pub const TreasuryAccount: AccountId32 = AccountId32::from([2u8; 32]); + pub const NetworkContractAccount: AccountId32 = AccountId32::from([0u8; 32]); + pub const StorageDepositPerByte: u128 = 10; + pub const MaxCodeSize: u32 = 60 * 1024; + pub const DeveloperDeposit: u64 = 1000; + pub const DeploymentFee: u64 = 200; +} + +impl module_evm::Config for Runtime { + type AddressMapping = MockAddressMapping; + type Currency = Balances; + type TransferAll = (); + type NewContractExtraBytes = NewContractExtraBytes; + type StorageDepositPerByte = StorageDepositPerByte; + type MaxCodeSize = MaxCodeSize; + + type Event = Event; + type Precompiles = (); + type ChainId = (); + type GasToWeight = (); + type ChargeTransactionPayment = (); + type NetworkContractOrigin = EnsureSignedBy; + type NetworkContractSource = NetworkContractSource; + + type DeveloperDeposit = DeveloperDeposit; + type DeploymentFee = DeploymentFee; + type TreasuryAccount = TreasuryAccount; + type FreeDeploymentOrigin = EnsureSignedBy; + + type WeightInfo = (); +} + +impl module_evm_bridge::Config for Runtime { + type EVM = EVM; +} + +impl Config for Runtime { + type Currency = Balances; + type EVMBridge = EVMBridge; +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +pub fn erc20_address() -> EvmAddress { + EvmAddress::from_str("0000000000000000000000000000000002000000").unwrap() +} + +pub fn erc20_address_not_exists() -> EvmAddress { + EvmAddress::from_str("0000000000000000000000000000000002000001").unwrap() +} + +pub fn alice() -> AccountId { + ::AddressMapping::get_account_id(&alice_evm_addr()) +} + +pub fn alice_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000001").unwrap() +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + EvmManager: evm_manager::{Pallet, Storage}, + Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Currencies: orml_currencies::{Pallet, Call, Event}, + EVM: module_evm::{Pallet, Config, Call, Storage, Event}, + EVMBridge: module_evm_bridge::{Pallet}, + } +); + +pub fn deploy_contracts() { + let code = from_hex(include!("../../evm-bridge/src/erc20_demo_contract")).unwrap(); + assert_ok!(EVM::create_network_contract( + Origin::signed(NetworkContractAccount::get()), + code, + 0, + 2100_000, + 10000 + )); + + let event = Event::module_evm(module_evm::Event::Created(erc20_address())); + assert_eq!(System::events().iter().last().unwrap().event, event); + + assert_ok!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), erc20_address())); +} + +pub struct ExtBuilder { + endowed_accounts: Vec<(AccountId, Balance)>, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + endowed_accounts: vec![], + } + } +} + +impl ExtBuilder { + pub fn balances(mut self, endowed_accounts: Vec<(AccountId, Balance)>) -> Self { + self.endowed_accounts = endowed_accounts; + self + } + + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: self.endowed_accounts.clone().into_iter().collect::>(), + } + .assimilate_storage(&mut t) + .unwrap(); + + module_evm::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} diff --git a/lib-serml/evm-manager/src/tests.rs b/lib-serml/evm-manager/src/tests.rs new file mode 100644 index 000000000..8a8298617 --- /dev/null +++ b/lib-serml/evm-manager/src/tests.rs @@ -0,0 +1,458 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum-Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Unit tests for the evm-manager module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::{alice, deploy_contracts, erc20_address, erc20_address_not_exists, ExtBuilder, Runtime}; +use orml_utilities::with_transaction_result; +use primitives::TokenSymbol; +use sp_core::H160; +use std::str::FromStr; + +#[test] +fn set_erc20_mapping_works() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + + assert_noop!( + with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping( + EvmAddress::from_str("0000000000000000000000000000000200000000").unwrap(), + ) + }), + Error::::CurrencyIdExisted, + ); + + assert_noop!( + with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping( + EvmAddress::from_str("0000000000000000000000000000000200000001").unwrap(), + ) + }), + Error::::CurrencyIdExisted, + ); + + assert_noop!( + with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address_not_exists()) + }), + module_evm_bridge::Error::::InvalidReturnValue, + ); + }); +} + +#[test] +fn get_evm_address_works() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + assert_eq!( + EvmCurrencyIdMapping::::get_evm_address(DexShare::Erc20(erc20_address()).into()), + Some(erc20_address()) + ); + + assert_eq!(EvmCurrencyIdMapping::::get_evm_address(u32::default()), None); + }); +} + +#[test] +fn name_works() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::Token(TokenSymbol::DNAR)), + Some(b"Setheum".to_vec()) + ); + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::Erc20(erc20_address())), + Some(b"long string name, long string name, long string name, long string name, long string name"[..32].to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::Erc20(erc20_address_not_exists())), + None + ); + + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::DexShare(DexShare::Token(TokenSymbol::DNAR), DexShare::Token(TokenSymbol::USDJ))), + Some(b"LP Setheum - Setheum US Dollar".to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::DexShare(DexShare::Erc20(erc20_address()), DexShare::Token(TokenSymbol::USDJ))), + Some(b"LP long string name, long string name, long string name, long string name, long string name - Setheum US Dollar"[..32].to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::DexShare(DexShare::Erc20(erc20_address()), DexShare::Erc20(erc20_address()))), + Some(b"LP long string name, long string name, long string name, long string name, long string name - long string name, long string name, long string name, long string name, long string name"[..32].to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::DexShare(DexShare::Token(TokenSymbol::DNAR), DexShare::Erc20(erc20_address_not_exists()))), + None + ); + + assert_eq!( + EvmCurrencyIdMapping::::name(CurrencyId::DexShare(DexShare::Erc20(erc20_address()), DexShare::Erc20(erc20_address_not_exists()))), + None + ); + }); +} + +#[test] +fn symbol_works() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::Token(TokenSymbol::DNAR)), + Some(b"DNAR".to_vec()) + ); + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::Erc20(erc20_address())), + Some(b"TestToken".to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::Erc20(erc20_address_not_exists())), + None + ); + + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::DNAR), + DexShare::Token(TokenSymbol::USDJ) + )), + Some(b"LP_DNAR_USDJ".to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Token(TokenSymbol::USDJ) + )), + Some(b"LP_TestToken_USDJ".to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address()) + )), + Some(b"LP_TestToken_TestToken".to_vec()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::DNAR), + DexShare::Erc20(erc20_address_not_exists()) + )), + None + ); + + assert_eq!( + EvmCurrencyIdMapping::::symbol(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address_not_exists()) + )), + None + ); + }); +} + +#[test] +fn decimals_works() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + assert_eq!( + EvmCurrencyIdMapping::::decimals(CurrencyId::Token(TokenSymbol::DNAR)), + Some(12) + ); + assert_eq!( + EvmCurrencyIdMapping::::decimals(CurrencyId::Erc20(erc20_address())), + Some(17) + ); + + assert_eq!( + EvmCurrencyIdMapping::::decimals(CurrencyId::Erc20(erc20_address_not_exists())), + None + ); + + assert_eq!( + EvmCurrencyIdMapping::::decimals(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::DNAR), + DexShare::Token(TokenSymbol::USDJ) + )), + Some(12) + ); + + assert_eq!( + EvmCurrencyIdMapping::::decimals(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Token(TokenSymbol::USDJ) + )), + Some(17) + ); + + assert_eq!( + EvmCurrencyIdMapping::::decimals(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address()) + )), + Some(17) + ); + + assert_eq!( + EvmCurrencyIdMapping::::decimals(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address_not_exists()) + )), + None + ); + }); +} + +#[test] +fn encode_evm_address_works() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::Token(TokenSymbol::DNAR)), + H160::from_str("0x0000000000000000000000000000000001000000").ok() + ); + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::Erc20(erc20_address())), + Some(erc20_address()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::Erc20(erc20_address_not_exists())), + Some(erc20_address_not_exists()) + ); + + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::DNAR), + DexShare::Token(TokenSymbol::USDJ) + )), + H160::from_str("0x0000000000000000000000010000000000000001").ok() + ); + + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Token(TokenSymbol::USDJ) + )), + H160::from_str("0x0000000000000000000000010200000000000001").ok() + ); + + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::USDJ), + DexShare::Erc20(erc20_address()) + )), + H160::from_str("0x0000000000000000000000010000000102000000").ok() + ); + + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address()) + )), + H160::from_str("0x0000000000000000000000010200000002000000").ok() + ); + + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::DNAR), + DexShare::Erc20(erc20_address_not_exists()) + )), + None + ); + + assert_eq!( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address_not_exists()) + )), + None + ); + }); +} + +#[test] +fn decode_evm_address_works() { + ExtBuilder::default() + .balances(vec![(alice(), 1_000_000_000_000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_ok!(with_transaction_result(|| -> DispatchResult { + EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address()) + })); + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::Token(TokenSymbol::DNAR)).unwrap() + ), + Some(CurrencyId::Token(TokenSymbol::DNAR)) + ); + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::Erc20(erc20_address())).unwrap() + ), + Some(CurrencyId::Erc20(erc20_address())) + ); + + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::Erc20(erc20_address_not_exists())) + .unwrap() + ), + None, + ); + + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::DNAR), + DexShare::Token(TokenSymbol::USDJ) + )) + .unwrap(), + ), + Some(CurrencyId::DexShare( + DexShare::Token(TokenSymbol::DNAR), + DexShare::Token(TokenSymbol::USDJ) + )) + ); + + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Token(TokenSymbol::USDJ) + )) + .unwrap() + ), + Some(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Token(TokenSymbol::USDJ) + )) + ); + + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + EvmCurrencyIdMapping::::encode_evm_address(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address()) + )) + .unwrap() + ), + Some(CurrencyId::DexShare( + DexShare::Erc20(erc20_address()), + DexShare::Erc20(erc20_address()) + )) + ); + + // decode invalid evm address + // CurrencyId::DexShare(DexShare::Token(TokenSymbol::DNAR), + // DexShare::Erc20(erc20_address_not_exists())) + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + H160::from_str("0x0000000000000000000000010000000002000001").unwrap() + ), + None + ); + + // decode invalid evm address + // CurrencyId::DexShare(DexShare::Erc20(erc20_address()), + // DexShare::Erc20(erc20_address_not_exists())) + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address( + H160::from_str("0x0000000000000000000000010200000002000001").unwrap() + ), + None + ); + + // decode invalid evm address + // Allow non-system contracts + let non_system_contracts = H160::from_str("0x1000000000000000000000000000000000000000").unwrap(); + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address(non_system_contracts), + None + ); + + let id = Into::::into(DexShare::Erc20(non_system_contracts)); + CurrencyIdMap::::mutate(id, |maybe_erc20_info| { + let info = Erc20Info { + address: non_system_contracts, + name: b"Test".to_vec(), + symbol: b"T".to_vec(), + decimals: 17, + }; + + *maybe_erc20_info = Some(info); + }); + assert_eq!( + EvmCurrencyIdMapping::::decode_evm_address(non_system_contracts), + Some(CurrencyId::Erc20(non_system_contracts)) + ); + }); +} From ebc8b8a8a2bed817932e63b078e448e49ef9cf89 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 05:08:17 +0800 Subject: [PATCH 14/83] Update NFT --- lib-serml/nft/src/lib.rs | 157 ++++++++++++++++++++++++++------------- 1 file changed, 104 insertions(+), 53 deletions(-) diff --git a/lib-serml/nft/src/lib.rs b/lib-serml/nft/src/lib.rs index d5ab6f0a4..7f2ea43c3 100644 --- a/lib-serml/nft/src/lib.rs +++ b/lib-serml/nft/src/lib.rs @@ -24,18 +24,23 @@ use enumflags2::BitFlags; use frame_support::{ pallet_prelude::*, - traits::{Currency, ExistenceRequirement::KeepAlive}, + traits::{ + Currency, + ExistenceRequirement::{AllowDeath, KeepAlive}, + ReservableCurrency, + }, transactional, PalletId, }; use frame_system::pallet_prelude::*; -use orml_traits::{BasicCurrency, BasicReservableCurrency, NFT}; -use primitives::{Balance, NFTBalance}; +use orml_traits::NFT; +use primitives::NFTBalance; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; use sp_runtime::{ - traits::{AccountIdConversion, StaticLookup, Zero}, + traits::{AccountIdConversion, Hash, Saturating, StaticLookup, Zero}, DispatchResult, RuntimeDebug, }; +use sp_std::vec::Vec; pub mod benchmarking; mod mock; @@ -45,7 +50,7 @@ pub mod weights; pub use module::*; pub use weights::WeightInfo; -pub type CID = sp_std::vec::Vec; +pub type CID = Vec; #[repr(u8)] #[derive(Encode, Decode, Clone, Copy, BitFlags, RuntimeDebug, PartialEq, Eq)] @@ -77,7 +82,7 @@ impl Decode for Properties { #[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct ClassData { +pub struct ClassData { /// The minimum balance to create class pub deposit: Balance, /// Property of token @@ -86,13 +91,15 @@ pub struct ClassData { #[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct TokenData { +pub struct TokenData { /// The minimum balance to create token pub deposit: Balance, } pub type TokenIdOf = ::TokenId; pub type ClassIdOf = ::ClassId; +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; #[frame_support::pallet] pub mod module { @@ -100,26 +107,24 @@ pub mod module { #[pallet::config] pub trait Config: - frame_system::Config + orml_nft::Config + pallet_proxy::Config + frame_system::Config + + orml_nft::Config>, TokenData = TokenData>> + + pallet_proxy::Config { type Event: From> + IsType<::Event>; /// The minimum balance to create class #[pallet::constant] - type CreateClassDeposit: Get; + type CreateClassDeposit: Get>; /// The minimum balance to create token #[pallet::constant] - type CreateTokenDeposit: Get; + type CreateTokenDeposit: Get>; /// The NFT's module id #[pallet::constant] type PalletId: Get; - /// Currency type for reserve/unreserve balance to - /// create_class/mint/burn/destroy_class - type Currency: BasicReservableCurrency; - /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; } @@ -154,8 +159,10 @@ pub mod module { TransferredToken(T::AccountId, T::AccountId, ClassIdOf, TokenIdOf), /// Burned NFT token. \[owner, class_id, token_id\] BurnedToken(T::AccountId, ClassIdOf, TokenIdOf), - /// Destroyed NFT class. \[owner, class_id, dest\] - DestroyedClass(T::AccountId, ClassIdOf, T::AccountId), + /// Burned NFT token with remark. \[owner, class_id, token_id, remark_hash\] + BurnedTokenWithRemark(T::AccountId, ClassIdOf, TokenIdOf, T::Hash), + /// Destroyed NFT class. \[owner, class_id\] + DestroyedClass(T::AccountId, ClassIdOf), } #[pallet::pallet] @@ -176,19 +183,23 @@ pub mod module { let who = ensure_signed(origin)?; let next_id = orml_nft::Pallet::::next_class_id(); let owner: T::AccountId = T::PalletId::get().into_sub_account(next_id); - let deposit = T::CreateClassDeposit::get(); + let class_deposit = T::CreateClassDeposit::get(); + + let proxy_deposit = >::deposit(1u32); + let total_deposit = proxy_deposit.saturating_add(class_deposit); - // it depends https://github.com/paritytech/substrate/issues/7563 - ::Currency::transfer(&who, &owner, deposit)?; - // Currently, use `free_balance(owner)` instead of `deposit`. - ::Currency::reserve(&owner, ::Currency::free_balance(&owner))?; + // ensure enough token for proxy deposit + class deposit + T::Currency::transfer(&who, &owner, total_deposit, KeepAlive)?; + + T::Currency::reserve(&owner, class_deposit)?; // owner add proxy delegate to origin - let proxy_deposit = >::deposit(1u32); - ::Currency::transfer(&who, &owner, proxy_deposit, KeepAlive)?; >::add_proxy_delegate(&owner, who, Default::default(), Zero::zero())?; - let data = ClassData { deposit, properties }; + let data = ClassData { + deposit: class_deposit, + properties, + }; orml_nft::Pallet::::create_class(&owner, metadata, data)?; Self::deposit_event(Event::CreatedClass(owner, next_id)); @@ -216,8 +227,12 @@ pub mod module { let class_info = orml_nft::Pallet::::classes(class_id).ok_or(Error::::ClassIdNotFound)?; ensure!(who == class_info.owner, Error::::NoPermission); let deposit = T::CreateTokenDeposit::get(); - let total_deposit = deposit * (quantity as u128); - ::Currency::reserve(&class_info.owner, total_deposit)?; + let total_deposit = deposit.saturating_mul(quantity.into()); + + // `repatriate_reserved` will check `to` account exist and may return + // `DeadAccount`. + T::Currency::transfer(&who, &to, total_deposit, KeepAlive)?; + T::Currency::reserve(&to, total_deposit)?; let data = TokenData { deposit }; for _ in 0..quantity { @@ -252,32 +267,34 @@ pub mod module { #[transactional] pub fn burn(origin: OriginFor, token: (ClassIdOf, TokenIdOf)) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - let class_info = orml_nft::Pallet::::classes(token.0).ok_or(Error::::ClassIdNotFound)?; - let data = class_info.data; - ensure!( - data.properties.0.contains(ClassProperty::Burnable), - Error::::NonBurnable - ); - - let token_info = orml_nft::Pallet::::tokens(token.0, token.1).ok_or(Error::::TokenIdNotFound)?; - ensure!(who == token_info.owner, Error::::NoPermission); - - orml_nft::Pallet::::burn(&who, token)?; - let owner: T::AccountId = T::PalletId::get().into_sub_account(token.0); - let data = token_info.data; - // `repatriate_reserved` will check `to` account exist and return `DeadAccount`. - // `transfer` not do this check. - ::Currency::unreserve(&owner, data.deposit); - ::Currency::transfer(&owner, &who, data.deposit)?; - + Self::do_burn(&who, token)?; Self::deposit_event(Event::BurnedToken(who, token.0, token.1)); Ok(().into()) } - /// Destroy NFT class + /// Burn NFT token + /// + /// - `token`: (class_id, token_id) + /// - `remark`: Vec + #[pallet::weight(::WeightInfo::burn_with_remark(remark.len() as u32))] + #[transactional] + pub fn burn_with_remark( + origin: OriginFor, + token: (ClassIdOf, TokenIdOf), + remark: Vec, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + Self::do_burn(&who, token)?; + let hash = T::Hashing::hash(&remark[..]); + Self::deposit_event(Event::BurnedTokenWithRemark(who, token.0, token.1, hash)); + Ok(().into()) + } + + /// Destroy NFT class, remove dest from proxy, and send all the free + /// balance to dest /// - /// - `class_id`: destroy class id - /// - `dest`: transfer reserve balance from sub_account to dest + /// - `class_id`: The class ID to destroy + /// - `dest`: The proxy account that will receive free balance #[pallet::weight(::WeightInfo::destroy_class())] #[transactional] pub fn destroy_class( @@ -294,13 +311,25 @@ pub mod module { Error::::CannotDestroyClass ); - let owner: T::AccountId = T::PalletId::get().into_sub_account(class_id); let data = class_info.data; - // `repatriate_reserved` will check `to` account exist and return `DeadAccount`. - // `transfer` not do this check. - ::Currency::unreserve(&owner, data.deposit); - ::Currency::transfer(&owner, &dest, data.deposit)?; + T::Currency::unreserve(&who, data.deposit); + + orml_nft::Pallet::::destroy_class(&who, class_id)?; + + // this should unresere proxy deposit + pallet_proxy::Pallet::::remove_proxy_delegate(&who, dest.clone(), Default::default(), Zero::zero())?; + + T::Currency::transfer(&who, &dest, T::Currency::free_balance(&who), AllowDeath)?; + + Self::deposit_event(Event::DestroyedClass(who, class_id)); + Ok(().into()) + } + } +} + +impl Pallet { + /// Ensured atomic. #[transactional] fn do_transfer(from: &T::AccountId, to: &T::AccountId, token: (ClassIdOf, TokenIdOf)) -> DispatchResult { let class_info = orml_nft::Pallet::::classes(token.0).ok_or(Error::::ClassIdNotFound)?; @@ -311,13 +340,35 @@ pub mod module { ); let token_info = orml_nft::Pallet::::tokens(token.0, token.1).ok_or(Error::::TokenIdNotFound)?; - ensure!(*from == token_info.owner, Error::::NoPermission); orml_nft::Pallet::::transfer(from, to, token)?; + T::Currency::unreserve(&from, token_info.data.deposit); + T::Currency::transfer(&from, &to, token_info.data.deposit, AllowDeath)?; + T::Currency::reserve(&to, token_info.data.deposit)?; + Self::deposit_event(Event::TransferredToken(from.clone(), to.clone(), token.0, token.1)); Ok(()) } + + /// Ensured atomic. + #[transactional] + fn do_burn(who: &T::AccountId, token: (ClassIdOf, TokenIdOf)) -> DispatchResult { + let class_info = orml_nft::Pallet::::classes(token.0).ok_or(Error::::ClassIdNotFound)?; + let data = class_info.data; + ensure!( + data.properties.0.contains(ClassProperty::Burnable), + Error::::NonBurnable + ); + + let token_info = orml_nft::Pallet::::tokens(token.0, token.1).ok_or(Error::::TokenIdNotFound)?; + ensure!(*who == token_info.owner, Error::::NoPermission); + + orml_nft::Pallet::::burn(&who, token)?; + + T::Currency::unreserve(&who, token_info.data.deposit); + Ok(()) + } } impl NFT for Pallet { From 1c3e76c8e03cde914e4e9b5060358e2e54a8cd0a Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 05:19:09 +0800 Subject: [PATCH 15/83] update setheum-nft --- lib-serml/nft/src/mock.rs | 37 ++++----- lib-serml/nft/src/tests.rs | 151 ++++++++++++++++++++++++++++------- lib-serml/nft/src/weights.rs | 19 ++++- 3 files changed, 156 insertions(+), 51 deletions(-) diff --git a/lib-serml/nft/src/mock.rs b/lib-serml/nft/src/mock.rs index d89b8cbbe..844846dcf 100644 --- a/lib-serml/nft/src/mock.rs +++ b/lib-serml/nft/src/mock.rs @@ -20,21 +20,21 @@ use super::*; -use crate as setrheum_nft; +use crate as nft; use codec::{Decode, Encode}; use frame_support::{ construct_runtime, parameter_types, traits::{Filter, InstanceFilter}, - RuntimeDebug, PalletId + RuntimeDebug, }; use orml_traits::parameter_type_with_key; -use primitives::{mocks::MockAddressMapping, Amount, BlockNumber, CurrencyId, TokenSymbol}; +use primitives::{Amount, Balance, BlockNumber, CurrencyId, TokenSymbol}; use sp_core::{crypto::AccountId32, H256}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, - DispatchError, DispatchResult, }; +use support::mocks::MockAddressMapping; parameter_types! { pub const BlockHashCount: u64 = 250; @@ -65,6 +65,7 @@ impl frame_system::Config for Runtime { type OnKilledAccount = (); type SystemWeightInfo = (); type SS58Prefix = (); + type OnSetCode = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -91,7 +92,7 @@ parameter_types! { pub const AnnouncementDepositBase: u64 = 1; pub const AnnouncementDepositFactor: u64 = 1; } -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)] pub enum ProxyType { Any, JustTransfer, @@ -171,32 +172,33 @@ impl setheum_currencies::Config for Runtime { type NativeCurrency = NativeCurrency; type GetNativeCurrencyId = GetNativeCurrencyId; type WeightInfo = (); + type AddressMapping = MockAddressMapping; + type EVMBridge = (); } parameter_types! { pub const CreateClassDeposit: Balance = 200; pub const CreateTokenDeposit: Balance = 100; - pub const NftPalletId: PalletId = PalletId(*b"dnr/sNFT"); + pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } impl Config for Runtime { type Event = Event; type CreateClassDeposit = CreateClassDeposit; type CreateTokenDeposit = CreateTokenDeposit; type PalletId = NftPalletId; - type Currency = NativeCurrency; type WeightInfo = (); } - parameter_types! { - pub const MaxClassMetadata: u32 = 1024; - pub const MaxTokenMetadata: u32 = 1024; - } +parameter_types! { + pub const MaxClassMetadata: u32 = 1024; + pub const MaxTokenMetadata: u32 = 1024; +} impl orml_nft::Config for Runtime { type ClassId = u32; type TokenId = u64; - type ClassData = ClassData; - type TokenData = TokenData; + type ClassData = ClassData; + type TokenData = TokenData; type MaxClassMetadata = MaxClassMetadata; type MaxTokenMetadata = MaxTokenMetadata; } @@ -213,7 +215,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system::{Pallet, Call, Config, Storage, Event}, - SetheumNFT: setheum_nft::{Pallet, Call, Event}, + SetheumNFT: nft::{Pallet, Call, Event}, OrmlNFT: orml_nft::{Pallet, Storage, Config}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Proxy: pallet_proxy::{Pallet, Call, Storage, Event}, @@ -254,10 +256,3 @@ impl ExtBuilder { ext } } - -pub fn last_event() -> Event { - frame_system::Pallet::::events() - .pop() - .expect("Event expected") - .event -} diff --git a/lib-serml/nft/src/tests.rs b/lib-serml/nft/src/tests.rs index c1457d8ea..30dafff0f 100644 --- a/lib-serml/nft/src/tests.rs +++ b/lib-serml/nft/src/tests.rs @@ -21,15 +21,20 @@ #![cfg(test)] use super::*; +use frame_support::traits::Currency; use frame_support::{assert_noop, assert_ok}; use mock::{Event, *}; +use orml_nft::TokenInfo; +use primitives::Balance; +use sp_runtime::{traits::BlakeTwo256, ArithmeticError}; +use sp_std::convert::TryInto; fn free_balance(who: &AccountId) -> Balance { - ::Currency::free_balance(who) + ::Currency::free_balance(who) } fn reserved_balance(who: &AccountId) -> Balance { - ::Currency::reserved_balance(who) + ::Currency::reserved_balance(who) } fn class_id_account() -> AccountId { @@ -44,8 +49,7 @@ fn create_class_should_work() { vec![1], Default::default() )); - System::assert_last_event(Event::setheum_nft(crate::Event::CreatedClass(class_id_account(), CLASS_ID))); - + System::assert_last_event(Event::nft(crate::Event::CreatedClass(class_id_account(), CLASS_ID))); assert_eq!( reserved_balance(&class_id_account()), ::CreateClassDeposit::get() + Proxy::deposit(1u32) @@ -75,8 +79,7 @@ fn mint_should_work() { vec![1], Properties(ClassProperty::Transferable | ClassProperty::Burnable) )); - System::assert_last_event(Event::setheum_nft(crate::Event::CreatedClass(class_id_account(), CLASS_ID))); - + System::assert_last_event(Event::nft(crate::Event::CreatedClass(class_id_account(), CLASS_ID))); assert_eq!( Balances::deposit_into_existing(&class_id_account(), 2 * ::CreateTokenDeposit::get()) .is_ok(), @@ -86,16 +89,42 @@ fn mint_should_work() { Origin::signed(class_id_account()), BOB, CLASS_ID, - vec![1], + vec![2], 2 )); - System::assert_last_event(Event::setheum_nft(crate::Event::MintedToken(class_id_account(), BOB, CLASS_ID, 2))); - + System::assert_last_event(Event::nft(crate::Event::MintedToken( + class_id_account(), + BOB, + CLASS_ID, + 2, + ))); assert_eq!( reserved_balance(&class_id_account()), - ::CreateClassDeposit::get() - + 2 * ::CreateTokenDeposit::get() - + Proxy::deposit(1u32) + ::CreateClassDeposit::get() + Proxy::deposit(1u32) + ); + assert_eq!( + reserved_balance(&BOB), + 2 * ::CreateTokenDeposit::get() + ); + assert_eq!( + orml_nft::Pallet::::tokens(0, 0).unwrap(), + TokenInfo { + metadata: vec![2].try_into().unwrap(), + owner: BOB, + data: TokenData { + deposit: ::CreateTokenDeposit::get() + } + } + ); + assert_eq!( + orml_nft::Pallet::::tokens(0, 1).unwrap(), + TokenInfo { + metadata: vec![2].try_into().unwrap(), + owner: BOB, + data: TokenData { + deposit: ::CreateTokenDeposit::get() + } + } ); }); } @@ -159,11 +188,33 @@ fn transfer_should_work() { 2 )); + assert_eq!( + reserved_balance(&BOB), + 2 * ::CreateTokenDeposit::get() + ); + assert_ok!(SetheumNFT::transfer(Origin::signed(BOB), ALICE, (CLASS_ID, TOKEN_ID))); - System::assert_last_event(Event::setheum_nft(crate::Event::TransferredToken(BOB, ALICE, CLASS_ID, TOKEN_ID))); + System::assert_last_event(Event::nft(crate::Event::TransferredToken( + BOB, ALICE, CLASS_ID, TOKEN_ID, + ))); + assert_eq!( + reserved_balance(&BOB), + 1 * ::CreateTokenDeposit::get() + ); + assert_eq!( + reserved_balance(&ALICE), + 1 * ::CreateTokenDeposit::get() + ); assert_ok!(SetheumNFT::transfer(Origin::signed(ALICE), BOB, (CLASS_ID, TOKEN_ID))); - System::assert_last_event(Event::setheum_nft(crate::Event::TransferredToken(ALICE, BOB, CLASS_ID, TOKEN_ID))); + System::assert_last_event(Event::nft(crate::Event::TransferredToken( + ALICE, BOB, CLASS_ID, TOKEN_ID, + ))); + assert_eq!( + reserved_balance(&BOB), + 2 * ::CreateTokenDeposit::get() + ); + assert_eq!(reserved_balance(&ALICE), 0); }); } @@ -197,7 +248,7 @@ fn transfer_should_fail() { ); assert_noop!( SetheumNFT::transfer(Origin::signed(ALICE), BOB, (CLASS_ID, TOKEN_ID)), - Error::::NoPermission + orml_nft::Error::::NoPermission ); }); @@ -247,8 +298,7 @@ fn burn_should_work() { 1 )); assert_ok!(SetheumNFT::burn(Origin::signed(BOB), (CLASS_ID, TOKEN_ID))); - System::assert_last_event(Event::setheum_nft(crate::Event::BurnedToken(BOB, CLASS_ID, TOKEN_ID))); - + System::assert_last_event(Event::nft(crate::Event::BurnedToken(BOB, CLASS_ID, TOKEN_ID))); assert_eq!( reserved_balance(&class_id_account()), ::CreateClassDeposit::get() + Proxy::deposit(1u32) @@ -291,7 +341,7 @@ fn burn_should_fail() { }); assert_noop!( SetheumNFT::burn(Origin::signed(BOB), (CLASS_ID, TOKEN_ID)), - orml_nft::Error::::NumOverflow + ArithmeticError::Overflow, ); }); @@ -321,7 +371,7 @@ fn burn_should_fail() { } #[test] -fn destroy_class_should_work() { +fn burn_with_remark_should_work() { ExtBuilder::default().build().execute_with(|| { assert_ok!(SetheumNFT::create_class( Origin::signed(ALICE), @@ -332,7 +382,48 @@ fn destroy_class_should_work() { Balances::deposit_into_existing(&class_id_account(), 1 * ::CreateTokenDeposit::get()) .is_ok(), true - ); // + 100 + ); + assert_ok!(SetheumNFT::mint( + Origin::signed(class_id_account()), + BOB, + CLASS_ID, + vec![1], + 1 + )); + + let remark = "remark info".as_bytes().to_vec(); + let remark_hash = BlakeTwo256::hash(&remark[..]); + assert_ok!(SetheumNFT::burn_with_remark( + Origin::signed(BOB), + (CLASS_ID, TOKEN_ID), + remark + )); + System::assert_last_event(Event::nft(crate::Event::BurnedTokenWithRemark( + BOB, + CLASS_ID, + TOKEN_ID, + remark_hash, + ))); + + assert_eq!( + reserved_balance(&class_id_account()), + ::CreateClassDeposit::get() + Proxy::deposit(1u32) + ); + }); +} + +#[test] +fn destroy_class_should_work() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(SetheumNFT::create_class( + Origin::signed(ALICE), + vec![1], + Properties(ClassProperty::Transferable | ClassProperty::Burnable) + )); + assert_ok!(Balances::deposit_into_existing( + &class_id_account(), + 1 * ::CreateTokenDeposit::get() + )); // + 100 assert_ok!(SetheumNFT::mint( Origin::signed(class_id_account()), BOB, @@ -344,13 +435,13 @@ fn destroy_class_should_work() { assert_ok!(SetheumNFT::destroy_class( Origin::signed(class_id_account()), CLASS_ID, - BOB + ALICE )); - System::assert_last_event(Event::setheum_nft(crate::Event::DestroyedClass(class_id_account(), CLASS_ID, BOB))); - - assert_eq!(reserved_balance(&class_id_account()), 2); - assert_eq!(free_balance(&ALICE), 99700 + 100 - 2); - assert_eq!(free_balance(&BOB), 300); + System::assert_last_event(Event::nft(crate::Event::DestroyedClass(class_id_account(), CLASS_ID))); + assert_eq!(free_balance(&class_id_account()), 0); + assert_eq!(reserved_balance(&class_id_account()), 0); + assert_eq!(free_balance(&ALICE), 100000); + assert_eq!(free_balance(&BOB), ::CreateTokenDeposit::get()); }); } @@ -390,10 +481,16 @@ fn destroy_class_should_fail() { ); assert_ok!(SetheumNFT::burn(Origin::signed(BOB), (CLASS_ID, TOKEN_ID))); + + assert_noop!( + SetheumNFT::destroy_class(Origin::signed(class_id_account()), CLASS_ID, BOB), + pallet_proxy::Error::::NotFound + ); + assert_ok!(SetheumNFT::destroy_class( Origin::signed(class_id_account()), CLASS_ID, - BOB + ALICE )); }); } diff --git a/lib-serml/nft/src/weights.rs b/lib-serml/nft/src/weights.rs index 8c7a9a899..c80578be5 100644 --- a/lib-serml/nft/src/weights.rs +++ b/lib-serml/nft/src/weights.rs @@ -45,17 +45,18 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for setheum_nft. +/// Weight functions needed for module_nft. pub trait WeightInfo { fn create_class() -> Weight; fn mint(i: u32, ) -> Weight; fn transfer() -> Weight; fn burn() -> Weight; + fn burn_with_remark(b: u32, ) -> Weight; fn destroy_class() -> Weight; } -/// Weights for setheum_nft using the Setheum node and recommended hardware. -pub struct SetheumWeight(_); +/// Weights for module_nft using the Setheum node and recommended hardware. +pub struct SetheumWeight(PhantomData); impl WeightInfo for SetheumWeight { fn create_class() -> Weight { (200_357_000 as Weight) @@ -80,6 +81,12 @@ impl WeightInfo for SetheumWeight { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } + fn burn_with_remark(b: u32, ) -> Weight { + (154_177_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + .saturating_add((1_000 as Weight).saturating_mul(b as Weight)) + } fn destroy_class() -> Weight { (137_255_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) @@ -112,6 +119,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } + fn burn_with_remark(b: u32, ) -> Weight { + (154_177_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + .saturating_add((1_000 as Weight).saturating_mul(b as Weight)) + } fn destroy_class() -> Weight { (137_255_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) From b5b6bf987a93f8c5aa97298b00bb273b3ef6a5e1 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 05:24:35 +0800 Subject: [PATCH 16/83] update NFT Benchmarking --- lib-serml/nft/src/benchmarking.rs | 115 ++++++++++++++---------------- 1 file changed, 52 insertions(+), 63 deletions(-) diff --git a/lib-serml/nft/src/benchmarking.rs b/lib-serml/nft/src/benchmarking.rs index 11372da7b..dc0bb843f 100644 --- a/lib-serml/nft/src/benchmarking.rs +++ b/lib-serml/nft/src/benchmarking.rs @@ -24,18 +24,15 @@ use sp_std::prelude::*; use sp_std::vec; use frame_benchmarking::{account, benchmarks}; -use frame_support::traits::Get; +use frame_support::{traits::Get, weights::DispatchClass}; use frame_system::RawOrigin; use sp_runtime::traits::{AccountIdConversion, StaticLookup, UniqueSaturatedInto}; pub use crate::*; -use orml_traits::BasicCurrencyExtended; use primitives::Balance; pub struct Module(crate::Pallet); -pub trait Config: crate::Config + orml_nft::Config + pallet_proxy::Config + setheum_currencies::Config {} - const SEED: u32 = 0; fn dollar(d: u32) -> Balance { @@ -49,7 +46,7 @@ benchmarks! { let caller: T::AccountId = account("caller", 0, SEED); let base_currency_amount = dollar(1000); - ::NativeCurrency::update_balance(&caller, base_currency_amount.unique_saturated_into())?; + T::Currency::make_free_balance_be(&caller, base_currency_amount.unique_saturated_into()); }: _(RawOrigin::Signed(caller), vec![1], Properties(ClassProperty::Transferable | ClassProperty::Burnable)) // mint NFT token @@ -61,12 +58,12 @@ benchmarks! { let to_lookup = T::Lookup::unlookup(to); let base_currency_amount = dollar(1000); - ::NativeCurrency::update_balance(&caller, base_currency_amount.unique_saturated_into())?; + T::Currency::make_free_balance_be(&caller, base_currency_amount.unique_saturated_into()); - let setheum_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); + let module_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); crate::Pallet::::create_class(RawOrigin::Signed(caller).into(), vec![1], Properties(ClassProperty::Transferable | ClassProperty::Burnable))?; - ::NativeCurrency::update_balance(&setheum_account, base_currency_amount.unique_saturated_into())?; - }: _(RawOrigin::Signed(setheum_account), to_lookup, 0u32.into(), vec![1], i) + T::Currency::make_free_balance_be(&module_account, base_currency_amount.unique_saturated_into()); + }: _(RawOrigin::Signed(module_account), to_lookup, 0u32.into(), vec![1], i) // transfer NFT token to another account transfer { @@ -76,12 +73,12 @@ benchmarks! { let to_lookup = T::Lookup::unlookup(to.clone()); let base_currency_amount = dollar(1000); - ::NativeCurrency::update_balance(&caller, base_currency_amount.unique_saturated_into())?; + T::Currency::make_free_balance_be(&caller, base_currency_amount.unique_saturated_into()); - let setheum_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); + let module_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); crate::Pallet::::create_class(RawOrigin::Signed(caller).into(), vec![1], Properties(ClassProperty::Transferable | ClassProperty::Burnable))?; - ::NativeCurrency::update_balance(&setheum_account, base_currency_amount.unique_saturated_into())?; - crate::Pallet::::mint(RawOrigin::Signed(setheum_account).into(), to_lookup, 0u32.into(), vec![1], 1)?; + T::Currency::make_free_balance_be(&module_account, base_currency_amount.unique_saturated_into()); + crate::Pallet::::mint(RawOrigin::Signed(module_account).into(), to_lookup, 0u32.into(), vec![1], 1)?; }: _(RawOrigin::Signed(to), caller_lookup, (0u32.into(), 0u32.into())) // burn NFT token @@ -91,47 +88,62 @@ benchmarks! { let to_lookup = T::Lookup::unlookup(to.clone()); let base_currency_amount = dollar(1000); - ::NativeCurrency::update_balance(&caller, base_currency_amount.unique_saturated_into())?; + T::Currency::make_free_balance_be(&caller, base_currency_amount.unique_saturated_into()); - let setheum_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); + let module_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); crate::Pallet::::create_class(RawOrigin::Signed(caller).into(), vec![1], Properties(ClassProperty::Transferable | ClassProperty::Burnable))?; - ::NativeCurrency::update_balance(&setheum_account, base_currency_amount.unique_saturated_into())?; - crate::Pallet::::mint(RawOrigin::Signed(setheum_account).into(), to_lookup, 0u32.into(), vec![1], 1)?; + T::Currency::make_free_balance_be(&module_account, base_currency_amount.unique_saturated_into()); + crate::Pallet::::mint(RawOrigin::Signed(module_account).into(), to_lookup, 0u32.into(), vec![1], 1)?; }: _(RawOrigin::Signed(to), (0u32.into(), 0u32.into())) + // burn NFT token with remark + burn_with_remark { + let b in 0 .. *T::BlockLength::get().max.get(DispatchClass::Normal) as u32; + let remark_message = vec![1; b as usize]; + let caller: T::AccountId = account("caller", 0, SEED); + let to: T::AccountId = account("to", 0, SEED); + let to_lookup = T::Lookup::unlookup(to.clone()); + + let base_currency_amount = dollar(1000); + T::Currency::make_free_balance_be(&caller, base_currency_amount.unique_saturated_into()); + + let module_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); + crate::Pallet::::create_class(RawOrigin::Signed(caller).into(), vec![1], Properties(ClassProperty::Transferable | ClassProperty::Burnable))?; + T::Currency::make_free_balance_be(&module_account, base_currency_amount.unique_saturated_into()); + crate::Pallet::::mint(RawOrigin::Signed(module_account).into(), to_lookup, 0u32.into(), vec![1], 1)?; + }: _(RawOrigin::Signed(to), (0u32.into(), 0u32.into()), remark_message) + // destroy NFT class destroy_class { let caller: T::AccountId = account("caller", 0, SEED); - let to: T::AccountId = account("to", 0, SEED); - let to_lookup = T::Lookup::unlookup(to); + let caller_lookup = T::Lookup::unlookup(caller.clone()); let base_currency_amount = dollar(1000); - ::NativeCurrency::update_balance(&caller, base_currency_amount.unique_saturated_into())?; + T::Currency::make_free_balance_be(&caller, base_currency_amount.unique_saturated_into()); - let setheum_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); + let module_account: T::AccountId = T::PalletId::get().into_sub_account(orml_nft::Pallet::::next_class_id()); crate::Pallet::::create_class(RawOrigin::Signed(caller).into(), vec![1], Properties(ClassProperty::Transferable | ClassProperty::Burnable))?; - }: _(RawOrigin::Signed(setheum_account), 0u32.into(), to_lookup) + }: _(RawOrigin::Signed(module_account), 0u32.into(), caller_lookup) } #[cfg(test)] mod mock { use super::*; + use crate as nft; use codec::{Decode, Encode}; use frame_support::{ parameter_types, traits::{Filter, InstanceFilter}, weights::Weight, - RuntimeDebug, + PalletId, RuntimeDebug, }; - use orml_traits::parameter_type_with_key; - use primitives::{mocks::MockAddressMapping, Amount, BlockNumber, CurrencyId}; use sp_core::{crypto::AccountId32, H256}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, - DispatchError, DispatchResult, PalletId, Perbill, + Perbill, }; parameter_types! { @@ -166,6 +178,7 @@ mod mock { type OnKilledAccount = (); type SystemWeightInfo = (); type SS58Prefix = (); + type OnSetCode = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -192,7 +205,7 @@ mod mock { pub const AnnouncementDepositBase: u64 = 1; pub const AnnouncementDepositFactor: u64 = 1; } - #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)] pub enum ProxyType { Any, JustTransfer, @@ -241,43 +254,16 @@ mod mock { type AnnouncementDepositFactor = AnnouncementDepositFactor; } - pub type NativeCurrency = setheum_currencies::BasicCurrencyAdapter; - - parameter_type_with_key! { - pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { - Default::default() - }; - } - - impl orml_tokens::Config for Runtime { - type Event = (); - type Balance = Balance; - type Amount = Amount; - type CurrencyId = CurrencyId; - type WeightInfo = (); - type ExistentialDeposits = ExistentialDeposits; - type OnDust = (); - type MaxLocks = (); - } - - impl setheum_currencies::Config for Runtime { - type Event = (); - type MultiCurrency = Tokens; - type NativeCurrency = NativeCurrency; - type WeightInfo = (); - } - parameter_types! { pub const CreateClassDeposit: Balance = 200; pub const CreateTokenDeposit: Balance = 100; - pub const NftPalletId: PalletId = PalletId(*b"dnr/sNFT"); + pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } impl crate::Config for Runtime { type Event = (); type CreateClassDeposit = CreateClassDeposit; type CreateTokenDeposit = CreateTokenDeposit; type PalletId = NftPalletId; - type Currency = NativeCurrency; type WeightInfo = (); } @@ -289,8 +275,8 @@ mod mock { impl orml_nft::Config for Runtime { type ClassId = u32; type TokenId = u64; - type ClassData = ClassData; - type TokenData = TokenData; + type ClassData = ClassData; + type TokenData = TokenData; type MaxClassMetadata = MaxClassMetadata; type MaxTokenMetadata = MaxTokenMetadata; } @@ -307,18 +293,14 @@ mod mock { System: frame_system::{Pallet, Call, Config, Storage, Event}, Utility: pallet_utility::{Pallet, Call, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Currencies: setheum_currencies::{Pallet, Call, Event}, - Tokens: orml_tokens::{Pallet, Storage, Event, Config}, Proxy: pallet_proxy::{Pallet, Call, Storage, Event}, OrmlNFT: orml_nft::{Pallet, Storage, Config}, - NFT: crate::{Pallet, Call, Event}, + NFT: nft::{Pallet, Call, Event}, } ); use frame_system::Call as SystemCall; - impl crate::Config for Runtime {} - pub fn new_test_ext() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::default() .build_storage::() @@ -333,8 +315,8 @@ mod mock { #[cfg(test)] mod tests { use super::*; - use crate::mock::{new_test_ext, Runtime}; use frame_support::assert_ok; + use mock::{new_test_ext, Runtime}; #[test] fn test_create_class() { @@ -364,6 +346,13 @@ mod tests { }); } + #[test] + fn test_burn_with_remark() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_burn_with_remark::()); + }); + } + #[test] fn test_destroy_class() { new_test_ext().execute_with(|| { From b69ec33fafb1208da18429be4723b446c045bada Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 08:55:04 +0800 Subject: [PATCH 17/83] Update price to use EVM-ERC20 --- lib-serml/prices/src/lib.rs | 30 ++++++++++++++----- lib-serml/prices/src/mock.rs | 42 +++++++++++++++++++------- lib-serml/prices/src/tests.rs | 56 +++++++++++++++++++---------------- 3 files changed, 83 insertions(+), 45 deletions(-) diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index 2d9bca3d0..139601d05 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -20,8 +20,10 @@ //! //! ## Overview //! -//! The data from Oracle cannot be used in business, prices module will do some -//! process and feed prices for setheum. Process include: +//! The data from Oracle cannot be used in production, prices module will +//! do some process and feed prices for setheum, this includes constructing +//! the Setter (SETT) currency basket price. +//! Process include: //! - specify a fixed price for stable currency //! - feed price in USD or related price bewteen two currencies //! - lock/unlock the price data get from oracle @@ -32,13 +34,16 @@ use frame_support::{pallet_prelude::*, transactional}; use frame_system::pallet_prelude::*; use orml_traits::{DataFeeder, DataProvider, MultiCurrency}; -use primitives::{currency::Amount, Balance, CurrencyId, GetDecimals}; +use primitives::{ + currency::{Amount, DexShare}, + Balance, CurrencyId, GetDecimals +}; use sp_runtime::{ traits::{CheckedDiv, CheckedMul}, FixedPointNumber, }; use sp_std::{convert::TryInto, prelude::*, vec}; -use support::{DexManager, ExchangeRateProvider, Price, PriceProvider}; +use support::{CurrencyIdMapping, DexManager, ExchangeRateProvider, Price, PriceProvider}; mod mock; mod tests; @@ -128,6 +133,9 @@ pub mod module { /// Currency provide the total insurance of LPToken. type Currency: MultiCurrency; + /// Mapping between CurrencyId and ERC20 address so user can use Erc20. + type CurrencyIdMapping: CurrencyIdMapping; + /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; } @@ -355,9 +363,15 @@ impl PriceProvider for Pallet { // if is Setter (SETT) basket currency, return fixed price Some(Self::get_setter_fixed_price()) } else if let CurrencyId::DexShare(symbol_0, symbol_1) = currency_id { - let token_0 = CurrencyId::Token(symbol_0); - let token_1 = CurrencyId::Token(symbol_1); - let (pool_0, _) = T::Dex::get_liquidity_pool(token_0, token_1); + let token_0 = match symbol_0 { + DexShare::Token(token) => CurrencyId::Token(token), + DexShare::Erc20(address) => CurrencyId::Erc20(address), + }; + let token_1 = match symbol_1 { + DexShare::Token(token) => CurrencyId::Token(token), + DexShare::Erc20(address) => CurrencyId::Erc20(address), + }; + let (pool_0, _) = T::DEX::get_liquidity_pool(token_0, token_1); let total_shares = T::Currency::total_issuance(currency_id); return { @@ -376,7 +390,7 @@ impl PriceProvider for Pallet { // if locked price exists, return it, otherwise return latest price from oracle. Self::locked_price(currency_id).or_else(|| T::Source::get(¤cy_id)) }; - let maybe_adjustment_multiplier = 10u128.checked_pow(currency_id.decimals()); + let maybe_adjustment_multiplier = 10u128.checked_pow(T::CurrencyIdMapping::decimals(currency_id)?.into()); if let (Some(feed_price), Some(adjustment_multiplier)) = (maybe_feed_price, maybe_adjustment_multiplier) { Price::checked_from_rational(feed_price.into_inner(), adjustment_multiplier) diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index d9b69142a..60778ace3 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -31,11 +31,15 @@ use sp_runtime::{ traits::{IdentityLookup, One as OneT, Zero}, DispatchError, FixedPointNumber, }; -use support::{ExchangeRate, Ratio}; +use support::{mocks::MockCurrencyIdMapping, ExchangeRate, Ratio}; pub type AccountId = u128; pub type BlockNumber = u64; +mod setheum_prices { + pub use super::super::*; +} + // Currencies constants - CurrencyId/TokenSymbol pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); @@ -83,8 +87,10 @@ pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); // LP tokens constants - CurrencyId/TokenSymbol : Dex Shares -pub const LP_CHFJ_USDJ: CurrencyId = CurrencyId::DexShare(TokenSymbol::CHFJ, TokenSymbol::USDJ); -pub const LP_USDJ_DNAR: CurrencyId = CurrencyId::DexShare(TokenSymbol::USDJ, TokenSymbol::DNAR); +pub const LP_CHFJ_USDJ: CurrencyId = +CurrencyId::DexShare(DexShare::Token(TokenSymbol::CHFJ), DexShare::Token(TokenSymbol::USDJ)); +pub const LP_USDJ_DNAR: CurrencyId = +CurrencyId::DexShare(DexShare::Token(TokenSymbol::USDJ), DexShare::Token(TokenSymbol::DNAR)); // Currencies constants - FiatCurrencyIds (CurrencyId/TokenSymbol) pub const AED: CurrencyId = CurrencyId::Token(TokenSymbol::AED); @@ -137,10 +143,6 @@ pub const KYD: CurrencyId = CurrencyId::Token(TokenSymbol::KYD); pub const OMR: CurrencyId = CurrencyId::Token(TokenSymbol::OMR); pub const GIP: CurrencyId = CurrencyId::Token(TokenSymbol::GIP); -mod setheum_prices { - pub use super::super::*; -} - parameter_types! { pub const BlockHashCount: u64 = 250; } @@ -168,6 +170,7 @@ impl frame_system::Config for Runtime { type BaseCallFilter = (); type SystemWeightInfo = (); type SS58Prefix = (); + type OnSetCode = (); } pub struct MockDataProvider; @@ -234,11 +237,27 @@ impl DexManager for MockDex { unimplemented!() } - fn add_liquidity(_: &AccountId, _: CurrencyId, _: CurrencyId, _: Balance, _: Balance, _: bool) -> DispatchResult { + fn add_liquidity( + _who: &AccountId, + _currency_id_a: CurrencyId, + _currency_id_b: CurrencyId, + _max_amount_a: Balance, + _max_amount_b: Balance, + _min_share_increment: Balance, + _deposit_increment_share: bool, + ) -> DispatchResult { unimplemented!() } - fn remove_liquidity(_: &AccountId, _: CurrencyId, _: CurrencyId, _: Balance, _: bool) -> DispatchResult { + fn remove_liquidity( + _who: &AccountId, + _currency_id_a: CurrencyId, + _currency_id_b: CurrencyId, + _remove_share: Balance, + _min_withdrawn_a: Balance, + _min_withdrawn_b: Balance, + _by_withdraw: bool, + ) -> DispatchResult { unimplemented!() } } @@ -295,7 +314,7 @@ parameter_type_with_key! { &UAHJ => &UAH, &USDJ => &USD, &ZARJ => &ZAR, - _ => 0, + _ => None, } }; } @@ -445,6 +464,7 @@ impl Config for Runtime { type LockOrigin = EnsureSignedBy; type Dex = MockDex; type Currency = Tokens; + type CurrencyIdMapping = MockCurrencyIdMapping; type WeightInfo = (); } @@ -458,7 +478,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system::{Pallet, Call, Config, Storage, Event}, - PricesModule: setheum_prices::{Pallet, Storage, Call, Event}, + SetheumPrices: setheum_prices::{Pallet, Storage, Call, Event}, Tokens: orml_tokens::{Pallet, Call, Storage, Event}, } ); diff --git a/lib-serml/prices/src/tests.rs b/lib-serml/prices/src/tests.rs index f6ef011c1..b24c4fcdb 100644 --- a/lib-serml/prices/src/tests.rs +++ b/lib-serml/prices/src/tests.rs @@ -22,20 +22,24 @@ use super::*; use frame_support::{assert_noop, assert_ok}; -use mock::{Event, *};use sp_runtime::{traits::{BadOrigin, Zero}, FixedPointNumber}; +use mock::{Event, *}; +use sp_runtime::{ + traits::{BadOrigin, Zero}, + FixedPointNumber +}; #[test] fn get_price_from_oracle() { ExtBuilder::default().build().execute_with(|| { assert_eq!( - PricesModule::get_price(JCHF), + SetheumPrices::get_price(JCHF), Some(Price::saturating_from_integer(500000000000000u128)) ); // 50000 USD, right shift the decimal point (18-10) places assert_eq!( - PricesModule::get_price(DNAR), + SetheumPrices::get_price(DNAR), Some(Price::saturating_from_integer(10000000000u128)) ); // 100 USD, right shift the decimal point (18-12) places - assert_eq!(PricesModule::get_price(DNAR), Some(Price::zero())); + assert_eq!(SetheumPrices::get_price(DNAR), Some(Price::zero())); }); } @@ -43,7 +47,7 @@ fn get_price_from_oracle() { fn get_price_of_stable_currency_id() { ExtBuilder::default().build().execute_with(|| { assert_eq!( - PricesModule::get_price(USDJ), + SetheumPrices::get_price(USDJ), Some(Price::saturating_from_integer(1000000)) ); // 1 USD, right shift the decimal point (18-12) places }); @@ -54,20 +58,20 @@ fn get_price_of_lp_token_currency_id() { ExtBuilder::default().build().execute_with(|| { assert_eq!(MockDex::get_liquidity_pool(USDJ, DNAR), (10000, 200)); assert_eq!( - PricesModule::get_price(LP_USDJ_DNAR), + SetheumPrices::get_price(LP_USDJ_DNAR), None ); assert_ok!(Tokens::deposit(LP_USDJ_DNAR, &1, 100)); assert_eq!(Tokens::total_issuance(LP_USDJ_DNAR), 100); - assert_eq!(PricesModule::get_price(USDJ), Some(Price::saturating_from_rational(1000000u128, 1))); + assert_eq!(SetheumPrices::get_price(USDJ), Some(Price::saturating_from_rational(1000000u128, 1))); assert_eq!( - PricesModule::get_price(LP_USDJ_DNAR), + SetheumPrices::get_price(LP_USDJ_DNAR), Some(Price::saturating_from_rational(200000000u128, 1)) // 10000/100 * Price::saturating_from_rational(1000000u128, 1) * 2 ); assert_eq!(MockDex::get_liquidity_pool(JCHF, USDJ), (0, 0)); assert_eq!( - PricesModule::get_price(LP_JCHF_USDJ), + SetheumPrices::get_price(LP_JCHF_USDJ), None ); }); @@ -77,24 +81,24 @@ fn get_price_of_lp_token_currency_id() { fn get_relative_price_work() { ExtBuilder::default().build().execute_with(|| { assert_eq!( - PricesModule::get_relative_price(DNAR, USDJ), + SetheumPrices::get_relative_price(DNAR, USDJ), Some(Price::saturating_from_rational(10000, 1)) /* 1DNAR = 100USDJ, right shift the decimal point (12-10) * places */ ); assert_eq!( - PricesModule::get_relative_price(JCHF, USDJ), + SetheumPrices::get_relative_price(JCHF, USDJ), Some(Price::saturating_from_rational(500000000, 1)) /* 1JCHF = 50000USDJ, right shift the decimal point * (12-8) places */ ); assert_eq!( - PricesModule::get_relative_price(JUSD, DNAR), + SetheumPrices::get_relative_price(JUSD, DNAR), Some(Price::saturating_from_rational(1, 2)) // 1JUSD = 1/2DNAR, right shift the decimal point (10-10) places ); assert_eq!( - PricesModule::get_relative_price(JUSD, USDJ), + SetheumPrices::get_relative_price(JUSD, USDJ), Some(Price::saturating_from_rational(1, 1)) // 1USDJ = 1USDJ, right shift the decimal point (10-10) places ); - assert_eq!(PricesModule::get_relative_price(USDJ, DNAR), None); + assert_eq!(SetheumPrices::get_relative_price(USDJ, DNAR), None); }); } @@ -102,12 +106,12 @@ fn get_relative_price_work() { fn lock_price_work() { ExtBuilder::default().build().execute_with(|| { assert_eq!( - PricesModule::get_price(JCHF), + SetheumPrices::get_price(JCHF), Some(Price::saturating_from_integer(500000000000000u128)) ); LockedPrice::::insert(JCHF, Price::saturating_from_integer(80000)); assert_eq!( - PricesModule::get_price(JCHF), + SetheumPrices::get_price(JCHF), Some(Price::saturating_from_integer(800000000000000u128)) ); }); @@ -117,12 +121,14 @@ fn lock_price_work() { fn lock_price_call_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_noop!(PricesModule::lock_price(Origin::signed(5), JCHF), BadOrigin,); - assert_ok!(PricesModule::lock_price(Origin::signed(1), JCHF)); - - System::assert_last_event(Event::prices(crate::Event::LockPrice(JCHF, Price::saturating_from_integer(50000)))); + assert_noop!(SetheumPrices::lock_price(Origin::signed(5), JCHF), BadOrigin,); + assert_ok!(SetheumPrices::lock_price(Origin::signed(1), JCHF)); + System::assert_last_event(Event::prices(crate::Event::LockPrice( + JCHF, + Price::saturating_from_integer(50000) + ))); assert_eq!( - PricesModule::locked_price(JCHF), + SetheumPrices::locked_price(JCHF), Some(Price::saturating_from_integer(50000)) ); }); @@ -133,11 +139,9 @@ fn unlock_price_call_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); LockedPrice::::insert(JCHF, Price::saturating_from_integer(80000)); - assert_noop!(PricesModule::unlock_price(Origin::signed(5), JCHF), BadOrigin,); - assert_ok!(PricesModule::unlock_price(Origin::signed(1), JCHF)); - + assert_noop!(SetheumPrices::unlock_price(Origin::signed(5), JCHF), BadOrigin,); + assert_ok!(SetheumPrices::unlock_price(Origin::signed(1), JCHF)); System::assert_last_event(Event::prices(crate::Event::UnlockPrice(JCHF))); - - assert_eq!(PricesModule::locked_price(JCHF), None); + assert_eq!(SetheumPrices::locked_price(JCHF), None); }); } From 7637692b1d3a29480a77917f4013797b4029a30e Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 09:12:01 +0800 Subject: [PATCH 18/83] remove duplicate variable and fix peg currencies tagparams --- lib-serml/prices/src/mock.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index 60778ace3..554edc84c 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -134,8 +134,6 @@ pub const TZS: CurrencyId = CurrencyId::Token(TokenSymbol::TZS); pub const UAH: CurrencyId = CurrencyId::Token(TokenSymbol::UAH); pub const USD: CurrencyId = CurrencyId::Token(TokenSymbol::USD); pub const ZAR: CurrencyId = CurrencyId::Token(TokenSymbol::ZAR); -pub const CHF: CurrencyId = CurrencyId::Token(TokenSymbol::CHF); -pub const CHF: CurrencyId = CurrencyId::Token(TokenSymbol::CHF); pub const KWD: CurrencyId = CurrencyId::Token(TokenSymbol::KWD); pub const JOD: CurrencyId = CurrencyId::Token(TokenSymbol::JOD); pub const BHD: CurrencyId = CurrencyId::Token(TokenSymbol::BHD); @@ -266,7 +264,9 @@ parameter_type_with_key! { pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { Default::default() }; +} +parameter_type_with_key! { pub PegCurrencyIds: |_currency_id: CurrencyId| -> CurrencyId { match currency_id { &USDJ => &USD, From 1113ef6529efdc9005059bf90ac4084a2e968f86 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 09:53:37 +0800 Subject: [PATCH 19/83] update serp-auctions --- lib-serml/serp-auction/src/lib.rs | 112 +------------ lib-serml/serp-auction/src/mock.rs | 6 +- lib-serml/serp-auction/src/tests.rs | 240 ++++++++++++++-------------- 3 files changed, 124 insertions(+), 234 deletions(-) diff --git a/lib-serml/serp-auction/src/lib.rs b/lib-serml/serp-auction/src/lib.rs index fc81fd041..cd7c82d96 100644 --- a/lib-serml/serp-auction/src/lib.rs +++ b/lib-serml/serp-auction/src/lib.rs @@ -61,12 +61,6 @@ pub mod weights; pub use module::*; pub use weights::WeightInfo; -pub const OFFCHAIN_WORKER_DATA: &[u8] = b"setheum/serp-auction/data/"; -pub const OFFCHAIN_WORKER_LOCK: &[u8] = b"setheum/serp-auction/lock/"; -pub const OFFCHAIN_WORKER_MAX_ITERATIONS: &[u8] = b"setheum/serp-auction/max-iterations/"; -pub const LOCK_DURATION: u64 = 100; -pub const DEFAULT_MAX_ITERATIONS: u32 = 1000; - /// Information of a diamond auction #[cfg_attr(feature = "std", derive(PartialEq, Eq))] #[derive(Encode, Decode, Clone, RuntimeDebug)] @@ -288,10 +282,6 @@ pub mod module { #[pallet::hooks] impl Hooks for Pallet {} - - #[pallet::call] - impl Pallet {} - } impl Pallet { @@ -299,106 +289,6 @@ impl Pallet { T::Auction::auction_info(auction_id).and_then(|auction_info| auction_info.bid) } - fn submit_cancel_auction_tx(auction_id: AuctionId) { - let call = Call::::cancel(auction_id); - if let Err(err) = SubmitTransaction::>::submit_unsigned_transaction(call.into()) { - log::info!( - target: "serp-auction", - "offchain worker: submit unsigned auction cancel tx for AuctionId {:?} failed: {:?}", - auction_id, err, - ); - } - } - - fn _offchain_worker() -> Result<(), OffchainErr> { - // acquire offchain worker lock. - let lock_expiration = Duration::from_millis(LOCK_DURATION); - let mut lock = StorageLock::<'_, Time>::with_deadline(&OFFCHAIN_WORKER_LOCK, lock_expiration); - let mut guard = lock.try_lock().map_err(|_| OffchainErr::OffchainLock)?; - - let mut to_be_continue = StorageValueRef::persistent(&OFFCHAIN_WORKER_DATA); - - // get to_be_continue record, - // if it exsits, iterator map storage start with previous key - let (auction_type_num, start_key) = if let Some(Some((auction_type_num, last_iterator_previous_key))) = - to_be_continue.get::<(u32, Vec)>() - { - (auction_type_num, Some(last_iterator_previous_key)) - } else { - let random_seed = sp_io::offchain::random_seed(); - let mut rng = RandomNumberGenerator::::new(BlakeTwo256::hash(&random_seed[..])); - (rng.pick_u32(2), None) - }; - - // get the max iterationns config - let max_iterations = StorageValueRef::persistent(&OFFCHAIN_WORKER_MAX_ITERATIONS) - .get::() - .unwrap_or(Some(DEFAULT_MAX_ITERATIONS)); - - log::debug!( - target: "serp-auction", - "offchain worker: max iterations is {:?}", - max_iterations - ); - // Randomly choose to start iterations to cancel reserve/serplus/standard - // auctions - match auction_type_num { - 0 => { - let mut iterator = - as IterableStorageMapExtended<_, _>>::iter(max_iterations, start_key); - while let Some((diamond_auction_id, _)) = iterator.next() { - Self::submit_cancel_auction_tx(diamond_auction_id); - guard.extend_lock().map_err(|_| OffchainErr::OffchainLock)?; - } - - // if iteration for map storage finished, clear to be continue record - // otherwise, update to be continue record - if iterator.finished { - to_be_continue.clear(); - } else { - to_be_continue.set(&(auction_type_num, iterator.storage_map_iterator.previous_key)); - } - } - 1 => { - let mut iterator = - as IterableStorageMapExtended<_, _>>::iter(max_iterations, start_key); - while let Some((setter_auction_id, _)) = iterator.next() { - Self::submit_cancel_auction_tx(setter_auction_id); - guard.extend_lock().map_err(|_| OffchainErr::OffchainLock)?; - } - - // if iteration for map storage finished, clear to be continue record - // otherwise, update to be continue record - if iterator.finished { - to_be_continue.clear(); - } else { - to_be_continue.set(&(auction_type_num, iterator.storage_map_iterator.previous_key)); - } - } - _ => { - let mut iterator = - as IterableStorageMapExtended<_, _>>::iter(max_iterations, start_key); - while let Some((serplus_auction_id, _)) = iterator.next() { - Self::submit_cancel_auction_tx(serplus_auction_id); - guard.extend_lock().map_err(|_| OffchainErr::OffchainLock)?; - } - - // if iteration for map storage finished, clear to be continue record - // otherwise, update to be continue record - if iterator.finished { - to_be_continue.clear(); - } else { - to_be_continue.set(&(auction_type_num, iterator.storage_map_iterator.previous_key)); - } - } - } - - // Consume the guard but **do not** unlock the underlying lock. - guard.forget(); - - Ok(()) - } - fn cancel_diamond_auction(id: AuctionId, diamond_auction: DiamondAuctionItem) -> DispatchResult { // if there's bid if let Some((bidder, _)) = Self::get_last_bid(id) { @@ -808,7 +698,7 @@ impl AuctionHandler } } -impl SerpAuction for Pallet { +impl SerpAuctionManager for Pallet { type CurrencyId = CurrencyId; type Balance = Balance; type AuctionId = AuctionId; diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index dafd93419..b848158e3 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -101,7 +101,7 @@ impl orml_auction::Config for Runtime { type Event = Event; type Balance = Balance; type AuctionId = AuctionId; - type Handler = SerpAuctionModule; + type Handler = SerpAuctionManagerModule; type WeightInfo = (); } @@ -120,7 +120,7 @@ impl serp_treasury::Config for Runtime { type Event = Event; type Currency = Tokens; type GetStableCurrencyId = GetStableCurrencyId; - type SerpAuctionHandler = SerpAuctionModule; + type SerpAuctionManagerHandler = SerpAuctionManagerModule; type UpdateOrigin = EnsureSignedBy; type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; @@ -209,7 +209,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Module, Call, Storage, Config, Event}, - SerpAuctionModule: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, + SerpAuctionManagerModule: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, Tokens: orml_tokens::{Module, Storage, Event, Config}, AuctionModule: orml_auction::{Module, Storage, Call, Event}, SerpTreasuryModule: serp_treasury::{Module, Storage, Call, Event}, diff --git a/lib-serml/serp-auction/src/tests.rs b/lib-serml/serp-auction/src/tests.rs index 01eb4aa09..992439921 100644 --- a/lib-serml/serp-auction/src/tests.rs +++ b/lib-serml/serp-auction/src/tests.rs @@ -27,16 +27,16 @@ use mock::{Event, *}; #[test] fn get_auction_time_to_close_work() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(SerpAuctionModule::get_auction_time_to_close(2000, 1), 100); - assert_eq!(SerpAuctionModule::get_auction_time_to_close(2001, 1), 50); + assert_eq!(SerpAuctionManagerModule::get_auction_time_to_close(2000, 1), 100); + assert_eq!(SerpAuctionManagerModule::get_auction_time_to_close(2001, 1), 50); }); } #[test] fn setter_auction_methods() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 10, 100)); - let setter_auction_with_positive_target = SerpAuctionModule::setter_auctions(0).unwrap(); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 100)); + let setter_auction_with_positive_target = SerpAuctionManagerModule::setter_auctions(0).unwrap(); assert_eq!(setter_auction_with_positive_target.always_forward(), false); assert_eq!(setter_auction_with_positive_target.in_reverse_stage(99), false); assert_eq!(setter_auction_with_positive_target.in_reverse_stage(100), true); @@ -47,8 +47,8 @@ fn setter_auction_methods() { assert_eq!(setter_auction_with_positive_target.reserve_amount(80, 100), 10); assert_eq!(setter_auction_with_positive_target.reserve_amount(100, 200), 5); - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 10, 0)); - let setter_auction_with_zero_target = SerpAuctionModule::setter_auctions(1).unwrap(); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 0)); + let setter_auction_with_zero_target = SerpAuctionManagerModule::setter_auctions(1).unwrap(); assert_eq!(setter_auction_with_zero_target.always_forward(), true); assert_eq!(setter_auction_with_zero_target.in_reverse_stage(0), false); assert_eq!(setter_auction_with_zero_target.in_reverse_stage(100), false); @@ -61,8 +61,8 @@ fn setter_auction_methods() { #[test] fn diamond_auction_methods() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionModule::new_diamond_auction(200, 100)); - let diamond_auction = SerpAuctionModule::diamond_auctions(0).unwrap(); + assert_ok!(SerpAuctionManagerModule::new_diamond_auction(200, 100)); + let diamond_auction = SerpAuctionManagerModule::diamond_auctions(0).unwrap(); assert_eq!(diamond_auction.amount_for_sale(0, 100), 200); assert_eq!(diamond_auction.amount_for_sale(100, 200), 100); assert_eq!(diamond_auction.amount_for_sale(200, 1000), 40); @@ -75,20 +75,20 @@ fn new_setter_auction_work() { System::set_block_number(1); let ref_count_0 = System::consumers(&ALICE); assert_noop!( - SerpAuctionModule::new_setter_auction(&ALICE, BTC, 0, 100), + SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 0, 100), Error::::InvalidAmount, ); - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 10, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 100)); System::assert_last_event(Event::serp_auction(crate::Event::NewSetterAuction(0, BTC, 10, 100))); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 10); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 10); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 100); assert_eq!(AuctionModule::auctions_index(), 1); assert_eq!(System::consumers(&ALICE), ref_count_0 + 1); assert_noop!( - SerpAuctionModule::new_setter_auction(&ALICE, BTC, Balance::max_value(), Balance::max_value()), + SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, Balance::max_value(), Balance::max_value()), Error::::InvalidAmount, ); }); @@ -99,22 +99,22 @@ fn new_diamond_auction_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_noop!( - SerpAuctionModule::new_diamond_auction(0, 100), + SerpAuctionManagerModule::new_diamond_auction(0, 100), Error::::InvalidAmount, ); assert_noop!( - SerpAuctionModule::new_diamond_auction(200, 0), + SerpAuctionManagerModule::new_diamond_auction(200, 0), Error::::InvalidAmount, ); - assert_ok!(SerpAuctionModule::new_diamond_auction(200, 100)); + assert_ok!(SerpAuctionManagerModule::new_diamond_auction(200, 100)); System::assert_last_event(Event::serp_auction(crate::Event::NewDiamondAuction(0, 200, 100))); - assert_eq!(SerpAuctionModule::total_standard_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); assert_eq!(AuctionModule::auctions_index(), 1); assert_noop!( - SerpAuctionModule::new_diamond_auction(200, Balance::max_value()), + SerpAuctionManagerModule::new_diamond_auction(200, Balance::max_value()), Error::::InvalidAmount, ); }); @@ -125,18 +125,18 @@ fn new_serplus_auction_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_noop!( - SerpAuctionModule::new_serplus_auction(0), + SerpAuctionManagerModule::new_serplus_auction(0), Error::::InvalidAmount, ); - assert_ok!(SerpAuctionModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); System::assert_last_event(Event::serp_auction(crate::Event::NewSerplusAuction(0, 100))); - assert_eq!(SerpAuctionModule::total_diamond_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::total_diamond_in_auction(), 100); assert_eq!(AuctionModule::auctions_index(), 1); assert_noop!( - SerpAuctionModule::new_serplus_auction(Balance::max_value()), + SerpAuctionManagerModule::new_serplus_auction(Balance::max_value()), Error::::InvalidAmount, ); }); @@ -146,27 +146,27 @@ fn new_serplus_auction_work() { fn setter_auction_bid_handler_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SerpAuctionModule::setter_auction_bid_handler(1, 0, (BOB, 99), None), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 99), None), Error::::AuctionNotExists, ); - assert_ok!(SerpAuctionModule::new_setter_auction(200, 100)); - assert_eq!(SerpAuctionModule::total_standard_in_auction(), 100); - assert_eq!(SerpAuctionModule::setter_auctions(0).unwrap().amount, 200); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(200, 100)); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0).unwrap().amount, 200); assert_eq!(SerpTreasuryModule::serplus_pool(), 0); assert_eq!(Tokens::free_balance(SETT, &BOB), 1000); let bob_ref_count_0 = System::consumers(&BOB); assert_noop!( - SerpAuctionModule::setter_auction_bid_handler(1, 0, (BOB, 99), None), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 99), None), Error::::InvalidBidPrice, ); assert_eq!( - SerpAuctionModule::setter_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), true ); - assert_eq!(SerpAuctionModule::setter_auctions(0).unwrap().amount, 200); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0).unwrap().amount, 200); assert_eq!(SerpTreasuryModule::serplus_pool(), 100); assert_eq!(Tokens::free_balance(SETT, &BOB), 900); @@ -175,10 +175,10 @@ fn setter_auction_bid_handler_work() { let carol_ref_count_0 = System::consumers(&CAROL); assert_eq!( - SerpAuctionModule::setter_auction_bid_handler(2, 0, (CAROL, 200), Some((BOB, 100))).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(2, 0, (CAROL, 200), Some((BOB, 100))).is_ok(), true ); - assert_eq!(SerpAuctionModule::setter_auctions(0).unwrap().amount, 100); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0).unwrap().amount, 100); assert_eq!(SerpTreasuryModule::serplus_pool(), 100); assert_eq!(Tokens::free_balance(SETT, &BOB), 1000); assert_eq!(Tokens::free_balance(SETT, &CAROL), 900); @@ -193,27 +193,27 @@ fn setter_auction_bid_handler_work() { fn diamond_auction_bid_handler_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SerpAuctionModule::diamond_auction_bid_handler(1, 0, (BOB, 99), None), + SerpAuctionManagerModule::diamond_auction_bid_handler(1, 0, (BOB, 99), None), Error::::AuctionNotExists, ); - assert_ok!(SerpAuctionModule::new_diamond_auction(200, 100)); - assert_eq!(SerpAuctionModule::total_standard_in_auction(), 100); - assert_eq!(SerpAuctionModule::diamond_auctions(0).unwrap().amount, 200); + assert_ok!(SerpAuctionManagerModule::new_diamond_auction(200, 100)); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::diamond_auctions(0).unwrap().amount, 200); assert_eq!(SerpTreasuryModule::serplus_pool(), 0); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1000); let bob_ref_count_0 = System::consumers(&BOB); assert_noop!( - SerpAuctionModule::diamond_auction_bid_handler(1, 0, (BOB, 99), None), + SerpAuctionManagerModule::diamond_auction_bid_handler(1, 0, (BOB, 99), None), Error::::InvalidBidPrice, ); assert_eq!( - SerpAuctionModule::diamond_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), + SerpAuctionManagerModule::diamond_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), true ); - assert_eq!(SerpAuctionModule::diamond_auctions(0).unwrap().amount, 200); + assert_eq!(SerpAuctionManagerModule::diamond_auctions(0).unwrap().amount, 200); assert_eq!(SerpTreasuryModule::serplus_pool(), 100); assert_eq!(Tokens::free_balance(DNAR, &BOB), 900); @@ -222,10 +222,10 @@ fn diamond_auction_bid_handler_work() { let carol_ref_count_0 = System::consumers(&CAROL); assert_eq!( - SerpAuctionModule::diamond_auction_bid_handler(2, 0, (CAROL, 200), Some((BOB, 100))).is_ok(), + SerpAuctionManagerModule::diamond_auction_bid_handler(2, 0, (CAROL, 200), Some((BOB, 100))).is_ok(), true ); - assert_eq!(SerpAuctionModule::diamond_auctions(0).unwrap().amount, 100); + assert_eq!(SerpAuctionManagerModule::diamond_auctions(0).unwrap().amount, 100); assert_eq!(SerpTreasuryModule::serplus_pool(), 100); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1000); assert_eq!(Tokens::free_balance(DNAR, &CAROL), 900); @@ -240,17 +240,17 @@ fn diamond_auction_bid_handler_work() { fn serplus_auction_bid_handler_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SerpAuctionModule::serplus_auction_bid_handler(1, 0, (BOB, 99), None), + SerpAuctionManagerModule::serplus_auction_bid_handler(1, 0, (BOB, 99), None), Error::::AuctionNotExists, ); - assert_ok!(SerpAuctionModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1000); let bob_ref_count_0 = System::consumers(&BOB); assert_eq!( - SerpAuctionModule::serplus_auction_bid_handler(1, 0, (BOB, 50), None).is_ok(), + SerpAuctionManagerModule::serplus_auction_bid_handler(1, 0, (BOB, 50), None).is_ok(), true ); assert_eq!(Tokens::free_balance(USDJ, &BOB), 950); @@ -261,11 +261,11 @@ fn serplus_auction_bid_handler_work() { let carol_ref_count_0 = System::consumers(&CAROL); assert_noop!( - SerpAuctionModule::serplus_auction_bid_handler(2, 0, (CAROL, 51), Some((BOB, 50))), + SerpAuctionManagerModule::serplus_auction_bid_handler(2, 0, (CAROL, 51), Some((BOB, 50))), Error::::InvalidBidPrice, ); assert_eq!( - SerpAuctionModule::serplus_auction_bid_handler(2, 0, (CAROL, 55), Some((BOB, 50))).is_ok(), + SerpAuctionManagerModule::serplus_auction_bid_handler(2, 0, (CAROL, 55), Some((BOB, 50))).is_ok(), true ); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1000); @@ -280,17 +280,17 @@ fn serplus_auction_bid_handler_work() { #[test] fn bid_when_soft_cap_for_setter_auction_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 10, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 100)); assert_eq!( - SerpAuctionModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, + SerpAuctionManagerModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, Change::NewValue(Some(101)) ); assert_eq!( - SerpAuctionModule::on_new_bid(2001, 0, (CAROL, 10), Some((BOB, 5))).accept_bid, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 10), Some((BOB, 5))).accept_bid, false, ); assert_eq!( - SerpAuctionModule::on_new_bid(2001, 0, (CAROL, 15), Some((BOB, 5))).auction_end_change, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 15), Some((BOB, 5))).auction_end_change, Change::NewValue(Some(2051)) ); }); @@ -299,17 +299,17 @@ fn bid_when_soft_cap_for_setter_auction_work() { #[test] fn bid_when_soft_cap_for_diamond_auction_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionModule::new_diamond_auction(200, 100)); + assert_ok!(SerpAuctionManagerModule::new_diamond_auction(200, 100)); assert_eq!( - SerpAuctionModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, + SerpAuctionManagerModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, Change::NewValue(Some(101)) ); assert_eq!( - SerpAuctionModule::on_new_bid(2001, 0, (CAROL, 105), Some((BOB, 100))).accept_bid, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 105), Some((BOB, 100))).accept_bid, false ); assert_eq!( - SerpAuctionModule::on_new_bid(2001, 0, (CAROL, 110), Some((BOB, 100))).auction_end_change, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 110), Some((BOB, 100))).auction_end_change, Change::NewValue(Some(2051)) ); }); @@ -318,17 +318,17 @@ fn bid_when_soft_cap_for_diamond_auction_work() { #[test] fn bid_when_soft_cap_for_serplus_auction_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); assert_eq!( - SerpAuctionModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, + SerpAuctionManagerModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, Change::NewValue(Some(101)) ); assert_eq!( - SerpAuctionModule::on_new_bid(2001, 0, (CAROL, 105), Some((BOB, 100))).accept_bid, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 105), Some((BOB, 100))).accept_bid, false ); assert_eq!( - SerpAuctionModule::on_new_bid(2001, 0, (CAROL, 110), Some((BOB, 100))).auction_end_change, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 110), Some((BOB, 100))).auction_end_change, Change::NewValue(Some(2051)) ); }); @@ -339,20 +339,20 @@ fn setter_auction_end_handler_without_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 100, 200)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 100); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 100); let alice_ref_count_0 = System::consumers(&ALICE); - assert_eq!(SerpAuctionModule::setter_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, None); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, None); System::assert_last_event(Event::serp_auction(crate::Event::CancelAuction(0))); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); - assert_eq!(SerpAuctionModule::setter_auctions(0), None); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 0); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); let alice_ref_count_1 = System::consumers(&ALICE); assert_eq!(alice_ref_count_1, alice_ref_count_0 - 1); }); @@ -363,13 +363,13 @@ fn setter_auction_end_handler_in_reverse_stage() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 100, 200)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); assert_eq!( - SerpAuctionModule::setter_auction_bid_handler(2, 0, (BOB, 400), None).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(2, 0, (BOB, 400), None).is_ok(), true ); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 50); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 50); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 50); assert_eq!(Tokens::free_balance(BTC, &ALICE), 1050); assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 800); @@ -378,13 +378,13 @@ fn setter_auction_end_handler_in_reverse_stage() { let alice_ref_count_0 = System::consumers(&ALICE); let bob_ref_count_0 = System::consumers(&BOB); - assert_eq!(SerpAuctionModule::setter_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, Some((BOB, 400))); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 400))); System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, BTC, 50, BOB, 200))); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); - assert_eq!(SerpAuctionModule::setter_auctions(0), None); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 0); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); assert_eq!(Tokens::free_balance(BTC, &ALICE), 1050); assert_eq!(Tokens::free_balance(BTC, &BOB), 1050); assert_eq!(Tokens::free_balance(USDJ, &BOB), 800); @@ -402,14 +402,14 @@ fn setter_auction_end_handler_by_dealing_which_target_not_zero() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 100, 200)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); assert_eq!( - SerpAuctionModule::setter_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), true ); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 100); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 100); assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 900); assert_eq!(SerpTreasuryModule::serplus_pool(), 100); @@ -417,15 +417,15 @@ fn setter_auction_end_handler_by_dealing_which_target_not_zero() { let alice_ref_count_0 = System::consumers(&ALICE); let bob_ref_count_0 = System::consumers(&BOB); - assert_eq!(SerpAuctionModule::setter_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, Some((BOB, 100))); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 100))); System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, BTC, 100, BOB, 100))); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); - assert_eq!(SerpAuctionModule::setter_auctions(0), None); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 0); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); assert_eq!(Tokens::free_balance(BTC, &BOB), 1100); let alice_ref_count_1 = System::consumers(&ALICE); @@ -440,9 +440,9 @@ fn setter_auction_end_handler_by_dex_which_target_not_zero() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionModule::new_setter_auction(&ALICE, BTC, 100, 200)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); assert_eq!( - SerpAuctionModule::setter_auction_bid_handler(1, 0, (BOB, 20), None).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 20), None).is_ok(), true ); assert_ok!(DexModule::add_liquidity( @@ -456,8 +456,8 @@ fn setter_auction_end_handler_by_dex_which_target_not_zero() { assert_eq!(DexModule::get_swap_target_amount(&[BTC, USDJ], 100, None).unwrap(), 500); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 100); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 100); assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 980); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1000); @@ -466,8 +466,8 @@ fn setter_auction_end_handler_by_dex_which_target_not_zero() { let alice_ref_count_0 = System::consumers(&ALICE); let bob_ref_count_0 = System::consumers(&BOB); - assert_eq!(SerpAuctionModule::setter_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, Some((BOB, 20))); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 20))); let dex_take_setter_auction = Event::serp_auction(crate::Event::DEXTakeSetterAuction(0, BTC, 100, 500)); assert!(System::events() @@ -475,9 +475,9 @@ fn setter_auction_end_handler_by_dex_which_target_not_zero() { .any(|record| record.event == dex_take_setter_auction)); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); - assert_eq!(SerpAuctionModule::setter_auctions(0), None); - assert_eq!(SerpAuctionModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionModule::total_reserve_in_auction(BTC), 0); + assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1300); @@ -494,15 +494,15 @@ fn setter_auction_end_handler_by_dex_which_target_not_zero() { fn diamond_auction_end_handler_without_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpAuctionModule::new_diamond_auction(300, 100)); - assert_eq!(SerpAuctionModule::total_standard_in_auction(), 100); + assert_ok!(SerpAuctionManagerModule::new_diamond_auction(300, 100)); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); - assert_eq!(SerpAuctionModule::diamond_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, None); + assert_eq!(SerpAuctionManagerModule::diamond_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, None); System::assert_last_event(Event::serp_auction(crate::Event::CancelAuction(0))); - assert_eq!(SerpAuctionModule::diamond_auctions(0), None); - assert_eq!(SerpAuctionModule::total_standard_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::diamond_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 0); }); } @@ -510,25 +510,25 @@ fn diamond_auction_end_handler_without_bid() { fn diamond_auction_end_handler_with_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpAuctionModule::new_diamond_auction(300, 100)); + assert_ok!(SerpAuctionManagerModule::new_diamond_auction(300, 100)); assert_eq!( - SerpAuctionModule::diamond_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), + SerpAuctionManagerModule::diamond_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), true ); - assert_eq!(SerpAuctionModule::total_standard_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); assert_eq!(Tokens::free_balance(USDJ, &BOB), 900); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1000); let bob_ref_count_0 = System::consumers(&BOB); - assert_eq!(SerpAuctionModule::diamond_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, Some((BOB, 100))); + assert_eq!(SerpAuctionManagerModule::diamond_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 100))); System::assert_last_event(Event::serp_auction(crate::Event::DiamondAuctionDealt(0, 300, BOB, 100))); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1300); assert_eq!(Tokens::total_issuance(DNAR), 3300); - assert_eq!(SerpAuctionModule::diamond_auctions(0), None); - assert_eq!(SerpAuctionModule::total_standard_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::diamond_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 0); let bob_ref_count_1 = System::consumers(&BOB); assert_eq!(bob_ref_count_1, bob_ref_count_0 - 1); @@ -539,15 +539,15 @@ fn diamond_auction_end_handler_with_bid() { fn serplus_auction_end_handler_without_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpAuctionModule::new_serplus_auction(100)); - assert_eq!(SerpAuctionModule::total_diamond_in_auction(), 100); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); + assert_eq!(SerpAuctionManagerModule::total_diamond_in_auction(), 100); - assert_eq!(SerpAuctionModule::serplus_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, None); + assert_eq!(SerpAuctionManagerModule::serplus_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, None); System::assert_last_event(Event::serp_auction(crate::Event::CancelAuction(0))); - assert_eq!(SerpAuctionModule::serplus_auctions(0), None); - assert_eq!(SerpAuctionModule::total_diamond_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::serplus_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_diamond_in_auction(), 0); }); } @@ -556,24 +556,24 @@ fn serplus_auction_end_handler_with_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(SerpTreasuryModule::on_system_serpup(100)); - assert_ok!(SerpAuctionModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); assert_eq!( - SerpAuctionModule::serplus_auction_bid_handler(1, 0, (BOB, 500), None).is_ok(), + SerpAuctionManagerModule::serplus_auction_bid_handler(1, 0, (BOB, 500), None).is_ok(), true ); - assert_eq!(SerpAuctionModule::total_diamond_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::total_diamond_in_auction(), 100); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 500); assert_eq!(Tokens::total_issuance(DNAR), 2500); let bob_ref_count_0 = System::consumers(&BOB); - assert_eq!(SerpAuctionModule::serplus_auctions(0).is_some(), true); - SerpAuctionModule::on_auction_ended(0, Some((BOB, 500))); + assert_eq!(SerpAuctionManagerModule::serplus_auctions(0).is_some(), true); + SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 500))); System::assert_last_event(Event::serp_auction(crate::Event::SerplusAuctionDealt(0, 100, BOB, 500))); - assert_eq!(SerpAuctionModule::serplus_auctions(0), None); - assert_eq!(SerpAuctionModule::total_diamond_in_auction(), 0); + assert_eq!(SerpAuctionManagerModule::serplus_auctions(0), None); + assert_eq!(SerpAuctionManagerModule::total_diamond_in_auction(), 0); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1100); assert_eq!(Tokens::total_issuance(DNAR), 2500); @@ -588,19 +588,19 @@ fn swap_bidders_works() { let alice_ref_count_0 = System::consumers(&ALICE); let bob_ref_count_0 = System::consumers(&BOB); - SerpAuctionModule::swap_bidders(&BOB, None); + SerpAuctionManagerModule::swap_bidders(&BOB, None); let bob_ref_count_1 = System::consumers(&BOB); assert_eq!(bob_ref_count_1, bob_ref_count_0 + 1); - SerpAuctionModule::swap_bidders(&ALICE, Some(&BOB)); + SerpAuctionManagerModule::swap_bidders(&ALICE, Some(&BOB)); let alice_ref_count_1 = System::consumers(&ALICE); assert_eq!(alice_ref_count_1, alice_ref_count_0 + 1); let bob_ref_count_2 = System::consumers(&BOB); assert_eq!(bob_ref_count_2, bob_ref_count_1 - 1); - SerpAuctionModule::swap_bidders(&BOB, Some(&ALICE)); + SerpAuctionManagerModule::swap_bidders(&BOB, Some(&ALICE)); let alice_ref_count_2 = System::consumers(&ALICE); assert_eq!(alice_ref_count_2, alice_ref_count_1 - 1); From ffc2dc94edf98ae974ab9c80d54543b15350d22c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 09:57:36 +0800 Subject: [PATCH 20/83] update serp-auction --- lib-serml/serp-treasury/src/lib.rs | 12 ++++++------ lib-serml/serp-treasury/src/mock.rs | 6 +++--- lib-serml/setters-manager/src/mock.rs | 8 ++++---- lib-serml/settmint-engine/src/mock.rs | 6 +++--- lib-serml/settway/src/mock.rs | 8 ++++---- runtime/common/src/lib.rs | 2 +- runtime/neom/src/lib.rs | 8 ++++---- runtime/newrome/src/benchmarking/auction.rs | 18 +++++++++--------- runtime/newrome/src/lib.rs | 8 ++++---- runtime/setheum/src/lib.rs | 8 ++++---- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index a883076c3..9f8694747 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -110,7 +110,7 @@ pub mod module { type CharityFundAcc: Get; /// Auction manager creates different types of auction to handle system serplus and standard. - type SerpAuctionHandler: SerpAuction; + type SerpAuctionManagerHandler: SerpAuctionManager; /// Dex manager is used to swap reserve asset (Setter) for propper (SettCurrency). type Dex: DexManager; @@ -214,7 +214,7 @@ pub mod module { T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, ); - T::SerpAuctionHandler::new_serplus_auction(amount, ¤cy_id)?; + T::SerpAuctionManagerHandler::new_serplus_auction(amount, ¤cy_id)?; Ok(().into()) } @@ -226,7 +226,7 @@ pub mod module { initial_price: Balance, ) -> DispatchResultWithPostInfo { T::UpdateOrigin::ensure_origin(origin)?; - T::SerpAuctionHandler::new_diamond_auction(initial_price, setter_amount)?; + T::SerpAuctionManagerHandler::new_diamond_auction(initial_price, setter_amount)?; Ok(().into()) } @@ -239,7 +239,7 @@ pub mod module { initial_price: Balance, ) -> DispatchResultWithPostInfo { T::UpdateOrigin::ensure_origin(origin)?; - T::SerpAuctionHandler::new_setter_auction(initial_price, currency_amount, accepted_currency)?; + T::SerpAuctionManagerHandler::new_setter_auction(initial_price, currency_amount, accepted_currency)?; Ok(().into()) } } @@ -376,7 +376,7 @@ impl SerpTreasury for Pallet { Error::::InvalidAmount, ); /// Diamond Auction if it's to serpdown Setter. - T::SerpAuctionHandler::new_diamond_auction(&initial_amount, &amount) + T::SerpAuctionManagerHandler::new_diamond_auction(&initial_amount, &amount) } else { let settcurrency_fixed_price = T::Price::get_stablecoin_fixed_price(currency_id); @@ -390,7 +390,7 @@ impl SerpTreasury for Pallet { Error::::InvalidAmount, ); /// Setter Auction if it's not to serpdown Setter. - T::SerpAuctionHandler::new_setter_auction(&initial_setter_amount, &amount, ¤cy_id) + T::SerpAuctionManagerHandler::new_setter_auction(&initial_setter_amount, &amount, ¤cy_id) } Self::deposit_event(Event::CurrencySerpDownTriggered(amount, currency_id)); diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index c2bc2b12e..e01139e64 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -185,8 +185,8 @@ thread_local! { pub static TOTAL_SERPLUS_IN_AUCTION: RefCell = RefCell::new(0); } -pub struct MockSerpAuction; -impl SerpAuction for MockSerpAuction { +pub struct MockSerpAuctionManager; +impl SerpAuctionManager for MockSerpAuctionManager { type CurrencyId = CurrencyId; type Balance = Balance; type AuctionId = AuctionId; @@ -289,7 +289,7 @@ impl Config for Runtime { type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionHandler = MockSerpAuction; + type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index dcaf22627..4cf37580a 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -27,7 +27,7 @@ use orml_traits::parameter_type_with_key; use primitives::TokenSymbol; use sp_core::H256; use sp_runtime::{testing::Header, traits::IdentityLookup}; -use support::{SerpAuction, StandardValidator}; +use support::{SerpAuctionManager, StandardValidator}; pub type AccountId = u128; pub type AuctionId = u32; @@ -128,8 +128,8 @@ impl orml_currencies::Config for Runtime { } pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter; -pub struct MockSerpAuction; -impl SerpAuction for MockSerpAuction { +pub struct MockSerpAuctionManager; +impl SerpAuctionManager for MockSerpAuctionManager { type CurrencyId = CurrencyId; type Balance = Balance; type AuctionId = AuctionId; @@ -234,7 +234,7 @@ impl serp_treasury::Config for Runtime { type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionHandler = MockSerpAuction; + type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; type Dex = (); type MaxAuctionsCount = MaxAuctionsCount; diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index 8f67802c5..9b1ef1349 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -174,8 +174,8 @@ impl PriceProvider for MockPriceSource { fn unlock_price(_currency_id: CurrencyId) {} } -pub struct MockSerpAuction; -impl SerpAuction for MockSerpAuction { +pub struct MockSerpAuctionManager; +impl SerpAuctionManager for MockSerpAuctionManager { type Balance = Balance; type CurrencyId = CurrencyId; type AuctionId = AuctionId; @@ -276,7 +276,7 @@ impl serp_treasury::Config for Runtime { type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionHandler = MockSerpAuction; + type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; type Dex = (); type MaxAuctionsCount = MaxAuctionsCount; diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index 3b00e01fd..3169d8de1 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -32,7 +32,7 @@ use sp_runtime::{ FixedPointNumber, }; use sp_std::cell::RefCell; -use support::{SerpAuction, ExchangeRate, Price, PriceProvider, Rate, Ratio}; +use support::{SerpAuctionManager, ExchangeRate, Price, PriceProvider, Rate, Ratio}; mod settway { pub use super::super::*; @@ -149,8 +149,8 @@ impl PriceProvider for MockPriceSource { fn unlock_price(_currency_id: CurrencyId) {} } // TODO: Update -pub struct MockSerpAuction; -impl SerpAuction for MockSerpAuction { +pub struct MockSerpAuctionManager; +impl SerpAuctionManager for MockSerpAuctionManager { type Balance = Balance; type CurrencyId = CurrencyId; type AuctionId = AuctionId; @@ -255,7 +255,7 @@ impl serp_treasury::Config for Runtime { type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionHandler = MockSerpAuction; + type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; type Dex = (); type MaxAuctionsCount = MaxAuctionsCount; diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 122c0841e..8ff624ebd 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -54,7 +54,7 @@ parameter_types! { pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; pub const RenvmBridgeUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; pub const SettmintEngineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); - pub const SerpAuctionUnsignedPriority: TransactionPriority = TransactionPriority::max_value() - 1; + pub const SerpAuctionManagerUnsignedPriority: TransactionPriority = TransactionPriority::max_value() - 1; } parameter_types! { diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index 8681cdb1e..66c72edab 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -629,7 +629,7 @@ impl orml_auction::Config for Runtime { type Event = Event; type Balance = Balance; type AuctionId = AuctionId; - type Handler = SerpAuction; + type Handler = SerpAuctionManager; type WeightInfo = weights::orml_auction::WeightInfo; } @@ -810,7 +810,7 @@ impl serp_auction::Config for Runtime { type SerpTreasury = SerpTreasury; type Dex = Dex; type PriceSource = Prices; - type UnsignedPriority = runtime_common::SerpAuctionUnsignedPriority; + type UnsignedPriority = runtime_common::SerpAuctionManagerUnsignedPriority; type WeightInfo = weights::serp_auction::WeightInfo; } @@ -950,7 +950,7 @@ impl serp_treasury::Config for Runtime { type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionHandler = SerpAuction; + type SerpAuctionManagerHandler = SerpAuctionManager; type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; type Dex = Dex; type MaxAuctionsCount = MaxAuctionsCount; @@ -1126,7 +1126,7 @@ construct_runtime!( Dex: dex::{Module, Storage, Call, Event, Config}, // Settway - SerpAuction: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, + SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, SettersManager: setters_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, diff --git a/runtime/newrome/src/benchmarking/auction.rs b/runtime/newrome/src/benchmarking/auction.rs index fb436abba..9f219cad0 100644 --- a/runtime/newrome/src/benchmarking/auction.rs +++ b/runtime/newrome/src/benchmarking/auction.rs @@ -17,14 +17,14 @@ // along with this program. If not, see . use crate::{ - dollar, Auction, AuctionId, SerpAuction, AuctionTimeToClose, SerpTreasury, Runtime, System, ROME, rUSD, rSETT, + dollar, Auction, AuctionId, SerpAuctionManager, AuctionTimeToClose, SerpTreasury, Runtime, System, ROME, rUSD, rSETT, }; use super::utils::set_balance; use frame_benchmarking::account; use frame_support::traits::OnFinalize; use frame_system::RawOrigin; -use setheum_support::{SerpAuction as SerpAuctionTrait, SerpTreasury}; +use setheum_support::{SerpAuctionManager as SerpAuctionManagerTrait, SerpTreasury}; use orml_benchmarking::runtime_benchmarks; use sp_std::prelude::*; @@ -55,7 +55,7 @@ runtime_benchmarks! { set_balance(currency_id, &funder, reserve_amount); set_balance(rUSD, &bidder, bid_price); >::deposit_reserve(&funder, currency_id, reserve_amount)?; - SerpAuction::new_setter_auction(&funder, currency_id, reserve_amount, target_amount)?; + SerpAuctionManager::new_setter_auction(&funder, currency_id, reserve_amount, target_amount)?; }: bid(RawOrigin::Signed(bidder), auction_id, bid_price) // `bid` a setter auction, worst cases: @@ -75,7 +75,7 @@ runtime_benchmarks! { set_balance(rUSD, &bidder, bid_price); set_balance(rUSD, &previous_bidder, previous_bid_price); >::deposit_reserve(&funder, currency_id, reserve_amount)?; - SerpAuction::new_setter_auction(&funder, currency_id, reserve_amount, target_amount)?; + SerpAuctionManager::new_setter_auction(&funder, currency_id, reserve_amount, target_amount)?; Auction::bid(RawOrigin::Signed(previous_bidder).into(), auction_id, previous_bid_price)?; }: bid(RawOrigin::Signed(bidder), auction_id, bid_price) @@ -90,7 +90,7 @@ runtime_benchmarks! { let auction_id: AuctionId = 0; set_balance(ROME, &bidder, bid_price); - SerpAuction::new_serplus_auction(serplus_amount)?; + SerpAuctionManager::new_serplus_auction(serplus_amount)?; }: bid(RawOrigin::Signed(bidder), auction_id, bid_price) // `bid` a serplus auction, worst cases: @@ -105,7 +105,7 @@ runtime_benchmarks! { set_balance(ROME, &bidder, bid_price); set_balance(ROME, &previous_bidder, previous_bid_price); - SerpAuction::new_serplus_auction(serplus_amount)?; + SerpAuctionManager::new_serplus_auction(serplus_amount)?; Auction::bid(RawOrigin::Signed(previous_bidder).into(), auction_id, previous_bid_price)?; }: bid(RawOrigin::Signed(bidder), auction_id, bid_price) @@ -120,7 +120,7 @@ runtime_benchmarks! { let auction_id: AuctionId = 0; set_balance(rUSD, &bidder, fix_standard_amount); - SerpAuction::new_diamond_auction(initial_amount ,fix_standard_amount)?; + SerpAuctionManager::new_diamond_auction(initial_amount ,fix_standard_amount)?; }: bid(RawOrigin::Signed(bidder), auction_id, fix_standard_amount) // `bid` a diamond auction, worst cases: @@ -136,7 +136,7 @@ runtime_benchmarks! { set_balance(rUSD, &bidder, bid_price); set_balance(rUSD, &previous_bidder, previous_bid_price); - SerpAuction::new_diamond_auction(initial_amount ,fix_standard_amount)?; + SerpAuctionManager::new_diamond_auction(initial_amount ,fix_standard_amount)?; Auction::bid(RawOrigin::Signed(previous_bidder).into(), auction_id, previous_bid_price)?; }: bid(RawOrigin::Signed(bidder), auction_id, bid_price) @@ -151,7 +151,7 @@ runtime_benchmarks! { System::set_block_number(1); for auction_id in 0 .. c { - SerpAuction::new_diamond_auction(initial_amount ,fix_standard_amount)?; + SerpAuctionManager::new_diamond_auction(initial_amount ,fix_standard_amount)?; Auction::bid(RawOrigin::Signed(bidder.clone()).into(), auction_id, fix_standard_amount)?; } }: { diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index e27e87938..3bc598deb 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -631,7 +631,7 @@ impl orml_auction::Config for Runtime { type Event = Event; type Balance = Balance; type AuctionId = AuctionId; - type Handler = SerpAuction; + type Handler = SerpAuctionManager; type WeightInfo = weights::orml_auction::WeightInfo; } @@ -812,7 +812,7 @@ impl serp_auction::Config for Runtime { type SerpTreasury = SerpTreasury; type Dex = Dex; type PriceSource = Prices; - type UnsignedPriority = runtime_common::SerpAuctionUnsignedPriority; + type UnsignedPriority = runtime_common::SerpAuctionManagerUnsignedPriority; type WeightInfo = weights::serp_auction::WeightInfo; } @@ -952,7 +952,7 @@ impl serp_treasury::Config for Runtime { type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionHandler = SerpAuction; + type SerpAuctionManagerHandler = SerpAuctionManager; type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; type Dex = Dex; type MaxAuctionsCount = MaxAuctionsCount; @@ -1128,7 +1128,7 @@ construct_runtime!( Dex: dex::{Module, Storage, Call, Event, Config}, // Settway - SerpAuction: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, + SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, SettersManager: setters_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index 07ce8a84e..d0c8340a8 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -630,7 +630,7 @@ impl orml_auction::Config for Runtime { type Event = Event; type Balance = Balance; type AuctionId = AuctionId; - type Handler = SerpAuction; + type Handler = SerpAuctionManager; type WeightInfo = weights::orml_auction::WeightInfo; } @@ -812,7 +812,7 @@ impl serp_auction::Config for Runtime { type SerpTreasury = SerpTreasury; type Dex = Dex; type PriceSource = Prices; - type UnsignedPriority = runtime_common::SerpAuctionUnsignedPriority; + type UnsignedPriority = runtime_common::SerpAuctionManagerUnsignedPriority; type WeightInfo = weights::serp_auction::WeightInfo; } @@ -953,7 +953,7 @@ impl serp_treasury::Config for Runtime { type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionHandler = SerpAuction; + type SerpAuctionManagerHandler = SerpAuctionManager; type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; type Dex = Dex; type MaxAuctionsCount = MaxAuctionsCount; @@ -1129,7 +1129,7 @@ construct_runtime!( Dex: dex::{Module, Storage, Call, Event, Config}, // Settway - SerpAuction: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, + SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, SettersManager: setters_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, From afd9ad9ac0291f44a54a61cda090af169c504b91 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 10:47:25 +0800 Subject: [PATCH 21/83] update auctions & fix Diamond --- lib-serml/serp-auction/src/lib.rs | 38 +++++++++++++------------------ 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/lib-serml/serp-auction/src/lib.rs b/lib-serml/serp-auction/src/lib.rs index cd7c82d96..c5aa686be 100644 --- a/lib-serml/serp-auction/src/lib.rs +++ b/lib-serml/serp-auction/src/lib.rs @@ -722,21 +722,18 @@ impl SerpAuctionManager for Pallet { let diamond = T::GetNativeCurrencyId::get(); // set setter currency_id accepted for diamond auction (Only Setter is accepted (SETT)) - if setter_currency_id = T::GetSetterCurrencyId::get() { - >::insert( - auction_id, - DiamondAuctionItem { - initial_amount, - diamond: diamond, - amount: initial_amount, - fix: fix_setter, - setter: setter_currency_id, - start_time, - }, - ); - } else { - return Err(Error::::CurrencyNotAccepted.into()); - } + let setter_currency_id = T::GetSetterCurrencyId::get(); + >::insert( + auction_id, + DiamondAuctionItem { + initial_amount, + diamond: diamond, + amount: initial_amount, + fix: fix_setter, + setter: setter_currency_id, + start_time, + }, + ); Self::deposit_event(Event::NewDiamondAuction(auction_id, initial_amount, diamond, fix_setter, setter_currency_id)); Ok(()) @@ -820,18 +817,15 @@ impl SerpAuctionManager for Pallet { Ok(()) } - fn get_total_setter_in_auction() -> Self::Balance { - Self::total_setter_in_auction() + fn get_total_serplus_in_auction(id: Self::CurrencyId) -> Self::Balance { + Self::total_serplus_in_auction(id) } fn get_total_settcurrency_in_auction(id: Self::CurrencyId) -> Self::Balance { Self::total_settcurrency_in_auction(id) } - fn get_total_serplus_in_auction(id: Self::CurrencyId) -> Self::Balance { - Self::total_serplus_in_auction(id) - } - fn get_total_diamond_in_auction(id: Self::CurrencyId) -> Self::Balance { - Self::total_diamond_in_auction(id) + fn get_total_setter_in_auction() -> Self::Balance { + Self::total_setter_in_auction() } } From 27f3c2552bcbae3785a0e9c35b8fd586efec1cd8 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 12:28:23 +0800 Subject: [PATCH 22/83] update support, treasury, and remove SIF --- lib-serml/serp-treasury/src/lib.rs | 23 +--- lib-serml/serp-treasury/src/mock.rs | 18 ++- lib-serml/setters-manager/src/mock.rs | 168 ++++++++++++++++---------- lib-serml/settmint-engine/src/mock.rs | 161 ++++++++++++++---------- lib-serml/settway/src/mock.rs | 85 +++++++------ lib-serml/support/src/lib.rs | 26 ++-- runtime/neom/src/authority.rs | 41 +++---- runtime/neom/src/lib.rs | 24 ++-- runtime/newrome/src/authority.rs | 41 +++---- runtime/newrome/src/lib.rs | 23 ++-- runtime/setheum/src/authority.rs | 41 +++---- runtime/setheum/src/lib.rs | 24 ++-- 12 files changed, 351 insertions(+), 324 deletions(-) diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index 9f8694747..434d8ad5b 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -87,9 +87,6 @@ pub mod module { /// SerpUp ratio for Setheum Foundation's Charity Fund type CharityFundSerpupRatio: Get; - /// SerpUp ratio for Setheum Investment Fund (SIF) DAO - type SIFSerpupRatio: Get; - #[pallet::constant] /// SerpUp pool/account for receiving funds SettPay Cashdrops /// SettPayTreasury account. @@ -100,11 +97,6 @@ pub mod module { /// SetheumTreasury account. type SetheumTreasuryAcc: Get; - #[pallet::constant] - /// SerpUp pool/account for receiving funds Setheum Investment Fund (SIF) DAO - /// SIF account. - type SIFAcc: Get; - /// SerpUp pool/account for receiving funds Setheum Foundation's Charity Fund /// CharityFund account. type CharityFundAcc: Get; @@ -309,20 +301,10 @@ impl SerpTreasury for Pallet { Ok(()) } - /// SerpUp ratio for Setheum Investment Fund (SIF) DAO - fn get_sif_serpup(amount: Balance, currency_id: Self::CurrencyId) -> DispatchResult { - // SIF SerpUp Pool - 10% - let sif_account = T::SIFAcc::get(); - let sif_propper = T::SIFSerpupRatio::get() * amount; - Self::issue_propper(currency_id, sif_account, sif_propper); - - Self::deposit_event(Event::CurrencySerpUpDelivered(amount, currency_id)); - Ok(()) - } - /// SerpUp ratio for Setheum Foundation's Charity Fund fn get_charity_fund_serpup(amount: Balance, currency_id: Self::CurrencyId) -> DispatchResult { - // Charity Fund SerpUp Pool - 10% + // TODO: update to 20% + // Charity Fund SerpUp Pool - 20% let charity_fund_account = T::CharityFundAcc::get(); let charity_fund_propper = T::CharityFundSerpupRatio::get() * amount; Self::issue_propper(currency_id, charity_fund_account, charity_fund_propper); @@ -346,7 +328,6 @@ impl SerpTreasury for Pallet { get_serplus_serpup(amount, currency_id); get_settpay_serpup(amount, currency_id); get_treasury_serpup(amount, currency_id); - get_sif_serpup(amount, currency_id); get_charity_fund_serpup(amount, currency_id); Self::deposit_event(Event::CurrencySerpedUp(amount, currency_id)); diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index e01139e64..1633c05f4 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -201,16 +201,24 @@ impl SerpAuctionManager for MockSerpAuctionManager { Ok(()) } - fn new_serplus_auction(_amount: Self::Balance) -> DispatchResult { + fn new_serplus_auction(_amount: Self::Balance, _currency: Self::CurrencyId) -> DispatchResult { TOTAL_SERPLUS_IN_AUCTION.with(|v| *v.borrow_mut() += 1); Ok(()) } - fn get_total_setter_in_auction(_id: Self::CurrencyId) -> Self::Balance { + fn cancel_auction(_id: Self::AuctionId) -> DispatchResult { + Ok(()) + } + + fn get_total_serplus_in_auction(_currency: Self::CurrencyId) -> Self::Balance { + Default::default() + } + + fn get_total_settcurrency_in_auction(_currency: Self::CurrencyId) -> Self::Balance { Default::default() } - fn get_total_diamond_in_auction() -> Self::Balance { + fn get_total_setter_in_auction(_currency: Self::CurrencyId) -> Self::Balance { Default::default() } } @@ -273,8 +281,7 @@ parameter_types! { pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. - pub CharityFundSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to Setheum Foundation's Charity Fund. - pub SIFSerpupRatio: Rate = Permill = Permill::from_percent(10); // 10% of SerpUp to Setheum Investment Fund (SIF) (NIF in Neom). + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } impl Config for Runtime { @@ -288,7 +295,6 @@ impl Config for Runtime { type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; - type SIFSerpupRatio = SIFSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; type Dex = DexModule; diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index 4cf37580a..7c330214d 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -38,18 +38,49 @@ pub const BOB: AccountId = 2; // Currencies constants - CurrencyId/TokenSymbol pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); -pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); // SettinDex -pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); // Setter - The Defacto stablecoin & settmint reserve asset -pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); // Setheum USD (US Dollar stablecoin) -pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); // Setheum GBP (Pound Sterling stablecoin) -pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); // Setheum EUR (Euro stablecoin) -pub const KWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::KWDJ); // Setheum KWD (Kuwaiti Dinar stablecoin) -pub const JODJ: CurrencyId = CurrencyId::Token(TokenSymbol::JODJ); // Setheum JOD (Jordanian Dinar stablecoin) -pub const BHDJ: CurrencyId = CurrencyId::Token(TokenSymbol::BHDJ); // Setheum BHD (Bahraini Dirham stablecoin) -pub const KYDJ: CurrencyId = CurrencyId::Token(TokenSymbol::KYDJ); // Setheum KYD (Cayman Islands Dollar stablecoin) -pub const OMRJ: CurrencyId = CurrencyId::Token(TokenSymbol::OMRJ); // Setheum OMR (Omani Riyal stablecoin) -pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); // Setheum CHF (Swiss Franc stablecoin) -pub const GIPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GIPJ); // Setheum GIP (Gibraltar Pound stablecoin) +pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); +pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); +pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); +pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); +pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); +pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); +pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); +pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); +pub const CLPJ: CurrencyId = CurrencyId::Token(TokenSymbol::CLPJ); +pub const CNYJ: CurrencyId = CurrencyId::Token(TokenSymbol::CNYJ); +pub const COPJ: CurrencyId = CurrencyId::Token(TokenSymbol::COPJ); +pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); +pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); +pub const HKDJ: CurrencyId = CurrencyId::Token(TokenSymbol::HKDJ); +pub const HUFJ: CurrencyId = CurrencyId::Token(TokenSymbol::HUFJ); +pub const IDRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IDRJ); +pub const IRRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IRRJ); +pub const JPYJ: CurrencyId = CurrencyId::Token(TokenSymbol::JPYJ); +pub const KESJ: CurrencyId = CurrencyId::Token(TokenSymbol::KESJ); +pub const KRWJ: CurrencyId = CurrencyId::Token(TokenSymbol::KRWJ); +pub const KZTJ: CurrencyId = CurrencyId::Token(TokenSymbol::KZTJ); +pub const MXNJ: CurrencyId = CurrencyId::Token(TokenSymbol::MXNJ); +pub const MYRJ: CurrencyId = CurrencyId::Token(TokenSymbol::MYRJ); +pub const NGNJ: CurrencyId = CurrencyId::Token(TokenSymbol::NGNJ); +pub const NOKJ: CurrencyId = CurrencyId::Token(TokenSymbol::NOKJ); +pub const NZDJ: CurrencyId = CurrencyId::Token(TokenSymbol::NZDJ); +pub const PENJ: CurrencyId = CurrencyId::Token(TokenSymbol::PENJ); +pub const PHPJ: CurrencyId = CurrencyId::Token(TokenSymbol::PHPJ); +pub const PKRJ: CurrencyId = CurrencyId::Token(TokenSymbol::PKRJ); +pub const PLNJ: CurrencyId = CurrencyId::Token(TokenSymbol::PLNJ); +pub const QARJ: CurrencyId = CurrencyId::Token(TokenSymbol::QARJ); +pub const RONJ: CurrencyId = CurrencyId::Token(TokenSymbol::RONJ); +pub const RUBJ: CurrencyId = CurrencyId::Token(TokenSymbol::RUBJ); +pub const SARJ: CurrencyId = CurrencyId::Token(TokenSymbol::SARJ); +pub const SEKJ: CurrencyId = CurrencyId::Token(TokenSymbol::SEKJ); +pub const SGDJ: CurrencyId = CurrencyId::Token(TokenSymbol::SGDJ); +pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); +pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); +pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); +pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); +pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); +pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); +pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); mod setters_manager { pub use super::super::*; @@ -130,40 +161,35 @@ pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter for MockSerpAuctionManager { - type CurrencyId = CurrencyId; type Balance = Balance; + type CurrencyId = CurrencyId; type AuctionId = AuctionId; - fn new_setter_auction( - _refund_recipient: &AccountId, - _currency_id: Self::CurrencyId, - _amount: Self::Balance, - _target: Self::Balance, - ) -> DispatchResult { + fn new_diamond_auction(_amount: Self::Balance, _fix: Self::Balance) -> DispatchResult { Ok(()) } - fn new_diamond_auction(_amount: Self::Balance, _fix: Self::Balance) -> DispatchResult { + fn new_setter_auction(_amount: Self::Balance, _fix: Self::Balance, _id: Self::CurrencyId) -> DispatchResult { Ok(()) } - fn new_serplus_auction(_amount: Self::Balance) -> DispatchResult { + fn new_serplus_auction(_amount: Self::Balance, _id: Self::CurrencyId) -> DispatchResult { Ok(()) } - fn get_total_standard_in_auction() -> Self::Balance { - Default::default() + fn cancel_auction(_id: Self::AuctionId) -> DispatchResult { + Ok(()) } - fn get_total_target_in_auction() -> Self::Balance { + fn get_total_serplus_in_auction(_id: Self::CurrencyId) -> Self::Balance { Default::default() } - fn get_total_setter_in_auction(_id: Self::CurrencyId) -> Self::Balance { + fn get_total_settcurrency_in_auction(_id: Self::CurrencyId) -> Self::Balance { Default::default() } - fn get_total_diamond_in_auction() -> Self::Balance { + fn get_total_setter_in_auction() -> Self::Balance { Default::default() } } @@ -174,30 +200,52 @@ ord_parameter_types! { parameter_types! { pub StableCurrencyIds: Vec = vec![ - SETT, // Setter - The Defacto stablecoin & settmint reserve asset - USDJ, // Setheum USD (US Dollar stablecoin) - GBPJ, // Setheum GBP (Pound Sterling stablecoin) - EURJ, // Setheum EUR (Euro stablecoin) - KWDJ, // Setheum KWD (Kuwaiti Dinar stablecoin) - JODJ, // Setheum JOD (Jordanian Dinar stablecoin) - BHDJ, // Setheum BHD (Bahraini Dirham stablecoin) - KYDJ, // Setheum KYD (Cayman Islands Dollar stablecoin) - OMRJ, // Setheum OMR (Omani Riyal stablecoin) - CHFJ, // Setheum CHF (Swiss Franc stablecoin) - GIPJ, // Setheum GIP (Gibraltar Pound stablecoin) + SETT, + AEDJ, + ARSJ, + AUDJ, + BRLJ, + CADJ, + CHFJ, + CLPJ, + CNYJ, + COPJ, + EURJ, + GBPJ, + HKDJ, + HUFJ, + IDRJ, + IRRJ, + JPYJ, + KESJ, + KRWJ, + KZTJ, + MXNJ, + MYRJ, + NGNJ, + NOKJ, + NZDJ, + PENJ, + PHPJ, + PKRJ, + PLNJ, + QARJ, + RONJ, + RUBJ, + SARJ, + SEKJ, + SGDJ, + THBJ, + TRYJ, + TWDJ, + TZSJ, + UAHJ, + USDJ, + ZARJ, ]; - pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT - pub const GetSettUSDCurrencyId: CurrencyId = USDJ; // SettUSD currency ticker is USDJ - pub const GetSettGBPCurrencyId: CurrencyId = GBPJ; // SettGBP currency ticker is GBPJ - pub const GetSettEURCurrencyId: CurrencyId = EURJ; // SettEUR currency ticker is EURJ - pub const GetSettKWDCurrencyId: CurrencyId = KWDJ; // SettKWD currency ticker is KWDJ - pub const GetSettJODCurrencyId: CurrencyId = JODJ; // SettJOD currency ticker is JODJ - pub const GetSettBHDCurrencyId: CurrencyId = BHDJ; // SettBHD currency ticker is BHDJ - pub const GetSettKYDCurrencyId: CurrencyId = KYDJ; // SettKYD currency ticker is KYDJ - pub const GetSettOMRCurrencyId: CurrencyId = OMRJ; // SettOMR currency ticker is OMRJ - pub const GetSettCHFCurrencyId: CurrencyId = CHFJ; // SettCHF currency ticker is CHFJ - pub const GetSettGIPCurrencyId: CurrencyId = GIPJ; // SettGIP currency ticker is GIPJ - pub const GetDexerCurrencyId: CurrencyId = SDEX; + pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT + pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX + pub const GetExchangeFee: (u32, u32) = (0, 100); pub const TradingPathLimit: u32 = 3; pub EnabledTradingPairs: Vec = vec![TradingPair::new(USDJ, SETT)]; @@ -205,11 +253,10 @@ parameter_types! { pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks - pub SerplusSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to buy back & burn NativeCurrency. - pub SettPaySerpupRatio: Rate = Rate::saturating_from_rational(6 : 10); // 60% of SerpUp to SettPay as Cashdrops. - pub SetheumTreasurySerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to network Treasury. - pub CharityFundSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Foundation's Charity Fund. - pub SIFSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Investment Fund (SIF) (NIF in Neom). + pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. + pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. + pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } impl serp_treasury::Config for Runtime { @@ -217,26 +264,15 @@ impl serp_treasury::Config for Runtime { type Currency = Currencies; type StableCurrencyIds = StableCurrencyIds; type GetSetterCurrencyId = GetSetterCurrencyId; - type GetSettUSDCurrencyId = GetSettUSDCurrencyId; - type GetSettGBPCurrencyId = GetSettGBPCurrencyId; - type GetSettEURCurrencyId = GetSettEURCurrencyId; - type GetSettKWDCurrencyId = GetSettKWDCurrencyId; - type GetSettJODCurrencyId = GetSettJODCurrencyId; - type GetSettBHDCurrencyId = GetSettBHDCurrencyId; - type GetSettKYDCurrencyId = GetSettKYDCurrencyId; - type GetSettOMRCurrencyId = GetSettOMRCurrencyId; - type GetSettCHFCurrencyId = GetSettCHFCurrencyId; - type GetSettGIPCurrencyId = GetSettGIPCurrencyId; type GetDexerCurrencyId = GetDexerCurrencyId; type SerpTesSchedule = SerpTesSchedule; type SerplusSerpupRatio = SerplusSerpupRatio; type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; - type SIFSerpupRatio = SIFSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = (); + type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index 9b1ef1349..df57e324c 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -42,18 +42,49 @@ pub const CAROL: AccountId = 3; // Currencies constants - CurrencyId/TokenSymbol pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); -pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); // SettinDex -pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); // Setter - The Defacto stablecoin & settmint reserve asset -pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); // Setheum USD (US Dollar stablecoin) -pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); // Setheum GBP (Pound Sterling stablecoin) -pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); // Setheum EUR (Euro stablecoin) -pub const KWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::KWDJ); // Setheum KWD (Kuwaiti Dinar stablecoin) -pub const JODJ: CurrencyId = CurrencyId::Token(TokenSymbol::JODJ); // Setheum JOD (Jordanian Dinar stablecoin) -pub const BHDJ: CurrencyId = CurrencyId::Token(TokenSymbol::BHDJ); // Setheum BHD (Bahraini Dirham stablecoin) -pub const KYDJ: CurrencyId = CurrencyId::Token(TokenSymbol::KYDJ); // Setheum KYD (Cayman Islands Dollar stablecoin) -pub const OMRJ: CurrencyId = CurrencyId::Token(TokenSymbol::OMRJ); // Setheum OMR (Omani Riyal stablecoin) -pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); // Setheum CHF (Swiss Franc stablecoin) -pub const GIPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GIPJ); // Setheum GIP (Gibraltar Pound stablecoin) +pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); +pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); +pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); +pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); +pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); +pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); +pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); +pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); +pub const CLPJ: CurrencyId = CurrencyId::Token(TokenSymbol::CLPJ); +pub const CNYJ: CurrencyId = CurrencyId::Token(TokenSymbol::CNYJ); +pub const COPJ: CurrencyId = CurrencyId::Token(TokenSymbol::COPJ); +pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); +pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); +pub const HKDJ: CurrencyId = CurrencyId::Token(TokenSymbol::HKDJ); +pub const HUFJ: CurrencyId = CurrencyId::Token(TokenSymbol::HUFJ); +pub const IDRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IDRJ); +pub const IRRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IRRJ); +pub const JPYJ: CurrencyId = CurrencyId::Token(TokenSymbol::JPYJ); +pub const KESJ: CurrencyId = CurrencyId::Token(TokenSymbol::KESJ); +pub const KRWJ: CurrencyId = CurrencyId::Token(TokenSymbol::KRWJ); +pub const KZTJ: CurrencyId = CurrencyId::Token(TokenSymbol::KZTJ); +pub const MXNJ: CurrencyId = CurrencyId::Token(TokenSymbol::MXNJ); +pub const MYRJ: CurrencyId = CurrencyId::Token(TokenSymbol::MYRJ); +pub const NGNJ: CurrencyId = CurrencyId::Token(TokenSymbol::NGNJ); +pub const NOKJ: CurrencyId = CurrencyId::Token(TokenSymbol::NOKJ); +pub const NZDJ: CurrencyId = CurrencyId::Token(TokenSymbol::NZDJ); +pub const PENJ: CurrencyId = CurrencyId::Token(TokenSymbol::PENJ); +pub const PHPJ: CurrencyId = CurrencyId::Token(TokenSymbol::PHPJ); +pub const PKRJ: CurrencyId = CurrencyId::Token(TokenSymbol::PKRJ); +pub const PLNJ: CurrencyId = CurrencyId::Token(TokenSymbol::PLNJ); +pub const QARJ: CurrencyId = CurrencyId::Token(TokenSymbol::QARJ); +pub const RONJ: CurrencyId = CurrencyId::Token(TokenSymbol::RONJ); +pub const RUBJ: CurrencyId = CurrencyId::Token(TokenSymbol::RUBJ); +pub const SARJ: CurrencyId = CurrencyId::Token(TokenSymbol::SARJ); +pub const SEKJ: CurrencyId = CurrencyId::Token(TokenSymbol::SEKJ); +pub const SGDJ: CurrencyId = CurrencyId::Token(TokenSymbol::SGDJ); +pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); +pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); +pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); +pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); +pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); +pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); +pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); mod settmint_engine { pub use super::super::*; @@ -180,20 +211,15 @@ impl SerpAuctionManager for MockSerpAuctionManager { type CurrencyId = CurrencyId; type AuctionId = AuctionId; - fn new_setter_auction( - _refund_recipient: &AccountId, - _currency_id: Self::CurrencyId, - _amount: Self::Balance, - _target: Self::Balance, - ) -> DispatchResult { + fn new_diamond_auction(_amount: Self::Balance, _fix: Self::Balance) -> DispatchResult { Ok(()) } - fn new_diamond_auction(_amount: Self::Balance, _fix: Self::Balance) -> DispatchResult { + fn new_setter_auction(_amount: Self::Balance, _fix: Self::Balance, _id: Self::CurrencyId) -> DispatchResult { Ok(()) } - fn new_serplus_auction(_amount: Self::Balance) -> DispatchResult { + fn new_serplus_auction(_amount: Self::Balance, _id: Self::CurrencyId) -> DispatchResult { Ok(()) } @@ -201,57 +227,73 @@ impl SerpAuctionManager for MockSerpAuctionManager { Ok(()) } - fn get_total_standard_in_auction() -> Self::Balance { - Default::default() - } - - fn get_total_target_in_auction() -> Self::Balance { + fn get_total_serplus_in_auction(_id: Self::CurrencyId) -> Self::Balance { Default::default() } - fn get_total_setter_in_auction(_id: Self::CurrencyId) -> Self::Balance { + fn get_total_settcurrency_in_auction(_id: Self::CurrencyId) -> Self::Balance { Default::default() } - fn get_total_diamond_in_auction() -> Self::Balance { + fn get_total_setter_in_auction() -> Self::Balance { Default::default() } } parameter_types! { pub StableCurrencyIds: Vec = vec![ - SETT, // Setter - The Defacto stablecoin & settmint reserve asset - USDJ, // Setheum USD (US Dollar stablecoin) - GBPJ, // Setheum GBP (Pound Sterling stablecoin) - EURJ, // Setheum EUR (Euro stablecoin) - KWDJ, // Setheum KWD (Kuwaiti Dinar stablecoin) - JODJ, // Setheum JOD (Jordanian Dinar stablecoin) - BHDJ, // Setheum BHD (Bahraini Dirham stablecoin) - KYDJ, // Setheum KYD (Cayman Islands Dollar stablecoin) - OMRJ, // Setheum OMR (Omani Riyal stablecoin) - CHFJ, // Setheum CHF (Swiss Franc stablecoin) - GIPJ, // Setheum GIP (Gibraltar Pound stablecoin) + SETT, + AEDJ, + ARSJ, + AUDJ, + BRLJ, + CADJ, + CHFJ, + CLPJ, + CNYJ, + COPJ, + EURJ, + GBPJ, + HKDJ, + HUFJ, + IDRJ, + IRRJ, + JPYJ, + KESJ, + KRWJ, + KZTJ, + MXNJ, + MYRJ, + NGNJ, + NOKJ, + NZDJ, + PENJ, + PHPJ, + PKRJ, + PLNJ, + QARJ, + RONJ, + RUBJ, + SARJ, + SEKJ, + SGDJ, + THBJ, + TRYJ, + TWDJ, + TZSJ, + UAHJ, + USDJ, + ZARJ, ]; pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT - pub const GetSettUSDCurrencyId: CurrencyId = USDJ; // SettUSD currency ticker is USDJ - pub const GetSettGBPCurrencyId: CurrencyId = GBPJ; // SettGBP currency ticker is GBPJ - pub const GetSettEURCurrencyId: CurrencyId = EURJ; // SettEUR currency ticker is EURJ - pub const GetSettKWDCurrencyId: CurrencyId = KWDJ; // SettKWD currency ticker is KWDJ - pub const GetSettJODCurrencyId: CurrencyId = JODJ; // SettJOD currency ticker is JODJ - pub const GetSettBHDCurrencyId: CurrencyId = BHDJ; // SettBHD currency ticker is BHDJ - pub const GetSettKYDCurrencyId: CurrencyId = KYDJ; // SettKYD currency ticker is KYDJ - pub const GetSettOMRCurrencyId: CurrencyId = OMRJ; // SettOMR currency ticker is OMRJ - pub const GetSettCHFCurrencyId: CurrencyId = CHFJ; // SettCHF currency ticker is CHFJ - pub const GetSettGIPCurrencyId: CurrencyId = GIPJ; // SettGIP currency ticker is GIPJ pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks - pub SerplusSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to buy back & burn NativeCurrency. - pub SettPaySerpupRatio: Rate = Rate::saturating_from_rational(6 : 10); // 60% of SerpUp to SettPay as Cashdrops. - pub SetheumTreasurySerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to network Treasury. - pub CharityFundSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Foundation's Charity Fund. - pub SIFSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Investment Fund (SIF) (NIF in Neom). + pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. + pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. + pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } impl serp_treasury::Config for Runtime { @@ -259,26 +301,15 @@ impl serp_treasury::Config for Runtime { type Currency = Currencies; type StableCurrencyIds = StableCurrencyIds; type GetSetterCurrencyId = GetSetterCurrencyId; - type GetSettUSDCurrencyId = GetSettUSDCurrencyId; - type GetSettGBPCurrencyId = GetSettGBPCurrencyId; - type GetSettEURCurrencyId = GetSettEURCurrencyId; - type GetSettKWDCurrencyId = GetSettKWDCurrencyId; - type GetSettJODCurrencyId = GetSettJODCurrencyId; - type GetSettBHDCurrencyId = GetSettBHDCurrencyId; - type GetSettKYDCurrencyId = GetSettKYDCurrencyId; - type GetSettOMRCurrencyId = GetSettOMRCurrencyId; - type GetSettCHFCurrencyId = GetSettCHFCurrencyId; - type GetSettGIPCurrencyId = GetSettGIPCurrencyId; type GetDexerCurrencyId = GetDexerCurrencyId; type SerpTesSchedule = SerpTesSchedule; type SerplusSerpupRatio = SerplusSerpupRatio; type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; - type SIFSerpupRatio = SIFSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = (); + type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index 3169d8de1..34fa3849e 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -199,38 +199,58 @@ ord_parameter_types! { parameter_types! { pub StableCurrencyIds: Vec = vec![ - SETT, // Setter - The Defacto stablecoin & settmint reserve asset - USDJ, // Setheum USD (US Dollar stablecoin) - GBPJ, // Setheum GBP (Pound Sterling stablecoin) - EURJ, // Setheum EUR (Euro stablecoin) - KWDJ, // Setheum KWD (Kuwaiti Dinar stablecoin) - JODJ, // Setheum JOD (Jordanian Dinar stablecoin) - BHDJ, // Setheum BHD (Bahraini Dirham stablecoin) - KYDJ, // Setheum KYD (Cayman Islands Dollar stablecoin) - OMRJ, // Setheum OMR (Omani Riyal stablecoin) - CHFJ, // Setheum CHF (Swiss Franc stablecoin) - GIPJ, // Setheum GIP (Gibraltar Pound stablecoin) + SETT, + AEDJ, + ARSJ, + AUDJ, + BRLJ, + CADJ, + CHFJ, + CLPJ, + CNYJ, + COPJ, + EURJ, + GBPJ, + HKDJ, + HUFJ, + IDRJ, + IRRJ, + JPYJ, + KESJ, + KRWJ, + KZTJ, + MXNJ, + MYRJ, + NGNJ, + NOKJ, + NZDJ, + PENJ, + PHPJ, + PKRJ, + PLNJ, + QARJ, + RONJ, + RUBJ, + SARJ, + SEKJ, + SGDJ, + THBJ, + TRYJ, + TWDJ, + TZSJ, + UAHJ, + USDJ, + ZARJ, ]; pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT - pub const GetSettUSDCurrencyId: CurrencyId = USDJ; // SettUSD currency ticker is USDJ - pub const GetSettGBPCurrencyId: CurrencyId = GBPJ; // SettGBP currency ticker is GBPJ - pub const GetSettEURCurrencyId: CurrencyId = EURJ; // SettEUR currency ticker is EURJ - pub const GetSettKWDCurrencyId: CurrencyId = KWDJ; // SettKWD currency ticker is KWDJ - pub const GetSettJODCurrencyId: CurrencyId = JODJ; // SettJOD currency ticker is JODJ - pub const GetSettBHDCurrencyId: CurrencyId = BHDJ; // SettBHD currency ticker is BHDJ - pub const GetSettKYDCurrencyId: CurrencyId = KYDJ; // SettKYD currency ticker is KYDJ - pub const GetSettOMRCurrencyId: CurrencyId = OMRJ; // SettOMR currency ticker is OMRJ - pub const GetSettCHFCurrencyId: CurrencyId = CHFJ; // SettCHF currency ticker is CHFJ - pub const GetSettGIPCurrencyId: CurrencyId = GIPJ; // SettGIP currency ticker is GIPJ pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks - pub SerplusSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to buy back & burn NativeCurrency. - pub SettPaySerpupRatio: Rate = Rate::saturating_from_rational(6 : 10); // 60% of SerpUp to SettPay as Cashdrops. - pub SetheumTreasurySerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to network Treasury. - pub CharityFundSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Foundation's Charity Fund. - pub SIFSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Investment Fund (SIF) (NIF in Neom). + pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. + pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. + pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } impl serp_treasury::Config for Runtime { @@ -238,26 +258,15 @@ impl serp_treasury::Config for Runtime { type Currency = Currencies; type StableCurrencyIds = StableCurrencyIds; type GetSetterCurrencyId = GetSetterCurrencyId; - type GetSettUSDCurrencyId = GetSettUSDCurrencyId; - type GetSettGBPCurrencyId = GetSettGBPCurrencyId; - type GetSettEURCurrencyId = GetSettEURCurrencyId; - type GetSettKWDCurrencyId = GetSettKWDCurrencyId; - type GetSettJODCurrencyId = GetSettJODCurrencyId; - type GetSettBHDCurrencyId = GetSettBHDCurrencyId; - type GetSettKYDCurrencyId = GetSettKYDCurrencyId; - type GetSettOMRCurrencyId = GetSettOMRCurrencyId; - type GetSettCHFCurrencyId = GetSettCHFCurrencyId; - type GetSettGIPCurrencyId = GetSettGIPCurrencyId; type GetDexerCurrencyId = GetDexerCurrencyId; type SerpTesSchedule = SerpTesSchedule; type SerplusSerpupRatio = SerplusSerpupRatio; type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; - type SIFSerpupRatio = SIFSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = (); + type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index 51ca67653..58e830e61 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -21,6 +21,10 @@ use codec::{Decode, Encode, FullCodec, HasCompact}; use frame_support::pallet_prelude::{DispatchClass, Pays, Weight}; +use primitives::{ + evm::{CallInfo, EvmAddress}, + CurrencyId, +}; use sp_core::H160; use sp_runtime::{ traits::{AtLeast32BitUnsigned, Convert, MaybeSerializeDeserialize}, @@ -34,27 +38,29 @@ use sp_std::{ prelude::*, }; +pub mod mocks; + pub type BlockNumber = u32; pub type Price = FixedU128; pub type ExchangeRate = FixedU128; pub type Ratio = FixedU128; pub type Rate = FixedU128; -pub trait StandardManager { +pub trait StandardManager { fn check_position_valid( currency_id: CurrencyId, reserve_balance: Balance, - standard_balance: Balance, + standard_balance: StandardBalance, ) -> DispatchResult; } -impl StandardManager +impl StandardManager for () { fn check_position_valid( _currency_id: CurrencyId, _reserve_balance: Balance, - _standard_balance: Balance, + _standard_balance: StandardBalance, ) -> DispatchResult { Ok(()) } @@ -146,12 +152,6 @@ pub trait SerpTreasury { fn get_adjustment_frequency() -> Self::BlockNumber; - /// get surplus amount of serp treasury - fn get_surplus_pool() -> Self::Balance; - - /// get serpup amount of serp treasury - fn get_surpup_pool() -> Self::Balance; - /// get reserve asset amount of serp treasury fn get_total_setter() -> Self::Balance; @@ -167,9 +167,6 @@ pub trait SerpTreasury { /// SerpUp ratio for Setheum Treasury fn get_treasury_serpup(amount: Self::Balance, currency_id: Self::CurrencyId) -> DispatchResult; - /// SerpUp ratio for Setheum Investment Fund (SIF) DAO - fn get_sif_serpup(amount: Self::Balance, currency_id: Self::CurrencyId) -> DispatchResult; - /// SerpUp ratio for Setheum Foundation's Charity Fund fn get_charity_fund_serpup(amount: Self::Balance, currency_id: Self::CurrencyId) -> DispatchResult; @@ -220,9 +217,6 @@ pub trait SerpTreasury { /// Burn Reserve asset (Setter (SETT)) fn burn_reserve(to: &AccountId, amount: Self::Balance) -> DispatchResult; - - /// Withdraw reserve asset (Setter (SETT)) of serp treasury to `who` - fn withdraw_reserve(to: &AccountId, amount: Self::Balance) -> DispatchResult; } pub trait SerpTreasuryExtended: SerpTreasury { diff --git a/runtime/neom/src/authority.rs b/runtime/neom/src/authority.rs index 63a11d324..8b6989d91 100644 --- a/runtime/neom/src/authority.rs +++ b/runtime/neom/src/authority.rs @@ -19,7 +19,7 @@ //! An orml_authority trait implementation. use crate::{ - SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, SIFPalletId, + SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfSettwayCouncil, EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, EnsureRootOrTwoThirdsTechnicalCommittee, SettwayTreasuryPalletId, OneDay, Origin, @@ -83,39 +83,32 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { AuthoritysOriginId::SettwayTreasury => Origin::signed(SettwayTreasuryPalletId::get().into_account()) .caller() .clone(), - AuthoritysOriginId::SIF => Origin::signed(SIFPalletId::get().into_account()).caller().clone(), } } fn check_dispatch_from(&self, origin: Origin) -> DispatchResult { ensure_root(origin.clone()).or_else(|_| { match self { - AuthoritysOriginId::Root => as EnsureOrigin>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())), - AuthoritysOriginId::SetheumTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } - AuthoritysOriginId::SettwayTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } - AuthoritysOriginId::SIF => { - , BlockNumber, OriginCaller> as EnsureOrigin< + AuthoritysOriginId::Root => as EnsureOrigin>::ensure_origin(origin) + .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())), + AuthoritysOriginId::SetheumTreasury => { + as EnsureOrigin< + Origin, + >>::ensure_origin(origin) + .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) + } + AuthoritysOriginId::SettwayTreasury => { + as EnsureOrigin< Origin, >>::ensure_origin(origin) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) + } } - } }) } } diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index 66c72edab..a0235673f 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -132,11 +132,10 @@ parameter_types! { pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); - // Decentralized Sovereign Wealth Fund - pub const SIFPalletId: PalletId = PalletId(*b"set/dsif"); pub const NftPalletId: PalletId = PalletId(*b"set/aNFT"); } +// TODO: Update pub fn get_all_setheum_accounts() -> Vec { vec![ SetheumTreasuryPalletId::get().into_account(), @@ -145,7 +144,6 @@ pub fn get_all_setheum_accounts() -> Vec { SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), IncentivesPalletId::get().into_account(), - SIFPalletId::get().into_account(), ZeroAccountId::get(), ] } @@ -931,12 +929,12 @@ impl dex::Config for Runtime { } parameter_types! { - pub const MaxAuctionsCount: u32 = 100; - pub SerplusSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to buy back & burn NativeCurrency. - pub SettPaySerpupRatio: Rate = Rate::saturating_from_rational(6 : 10); // 60% of SerpUp to SettPay as Cashdrops. - pub SetheumTreasurySerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to network Treasury. - pub CharityFundSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Foundation's Charity Fund. - pub SIFSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Investment Fund (SIF) (NIF in Neom). + pub const MaxAuctionsCount: u32 = 258; + pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks + pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. + pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. + pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } impl serp_treasury::Config for Runtime { @@ -945,14 +943,14 @@ impl serp_treasury::Config for Runtime { type StableCurrencyIds = StableCurrencyIds; type GetSetterCurrencyId = GetSetterCurrencyId; type GetDexerCurrencyId = GetDexerCurrencyId; + type SerpTesSchedule = SerpTesSchedule; type SerplusSerpupRatio = SerplusSerpupRatio; type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; - type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionManagerHandler = SerpAuctionManager; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; - type Dex = Dex; + type SerpAuctionManagerHandler = MockSerpAuctionManager; + type UpdateOrigin = EnsureSignedBy; + type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = weights::serp_treasury::WeightInfo; diff --git a/runtime/newrome/src/authority.rs b/runtime/newrome/src/authority.rs index c5a9b8d5a..8b6989d91 100644 --- a/runtime/newrome/src/authority.rs +++ b/runtime/newrome/src/authority.rs @@ -20,7 +20,7 @@ use crate::{ SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, - SIFPalletId, DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfSettwayCouncil, + DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfSettwayCouncil, EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, EnsureRootOrTwoThirdsTechnicalCommittee, SettwayTreasuryPalletId, OneDay, Origin, OriginCaller, SevenDays, ZeroDay, HOURS, @@ -83,39 +83,32 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { AuthoritysOriginId::SettwayTreasury => Origin::signed(SettwayTreasuryPalletId::get().into_account()) .caller() .clone(), - AuthoritysOriginId::SIF => Origin::signed(SIFPalletId::get().into_account()).caller().clone(), } } fn check_dispatch_from(&self, origin: Origin) -> DispatchResult { ensure_root(origin.clone()).or_else(|_| { match self { - AuthoritysOriginId::Root => as EnsureOrigin>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())), - AuthoritysOriginId::SetheumTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } - AuthoritysOriginId::SettwayTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } - AuthoritysOriginId::SIF => { - , BlockNumber, OriginCaller> as EnsureOrigin< + AuthoritysOriginId::Root => as EnsureOrigin>::ensure_origin(origin) + .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())), + AuthoritysOriginId::SetheumTreasury => { + as EnsureOrigin< + Origin, + >>::ensure_origin(origin) + .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) + } + AuthoritysOriginId::SettwayTreasury => { + as EnsureOrigin< Origin, >>::ensure_origin(origin) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) + } } - } }) } } diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index 3bc598deb..533c89cd0 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -134,8 +134,6 @@ parameter_types! { pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); - // Decentralized Sovereign Wealth Fund - pub const SIFPalletId: PalletId = PalletId(*b"set/dsif"); pub const NftPalletId: PalletId = PalletId(*b"set/aNFT"); } @@ -147,7 +145,6 @@ pub fn get_all_setheum_accounts() -> Vec { SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), IncentivesPalletId::get().into_account(), - SIFPalletId::get().into_account(), ZeroAccountId::get(), ] } @@ -933,12 +930,12 @@ impl dex::Config for Runtime { } parameter_types! { - pub const MaxAuctionsCount: u32 = 100; - pub SerplusSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to buy back & burn NativeCurrency. - pub SettPaySerpupRatio: Rate = Rate::saturating_from_rational(6 : 10); // 60% of SerpUp to SettPay as Cashdrops. - pub SetheumTreasurySerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to network Treasury. - pub CharityFundSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Foundation's Charity Fund. - pub SIFSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Investment Fund (SIF) (NIF in Neom). + pub const MaxAuctionsCount: u32 = 258; + pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks + pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. + pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. + pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } impl serp_treasury::Config for Runtime { @@ -947,14 +944,14 @@ impl serp_treasury::Config for Runtime { type StableCurrencyIds = StableCurrencyIds; type GetSetterCurrencyId = GetSetterCurrencyId; type GetDexerCurrencyId = GetDexerCurrencyId; + type SerpTesSchedule = SerpTesSchedule; type SerplusSerpupRatio = SerplusSerpupRatio; type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; - type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionManagerHandler = SerpAuctionManager; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; - type Dex = Dex; + type SerpAuctionManagerHandler = MockSerpAuctionManager; + type UpdateOrigin = EnsureSignedBy; + type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = weights::serp_treasury::WeightInfo; diff --git a/runtime/setheum/src/authority.rs b/runtime/setheum/src/authority.rs index 55ab4377d..5c286a4bc 100644 --- a/runtime/setheum/src/authority.rs +++ b/runtime/setheum/src/authority.rs @@ -19,7 +19,7 @@ //! An orml_authority trait implementation. use crate::{ - SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, SIFPalletId, + SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfSettwayCouncil, EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, EnsureRootOrTwoThirdsTechnicalCommittee, SettwayTreasuryPalletId, OneDay, Origin, @@ -83,39 +83,32 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { AuthoritysOriginId::SettwayTreasury => Origin::signed(SettwayTreasuryPalletId::get().into_account()) .caller() .clone(), - AuthoritysOriginId::SIF => Origin::signed(SIFPalletId::get().into_account()).caller().clone(), } } fn check_dispatch_from(&self, origin: Origin) -> DispatchResult { ensure_root(origin.clone()).or_else(|_| { match self { - AuthoritysOriginId::Root => as EnsureOrigin>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())), - AuthoritysOriginId::SetheumTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } - AuthoritysOriginId::SettwayTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } - AuthoritysOriginId::SIF => { - , BlockNumber, OriginCaller> as EnsureOrigin< + AuthoritysOriginId::Root => as EnsureOrigin>::ensure_origin(origin) + .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())), + AuthoritysOriginId::SetheumTreasury => { + as EnsureOrigin< + Origin, + >>::ensure_origin(origin) + .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) + } + AuthoritysOriginId::SettwayTreasury => { + as EnsureOrigin< Origin, >>::ensure_origin(origin) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) + } } - } }) } } diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index d0c8340a8..192db5a5f 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -133,8 +133,6 @@ parameter_types! { pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); - // Decentralized Sovereign Wealth Fund - pub const SIFPalletId: PalletId = PalletId(*b"set/dsif"); pub const NftPalletId: PalletId = PalletId(*b"set/aNFT"); } @@ -146,7 +144,6 @@ pub fn get_all_setheum_accounts() -> Vec { SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), IncentivesPalletId::get().into_account(), - SIFPalletId::get().into_account(), ZeroAccountId::get(), ] } @@ -933,29 +930,28 @@ impl dex::Config for Runtime { } parameter_types! { - pub const MaxAuctionsCount: u32 = 100; + pub const MaxAuctionsCount: u32 = 258; pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); - pub SerplusSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to buy back & burn NativeCurrency. - pub SettPaySerpupRatio: Rate = Rate::saturating_from_rational(6 : 10); // 60% of SerpUp to SettPay as Cashdrops. - pub SetheumTreasurySerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to network Treasury. - pub CharityFundSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Foundation's Charity Fund. - pub SIFSerpupRatio: Rate = Rate::saturating_from_rational(1 : 10); // 10% of SerpUp to Setheum Investment Fund (SIF) (NIF in Neom). + pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks + pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. + pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. + pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } - impl serp_treasury::Config for Runtime { type Event = Event; type Currency = Currencies; type StableCurrencyIds = StableCurrencyIds; type GetSetterCurrencyId = GetSetterCurrencyId; type GetDexerCurrencyId = GetDexerCurrencyId; + type SerpTesSchedule = SerpTesSchedule; type SerplusSerpupRatio = SerplusSerpupRatio; type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; - type SIFSerpupRatio = SIFSerpupRatio; - type SerpAuctionManagerHandler = SerpAuctionManager; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; - type Dex = Dex; + type SerpAuctionManagerHandler = MockSerpAuctionManager; + type UpdateOrigin = EnsureSignedBy; + type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = weights::serp_treasury::WeightInfo; From b1ae21e4cbd3c3fd9e86646ff0e057a8064b0fdc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 12:29:03 +0800 Subject: [PATCH 23/83] sNFT id --- runtime/neom/src/lib.rs | 2 +- runtime/newrome/src/lib.rs | 2 +- runtime/setheum/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index a0235673f..8412c6e0c 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -132,7 +132,7 @@ parameter_types! { pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); - pub const NftPalletId: PalletId = PalletId(*b"set/aNFT"); + pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } // TODO: Update diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index 533c89cd0..d6e9163fe 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -134,7 +134,7 @@ parameter_types! { pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); - pub const NftPalletId: PalletId = PalletId(*b"set/aNFT"); + pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } pub fn get_all_setheum_accounts() -> Vec { diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index 192db5a5f..fcf4ca798 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -133,7 +133,7 @@ parameter_types! { pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); - pub const NftPalletId: PalletId = PalletId(*b"set/aNFT"); + pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } pub fn get_all_setheum_accounts() -> Vec { From 0df3bec4b8144123fa0656d726e1567a2a597103 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 22 Jun 2021 23:50:03 +0800 Subject: [PATCH 24/83] update ChainBridge primitives --- lib-serml/chainbridge/src/lib.rs | 4 ++-- lib-serml/chainbridge/src/mock.rs | 2 +- lib-serml/dex/src/lib.rs | 1 + lib-serml/evm-manager/src/lib.rs | 8 ++++---- primitives/src/currency.rs | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib-serml/chainbridge/src/lib.rs b/lib-serml/chainbridge/src/lib.rs index 479d1a891..f3e738b67 100644 --- a/lib-serml/chainbridge/src/lib.rs +++ b/lib-serml/chainbridge/src/lib.rs @@ -103,10 +103,10 @@ pub mod module { ); let check_match = if Self::is_origin_chain_resource(resource_id) { - !matches!(currency_id, CurrencyId::ChainSafe(_)) + !matches!(currency_id, CurrencyId::ChainBridge(_)) } else { match currency_id { - CurrencyId::ChainSafe(r_id) => r_id == resource_id, + CurrencyId::ChainBridge(r_id) => r_id == resource_id, _ => false, } }; diff --git a/lib-serml/chainbridge/src/mock.rs b/lib-serml/chainbridge/src/mock.rs index a22ef9a97..e64f72f0b 100644 --- a/lib-serml/chainbridge/src/mock.rs +++ b/lib-serml/chainbridge/src/mock.rs @@ -94,7 +94,7 @@ parameter_types! { pub DNARResourceId: chainbridge::ResourceId = chainbridge::derive_resource_id(LocalChainId::get(), b"DNAR"); pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub WETHResourceId: chainbridge::ResourceId = chainbridge::derive_resource_id(0, b"weth"); - pub WETH: CurrencyId = CurrencyId::ChainSafe(WETHResourceId::get()); + pub WETH: CurrencyId = CurrencyId::ChainBridge(WETHResourceId::get()); } impl chainbridge::Config for Runtime { diff --git a/lib-serml/dex/src/lib.rs b/lib-serml/dex/src/lib.rs index b15d850d1..6d3485175 100644 --- a/lib-serml/dex/src/lib.rs +++ b/lib-serml/dex/src/lib.rs @@ -905,6 +905,7 @@ impl Pallet { } } + // TODO: Set Custom Governed FlexibleTradingFees for each path fn get_target_amounts( path: &[CurrencyId], supply_amount: Balance, diff --git a/lib-serml/evm-manager/src/lib.rs b/lib-serml/evm-manager/src/lib.rs index 10c66d28b..0b76dc3f6 100644 --- a/lib-serml/evm-manager/src/lib.rs +++ b/lib-serml/evm-manager/src/lib.rs @@ -151,7 +151,7 @@ impl CurrencyIdMapping for EvmCurrencyIdMapping { CurrencyId::Erc20(address) => CurrencyIdMap::::get(Into::::into(DexShare::Erc20(address))) .filter(|v| v.address == address) .map(|v| v.name), - CurrencyId::ChainSafe(_) => None, + CurrencyId::ChainBridge(_) => None, }?; // More than 32 bytes will be truncated. @@ -192,7 +192,7 @@ impl CurrencyIdMapping for EvmCurrencyIdMapping { CurrencyId::Erc20(address) => CurrencyIdMap::::get(Into::::into(DexShare::Erc20(address))) .filter(|v| v.address == address) .map(|v| v.symbol), - CurrencyId::ChainSafe(_) => None, + CurrencyId::ChainBridge(_) => None, }?; // More than 32 bytes will be truncated. @@ -228,7 +228,7 @@ impl CurrencyIdMapping for EvmCurrencyIdMapping { CurrencyId::Erc20(address) => CurrencyIdMap::::get(Into::::into(DexShare::Erc20(address))) .filter(|v| v.address == address) .map(|v| v.decimals), - CurrencyId::ChainSafe(_) => None, + CurrencyId::ChainBridge(_) => None, } } @@ -258,7 +258,7 @@ impl CurrencyIdMapping for EvmCurrencyIdMapping { Some(prefix | EvmAddress::from_low_u64_be(u64::from(symbol_0) << 32 | u64::from(symbol_1))) } - // Token or Erc20 or ChainSafe + // Token or Erc20 or ChainBridge _ => EvmAddress::try_from(v).ok(), } } diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index b95e3465e..b406c47af 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -349,7 +349,7 @@ pub enum CurrencyId { Token(TokenSymbol), DexShare(DexShare, DexShare), Erc20(EvmAddress), - ChainSafe(chainbridge::ResourceId), + ChainBridge(chainbridge::ResourceId), } impl CurrencyId { @@ -433,7 +433,7 @@ impl TryFrom for EvmAddress { Ok(prefix | EvmAddress::from_low_u64_be(u64::from(symbol_0) << 32 | u64::from(symbol_1))) } CurrencyId::Erc20(address) => Ok(address), - CurrencyId::ChainSafe(_) => Err(()), + CurrencyId::ChainBridge(_) => Err(()), } } } From 4d273f2c22c5eb4939abe676fb0cc325d7243324 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 00:21:01 +0800 Subject: [PATCH 25/83] Support EVM and ERC20in setheum_currencies --- lib-serml/currencies/Cargo.toml | 4 + lib-serml/currencies/src/default_weight.rs | 29 - lib-serml/currencies/src/lib.rs | 437 +++++++----- lib-serml/currencies/src/mock.rs | 149 +++- lib-serml/currencies/src/tests.rs | 671 ++++++++++++++++-- lib-serml/currencies/src/weights.rs | 57 +- lib-serml/dex/src/weights.rs | 1 - lib-serml/evm-accounts/src/weights.rs | 1 - lib-serml/evm/src/weights.rs | 1 - lib-serml/incentives/src/weights.rs | 1 - lib-serml/nft/src/weights.rs | 1 - lib-serml/prices/src/weights.rs | 1 - lib-serml/serp-auction/src/weights.rs | 1 - lib-serml/serp-treasury/src/weights.rs | 1 - lib-serml/settway/src/weights.rs | 1 - lib-serml/transaction-payment/src/weights.rs | 1 - runtime/neom/src/weights/orml_auction.rs | 1 - runtime/neom/src/weights/orml_authority.rs | 1 - runtime/neom/src/weights/orml_oracle.rs | 1 - runtime/neom/src/weights/orml_rewards.rs | 1 - runtime/neom/src/weights/orml_tokens.rs | 1 - runtime/neom/src/weights/orml_vesting.rs | 1 - .../src/weights/setheum_auction_manager.rs | 1 - .../neom/src/weights/setheum_currencies.rs | 1 - runtime/neom/src/weights/setheum_dex.rs | 1 - .../neom/src/weights/setheum_incentives.rs | 1 - runtime/neom/src/weights/setheum_nft.rs | 1 - runtime/neom/src/weights/setheum_prices.rs | 1 - runtime/neom/src/weights/setheum_serp.rs | 1 - .../src/weights/setheum_settmint_treasury.rs | 1 - .../weights/setheum_transaction_payment.rs | 1 - .../src/weights/module_transaction_payment.rs | 1 - runtime/newrome/src/weights/orml_auction.rs | 1 - runtime/newrome/src/weights/orml_authority.rs | 1 - runtime/newrome/src/weights/orml_oracle.rs | 1 - runtime/newrome/src/weights/orml_rewards.rs | 1 - runtime/newrome/src/weights/orml_tokens.rs | 1 - runtime/newrome/src/weights/orml_vesting.rs | 1 - .../src/weights/setheum_auction_manager.rs | 1 - .../newrome/src/weights/setheum_currencies.rs | 1 - runtime/newrome/src/weights/setheum_dex.rs | 1 - .../newrome/src/weights/setheum_incentives.rs | 1 - runtime/newrome/src/weights/setheum_nft.rs | 1 - runtime/newrome/src/weights/setheum_prices.rs | 1 - runtime/newrome/src/weights/setheum_serp.rs | 1 - .../src/weights/setheum_settmint_treasury.rs | 1 - runtime/setheum/src/weights/orml_auction.rs | 1 - runtime/setheum/src/weights/orml_authority.rs | 1 - runtime/setheum/src/weights/orml_oracle.rs | 1 - runtime/setheum/src/weights/orml_rewards.rs | 1 - runtime/setheum/src/weights/orml_tokens.rs | 1 - runtime/setheum/src/weights/orml_vesting.rs | 1 - .../src/weights/setheum_auction_manager.rs | 1 - .../setheum/src/weights/setheum_currencies.rs | 1 - runtime/setheum/src/weights/setheum_dex.rs | 1 - .../setheum/src/weights/setheum_incentives.rs | 1 - runtime/setheum/src/weights/setheum_nft.rs | 1 - runtime/setheum/src/weights/setheum_prices.rs | 1 - runtime/setheum/src/weights/setheum_serp.rs | 1 - .../src/weights/setheum_settmint_treasury.rs | 1 - .../weights/setheum_transaction_payment.rs | 1 - 61 files changed, 1032 insertions(+), 370 deletions(-) delete mode 100644 lib-serml/currencies/src/default_weight.rs diff --git a/lib-serml/currencies/Cargo.toml b/lib-serml/currencies/Cargo.toml index b29a38591..a0f64b18f 100644 --- a/lib-serml/currencies/Cargo.toml +++ b/lib-serml/currencies/Cargo.toml @@ -24,12 +24,15 @@ orml-utilities = { path = "../../lib-openrml/utilities", default-features = fals # local dependencies primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } +support = { path = "../support", default-features = false } [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } tokens = { package = "orml-tokens", path = "../../lib-openrml/tokens" } +setheum-evm = { path = "../evm" } +setheum-evm-bridge = { path = "../evm-bridge" } [features] default = ["std"] @@ -45,5 +48,6 @@ std = [ "orml-traits/std", "orml-utilities/std", "primitives/std", + "support/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/lib-serml/currencies/src/default_weight.rs b/lib-serml/currencies/src/default_weight.rs deleted file mode 100644 index 079c8ced4..000000000 --- a/lib-serml/currencies/src/default_weight.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 - -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(clippy::unnecessary_cast)] - -use frame_support::weights::{constants::RocksDbWeight as DbWeight, Weight}; - -impl crate::WeightInfo for () { - fn transfer_non_native_currency() -> Weight { - (172_011_000 as Weight) - .saturating_add(DbWeight::get().reads(5 as Weight)) - .saturating_add(DbWeight::get().writes(2 as Weight)) - } - fn transfer_native_currency() -> Weight { - (43_023_000 as Weight) - } - fn update_balance_non_native_currency() -> Weight { - (137_440_000 as Weight) - .saturating_add(DbWeight::get().reads(5 as Weight)) - .saturating_add(DbWeight::get().writes(2 as Weight)) - } - fn update_balance_native_currency_creating() -> Weight { - (64_432_000 as Weight) - } - fn update_balance_native_currency_killing() -> Weight { - (62_595_000 as Weight) - } -} diff --git a/lib-serml/currencies/src/lib.rs b/lib-serml/currencies/src/lib.rs index dbf569257..1abcc6dea 100644 --- a/lib-serml/currencies/src/lib.rs +++ b/lib-serml/currencies/src/lib.rs @@ -20,6 +20,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::unused_unit)] +#![allow(clippy::upper_case_acronyms)] use codec::Codec; use frame_support::{ @@ -37,9 +38,10 @@ use orml_traits::{ BalanceStatus, BasicCurrency, BasicCurrencyExtended, BasicLockableCurrency, BasicReservableCurrency, LockIdentifier, MultiCurrency, MultiCurrencyExtended, MultiLockableCurrency, MultiReservableCurrency, }; -use primitives::CurrencyId; +use primitives::{evm::EvmAddress, CurrencyId}; +use sp_io::hashing::blake2_256; use sp_runtime::{ - traits::{CheckedSub, MaybeSerializeDeserialize, StaticLookup, Zero}, + traits::{CheckedSub, MaybeSerializeDeserialize, Saturating, StaticLookup, Zero}, DispatchError, DispatchResult, }; use sp_std::{ @@ -47,10 +49,11 @@ use sp_std::{ fmt::Debug, marker, result, }; +use support::{AddressMapping, EVMBridge, InvokeContext}; mod mock; mod tests; -mod weights; +pub mod weights; pub use module::*; pub use weights::WeightInfo; @@ -83,6 +86,10 @@ pub mod module { /// Weight information for extrinsics in this module. type WeightInfo: WeightInfo; + + /// Mapping from address to account id. + type AddressMapping: AddressMapping; + type EVMBridge: EVMBridge>; } #[pallet::error] @@ -91,8 +98,10 @@ pub mod module { AmountIntoBalanceFailed, /// Balance is too low. BalanceTooLow, - /// Invalid Currency Type. - InvalidCurrencyType, + /// Erc20 invalid operation + Erc20InvalidOperation, + /// EVM account not found + EvmAccountNotFound, } #[pallet::event] @@ -126,14 +135,9 @@ pub mod module { dest: ::Source, currency_id: CurrencyIdOf, #[pallet::compact] amount: BalanceOf, - // TODO: Add `claim_cashdrop: bool`, and if yes then call clain_cashdrop(origin, currency_id, amount) to claim cashdrop. ) -> DispatchResultWithPostInfo { let from = ensure_signed(origin)?; let to = T::Lookup::lookup(dest)?; - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); >::transfer(currency_id, &from, &to, amount)?; Ok(().into()) } @@ -168,10 +172,6 @@ pub mod module { ) -> DispatchResultWithPostInfo { ensure_root(origin)?; let dest = T::Lookup::lookup(who)?; - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); >::update_balance(currency_id, &dest, amount)?; Ok(().into()) } @@ -183,62 +183,80 @@ impl MultiCurrency for Pallet { type Balance = BalanceOf; fn minimum_balance(currency_id: Self::CurrencyId) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::minimum_balance() - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::minimum_balance(currency_id) + match currency_id { + CurrencyId::Erc20(_) => Default::default(), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::minimum_balance(), + _ => T::MultiCurrency::minimum_balance(currency_id), } } fn total_issuance(currency_id: Self::CurrencyId) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::total_issuance() - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::total_issuance(currency_id) + match currency_id { + CurrencyId::Erc20(contract) => T::EVMBridge::total_supply(InvokeContext { + contract, + sender: Default::default(), + origin: Default::default(), + }) + .unwrap_or_default(), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::total_issuance(), + _ => T::MultiCurrency::total_issuance(currency_id), } } fn total_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::total_balance(who) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::total_balance(currency_id, who) + match currency_id { + CurrencyId::Erc20(contract) => { + if let Some(address) = T::AddressMapping::get_evm_address(&who) { + let context = InvokeContext { + contract, + sender: Default::default(), + origin: Default::default(), + }; + return T::EVMBridge::balance_of(context, address).unwrap_or_default(); + } + Default::default() + } + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::total_balance(who), + _ => T::MultiCurrency::total_balance(currency_id, who), } } fn free_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::free_balance(who) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::free_balance(currency_id, who) + match currency_id { + CurrencyId::Erc20(contract) => { + if let Some(address) = T::AddressMapping::get_evm_address(&who) { + let context = InvokeContext { + contract, + sender: Default::default(), + origin: Default::default(), + }; + return T::EVMBridge::balance_of(context, address).unwrap_or_default(); + } + Default::default() + } + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::free_balance(who), + _ => T::MultiCurrency::free_balance(currency_id, who), } } fn ensure_can_withdraw(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::ensure_can_withdraw(who, amount) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::ensure_can_withdraw(currency_id, who, amount) + match currency_id { + CurrencyId::Erc20(contract) => { + let address = T::AddressMapping::get_evm_address(&who).ok_or(Error::::EvmAccountNotFound)?; + let balance = T::EVMBridge::balance_of( + InvokeContext { + contract, + sender: Default::default(), + origin: Default::default(), + }, + address, + ) + .unwrap_or_default(); + ensure!(balance >= amount, Error::::BalanceTooLow); + Ok(()) + } + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::ensure_can_withdraw(who, amount), + _ => T::MultiCurrency::ensure_can_withdraw(currency_id, who, amount), } } @@ -251,15 +269,27 @@ impl MultiCurrency for Pallet { if amount.is_zero() || from == to { return Ok(()); } - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::transfer(from, to, amount)?; - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::transfer(currency_id, from, to, amount)?; + + match currency_id { + CurrencyId::Erc20(contract) => { + let sender = T::AddressMapping::get_evm_address(&from).ok_or(Error::::EvmAccountNotFound)?; + let origin = T::EVMBridge::get_origin().unwrap_or_default(); + let origin_address = T::AddressMapping::get_or_create_evm_address(&origin); + let address = T::AddressMapping::get_or_create_evm_address(&to); + T::EVMBridge::transfer( + InvokeContext { + contract, + sender, + origin: origin_address, + }, + address, + amount, + )?; + } + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::transfer(from, to, amount)?, + _ => T::MultiCurrency::transfer(currency_id, from, to, amount)?, } + Self::deposit_event(Event::Transferred(currency_id, from.clone(), to.clone(), amount)); Ok(()) } @@ -268,14 +298,10 @@ impl MultiCurrency for Pallet { if amount.is_zero() { return Ok(()); } - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::deposit(who, amount)?; - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::deposit(currency_id, who, amount)?; + match currency_id { + CurrencyId::Erc20(_) => return Err(Error::::Erc20InvalidOperation.into()), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::deposit(who, amount)?, + _ => T::MultiCurrency::deposit(currency_id, who, amount)?, } Self::deposit_event(Event::Deposited(currency_id, who.clone(), amount)); Ok(()) @@ -285,40 +311,28 @@ impl MultiCurrency for Pallet { if amount.is_zero() { return Ok(()); } - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::withdraw(who, amount)?; - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::withdraw(currency_id, who, amount)?; + match currency_id { + CurrencyId::Erc20(_) => return Err(Error::::Erc20InvalidOperation.into()), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::withdraw(who, amount)?, + _ => T::MultiCurrency::withdraw(currency_id, who, amount)?, } Self::deposit_event(Event::Withdrawn(currency_id, who.clone(), amount)); Ok(()) } fn can_slash(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> bool { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::can_slash(who, amount) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::can_slash(currency_id, who, amount) + match currency_id { + CurrencyId::Erc20(_) => false, + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::can_slash(who, amount), + _ => T::MultiCurrency::can_slash(currency_id, who, amount), } } fn slash(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::slash(who, amount) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::slash(currency_id, who, amount) + match currency_id { + CurrencyId::Erc20(_) => Default::default(), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::slash(who, amount), + _ => T::MultiCurrency::slash(currency_id, who, amount), } } } @@ -327,14 +341,10 @@ impl MultiCurrencyExtended for Pallet { type Amount = AmountOf; fn update_balance(currency_id: Self::CurrencyId, who: &T::AccountId, by_amount: Self::Amount) -> DispatchResult { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::update_balance(who, by_amount)?; - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::update_balance(currency_id, who, by_amount)?; + match currency_id { + CurrencyId::Erc20(_) => return Err(Error::::Erc20InvalidOperation.into()), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::update_balance(who, by_amount)?, + _ => T::MultiCurrency::update_balance(currency_id, who, by_amount)?, } Self::deposit_event(Event::BalanceUpdated(currency_id, who.clone(), by_amount)); Ok(()) @@ -350,14 +360,10 @@ impl MultiLockableCurrency for Pallet { who: &T::AccountId, amount: Self::Balance, ) -> DispatchResult { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::set_lock(lock_id, who, amount) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::set_lock(lock_id, currency_id, who, amount) + match currency_id { + CurrencyId::Erc20(_) => Err(Error::::Erc20InvalidOperation.into()), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::set_lock(lock_id, who, amount), + _ => T::MultiCurrency::set_lock(lock_id, currency_id, who, amount), } } @@ -367,88 +373,117 @@ impl MultiLockableCurrency for Pallet { who: &T::AccountId, amount: Self::Balance, ) -> DispatchResult { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::extend_lock(lock_id, who, amount) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::extend_lock(lock_id, currency_id, who, amount) + match currency_id { + CurrencyId::Erc20(_) => Err(Error::::Erc20InvalidOperation.into()), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::extend_lock(lock_id, who, amount), + _ => T::MultiCurrency::extend_lock(lock_id, currency_id, who, amount), } } fn remove_lock(lock_id: LockIdentifier, currency_id: Self::CurrencyId, who: &T::AccountId) -> DispatchResult { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::remove_lock(lock_id, who) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::remove_lock(lock_id, currency_id, who) + match currency_id { + CurrencyId::Erc20(_) => Err(Error::::Erc20InvalidOperation.into()), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::remove_lock(lock_id, who), + _ => T::MultiCurrency::remove_lock(lock_id, currency_id, who), } } } impl MultiReservableCurrency for Pallet { fn can_reserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> bool { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::can_reserve(who, value) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::can_reserve(currency_id, who, value) + match currency_id { + CurrencyId::Erc20(_) => Self::ensure_can_withdraw(currency_id, who, value).is_ok(), + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::can_reserve(who, value), + _ => T::MultiCurrency::can_reserve(currency_id, who, value), } } fn slash_reserved(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::slash_reserved(who, value) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::slash_reserved(currency_id, who, value) + match currency_id { + CurrencyId::Erc20(_) => value, + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::slash_reserved(who, value), + _ => T::MultiCurrency::slash_reserved(currency_id, who, value), } } fn reserved_balance(currency_id: Self::CurrencyId, who: &T::AccountId) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::reserved_balance(who) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::reserved_balance(currency_id, who) + match currency_id { + CurrencyId::Erc20(contract) => { + if let Some(address) = T::AddressMapping::get_evm_address(&who) { + return T::EVMBridge::balance_of( + InvokeContext { + contract, + sender: Default::default(), + origin: Default::default(), + }, + reserve_address(address), + ) + .unwrap_or_default(); + } + Default::default() + } + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::reserved_balance(who), + _ => T::MultiCurrency::reserved_balance(currency_id, who), } } fn reserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> DispatchResult { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::reserve(who, value) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::reserve(currency_id, who, value) + match currency_id { + CurrencyId::Erc20(contract) => { + if value.is_zero() { + return Ok(()); + } + let address = T::AddressMapping::get_evm_address(&who).ok_or(Error::::EvmAccountNotFound)?; + T::EVMBridge::transfer( + InvokeContext { + contract, + sender: address, + origin: address, + }, + reserve_address(address), + value, + ) + } + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::reserve(who, value), + _ => T::MultiCurrency::reserve(currency_id, who, value), } } fn unreserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> Self::Balance { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::unreserve(who, value) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::unreserve(currency_id, who, value) + match currency_id { + CurrencyId::Erc20(contract) => { + if value.is_zero() { + return value; + } + if let Some(address) = T::AddressMapping::get_evm_address(&who) { + let sender = reserve_address(address); + let reserved_balance = T::EVMBridge::balance_of( + InvokeContext { + contract, + sender: Default::default(), + origin: Default::default(), + }, + sender, + ) + .unwrap_or_default(); + let actual = reserved_balance.min(value); + return match T::EVMBridge::transfer( + InvokeContext { + contract, + sender, + origin: address, + }, + address, + actual, + ) { + Ok(_) => value - actual, + Err(_) => value, + }; + } + value + } + id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::unreserve(who, value), + _ => T::MultiCurrency::unreserve(currency_id, who, value), } } @@ -459,14 +494,63 @@ impl MultiReservableCurrency for Pallet { value: Self::Balance, status: BalanceStatus, ) -> result::Result { - if currency_id == T::GetNativeCurrencyId::get() { - T::NativeCurrency::repatriate_reserved(slashed, beneficiary, value, status) - } else { - ensure!( - !T::FiatCurrencyIds::get().contains(¤cy_id), - Error::::InvalidCurrencyType, - ); - T::MultiCurrency::repatriate_reserved(currency_id, slashed, beneficiary, value, status) + match currency_id { + CurrencyId::Erc20(contract) => { + if value.is_zero() { + return Ok(value); + } + if slashed == beneficiary { + return match status { + BalanceStatus::Free => Ok(Self::unreserve(currency_id, slashed, value)), + BalanceStatus::Reserved => { + Ok(value.saturating_sub(Self::reserved_balance(currency_id, slashed))) + } + }; + } + + let slashed_address = + T::AddressMapping::get_evm_address(&slashed).ok_or(Error::::EvmAccountNotFound)?; + let beneficiary_address = T::AddressMapping::get_or_create_evm_address(&beneficiary); + + let slashed_reserve_address = reserve_address(slashed_address); + let beneficiary_reserve_address = reserve_address(beneficiary_address); + + let slashed_reserved_balance = T::EVMBridge::balance_of( + InvokeContext { + contract, + sender: Default::default(), + origin: Default::default(), + }, + slashed_reserve_address, + ) + .unwrap_or_default(); + let actual = slashed_reserved_balance.min(value); + match status { + BalanceStatus::Free => T::EVMBridge::transfer( + InvokeContext { + contract, + sender: slashed_reserve_address, + origin: slashed_address, + }, + beneficiary_address, + actual, + ), + BalanceStatus::Reserved => T::EVMBridge::transfer( + InvokeContext { + contract, + sender: slashed_reserve_address, + origin: slashed_address, + }, + beneficiary_reserve_address, + actual, + ), + } + .map(|_| value - actual) + } + id if id == T::GetNativeCurrencyId::get() => { + T::NativeCurrency::repatriate_reserved(slashed, beneficiary, value, status) + } + _ => T::MultiCurrency::repatriate_reserved(currency_id, slashed, beneficiary, value, status), } } } @@ -759,3 +843,8 @@ impl TransferAll for Pallet { T::NativeCurrency::transfer(source, dest, T::NativeCurrency::free_balance(source)) } } + +fn reserve_address(address: EvmAddress) -> EvmAddress { + let payload = (b"erc20:", address); + EvmAddress::from_slice(&payload.using_encoded(blake2_256)[0..20]) +} diff --git a/lib-serml/currencies/src/mock.rs b/lib-serml/currencies/src/mock.rs index a597e8d2f..aac487a8f 100644 --- a/lib-serml/currencies/src/mock.rs +++ b/lib-serml/currencies/src/mock.rs @@ -20,8 +20,7 @@ #![cfg(test)] -use super::*; -use frame_support::{parameter_types, PalletId}; +use frame_support::{assert_ok, ord_parameter_types, parameter_types, traits::GenesisBuild, PalletId}; use orml_traits::parameter_type_with_key; use primitives::{CurrencyId, TokenSymbol}; use sp_core::H256; @@ -30,6 +29,12 @@ use sp_runtime::{ traits::{AccountIdConversion, IdentityLookup}, AccountId32, Perbill, }; +use support::{mocks::MockAddressMapping, AddressMapping}; + +use super::*; +use frame_system::EnsureSignedBy; +use sp_core::{bytes::from_hex, H160}; +use sp_std::str::FromStr; pub use crate as currencies; @@ -76,17 +81,17 @@ parameter_type_with_key! { } parameter_types! { - pub DustAccount: AccountId = PalletId(*b"orml/dst").into_account(); + pub DustAccount: AccountId = PalletId(*b"serml/dst").into_account(); pub const MaxLocks: u32 = 100; } -impl orml_tokens::Config for Runtime { +impl tokens::Config for Runtime { type Event = Event; type Balance = Balance; type Amount = i64; type CurrencyId = CurrencyId; type ExistentialDeposits = ExistentialDeposits; - type OnDust = orml_tokens::TransferDust; + type OnDust = tokens::TransferDust; type WeightInfo = (); type MaxLocks = MaxLocks; } @@ -114,38 +119,138 @@ impl pallet_balances::Config for Runtime { pub type PalletBalances = pallet_balances::Pallet; +parameter_types! { + pub const MinimumPeriod: u64 = 1000; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + pub const NewContractExtraBytes: u32 = 1; + pub NetworkContractSource: H160 = alice_evm_addr(); +} + +ord_parameter_types! { + pub const CouncilAccount: AccountId32 = AccountId32::from([1u8; 32]); + pub const TreasuryAccount: AccountId32 = AccountId32::from([2u8; 32]); + pub const NetworkContractAccount: AccountId32 = AccountId32::from([0u8; 32]); + pub const StorageDepositPerByte: u128 = 10; + pub const MaxCodeSize: u32 = 60 * 1024; + pub const DeveloperDeposit: u64 = 1000; + pub const DeploymentFee: u64 = 200; +} + +impl setheum_evm::Config for Runtime { + type AddressMapping = MockAddressMapping; + type Currency = PalletBalances; + type TransferAll = (); + type NewContractExtraBytes = NewContractExtraBytes; + type StorageDepositPerByte = StorageDepositPerByte; + type MaxCodeSize = MaxCodeSize; + + type Event = Event; + type Precompiles = (); + type ChainId = (); + type GasToWeight = (); + type ChargeTransactionPayment = (); + type NetworkContractOrigin = EnsureSignedBy; + type NetworkContractSource = NetworkContractSource; + + type DeveloperDeposit = DeveloperDeposit; + type DeploymentFee = DeploymentFee; + type TreasuryAccount = TreasuryAccount; + type FreeDeploymentOrigin = EnsureSignedBy; + + type WeightInfo = (); +} + +impl setheum_evm_bridge::Config for Runtime { + type EVM = EVM; +} + impl Config for Runtime { type Event = Event; type MultiCurrency = Tokens; type NativeCurrency = AdaptedBasicCurrency; type GetNativeCurrencyId = GetNativeCurrencyId; type WeightInfo = (); + type AddressMapping = MockAddressMapping; + type EVMBridge = EVMBridge; } pub type NativeCurrency = Currency; pub type AdaptedBasicCurrency = BasicCurrencyAdapter; -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -type Block = frame_system::mocking::MockBlock; +pub type SignedExtra = setheum_evm::SetEvmOrigin; + +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( pub enum Runtime where Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + Tokens: tokens::{Pallet, Storage, Event, Config}, Currencies: currencies::{Pallet, Call, Event}, + EVM: setheum_evm::{Pallet, Config, Call, Storage, Event}, + EVMBridge: setheum_evm_bridge::{Pallet}, } ); -pub const ALICE: AccountId = AccountId32::new([1u8; 32]); -pub const BOB: AccountId = AccountId32::new([2u8; 32]); -pub const EVA: AccountId = AccountId32::new([5u8; 32]); +pub fn alice() -> AccountId { + ::AddressMapping::get_account_id(&alice_evm_addr()) +} + +pub fn alice_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000001").unwrap() +} + +pub fn bob() -> AccountId { + ::AddressMapping::get_account_id(&bob_evm_addr()) +} + +pub fn bob_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000002").unwrap() +} + +pub fn eva() -> AccountId { + ::AddressMapping::get_account_id(&eva_evm_addr()) +} + +pub fn eva_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000005").unwrap() +} + pub const ID_1: LockIdentifier = *b"1 "; +pub fn erc20_address() -> EvmAddress { + EvmAddress::from_str("0000000000000000000000000000000002000000").unwrap() +} + +pub fn deploy_contracts() { + let code = from_hex(include!("../../evm-bridge/src/erc20_demo_contract")).unwrap(); + assert_ok!(EVM::create_network_contract( + Origin::signed(NetworkContractAccount::get()), + code, + 0, + 2100_000, + 10000 + )); + + let event = Event::module_evm(module_evm::Event::Created(erc20_address())); + assert_eq!(System::events().iter().last().unwrap().event, event); + + assert_ok!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), erc20_address())); +} + pub struct ExtBuilder { endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>, } @@ -166,10 +271,10 @@ impl ExtBuilder { pub fn one_hundred_for_alice_n_bob(self) -> Self { self.balances(vec![ - (ALICE, NATIVE_CURRENCY_ID, 100), - (BOB, NATIVE_CURRENCY_ID, 100), - (ALICE, X_TOKEN_ID, 100), - (BOB, X_TOKEN_ID, 100), + (alice(), NATIVE_CURRENCY_ID, 100), + (bob(), NATIVE_CURRENCY_ID, 100), + (alice(), X_TOKEN_ID, 100), + (bob(), X_TOKEN_ID, 100), ]) } @@ -190,7 +295,7 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - orml_tokens::GenesisConfig:: { + tokens::GenesisConfig:: { endowed_accounts: self .endowed_accounts .into_iter() @@ -200,6 +305,12 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - t.into() + module_evm::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } } diff --git a/lib-serml/currencies/src/tests.rs b/lib-serml/currencies/src/tests.rs index 5868510f4..3163bfb5b 100644 --- a/lib-serml/currencies/src/tests.rs +++ b/lib-serml/currencies/src/tests.rs @@ -22,8 +22,13 @@ use super::*; use frame_support::{assert_noop, assert_ok}; -use mock::{Event, *}; +use mock::{ + alice, bob, deploy_contracts, erc20_address, eva, AccountId, AdaptedBasicCurrency, Currencies, Event, ExtBuilder, + NativeCurrency, Origin, PalletBalances, Runtime, System, Tokens, EVM, ID_1, NATIVE_CURRENCY_ID, X_TOKEN_ID, +}; +use sp_core::H160; use sp_runtime::traits::BadOrigin; +use support::EVM as EVMTrait; #[test] fn multi_lockable_currency_should_work() { @@ -31,10 +36,10 @@ fn multi_lockable_currency_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(Currencies::set_lock(ID_1, X_TOKEN_ID, &ALICE, 50)); - assert_eq!(Tokens::locks(&ALICE, X_TOKEN_ID).len(), 1); - assert_ok!(Currencies::set_lock(ID_1, NATIVE_CURRENCY_ID, &ALICE, 50)); - assert_eq!(PalletBalances::locks(&ALICE).len(), 1); + assert_ok!(Currencies::set_lock(ID_1, X_TOKEN_ID, &alice(), 50)); + assert_eq!(Tokens::locks(&alice(), X_TOKEN_ID).len(), 1); + assert_ok!(Currencies::set_lock(ID_1, NATIVE_CURRENCY_ID, &alice(), 50)); + assert_eq!(PalletBalances::locks(&alice()).len(), 1); }); } @@ -46,13 +51,13 @@ fn multi_reservable_currency_should_work() { .execute_with(|| { assert_eq!(Currencies::total_issuance(NATIVE_CURRENCY_ID), 200); assert_eq!(Currencies::total_issuance(X_TOKEN_ID), 200); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 100); - assert_eq!(NativeCurrency::free_balance(&ALICE), 100); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 100); + assert_eq!(NativeCurrency::free_balance(&alice()), 100); - assert_ok!(Currencies::reserve(X_TOKEN_ID, &ALICE, 30)); - assert_ok!(Currencies::reserve(NATIVE_CURRENCY_ID, &ALICE, 40)); - assert_eq!(Currencies::reserved_balance(X_TOKEN_ID, &ALICE), 30); - assert_eq!(Currencies::reserved_balance(NATIVE_CURRENCY_ID, &ALICE), 40); + assert_ok!(Currencies::reserve(X_TOKEN_ID, &alice(), 30)); + assert_ok!(Currencies::reserve(NATIVE_CURRENCY_ID, &alice(), 40)); + assert_eq!(Currencies::reserved_balance(X_TOKEN_ID, &alice()), 30); + assert_eq!(Currencies::reserved_balance(NATIVE_CURRENCY_ID, &alice()), 40); }); } @@ -62,10 +67,10 @@ fn native_currency_lockable_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(NativeCurrency::set_lock(ID_1, &ALICE, 10)); - assert_eq!(PalletBalances::locks(&ALICE).len(), 1); - assert_ok!(NativeCurrency::remove_lock(ID_1, &ALICE)); - assert_eq!(PalletBalances::locks(&ALICE).len(), 0); + assert_ok!(NativeCurrency::set_lock(ID_1, &alice(), 10)); + assert_eq!(PalletBalances::locks(&alice()).len(), 1); + assert_ok!(NativeCurrency::remove_lock(ID_1, &alice())); + assert_eq!(PalletBalances::locks(&alice()).len(), 0); }); } @@ -75,8 +80,8 @@ fn native_currency_reservable_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(NativeCurrency::reserve(&ALICE, 50)); - assert_eq!(NativeCurrency::reserved_balance(&ALICE), 50); + assert_ok!(NativeCurrency::reserve(&alice(), 50)); + assert_eq!(NativeCurrency::reserved_balance(&alice()), 50); }); } @@ -86,10 +91,10 @@ fn basic_currency_adapting_pallet_balances_lockable() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::set_lock(ID_1, &ALICE, 10)); - assert_eq!(PalletBalances::locks(&ALICE).len(), 1); - assert_ok!(AdaptedBasicCurrency::remove_lock(ID_1, &ALICE)); - assert_eq!(PalletBalances::locks(&ALICE).len(), 0); + assert_ok!(AdaptedBasicCurrency::set_lock(ID_1, &alice(), 10)); + assert_eq!(PalletBalances::locks(&alice()).len(), 1); + assert_ok!(AdaptedBasicCurrency::remove_lock(ID_1, &alice())); + assert_eq!(PalletBalances::locks(&alice()).len(), 0); }); } @@ -99,8 +104,8 @@ fn basic_currency_adapting_pallet_balances_reservable() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::reserve(&ALICE, 50)); - assert_eq!(AdaptedBasicCurrency::reserved_balance(&ALICE), 50); + assert_ok!(AdaptedBasicCurrency::reserve(&alice(), 50)); + assert_eq!(AdaptedBasicCurrency::reserved_balance(&alice()), 50); }); } @@ -110,9 +115,10 @@ fn multi_currency_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(Currencies::transfer(Some(ALICE).into(), BOB, X_TOKEN_ID, 50)); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 50); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &BOB), 150); + >::set_origin(alice()); + assert_ok!(Currencies::transfer(Some(alice()).into(), bob(), X_TOKEN_ID, 50)); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 50); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &bob()), 150); }); } @@ -123,9 +129,11 @@ fn multi_currency_extended_should_work() { .build() .execute_with(|| { assert_ok!(>::update_balance( - X_TOKEN_ID, &ALICE, 50 + X_TOKEN_ID, + &alice(), + 50 )); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 150); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 150); }); } @@ -135,16 +143,16 @@ fn native_currency_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(Currencies::transfer_native_currency(Some(ALICE).into(), BOB, 50)); - assert_eq!(NativeCurrency::free_balance(&ALICE), 50); - assert_eq!(NativeCurrency::free_balance(&BOB), 150); + assert_ok!(Currencies::transfer_native_currency(Some(alice()).into(), bob(), 50)); + assert_eq!(NativeCurrency::free_balance(&alice()), 50); + assert_eq!(NativeCurrency::free_balance(&bob()), 150); - assert_ok!(NativeCurrency::transfer(&ALICE, &BOB, 10)); - assert_eq!(NativeCurrency::free_balance(&ALICE), 40); - assert_eq!(NativeCurrency::free_balance(&BOB), 160); + assert_ok!(NativeCurrency::transfer(&alice(), &bob(), 10)); + assert_eq!(NativeCurrency::free_balance(&alice()), 40); + assert_eq!(NativeCurrency::free_balance(&bob()), 160); - assert_eq!(Currencies::slash(NATIVE_CURRENCY_ID, &ALICE, 10), 0); - assert_eq!(NativeCurrency::free_balance(&ALICE), 30); + assert_eq!(Currencies::slash(NATIVE_CURRENCY_ID, &alice(), 10), 0); + assert_eq!(NativeCurrency::free_balance(&alice()), 30); assert_eq!(NativeCurrency::total_issuance(), 190); }); } @@ -155,15 +163,15 @@ fn native_currency_extended_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(NativeCurrency::update_balance(&ALICE, 10)); - assert_eq!(NativeCurrency::free_balance(&ALICE), 110); + assert_ok!(NativeCurrency::update_balance(&alice(), 10)); + assert_eq!(NativeCurrency::free_balance(&alice()), 110); assert_ok!(>::update_balance( NATIVE_CURRENCY_ID, - &ALICE, + &alice(), 10 )); - assert_eq!(NativeCurrency::free_balance(&ALICE), 120); + assert_eq!(NativeCurrency::free_balance(&alice()), 120); }); } @@ -173,14 +181,14 @@ fn basic_currency_adapting_pallet_balances_transfer() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::transfer(&ALICE, &BOB, 50)); - assert_eq!(PalletBalances::total_balance(&ALICE), 50); - assert_eq!(PalletBalances::total_balance(&BOB), 150); + assert_ok!(AdaptedBasicCurrency::transfer(&alice(), &bob(), 50)); + assert_eq!(PalletBalances::total_balance(&alice()), 50); + assert_eq!(PalletBalances::total_balance(&bob()), 150); // creation fee - assert_ok!(AdaptedBasicCurrency::transfer(&ALICE, &EVA, 10)); - assert_eq!(PalletBalances::total_balance(&ALICE), 40); - assert_eq!(PalletBalances::total_balance(&EVA), 10); + assert_ok!(AdaptedBasicCurrency::transfer(&alice(), &eva(), 10)); + assert_eq!(PalletBalances::total_balance(&alice()), 40); + assert_eq!(PalletBalances::total_balance(&eva()), 10); }); } @@ -190,8 +198,8 @@ fn basic_currency_adapting_pallet_balances_deposit() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::deposit(&EVA, 50)); - assert_eq!(PalletBalances::total_balance(&EVA), 50); + assert_ok!(AdaptedBasicCurrency::deposit(&eva(), 50)); + assert_eq!(PalletBalances::total_balance(&eva()), 50); assert_eq!(PalletBalances::total_issuance(), 250); }); } @@ -202,8 +210,8 @@ fn basic_currency_adapting_pallet_balances_withdraw() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::withdraw(&ALICE, 100)); - assert_eq!(PalletBalances::total_balance(&ALICE), 0); + assert_ok!(AdaptedBasicCurrency::withdraw(&alice(), 100)); + assert_eq!(PalletBalances::total_balance(&alice()), 0); assert_eq!(PalletBalances::total_issuance(), 100); }); } @@ -214,8 +222,8 @@ fn basic_currency_adapting_pallet_balances_slash() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_eq!(AdaptedBasicCurrency::slash(&ALICE, 101), 1); - assert_eq!(PalletBalances::total_balance(&ALICE), 0); + assert_eq!(AdaptedBasicCurrency::slash(&alice(), 101), 1); + assert_eq!(PalletBalances::total_balance(&alice()), 0); assert_eq!(PalletBalances::total_issuance(), 100); }); } @@ -226,8 +234,8 @@ fn basic_currency_adapting_pallet_balances_update_balance() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::update_balance(&ALICE, -10)); - assert_eq!(PalletBalances::total_balance(&ALICE), 90); + assert_ok!(AdaptedBasicCurrency::update_balance(&alice(), -10)); + assert_eq!(PalletBalances::total_balance(&alice()), 90); assert_eq!(PalletBalances::total_issuance(), 190); }); } @@ -240,14 +248,14 @@ fn update_balance_call_should_work() { .execute_with(|| { assert_ok!(Currencies::update_balance( Origin::root(), - ALICE, + alice(), NATIVE_CURRENCY_ID, -10 )); - assert_eq!(NativeCurrency::free_balance(&ALICE), 90); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 100); - assert_ok!(Currencies::update_balance(Origin::root(), ALICE, X_TOKEN_ID, 10)); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 110); + assert_eq!(NativeCurrency::free_balance(&alice()), 90); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 100); + assert_ok!(Currencies::update_balance(Origin::root(), alice(), X_TOKEN_ID, 10)); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 110); }); } @@ -255,7 +263,7 @@ fn update_balance_call_should_work() { fn update_balance_call_fails_if_not_root_origin() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - Currencies::update_balance(Some(ALICE).into(), ALICE, X_TOKEN_ID, 100), + Currencies::update_balance(Some(alice()).into(), alice(), X_TOKEN_ID, 100), BadOrigin ); }); @@ -267,30 +275,541 @@ fn call_event_should_work() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - System::set_block_number(1); - - assert_ok!(Currencies::transfer(Some(ALICE).into(), BOB, X_TOKEN_ID, 50)); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 50); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &BOB), 150); - System::assert_last_event(Event::currencies(crate::Event::Transferred(X_TOKEN_ID, ALICE, BOB, 50))); + assert_ok!(Currencies::transfer(Some(alice()).into(), bob(), X_TOKEN_ID, 50)); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 50); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &bob()), 150); + System::assert_last_event(Event::currencies(crate::Event::Transferred( + X_TOKEN_ID, + alice(), + bob(), + 50, + ))); assert_ok!(>::transfer( - X_TOKEN_ID, &ALICE, &BOB, 10 + X_TOKEN_ID, + &alice(), + &bob(), + 10 )); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 40); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &BOB), 160); - System::assert_last_event(Event::currencies(crate::Event::Transferred(X_TOKEN_ID, ALICE, BOB, 10))); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 40); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &bob()), 160); + System::assert_last_event(Event::currencies(crate::Event::Transferred( + X_TOKEN_ID, + alice(), + bob(), + 10, + ))); assert_ok!(>::deposit( - X_TOKEN_ID, &ALICE, 100 + X_TOKEN_ID, + &alice(), + 100 )); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 140); - System::assert_last_event(Event::currencies(crate::Event::Deposited(X_TOKEN_ID, ALICE, 100))); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 140); + System::assert_last_event(Event::currencies(crate::Event::Deposited(X_TOKEN_ID, alice(), 100))); assert_ok!(>::withdraw( - X_TOKEN_ID, &ALICE, 20 + X_TOKEN_ID, + &alice(), + 20 + )); + assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 120); + System::assert_last_event(Event::currencies(crate::Event::Withdrawn(X_TOKEN_ID, alice(), 20))); + }); +} + +#[test] +fn erc20_total_issuance_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!(Currencies::total_issuance(CurrencyId::Erc20(erc20_address())), 10000); + }); +} + +#[test] +fn erc20_free_balance_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + // empty address + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(H160::default()), &alice()), + 0 + ); + assert_eq!(Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), 0); + + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 10000 + ); + assert_eq!(Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), 0); + }); +} + +#[test] +fn erc20_total_balance_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + // empty address + assert_eq!( + Currencies::total_balance(CurrencyId::Erc20(H160::default()), &alice()), + 0 + ); + assert_eq!(Currencies::total_balance(CurrencyId::Erc20(H160::default()), &bob()), 0); + + assert_eq!( + Currencies::total_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 10000 + ); + assert_eq!(Currencies::total_balance(CurrencyId::Erc20(erc20_address()), &bob()), 0); + }); +} + +#[test] +fn erc20_ensure_withdraw_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + >::set_origin(alice()); + assert_ok!(Currencies::ensure_can_withdraw( + CurrencyId::Erc20(erc20_address()), + &alice(), + 100 + )); + assert_eq!( + Currencies::ensure_can_withdraw(CurrencyId::Erc20(erc20_address()), &bob(), 100), + Err(Error::::BalanceTooLow.into()), + ); + assert_ok!(Currencies::transfer( + Origin::signed(alice()), + bob(), + CurrencyId::Erc20(erc20_address()), + 100 + )); + assert_ok!(Currencies::ensure_can_withdraw( + CurrencyId::Erc20(erc20_address()), + &bob(), + 100 + )); + assert_eq!( + Currencies::ensure_can_withdraw(CurrencyId::Erc20(erc20_address()), &bob(), 101), + Err(Error::::BalanceTooLow.into()), + ); + }); +} + +#[test] +fn erc20_transfer_should_work() { + ExtBuilder::default() + .balances(vec![ + (alice(), NATIVE_CURRENCY_ID, 100000), + (bob(), NATIVE_CURRENCY_ID, 100000), + ]) + .build() + .execute_with(|| { + deploy_contracts(); + let alice_balance = 10000; + >::set_origin(alice()); + >::set_origin(bob()); + assert_ok!(Currencies::transfer( + Origin::signed(alice()), + bob(), + CurrencyId::Erc20(erc20_address()), + 100 + )); + + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 100 + ); + assert_eq!( + Currencies::total_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 100 + ); + + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance - 100 + ); + assert_eq!( + Currencies::total_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance - 100 + ); + + assert_ok!(Currencies::transfer( + Origin::signed(bob()), + alice(), + CurrencyId::Erc20(erc20_address()), + 10 )); - assert_eq!(Currencies::free_balance(X_TOKEN_ID, &ALICE), 120); - System::assert_last_event(Event::currencies(crate::Event::Withdrawn(X_TOKEN_ID, ALICE, 20))); + + assert_eq!(Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), 90); + assert_eq!( + Currencies::total_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 90 + ); + + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance - 90 + ); + assert_eq!( + Currencies::total_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance - 90 + ); + }); +} + +#[test] +fn erc20_transfer_should_fail() { + ExtBuilder::default() + .balances(vec![ + (alice(), NATIVE_CURRENCY_ID, 100000), + (bob(), NATIVE_CURRENCY_ID, 100000), + ]) + .build() + .execute_with(|| { + deploy_contracts(); + >::set_origin(alice()); + >::set_origin(bob()); + // empty address + assert!( + Currencies::transfer(Origin::signed(alice()), bob(), CurrencyId::Erc20(H160::default()), 100).is_err() + ); + + // bob can't transfer. bob balance 0 + assert!( + Currencies::transfer(Origin::signed(bob()), alice(), CurrencyId::Erc20(erc20_address()), 1).is_err() + ); + }); +} + +#[test] +fn erc20_can_reserve_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!( + Currencies::can_reserve(CurrencyId::Erc20(erc20_address()), &alice(), 1), + true + ); + }); +} + +#[test] +fn erc20_slash_reserve_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!( + Currencies::slash_reserved(CurrencyId::Erc20(erc20_address()), &alice(), 1), + 1 + ); + assert_ok!(Currencies::reserve(CurrencyId::Erc20(erc20_address()), &alice(), 100)); + assert_eq!( + Currencies::slash_reserved(CurrencyId::Erc20(erc20_address()), &alice(), 10), + 10 + ); + }); +} + +#[test] +fn erc20_reserve_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + let alice_balance = 10000; + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 0 + ); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance + ); + + assert_ok!(Currencies::reserve(CurrencyId::Erc20(erc20_address()), &alice(), 100)); + + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 100 + ); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance - 100 + ); + }); +} + +#[test] +fn erc20_unreserve_should_work() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + let alice_balance = 10000; + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 0 + ); + assert_eq!( + Currencies::unreserve(CurrencyId::Erc20(erc20_address()), &alice(), 0), + 0 + ); + assert_eq!( + Currencies::unreserve(CurrencyId::Erc20(erc20_address()), &alice(), 50), + 50 + ); + assert_ok!(Currencies::reserve(CurrencyId::Erc20(erc20_address()), &alice(), 30)); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance - 30 + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 30 + ); + assert_eq!( + Currencies::unreserve(CurrencyId::Erc20(erc20_address()), &alice(), 15), + 0 + ); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance - 15 + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 15 + ); + assert_eq!( + Currencies::unreserve(CurrencyId::Erc20(erc20_address()), &alice(), 30), + 15 + ); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 0 + ); + }); +} + +#[test] +fn erc20_should_not_slash() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_eq!( + Currencies::can_slash(CurrencyId::Erc20(erc20_address()), &alice(), 1), + false + ); + // calling slash will return 0 + assert_eq!(Currencies::slash(CurrencyId::Erc20(erc20_address()), &alice(), 1), 0); + }); +} + +#[test] +fn erc20_should_not_be_lockable() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_noop!( + Currencies::set_lock(ID_1, CurrencyId::Erc20(erc20_address()), &alice(), 1), + Error::::Erc20InvalidOperation + ); + assert_noop!( + Currencies::extend_lock(ID_1, CurrencyId::Erc20(erc20_address()), &alice(), 1), + Error::::Erc20InvalidOperation + ); + assert_noop!( + Currencies::remove_lock(ID_1, CurrencyId::Erc20(erc20_address()), &alice()), + Error::::Erc20InvalidOperation + ); + }); +} + +#[test] +fn erc20_repatriate_reserved_should_work() { + ExtBuilder::default() + .balances(vec![ + (alice(), NATIVE_CURRENCY_ID, 100000), + (bob(), NATIVE_CURRENCY_ID, 100000), + ]) + .build() + .execute_with(|| { + deploy_contracts(); + let bob_balance = 100; + let alice_balance = 10000 - bob_balance; + >::set_origin(alice()); + assert_ok!(Currencies::transfer( + Origin::signed(alice()), + bob(), + CurrencyId::Erc20(erc20_address()), + bob_balance + )); + + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 0 + ); + assert_eq!( + Currencies::repatriate_reserved( + CurrencyId::Erc20(erc20_address()), + &alice(), + &alice(), + 0, + BalanceStatus::Free + ), + Ok(0) + ); + assert_eq!( + Currencies::repatriate_reserved( + CurrencyId::Erc20(erc20_address()), + &alice(), + &alice(), + 50, + BalanceStatus::Free + ), + Ok(50) + ); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 0 + ); + + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), + bob_balance + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 0 + ); + assert_ok!(Currencies::reserve(CurrencyId::Erc20(erc20_address()), &bob(), 50)); + assert_eq!(Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), 50); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 50 + ); + assert_eq!( + Currencies::repatriate_reserved( + CurrencyId::Erc20(erc20_address()), + &bob(), + &bob(), + 60, + BalanceStatus::Reserved + ), + Ok(10) + ); + assert_eq!(Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), 50); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 50 + ); + + assert_eq!( + Currencies::repatriate_reserved( + CurrencyId::Erc20(erc20_address()), + &bob(), + &alice(), + 30, + BalanceStatus::Reserved + ), + Ok(0) + ); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 30 + ); + assert_eq!(Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), 50); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 20 + ); + + assert_eq!( + Currencies::repatriate_reserved( + CurrencyId::Erc20(erc20_address()), + &bob(), + &alice(), + 30, + BalanceStatus::Free + ), + Ok(10) + ); + assert_eq!( + Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &alice()), + alice_balance + 20 + ); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &alice()), + 30 + ); + assert_eq!(Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &bob()), 50); + assert_eq!( + Currencies::reserved_balance(CurrencyId::Erc20(erc20_address()), &bob()), + 0 + ); + }); +} + +#[test] +fn erc20_invalid_operation() { + ExtBuilder::default() + .balances(vec![(alice(), NATIVE_CURRENCY_ID, 100000)]) + .build() + .execute_with(|| { + deploy_contracts(); + assert_noop!( + Currencies::deposit(CurrencyId::Erc20(erc20_address()), &alice(), 1), + Error::::Erc20InvalidOperation + ); + assert_noop!( + Currencies::withdraw(CurrencyId::Erc20(erc20_address()), &alice(), 1), + Error::::Erc20InvalidOperation + ); + assert_noop!( + Currencies::update_balance(Origin::root(), alice(), CurrencyId::Erc20(erc20_address()), 1), + Error::::Erc20InvalidOperation, + ); }); } diff --git a/lib-serml/currencies/src/weights.rs b/lib-serml/currencies/src/weights.rs index 9d338d87e..df7837faa 100644 --- a/lib-serml/currencies/src/weights.rs +++ b/lib-serml/currencies/src/weights.rs @@ -28,14 +28,19 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=module_currencies +// --pallet=setheum_currencies // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 // --output=./currencies/src/weights.rs -// --template -// ../templates/lib-openrml-weight-template.hbs +// --template=./templates/module-weight-template.hbs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] #![cfg_attr(rustfmt, rustfmt_skip)] @@ -55,31 +60,49 @@ pub trait WeightInfo { fn update_balance_native_currency_killing() -> Weight; } -/// Default weights. +/// Weights for module_currencies using the Setheum node and recommended hardware. +pub struct SetheumWeight(PhantomData); +impl WeightInfo for SetheumWeight { + fn transfer_non_native_currency() -> Weight { + (65_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + } + fn transfer_native_currency() -> Weight { + (11_000_000 as Weight) + } + fn update_balance_non_native_currency() -> Weight { + (31_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn update_balance_native_currency_creating() -> Weight { + (14_000_000 as Weight) + } + fn update_balance_native_currency_killing() -> Weight { + (13_000_000 as Weight) + } +} + +// For backwards compatibility and tests impl WeightInfo for () { fn transfer_non_native_currency() -> Weight { - (60_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + (65_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) } fn transfer_native_currency() -> Weight { - (60_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + (11_000_000 as Weight) } fn update_balance_non_native_currency() -> Weight { - (29_000_000 as Weight) + (31_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn update_balance_native_currency_creating() -> Weight { - (31_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + (14_000_000 as Weight) } fn update_balance_native_currency_killing() -> Weight { - (37_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + (13_000_000 as Weight) } } diff --git a/lib-serml/dex/src/weights.rs b/lib-serml/dex/src/weights.rs index f2cfd8680..b4cb3772c 100644 --- a/lib-serml/dex/src/weights.rs +++ b/lib-serml/dex/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/evm-accounts/src/weights.rs b/lib-serml/evm-accounts/src/weights.rs index d229c02fc..455511fca 100644 --- a/lib-serml/evm-accounts/src/weights.rs +++ b/lib-serml/evm-accounts/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/evm/src/weights.rs b/lib-serml/evm/src/weights.rs index b48e63e2f..6485e6cb9 100644 --- a/lib-serml/evm/src/weights.rs +++ b/lib-serml/evm/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/incentives/src/weights.rs b/lib-serml/incentives/src/weights.rs index 33cb8edba..2b610048b 100644 --- a/lib-serml/incentives/src/weights.rs +++ b/lib-serml/incentives/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/nft/src/weights.rs b/lib-serml/nft/src/weights.rs index c80578be5..c8ad40da1 100644 --- a/lib-serml/nft/src/weights.rs +++ b/lib-serml/nft/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/prices/src/weights.rs b/lib-serml/prices/src/weights.rs index 51ea19468..d3a7ed154 100644 --- a/lib-serml/prices/src/weights.rs +++ b/lib-serml/prices/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/serp-auction/src/weights.rs b/lib-serml/serp-auction/src/weights.rs index 6b8e9b230..b44ba1135 100644 --- a/lib-serml/serp-auction/src/weights.rs +++ b/lib-serml/serp-auction/src/weights.rs @@ -23,7 +23,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/serp-treasury/src/weights.rs b/lib-serml/serp-treasury/src/weights.rs index cbb281d8b..cfc14b64f 100644 --- a/lib-serml/serp-treasury/src/weights.rs +++ b/lib-serml/serp-treasury/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/settway/src/weights.rs b/lib-serml/settway/src/weights.rs index 3364fd067..b7a43fc01 100644 --- a/lib-serml/settway/src/weights.rs +++ b/lib-serml/settway/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/lib-serml/transaction-payment/src/weights.rs b/lib-serml/transaction-payment/src/weights.rs index 0bbf8942c..ea07c5a65 100644 --- a/lib-serml/transaction-payment/src/weights.rs +++ b/lib-serml/transaction-payment/src/weights.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/orml_auction.rs b/runtime/neom/src/weights/orml_auction.rs index b8c33bc1a..d0204cf24 100644 --- a/runtime/neom/src/weights/orml_auction.rs +++ b/runtime/neom/src/weights/orml_auction.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/orml_authority.rs b/runtime/neom/src/weights/orml_authority.rs index 7b28f4c00..38fdadbea 100644 --- a/runtime/neom/src/weights/orml_authority.rs +++ b/runtime/neom/src/weights/orml_authority.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/orml_oracle.rs b/runtime/neom/src/weights/orml_oracle.rs index 3195adbf2..9ec1594a1 100644 --- a/runtime/neom/src/weights/orml_oracle.rs +++ b/runtime/neom/src/weights/orml_oracle.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/orml_rewards.rs b/runtime/neom/src/weights/orml_rewards.rs index c20fb5dc7..2404367b0 100644 --- a/runtime/neom/src/weights/orml_rewards.rs +++ b/runtime/neom/src/weights/orml_rewards.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/orml_tokens.rs b/runtime/neom/src/weights/orml_tokens.rs index 75e8b334e..33e3e0a02 100644 --- a/runtime/neom/src/weights/orml_tokens.rs +++ b/runtime/neom/src/weights/orml_tokens.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/orml_vesting.rs b/runtime/neom/src/weights/orml_vesting.rs index afb1da03f..9c3ee6b38 100644 --- a/runtime/neom/src/weights/orml_vesting.rs +++ b/runtime/neom/src/weights/orml_vesting.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_auction_manager.rs b/runtime/neom/src/weights/setheum_auction_manager.rs index 67656891a..4000759f1 100644 --- a/runtime/neom/src/weights/setheum_auction_manager.rs +++ b/runtime/neom/src/weights/setheum_auction_manager.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_currencies.rs b/runtime/neom/src/weights/setheum_currencies.rs index 3ad411f9b..3859ff8d9 100644 --- a/runtime/neom/src/weights/setheum_currencies.rs +++ b/runtime/neom/src/weights/setheum_currencies.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_dex.rs b/runtime/neom/src/weights/setheum_dex.rs index e454b22c0..41484b551 100644 --- a/runtime/neom/src/weights/setheum_dex.rs +++ b/runtime/neom/src/weights/setheum_dex.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_incentives.rs b/runtime/neom/src/weights/setheum_incentives.rs index 40dfecb32..7cbbc5388 100644 --- a/runtime/neom/src/weights/setheum_incentives.rs +++ b/runtime/neom/src/weights/setheum_incentives.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_nft.rs b/runtime/neom/src/weights/setheum_nft.rs index c7d5ddd67..01cab9ed9 100644 --- a/runtime/neom/src/weights/setheum_nft.rs +++ b/runtime/neom/src/weights/setheum_nft.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_prices.rs b/runtime/neom/src/weights/setheum_prices.rs index 5e24c5089..3b39f2d15 100644 --- a/runtime/neom/src/weights/setheum_prices.rs +++ b/runtime/neom/src/weights/setheum_prices.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_serp.rs b/runtime/neom/src/weights/setheum_serp.rs index 0bf5f2329..6252c38d3 100644 --- a/runtime/neom/src/weights/setheum_serp.rs +++ b/runtime/neom/src/weights/setheum_serp.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_settmint_treasury.rs b/runtime/neom/src/weights/setheum_settmint_treasury.rs index a5e2e8072..2d0865a06 100644 --- a/runtime/neom/src/weights/setheum_settmint_treasury.rs +++ b/runtime/neom/src/weights/setheum_settmint_treasury.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/neom/src/weights/setheum_transaction_payment.rs b/runtime/neom/src/weights/setheum_transaction_payment.rs index cbec3ddce..f133fb05d 100644 --- a/runtime/neom/src/weights/setheum_transaction_payment.rs +++ b/runtime/neom/src/weights/setheum_transaction_payment.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/module_transaction_payment.rs b/runtime/newrome/src/weights/module_transaction_payment.rs index b8e3833f2..41dc1f633 100644 --- a/runtime/newrome/src/weights/module_transaction_payment.rs +++ b/runtime/newrome/src/weights/module_transaction_payment.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/orml_auction.rs b/runtime/newrome/src/weights/orml_auction.rs index 70ea493e0..54bb8db5e 100644 --- a/runtime/newrome/src/weights/orml_auction.rs +++ b/runtime/newrome/src/weights/orml_auction.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/orml_authority.rs b/runtime/newrome/src/weights/orml_authority.rs index 4e73721a4..edf9f5c21 100644 --- a/runtime/newrome/src/weights/orml_authority.rs +++ b/runtime/newrome/src/weights/orml_authority.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/orml_oracle.rs b/runtime/newrome/src/weights/orml_oracle.rs index bbba27e53..c35c39e39 100644 --- a/runtime/newrome/src/weights/orml_oracle.rs +++ b/runtime/newrome/src/weights/orml_oracle.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/orml_rewards.rs b/runtime/newrome/src/weights/orml_rewards.rs index 29af5a15b..ae4a78e22 100644 --- a/runtime/newrome/src/weights/orml_rewards.rs +++ b/runtime/newrome/src/weights/orml_rewards.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/orml_tokens.rs b/runtime/newrome/src/weights/orml_tokens.rs index 7ac882a94..8fe53f8fb 100644 --- a/runtime/newrome/src/weights/orml_tokens.rs +++ b/runtime/newrome/src/weights/orml_tokens.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/orml_vesting.rs b/runtime/newrome/src/weights/orml_vesting.rs index bf8d12e1e..6b21f185b 100644 --- a/runtime/newrome/src/weights/orml_vesting.rs +++ b/runtime/newrome/src/weights/orml_vesting.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_auction_manager.rs b/runtime/newrome/src/weights/setheum_auction_manager.rs index f0007badb..8681543d7 100644 --- a/runtime/newrome/src/weights/setheum_auction_manager.rs +++ b/runtime/newrome/src/weights/setheum_auction_manager.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_currencies.rs b/runtime/newrome/src/weights/setheum_currencies.rs index 896067a62..0e1d1d696 100644 --- a/runtime/newrome/src/weights/setheum_currencies.rs +++ b/runtime/newrome/src/weights/setheum_currencies.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_dex.rs b/runtime/newrome/src/weights/setheum_dex.rs index ae6af2182..f9ca05dd3 100644 --- a/runtime/newrome/src/weights/setheum_dex.rs +++ b/runtime/newrome/src/weights/setheum_dex.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_incentives.rs b/runtime/newrome/src/weights/setheum_incentives.rs index b4eaa8fdd..6bbfc1a50 100644 --- a/runtime/newrome/src/weights/setheum_incentives.rs +++ b/runtime/newrome/src/weights/setheum_incentives.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_nft.rs b/runtime/newrome/src/weights/setheum_nft.rs index 1a1558d4a..c7b81ee7a 100644 --- a/runtime/newrome/src/weights/setheum_nft.rs +++ b/runtime/newrome/src/weights/setheum_nft.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_prices.rs b/runtime/newrome/src/weights/setheum_prices.rs index 1fc575c55..750295447 100644 --- a/runtime/newrome/src/weights/setheum_prices.rs +++ b/runtime/newrome/src/weights/setheum_prices.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_serp.rs b/runtime/newrome/src/weights/setheum_serp.rs index 7ec116c1f..692562cc8 100644 --- a/runtime/newrome/src/weights/setheum_serp.rs +++ b/runtime/newrome/src/weights/setheum_serp.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/newrome/src/weights/setheum_settmint_treasury.rs b/runtime/newrome/src/weights/setheum_settmint_treasury.rs index d6f4759d7..61bbfa0ef 100644 --- a/runtime/newrome/src/weights/setheum_settmint_treasury.rs +++ b/runtime/newrome/src/weights/setheum_settmint_treasury.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/orml_auction.rs b/runtime/setheum/src/weights/orml_auction.rs index d17c796ff..8be0fd109 100644 --- a/runtime/setheum/src/weights/orml_auction.rs +++ b/runtime/setheum/src/weights/orml_auction.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/orml_authority.rs b/runtime/setheum/src/weights/orml_authority.rs index 25cdb343d..ce7b354b5 100644 --- a/runtime/setheum/src/weights/orml_authority.rs +++ b/runtime/setheum/src/weights/orml_authority.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/orml_oracle.rs b/runtime/setheum/src/weights/orml_oracle.rs index 70b8c9d94..6dea2b9e7 100644 --- a/runtime/setheum/src/weights/orml_oracle.rs +++ b/runtime/setheum/src/weights/orml_oracle.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/orml_rewards.rs b/runtime/setheum/src/weights/orml_rewards.rs index e58f3c45c..a49f79bda 100644 --- a/runtime/setheum/src/weights/orml_rewards.rs +++ b/runtime/setheum/src/weights/orml_rewards.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/orml_tokens.rs b/runtime/setheum/src/weights/orml_tokens.rs index 45dd65fdf..256d2ba3a 100644 --- a/runtime/setheum/src/weights/orml_tokens.rs +++ b/runtime/setheum/src/weights/orml_tokens.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/orml_vesting.rs b/runtime/setheum/src/weights/orml_vesting.rs index dc17dbd62..5b9a5e0b4 100644 --- a/runtime/setheum/src/weights/orml_vesting.rs +++ b/runtime/setheum/src/weights/orml_vesting.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_auction_manager.rs b/runtime/setheum/src/weights/setheum_auction_manager.rs index 7de03b0fb..669f8d129 100644 --- a/runtime/setheum/src/weights/setheum_auction_manager.rs +++ b/runtime/setheum/src/weights/setheum_auction_manager.rs @@ -24,7 +24,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_currencies.rs b/runtime/setheum/src/weights/setheum_currencies.rs index 6b162b0c3..5637787d8 100644 --- a/runtime/setheum/src/weights/setheum_currencies.rs +++ b/runtime/setheum/src/weights/setheum_currencies.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_dex.rs b/runtime/setheum/src/weights/setheum_dex.rs index eaae22409..2d38ee40e 100644 --- a/runtime/setheum/src/weights/setheum_dex.rs +++ b/runtime/setheum/src/weights/setheum_dex.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_incentives.rs b/runtime/setheum/src/weights/setheum_incentives.rs index 7071ee598..392e3358c 100644 --- a/runtime/setheum/src/weights/setheum_incentives.rs +++ b/runtime/setheum/src/weights/setheum_incentives.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_nft.rs b/runtime/setheum/src/weights/setheum_nft.rs index cff4a4e85..5524594a4 100644 --- a/runtime/setheum/src/weights/setheum_nft.rs +++ b/runtime/setheum/src/weights/setheum_nft.rs @@ -23,7 +23,6 @@ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_prices.rs b/runtime/setheum/src/weights/setheum_prices.rs index 4f40a3699..285291d15 100644 --- a/runtime/setheum/src/weights/setheum_prices.rs +++ b/runtime/setheum/src/weights/setheum_prices.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_serp.rs b/runtime/setheum/src/weights/setheum_serp.rs index d60050bea..2a259328b 100644 --- a/runtime/setheum/src/weights/setheum_serp.rs +++ b/runtime/setheum/src/weights/setheum_serp.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_settmint_treasury.rs b/runtime/setheum/src/weights/setheum_settmint_treasury.rs index 9ddb144e5..38f98b403 100644 --- a/runtime/setheum/src/weights/setheum_settmint_treasury.rs +++ b/runtime/setheum/src/weights/setheum_settmint_treasury.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 diff --git a/runtime/setheum/src/weights/setheum_transaction_payment.rs b/runtime/setheum/src/weights/setheum_transaction_payment.rs index eb66d44a1..d56827367 100644 --- a/runtime/setheum/src/weights/setheum_transaction_payment.rs +++ b/runtime/setheum/src/weights/setheum_transaction_payment.rs @@ -24,7 +24,6 @@ //! CACHE: 128 // Executed Command: -// target/release/setheum // benchmark // --chain=dev // --steps=50 From c58249652848fe4df3eb90bfeaade969c77e17a5 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 02:52:52 +0800 Subject: [PATCH 26/83] REMOVE THE IRR currency --- lib-serml/prices/src/mock.rs | 5 ----- lib-serml/serp-treasury/src/mock.rs | 2 -- lib-serml/setters-manager/src/mock.rs | 3 --- lib-serml/settmint-engine/src/mock.rs | 3 --- lib-serml/settway/src/mock.rs | 2 -- primitives/src/currency.rs | 3 --- 6 files changed, 18 deletions(-) diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index 554edc84c..241cf3d1f 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -58,7 +58,6 @@ pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); pub const HKDJ: CurrencyId = CurrencyId::Token(TokenSymbol::HKDJ); pub const HUFJ: CurrencyId = CurrencyId::Token(TokenSymbol::HUFJ); pub const IDRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IDRJ); -pub const IRRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IRRJ); pub const JPYJ: CurrencyId = CurrencyId::Token(TokenSymbol::JPYJ); pub const KESJ: CurrencyId = CurrencyId::Token(TokenSymbol::KESJ); pub const KRWJ: CurrencyId = CurrencyId::Token(TokenSymbol::KRWJ); @@ -107,7 +106,6 @@ pub const GBP: CurrencyId = CurrencyId::Token(TokenSymbol::GBP); pub const HKD: CurrencyId = CurrencyId::Token(TokenSymbol::HKD); pub const HUF: CurrencyId = CurrencyId::Token(TokenSymbol::HUF); pub const IDR: CurrencyId = CurrencyId::Token(TokenSymbol::IDR); -pub const IRR: CurrencyId = CurrencyId::Token(TokenSymbol::IRR); pub const JPY: CurrencyId = CurrencyId::Token(TokenSymbol::JPY); pub const KES: CurrencyId = CurrencyId::Token(TokenSymbol::KES); pub const KRW: CurrencyId = CurrencyId::Token(TokenSymbol::KRW); @@ -287,7 +285,6 @@ parameter_type_with_key! { &HKDJ => &HKD, &HUFJ => &HUF, &IDRJ => &IDR, - &IRRJ => &IRR, &JPYJ => &JPY, &KESJ => &KES, &KRWJ => &KRW, @@ -365,7 +362,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, @@ -408,7 +404,6 @@ parameter_types! { HKD, HUF, IDR, - IRR, JPY, KES, KRW, diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index 1633c05f4..899bc3915 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -55,7 +55,6 @@ pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); pub const HKDJ: CurrencyId = CurrencyId::Token(TokenSymbol::HKDJ); pub const HUFJ: CurrencyId = CurrencyId::Token(TokenSymbol::HUFJ); pub const IDRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IDRJ); -pub const IRRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IRRJ); pub const JPYJ: CurrencyId = CurrencyId::Token(TokenSymbol::JPYJ); pub const KESJ: CurrencyId = CurrencyId::Token(TokenSymbol::KESJ); pub const KRWJ: CurrencyId = CurrencyId::Token(TokenSymbol::KRWJ); @@ -245,7 +244,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index 7c330214d..ee5540ca4 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -54,7 +54,6 @@ pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); pub const HKDJ: CurrencyId = CurrencyId::Token(TokenSymbol::HKDJ); pub const HUFJ: CurrencyId = CurrencyId::Token(TokenSymbol::HUFJ); pub const IDRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IDRJ); -pub const IRRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IRRJ); pub const JPYJ: CurrencyId = CurrencyId::Token(TokenSymbol::JPYJ); pub const KESJ: CurrencyId = CurrencyId::Token(TokenSymbol::KESJ); pub const KRWJ: CurrencyId = CurrencyId::Token(TokenSymbol::KRWJ); @@ -215,7 +214,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, @@ -318,7 +316,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index df57e324c..918e9c0aa 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -58,7 +58,6 @@ pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); pub const HKDJ: CurrencyId = CurrencyId::Token(TokenSymbol::HKDJ); pub const HUFJ: CurrencyId = CurrencyId::Token(TokenSymbol::HUFJ); pub const IDRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IDRJ); -pub const IRRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IRRJ); pub const JPYJ: CurrencyId = CurrencyId::Token(TokenSymbol::JPYJ); pub const KESJ: CurrencyId = CurrencyId::Token(TokenSymbol::KESJ); pub const KRWJ: CurrencyId = CurrencyId::Token(TokenSymbol::KRWJ); @@ -257,7 +256,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, @@ -353,7 +351,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index 34fa3849e..0d96d5dfb 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -214,7 +214,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, @@ -288,7 +287,6 @@ parameter_types! { HKDJ, HUFJ, IDRJ, - IRRJ, JPYJ, KESJ, KRWJ, diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index b406c47af..8a45031cb 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -197,7 +197,6 @@ create_currency_id! { HKDJ("Setheum HongKong Dollar", 12) = 14, HUFJ("Setheum Hungarian Forint", 12) = 15, IDRJ("Setheum Indonesian Rupiah", 12) = 16, - IRRJ("Setheum Iranian Riyal", 12) = 17, JPYJ("Setheum Japanese Yen", 12) = 18, KESJ("Setheum Kenyan Shilling", 12) = 19, KRWJ("Setheum South Korean Won", 12) = 20, @@ -246,7 +245,6 @@ create_currency_id! { JHKD("Neom HongKong Dollar", 12) = 14, JHUF("Neom Hungarian Forint", 12) = 15, JIDR("Neom Indonesian Rupiah", 12) = 16, - JIRR("Neom Iranian Riyal", 12) = 17, JJPY("Neom Japanese Yen", 12) = 18, JKES("Neom Kenyan Shilling", 12) = 19, JKRW("Neom South Korean Won", 12) = 20, @@ -292,7 +290,6 @@ create_currency_id! { HKD("Fiat HongKong Dollar", 12) = 182, HUF("Fiat Hungarian Forint", 12) = 183, IDR("Fiat Indonesian Rupiah", 12) = 184, - IRR("Fiat Iranian Riyal", 12) = 185, JPY("Fiat Japanese Yen", 12) = 186, KES("Fiat Kenyan Shilling", 12) = 187, KRW("Fiat South Korean Won", 12) = 188, From c09899cc9ead572af6140116a4814ff6b2ef5d83 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 04:09:17 +0800 Subject: [PATCH 27/83] update DEX to use erc20 on EVM --- lib-serml/dex/src/lib.rs | 42 ++- lib-serml/dex/src/mock.rs | 34 +- lib-serml/dex/src/tests.rs | 441 +++++++++++----------- lib-serml/dex/src/weights.rs | 4 +- lib-serml/incentives/src/lib.rs | 11 +- lib-serml/incentives/src/mock.rs | 4 +- lib-serml/prices/src/lib.rs | 4 +- lib-serml/prices/src/mock.rs | 2 +- lib-serml/serp-auction/src/lib.rs | 4 +- lib-serml/serp-auction/src/mock.rs | 12 +- lib-serml/serp-auction/src/tests.rs | 90 ++--- lib-serml/serp-treasury/src/lib.rs | 4 +- lib-serml/serp-treasury/src/mock.rs | 2 +- lib-serml/settmint-engine/src/lib.rs | 2 +- lib-serml/settmint-engine/src/mock.rs | 2 +- lib-serml/settway/src/mock.rs | 15 +- lib-serml/support/src/lib.rs | 8 +- lib-serml/transaction-payment/src/lib.rs | 4 +- lib-serml/transaction-payment/src/mock.rs | 2 +- runtime/neom/src/lib.rs | 2 +- runtime/newrome/src/lib.rs | 2 +- runtime/setheum/src/lib.rs | 2 +- 22 files changed, 350 insertions(+), 343 deletions(-) diff --git a/lib-serml/dex/src/lib.rs b/lib-serml/dex/src/lib.rs index 6d3485175..f64c249c1 100644 --- a/lib-serml/dex/src/lib.rs +++ b/lib-serml/dex/src/lib.rs @@ -34,13 +34,13 @@ use frame_support::{log, pallet_prelude::*, traits::MaxEncodedLen, transactional use frame_system::pallet_prelude::*; use orml_traits::{MultiCurrency, MultiCurrencyExtended}; use primitives::{Balance, CurrencyId, TradingPair}; -use sp_core::U256; +use sp_core::{H160, U256}; use sp_runtime::{ traits::{AccountIdConversion, UniqueSaturatedInto, Zero}, DispatchError, DispatchResult, FixedPointNumber, RuntimeDebug, SaturatedConversion, }; use sp_std::{convert::TryInto, prelude::*, vec}; -use support::{DexIncentives, DexManager, Price, Ratio}; +use support::{CurrencyIdMapping, DEXIncentives, DEXManager, Price, Ratio}; mod mock; mod tests; @@ -105,15 +105,19 @@ pub mod module { #[pallet::constant] type TradingPathLimit: Get; - /// The Dex's module id, keep all assets in Dex. + /// The DEX's module id, keep all assets in DEX. #[pallet::constant] type PalletId: Get; + /// Mapping between CurrencyId and ERC20 address so user can use Erc20 + /// address as LP token. + type CurrencyIdMapping: CurrencyIdMapping; + /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; /// Dex incentives - type DexIncentives: DexIncentives; + type DEXIncentives: DEXIncentives; /// The origin which may list, enable or disable trading pairs. type ListingOrigin: EnsureOrigin; @@ -185,17 +189,24 @@ pub mod module { } /// Liquidity pool for TradingPair. + /// + /// LiquidityPool: map TradingPair => (Balance, Balance) #[pallet::storage] #[pallet::getter(fn liquidity_pool)] pub type LiquidityPool = StorageMap<_, Twox64Concat, TradingPair, (Balance, Balance), ValueQuery>; /// Status for TradingPair. + /// + /// TradingPairStatuses: map TradingPair => TradingPairStatus #[pallet::storage] #[pallet::getter(fn trading_pair_statuses)] pub type TradingPairStatuses = StorageMap<_, Twox64Concat, TradingPair, TradingPairStatus, ValueQuery>; /// Provision of TradingPair by AccountId. + /// + /// ProvisioningPool: double_map TradingPair, AccountId => (Balance, + /// Balance) #[pallet::storage] #[pallet::getter(fn provisioning_pool)] pub type ProvisioningPool = @@ -286,7 +297,7 @@ pub mod module { #[pallet::call] impl Pallet { - /// Trading with Dex, swap with exact supply amount + /// Trading with DEX, swap with exact supply amount /// /// - `path`: trading path. /// - `supply_amount`: exact supply amount. @@ -304,7 +315,7 @@ pub mod module { Ok(().into()) } - /// Trading with Dex, swap with exact target amount + /// Trading with DEX, swap with exact target amount /// /// - `path`: trading path. /// - `target_amount`: exact target amount. @@ -446,6 +457,13 @@ pub mod module { Error::::NotAllowedList ); + if let CurrencyId::Erc20(address) = currency_id_a { + T::CurrencyIdMapping::set_erc20_mapping(address)?; + } + if let CurrencyId::Erc20(address) = currency_id_b { + T::CurrencyIdMapping::set_erc20_mapping(address)?; + } + let (min_contribution, target_provision) = if currency_id_a == trading_pair.0 { ( (min_contribution_a, min_contribution_b), @@ -780,7 +798,7 @@ impl Pallet { *pool_1 = pool_1.saturating_add(pool_1_increment); if deposit_increment_share { - T::DexIncentives::do_deposit_dex_share(who, lp_share_currency_id, share_increment)?; + T::DEXIncentives::do_deposit_dex_share(who, lp_share_currency_id, share_increment)?; } Self::deposit_event(Event::AddLiquidity( @@ -832,7 +850,7 @@ impl Pallet { ); if by_withdraw { - T::DexIncentives::do_withdraw_dex_share(who, lp_share_currency_id, remove_share)?; + T::DEXIncentives::do_withdraw_dex_share(who, lp_share_currency_id, remove_share)?; } T::Currency::withdraw(lp_share_currency_id, &who, remove_share)?; T::Currency::transfer(trading_pair.0, &module_account_id, &who, pool_0_decrement)?; @@ -1085,11 +1103,17 @@ impl Pallet { } } -impl DexManager for Pallet { +impl DEXManager for Pallet { fn get_liquidity_pool(currency_id_a: CurrencyId, currency_id_b: CurrencyId) -> (Balance, Balance) { Self::get_liquidity(currency_id_a, currency_id_b) } + fn get_liquidity_token_address(currency_id_a: CurrencyId, currency_id_b: CurrencyId) -> Option { + let trading_pair = TradingPair::from_token_currency_ids(currency_id_a, currency_id_b)?; + let dex_share_currency_id = trading_pair.get_dex_share_currency_id()?; + T::CurrencyIdMapping::encode_evm_address(dex_share_currency_id) + } + fn get_swap_target_amount( path: &[CurrencyId], supply_amount: Balance, diff --git a/lib-serml/dex/src/mock.rs b/lib-serml/dex/src/mock.rs index 96a2e29f9..ad6ff4564 100644 --- a/lib-serml/dex/src/mock.rs +++ b/lib-serml/dex/src/mock.rs @@ -34,11 +34,12 @@ pub type AccountId = u128; pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); -pub const JCHF: CurrencyId = CurrencyId::Token(TokenSymbol::JCHF); +pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); +pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); -pub const USDJ_JCHF_PAIR: TradingPair = TradingPair(USDJ, JCHF); +pub const USDJ_CHFJ_PAIR: TradingPair = TradingPair(USDJ, CHFJ); pub const USDJ_DNAR_PAIR: TradingPair = TradingPair(USDJ, DNAR); -pub const DNAR_JCHF_PAIR: TradingPair = TradingPair(DNAR, JCHF); +pub const DNAR_CHFJ_PAIR: TradingPair = TradingPair(DNAR, CHFJ); mod dex { pub use super::super::*; @@ -91,8 +92,8 @@ impl orml_tokens::Config for Runtime { type MaxLocks = (); } -pub struct MockDexIncentives; -impl DexIncentives for MockDexIncentives { +pub struct MockDEXIncentives; +impl DEXIncentives for MockDEXIncentives { fn do_deposit_dex_share(who: &AccountId, lp_currency_id: CurrencyId, amount: Balance) -> DispatchResult { Tokens::reserve(lp_currency_id, who, amount) } @@ -118,9 +119,10 @@ impl Config for Runtime { type Currency = Tokens; type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; - type PalletId = DexPalletId; + type PalletId = DEXPalletId; + type CurrencyIdMapping = (); type WeightInfo = (); - type DexIncentives = MockDexIncentives; + type DEXIncentives = MockDEXIncentives; type ListingOrigin = EnsureSignedBy; } @@ -134,7 +136,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Storage, Config, Event}, - Dex: dex::{Pallet, Storage, Call, Event, Config}, + DexModule: dex::{Pallet, Storage, Call, Event, Config}, Tokens: orml_tokens::{Pallet, Storage, Event, Config}, } ); @@ -152,8 +154,10 @@ impl Default for ExtBuilder { endowed_accounts: vec![ (ALICE, USDJ, 1_000_000_000_000_000_000u128), (BOB, USDJ, 1_000_000_000_000_000_000u128), - (ALICE, JCHF, 1_000_000_000_000_000_000u128), - (BOB, JCHF, 1_000_000_000_000_000_000u128), + (ALICE, EURJ, 1_000_000_000_000_000_000u128), + (BOB, EURJ, 1_000_000_000_000_000_000u128), + (ALICE, CHFJ, 1_000_000_000_000_000_000u128), + (BOB, CHFJ, 1_000_000_000_000_000_000u128), (ALICE, DNAR, 1_000_000_000_000_000_000u128), (BOB, DNAR, 1_000_000_000_000_000_000u128), ], @@ -174,13 +178,13 @@ impl ExtBuilder { 10, ), ( - USDJ_JCHF_PAIR, + USDJ_CHFJ_PAIR, (20_000_000_000_000u128, 1_000_000_000u128), (20_000_000_000_000_000u128, 1_000_000_000_000u128), 10, ), ( - DNAR_JCHF_PAIR, + DNAR_CHFJ_PAIR, (4_000_000_000_000u128, 1_000_000_000u128), (4_000_000_000_000_000u128, 1_000_000_000_000u128), 20, @@ -190,7 +194,7 @@ impl ExtBuilder { } pub fn initialize_enabled_trading_pairs(mut self) -> Self { - self.initial_enabled_trading_pairs = vec![USDJ_DNAR_PAIR, USDJ_JCHF_PAIR, DNAR_JCHF_PAIR]; + self.initial_enabled_trading_pairs = vec![USDJ_DNAR_PAIR, USDJ_CHFJ_PAIR, DNAR_CHFJ_PAIR]; self } @@ -199,8 +203,8 @@ impl ExtBuilder { who, vec![ (USDJ_DNAR_PAIR, (1_000_000u128, 2_000_000u128)), - (USDJ_JCHF_PAIR, (1_000_000u128, 2_000_000u128)), - (DNAR_JCHF_PAIR, (1_000_000u128, 2_000_000u128)), + (USDJ_CHFJ_PAIR, (1_000_000u128, 2_000_000u128)), + (DNAR_CHFJ_PAIR, (1_000_000u128, 2_000_000u128)), ], )]; self diff --git a/lib-serml/dex/src/tests.rs b/lib-serml/dex/src/tests.rs index 7060e7a28..146ed105f 100644 --- a/lib-serml/dex/src/tests.rs +++ b/lib-serml/dex/src/tests.rs @@ -23,8 +23,8 @@ use super::*; use frame_support::{assert_noop, assert_ok}; use mock::{ - Dex, Event, ExtBuilder, ListingOrigin, Origin, Runtime, System, Tokens, DNAR, ALICE, USDJ, USDJ_DNAR_PAIR, - USDJ_JCHF_PAIR, BOB, JCHF, + DexModule, Event, ExtBuilder, ListingOrigin, Origin, Runtime, System, Tokens, + ALICE, BOB, DNAR, USDJ, EURJ, CHFJ, USDJ_DNAR_PAIR, USDJ_CHFJ_PAIR, }; use orml_traits::MultiReservableCurrency; use sp_runtime::traits::BadOrigin; @@ -35,28 +35,27 @@ fn enable_new_trading_pair_work() { System::set_block_number(1); assert_noop!( - Dex::enable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), + DexModule::enable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), BadOrigin ); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); - assert_ok!(Dex::enable_trading_pair( + assert_ok!(DexModule::enable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR )); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Enabled ); - System::assert_last_event(Event::dex(crate::Event::EnableTradingPair(USDJ_DNAR_PAIR))); assert_noop!( - Dex::enable_trading_pair(Origin::signed(ListingOrigin::get()), DNAR, USDJ), + DexModule::enable_trading_pair(Origin::signed(ListingOrigin::get()), DNAR, USDJ), Error::::MustBeNotEnabled ); }); @@ -68,7 +67,7 @@ fn list_new_trading_pair_work() { System::set_block_number(1); assert_noop!( - Dex::list_trading_pair( + DexModule::list_trading_pair( Origin::signed(ALICE), USDJ, DNAR, @@ -82,10 +81,10 @@ fn list_new_trading_pair_work() { ); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); - assert_ok!(Dex::list_trading_pair( + assert_ok!(DexModule::list_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR, @@ -96,7 +95,7 @@ fn list_new_trading_pair_work() { 10, )); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (1_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000u128, 2_000_000_000_000u128), @@ -104,13 +103,13 @@ fn list_new_trading_pair_work() { not_before: 10, }) ); - System::assert_last_event(Event::dex(crate::Event::ListTradingPair(USDJ_DNAR_PAIR))); + assert_noop!( - Dex::list_trading_pair( + DexModule::list_trading_pair( Origin::signed(ListingOrigin::get()), - DNAR, - DNAR, + USDJ, + USDJ, 1_000_000_000_000u128, 1_000_000_000_000u128, 5_000_000_000_000u128, @@ -121,7 +120,7 @@ fn list_new_trading_pair_work() { ); assert_noop!( - Dex::list_trading_pair( + DexModule::list_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR, @@ -141,34 +140,34 @@ fn disable_enabled_trading_pair_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(Dex::enable_trading_pair( + assert_ok!(DexModule::enable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR )); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Enabled ); assert_noop!( - Dex::disable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), + DexModule::disable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), BadOrigin ); - assert_ok!(Dex::disable_trading_pair( + assert_ok!(DexModule::disable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR )); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); - System::assert_last_event(Event::dex(crate::Event::DisableTradingPair(USDJ_DNAR_PAIR))); + assert_noop!( - Dex::disable_trading_pair(Origin::signed(ListingOrigin::get()), USDJ, DNAR), + DexModule::disable_trading_pair(Origin::signed(ListingOrigin::get()), USDJ, DNAR), Error::::NotEnabledTradingPair ); }); @@ -182,20 +181,22 @@ fn disable_provisioning_trading_pair_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, 5_000_000_000_000u128, 0, + 0, false )); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(BOB), USDJ, DNAR, 5_000_000_000_000u128, 1_000_000_000_000u128, + 0, false )); @@ -204,23 +205,23 @@ fn disable_provisioning_trading_pair_work() { assert_eq!(Tokens::free_balance(USDJ, &BOB), 999_995_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_999_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 10_000_000_000_000u128 ); assert_eq!( - Tokens::free_balance(DNAR, &Dex::account_id()), + Tokens::free_balance(DNAR, &DexModule::account_id()), 1_000_000_000_000u128 ); assert_eq!( - Dex::provisioning_pool(USDJ_DNAR_PAIR, ALICE), + DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (5_000_000_000_000u128, 0) ); assert_eq!( - Dex::provisioning_pool(USDJ_DNAR_PAIR, BOB), + DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (5_000_000_000_000u128, 1_000_000_000_000u128) ); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -231,7 +232,7 @@ fn disable_provisioning_trading_pair_work() { let alice_ref_count_0 = System::consumers(&ALICE); let bob_ref_count_0 = System::consumers(&BOB); - assert_ok!(Dex::disable_trading_pair( + assert_ok!(DexModule::disable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR @@ -240,12 +241,12 @@ fn disable_provisioning_trading_pair_work() { assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000u128); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 0); - assert_eq!(Dex::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); - assert_eq!(Dex::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); + assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); + assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); assert_eq!(System::consumers(&ALICE), alice_ref_count_0 - 1); @@ -262,12 +263,13 @@ fn add_provision_work() { System::set_block_number(1); assert_noop!( - Dex::add_liquidity( + DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, 4_999_999_999_999u128, 999_999_999_999u128, + 0, false ), Error::::InvalidContributionIncrement @@ -275,7 +277,7 @@ fn add_provision_work() { // alice add provision assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -283,23 +285,24 @@ fn add_provision_work() { not_before: 10, }) ); - assert_eq!(Dex::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); + assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000u128); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 0); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); let alice_ref_count_0 = System::consumers(&ALICE); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, 5_000_000_000_000u128, 0, + 0, false )); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -308,16 +311,16 @@ fn add_provision_work() { }) ); assert_eq!( - Dex::provisioning_pool(USDJ_DNAR_PAIR, ALICE), + DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (5_000_000_000_000u128, 0) ); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 999_995_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 5_000_000_000_000u128 ); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); let alice_ref_count_1 = System::consumers(&ALICE); assert_eq!(alice_ref_count_1, alice_ref_count_0 + 1); System::assert_last_event(Event::dex(crate::Event::AddProvision( @@ -329,21 +332,22 @@ fn add_provision_work() { ))); // bob add provision - assert_eq!(Dex::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); + assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000u128); let bob_ref_count_0 = System::consumers(&BOB); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(BOB), DNAR, USDJ, 1_000_000_000_000_000u128, 0, + 0, false )); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -352,17 +356,17 @@ fn add_provision_work() { }) ); assert_eq!( - Dex::provisioning_pool(USDJ_DNAR_PAIR, BOB), + DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 1_000_000_000_000_000u128) ); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_000_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 5_000_000_000_000u128 ); assert_eq!( - Tokens::free_balance(DNAR, &Dex::account_id()), + Tokens::free_balance(DNAR, &DexModule::account_id()), 1_000_000_000_000_000u128 ); let bob_ref_count_1 = System::consumers(&BOB); @@ -393,22 +397,23 @@ fn add_provision_work() { ); System::set_block_number(10); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, 995_000_000_000_000u128, 1_000_000_000_000_000u128, + 0, false )); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 999_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 999_000_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 1_000_000_000_000_000u128 ); assert_eq!( - Tokens::free_balance(DNAR, &Dex::account_id()), + Tokens::free_balance(DNAR, &DexModule::account_id()), 2_000_000_000_000_000u128 ); assert_eq!( @@ -423,13 +428,12 @@ fn add_provision_work() { Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &BOB), 1_000_000_000_000_000, ); - assert_eq!(Dex::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); - assert_eq!(Dex::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); + assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); + assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); assert_eq!( - Dex::trading_pair_statuses(USDJ_DNAR_PAIR), + DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Enabled ); - System::assert_last_event(Event::dex(crate::Event::ProvisioningToEnabled( USDJ_DNAR_PAIR, 1_000_000_000_000_000u128, @@ -443,35 +447,35 @@ fn add_provision_work() { fn get_liquidity_work() { ExtBuilder::default().build().execute_with(|| { LiquidityPool::::insert(USDJ_DNAR_PAIR, (1000, 20)); - assert_eq!(Dex::liquidity_pool(USDJ_DNAR_PAIR), (1000, 20)); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (1000, 20)); - assert_eq!(Dex::get_liquidity(DNAR, USDJ), (20, 1000)); + assert_eq!(DexModule::liquidity_pool(USDJ_DNAR_PAIR), (1000, 20)); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (1000, 20)); + assert_eq!(DexModule::get_liquidity(DNAR, USDJ), (20, 1000)); }); } #[test] fn get_target_amount_work() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(Dex::get_target_amount(10000, 0, 1000), 0); - assert_eq!(Dex::get_target_amount(0, 20000, 1000), 0); - assert_eq!(Dex::get_target_amount(10000, 20000, 0), 0); - assert_eq!(Dex::get_target_amount(10000, 1, 1000000), 0); - assert_eq!(Dex::get_target_amount(10000, 20000, 10000), 9949); - assert_eq!(Dex::get_target_amount(10000, 20000, 1000), 1801); + assert_eq!(DexModule::get_target_amount(10000, 0, 1000), 0); + assert_eq!(DexModule::get_target_amount(0, 20000, 1000), 0); + assert_eq!(DexModule::get_target_amount(10000, 20000, 0), 0); + assert_eq!(DexModule::get_target_amount(10000, 1, 1000000), 0); + assert_eq!(DexModule::get_target_amount(10000, 20000, 10000), 9949); + assert_eq!(DexModule::get_target_amount(10000, 20000, 1000), 1801); }); } #[test] fn get_supply_amount_work() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(Dex::get_supply_amount(10000, 0, 1000), 0); - assert_eq!(Dex::get_supply_amount(0, 20000, 1000), 0); - assert_eq!(Dex::get_supply_amount(10000, 20000, 0), 0); - assert_eq!(Dex::get_supply_amount(10000, 1, 1), 0); - assert_eq!(Dex::get_supply_amount(10000, 20000, 9949), 9999); - assert_eq!(Dex::get_target_amount(10000, 20000, 9999), 9949); - assert_eq!(Dex::get_supply_amount(10000, 20000, 1801), 1000); - assert_eq!(Dex::get_target_amount(10000, 20000, 1000), 1801); + assert_eq!(DexModule::get_supply_amount(10000, 0, 1000), 0); + assert_eq!(DexModule::get_supply_amount(0, 20000, 1000), 0); + assert_eq!(DexModule::get_supply_amount(10000, 20000, 0), 0); + assert_eq!(DexModule::get_supply_amount(10000, 1, 1), 0); + assert_eq!(DexModule::get_supply_amount(10000, 20000, 9949), 9999); + assert_eq!(DexModule::get_target_amount(10000, 20000, 9999), 9949); + assert_eq!(DexModule::get_supply_amount(10000, 20000, 1801), 1000); + assert_eq!(DexModule::get_target_amount(10000, 20000, 1000), 1801); }); } @@ -482,41 +486,37 @@ fn get_target_amounts_work() { .build() .execute_with(|| { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); - LiquidityPool::::insert(USDJ_JCHF_PAIR, (100000, 10)); + LiquidityPool::::insert(USDJ_CHFJ_PAIR, (100000, 10)); assert_noop!( - Dex::get_target_amounts(&vec![DNAR], 10000, None), + DexModule::get_target_amounts(&vec![DNAR], 10000, None), Error::::InvalidTradingPathLength, ); assert_noop!( - Dex::get_target_amounts(&vec![DNAR, USDJ, JCHF], 10000, None), + DexModule::get_target_amounts(&vec![DNAR, USDJ, CHFJ, EURJ], 10000, None), Error::::InvalidTradingPathLength, ); - assert_noop!( - Dex::get_target_amounts(&vec![DNAR, USDJ], 10000, None), - Error::::MustBeEnabled, - ); assert_eq!( - Dex::get_target_amounts(&vec![DNAR, USDJ], 10000, None), + DexModule::get_target_amounts(&vec![DNAR, USDJ], 10000, None), Ok(vec![10000, 24874]) ); assert_eq!( - Dex::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(50, 100)), + DexModule::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(50, 100)), Ok(vec![10000, 24874]) ); assert_noop!( - Dex::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(49, 100)), + DexModule::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(49, 100)), Error::::ExceedPriceImpactLimit, ); assert_eq!( - Dex::get_target_amounts(&vec![DNAR, USDJ, JCHF], 10000, None), + DexModule::get_target_amounts(&vec![DNAR, USDJ, CHFJ], 10000, None), Ok(vec![10000, 24874, 1]) ); assert_noop!( - Dex::get_target_amounts(&vec![DNAR, USDJ, JCHF], 100, None), + DexModule::get_target_amounts(&vec![DNAR, USDJ, CHFJ], 100, None), Error::::ZeroTargetAmount, ); assert_noop!( - Dex::get_target_amounts(&vec![DNAR, JCHF], 100, None), + DexModule::get_target_amounts(&vec![DNAR, CHFJ], 100, None), Error::::InsufficientLiquidity, ); }); @@ -530,7 +530,7 @@ fn calculate_amount_for_big_number_work() { (171_000_000_000_000_000_000_000, 56_000_000_000_000_000_000_000), ); assert_eq!( - Dex::get_supply_amount( + DexModule::get_supply_amount( 171_000_000_000_000_000_000_000, 56_000_000_000_000_000_000_000, 1_000_000_000_000_000_000_000 @@ -538,7 +538,7 @@ fn calculate_amount_for_big_number_work() { 3_140_495_867_768_595_041_323 ); assert_eq!( - Dex::get_target_amount( + DexModule::get_target_amount( 171_000_000_000_000_000_000_000, 56_000_000_000_000_000_000_000, 3_140_495_867_768_595_041_323 @@ -555,37 +555,33 @@ fn get_supply_amounts_work() { .build() .execute_with(|| { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); - LiquidityPool::::insert(USDJ_JCHF_PAIR, (100000, 10)); + LiquidityPool::::insert(USDJ_CHFJ_PAIR, (100000, 10)); assert_noop!( - Dex::get_supply_amounts(&vec![DNAR], 10000, None), + DexModule::get_supply_amounts(&vec![DNAR], 10000, None), Error::::InvalidTradingPathLength, ); assert_noop!( - Dex::get_supply_amounts(&vec![DNAR, USDJ, JCHF], 10000, None), + DexModule::get_supply_amounts(&vec![DNAR, USDJ, CHFJ, EURJ], 10000, None), Error::::InvalidTradingPathLength, ); - assert_noop!( - Dex::get_supply_amounts(&vec![DNAR, USDJ], 10000, None), - Error::::MustBeEnabled, - ); assert_eq!( - Dex::get_supply_amounts(&vec![DNAR, USDJ], 24874, None), + DexModule::get_supply_amounts(&vec![DNAR, USDJ], 24874, None), Ok(vec![10000, 24874]) ); assert_eq!( - Dex::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(50, 100)), + DexModule::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(50, 100)), Ok(vec![10102, 25000]) ); assert_noop!( - Dex::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(49, 100)), + DexModule::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(49, 100)), Error::::ExceedPriceImpactLimit, ); assert_noop!( - Dex::get_supply_amounts(&vec![DNAR, USDJ, JCHF], 10000, None), + DexModule::get_supply_amounts(&vec![DNAR, USDJ, CHFJ], 10000, None), Error::::ZeroSupplyAmount, ); assert_noop!( - Dex::get_supply_amounts(&vec![DNAR, JCHF], 10000, None), + DexModule::get_supply_amounts(&vec![DNAR, CHFJ], 10000, None), Error::::InsufficientLiquidity, ); }); @@ -599,11 +595,11 @@ fn _swap_work() { .execute_with(|| { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (50000, 10000)); - Dex::_swap(USDJ, DNAR, 1000, 1000); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (51000, 9000)); - Dex::_swap(DNAR, USDJ, 100, 800); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (50200, 9100)); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (50000, 10000)); + DexModule::_swap(USDJ, DNAR, 1000, 1000); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (51000, 9000)); + DexModule::_swap(DNAR, USDJ, 100, 800); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (50200, 9100)); }); } @@ -614,15 +610,15 @@ fn _swap_by_path_work() { .build() .execute_with(|| { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); - LiquidityPool::::insert(USDJ_JCHF_PAIR, (100000, 10)); - - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (50000, 10000)); - assert_eq!(Dex::get_liquidity(USDJ, JCHF), (100000, 10)); - Dex::_swap_by_path(&vec![DNAR, USDJ], &vec![10000, 25000]); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (25000, 20000)); - Dex::_swap_by_path(&vec![DNAR, USDJ, JCHF], &vec![4000, 10000, 2]); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (15000, 24000)); - assert_eq!(Dex::get_liquidity(USDJ, JCHF), (110000, 8)); + LiquidityPool::::insert(USDJ_CHFJ_PAIR, (100000, 10)); + + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (50000, 10000)); + assert_eq!(DexModule::get_liquidity(USDJ, CHFJ), (100000, 10)); + DexModule::_swap_by_path(&vec![DNAR, USDJ], &vec![10000, 25000]); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (25000, 20000)); + DexModule::_swap_by_path(&vec![DNAR, USDJ, CHFJ], &vec![4000, 10000, 2]); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (15000, 24000)); + assert_eq!(DexModule::get_liquidity(USDJ, CHFJ), (110000, 8)); }); } @@ -635,17 +631,17 @@ fn add_liquidity_work() { System::set_block_number(1); assert_noop!( - Dex::add_liquidity(Origin::signed(ALICE), DNAR, USDJ, 100_000_000, 100_000_000, false), + DexModule::add_liquidity(Origin::signed(ALICE), DNAR, USDJ, 100_000_000, 100_000_000, 0, false), Error::::NotEnabledTradingPair ); assert_noop!( - Dex::add_liquidity(Origin::signed(ALICE), USDJ, DNAR, 0, 100_000_000, false), + DexModule::add_liquidity(Origin::signed(ALICE), USDJ, DNAR, 0, 100_000_000, 0, false), Error::::InvalidLiquidityIncrement ); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (0, 0)); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 0); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (0, 0)); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 0 @@ -657,12 +653,13 @@ fn add_liquidity_work() { assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, 5_000_000_000_000, 1_000_000_000_000, + 0, false, )); System::assert_last_event(Event::dex(crate::Event::AddLiquidity( @@ -674,11 +671,11 @@ fn add_liquidity_work() { 10_000_000_000_000, ))); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (5_000_000_000_000, 1_000_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 5_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 1_000_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 5_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 1_000_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 10_000_000_000_000 @@ -701,7 +698,7 @@ fn add_liquidity_work() { assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000); assert_noop!( - Dex::add_liquidity( + DexModule::add_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -712,15 +709,15 @@ fn add_liquidity_work() { ), Error::::UnacceptableShareIncrement ); - assert_ok!(Dex::add_liquidity( - Origin::signed(BOB), - USDJ, - DNAR, - 50_000_000_000_000, - 8_000_000_000_000, - 80_000_000_000_001, - true, - )); + assert_ok!(DexModule::add_liquidity( + Origin::signed(BOB), + USDJ, + DNAR, + 50_000_000_000_000, + 8_000_000_000_000, + 80_000_000_000_000, + true, + )); System::assert_last_event(Event::dex(crate::Event::AddLiquidity( BOB, USDJ, @@ -730,11 +727,11 @@ fn add_liquidity_work() { 80_000_000_000_000, ))); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (45_000_000_000_000, 9_000_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 45_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 9_000_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 45_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 9_000_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &BOB), 0 @@ -756,16 +753,17 @@ fn remove_liquidity_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, 5_000_000_000_000, 1_000_000_000_000, + 0, false )); assert_noop!( - Dex::remove_liquidity( + DexModule::remove_liquidity( Origin::signed(ALICE), USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), DNAR, @@ -778,11 +776,11 @@ fn remove_liquidity_work() { ); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (5_000_000_000_000, 1_000_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 5_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 1_000_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 5_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 1_000_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 10_000_000_000_000 @@ -791,7 +789,7 @@ fn remove_liquidity_work() { assert_eq!(Tokens::free_balance(DNAR, &ALICE), 999_999_000_000_000_000); assert_noop!( - Dex::remove_liquidity( + DexModule::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -803,7 +801,7 @@ fn remove_liquidity_work() { Error::::UnacceptableLiquidityWithdrawn ); assert_noop!( - Dex::remove_liquidity( + DexModule::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -814,7 +812,7 @@ fn remove_liquidity_work() { ), Error::::UnacceptableLiquidityWithdrawn ); - assert_ok!(Dex::remove_liquidity( + assert_ok!(DexModule::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -832,11 +830,11 @@ fn remove_liquidity_work() { 8_000_000_000_000, ))); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (1_000_000_000_000, 200_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 1_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 200_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 1_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 200_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 2_000_000_000_000 @@ -844,7 +842,7 @@ fn remove_liquidity_work() { assert_eq!(Tokens::free_balance(USDJ, &ALICE), 999_999_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 999_999_800_000_000_000); - assert_ok!(Dex::remove_liquidity( + assert_ok!(DexModule::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -861,9 +859,9 @@ fn remove_liquidity_work() { 200_000_000_000, 2_000_000_000_000, ))); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (0, 0)); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 0); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (0, 0)); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 0 @@ -871,7 +869,7 @@ fn remove_liquidity_work() { assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -888,7 +886,7 @@ fn remove_liquidity_work() { Tokens::reserved_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &BOB), 10_000_000_000_000 ); - assert_ok!(Dex::remove_liquidity( + assert_ok!(DexModule::remove_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -916,7 +914,7 @@ fn do_swap_with_exact_supply_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -925,10 +923,10 @@ fn do_swap_with_exact_supply_work() { 0, false, )); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, - JCHF, + CHFJ, 100_000_000_000_000, 10_000_000_000, 0, @@ -936,25 +934,25 @@ fn do_swap_with_exact_supply_work() { )); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (500_000_000_000_000, 100_000_000_000_000) ); assert_eq!( - Dex::get_liquidity(USDJ, JCHF), + DexModule::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 600_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 100_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &Dex::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 100_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &BOB), 1_000_000_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); assert_noop!( - Dex::do_swap_with_exact_supply( + DexModule::do_swap_with_exact_supply( &BOB, &[DNAR, USDJ], 100_000_000_000_000, @@ -964,7 +962,7 @@ fn do_swap_with_exact_supply_work() { Error::::InsufficientTargetAmount ); assert_noop!( - Dex::do_swap_with_exact_supply( + DexModule::do_swap_with_exact_supply( &BOB, &[DNAR, USDJ], 100_000_000_000_000, @@ -974,15 +972,11 @@ fn do_swap_with_exact_supply_work() { Error::::ExceedPriceImpactLimit, ); assert_noop!( - Dex::do_swap_with_exact_supply(&BOB, &[DNAR, USDJ, JCHF], 100_000_000_000_000, 0, None), + DexModule::do_swap_with_exact_supply(&BOB, &[DNAR, USDJ, CHFJ, EURJ], 100_000_000_000_000, 0, None), Error::::InvalidTradingPathLength, ); - assert_noop!( - Dex::do_swap_with_exact_supply(&BOB, &[JCHF, DNAR], 100_000_000_000_000, 0, None), - Error::::MustBeEnabled, - ); - assert_ok!(Dex::do_swap_with_exact_supply( + assert_ok!(DexModule::do_swap_with_exact_supply( &BOB, &[DNAR, USDJ], 100_000_000_000_000, @@ -996,53 +990,53 @@ fn do_swap_with_exact_supply_work() { 248_743_718_592_964, ))); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (251_256_281_407_036, 200_000_000_000_000) ); assert_eq!( - Dex::get_liquidity(USDJ, JCHF), + DexModule::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 351_256_281_407_036 ); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 200_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &Dex::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 200_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_248_743_718_592_964); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_900_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &BOB), 1_000_000_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); - assert_ok!(Dex::do_swap_with_exact_supply( + assert_ok!(DexModule::do_swap_with_exact_supply( &BOB, - &[DNAR, USDJ, JCHF], + &[DNAR, USDJ, CHFJ], 200_000_000_000_000, 1, None )); System::assert_last_event(Event::dex(crate::Event::Swap( BOB, - vec![DNAR, USDJ, JCHF], + vec![DNAR, USDJ, CHFJ], 200_000_000_000_000, 5_530_663_837, ))); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (126_259_437_892_983, 400_000_000_000_000) ); assert_eq!( - Dex::get_liquidity(USDJ, JCHF), + DexModule::get_liquidity(USDJ, CHFJ), (224_996_843_514_053, 4_469_336_163) ); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 351_256_281_407_036 ); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 400_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &Dex::account_id()), 4_469_336_163); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 400_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 4_469_336_163); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_248_743_718_592_964); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_700_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &BOB), 1_000_000_005_530_663_837); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_005_530_663_837); }); } @@ -1054,7 +1048,7 @@ fn do_swap_with_exact_target_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -1063,10 +1057,10 @@ fn do_swap_with_exact_target_work() { 0, false, )); - assert_ok!(Dex::add_liquidity( + assert_ok!(DexModule::add_liquidity( Origin::signed(ALICE), USDJ, - JCHF, + CHFJ, 100_000_000_000_000, 10_000_000_000, 0, @@ -1074,25 +1068,25 @@ fn do_swap_with_exact_target_work() { )); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (500_000_000_000_000, 100_000_000_000_000) ); assert_eq!( - Dex::get_liquidity(USDJ, JCHF), + DexModule::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 600_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 100_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &Dex::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 100_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000); - assert_eq!(Tokens::free_balance(JCHF, &BOB), 1_000_000_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); assert_noop!( - Dex::do_swap_with_exact_target( + DexModule::do_swap_with_exact_target( &BOB, &[DNAR, USDJ], 250_000_000_000_000, @@ -1102,7 +1096,7 @@ fn do_swap_with_exact_target_work() { Error::::ExcessiveSupplyAmount ); assert_noop!( - Dex::do_swap_with_exact_target( + DexModule::do_swap_with_exact_target( &BOB, &[DNAR, USDJ], 250_000_000_000_000, @@ -1112,21 +1106,17 @@ fn do_swap_with_exact_target_work() { Error::::ExceedPriceImpactLimit, ); assert_noop!( - Dex::do_swap_with_exact_target( + DexModule::do_swap_with_exact_target( &BOB, - &[DNAR, USDJ, JCHF], + &[DNAR, USDJ, CHFJ, EURJ], 250_000_000_000_000, 200_000_000_000_000, None ), Error::::InvalidTradingPathLength, ); - assert_noop!( - Dex::do_swap_with_exact_target(&BOB, &[JCHF, DNAR], 250_000_000_000_000, 200_000_000_000_000, None), - Error::::MustBeEnabled, - ); - assert_ok!(Dex::do_swap_with_exact_target( + assert_ok!(DexModule::do_swap_with_exact_target( &BOB, &[DNAR, USDJ], 250_000_000_000_000, @@ -1139,55 +1129,54 @@ fn do_swap_with_exact_target_work() { 101_010_101_010_102, 250_000_000_000_000, ))); - assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (250_000_000_000_000, 201_010_101_010_102) ); assert_eq!( - Dex::get_liquidity(USDJ, JCHF), + DexModule::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 350_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 201_010_101_010_102); - assert_eq!(Tokens::free_balance(JCHF, &Dex::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 201_010_101_010_102); + assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_250_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_898_989_898_989_898); - assert_eq!(Tokens::free_balance(JCHF, &BOB), 1_000_000_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); - assert_ok!(Dex::do_swap_with_exact_target( + assert_ok!(DexModule::do_swap_with_exact_target( &BOB, - &[DNAR, USDJ, JCHF], + &[DNAR, USDJ, CHFJ], 5_000_000_000, 2_000_000_000_000_000, None )); System::assert_last_event(Event::dex(crate::Event::Swap( BOB, - vec![DNAR, USDJ, JCHF], + vec![DNAR, USDJ, CHFJ], 137_654_580_386_993, 5_000_000_000, ))); assert_eq!( - Dex::get_liquidity(USDJ, DNAR), + DexModule::get_liquidity(USDJ, DNAR), (148_989_898_989_898, 338_664_681_397_095) ); assert_eq!( - Dex::get_liquidity(USDJ, JCHF), + DexModule::get_liquidity(USDJ, CHFJ), (201_010_101_010_102, 5_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &Dex::account_id()), + Tokens::free_balance(USDJ, &DexModule::account_id()), 350_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 338_664_681_397_095); - assert_eq!(Tokens::free_balance(JCHF, &Dex::account_id()), 5_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 338_664_681_397_095); + assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 5_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_250_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_761_335_318_602_905); - assert_eq!(Tokens::free_balance(JCHF, &BOB), 1_000_000_005_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_005_000_000_000); }); } @@ -1200,9 +1189,9 @@ fn initialize_added_liquidity_pools_genesis_work() { .execute_with(|| { System::set_block_number(1); - assert_eq!(Dex::get_liquidity(USDJ, DNAR), (1000000, 2000000)); - assert_eq!(Tokens::free_balance(USDJ, &Dex::account_id()), 2000000); - assert_eq!(Tokens::free_balance(DNAR, &Dex::account_id()), 3000000); + assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (1000000, 2000000)); + assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 2000000); + assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 3000000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 4000000 diff --git a/lib-serml/dex/src/weights.rs b/lib-serml/dex/src/weights.rs index b4cb3772c..2af8174f0 100644 --- a/lib-serml/dex/src/weights.rs +++ b/lib-serml/dex/src/weights.rs @@ -44,7 +44,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for setheum-dex. +/// Weight functions needed for setheum_dex. pub trait WeightInfo { fn enable_trading_pair() -> Weight; fn disable_trading_pair() -> Weight; @@ -57,7 +57,7 @@ pub trait WeightInfo { fn swap_with_exact_target(u: u32, ) -> Weight; } -/// Weights for setheum-dex using the Setheum node and recommended hardware. +/// Weights for setheum_dex using the Setheum node and recommended hardware. pub struct SetheumWeight(PhantomData); impl WeightInfo for SetheumWeight { fn enable_trading_pair() -> Weight { diff --git a/lib-serml/incentives/src/lib.rs b/lib-serml/incentives/src/lib.rs index dfb099bf4..ff689c319 100644 --- a/lib-serml/incentives/src/lib.rs +++ b/lib-serml/incentives/src/lib.rs @@ -29,7 +29,7 @@ use sp_runtime::{ DispatchResult, FixedPointNumber, RuntimeDebug, }; use sp_std::{fmt::Debug, vec::Vec}; -use support::{SerpTreasury, DexIncentives, DexManager, Rate}; +use support::{SerpTreasury, DEXIncentives, DEXManager, Rate}; mod mock; mod tests; @@ -41,6 +41,7 @@ pub use weights::WeightInfo; /// PoolId for various rewards pools #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub enum PoolId { + // TODO: Update new swapped changes /// Rewards pool(DexCurrencyId) (SDEX or HALAL) for market makers who provide Dex liquidity /// for all pools. DexIncentive(CurrencyId), @@ -58,7 +59,7 @@ pub enum PoolId { DexBonus(CurrencyId), /// Rewards pool(SettEURCurrencyId) (EURJ or JEUR) for market makers who provide Dex liquidity - /// for Certain Strategic Currencies LPs, e.g. DOT, XBTC et al. + /// for Certain Strategic Currencies LPs. DexExtra(CurrencyId), } @@ -138,7 +139,7 @@ pub mod module { /// The Extra reward type (EURJ/JEUR/rEUR) /// EURJ in Setheum, JEUR in Neom, rEUR in NewRome testnet - /// For Certain Strategic Currencies LPs, e.g. DOT, XBTC et al. + /// For Certain Strategic Currencies LPs. #[pallet::constant] type ExtraCurrencyId: Get; @@ -162,7 +163,7 @@ pub mod module { type Currency: MultiCurrency; /// Dex to supply liquidity info - type Dex: DexManager; + type Dex: DEXManager; /// The module id, keep DexShare LP. #[pallet::constant] @@ -363,7 +364,7 @@ impl Pallet { } } -impl DexIncentives for Pallet { +impl DEXIncentives for Pallet { fn do_deposit_dex_share(who: &T::AccountId, lp_currency_id: CurrencyId, amount: Balance) -> DispatchResult { ensure!(lp_currency_id.is_dex_share_currency_id(), Error::::InvalidCurrencyId); diff --git a/lib-serml/incentives/src/mock.rs b/lib-serml/incentives/src/mock.rs index 5ed5ab345..7472deb80 100644 --- a/lib-serml/incentives/src/mock.rs +++ b/lib-serml/incentives/src/mock.rs @@ -32,7 +32,7 @@ use primitives::TokenSymbol; use sp_core::{H160, H256}; use sp_runtime::{testing::Header, traits::IdentityLookup}; use sp_std::cell::RefCell; -pub use support::{SerpTreasury, DexManager, Price, Ratio}; +pub use support::{SerpTreasury, DEXManager, Price, Ratio}; pub type AccountId = u128; pub type BlockNumber = u64; @@ -212,7 +212,7 @@ impl SerpTreasury for MockSerpTreasury { } pub struct MockDex; -impl DexManager for MockDex { +impl DEXManager for MockDex { fn get_liquidity_pool(currency_id_a: CurrencyId, currency_id_b: CurrencyId) -> (Balance, Balance) { match (currency_id_a, currency_id_b) { (SETT, CHFJ) => (500, 100), diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index 139601d05..4ccfed75c 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -43,7 +43,7 @@ use sp_runtime::{ FixedPointNumber, }; use sp_std::{convert::TryInto, prelude::*, vec}; -use support::{CurrencyIdMapping, DexManager, ExchangeRateProvider, Price, PriceProvider}; +use support::{CurrencyIdMapping, DEXManager, ExchangeRateProvider, Price, PriceProvider}; mod mock; mod tests; @@ -128,7 +128,7 @@ pub mod module { type LockOrigin: EnsureOrigin; /// Dex provide liquidity info. - type Dex = DexManager; + type Dex = DEXManager; /// Currency provide the total insurance of LPToken. type Currency: MultiCurrency; diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index 241cf3d1f..a8f30f5a3 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -189,7 +189,7 @@ impl DataFeeder for MockDataProvider { } pub struct MockDex; -impl DexManager for MockDex { +impl DEXManager for MockDex { fn get_liquidity_pool(currency_id_a: CurrencyId, currency_id_b: CurrencyId) -> (Balance, Balance) { match (currency_id_a, currency_id_b) { (USDJ, DNAR) => (10000, 200), diff --git a/lib-serml/serp-auction/src/lib.rs b/lib-serml/serp-auction/src/lib.rs index c5aa686be..275cc5839 100644 --- a/lib-serml/serp-auction/src/lib.rs +++ b/lib-serml/serp-auction/src/lib.rs @@ -52,7 +52,7 @@ use sp_runtime::{ DispatchError, DispatchResult, FixedPointNumber, RandomNumberGenerator, RuntimeDebug, }; use sp_std::prelude::*; -use support::{SerpTreasury, DexManager, PriceProvider, Rate}; +use support::{SerpTreasury, DEXManager, PriceProvider, Rate}; mod mock; mod tests; @@ -192,7 +192,7 @@ pub mod module { type SerpTreasury: SerpTreasury; /// Dex to get exchange info - type Dex: DexManager; + type Dex: DEXManager; /// The price source of currencies type PriceSource: PriceProvider; diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index b848158e3..7e788e89d 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -45,7 +45,7 @@ pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); -pub const BTC: CurrencyId = CurrencyId::Token(TokenSymbol::XBTC); +pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); mod serp_auction { pub use super::super::*; @@ -156,7 +156,7 @@ parameter_types! { pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const GetExchangeFee: (u32, u32) = (0, 100); pub const TradingPathLimit: u32 = 3; - pub EnabledTradingPairs : Vec = vec![TradingPair::new(USDJ, BTC)]; + pub EnabledTradingPairs : Vec = vec![TradingPair::new(USDJ, CHFJ)]; } impl dex::Config for Runtime { @@ -165,7 +165,7 @@ impl dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DexPalletId; - type DexIncentives = (); + type DEXIncentives = (); type WeightInfo = (); type ListingOrigin = EnsureSignedBy; } @@ -238,9 +238,9 @@ impl Default for ExtBuilder { (ALICE, USDJ, 1000), (BOB, USDJ, 1000), (CAROL, USDJ, 1000), - (ALICE, BTC, 1000), - (BOB, BTC, 1000), - (CAROL, BTC, 1000), + (ALICE, CHFJ, 1000), + (BOB, CHFJ, 1000), + (CAROL, CHFJ, 1000), (ALICE, DNAR, 1000), (BOB, DNAR, 1000), (CAROL, DNAR, 1000), diff --git a/lib-serml/serp-auction/src/tests.rs b/lib-serml/serp-auction/src/tests.rs index 992439921..c9dca1634 100644 --- a/lib-serml/serp-auction/src/tests.rs +++ b/lib-serml/serp-auction/src/tests.rs @@ -35,7 +35,7 @@ fn get_auction_time_to_close_work() { #[test] fn setter_auction_methods() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 100)); let setter_auction_with_positive_target = SerpAuctionManagerModule::setter_auctions(0).unwrap(); assert_eq!(setter_auction_with_positive_target.always_forward(), false); assert_eq!(setter_auction_with_positive_target.in_reverse_stage(99), false); @@ -47,7 +47,7 @@ fn setter_auction_methods() { assert_eq!(setter_auction_with_positive_target.reserve_amount(80, 100), 10); assert_eq!(setter_auction_with_positive_target.reserve_amount(100, 200), 5); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 0)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 0)); let setter_auction_with_zero_target = SerpAuctionManagerModule::setter_auctions(1).unwrap(); assert_eq!(setter_auction_with_zero_target.always_forward(), true); assert_eq!(setter_auction_with_zero_target.in_reverse_stage(0), false); @@ -75,20 +75,20 @@ fn new_setter_auction_work() { System::set_block_number(1); let ref_count_0 = System::consumers(&ALICE); assert_noop!( - SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 0, 100), + SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 0, 100), Error::::InvalidAmount, ); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 100)); - System::assert_last_event(Event::serp_auction(crate::Event::NewSetterAuction(0, BTC, 10, 100))); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 100)); + System::assert_last_event(Event::serp_auction(crate::Event::NewSetterAuction(0, CHFJ, 10, 100))); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 10); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 10); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 100); assert_eq!(AuctionModule::auctions_index(), 1); assert_eq!(System::consumers(&ALICE), ref_count_0 + 1); assert_noop!( - SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, Balance::max_value(), Balance::max_value()), + SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, Balance::max_value(), Balance::max_value()), Error::::InvalidAmount, ); }); @@ -280,7 +280,7 @@ fn serplus_auction_bid_handler_work() { #[test] fn bid_when_soft_cap_for_setter_auction_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 10, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 100)); assert_eq!( SerpAuctionManagerModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, Change::NewValue(Some(101)) @@ -338,21 +338,21 @@ fn bid_when_soft_cap_for_serplus_auction_work() { fn setter_auction_end_handler_without_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); + assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 100); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 100); let alice_ref_count_0 = System::consumers(&ALICE); assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); SerpAuctionManagerModule::on_auction_ended(0, None); System::assert_last_event(Event::serp_auction(crate::Event::CancelAuction(0))); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); let alice_ref_count_1 = System::consumers(&ALICE); assert_eq!(alice_ref_count_1, alice_ref_count_0 - 1); }); @@ -362,16 +362,16 @@ fn setter_auction_end_handler_without_bid() { fn setter_auction_end_handler_in_reverse_stage() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); + assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); assert_eq!( SerpAuctionManagerModule::setter_auction_bid_handler(2, 0, (BOB, 400), None).is_ok(), true ); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 50); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 50); - assert_eq!(Tokens::free_balance(BTC, &ALICE), 1050); - assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 50); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 50); + assert_eq!(Tokens::free_balance(CHFJ, &ALICE), 1050); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 800); assert_eq!(SerpTreasuryModule::serplus_pool(), 200); @@ -380,13 +380,13 @@ fn setter_auction_end_handler_in_reverse_stage() { assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 400))); - System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, BTC, 50, BOB, 200))); + System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, CHFJ, 50, BOB, 200))); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 0); assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); - assert_eq!(Tokens::free_balance(BTC, &ALICE), 1050); - assert_eq!(Tokens::free_balance(BTC, &BOB), 1050); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); + assert_eq!(Tokens::free_balance(CHFJ, &ALICE), 1050); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1050); assert_eq!(Tokens::free_balance(USDJ, &BOB), 800); assert_eq!(SerpTreasuryModule::serplus_pool(), 200); @@ -401,16 +401,16 @@ fn setter_auction_end_handler_in_reverse_stage() { fn setter_auction_end_handler_by_dealing_which_target_not_zero() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); + assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); assert_eq!( SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), true ); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 100); - assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 100); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 900); assert_eq!(SerpTreasuryModule::serplus_pool(), 100); @@ -419,14 +419,14 @@ fn setter_auction_end_handler_by_dealing_which_target_not_zero() { assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 100))); - System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, BTC, 100, BOB, 100))); + System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, CHFJ, 100, BOB, 100))); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 0); assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(Tokens::free_balance(BTC, &BOB), 1100); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1100); let alice_ref_count_1 = System::consumers(&ALICE); assert_eq!(alice_ref_count_1, alice_ref_count_0 - 1); @@ -439,26 +439,26 @@ fn setter_auction_end_handler_by_dealing_which_target_not_zero() { fn setter_auction_end_handler_by_dex_which_target_not_zero() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, BTC, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, BTC, 100, 200)); + assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); assert_eq!( SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 20), None).is_ok(), true ); assert_ok!(DexModule::add_liquidity( Origin::signed(CAROL), - BTC, + CHFJ, USDJ, 100, 1000, false )); - assert_eq!(DexModule::get_swap_target_amount(&[BTC, USDJ], 100, None).unwrap(), 500); + assert_eq!(DexModule::get_swap_target_amount(&[CHFJ, USDJ], 100, None).unwrap(), 500); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 100); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 100); - assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 100); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 980); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1000); assert_eq!(SerpTreasuryModule::serplus_pool(), 20); @@ -469,16 +469,16 @@ fn setter_auction_end_handler_by_dex_which_target_not_zero() { assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 20))); let dex_take_setter_auction = - Event::serp_auction(crate::Event::DEXTakeSetterAuction(0, BTC, 100, 500)); + Event::serp_auction(crate::Event::DEXTakeSetterAuction(0, CHFJ, 100, 500)); assert!(System::events() .iter() .any(|record| record.event == dex_take_setter_auction)); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); + assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 0); assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(BTC), 0); - assert_eq!(Tokens::free_balance(BTC, &BOB), 1000); + assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); + assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1000); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1300); assert_eq!(SerpTreasuryModule::serplus_pool(), 520); diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index 434d8ad5b..d63ca1e4f 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -36,7 +36,7 @@ use sp_runtime::{ traits::{AccountIdConversion, One, Zero}, DispatchError, DispatchResult, FixedPointNumber, }; -use support::{SerpTreasury, DexManager, Ratio}; +use support::{SerpTreasury, DEXManager, Ratio}; mod mock; mod tests; pub mod weights; @@ -105,7 +105,7 @@ pub mod module { type SerpAuctionManagerHandler: SerpAuctionManager; /// Dex manager is used to swap reserve asset (Setter) for propper (SettCurrency). - type Dex: DexManager; + type Dex: DEXManager; #[pallet::constant] /// The cap of lots when an auction is created diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index 899bc3915..baf28d76f 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -172,7 +172,7 @@ impl dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DexPalletId; - type DexIncentives = (); + type DEXIncentives = (); type WeightInfo = (); type ListingOrigin = EnsureSignedBy; } diff --git a/lib-serml/settmint-engine/src/lib.rs b/lib-serml/settmint-engine/src/lib.rs index 6192d2a31..335c3e3b6 100644 --- a/lib-serml/settmint-engine/src/lib.rs +++ b/lib-serml/settmint-engine/src/lib.rs @@ -51,7 +51,7 @@ use sp_runtime::{ }; use sp_std::prelude::*; use support::{ - DexManager, ExchangeRate, Price, PriceProvider, Rate, Ratio, + DEXManager, ExchangeRate, Price, PriceProvider, Rate, Ratio, }; mod mock; diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index 918e9c0aa..1e79cf98a 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -326,7 +326,7 @@ impl dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DexPalletId; - type DexIncentives = (); + type DEXIncentives = (); type WeightInfo = (); type ListingOrigin = EnsureSignedBy; } diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index 0d96d5dfb..d5fd087b8 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -51,15 +51,6 @@ pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); // SettinDex pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); // Setter - The Defacto stablecoin & settmint reserve asset pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); // Setheum USD (US Dollar stablecoin) -pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); // Setheum GBP (Pound Sterling stablecoin) -pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); // Setheum EUR (Euro stablecoin) -pub const KWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::KWDJ); // Setheum KWD (Kuwaiti Dinar stablecoin) -pub const JODJ: CurrencyId = CurrencyId::Token(TokenSymbol::JODJ); // Setheum JOD (Jordanian Dinar stablecoin) -pub const BHDJ: CurrencyId = CurrencyId::Token(TokenSymbol::BHDJ); // Setheum BHD (Bahraini Dirham stablecoin) -pub const KYDJ: CurrencyId = CurrencyId::Token(TokenSymbol::KYDJ); // Setheum KYD (Cayman Islands Dollar stablecoin) -pub const OMRJ: CurrencyId = CurrencyId::Token(TokenSymbol::OMRJ); // Setheum OMR (Omani Riyal stablecoin) -pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); // Setheum CHF (Swiss Franc stablecoin) -pub const GIPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GIPJ); // Setheum GIP (Gibraltar Pound stablecoin) parameter_types! { pub const BlockHashCount: u64 = 250; @@ -398,10 +389,8 @@ impl Default for ExtBuilder { fn default() -> Self { Self { endowed_accounts: vec![ - (ALICE, BTC, 1000), - (BOB, BTC, 1000), - (ALICE, DOT, 1000), - (BOB, DOT, 1000), + (ALICE, SETT, 1000), + (BOB, SETT, 1000), ], } } diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index 58e830e61..9e2f9bbc1 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -66,7 +66,7 @@ impl StandardManager { +pub trait SetheumDEXManager { fn get_liquidity_pool(currency_id_a: CurrencyId, currency_id_b: CurrencyId) -> (Balance, Balance); fn get_swap_target_amount( @@ -98,7 +98,7 @@ pub trait SetheumDexManager { ) -> sp_std::result::Result; } -impl SetheumDexManager for () +impl SetheumDEXManager for () where Balance: Default, { @@ -262,12 +262,12 @@ pub trait ExchangeRateProvider { fn get_exchange_rate() -> ExchangeRate; } -pub trait DexIncentives { +pub trait DEXIncentives { fn do_deposit_dex_share(who: &AccountId, lp_currency_id: CurrencyId, amount: Balance) -> DispatchResult; fn do_withdraw_dex_share(who: &AccountId, lp_currency_id: CurrencyId, amount: Balance) -> DispatchResult; } -impl DexIncentives for () { +impl DEXIncentives for () { fn do_deposit_dex_share(_: &AccountId, _: CurrencyId, _: Balance) -> DispatchResult { Ok(()) } diff --git a/lib-serml/transaction-payment/src/lib.rs b/lib-serml/transaction-payment/src/lib.rs index 655ebbb51..6824f5f98 100644 --- a/lib-serml/transaction-payment/src/lib.rs +++ b/lib-serml/transaction-payment/src/lib.rs @@ -48,7 +48,7 @@ use sp_runtime::{ FixedPointNumber, FixedPointOperand, FixedU128, Perquintill, }; use sp_std::{prelude::*, vec}; -use support::{DexManager, Ratio, TransactionPayment}; +use support::{DEXManager, Ratio, TransactionPayment}; mod mock; mod tests; @@ -252,7 +252,7 @@ pub mod module { type FeeMultiplierUpdate: MultiplierUpdate; /// Dex to exchange currencies. - type Dex = DexManager; + type Dex = DEXManager; /// The max slippage allowed when swap fee with Dex #[pallet::constant] diff --git a/lib-serml/transaction-payment/src/mock.rs b/lib-serml/transaction-payment/src/mock.rs index a7c967ffc..38b29b4e3 100644 --- a/lib-serml/transaction-payment/src/mock.rs +++ b/lib-serml/transaction-payment/src/mock.rs @@ -153,7 +153,7 @@ impl dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DexPalletId; - type DexIncentives = (); + type DEXIncentives = (); type WeightInfo = (); type ListingOrigin = frame_system::EnsureSignedBy; } diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index 8412c6e0c..f98a0afe7 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -923,7 +923,7 @@ impl dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DexPalletId; - type DexIncentives = Incentives; + type DEXIncentives = Incentives; type WeightInfo = weights::dex::WeightInfo; type ListingOrigin = EnsureRootOrHalfGeneralCouncil; } diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index d6e9163fe..ef5374b57 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -924,7 +924,7 @@ impl dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DexPalletId; - type DexIncentives = Incentives; + type DEXIncentives = Incentives; type WeightInfo = weights::dex::WeightInfo; type ListingOrigin = EnsureRootOrHalfGeneralCouncil; } diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index fcf4ca798..82c2d836f 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -924,7 +924,7 @@ impl dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DexPalletId; - type DexIncentives = Incentives; + type DEXIncentives = Incentives; type WeightInfo = weights::dex::WeightInfo; type ListingOrigin = EnsureRootOrHalfGeneralCouncil; } From 5aa9ce152c117164caf9306b19fe59eea7ed2b6e Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 04:13:43 +0800 Subject: [PATCH 28/83] upd inline --- lib-serml/prices/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index 4ccfed75c..fefe9f7eb 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -24,7 +24,8 @@ //! do some process and feed prices for setheum, this includes constructing //! the Setter (SETT) currency basket price. //! Process include: -//! - specify a fixed price for stable currency +//! - specify a fixed price for stable currencies +//! - specify the Setter basket currency price //! - feed price in USD or related price bewteen two currencies //! - lock/unlock the price data get from oracle From f54b3d8d3b8cba8ddb63656ad797f3f08b52b01e Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 05:06:32 +0800 Subject: [PATCH 29/83] Update get_stablecoin_fixed_price --- lib-serml/prices/src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index fefe9f7eb..4c70b1312 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -257,12 +257,11 @@ impl PriceProvider for Pallet { T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, ); - let fiat_currency_id = Self::get_peg_currency_by_currency_id(¤cy_id); - ensure!( - T::FiatCurrencyIds::get().contains(&fiat_currency_id), - Error::::InvalidFiatCurrencyType, - ); + if currency_id == T::SetterCurrencyId::get() { + T::Prices::get_setter_fixed_price() + } else { Self::get_peg_price(¤cy_id) + } } /// get the market price (not fixed price, for SERP-TES) of a From 25161d8347aa7e56a55c355bcb634a6b459f2e12 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 05:49:59 +0800 Subject: [PATCH 30/83] add Amount primitive to SerpTreasury mock --- lib-serml/serp-treasury/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index baf28d76f..8f95d59da 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -24,7 +24,7 @@ use super::*; use frame_support::{construct_runtime, ord_parameter_types, parameter_types, PalletId}; use frame_system::EnsureSignedBy; use orml_traits::parameter_type_with_key; -use primitives::{TokenSymbol, TradingPair}; +use primitives::{Amount, TokenSymbol, TradingPair}; use sp_core::H256; use sp_runtime::{Permill, testing::Header, traits::IdentityLookup}; use sp_std::cell::RefCell; From ce6da871d875f304fc3ed1640e6eebc1d5e76ae2 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 05:55:24 +0800 Subject: [PATCH 31/83] Update Setter Price and support erc20 on SEVM --- lib-serml/prices/src/lib.rs | 28 +++++++++++------- lib-serml/prices/src/mock.rs | 10 +++++-- lib-serml/prices/src/tests.rs | 54 +++++++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index 4c70b1312..72e26fb65 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -128,8 +128,8 @@ pub mod module { /// The origin which may lock and unlock prices feed to system. type LockOrigin: EnsureOrigin; - /// Dex provide liquidity info. - type Dex = DEXManager; + /// DEX to provide liquidity info. + type DEX = DEXManager; /// Currency provide the total insurance of LPToken. type Currency: MultiCurrency; @@ -257,8 +257,8 @@ impl PriceProvider for Pallet { T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, ); - if currency_id == T::SetterCurrencyId::get() { - T::Prices::get_setter_fixed_price() + if currency_id == T::GetSetterCurrencyId::get() { + Self::get_setter_fixed_price() } else { Self::get_peg_price(¤cy_id) } @@ -291,12 +291,20 @@ impl PriceProvider for Pallet { T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, ); - let fiat_currency_id = Self::get_peg_currency_by_currency_id(¤cy_id); - ensure!( - T::FiatCurrencyIds::get().contains(&fiat_currency_id), - Error::::InvalidFiatCurrencyType, - ); - Self::get_relative_price(¤cy_id, &fiat_currency_id) + if currency_id == T::GetSetterCurrencyId::get() { + let basket_price = Self::get_setter_fixed_price(); + let coin_price = Self::get_price(currency_id); + coin_price.checked_div(&basket_price) + } else if !currency_id == T::GetSetterCurrencyId::get() { + let fiat_currency_id = Self::get_peg_currency_by_currency_id(¤cy_id); + ensure!( + T::FiatCurrencyIds::get().contains(&fiat_currency_id), + Error::::InvalidFiatCurrencyType, + ); + Self::get_relative_price(¤cy_id, &fiat_currency_id) + } else { + None + } } /// Get the price of a Setter (SETT basket coin - basket of currencies) - diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index a8f30f5a3..95ad66578 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -25,7 +25,7 @@ use frame_support::{construct_runtime, ord_parameter_types, parameter_types}; use frame_system::EnsureSignedBy; use orml_traits::{parameter_type_with_key, DataFeeder}; use primitives::{Amount, TokenSymbol}; -use sp_core::H256; +use sp_core::{H160, H256}; use sp_runtime::{ testing::Header, traits::{IdentityLookup, One as OneT, Zero}, @@ -197,6 +197,10 @@ impl DEXManager for MockDex { } } + fn get_liquidity_token_address(_currency_id_a: CurrencyId, _currency_id_b: CurrencyId) -> Option { + unimplemented!() + } + fn get_swap_target_amount( _path: &[CurrencyId], _supply_amount: Balance, @@ -457,7 +461,7 @@ impl Config for Runtime { type StableCurrencyIds = StableCurrencyIds; type FiatCurrencyIds = FiatCurrencyIds; type LockOrigin = EnsureSignedBy; - type Dex = MockDex; + type DEX = MockDEX; type Currency = Tokens; type CurrencyIdMapping = MockCurrencyIdMapping; type WeightInfo = (); @@ -473,7 +477,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system::{Pallet, Call, Config, Storage, Event}, - SetheumPrices: setheum_prices::{Pallet, Storage, Call, Event}, + SetheumPrices: prices::{Pallet, Storage, Call, Event}, Tokens: orml_tokens::{Pallet, Call, Storage, Event}, } ); diff --git a/lib-serml/prices/src/tests.rs b/lib-serml/prices/src/tests.rs index b24c4fcdb..44d52bc3f 100644 --- a/lib-serml/prices/src/tests.rs +++ b/lib-serml/prices/src/tests.rs @@ -53,6 +53,16 @@ fn get_price_of_stable_currency_id() { }); } +#[test] +fn get_price_of_setter_basket_currency_id() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_price(SETT), + Some(Price::saturating_from_integer(1606750)) + ); // 1.60675 USD, right shift the decimal point (18-12) places + }); +} + #[test] fn get_price_of_lp_token_currency_id() { ExtBuilder::default().build().execute_with(|| { @@ -78,7 +88,7 @@ fn get_price_of_lp_token_currency_id() { } #[test] -fn get_relative_price_work() { +fn get_relative_price_works() { ExtBuilder::default().build().execute_with(|| { assert_eq!( SetheumPrices::get_relative_price(DNAR, USDJ), @@ -91,17 +101,49 @@ fn get_relative_price_work() { * (12-8) places */ ); assert_eq!( - SetheumPrices::get_relative_price(JUSD, DNAR), - Some(Price::saturating_from_rational(1, 2)) // 1JUSD = 1/2DNAR, right shift the decimal point (10-10) places - ); - assert_eq!( - SetheumPrices::get_relative_price(JUSD, USDJ), + SetheumPrices::get_relative_price(USDJ, USDJ), Some(Price::saturating_from_rational(1, 1)) // 1USDJ = 1USDJ, right shift the decimal point (10-10) places ); assert_eq!(SetheumPrices::get_relative_price(USDJ, DNAR), None); }); } +#[test] +fn get_coin_to_peg_relative_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + PricesModule::get_coin_to_peg_relative_price(USDJ), + Some(Price::saturating_from_rational(1100000, 1)) + // 1.1 USD, right shift the decimal point (18-12) places + // This means that the stablecoin's price is 10% above the peg, + // meaning demand is 10% higher than supply, thus needs 10% serping. + ); + assert_eq!( + PricesModule::get_coin_to_peg_relative_price(EURJ), + Some(Price::saturating_from_rational(990000, 1)) + // 0.99 EUR, right shift the decimal point (18-12) places + // This means that the stablecoin's price is 1% below the peg, + // meaning demand is 1% lower than supply, thus needs 1% serping. + ); + assert_eq!( + PricesModule::get_coin_to_peg_relative_price(CHFJ), + Some(Price::saturating_from_rational(1000000, 1)) + // 1 CHF, right shift the decimal point (18-12) places + // This means that the stablecoin's price is stable to the peg, + // meaning supply meets demand, thus doesn't need serping. + ); + assert_eq!( + PricesModule::get_coin_to_peg_relative_price(SETT), + Some(Price::saturating_from_rational(1200000, 1)) + // 1.2 SETT-Basket, right shift the decimal point (18-12) places + // This means that the stablecoin's price is 20% above the peg, + // meaning demand is 20% higher than supply, thus needs 20% serping. + ); + assert_eq!(PricesModule::get_coin_to_peg_relative_price(DNAR), None); + // DNAR is not a stablecoin, so get_coin_to_peg_relative_price returns None + }); +} + #[test] fn lock_price_work() { ExtBuilder::default().build().execute_with(|| { From 5888bf3efb73e114ce5cd726380ea57373ac300e Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 07:53:27 +0800 Subject: [PATCH 32/83] remove unneeded offchain-worker in serp auctions --- lib-serml/serp-auction/src/lib.rs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/lib-serml/serp-auction/src/lib.rs b/lib-serml/serp-auction/src/lib.rs index 275cc5839..f235f8bc3 100644 --- a/lib-serml/serp-auction/src/lib.rs +++ b/lib-serml/serp-auction/src/lib.rs @@ -32,24 +32,12 @@ #![allow(clippy::upper_case_acronyms)] use frame_support::{log, pallet_prelude::*, transactional}; -use frame_system::{ - offchain::{SendTransactionTypes, SubmitTransaction}, - pallet_prelude::*, -}; +use frame_system::pallet_prelude::*, use orml_traits::{Auction, AuctionHandler, Change, MultiCurrency, OnNewBidResult}; -use orml_utilities::{IterableStorageMapExtended, OffchainErr}; use primitives::{AuctionId, Balance, CurrencyId}; use sp_runtime::{ - offchain::{ - storage::StorageValueRef, - storage_lock::{StorageLock, Time}, - Duration, - }, traits::{BlakeTwo256, CheckedDiv, Hash, Saturating, Zero}, - transaction_validity::{ - InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, ValidTransaction, - }, - DispatchError, DispatchResult, FixedPointNumber, RandomNumberGenerator, RuntimeDebug, + DispatchError, DispatchResult, RuntimeDebug, }; use sp_std::prelude::*; use support::{SerpTreasury, DEXManager, PriceProvider, Rate}; @@ -147,7 +135,7 @@ pub mod module { use super::*; #[pallet::config] - pub trait Config: frame_system::Config + SendTransactionTypes> { + pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; #[pallet::constant] From d0ac5991689c72d7b677d39e24658d57453b886d Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 08:56:35 +0800 Subject: [PATCH 33/83] Update mock.rs --- lib-serml/serp-auction/src/mock.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index 7e788e89d..764d981fc 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -41,6 +41,7 @@ pub type Amount = i64; pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; pub const CAROL: AccountId = 3; + pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); From e6f042d6a8a3dde8df444faf7452463023f4fc6e Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 12:35:45 +0800 Subject: [PATCH 34/83] remove ARS, add VND currencies --- primitives/src/currency.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index 8a45031cb..76853c957 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -184,7 +184,6 @@ create_currency_id! { SETT("Setter", 12) = 2, // SettCurrencies (Alphabetical Order) AEDJ("Setheum UAE Emirati Dirham", 12) = 3, - ARSJ("Setheum Argentine Peso", 12) = 4, AUDJ("Setheum Australian Dollar", 12) = 5, BRLJ("Setheum Brazilian Real", 12) = 6, CADJ("Setheum Canadian Dollar", 12) = 7, @@ -218,11 +217,14 @@ create_currency_id! { SGDJ("Setheum Singapore Dollar", 12) = 36, THBJ("Setheum Thai Baht", 12) = 37, TRYJ("Setheum Turkish Lira", 12) = 38, - TWDJ("Setheum Taiwan Dollar", 12) = 39, + TWDJ("Setheum New Taiwan Dollar", 12) = 39, TZSJ("Setheum Tanzanian Shilling", 12) = 40, UAHJ("Setheum Ukranian Hryvnia", 12) = 41, USDJ("Setheum US Dollar", 12) = 42, + JVND("Setheum Vietnamese Dong") = 43, ZARJ("Setheum South African Rand", 12) = 43, + // Foreign System Currencies (Alphabetical Order) + RENBTC("renBTC", 8) = 4, /// Ends at 85 (42 places left yet reserved) /// Neom Network >---------------------->> @@ -232,7 +234,6 @@ create_currency_id! { NSETT("Neom Setter", 12) = 88, // SettCurrencies (Alphabetical Order) JAED("Neom UAE Emirati Dirham", 12) = 3, - JARS("Neom Argentine Peso", 12) = 4, JAUD("Neom Australian Dollar", 12) = 5, JBRL("Neom Brazilian Real", 12) = 6, JCAD("Neom Canadian Dollar", 12) = 7, @@ -266,18 +267,20 @@ create_currency_id! { JSGD("Neom Singapore Dollar", 12) = 36, JTHB("Neom Thai Baht", 12) = 37, JTRY("Neom Turkish Lira", 12) = 38, - JTWD("Neom Taiwan Dollar", 12) = 39, + JTWD("Neom New Taiwan Dollar", 12) = 39, JTZS("Neom Tanzanian Shilling", 12) = 40, JUAH("Neom Ukranian Hryvnia", 12) = 41, JUSD("Neom US Dollar", 12) = 42, - JZAR("Neom South African Rand", 12) = 43, + JVND("Neom Vietnamese Dong") = 43, + JZAR("Neom South African Rand", 12) = 44, + // Foreign System Currencies (Alphabetical Order) + RENBTC("Ren Protocol BTC", 8) = 4, /// Ends at 170 (42 places left yet reserved) /// Fiat Currencies as Pegs /// Fiat Currencies - only for price feed (Alphabetical Order) /// Starts from 171 (85 places available) AED("Fiat UAE Emirati Dirham", 12) = 171, - ARS("Fiat Argentine Peso", 12) = 172, AUD("Fiat Australian Dollar", 12) = 173, BRL("Fiat Brazilian Real", 12) = 174, CAD("Fiat Canadian Dollar", 12) = 175, @@ -311,17 +314,18 @@ create_currency_id! { SGD("Fiat Singapore Dollar", 12) = 204, THB("Fiat Thai Baht", 12) = 205, TRY("Fiat Turkish Lira", 12) = 206, - TWD("Fiat Taiwan Dollar", 12) = 207, + TWD("Fiat New Taiwan Dollar", 12) = 207, TZS("Fiat Tanzanian Shilling", 12) = 208, UAH("Fiat Ukranian Hryvnia", 12) = 209, USD("Fiat US Dollar", 12) = 210, - ZAR("Fiat South African Rand", 12) = 211, - KWD("Fiat Kuwaiti Dinar", 12) = 212, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - JOD("Fiat Jordanian Dinar", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - BHD("Fiat Bahraini Dirham", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - KYD("Fiat Cayman Islands Dollar", 12) = 215, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - OMR("Fiat Omani Riyal", 12) = 216, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - GIP("Fiat Gibraltar Pound", 12) = 217, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + VND("Fiat Vietnamese Dong") = 211, + ZAR("Fiat South African Rand", 12) = 212, + KWD("Fiat Kuwaiti Dinar", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + JOD("Fiat Jordanian Dinar", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + BHD("Fiat Bahraini Dirham", 12) = 215, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + KYD("Fiat Cayman Islands Dollar", 12) = 216, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + OMR("Fiat Omani Riyal", 12) = 217, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + GIP("Fiat Gibraltar Pound", 12) = 218, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. /// Ends at 255 (38 places left yet reserved). } } From 331d329011a24566a09537e664561b2acd4ce978 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 12:53:42 +0800 Subject: [PATCH 35/83] Add RENBTC currency primitive --- primitives/src/currency.rs | 266 +++++++++++++++++++------------------ 1 file changed, 134 insertions(+), 132 deletions(-) diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index 76853c957..5ae568585 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -179,154 +179,156 @@ create_currency_id! { pub enum TokenSymbol { /// Setheum Network /// Starts from 0 (85 places available) - DNAR("Setheum Dinar", 10) = 0, - SDEX("SettinDex", 10) = 1, + DNAR("Setheum Dinar", 10) = 0, // could consider having 12 decimals too. + SDEX("SettinDex", 10) = 1, // could consider having 12 decimals too. SETT("Setter", 12) = 2, // SettCurrencies (Alphabetical Order) AEDJ("Setheum UAE Emirati Dirham", 12) = 3, - AUDJ("Setheum Australian Dollar", 12) = 5, - BRLJ("Setheum Brazilian Real", 12) = 6, - CADJ("Setheum Canadian Dollar", 12) = 7, - CHFJ("Setheum Swiss Franc", 12) = 8, - CLPJ("Setheum Chilean Peso", 12) = 9, - CNYJ("Setheum Japanese Yen", 12) = 10, - COPJ("Setheum Colombian Peso", 12) = 11, - EURJ("Setheum Euro", 12) =12, - GBPJ("Setheum Pound Sterling", 12) = 13, - HKDJ("Setheum HongKong Dollar", 12) = 14, - HUFJ("Setheum Hungarian Forint", 12) = 15, - IDRJ("Setheum Indonesian Rupiah", 12) = 16, - JPYJ("Setheum Japanese Yen", 12) = 18, - KESJ("Setheum Kenyan Shilling", 12) = 19, - KRWJ("Setheum South Korean Won", 12) = 20, - KZTJ("Setheum Kzakhstani Tenge", 12) = 21, - MXNJ("Setheum Mexican Peso", 12) = 22, - MYRJ("Setheum Malaysian Ringgit", 12) = 23, - NGNJ("Setheum Nigerian Naira", 12) = 24, - NOKJ("Setheum Norwegian Krone", 12) = 25, - NZDJ("Setheum New Zealand Dollar ", 12) = 26, - PENJ("Setheum Peruvian Sol", 12) = 27, - PHPJ("Setheum Philippine Peso", 12) = 28, - PKRJ("Setheum Pakistani Rupee", 12) = 29, - PLNJ("Setheum Polish Zloty", 12) = 30, - QARJ("Setheum Qatari Riyal", 12) = 31, - RONJ("Setheum Romanian Leu", 12) = 32, - RUBJ("Setheum Russian Rubble", 12) = 33, - SARJ("Setheum Saudi Riyal", 12) = 34, - SEKJ("Setheum Swedish Krona", 12) = 35, - SGDJ("Setheum Singapore Dollar", 12) = 36, - THBJ("Setheum Thai Baht", 12) = 37, - TRYJ("Setheum Turkish Lira", 12) = 38, - TWDJ("Setheum New Taiwan Dollar", 12) = 39, - TZSJ("Setheum Tanzanian Shilling", 12) = 40, - UAHJ("Setheum Ukranian Hryvnia", 12) = 41, - USDJ("Setheum US Dollar", 12) = 42, - JVND("Setheum Vietnamese Dong") = 43, - ZARJ("Setheum South African Rand", 12) = 43, + AUDJ("Setheum Australian Dollar", 12) = 4, + BRLJ("Setheum Brazilian Real", 12) = 5, + CADJ("Setheum Canadian Dollar", 12) = 6, + CHFJ("Setheum Swiss Franc", 12) = 7, + CLPJ("Setheum Chilean Peso", 12) = 8, + CNYJ("Setheum Japanese Yen", 12) = 9, + COPJ("Setheum Colombian Peso", 12) = 10, + EURJ("Setheum Euro", 12) = 11, + GBPJ("Setheum Pound Sterling", 12) = 12, + HKDJ("Setheum HongKong Dollar", 12) = 13, + HUFJ("Setheum Hungarian Forint", 12) = 14, + IDRJ("Setheum Indonesian Rupiah", 12) = 15, + JPYJ("Setheum Japanese Yen", 12) = 16, + KESJ("Setheum Kenyan Shilling", 12) = 17, + KRWJ("Setheum South Korean Won", 12) = 18, + KZTJ("Setheum Kzakhstani Tenge", 12) = 19, + MXNJ("Setheum Mexican Peso", 12) = 20, + MYRJ("Setheum Malaysian Ringgit", 12) = 21, + NGNJ("Setheum Nigerian Naira", 12) = 22, + NOKJ("Setheum Norwegian Krone", 12) = 23, + NZDJ("Setheum New Zealand Dollar ", 12) = 24, + PENJ("Setheum Peruvian Sol", 12) = 25, + PHPJ("Setheum Philippine Peso", 12) = 26, + PKRJ("Setheum Pakistani Rupee", 12) = 27, + PLNJ("Setheum Polish Zloty", 12) = 28, + QARJ("Setheum Qatari Riyal", 12) = 29, + RONJ("Setheum Romanian Leu", 12) = 30, + RUBJ("Setheum Russian Rubble", 12) = 31, + SARJ("Setheum Saudi Riyal", 12) = 32, + SEKJ("Setheum Swedish Krona", 12) = 33, + SGDJ("Setheum Singapore Dollar", 12) = 34, + THBJ("Setheum Thai Baht", 12) = 35, + TRYJ("Setheum Turkish Lira", 12) = 36, + TWDJ("Setheum New Taiwan Dollar", 12) = 37, + TZSJ("Setheum Tanzanian Shilling", 12) = 38, + UAHJ("Setheum Ukranian Hryvnia", 12) = 39, + USDJ("Setheum US Dollar", 12) = 40, + VNDJ("Setheum Vietnamese Dong") = 41, + ZARJ("Setheum South African Rand", 12) = 42, // Foreign System Currencies (Alphabetical Order) - RENBTC("renBTC", 8) = 4, - /// Ends at 85 (42 places left yet reserved) + RENBTC("renBTC", 8) = 43, + /// Ends at 85 (41 places left yet reserved for Setheum Network) /// Neom Network >---------------------->> - /// Starts from 86 (85 places available) + /// Starts from 85 (85 places available) NEOM("Neom", 10) = 86, HALAL("HalalSwap", 10) = 87, NSETT("Neom Setter", 12) = 88, // SettCurrencies (Alphabetical Order) - JAED("Neom UAE Emirati Dirham", 12) = 3, - JAUD("Neom Australian Dollar", 12) = 5, - JBRL("Neom Brazilian Real", 12) = 6, - JCAD("Neom Canadian Dollar", 12) = 7, - JCHF("Neom Swiss Franc", 12) = 8, - JCLP("Neom Chilean Peso", 12) = 9, - JCNY("Neom Japanese Yen", 12) = 10, - JCOP("Neom Colombian Peso", 12) = 11, - JEUR("Neom Euro", 12) =12, - JGBP("Neom Pound Sterling", 12) = 13, - JHKD("Neom HongKong Dollar", 12) = 14, - JHUF("Neom Hungarian Forint", 12) = 15, - JIDR("Neom Indonesian Rupiah", 12) = 16, - JJPY("Neom Japanese Yen", 12) = 18, - JKES("Neom Kenyan Shilling", 12) = 19, - JKRW("Neom South Korean Won", 12) = 20, - JKZT("Neom Kzakhstani Tenge", 12) = 21, - JMXN("Neom Mexican Peso", 12) = 22, - JMYR("Neom Malaysian Ringgit", 12) = 23, - JNGN("Neom Nigerian Naira", 12) = 24, - JNOK("Neom Norwegian Krone", 12) = 25, - JNZD("Neom New Zealand Dollar ", 12) = 26, - JPEN("Neom Peruvian Sol", 12) = 27, - JPHP("Neom Philippine Peso", 12) = 28, - JPKR("Neom Pakistani Rupee", 12) = 29, - JPLN("Neom Polish Zloty", 12) = 30, - JQAR("Neom Qatari Riyal", 12) = 31, - JRON("Neom Romanian Leu", 12) = 32, - JRUB("Neom Russian Rubble", 12) = 33, - JSAR("Neom Saudi Riyal", 12) = 34, - JSEK("Neom Swedish Krona", 12) = 35, - JSGD("Neom Singapore Dollar", 12) = 36, - JTHB("Neom Thai Baht", 12) = 37, - JTRY("Neom Turkish Lira", 12) = 38, - JTWD("Neom New Taiwan Dollar", 12) = 39, - JTZS("Neom Tanzanian Shilling", 12) = 40, - JUAH("Neom Ukranian Hryvnia", 12) = 41, - JUSD("Neom US Dollar", 12) = 42, - JVND("Neom Vietnamese Dong") = 43, - JZAR("Neom South African Rand", 12) = 44, + JAED("Neom UAE Emirati Dirham", 12) = 89, + JAUD("Neom Australian Dollar", 12) = 90, + JBRL("Neom Brazilian Real", 12) = 91, + JCAD("Neom Canadian Dollar", 12) = 92, + JCHF("Neom Swiss Franc", 12) = 93, + JCLP("Neom Chilean Peso", 12) = 94, + JCNY("Neom Japanese Yen", 12) = 95, + JCOP("Neom Colombian Peso", 12) = 96, + JEUR("Neom Euro", 12) =97, + JGBP("Neom Pound Sterling", 12) = 98, + JHKD("Neom HongKong Dollar", 12) = 99, + JHUF("Neom Hungarian Forint", 12) = 100, + JIDR("Neom Indonesian Rupiah", 12) = 101, + JJPY("Neom Japanese Yen", 12) = 102, + JKES("Neom Kenyan Shilling", 12) = 103, + JKRW("Neom South Korean Won", 12) = 104, + JKZT("Neom Kzakhstani Tenge", 12) = 105, + JMXN("Neom Mexican Peso", 12) = 106, + JMYR("Neom Malaysian Ringgit", 12) = 107, + JNGN("Neom Nigerian Naira", 12) = 108, + JNOK("Neom Norwegian Krone", 12) = 109, + JNZD("Neom New Zealand Dollar ", 12) = 110, + JPEN("Neom Peruvian Sol", 12) = 111, + JPHP("Neom Philippine Peso", 12) = 112, + JPKR("Neom Pakistani Rupee", 12) = 113, + JPLN("Neom Polish Zloty", 12) = 114, + JQAR("Neom Qatari Riyal", 12) = 115, + JRON("Neom Romanian Leu", 12) = 116, + JRUB("Neom Russian Rubble", 12) = 117, + JSAR("Neom Saudi Riyal", 12) = 118, + JSEK("Neom Swedish Krona", 12) = 119, + JSGD("Neom Singapore Dollar", 12) = 120, + JTHB("Neom Thai Baht", 12) = 121, + JTRY("Neom Turkish Lira", 12) = 122, + JTWD("Neom New Taiwan Dollar", 12) = 123, + JTZS("Neom Tanzanian Shilling", 12) = 124, + JUAH("Neom Ukranian Hryvnia", 12) = 125, + JUSD("Neom US Dollar", 12) = 126, + JVND("Neom Vietnamese Dong") = 127, + JZAR("Neom South African Rand", 12) = 128, // Foreign System Currencies (Alphabetical Order) - RENBTC("Ren Protocol BTC", 8) = 4, - /// Ends at 170 (42 places left yet reserved) + RENBTC("renBTC", 8) = 4, + /// Ends at 170 (41 places left yet reserved for Neom Network) /// Fiat Currencies as Pegs /// Fiat Currencies - only for price feed (Alphabetical Order) /// Starts from 171 (85 places available) AED("Fiat UAE Emirati Dirham", 12) = 171, - AUD("Fiat Australian Dollar", 12) = 173, - BRL("Fiat Brazilian Real", 12) = 174, - CAD("Fiat Canadian Dollar", 12) = 175, - CHF("Fiat Swiss Franc", 12) = 176, - CLP("Fiat Chilean Peso", 12) = 177, - CNY("Fiat Japanese Yen", 12) = 178, - COP("Fiat Colombian Peso", 12) = 179, - EUR("Fiat Euro", 12) =180, - GBP("Fiat Pound Sterling", 12) = 181, - HKD("Fiat HongKong Dollar", 12) = 182, - HUF("Fiat Hungarian Forint", 12) = 183, - IDR("Fiat Indonesian Rupiah", 12) = 184, - JPY("Fiat Japanese Yen", 12) = 186, - KES("Fiat Kenyan Shilling", 12) = 187, - KRW("Fiat South Korean Won", 12) = 188, - KZT("Fiat Kzakhstani Tenge", 12) = 189, - MXN("Fiat Mexican Peso", 12) = 190, - MYR("Fiat Malaysian Ringgit", 12) = 191, - NGN("Fiat Nigerian Naira", 12) = 192, - NOK("Fiat Norwegian Krone", 12) = 193, - NZD("Fiat New Zealand Dollar ", 12) = 194, - PEN("Fiat Peruvian Sol", 12) = 195, - PHP("Fiat Philippine Peso", 12) = 196, - PKR("Fiat Pakistani Rupee", 12) = 197, - PLN("Fiat Polish Zloty", 12) = 198, - QAR("Fiat Qatari Riyal", 12) = 199, - RON("Fiat Romanian Leu", 12) = 200, - RUB("Fiat Russian Rubble", 12) = 201, - SAR("Fiat Saudi Riyal", 12) = 202, - SEK("Fiat Swedish Krona", 12) = 203, - SGD("Fiat Singapore Dollar", 12) = 204, - THB("Fiat Thai Baht", 12) = 205, - TRY("Fiat Turkish Lira", 12) = 206, - TWD("Fiat New Taiwan Dollar", 12) = 207, - TZS("Fiat Tanzanian Shilling", 12) = 208, - UAH("Fiat Ukranian Hryvnia", 12) = 209, - USD("Fiat US Dollar", 12) = 210, - VND("Fiat Vietnamese Dong") = 211, - ZAR("Fiat South African Rand", 12) = 212, - KWD("Fiat Kuwaiti Dinar", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - JOD("Fiat Jordanian Dinar", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - BHD("Fiat Bahraini Dirham", 12) = 215, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - KYD("Fiat Cayman Islands Dollar", 12) = 216, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - OMR("Fiat Omani Riyal", 12) = 217, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - GIP("Fiat Gibraltar Pound", 12) = 218, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - /// Ends at 255 (38 places left yet reserved). + AUD("Fiat Australian Dollar", 12) = 172, + BRL("Fiat Brazilian Real", 12) = 173, + CAD("Fiat Canadian Dollar", 12) = 174, + CHF("Fiat Swiss Franc", 12) = 175, + CLP("Fiat Chilean Peso", 12) = 176, + CNY("Fiat Japanese Yen", 12) = 177, + COP("Fiat Colombian Peso", 12) = 178, + EUR("Fiat Euro", 12) =179, + GBP("Fiat Pound Sterling", 12) = 180, + HKD("Fiat HongKong Dollar", 12) = 181, + HUF("Fiat Hungarian Forint", 12) = 182, + IDR("Fiat Indonesian Rupiah", 12) = 183, + JPY("Fiat Japanese Yen", 12) = 184, + KES("Fiat Kenyan Shilling", 12) = 185, + KRW("Fiat South Korean Won", 12) = 186, + KZT("Fiat Kzakhstani Tenge", 12) = 187, + MXN("Fiat Mexican Peso", 12) = 188, + MYR("Fiat Malaysian Ringgit", 12) = 189, + NGN("Fiat Nigerian Naira", 12) = 190, + NOK("Fiat Norwegian Krone", 12) = 191, + NZD("Fiat New Zealand Dollar ", 12) = 192, + PEN("Fiat Peruvian Sol", 12) = 193, + PHP("Fiat Philippine Peso", 12) = 194, + PKR("Fiat Pakistani Rupee", 12) = 195, + PLN("Fiat Polish Zloty", 12) = 196, + QAR("Fiat Qatari Riyal", 12) = 197, + RON("Fiat Romanian Leu", 12) = 198, + RUB("Fiat Russian Rubble", 12) = 199, + SAR("Fiat Saudi Riyal", 12) = 200, + SEK("Fiat Swedish Krona", 12) = 201, + SGD("Fiat Singapore Dollar", 12) = 202, + THB("Fiat Thai Baht", 12) = 203, + TRY("Fiat Turkish Lira", 12) = 204, + TWD("Fiat New Taiwan Dollar", 12) = 205, + TZS("Fiat Tanzanian Shilling", 12) = 206, + UAH("Fiat Ukranian Hryvnia", 12) = 207, + USD("Fiat US Dollar", 12) = 208, + VND("Fiat Vietnamese Dong") = 209, + ZAR("Fiat South African Rand", 12) = 210, + KWD("Fiat Kuwaiti Dinar", 12) = 211, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + JOD("Fiat Jordanian Dinar", 12) = 212, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + BHD("Fiat Bahraini Dirham", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + KYD("Fiat Cayman Islands Dollar", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + OMR("Fiat Omani Riyal", 12) = 215, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + GIP("Fiat Gibraltar Pound", 12) = 216, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + /// Ends at 255 (39 places left yet reserved for Fiat-Pegs). + /// + /// A total of 255 (with a total of 121 places left yet reserved) } } From d1b50c05defceca3889de6f374538db74ab28021 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Wed, 23 Jun 2021 15:21:17 +0800 Subject: [PATCH 36/83] Update Auction fixes --- lib-serml/incentives/src/mock.rs | 4 +- lib-serml/serp-auction/src/lib.rs | 38 +++---- lib-serml/serp-auction/src/mock.rs | 110 ++++++++++++++++++-- lib-serml/serp-treasury/src/lib.rs | 9 +- lib-serml/serp-treasury/src/tests.rs | 6 +- lib-serml/setters-manager/src/tests.rs | 2 +- lib-serml/support/src/lib.rs | 4 +- runtime/newrome/src/benchmarking/auction.rs | 4 +- 8 files changed, 135 insertions(+), 42 deletions(-) diff --git a/lib-serml/incentives/src/mock.rs b/lib-serml/incentives/src/mock.rs index 7472deb80..0388450ae 100644 --- a/lib-serml/incentives/src/mock.rs +++ b/lib-serml/incentives/src/mock.rs @@ -202,11 +202,11 @@ impl SerpTreasury for MockSerpTreasury { unimplemented!() } - fn deposit_reserve(_: AccountId, _:Balance) -> DispatchResult { + fn deposit_setter(_: AccountId, _:Balance) -> DispatchResult { unimplemented!() } - fn burn_reserve(_: AccountId, _:Balance) -> DispatchResult { + fn burn_setter(_: AccountId, _:Balance) -> DispatchResult { unimplemented!() } } diff --git a/lib-serml/serp-auction/src/lib.rs b/lib-serml/serp-auction/src/lib.rs index f235f8bc3..e5902b83e 100644 --- a/lib-serml/serp-auction/src/lib.rs +++ b/lib-serml/serp-auction/src/lib.rs @@ -59,9 +59,6 @@ pub struct DiamondAuctionItem { /// Current amount of native currency for sale to buy back Setter stablecoin. #[codec(compact)] amount: Balance, - /// Currency type accepted for the diamond auction. // Always just and only Setter (SETT). - #[codec(compact)] - setter: CurrencyId, /// Fix amount of Setter stablecoin value needed to be got back by this auction. #[codec(compact)] fix: Balance, @@ -416,16 +413,16 @@ impl Pallet { let last_bidder = last_bid.as_ref().map(|(who, _)| who); if let Some(last_bidder) = last_bidder { - // there's bid before, transfer the diamonds (native currency) from new bidder to last bidder + // there's bid before, transfer the setter from new bidder to last bidder T::Currency::transfer( - T::GetNativeCurrencyId::get(), + T::GetSetterCurrencyId::get(), &new_bidder, last_bidder, diamond_auction.fix, )?; } else { - // there's no bid before, transfer diamonds (native currency) to SERP Treasury - T::SerpTreasury::deposit_serplus(&new_bidder, diamond_auction.fix)?; + // there's no bid before, transfer setter to SERP Treasury + T::SerpTreasury::deposit_setter(&new_bidder, diamond_auction.fix)?; } Self::swap_bidders(&new_bidder, last_bidder); @@ -454,7 +451,7 @@ impl Pallet { let mut setter_auction = setter_auction.as_mut().ok_or(Error::::AuctionNonExistent)?; let (new_bidder, new_bid_price) = new_bid; let last_bid_price = last_bid.clone().map_or(Zero::zero(), |(_, price)| price); // get last bid price - let settcurrency_currency_id: CurrencyId; + let currency_id = setter_auction.currency; ensure!( Self::check_minimum_increment( new_bid_price, @@ -465,7 +462,7 @@ impl Pallet { Error::::InvalidBidPrice, ); ensure!( - T::StableCurrencyIds::get().contains(settcurrency_currency_id), + T::StableCurrencyIds::get().contains(currency_id), Error::::InvalidCyrrencyType, ); @@ -474,15 +471,14 @@ impl Pallet { if let Some(last_bidder) = last_bidder { // there's bid before, transfer the stablecoin from new bidder to last bidder T::Currency::transfer( - /// change to `T::StableCurrencyIds::get()` - settcurrency_currency_id, + ¤cy_id, &new_bidder, last_bidder, setter_auction.fix, )?; } else { // there's no bid before, transfer stablecoin to SERP Treasury - T::SerpTreasury::deposit_serplus(&new_bidder, setter_auction.fix)?; + T::SerpTreasury::deposit_serplus(¤cy_id, &new_bidder, setter_auction.fix)?; } Self::swap_bidders(&new_bidder, last_bidder); @@ -526,7 +522,12 @@ impl Pallet { let burn_amount = if let Some(last_bidder) = last_bidder { // refund last bidder - T::Currency::transfer(native_currency_id, &new_bidder, last_bidder, last_bid_price)?; + T::Currency::transfer( + native_currency_id, + &new_bidder, + last_bidder, + last_bid_price + )?; new_bid_price.saturating_sub(last_bid_price) } else { new_bid_price @@ -555,10 +556,8 @@ impl Pallet { Self::deposit_event(Event::DiamondAuctionDealt( auction_id, diamond_auction.amount, - currency_id, bidder, diamond_auction.fix, - diamond_auction.setter, )); } else { Self::deposit_event(Event::CancelAuction(auction_id)); @@ -578,12 +577,9 @@ impl Pallet { // by treasury council. TODO: transfer from RESERVED TREASURY instead of issuing let _ = T::SerpTreasury::issue_setter(&bidder, setter_auction.amount); - let currency_id = T::GetSetterCurrencyId::get() - Self::deposit_event(Event::SetterAuctionDealt( auction_id, setter_auction.amount, - currency_id, bidder, setter_auction.fix, setter_auction.currency, @@ -645,6 +641,7 @@ impl AuctionHandler fn on_new_bid( now: T::BlockNumber, id: AuctionId, + currency_id: CurrencyId, new_bid: (T::AccountId, Balance), last_bid: Option<(T::AccountId, Balance)>, ) -> OnNewBidResult { @@ -709,8 +706,6 @@ impl SerpAuctionManager for Pallet { let diamond = T::GetNativeCurrencyId::get(); - // set setter currency_id accepted for diamond auction (Only Setter is accepted (SETT)) - let setter_currency_id = T::GetSetterCurrencyId::get(); >::insert( auction_id, DiamondAuctionItem { @@ -718,12 +713,11 @@ impl SerpAuctionManager for Pallet { diamond: diamond, amount: initial_amount, fix: fix_setter, - setter: setter_currency_id, start_time, }, ); - Self::deposit_event(Event::NewDiamondAuction(auction_id, initial_amount, diamond, fix_setter, setter_currency_id)); + Self::deposit_event(Event::NewDiamondAuction(auction_id, initial_amount, diamond, fix_setter)); Ok(()) } diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index 764d981fc..b938fbd43 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -42,11 +42,50 @@ pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; pub const CAROL: AccountId = 3; +// Currencies constants - CurrencyId/TokenSymbol pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); +pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); +pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); +pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); +pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); +pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); +pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); +pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); +pub const CLPJ: CurrencyId = CurrencyId::Token(TokenSymbol::CLPJ); +pub const CNYJ: CurrencyId = CurrencyId::Token(TokenSymbol::CNYJ); +pub const COPJ: CurrencyId = CurrencyId::Token(TokenSymbol::COPJ); pub const EURJ: CurrencyId = CurrencyId::Token(TokenSymbol::EURJ); +pub const GBPJ: CurrencyId = CurrencyId::Token(TokenSymbol::GBPJ); +pub const HKDJ: CurrencyId = CurrencyId::Token(TokenSymbol::HKDJ); +pub const HUFJ: CurrencyId = CurrencyId::Token(TokenSymbol::HUFJ); +pub const IDRJ: CurrencyId = CurrencyId::Token(TokenSymbol::IDRJ); +pub const JPYJ: CurrencyId = CurrencyId::Token(TokenSymbol::JPYJ); +pub const KESJ: CurrencyId = CurrencyId::Token(TokenSymbol::KESJ); +pub const KRWJ: CurrencyId = CurrencyId::Token(TokenSymbol::KRWJ); +pub const KZTJ: CurrencyId = CurrencyId::Token(TokenSymbol::KZTJ); +pub const MXNJ: CurrencyId = CurrencyId::Token(TokenSymbol::MXNJ); +pub const MYRJ: CurrencyId = CurrencyId::Token(TokenSymbol::MYRJ); +pub const NGNJ: CurrencyId = CurrencyId::Token(TokenSymbol::NGNJ); +pub const NOKJ: CurrencyId = CurrencyId::Token(TokenSymbol::NOKJ); +pub const NZDJ: CurrencyId = CurrencyId::Token(TokenSymbol::NZDJ); +pub const PENJ: CurrencyId = CurrencyId::Token(TokenSymbol::PENJ); +pub const PHPJ: CurrencyId = CurrencyId::Token(TokenSymbol::PHPJ); +pub const PKRJ: CurrencyId = CurrencyId::Token(TokenSymbol::PKRJ); +pub const PLNJ: CurrencyId = CurrencyId::Token(TokenSymbol::PLNJ); +pub const QARJ: CurrencyId = CurrencyId::Token(TokenSymbol::QARJ); +pub const RONJ: CurrencyId = CurrencyId::Token(TokenSymbol::RONJ); +pub const RUBJ: CurrencyId = CurrencyId::Token(TokenSymbol::RUBJ); +pub const SARJ: CurrencyId = CurrencyId::Token(TokenSymbol::SARJ); +pub const SEKJ: CurrencyId = CurrencyId::Token(TokenSymbol::SEKJ); +pub const SGDJ: CurrencyId = CurrencyId::Token(TokenSymbol::SGDJ); +pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); +pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); +pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); +pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); +pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); -pub const CHFJ: CurrencyId = CurrencyId::Token(TokenSymbol::CHFJ); +pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); mod serp_auction { pub use super::super::*; @@ -111,17 +150,72 @@ ord_parameter_types! { } parameter_types! { - pub StableCurrencyIds: Vec = vec![USDJ, EURJ]; - pub const GetStableCurrencyId: CurrencyId = USDJ; - pub const MaxAuctionsCount: u32 = 10_000; + pub StableCurrencyIds: Vec = vec![ + SETT, + AEDJ, + ARSJ, + AUDJ, + BRLJ, + CADJ, + CHFJ, + CLPJ, + CNYJ, + COPJ, + EURJ, + GBPJ, + HKDJ, + HUFJ, + IDRJ, + JPYJ, + KESJ, + KRWJ, + KZTJ, + MXNJ, + MYRJ, + NGNJ, + NOKJ, + NZDJ, + PENJ, + PHPJ, + PKRJ, + PLNJ, + QARJ, + RONJ, + RUBJ, + SARJ, + SEKJ, + SGDJ, + THBJ, + TRYJ, + TWDJ, + TZSJ, + UAHJ, + USDJ, + ZARJ, + ]; + pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT + pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks + pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. + pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. + pub SetheumTreasurySerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to network Treasury. + pub CharityFundSerpupRatio: Permill = Permill::from_percent(20); // 20% of SerpUp to Setheum Foundation's Charity Fund. } impl serp_treasury::Config for Runtime { type Event = Event; - type Currency = Tokens; - type GetStableCurrencyId = GetStableCurrencyId; - type SerpAuctionManagerHandler = SerpAuctionManagerModule; + type Currency = Currencies; + type StableCurrencyIds = StableCurrencyIds; + type GetSetterCurrencyId = GetSetterCurrencyId; + type GetDexerCurrencyId = GetDexerCurrencyId; + type SerpTesSchedule = SerpTesSchedule; + type SerplusSerpupRatio = SerplusSerpupRatio; + type SettPaySerpupRatio = SettPaySerpupRatio; + type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; + type CharityFundSerpupRatio = CharityFundSerpupRatio; + type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; type Dex = DexModule; type MaxAuctionsCount = MaxAuctionsCount; @@ -177,6 +271,8 @@ parameter_types! { pub SerplusAuctionMinimumIncrementSize: Rate = Rate::saturating_from_rational(1, 100); // 1% increment pub const AuctionTimeToClose: u64 = 100; pub const AuctionDurationSoftCap: u64 = 2000; + pub const MaxAuctionsCount: u32 = 10_000; + pub const GetNativeCurrencyId: CurrencyId = DNAR; pub const GetSetterCurrencyId: CurrencyId = SETT; } diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index d63ca1e4f..7dcee097a 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -465,16 +465,19 @@ impl SerpTreasury for Pallet { T::Currency::withdraw(T::GetDexerCurrencyId::get(), who, dexer) } + /// deposit surplus(propperstable currency) to serp treasury by `from` fn deposit_serplus(currency_id: CurrencyId, from: &T::AccountId, serplus: Self::Balance) -> DispatchResult { T::Currency::transfer(currency_id, from, &Self::account_id(), serplus) } - fn deposit_reserve(from: &T::AccountId, amount: Self::Balance) -> DispatchResult { + /// deposit reserve asset (Setter (SETT)) to serp treasury by `who` + fn deposit_setter(from: &T::AccountId, amount: Self::Balance) -> DispatchResult { T::Currency::transfer(T::GetSetterCurrencyId::get(), from, &Self::account_id(), amount) } - fn burn_reserve(to: &T::AccountId, amount: Self::Balance) -> DispatchResult { - T::Currency::transfer(T::GetSetterCurrencyId::get(), &Self::account_id(), to, amount) + /// Burn Reserve asset (Setter (SETT)) + fn burn_setter(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + T::Currency::withdraw(T::GetSetterCurrencyId::get(), who, amount) } } diff --git a/lib-serml/serp-treasury/src/tests.rs b/lib-serml/serp-treasury/src/tests.rs index 1abf9f694..342f1f716 100644 --- a/lib-serml/serp-treasury/src/tests.rs +++ b/lib-serml/serp-treasury/src/tests.rs @@ -88,13 +88,13 @@ fn deposit_serplus_works() { } #[test] -fn deposit_reserve_works() { +fn deposit_setter_works() { ExtBuilder::default().build().execute_with(|| { assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); assert_eq!(Currencies::free_balance(BTC, &SerpTreasuryModule::account_id()), 0); assert_eq!(Currencies::free_balance(BTC, &ALICE), 1000); - assert_eq!(SerpTreasuryModule::deposit_reserve(&ALICE, BTC, 10000).is_ok(), false); - assert_ok!(SerpTreasuryModule::deposit_reserve(&ALICE, BTC, 500)); + assert_eq!(SerpTreasuryModule::deposit_setter(&ALICE, BTC, 10000).is_ok(), false); + assert_ok!(SerpTreasuryModule::deposit_setter(&ALICE, BTC, 500)); assert_eq!(SerpTreasuryModule::total_reserve(BTC), 500); assert_eq!(Currencies::free_balance(BTC, &SerpTreasuryModule::account_id()), 500); assert_eq!(Currencies::free_balance(BTC, &ALICE), 500); diff --git a/lib-serml/setters-manager/src/tests.rs b/lib-serml/setters-manager/src/tests.rs index 6f5b94f3c..0e91eb4f7 100644 --- a/lib-serml/setters-manager/src/tests.rs +++ b/lib-serml/setters-manager/src/tests.rs @@ -161,7 +161,7 @@ fn total_reserve_works() { #[test] fn get_total_reserve_works() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettersManagerModule::deposit_reserve(&ALICE, 500)); + assert_ok!(SettersManagerModule::deposit_setter(&ALICE, 500)); assert_eq!(SettersManagerModule::get_total_reserve(500); }); } diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index 9e2f9bbc1..c2c3548b1 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -213,10 +213,10 @@ pub trait SerpTreasury { fn deposit_surplus(currency_id: Self::CurrencyId, from: &AccountId, surplus: Self::Balance) -> DispatchResult; /// deposit reserve asset (Setter (SETT)) to serp treasury by `who` - fn deposit_reserve(from: &AccountId, amount: Self::Balance) -> DispatchResult; + fn deposit_setter(from: &AccountId, amount: Self::Balance) -> DispatchResult; /// Burn Reserve asset (Setter (SETT)) - fn burn_reserve(to: &AccountId, amount: Self::Balance) -> DispatchResult; + fn burn_setter(who, amount: Self::Balance) -> DispatchResult; } pub trait SerpTreasuryExtended: SerpTreasury { diff --git a/runtime/newrome/src/benchmarking/auction.rs b/runtime/newrome/src/benchmarking/auction.rs index 9f219cad0..d0b2eb6a5 100644 --- a/runtime/newrome/src/benchmarking/auction.rs +++ b/runtime/newrome/src/benchmarking/auction.rs @@ -54,7 +54,7 @@ runtime_benchmarks! { set_balance(currency_id, &funder, reserve_amount); set_balance(rUSD, &bidder, bid_price); - >::deposit_reserve(&funder, currency_id, reserve_amount)?; + >::deposit_setter(&funder, currency_id, reserve_amount)?; SerpAuctionManager::new_setter_auction(&funder, currency_id, reserve_amount, target_amount)?; }: bid(RawOrigin::Signed(bidder), auction_id, bid_price) @@ -74,7 +74,7 @@ runtime_benchmarks! { set_balance(currency_id, &funder, reserve_amount); set_balance(rUSD, &bidder, bid_price); set_balance(rUSD, &previous_bidder, previous_bid_price); - >::deposit_reserve(&funder, currency_id, reserve_amount)?; + >::deposit_setter(&funder, currency_id, reserve_amount)?; SerpAuctionManager::new_setter_auction(&funder, currency_id, reserve_amount, target_amount)?; Auction::bid(RawOrigin::Signed(previous_bidder).into(), auction_id, previous_bid_price)?; }: bid(RawOrigin::Signed(bidder), auction_id, bid_price) From 661ad16d0705b04a665976aa790c4c16fb0daa1c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 02:33:23 +0800 Subject: [PATCH 37/83] fix serplus auctions and tests --- lib-serml/serp-auction/src/lib.rs | 21 ++- lib-serml/serp-auction/src/tests.rs | 221 ++++++---------------------- 2 files changed, 61 insertions(+), 181 deletions(-) diff --git a/lib-serml/serp-auction/src/lib.rs b/lib-serml/serp-auction/src/lib.rs index e5902b83e..0507fdc45 100644 --- a/lib-serml/serp-auction/src/lib.rs +++ b/lib-serml/serp-auction/src/lib.rs @@ -117,12 +117,12 @@ impl SetterAuctionItem { #[cfg_attr(feature = "std", derive(PartialEq, Eq))] #[derive(Encode, Decode, Clone, RuntimeDebug)] pub struct SerplusAuctionItem { - /// Currency type auctioned in the serplus auction. - /// Always just and only SettCurrencies/stablecoins. - currency: CurrencyId, /// Fixed amount of serplus [serplus](stable currency) for sale to get back native currency. #[codec(compact)] amount: Balance, + /// Currency type auctioned in the serplus auction. + /// Always just and only SettCurrencies/stablecoins. + currency: CurrencyId, /// Auction start time start_time: BlockNumber, } @@ -641,7 +641,6 @@ impl AuctionHandler fn on_new_bid( now: T::BlockNumber, id: AuctionId, - currency_id: CurrencyId, new_bid: (T::AccountId, Balance), last_bid: Option<(T::AccountId, Balance)>, ) -> OnNewBidResult { @@ -760,13 +759,13 @@ impl SerpAuctionManager for Pallet { return Err(Error::::CurrencyNotAccepted.into()); } - Self::deposit_event(Event::NewSetterAuction(auction_id, initial_amount, setter, fix_settcurrency, settcurrency_id)); + Self::deposit_event(Event::NewSetterAuction(auction_id, initial_amount, fix_settcurrency, settcurrency_id)); Ok(()) } fn new_serplus_auction(amount: Self::Balance, currency_id: Self::CurrencyId) -> DispatchResult { ensure!(!amount.is_zero(), Error::::InvalidAmount,); - // ensure currency_id is accepted for serplus auction (Only SettCurrencies are accepted (SETT)) + // ensure currency_id can be auctioned for serplus auction (Only SettCurrencies (stablecoins)) ensure!( T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, @@ -779,8 +778,14 @@ impl SerpAuctionManager for Pallet { let start_time = >::block_number(); // do not set end time for serplus auction let auction_id = T::Auction::new_auction(start_time, None)?; - >::insert(auction_id, SerplusAuctionItem {amount, currency_id, start_time}); - + >::insert( + auction_id, + SerplusAuctionItem { + amount, + currency_id, + start_time + } + ); Self::deposit_event(Event::NewSerplusAuction(auction_id, amount, currency_id)); Ok(()) } diff --git a/lib-serml/serp-auction/src/tests.rs b/lib-serml/serp-auction/src/tests.rs index c9dca1634..78bf1afa7 100644 --- a/lib-serml/serp-auction/src/tests.rs +++ b/lib-serml/serp-auction/src/tests.rs @@ -25,7 +25,7 @@ use frame_support::{assert_noop, assert_ok}; use mock::{Event, *}; #[test] -fn get_auction_time_to_close_work() { +fn get_auction_time_to_close_works() { ExtBuilder::default().build().execute_with(|| { assert_eq!(SerpAuctionManagerModule::get_auction_time_to_close(2000, 1), 100); assert_eq!(SerpAuctionManagerModule::get_auction_time_to_close(2001, 1), 50); @@ -35,26 +35,11 @@ fn get_auction_time_to_close_work() { #[test] fn setter_auction_methods() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 100)); - let setter_auction_with_positive_target = SerpAuctionManagerModule::setter_auctions(0).unwrap(); - assert_eq!(setter_auction_with_positive_target.always_forward(), false); - assert_eq!(setter_auction_with_positive_target.in_reverse_stage(99), false); - assert_eq!(setter_auction_with_positive_target.in_reverse_stage(100), true); - assert_eq!(setter_auction_with_positive_target.in_reverse_stage(101), true); - assert_eq!(setter_auction_with_positive_target.payment_amount(99), 99); - assert_eq!(setter_auction_with_positive_target.payment_amount(100), 100); - assert_eq!(setter_auction_with_positive_target.payment_amount(101), 100); - assert_eq!(setter_auction_with_positive_target.reserve_amount(80, 100), 10); - assert_eq!(setter_auction_with_positive_target.reserve_amount(100, 200), 5); - - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 0)); - let setter_auction_with_zero_target = SerpAuctionManagerModule::setter_auctions(1).unwrap(); - assert_eq!(setter_auction_with_zero_target.always_forward(), true); - assert_eq!(setter_auction_with_zero_target.in_reverse_stage(0), false); - assert_eq!(setter_auction_with_zero_target.in_reverse_stage(100), false); - assert_eq!(setter_auction_with_zero_target.payment_amount(99), 99); - assert_eq!(setter_auction_with_zero_target.payment_amount(101), 101); - assert_eq!(setter_auction_with_zero_target.reserve_amount(100, 200), 10); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(200, 100, USDJ)); + let setter_auction = SerpAuctionManagerModule::setter_auctions(0).unwrap(); + assert_eq!(setter_auction.amount_for_sale(0, 100), 200); + assert_eq!(setter_auction.amount_for_sale(100, 200), 100); + assert_eq!(setter_auction.amount_for_sale(200, 1000), 40); }); } @@ -70,25 +55,26 @@ fn diamond_auction_methods() { } #[test] -fn new_setter_auction_work() { +fn new_setter_auction_works() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - let ref_count_0 = System::consumers(&ALICE); assert_noop!( - SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 0, 100), + SerpAuctionManagerModule::new_setter_auction(0, 100, USDJ), + Error::::InvalidAmount, + ); + assert_noop!( + SerpAuctionManagerModule::new_setter_auction(200, 0, USDJ), Error::::InvalidAmount, ); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 100)); - System::assert_last_event(Event::serp_auction(crate::Event::NewSetterAuction(0, CHFJ, 10, 100))); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(200, 100, USDJ)); + System::assert_last_event(Event::serp_auction(crate::Event::NewSetterAuction(0, 200, 100))); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 10); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 100); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); assert_eq!(AuctionModule::auctions_index(), 1); - assert_eq!(System::consumers(&ALICE), ref_count_0 + 1); assert_noop!( - SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, Balance::max_value(), Balance::max_value()), + SerpAuctionManagerModule::new_setter_auction(200, Balance::max_value(), USDJ), Error::::InvalidAmount, ); }); @@ -125,18 +111,18 @@ fn new_serplus_auction_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_noop!( - SerpAuctionManagerModule::new_serplus_auction(0), + SerpAuctionManagerModule::new_serplus_auction(0, USDJ), Error::::InvalidAmount, ); - assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); - System::assert_last_event(Event::serp_auction(crate::Event::NewSerplusAuction(0, 100))); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100, USDJ)); + System::assert_last_event(Event::serp_auction(crate::Event::NewSerplusAuction(0, 100, USDJ))); assert_eq!(SerpAuctionManagerModule::total_diamond_in_auction(), 100); assert_eq!(AuctionModule::auctions_index(), 1); assert_noop!( - SerpAuctionManagerModule::new_serplus_auction(Balance::max_value()), + SerpAuctionManagerModule::new_serplus_auction(Balance::max_value(), USDJ), Error::::InvalidAmount, ); }); @@ -146,11 +132,11 @@ fn new_serplus_auction_work() { fn setter_auction_bid_handler_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 99), None), - Error::::AuctionNotExists, + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, USDJ, (BOB, 99), None), + Error::::AuctionNonExistent, ); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(200, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(200, 100, USDJ)); assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); assert_eq!(SerpAuctionManagerModule::setter_auctions(0).unwrap().amount, 200); assert_eq!(SerpTreasuryModule::serplus_pool(), 0); @@ -159,11 +145,11 @@ fn setter_auction_bid_handler_work() { let bob_ref_count_0 = System::consumers(&BOB); assert_noop!( - SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 99), None), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, USDJ, (BOB, 99), None), Error::::InvalidBidPrice, ); assert_eq!( - SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, USDJ, (BOB, 100), None).is_ok(), true ); assert_eq!(SerpAuctionManagerModule::setter_auctions(0).unwrap().amount, 200); @@ -175,7 +161,7 @@ fn setter_auction_bid_handler_work() { let carol_ref_count_0 = System::consumers(&CAROL); assert_eq!( - SerpAuctionManagerModule::setter_auction_bid_handler(2, 0, (CAROL, 200), Some((BOB, 100))).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(2, 0, USDJ, (CAROL, 200), Some((BOB, 100))).is_ok(), true ); assert_eq!(SerpAuctionManagerModule::setter_auctions(0).unwrap().amount, 100); @@ -194,7 +180,7 @@ fn diamond_auction_bid_handler_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( SerpAuctionManagerModule::diamond_auction_bid_handler(1, 0, (BOB, 99), None), - Error::::AuctionNotExists, + Error::::AuctionNonExistent, ); assert_ok!(SerpAuctionManagerModule::new_diamond_auction(200, 100)); @@ -241,10 +227,10 @@ fn serplus_auction_bid_handler_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( SerpAuctionManagerModule::serplus_auction_bid_handler(1, 0, (BOB, 99), None), - Error::::AuctionNotExists, + Error::::AuctionNonExistent, ); - assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100, USDJ)); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1000); let bob_ref_count_0 = System::consumers(&BOB); @@ -280,17 +266,17 @@ fn serplus_auction_bid_handler_work() { #[test] fn bid_when_soft_cap_for_setter_auction_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 10, 100)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(200, 100, USDJ)); assert_eq!( SerpAuctionManagerModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, Change::NewValue(Some(101)) ); assert_eq!( - SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 10), Some((BOB, 5))).accept_bid, - false, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 105), Some((BOB, 100))).accept_bid, + false ); assert_eq!( - SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 15), Some((BOB, 5))).auction_end_change, + SerpAuctionManagerModule::on_new_bid(2001, 0, (CAROL, 110), Some((BOB, 100))).auction_end_change, Change::NewValue(Some(2051)) ); }); @@ -318,7 +304,7 @@ fn bid_when_soft_cap_for_diamond_auction_work() { #[test] fn bid_when_soft_cap_for_serplus_auction_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100, USDJ)); assert_eq!( SerpAuctionManagerModule::on_new_bid(1, 0, (BOB, 100), None).auction_end_change, Change::NewValue(Some(101)) @@ -338,153 +324,42 @@ fn bid_when_soft_cap_for_serplus_auction_work() { fn setter_auction_end_handler_without_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 100); - let alice_ref_count_0 = System::consumers(&ALICE); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(300, 100, USDJ)); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); SerpAuctionManagerModule::on_auction_ended(0, None); System::assert_last_event(Event::serp_auction(crate::Event::CancelAuction(0))); - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); - assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); - let alice_ref_count_1 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_1, alice_ref_count_0 - 1); - }); -} - -#[test] -fn setter_auction_end_handler_in_reverse_stage() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); - assert_eq!( - SerpAuctionManagerModule::setter_auction_bid_handler(2, 0, (BOB, 400), None).is_ok(), - true - ); - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 50); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 50); - assert_eq!(Tokens::free_balance(CHFJ, &ALICE), 1050); - assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); - assert_eq!(Tokens::free_balance(USDJ, &BOB), 800); - assert_eq!(SerpTreasuryModule::serplus_pool(), 200); - - let alice_ref_count_0 = System::consumers(&ALICE); - let bob_ref_count_0 = System::consumers(&BOB); - - assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); - SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 400))); - System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, CHFJ, 50, BOB, 200))); - - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 0); assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); - assert_eq!(Tokens::free_balance(CHFJ, &ALICE), 1050); - assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1050); - assert_eq!(Tokens::free_balance(USDJ, &BOB), 800); - assert_eq!(SerpTreasuryModule::serplus_pool(), 200); - - let alice_ref_count_1 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_1, alice_ref_count_0 - 1); - let bob_ref_count_1 = System::consumers(&BOB); - assert_eq!(bob_ref_count_1, bob_ref_count_0 - 1); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 0); }); } #[test] -fn setter_auction_end_handler_by_dealing_which_target_not_zero() { +fn setter_auction_end_handler_with_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); + assert_ok!(SerpAuctionManagerModule::new_setter_auction(300, 100, USDJ)); assert_eq!( - SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 100), None).is_ok(), + SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, USDJ, (BOB, 100), None).is_ok(), true ); - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 100); - assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 100); assert_eq!(Tokens::free_balance(USDJ, &BOB), 900); - assert_eq!(SerpTreasuryModule::serplus_pool(), 100); + assert_eq!(Tokens::free_balance(SETT, &BOB), 1000); - let alice_ref_count_0 = System::consumers(&ALICE); let bob_ref_count_0 = System::consumers(&BOB); assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 100))); - System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, CHFJ, 100, BOB, 100))); + System::assert_last_event(Event::serp_auction(crate::Event::SetterAuctionDealt(0, 300, BOB, 100))); - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 0); + assert_eq!(Tokens::free_balance(SETT, &BOB), 1300); + assert_eq!(Tokens::total_issuance(SETT), 3300); assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1100); - - let alice_ref_count_1 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_1, alice_ref_count_0 - 1); - let bob_ref_count_1 = System::consumers(&BOB); - assert_eq!(bob_ref_count_1, bob_ref_count_0 - 1); - }); -} - -#[test] -fn setter_auction_end_handler_by_dex_which_target_not_zero() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(SerpTreasuryModule::deposit_reserve(&CAROL, CHFJ, 100)); - assert_ok!(SerpAuctionManagerModule::new_setter_auction(&ALICE, CHFJ, 100, 200)); - assert_eq!( - SerpAuctionManagerModule::setter_auction_bid_handler(1, 0, (BOB, 20), None).is_ok(), - true - ); - assert_ok!(DexModule::add_liquidity( - Origin::signed(CAROL), - CHFJ, - USDJ, - 100, - 1000, - false - )); - assert_eq!(DexModule::get_swap_target_amount(&[CHFJ, USDJ], 100, None).unwrap(), 500); - - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 100); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 200); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 100); - assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); - assert_eq!(Tokens::free_balance(USDJ, &BOB), 980); - assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1000); - assert_eq!(SerpTreasuryModule::serplus_pool(), 20); - - let alice_ref_count_0 = System::consumers(&ALICE); - let bob_ref_count_0 = System::consumers(&BOB); - - assert_eq!(SerpAuctionManagerModule::setter_auctions(0).is_some(), true); - SerpAuctionManagerModule::on_auction_ended(0, Some((BOB, 20))); - let dex_take_setter_auction = - Event::serp_auction(crate::Event::DEXTakeSetterAuction(0, CHFJ, 100, 500)); - assert!(System::events() - .iter() - .any(|record| record.event == dex_take_setter_auction)); - - assert_eq!(SerpTreasuryModule::total_reserve(CHFJ), 0); - assert_eq!(SerpAuctionManagerModule::setter_auctions(0), None); - assert_eq!(SerpAuctionManagerModule::total_target_in_auction(), 0); - assert_eq!(SerpAuctionManagerModule::total_reserve_in_auction(CHFJ), 0); - assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1000); - assert_eq!(Tokens::free_balance(USDJ, &BOB), 1000); - assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1300); - assert_eq!(SerpTreasuryModule::serplus_pool(), 520); + assert_eq!(SerpAuctionManagerModule::total_standard_in_auction(), 0); - let alice_ref_count_1 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_1, alice_ref_count_0 - 1); let bob_ref_count_1 = System::consumers(&BOB); assert_eq!(bob_ref_count_1, bob_ref_count_0 - 1); }); @@ -539,7 +414,7 @@ fn diamond_auction_end_handler_with_bid() { fn serplus_auction_end_handler_without_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100, USDJ)); assert_eq!(SerpAuctionManagerModule::total_diamond_in_auction(), 100); assert_eq!(SerpAuctionManagerModule::serplus_auctions(0).is_some(), true); @@ -556,7 +431,7 @@ fn serplus_auction_end_handler_with_bid() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(SerpTreasuryModule::on_system_serpup(100)); - assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100)); + assert_ok!(SerpAuctionManagerModule::new_serplus_auction(100, USDJ)); assert_eq!( SerpAuctionManagerModule::serplus_auction_bid_handler(1, 0, (BOB, 500), None).is_ok(), true From 90297d28d0425a152d936407112101fecaf53d47 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 02:45:43 +0800 Subject: [PATCH 38/83] Support Setheum EVM traits --- lib-serml/support/src/lib.rs | 204 +++++++++++++++++++++++++++++++++ lib-serml/support/src/mocks.rs | 0 2 files changed, 204 insertions(+) create mode 100644 lib-serml/support/src/mocks.rs diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index c2c3548b1..09f1ef0af 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -277,6 +277,111 @@ impl DEXIncentives bool; +} + +/// An abstraction of EVM for EVMBridge +pub trait EVM { + type Balance: AtLeast32BitUnsigned + Copy + MaybeSerializeDeserialize + Default; + + fn execute( + context: InvokeContext, + input: Vec, + value: Self::Balance, + gas_limit: u64, + storage_limit: u32, + mode: ExecutionMode, + ) -> Result; + + /// Get the real origin account and charge storage rent from the origin. + fn get_origin() -> Option; + /// Provide a method to set origin for `on_initialize` + fn set_origin(origin: AccountId); +} + +#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug)] +pub enum ExecutionMode { + Execute, + /// Discard any state changes + View, + /// Also discard any state changes and use estimate gas mode for evm config + EstimateGas, +} + +#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug)] +pub struct InvokeContext { + pub contract: EvmAddress, + /// similar to msg.sender + pub sender: EvmAddress, + /// similar to tx.origin + pub origin: EvmAddress, +} + +/// An abstraction of EVMBridge +pub trait EVMBridge { + /// Execute ERC20.name() to read token name from ERC20 contract + fn name(context: InvokeContext) -> Result, DispatchError>; + /// Execute ERC20.symbol() to read token symbol from ERC20 contract + fn symbol(context: InvokeContext) -> Result, DispatchError>; + /// Execute ERC20.decimals() to read token decimals from ERC20 contract + fn decimals(context: InvokeContext) -> Result; + /// Execute ERC20.totalSupply() to read total supply from ERC20 contract + fn total_supply(context: InvokeContext) -> Result; + /// Execute ERC20.balanceOf(address) to read balance of address from ERC20 + /// contract + fn balance_of(context: InvokeContext, address: EvmAddress) -> Result; + /// Execute ERC20.transfer(address, uint256) to transfer value to `to` + fn transfer(context: InvokeContext, to: EvmAddress, value: Balance) -> DispatchResult; + /// Get the real origin account and charge storage rent from the origin. + fn get_origin() -> Option; + /// Provide a method to set origin for `on_initialize` + fn set_origin(origin: AccountId); +} + +#[cfg(feature = "std")] +impl EVMBridge for () { + fn name(_context: InvokeContext) -> Result, DispatchError> { + Err(DispatchError::Other("unimplemented evm bridge")) + } + fn symbol(_context: InvokeContext) -> Result, DispatchError> { + Err(DispatchError::Other("unimplemented evm bridge")) + } + fn decimals(_context: InvokeContext) -> Result { + Err(DispatchError::Other("unimplemented evm bridge")) + } + fn total_supply(_context: InvokeContext) -> Result { + Err(DispatchError::Other("unimplemented evm bridge")) + } + fn balance_of(_context: InvokeContext, _address: EvmAddress) -> Result { + Err(DispatchError::Other("unimplemented evm bridge")) + } + fn transfer(_context: InvokeContext, _to: EvmAddress, _value: Balance) -> DispatchResult { + Err(DispatchError::Other("unimplemented evm bridge")) + } + fn get_origin() -> Option { + None + } + fn set_origin(_origin: AccountId) {} +} + +/// An abstraction of EVMStateRentTrait +pub trait EVMStateRentTrait { + /// Query the constants `NewContractExtraBytes` value from evm module. + fn query_new_contract_extra_bytes() -> u32; + /// Query the constants `StorageDepositPerByte` value from evm module. + fn query_storage_deposit_per_byte() -> Balance; + /// Query the maintainer address from the ERC20 contract. + fn query_maintainer(contract: H160) -> Result; + /// Query the constants `DeveloperDeposit` value from evm module. + fn query_developer_deposit() -> Balance; + /// Query the constants `DeploymentFee` value from evm module. + fn query_deployment_fee() -> Balance; + /// Transfer the maintainer of the contract address. + fn transfer_maintainer(from: AccountId, contract: H160, new_maintainer: H160) -> DispatchResult; +} + pub trait TransactionPayment { fn reserve_fee(who: &AccountId, weight: Weight) -> Result; fn unreserve_fee(who: &AccountId, fee: Balance); @@ -295,6 +400,25 @@ pub trait TransactionPayment { ) -> Result<(), TransactionValidityError>; } +// TODO: Use this logic for SettPayCashDrop +// pub trait TransactionPayment { +// fn reserve_fee(who: &AccountId, weight: Weight) -> Result; +// fn unreserve_fee(who: &AccountId, fee: Balance); +// fn unreserve_and_charge_fee( +// who: &AccountId, +// weight: Weight, +// ) -> Result<(Balance, NegativeImbalance), TransactionValidityError>; +// fn refund_fee(who: &AccountId, weight: Weight, payed: NegativeImbalance) -> Result<(), TransactionValidityError>; +// fn charge_fee( +// who: &AccountId, +// len: u32, +// weight: Weight, +// tip: Balance, +// pays_fee: Pays, +// class: DispatchClass, +// ) -> Result<(), TransactionValidityError>; +// } + #[cfg(feature = "std")] use frame_support::traits::Imbalance; #[cfg(feature = "std")] @@ -337,3 +461,83 @@ impl> pub trait Contains { fn contains(t: &T) -> bool; } + +/// A mapping between `AccountId` and `EvmAddress`. +pub trait AddressMapping { + /// Returns the AccountId used go generate the given EvmAddress. + fn get_account_id(evm: &EvmAddress) -> AccountId; + /// Returns the EvmAddress associated with a given AccountId or the + /// underlying EvmAddress of the AccountId. + /// Returns None if there is no EvmAddress associated with the AccountId + /// and there is no underlying EvmAddress in the AccountId. + fn get_evm_address(account_id: &AccountId) -> Option; + /// Returns the EVM address associated with an account ID and generates an + /// account mapping if no association exists. + fn get_or_create_evm_address(account_id: &AccountId) -> EvmAddress; + /// Returns the default EVM address associated with an account ID. + fn get_default_evm_address(account_id: &AccountId) -> EvmAddress; + /// Returns true if a given AccountId is associated with a given EvmAddress + /// and false if is not. + fn is_linked(account_id: &AccountId, evm: &EvmAddress) -> bool; +} + +/// A mapping between u32 and Erc20 address. +/// provide a way to encode/decode for CurrencyId; +pub trait CurrencyIdMapping { + /// Use first 4 non-zero bytes as u32 to the mapping between u32 and evm + /// address. + fn set_erc20_mapping(address: EvmAddress) -> DispatchResult; + /// Returns the EvmAddress associated with a given u32. + fn get_evm_address(currency_id: u32) -> Option; + /// Returns the name associated with a given CurrencyId. + /// If CurrencyId is CurrencyId::DexShare and contain DexShare::Erc20, + /// the EvmAddress must have been mapped. + fn name(currency_id: CurrencyId) -> Option>; + /// Returns the symbol associated with a given CurrencyId. + /// If CurrencyId is CurrencyId::DexShare and contain DexShare::Erc20, + /// the EvmAddress must have been mapped. + fn symbol(currency_id: CurrencyId) -> Option>; + /// Returns the decimals associated with a given CurrencyId. + /// If CurrencyId is CurrencyId::DexShare and contain DexShare::Erc20, + /// the EvmAddress must have been mapped. + fn decimals(currency_id: CurrencyId) -> Option; + /// Encode the CurrencyId to EvmAddress. + /// If is CurrencyId::DexShare and contain DexShare::Erc20, + /// will use the u32 to get the DexShare::Erc20 from the mapping. + fn encode_evm_address(v: CurrencyId) -> Option; + /// Decode the CurrencyId from EvmAddress. + /// If is CurrencyId::DexShare and contain DexShare::Erc20, + /// will use the u32 to get the DexShare::Erc20 from the mapping. + fn decode_evm_address(v: EvmAddress) -> Option; +} + +#[cfg(feature = "std")] +impl CurrencyIdMapping for () { + fn set_erc20_mapping(_address: EvmAddress) -> DispatchResult { + Err(DispatchError::Other("unimplemented CurrencyIdMapping")) + } + + fn get_evm_address(_currency_id: u32) -> Option { + None + } + + fn name(_currency_id: CurrencyId) -> Option> { + None + } + + fn symbol(_currency_id: CurrencyId) -> Option> { + None + } + + fn decimals(_currency_id: CurrencyId) -> Option { + None + } + + fn encode_evm_address(_v: CurrencyId) -> Option { + None + } + + fn decode_evm_address(_v: EvmAddress) -> Option { + None + } +} diff --git a/lib-serml/support/src/mocks.rs b/lib-serml/support/src/mocks.rs new file mode 100644 index 000000000..e69de29bb From 8500cdd12e9576bc63893884723e0f16baffd8bc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 02:46:56 +0800 Subject: [PATCH 39/83] update support mocks --- lib-serml/support/src/mocks.rs | 101 +++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/lib-serml/support/src/mocks.rs b/lib-serml/support/src/mocks.rs index e69de29bb..5e7c33107 100644 --- a/lib-serml/support/src/mocks.rs +++ b/lib-serml/support/src/mocks.rs @@ -0,0 +1,101 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{AddressMapping, CurrencyId, CurrencyIdMapping}; +use codec::Encode; +use frame_support::pallet_prelude::DispatchResult; +use primitives::{currency::TokenInfo, evm::EvmAddress, H160_POSITION_TOKEN, H160_PREFIX_TOKEN}; +use sp_core::{crypto::AccountId32, H160}; +use sp_io::hashing::blake2_256; +use sp_std::{ + convert::{TryFrom, TryInto}, + vec::Vec, +}; + +pub struct MockAddressMapping; + +impl AddressMapping for MockAddressMapping { + fn get_account_id(address: &H160) -> AccountId32 { + let mut data = [0u8; 32]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + AccountId32::from(data) + } + + fn get_evm_address(account_id: &AccountId32) -> Option { + let data: [u8; 32] = account_id.clone().into(); + if data.starts_with(b"evm:") { + Some(H160::from_slice(&data[4..24])) + } else { + None + } + } + + fn get_default_evm_address(account_id: &AccountId32) -> H160 { + let slice: &[u8] = account_id.as_ref(); + H160::from_slice(&slice[0..20]) + } + + fn get_or_create_evm_address(account_id: &AccountId32) -> H160 { + Self::get_evm_address(account_id).unwrap_or({ + let payload = (b"evm:", account_id); + H160::from_slice(&payload.using_encoded(blake2_256)[0..20]) + }) + } + + fn is_linked(account_id: &AccountId32, evm: &H160) -> bool { + Self::get_or_create_evm_address(account_id) == *evm + } +} + +pub struct MockCurrencyIdMapping; + +impl CurrencyIdMapping for MockCurrencyIdMapping { + fn set_erc20_mapping(_address: EvmAddress) -> DispatchResult { + Ok(()) + } + + fn get_evm_address(_currency_id: u32) -> Option { + Some(EvmAddress::default()) + } + + fn name(currency_id: CurrencyId) -> Option> { + currency_id.name().map(|v| v.as_bytes().to_vec()) + } + + fn symbol(currency_id: CurrencyId) -> Option> { + currency_id.symbol().map(|v| v.as_bytes().to_vec()) + } + + fn decimals(currency_id: CurrencyId) -> Option { + currency_id.decimals() + } + + fn encode_evm_address(v: CurrencyId) -> Option { + EvmAddress::try_from(v).ok() + } + + fn decode_evm_address(v: EvmAddress) -> Option { + let address = v.as_bytes(); + if address.starts_with(&H160_PREFIX_TOKEN) { + address[H160_POSITION_TOKEN].try_into().map(CurrencyId::Token).ok() + } else { + None + } + } +} From 6e22dfabe73771c2f3201f27389a7b6ca2294dbc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 03:31:48 +0800 Subject: [PATCH 40/83] UPDATE tests --- lib-serml/transaction-payment/src/tests.rs | 31 ++++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib-serml/transaction-payment/src/tests.rs b/lib-serml/transaction-payment/src/tests.rs index 3f165308b..3fbb7dbbd 100644 --- a/lib-serml/transaction-payment/src/tests.rs +++ b/lib-serml/transaction-payment/src/tests.rs @@ -26,17 +26,17 @@ use frame_support::{ weights::{DispatchClass, DispatchInfo, Pays}, }; use mock::{ - AccountId, BlockWeights, Call, Currencies, Dex, ExtBuilder, Origin, Runtime, TransactionPayment, DNAR, ALICE, + AccountId, BlockWeights, Call, Currencies, SetheumDEX, ExtBuilder, Origin, Runtime, TransactionPayment, DNAR, ALICE, USDJ, BOB, DOT, }; use orml_traits::MultiCurrency; use sp_runtime::{testing::TestXt, traits::One}; const CALL: &::Call = - &Call::Currencies(setheum_currencies::Call::transfer(BOB, USDJ, 12)); + &Call::Currencies(module_currencies::Call::transfer(BOB, USDJ, 12)); const CALL2: &::Call = - &Call::Currencies(setheum_currencies::Call::transfer_native_currency(BOB, 12)); + &Call::Currencies(module_currencies::Call::transfer_native_currency(BOB, 12)); const INFO: DispatchInfo = DispatchInfo { weight: 1000, @@ -110,16 +110,17 @@ fn charges_fee_when_validate_and_native_is_not_enough() { assert_eq!(>::free_balance(DNAR, &BOB), 0); assert_eq!(>::free_balance(USDJ, &BOB), 1000); - // add liquidity to Dex - assert_ok!(Dex::add_liquidity( + // add liquidity to DEX + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), DNAR, USDJ, 10000, 1000, + 0, false )); - assert_eq!(Dex::get_liquidity_pool(DNAR, USDJ), (10000, 1000)); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000, 1000)); let fee = 500 * 2 + 1000; // len * byte + weight assert_eq!( @@ -132,7 +133,7 @@ fn charges_fee_when_validate_and_native_is_not_enough() { assert_eq!(Currencies::free_balance(DNAR, &BOB), 0); assert_eq!(Currencies::free_balance(USDJ, &BOB), 749); - assert_eq!(Dex::get_liquidity_pool(DNAR, USDJ), (10000 - 2000, 1251)); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000 - 2000, 1251)); }); } @@ -153,25 +154,27 @@ fn set_default_fee_token_work() { #[test] fn charge_fee_by_default_fee_token() { ExtBuilder::default().build().execute_with(|| { - // add liquidity to Dex - assert_ok!(Dex::add_liquidity( + // add liquidity to DEX + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), DNAR, USDJ, 10000, 1000, + 0, false )); - assert_ok!(Dex::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), DOT, USDJ, 100, 1000, + 0, false )); - assert_eq!(Dex::get_liquidity_pool(DNAR, USDJ), (10000, 1000)); - assert_eq!(Dex::get_liquidity_pool(DOT, USDJ), (100, 1000)); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000, 1000)); + assert_eq!(SetheumDEX::get_liquidity_pool(DOT, USDJ), (100, 1000)); assert_ok!(TransactionPayment::set_default_fee_token( Origin::signed(BOB), Some(DOT) @@ -194,8 +197,8 @@ fn charge_fee_by_default_fee_token() { assert_eq!(Currencies::free_balance(DNAR, &BOB), 0); assert_eq!(Currencies::free_balance(USDJ, &BOB), 0); assert_eq!(Currencies::free_balance(DOT, &BOB), 100 - 34); - assert_eq!(Dex::get_liquidity_pool(DNAR, USDJ), (10000 - 2000, 1251)); - assert_eq!(Dex::get_liquidity_pool(DOT, USDJ), (100 + 34, 1000 - 251)); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000 - 2000, 1251)); + assert_eq!(SetheumDEX::get_liquidity_pool(DOT, USDJ), (100 + 34, 1000 - 251)); }); } From 04558b803d7e5e462c8191d68bc969ae2d2a246f Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 03:31:58 +0800 Subject: [PATCH 41/83] update deps --- lib-serml/transaction-payment/Cargo.toml | 33 ++++++++++-------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/lib-serml/transaction-payment/Cargo.toml b/lib-serml/transaction-payment/Cargo.toml index 985425683..db1fe8ec5 100644 --- a/lib-serml/transaction-payment/Cargo.toml +++ b/lib-serml/transaction-payment/Cargo.toml @@ -10,28 +10,27 @@ serde = { version = "1.0.124", optional = true } codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } # Substrate dependencies -sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -sp-io= { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -pallet-proxy = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -pallet-transaction-payment = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +sp-io= { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } # orml dependencies -orml-tokens = { path = "../../lib-openrml/tokens", default-features = false } orml-traits = { path = "../../lib-openrml/traits", default-features = false } # local dependencies -setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } support = { package = "setheum-support", path = "../support", default-features = false } -setheum-dex = { path = "../dex", default-features = false } [dev-dependencies] -sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +orml-tokens = { path = "../../lib-openrml/tokens", default-features = false }setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } +setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } +setheum-dex = { path = "../dex", default-features = false } smallvec = "1.4.1" [features] @@ -44,16 +43,10 @@ std = [ "frame-system/std", "sp-io/std", "sp-std/std", - "orml-tokens/std", - "setheum-currencies/std", - "pallet-balances/std", - "pallet-proxy/std", "pallet-transaction-payment/std", "pallet-transaction-payment-rpc-runtime-api/std", "primitives/std", "support/std", "orml-traits/std", - "setheum-dex/std", ] - -try-runtime = ["frame-support/try-runtime"] \ No newline at end of file +try-runtime = ["frame-support/try-runtime"] From 62dab4afab96d617ce08f69a81715dad086517fc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 04:01:00 +0800 Subject: [PATCH 42/83] iterator inline update --- lib-serml/serp-treasury/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index 7dcee097a..c563d0b65 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -421,6 +421,7 @@ impl SerpTreasury for Pallet { /// and calls the serp to stabilise the unstable one(s) /// on SERP-TES. fn on_serp_tes() -> DispatchResult { + // iterator to SERP-TES every system stablecurrency for currency_id in T::StableCurrencyIds::get() { Self::serp_tes(currency_id) } From b1c56039eecfaedc5a049d0fdc2039b90681c7fb Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 04:22:25 +0800 Subject: [PATCH 43/83] on-serp-tes currencies custom serp_tes_schedule --- lib-serml/serp-treasury/src/lib.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index c563d0b65..f68f9e7b0 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -416,13 +416,26 @@ impl SerpTreasury for Pallet { Ok(()) } + // TODO: Update for every currency to have it's own governed custom adjustment-frequency, and call serp_tes at every block. + // TODO: - we can say that + // TODO: - ``` + // TODO: - if now % adjustment_frequency.currency_id == Zero::zero() { + // TODO: - Self::serp_tes(currency_id) + // TODO: - } // in the for loop. And then change `on_finalize` to call at every block. /// Trigger SERP-TES for all stablecoins /// Check all stablecoins stability and elasticity /// and calls the serp to stabilise the unstable one(s) /// on SERP-TES. fn on_serp_tes() -> DispatchResult { - // iterator to SERP-TES every system stablecurrency + // iterator to SERP-TES every system stablecurrency based on it's custom adjustment frequency for currency_id in T::StableCurrencyIds::get() { + // if now % T::SerpTesSchedule::get(currency_id) == Zero::zero() { + /// SERP TES (Token Elasticity of Supply). + /// Triggers Serping for all system stablecoins to stabilize stablecoin prices. + // Self::on_serp_tes(); + // } else { + + // } Self::serp_tes(currency_id) } Ok(()) From 7f38743a10a5cbe14b4b2f68ca1e147be015092c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 04:58:28 +0800 Subject: [PATCH 44/83] TODO for Migrate blocktime to Timestamp --- lib-serml/serp-treasury/src/lib.rs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index f68f9e7b0..c1e64da04 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -181,8 +181,12 @@ pub mod module { /// `pallet_timestamp`, the `timestamp` is not yet up to date at this point. /// Handle excessive surplus or debits of system when block end /// + // TODO: Migrate `BlockNumber` to `Timestamp` /// Triggers Serping for all system stablecoins at every block. fn on_initialize(now: T::BlockNumber) { + // TODO: Update for a global-adjustment-frequency to have it's own governed custom adjustment-frequency, + // TODO: - and call serp_tes at a timestamp e.g. every 10 minutes + /// /// SERP-TES Adjustment Frequency. /// Schedule for when to trigger SERP-TES /// (Blocktime/BlockNumber - every blabla block) @@ -416,12 +420,9 @@ impl SerpTreasury for Pallet { Ok(()) } - // TODO: Update for every currency to have it's own governed custom adjustment-frequency, and call serp_tes at every block. - // TODO: - we can say that - // TODO: - ``` - // TODO: - if now % adjustment_frequency.currency_id == Zero::zero() { - // TODO: - Self::serp_tes(currency_id) - // TODO: - } // in the for loop. And then change `on_finalize` to call at every block. + // TODO: Update for a global-adjustment-frequency to have it's own governed custom adjustment-frequency, + // TODO: - and call serp_tes at a timestamp e.g. every 10 minutes + /// /// Trigger SERP-TES for all stablecoins /// Check all stablecoins stability and elasticity /// and calls the serp to stabilise the unstable one(s) @@ -429,13 +430,6 @@ impl SerpTreasury for Pallet { fn on_serp_tes() -> DispatchResult { // iterator to SERP-TES every system stablecurrency based on it's custom adjustment frequency for currency_id in T::StableCurrencyIds::get() { - // if now % T::SerpTesSchedule::get(currency_id) == Zero::zero() { - /// SERP TES (Token Elasticity of Supply). - /// Triggers Serping for all system stablecoins to stabilize stablecoin prices. - // Self::on_serp_tes(); - // } else { - - // } Self::serp_tes(currency_id) } Ok(()) From 59382f45b78851ed76a893be9b977350743793de Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 05:00:30 +0800 Subject: [PATCH 45/83] update transaction-payments --- lib-serml/transaction-payment/src/lib.rs | 71 ++++++++++++---------- lib-serml/transaction-payment/src/mock.rs | 34 ++++++----- lib-serml/transaction-payment/src/tests.rs | 36 +++++------ 3 files changed, 76 insertions(+), 65 deletions(-) diff --git a/lib-serml/transaction-payment/src/lib.rs b/lib-serml/transaction-payment/src/lib.rs index 6824f5f98..e8c5e5717 100644 --- a/lib-serml/transaction-payment/src/lib.rs +++ b/lib-serml/transaction-payment/src/lib.rs @@ -29,7 +29,9 @@ use frame_support::{ dispatch::{DispatchResult, Dispatchable}, pallet_prelude::*, - traits::{Currency, ExistenceRequirement, Imbalance, OnUnbalanced, ReservableCurrency, WithdrawReasons}, + traits::{ + Currency, ExistenceRequirement, Imbalance, OnUnbalanced, ReservableCurrency, SameOrOther, WithdrawReasons, + }, weights::{DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, WeightToFeePolynomial}, }; use frame_system::pallet_prelude::*; @@ -215,7 +217,7 @@ pub mod module { #[pallet::config] pub trait Config: frame_system::Config { - /// All non-native currency ids in setheum. + /// All non-native currency ids in Setheum. #[pallet::constant] type AllNonNativeCurrencyIds: Get>; @@ -224,9 +226,9 @@ pub mod module { #[pallet::constant] type NativeCurrencyId: Get; - /// Stable currency id, should be USDJ + /// Setter currency id, should be SETT #[pallet::constant] - type StableCurrencyId: Get; + type GetSetterCurrencyId: Get; /// The currency type in which fees will be paid. type Currency: Currency + ReservableCurrency + Send + Sync; @@ -251,12 +253,12 @@ pub mod module { /// block's weight. type FeeMultiplierUpdate: MultiplierUpdate; - /// Dex to exchange currencies. - type Dex = DEXManager; + /// DEX to exchange currencies. + type DEX: DEXManager; - /// The max slippage allowed when swap fee with Dex + /// The max slippage allowed when swap fee with DEX #[pallet::constant] - type MaxSlippageSwapWithDex: Get; + type MaxSlippageSwapWithDEX: Get; /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; @@ -267,10 +269,16 @@ pub mod module { Multiplier::saturating_from_integer(1) } + /// The next fee multiplier. + /// + /// NextFeeMultiplier: Multiplier #[pallet::storage] #[pallet::getter(fn next_fee_multiplier)] pub type NextFeeMultiplier = StorageValue<_, Multiplier, ValueQuery, DefaultFeeMultiplier>; + /// The default fee currency for accounts. + /// + /// DefaultFeeCurrencyId: AccountId => Option #[pallet::storage] #[pallet::getter(fn default_fee_currency_id)] pub type DefaultFeeCurrencyId = StorageMap<_, Twox64Concat, T::AccountId, CurrencyId, OptionQuery>; @@ -421,18 +429,16 @@ where /// Compute the final fee value for a particular transaction. /// /// The final fee is composed of: - /// - `base_fee`: This is the minimum amount a user pays for a - /// transaction. It is declared as a base _weight_ in the runtime and - /// converted to a fee using `WeightToFee`. - /// - `len_fee`: The length fee, the amount paid for the encoded length - /// (in bytes) of the transaction. - /// - `weight_fee`: This amount is computed based on the weight of the - /// transaction. Weight accounts for the execution time of a + /// - `base_fee`: This is the minimum amount a user pays for a transaction. It is declared as + /// a base _weight_ in the runtime and converted to a fee using `WeightToFee`. + /// - `len_fee`: The length fee, the amount paid for the encoded length (in bytes) of the /// transaction. - /// - `targeted_fee_adjustment`: This is a multiplier that can tune the - /// final fee based on the congestion of the network. - /// - (Optional) `tip`: If included in the transaction, the tip will be - /// added on top. Only signed transactions can have a tip. + /// - `weight_fee`: This amount is computed based on the weight of the transaction. Weight + /// accounts for the execution time of a transaction. + /// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on the + /// congestion of the network. + /// - (Optional) `tip`: If included in the transaction, the tip will be added on top. Only + /// signed transactions can have a tip. /// /// The base fee and adjusted weight and length fees constitute the /// _inclusion fee,_ which is the minimum fee for a transaction to be @@ -533,9 +539,9 @@ where T::WeightToFee::calc(&capped_weight) } - fn ensure_can_charge_fee(who: &T::AccountId, fee: PalletBalanceOf, reason: WithdrawReasons) { + pub fn ensure_can_charge_fee(who: &T::AccountId, fee: PalletBalanceOf, reason: WithdrawReasons) { let native_currency_id = T::NativeCurrencyId::get(); - let stable_currency_id = T::StableCurrencyId::get(); + let setter_currency_id = T::GetSetterCurrencyId::get(); let other_currency_ids = T::AllNonNativeCurrencyIds::get(); let mut charge_fee_order: Vec = if let Some(default_fee_currency_id) = DefaultFeeCurrencyId::::get(who) { @@ -545,7 +551,7 @@ where }; charge_fee_order.dedup(); - let price_impact_limit = Some(T::MaxSlippageSwapWithDex::get()); + let price_impact_limit = Some(T::MaxSlippageSwapWithDEX::get()); // iterator charge fee order to get enough fee for currency_id in charge_fee_order { @@ -562,14 +568,14 @@ where break; } } else { - // try to use non-native currency to swap native currency by exchange with Dex - let trading_path = if currency_id == stable_currency_id { - vec![stable_currency_id, native_currency_id] + // try to use non-native currency to swap native currency by exchange with DEX + let trading_path = if currency_id == setter_currency_id { + vec![setter_currency_id, native_currency_id] } else { - vec![currency_id, stable_currency_id, native_currency_id] + vec![currency_id, setter_currency_id, native_currency_id] }; - if T::Dex::swap_with_exact_target( + if T::DEX::swap_with_exact_target( who, &trading_path, fee.unique_saturated_into(), @@ -748,8 +754,9 @@ where // The refund cannot be larger than the up front payed max weight. // `PostDispatchInfo::calc_unspent` guards against such a case. match payed.offset(refund_imbalance) { - Ok(actual_payment) => actual_payment, - Err(_) => return Err(InvalidTransaction::Payment.into()), + SameOrOther::Same(actual_payment) => actual_payment, + SameOrOther::None => Default::default(), + _ => return Err(InvalidTransaction::Payment.into()), } } // We do not recreate the account using the refund. The up front payment @@ -759,7 +766,6 @@ where let (tip, fee) = actual_payment.split(tip); // distribute fee - ::OnTransactionPayment::on_unbalanceds(Some(fee).into_iter().chain(Some(tip))); } Ok(()) @@ -810,8 +816,9 @@ where Ok(refund_imbalance) => { // The refund cannot be larger than the up front payed max weight. match payed.offset(refund_imbalance) { - Ok(actual_payment) => actual_payment, - Err(_) => return Err(InvalidTransaction::Payment.into()), + SameOrOther::Same(actual_payment) => actual_payment, + SameOrOther::None => Default::default(), + _ => return Err(InvalidTransaction::Payment.into()), } } // We do not recreate the account using the refund. The up front payment diff --git a/lib-serml/transaction-payment/src/mock.rs b/lib-serml/transaction-payment/src/mock.rs index 38b29b4e3..969f6df3b 100644 --- a/lib-serml/transaction-payment/src/mock.rs +++ b/lib-serml/transaction-payment/src/mock.rs @@ -22,7 +22,9 @@ use super::*; use crate as transaction_payment; -use frame_support::{construct_runtime, ord_parameter_types, parameter_types, weights::WeightToFeeCoefficients, PalletId}; +use frame_support::{ + construct_runtime, ord_parameter_types, parameter_types, weights::WeightToFeeCoefficients, PalletId, +}; use orml_traits::parameter_type_with_key; use primitives::{Amount, TokenSymbol, TradingPair}; use smallvec::smallvec; @@ -30,12 +32,10 @@ use sp_core::{crypto::AccountId32, H256}; use sp_runtime::{ testing::Header, traits::{IdentityLookup, One}, - DispatchError, DispatchResult, - FixedPointNumber, Perbill, }; use sp_std::cell::RefCell; -use support::Ratio; +use support::{mocks::MockAddressMapping, Ratio}; pub type AccountId = AccountId32; pub type BlockNumber = u64; @@ -43,7 +43,7 @@ pub type BlockNumber = u64; pub const ALICE: AccountId = AccountId::new([1u8; 32]); pub const BOB: AccountId = AccountId::new([2u8; 32]); pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); -pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); +pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const DOT: CurrencyId = CurrencyId::Token(TokenSymbol::DOT); parameter_types! { @@ -89,6 +89,7 @@ impl frame_system::Config for Runtime { type BaseCallFilter = (); type SystemWeightInfo = (); type SS58Prefix = (); + type OnSetCode = (); } parameter_type_with_key! { @@ -134,6 +135,8 @@ impl setheum_currencies::Config for Runtime { type NativeCurrency = AdaptedBasicCurrency; type GetNativeCurrencyId = GetNativeCurrencyId; type WeightInfo = (); + type AddressMapping = MockAddressMapping; + type EVMBridge = (); } ord_parameter_types! { @@ -144,7 +147,7 @@ parameter_types! { pub const DexPalletId: PalletId = PalletId(*b"dnr/sdex"); pub const GetExchangeFee: (u32, u32) = (0, 100); pub const TradingPathLimit: u32 = 3; - pub EnabledTradingPairs : Vec = vec![TradingPair::new(USDJ, DNAR), TradingPair::new(USDJ, DOT)]; + pub EnabledTradingPairs : Vec = vec![TradingPair::new(SETT, DNAR), TradingPair::new(SETT, DOT)]; } impl dex::Config for Runtime { @@ -152,31 +155,32 @@ impl dex::Config for Runtime { type Currency = Currencies; type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; - type PalletId = DexPalletId; + type PalletId = DEXPalletId; + type CurrencyIdMapping = (); type DEXIncentives = (); type WeightInfo = (); type ListingOrigin = frame_system::EnsureSignedBy; } parameter_types! { - pub AllNonNativeCurrencyIds: Vec = vec![USDJ, DOT]; + pub AllNonNativeCurrencyIds: Vec = vec![SETT, DOT]; pub MaxSlippageSwapWithDex: Ratio = Ratio::one(); - pub const StableCurrencyId: CurrencyId = USDJ; + pub const GetSetterCurrencyId: CurrencyId = SETT; pub static TransactionByteFee: u128 = 1; } impl Config for Runtime { type AllNonNativeCurrencyIds = AllNonNativeCurrencyIds; type NativeCurrencyId = GetNativeCurrencyId; - type StableCurrencyId = StableCurrencyId; + type GetSetterCurrencyId = GetSetterCurrencyId; type Currency = PalletBalances; type MultiCurrency = Currencies; type OnTransactionPayment = (); type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; type FeeMultiplierUpdate = (); - type Dex = Dex; - type MaxSlippageSwapWithDex = MaxSlippageSwapWithDex; + type DEX = SetheumDEX; + type MaxSlippageSwapWithDEX = MaxSlippageSwapWithDEX; type WeightInfo = (); } @@ -212,7 +216,7 @@ construct_runtime!( PalletBalances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Tokens: orml_tokens::{Pallet, Storage, Event, Config}, Currencies: setheum_currencies::{Pallet, Call, Event}, - Dex = dex::{Pallet, Storage, Call, Event, Config}, + SetheumDEX: setheum_dex::{Pallet, Storage, Call, Event, Config}, } ); @@ -226,7 +230,7 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> Self { Self { - endowed_accounts: vec![(ALICE, USDJ, 10000), (ALICE, DOT, 1000)], + endowed_accounts: vec![(ALICE, SETT, 10000), (ALICE, DOT, 1000)], base_weight: 0, byte_fee: 2, weight_to_fee: 1, @@ -270,7 +274,7 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - dex::GenesisConfig:: { + setheum_dex::GenesisConfig:: { initial_listing_trading_pairs: vec![], initial_enabled_trading_pairs: EnabledTradingPairs::get(), initial_added_liquidity_pools: vec![], diff --git a/lib-serml/transaction-payment/src/tests.rs b/lib-serml/transaction-payment/src/tests.rs index 3fbb7dbbd..5e452c1fd 100644 --- a/lib-serml/transaction-payment/src/tests.rs +++ b/lib-serml/transaction-payment/src/tests.rs @@ -27,13 +27,13 @@ use frame_support::{ }; use mock::{ AccountId, BlockWeights, Call, Currencies, SetheumDEX, ExtBuilder, Origin, Runtime, TransactionPayment, DNAR, ALICE, - USDJ, BOB, DOT, + SETT, BOB, DOT, }; use orml_traits::MultiCurrency; use sp_runtime::{testing::TestXt, traits::One}; const CALL: &::Call = - &Call::Currencies(module_currencies::Call::transfer(BOB, USDJ, 12)); + &Call::Currencies(module_currencies::Call::transfer(BOB, SETT, 12)); const CALL2: &::Call = &Call::Currencies(module_currencies::Call::transfer_native_currency(BOB, 12)); @@ -106,21 +106,21 @@ fn refund_fee_according_to_actual_when_post_dispatch_and_native_currency_is_enou #[test] fn charges_fee_when_validate_and_native_is_not_enough() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(>::transfer(USDJ, &ALICE, &BOB, 1000)); + assert_ok!(>::transfer(SETT, &ALICE, &BOB, 1000)); assert_eq!(>::free_balance(DNAR, &BOB), 0); - assert_eq!(>::free_balance(USDJ, &BOB), 1000); + assert_eq!(>::free_balance(SETT, &BOB), 1000); // add liquidity to DEX assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), DNAR, - USDJ, + SETT, 10000, 1000, 0, false )); - assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000, 1000)); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, SETT), (10000, 1000)); let fee = 500 * 2 + 1000; // len * byte + weight assert_eq!( @@ -132,8 +132,8 @@ fn charges_fee_when_validate_and_native_is_not_enough() { ); assert_eq!(Currencies::free_balance(DNAR, &BOB), 0); - assert_eq!(Currencies::free_balance(USDJ, &BOB), 749); - assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000 - 2000, 1251)); + assert_eq!(Currencies::free_balance(SETT, &BOB), 749); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, SETT), (10000 - 2000, 1251)); }); } @@ -143,9 +143,9 @@ fn set_default_fee_token_work() { assert_eq!(TransactionPayment::default_fee_currency_id(&ALICE), None); assert_ok!(TransactionPayment::set_default_fee_token( Origin::signed(ALICE), - Some(USDJ) + Some(SETT) )); - assert_eq!(TransactionPayment::default_fee_currency_id(&ALICE), Some(USDJ)); + assert_eq!(TransactionPayment::default_fee_currency_id(&ALICE), Some(SETT)); assert_ok!(TransactionPayment::set_default_fee_token(Origin::signed(ALICE), None)); assert_eq!(TransactionPayment::default_fee_currency_id(&ALICE), None); }); @@ -158,7 +158,7 @@ fn charge_fee_by_default_fee_token() { assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), DNAR, - USDJ, + SETT, 10000, 1000, 0, @@ -167,14 +167,14 @@ fn charge_fee_by_default_fee_token() { assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), DOT, - USDJ, + SETT, 100, 1000, 0, false )); - assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000, 1000)); - assert_eq!(SetheumDEX::get_liquidity_pool(DOT, USDJ), (100, 1000)); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, SETT), (10000, 1000)); + assert_eq!(SetheumDEX::get_liquidity_pool(DOT, SETT), (100, 1000)); assert_ok!(TransactionPayment::set_default_fee_token( Origin::signed(BOB), Some(DOT) @@ -182,7 +182,7 @@ fn charge_fee_by_default_fee_token() { assert_eq!(TransactionPayment::default_fee_currency_id(&BOB), Some(DOT)); assert_ok!(>::transfer(DOT, &ALICE, &BOB, 100)); assert_eq!(>::free_balance(DNAR, &BOB), 0); - assert_eq!(>::free_balance(USDJ, &BOB), 0); + assert_eq!(>::free_balance(SETT, &BOB), 0); assert_eq!(>::free_balance(DOT, &BOB), 100); let fee = 500 * 2 + 1000; // len * byte + weight @@ -195,10 +195,10 @@ fn charge_fee_by_default_fee_token() { ); assert_eq!(Currencies::free_balance(DNAR, &BOB), 0); - assert_eq!(Currencies::free_balance(USDJ, &BOB), 0); + assert_eq!(Currencies::free_balance(SETT, &BOB), 0); assert_eq!(Currencies::free_balance(DOT, &BOB), 100 - 34); - assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, USDJ), (10000 - 2000, 1251)); - assert_eq!(SetheumDEX::get_liquidity_pool(DOT, USDJ), (100 + 34, 1000 - 251)); + assert_eq!(SetheumDEX::get_liquidity_pool(DNAR, SETT), (10000 - 2000, 1251)); + assert_eq!(SetheumDEX::get_liquidity_pool(DOT, SETT), (100 + 34, 1000 - 251)); }); } From d45a0bd562e2bc44438565e7949aaaa0362ea29c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 05:25:03 +0800 Subject: [PATCH 46/83] Update Cargo.toml --- lib-serml/transaction-payment/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib-serml/transaction-payment/Cargo.toml b/lib-serml/transaction-payment/Cargo.toml index db1fe8ec5..55f515134 100644 --- a/lib-serml/transaction-payment/Cargo.toml +++ b/lib-serml/transaction-payment/Cargo.toml @@ -28,7 +28,7 @@ support = { package = "setheum-support", path = "../support", default-features = [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -orml-tokens = { path = "../../lib-openrml/tokens", default-features = false }setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } +orml-tokens = { path = "../../lib-openrml/tokens", default-features = false setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-dex = { path = "../dex", default-features = false } smallvec = "1.4.1" From ab2c8bf4a21bafd948480a097491dd00c93c2156 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 05:25:36 +0800 Subject: [PATCH 47/83] Update Cargo.toml --- lib-serml/transaction-payment/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib-serml/transaction-payment/Cargo.toml b/lib-serml/transaction-payment/Cargo.toml index 55f515134..aad4ffc9d 100644 --- a/lib-serml/transaction-payment/Cargo.toml +++ b/lib-serml/transaction-payment/Cargo.toml @@ -28,7 +28,7 @@ support = { package = "setheum-support", path = "../support", default-features = [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } -orml-tokens = { path = "../../lib-openrml/tokens", default-features = false +orml-tokens = { path = "../../lib-openrml/tokens", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-dex = { path = "../dex", default-features = false } smallvec = "1.4.1" From c0fbd656efa579993f935d15a53b7656a79de514 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Thu, 24 Jun 2021 05:53:03 +0800 Subject: [PATCH 48/83] DexModule to SetheumDEX --- lib-serml/dex/src/mock.rs | 2 +- lib-serml/dex/src/tests.rs | 354 +++++++++++++------------- lib-serml/serp-auction/src/mock.rs | 6 +- lib-serml/serp-treasury/src/mock.rs | 13 +- lib-serml/setters-manager/src/mock.rs | 2 +- lib-serml/settmint-engine/src/mock.rs | 6 +- lib-serml/settway/src/mock.rs | 2 +- runtime/neom/src/lib.rs | 2 +- runtime/newrome/src/lib.rs | 2 +- runtime/setheum/src/lib.rs | 2 +- 10 files changed, 200 insertions(+), 191 deletions(-) diff --git a/lib-serml/dex/src/mock.rs b/lib-serml/dex/src/mock.rs index ad6ff4564..c24ab25e4 100644 --- a/lib-serml/dex/src/mock.rs +++ b/lib-serml/dex/src/mock.rs @@ -136,7 +136,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Storage, Config, Event}, - DexModule: dex::{Pallet, Storage, Call, Event, Config}, + SetheumDEX: dex::{Pallet, Storage, Call, Event, Config}, Tokens: orml_tokens::{Pallet, Storage, Event, Config}, } ); diff --git a/lib-serml/dex/src/tests.rs b/lib-serml/dex/src/tests.rs index 146ed105f..290b29884 100644 --- a/lib-serml/dex/src/tests.rs +++ b/lib-serml/dex/src/tests.rs @@ -23,7 +23,7 @@ use super::*; use frame_support::{assert_noop, assert_ok}; use mock::{ - DexModule, Event, ExtBuilder, ListingOrigin, Origin, Runtime, System, Tokens, + SetheumDEX, Event, ExtBuilder, ListingOrigin, Origin, Runtime, System, Tokens, ALICE, BOB, DNAR, USDJ, EURJ, CHFJ, USDJ_DNAR_PAIR, USDJ_CHFJ_PAIR, }; use orml_traits::MultiReservableCurrency; @@ -35,27 +35,27 @@ fn enable_new_trading_pair_work() { System::set_block_number(1); assert_noop!( - DexModule::enable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), + SetheumDEX::enable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), BadOrigin ); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); - assert_ok!(DexModule::enable_trading_pair( + assert_ok!(SetheumDEX::enable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR )); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Enabled ); System::assert_last_event(Event::dex(crate::Event::EnableTradingPair(USDJ_DNAR_PAIR))); assert_noop!( - DexModule::enable_trading_pair(Origin::signed(ListingOrigin::get()), DNAR, USDJ), + SetheumDEX::enable_trading_pair(Origin::signed(ListingOrigin::get()), DNAR, USDJ), Error::::MustBeNotEnabled ); }); @@ -67,7 +67,7 @@ fn list_new_trading_pair_work() { System::set_block_number(1); assert_noop!( - DexModule::list_trading_pair( + SetheumDEX::list_trading_pair( Origin::signed(ALICE), USDJ, DNAR, @@ -81,10 +81,10 @@ fn list_new_trading_pair_work() { ); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); - assert_ok!(DexModule::list_trading_pair( + assert_ok!(SetheumDEX::list_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR, @@ -95,7 +95,7 @@ fn list_new_trading_pair_work() { 10, )); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (1_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000u128, 2_000_000_000_000u128), @@ -106,7 +106,7 @@ fn list_new_trading_pair_work() { System::assert_last_event(Event::dex(crate::Event::ListTradingPair(USDJ_DNAR_PAIR))); assert_noop!( - DexModule::list_trading_pair( + SetheumDEX::list_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, USDJ, @@ -120,7 +120,7 @@ fn list_new_trading_pair_work() { ); assert_noop!( - DexModule::list_trading_pair( + SetheumDEX::list_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR, @@ -140,34 +140,34 @@ fn disable_enabled_trading_pair_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(DexModule::enable_trading_pair( + assert_ok!(SetheumDEX::enable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR )); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Enabled ); assert_noop!( - DexModule::disable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), + SetheumDEX::disable_trading_pair(Origin::signed(ALICE), USDJ, DNAR), BadOrigin ); - assert_ok!(DexModule::disable_trading_pair( + assert_ok!(SetheumDEX::disable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR )); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); System::assert_last_event(Event::dex(crate::Event::DisableTradingPair(USDJ_DNAR_PAIR))); assert_noop!( - DexModule::disable_trading_pair(Origin::signed(ListingOrigin::get()), USDJ, DNAR), + SetheumDEX::disable_trading_pair(Origin::signed(ListingOrigin::get()), USDJ, DNAR), Error::::NotEnabledTradingPair ); }); @@ -181,7 +181,7 @@ fn disable_provisioning_trading_pair_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -190,7 +190,7 @@ fn disable_provisioning_trading_pair_work() { 0, false )); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -205,23 +205,23 @@ fn disable_provisioning_trading_pair_work() { assert_eq!(Tokens::free_balance(USDJ, &BOB), 999_995_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_999_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 10_000_000_000_000u128 ); assert_eq!( - Tokens::free_balance(DNAR, &DexModule::account_id()), + Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 1_000_000_000_000u128 ); assert_eq!( - DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), + SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (5_000_000_000_000u128, 0) ); assert_eq!( - DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), + SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, BOB), (5_000_000_000_000u128, 1_000_000_000_000u128) ); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -232,7 +232,7 @@ fn disable_provisioning_trading_pair_work() { let alice_ref_count_0 = System::consumers(&ALICE); let bob_ref_count_0 = System::consumers(&BOB); - assert_ok!(DexModule::disable_trading_pair( + assert_ok!(SetheumDEX::disable_trading_pair( Origin::signed(ListingOrigin::get()), USDJ, DNAR @@ -241,12 +241,12 @@ fn disable_provisioning_trading_pair_work() { assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000u128); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); - assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); - assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 0); + assert_eq!(SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); + assert_eq!(SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::NotEnabled ); assert_eq!(System::consumers(&ALICE), alice_ref_count_0 - 1); @@ -263,7 +263,7 @@ fn add_provision_work() { System::set_block_number(1); assert_noop!( - DexModule::add_liquidity( + SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -277,7 +277,7 @@ fn add_provision_work() { // alice add provision assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -285,14 +285,14 @@ fn add_provision_work() { not_before: 10, }) ); - assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); + assert_eq!(SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000u128); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 0); let alice_ref_count_0 = System::consumers(&ALICE); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -302,7 +302,7 @@ fn add_provision_work() { false )); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -311,16 +311,16 @@ fn add_provision_work() { }) ); assert_eq!( - DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), + SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (5_000_000_000_000u128, 0) ); assert_eq!(Tokens::free_balance(USDJ, &ALICE), 999_995_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 5_000_000_000_000u128 ); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 0); let alice_ref_count_1 = System::consumers(&ALICE); assert_eq!(alice_ref_count_1, alice_ref_count_0 + 1); System::assert_last_event(Event::dex(crate::Event::AddProvision( @@ -332,12 +332,12 @@ fn add_provision_work() { ))); // bob add provision - assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); + assert_eq!(SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000u128); let bob_ref_count_0 = System::consumers(&BOB); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(BOB), DNAR, USDJ, @@ -347,7 +347,7 @@ fn add_provision_work() { false )); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Provisioning(TradingPairProvisionParameters { min_contribution: (5_000_000_000_000u128, 1_000_000_000_000u128), target_provision: (5_000_000_000_000_000u128, 1_000_000_000_000_000u128), @@ -356,17 +356,17 @@ fn add_provision_work() { }) ); assert_eq!( - DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), + SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 1_000_000_000_000_000u128) ); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_000_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 5_000_000_000_000u128 ); assert_eq!( - Tokens::free_balance(DNAR, &DexModule::account_id()), + Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 1_000_000_000_000_000u128 ); let bob_ref_count_1 = System::consumers(&BOB); @@ -397,7 +397,7 @@ fn add_provision_work() { ); System::set_block_number(10); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -409,11 +409,11 @@ fn add_provision_work() { assert_eq!(Tokens::free_balance(USDJ, &ALICE), 999_000_000_000_000_000u128); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 999_000_000_000_000_000u128); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 1_000_000_000_000_000u128 ); assert_eq!( - Tokens::free_balance(DNAR, &DexModule::account_id()), + Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 2_000_000_000_000_000u128 ); assert_eq!( @@ -428,10 +428,10 @@ fn add_provision_work() { Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &BOB), 1_000_000_000_000_000, ); - assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); - assert_eq!(DexModule::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); + assert_eq!(SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, ALICE), (0, 0)); + assert_eq!(SetheumDEX::provisioning_pool(USDJ_DNAR_PAIR, BOB), (0, 0)); assert_eq!( - DexModule::trading_pair_statuses(USDJ_DNAR_PAIR), + SetheumDEX::trading_pair_statuses(USDJ_DNAR_PAIR), TradingPairStatus::<_, _>::Enabled ); System::assert_last_event(Event::dex(crate::Event::ProvisioningToEnabled( @@ -447,35 +447,35 @@ fn add_provision_work() { fn get_liquidity_work() { ExtBuilder::default().build().execute_with(|| { LiquidityPool::::insert(USDJ_DNAR_PAIR, (1000, 20)); - assert_eq!(DexModule::liquidity_pool(USDJ_DNAR_PAIR), (1000, 20)); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (1000, 20)); - assert_eq!(DexModule::get_liquidity(DNAR, USDJ), (20, 1000)); + assert_eq!(SetheumDEX::liquidity_pool(USDJ_DNAR_PAIR), (1000, 20)); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (1000, 20)); + assert_eq!(SetheumDEX::get_liquidity(DNAR, USDJ), (20, 1000)); }); } #[test] fn get_target_amount_work() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(DexModule::get_target_amount(10000, 0, 1000), 0); - assert_eq!(DexModule::get_target_amount(0, 20000, 1000), 0); - assert_eq!(DexModule::get_target_amount(10000, 20000, 0), 0); - assert_eq!(DexModule::get_target_amount(10000, 1, 1000000), 0); - assert_eq!(DexModule::get_target_amount(10000, 20000, 10000), 9949); - assert_eq!(DexModule::get_target_amount(10000, 20000, 1000), 1801); + assert_eq!(SetheumDEX::get_target_amount(10000, 0, 1000), 0); + assert_eq!(SetheumDEX::get_target_amount(0, 20000, 1000), 0); + assert_eq!(SetheumDEX::get_target_amount(10000, 20000, 0), 0); + assert_eq!(SetheumDEX::get_target_amount(10000, 1, 1000000), 0); + assert_eq!(SetheumDEX::get_target_amount(10000, 20000, 10000), 9949); + assert_eq!(SetheumDEX::get_target_amount(10000, 20000, 1000), 1801); }); } #[test] fn get_supply_amount_work() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(DexModule::get_supply_amount(10000, 0, 1000), 0); - assert_eq!(DexModule::get_supply_amount(0, 20000, 1000), 0); - assert_eq!(DexModule::get_supply_amount(10000, 20000, 0), 0); - assert_eq!(DexModule::get_supply_amount(10000, 1, 1), 0); - assert_eq!(DexModule::get_supply_amount(10000, 20000, 9949), 9999); - assert_eq!(DexModule::get_target_amount(10000, 20000, 9999), 9949); - assert_eq!(DexModule::get_supply_amount(10000, 20000, 1801), 1000); - assert_eq!(DexModule::get_target_amount(10000, 20000, 1000), 1801); + assert_eq!(SetheumDEX::get_supply_amount(10000, 0, 1000), 0); + assert_eq!(SetheumDEX::get_supply_amount(0, 20000, 1000), 0); + assert_eq!(SetheumDEX::get_supply_amount(10000, 20000, 0), 0); + assert_eq!(SetheumDEX::get_supply_amount(10000, 1, 1), 0); + assert_eq!(SetheumDEX::get_supply_amount(10000, 20000, 9949), 9999); + assert_eq!(SetheumDEX::get_target_amount(10000, 20000, 9999), 9949); + assert_eq!(SetheumDEX::get_supply_amount(10000, 20000, 1801), 1000); + assert_eq!(SetheumDEX::get_target_amount(10000, 20000, 1000), 1801); }); } @@ -488,35 +488,35 @@ fn get_target_amounts_work() { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); LiquidityPool::::insert(USDJ_CHFJ_PAIR, (100000, 10)); assert_noop!( - DexModule::get_target_amounts(&vec![DNAR], 10000, None), + SetheumDEX::get_target_amounts(&vec![DNAR], 10000, None), Error::::InvalidTradingPathLength, ); assert_noop!( - DexModule::get_target_amounts(&vec![DNAR, USDJ, CHFJ, EURJ], 10000, None), + SetheumDEX::get_target_amounts(&vec![DNAR, USDJ, CHFJ, EURJ], 10000, None), Error::::InvalidTradingPathLength, ); assert_eq!( - DexModule::get_target_amounts(&vec![DNAR, USDJ], 10000, None), + SetheumDEX::get_target_amounts(&vec![DNAR, USDJ], 10000, None), Ok(vec![10000, 24874]) ); assert_eq!( - DexModule::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(50, 100)), + SetheumDEX::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(50, 100)), Ok(vec![10000, 24874]) ); assert_noop!( - DexModule::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(49, 100)), + SetheumDEX::get_target_amounts(&vec![DNAR, USDJ], 10000, Ratio::checked_from_rational(49, 100)), Error::::ExceedPriceImpactLimit, ); assert_eq!( - DexModule::get_target_amounts(&vec![DNAR, USDJ, CHFJ], 10000, None), + SetheumDEX::get_target_amounts(&vec![DNAR, USDJ, CHFJ], 10000, None), Ok(vec![10000, 24874, 1]) ); assert_noop!( - DexModule::get_target_amounts(&vec![DNAR, USDJ, CHFJ], 100, None), + SetheumDEX::get_target_amounts(&vec![DNAR, USDJ, CHFJ], 100, None), Error::::ZeroTargetAmount, ); assert_noop!( - DexModule::get_target_amounts(&vec![DNAR, CHFJ], 100, None), + SetheumDEX::get_target_amounts(&vec![DNAR, CHFJ], 100, None), Error::::InsufficientLiquidity, ); }); @@ -530,7 +530,7 @@ fn calculate_amount_for_big_number_work() { (171_000_000_000_000_000_000_000, 56_000_000_000_000_000_000_000), ); assert_eq!( - DexModule::get_supply_amount( + SetheumDEX::get_supply_amount( 171_000_000_000_000_000_000_000, 56_000_000_000_000_000_000_000, 1_000_000_000_000_000_000_000 @@ -538,7 +538,7 @@ fn calculate_amount_for_big_number_work() { 3_140_495_867_768_595_041_323 ); assert_eq!( - DexModule::get_target_amount( + SetheumDEX::get_target_amount( 171_000_000_000_000_000_000_000, 56_000_000_000_000_000_000_000, 3_140_495_867_768_595_041_323 @@ -557,31 +557,31 @@ fn get_supply_amounts_work() { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); LiquidityPool::::insert(USDJ_CHFJ_PAIR, (100000, 10)); assert_noop!( - DexModule::get_supply_amounts(&vec![DNAR], 10000, None), + SetheumDEX::get_supply_amounts(&vec![DNAR], 10000, None), Error::::InvalidTradingPathLength, ); assert_noop!( - DexModule::get_supply_amounts(&vec![DNAR, USDJ, CHFJ, EURJ], 10000, None), + SetheumDEX::get_supply_amounts(&vec![DNAR, USDJ, CHFJ, EURJ], 10000, None), Error::::InvalidTradingPathLength, ); assert_eq!( - DexModule::get_supply_amounts(&vec![DNAR, USDJ], 24874, None), + SetheumDEX::get_supply_amounts(&vec![DNAR, USDJ], 24874, None), Ok(vec![10000, 24874]) ); assert_eq!( - DexModule::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(50, 100)), + SetheumDEX::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(50, 100)), Ok(vec![10102, 25000]) ); assert_noop!( - DexModule::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(49, 100)), + SetheumDEX::get_supply_amounts(&vec![DNAR, USDJ], 25000, Ratio::checked_from_rational(49, 100)), Error::::ExceedPriceImpactLimit, ); assert_noop!( - DexModule::get_supply_amounts(&vec![DNAR, USDJ, CHFJ], 10000, None), + SetheumDEX::get_supply_amounts(&vec![DNAR, USDJ, CHFJ], 10000, None), Error::::ZeroSupplyAmount, ); assert_noop!( - DexModule::get_supply_amounts(&vec![DNAR, CHFJ], 10000, None), + SetheumDEX::get_supply_amounts(&vec![DNAR, CHFJ], 10000, None), Error::::InsufficientLiquidity, ); }); @@ -595,11 +595,11 @@ fn _swap_work() { .execute_with(|| { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (50000, 10000)); - DexModule::_swap(USDJ, DNAR, 1000, 1000); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (51000, 9000)); - DexModule::_swap(DNAR, USDJ, 100, 800); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (50200, 9100)); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (50000, 10000)); + SetheumDEX::_swap(USDJ, DNAR, 1000, 1000); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (51000, 9000)); + SetheumDEX::_swap(DNAR, USDJ, 100, 800); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (50200, 9100)); }); } @@ -612,13 +612,13 @@ fn _swap_by_path_work() { LiquidityPool::::insert(USDJ_DNAR_PAIR, (50000, 10000)); LiquidityPool::::insert(USDJ_CHFJ_PAIR, (100000, 10)); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (50000, 10000)); - assert_eq!(DexModule::get_liquidity(USDJ, CHFJ), (100000, 10)); - DexModule::_swap_by_path(&vec![DNAR, USDJ], &vec![10000, 25000]); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (25000, 20000)); - DexModule::_swap_by_path(&vec![DNAR, USDJ, CHFJ], &vec![4000, 10000, 2]); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (15000, 24000)); - assert_eq!(DexModule::get_liquidity(USDJ, CHFJ), (110000, 8)); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (50000, 10000)); + assert_eq!(SetheumDEX::get_liquidity(USDJ, CHFJ), (100000, 10)); + SetheumDEX::_swap_by_path(&vec![DNAR, USDJ], &vec![10000, 25000]); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (25000, 20000)); + SetheumDEX::_swap_by_path(&vec![DNAR, USDJ, CHFJ], &vec![4000, 10000, 2]); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (15000, 24000)); + assert_eq!(SetheumDEX::get_liquidity(USDJ, CHFJ), (110000, 8)); }); } @@ -631,17 +631,17 @@ fn add_liquidity_work() { System::set_block_number(1); assert_noop!( - DexModule::add_liquidity(Origin::signed(ALICE), DNAR, USDJ, 100_000_000, 100_000_000, 0, false), + SetheumDEX::add_liquidity(Origin::signed(ALICE), DNAR, USDJ, 100_000_000, 100_000_000, 0, false), Error::::NotEnabledTradingPair ); assert_noop!( - DexModule::add_liquidity(Origin::signed(ALICE), USDJ, DNAR, 0, 100_000_000, 0, false), + SetheumDEX::add_liquidity(Origin::signed(ALICE), USDJ, DNAR, 0, 100_000_000, 0, false), Error::::InvalidLiquidityIncrement ); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (0, 0)); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (0, 0)); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 0); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 0 @@ -653,7 +653,7 @@ fn add_liquidity_work() { assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -671,11 +671,11 @@ fn add_liquidity_work() { 10_000_000_000_000, ))); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (5_000_000_000_000, 1_000_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 5_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 1_000_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 5_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 1_000_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 10_000_000_000_000 @@ -698,7 +698,7 @@ fn add_liquidity_work() { assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000); assert_noop!( - DexModule::add_liquidity( + SetheumDEX::add_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -709,7 +709,7 @@ fn add_liquidity_work() { ), Error::::UnacceptableShareIncrement ); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -727,11 +727,11 @@ fn add_liquidity_work() { 80_000_000_000_000, ))); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (45_000_000_000_000, 9_000_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 45_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 9_000_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 45_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 9_000_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &BOB), 0 @@ -753,7 +753,7 @@ fn remove_liquidity_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -763,7 +763,7 @@ fn remove_liquidity_work() { false )); assert_noop!( - DexModule::remove_liquidity( + SetheumDEX::remove_liquidity( Origin::signed(ALICE), USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), DNAR, @@ -776,11 +776,11 @@ fn remove_liquidity_work() { ); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (5_000_000_000_000, 1_000_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 5_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 1_000_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 5_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 1_000_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 10_000_000_000_000 @@ -789,7 +789,7 @@ fn remove_liquidity_work() { assert_eq!(Tokens::free_balance(DNAR, &ALICE), 999_999_000_000_000_000); assert_noop!( - DexModule::remove_liquidity( + SetheumDEX::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -801,7 +801,7 @@ fn remove_liquidity_work() { Error::::UnacceptableLiquidityWithdrawn ); assert_noop!( - DexModule::remove_liquidity( + SetheumDEX::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -812,7 +812,7 @@ fn remove_liquidity_work() { ), Error::::UnacceptableLiquidityWithdrawn ); - assert_ok!(DexModule::remove_liquidity( + assert_ok!(SetheumDEX::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -830,11 +830,11 @@ fn remove_liquidity_work() { 8_000_000_000_000, ))); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (1_000_000_000_000, 200_000_000_000) ); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 1_000_000_000_000); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 200_000_000_000); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 1_000_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 200_000_000_000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 2_000_000_000_000 @@ -842,7 +842,7 @@ fn remove_liquidity_work() { assert_eq!(Tokens::free_balance(USDJ, &ALICE), 999_999_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 999_999_800_000_000_000); - assert_ok!(DexModule::remove_liquidity( + assert_ok!(SetheumDEX::remove_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -859,9 +859,9 @@ fn remove_liquidity_work() { 200_000_000_000, 2_000_000_000_000, ))); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (0, 0)); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 0); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 0); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (0, 0)); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 0); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 0); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 0 @@ -869,7 +869,7 @@ fn remove_liquidity_work() { assert_eq!(Tokens::free_balance(USDJ, &ALICE), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &ALICE), 1_000_000_000_000_000_000); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -886,7 +886,7 @@ fn remove_liquidity_work() { Tokens::reserved_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &BOB), 10_000_000_000_000 ); - assert_ok!(DexModule::remove_liquidity( + assert_ok!(SetheumDEX::remove_liquidity( Origin::signed(BOB), USDJ, DNAR, @@ -914,7 +914,7 @@ fn do_swap_with_exact_supply_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -923,7 +923,7 @@ fn do_swap_with_exact_supply_work() { 0, false, )); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, CHFJ, @@ -934,25 +934,25 @@ fn do_swap_with_exact_supply_work() { )); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (500_000_000_000_000, 100_000_000_000_000) ); assert_eq!( - DexModule::get_liquidity(USDJ, CHFJ), + SetheumDEX::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 600_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 100_000_000_000_000); - assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 100_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &SetheumDEX::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); assert_noop!( - DexModule::do_swap_with_exact_supply( + SetheumDEX::do_swap_with_exact_supply( &BOB, &[DNAR, USDJ], 100_000_000_000_000, @@ -962,7 +962,7 @@ fn do_swap_with_exact_supply_work() { Error::::InsufficientTargetAmount ); assert_noop!( - DexModule::do_swap_with_exact_supply( + SetheumDEX::do_swap_with_exact_supply( &BOB, &[DNAR, USDJ], 100_000_000_000_000, @@ -972,11 +972,11 @@ fn do_swap_with_exact_supply_work() { Error::::ExceedPriceImpactLimit, ); assert_noop!( - DexModule::do_swap_with_exact_supply(&BOB, &[DNAR, USDJ, CHFJ, EURJ], 100_000_000_000_000, 0, None), + SetheumDEX::do_swap_with_exact_supply(&BOB, &[DNAR, USDJ, CHFJ, EURJ], 100_000_000_000_000, 0, None), Error::::InvalidTradingPathLength, ); - assert_ok!(DexModule::do_swap_with_exact_supply( + assert_ok!(SetheumDEX::do_swap_with_exact_supply( &BOB, &[DNAR, USDJ], 100_000_000_000_000, @@ -990,24 +990,24 @@ fn do_swap_with_exact_supply_work() { 248_743_718_592_964, ))); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (251_256_281_407_036, 200_000_000_000_000) ); assert_eq!( - DexModule::get_liquidity(USDJ, CHFJ), + SetheumDEX::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 351_256_281_407_036 ); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 200_000_000_000_000); - assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 200_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &SetheumDEX::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_248_743_718_592_964); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_900_000_000_000_000); assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); - assert_ok!(DexModule::do_swap_with_exact_supply( + assert_ok!(SetheumDEX::do_swap_with_exact_supply( &BOB, &[DNAR, USDJ, CHFJ], 200_000_000_000_000, @@ -1021,19 +1021,19 @@ fn do_swap_with_exact_supply_work() { 5_530_663_837, ))); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (126_259_437_892_983, 400_000_000_000_000) ); assert_eq!( - DexModule::get_liquidity(USDJ, CHFJ), + SetheumDEX::get_liquidity(USDJ, CHFJ), (224_996_843_514_053, 4_469_336_163) ); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 351_256_281_407_036 ); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 400_000_000_000_000); - assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 4_469_336_163); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 400_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &SetheumDEX::account_id()), 4_469_336_163); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_248_743_718_592_964); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_700_000_000_000_000); assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_005_530_663_837); @@ -1048,7 +1048,7 @@ fn do_swap_with_exact_target_work() { .execute_with(|| { System::set_block_number(1); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, DNAR, @@ -1057,7 +1057,7 @@ fn do_swap_with_exact_target_work() { 0, false, )); - assert_ok!(DexModule::add_liquidity( + assert_ok!(SetheumDEX::add_liquidity( Origin::signed(ALICE), USDJ, CHFJ, @@ -1068,25 +1068,25 @@ fn do_swap_with_exact_target_work() { )); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (500_000_000_000_000, 100_000_000_000_000) ); assert_eq!( - DexModule::get_liquidity(USDJ, CHFJ), + SetheumDEX::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 600_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 100_000_000_000_000); - assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 100_000_000_000_000); + assert_eq!(Tokens::free_balance(CHFJ, &SetheumDEX::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 1_000_000_000_000_000_000); assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); assert_noop!( - DexModule::do_swap_with_exact_target( + SetheumDEX::do_swap_with_exact_target( &BOB, &[DNAR, USDJ], 250_000_000_000_000, @@ -1096,7 +1096,7 @@ fn do_swap_with_exact_target_work() { Error::::ExcessiveSupplyAmount ); assert_noop!( - DexModule::do_swap_with_exact_target( + SetheumDEX::do_swap_with_exact_target( &BOB, &[DNAR, USDJ], 250_000_000_000_000, @@ -1106,7 +1106,7 @@ fn do_swap_with_exact_target_work() { Error::::ExceedPriceImpactLimit, ); assert_noop!( - DexModule::do_swap_with_exact_target( + SetheumDEX::do_swap_with_exact_target( &BOB, &[DNAR, USDJ, CHFJ, EURJ], 250_000_000_000_000, @@ -1116,7 +1116,7 @@ fn do_swap_with_exact_target_work() { Error::::InvalidTradingPathLength, ); - assert_ok!(DexModule::do_swap_with_exact_target( + assert_ok!(SetheumDEX::do_swap_with_exact_target( &BOB, &[DNAR, USDJ], 250_000_000_000_000, @@ -1130,24 +1130,24 @@ fn do_swap_with_exact_target_work() { 250_000_000_000_000, ))); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (250_000_000_000_000, 201_010_101_010_102) ); assert_eq!( - DexModule::get_liquidity(USDJ, CHFJ), + SetheumDEX::get_liquidity(USDJ, CHFJ), (100_000_000_000_000, 10_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 350_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 201_010_101_010_102); - assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 10_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 201_010_101_010_102); + assert_eq!(Tokens::free_balance(CHFJ, &SetheumDEX::account_id()), 10_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_250_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_898_989_898_989_898); assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_000_000_000_000); - assert_ok!(DexModule::do_swap_with_exact_target( + assert_ok!(SetheumDEX::do_swap_with_exact_target( &BOB, &[DNAR, USDJ, CHFJ], 5_000_000_000, @@ -1161,19 +1161,19 @@ fn do_swap_with_exact_target_work() { 5_000_000_000, ))); assert_eq!( - DexModule::get_liquidity(USDJ, DNAR), + SetheumDEX::get_liquidity(USDJ, DNAR), (148_989_898_989_898, 338_664_681_397_095) ); assert_eq!( - DexModule::get_liquidity(USDJ, CHFJ), + SetheumDEX::get_liquidity(USDJ, CHFJ), (201_010_101_010_102, 5_000_000_000) ); assert_eq!( - Tokens::free_balance(USDJ, &DexModule::account_id()), + Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 350_000_000_000_000 ); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 338_664_681_397_095); - assert_eq!(Tokens::free_balance(CHFJ, &DexModule::account_id()), 5_000_000_000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 338_664_681_397_095); + assert_eq!(Tokens::free_balance(CHFJ, &SetheumDEX::account_id()), 5_000_000_000); assert_eq!(Tokens::free_balance(USDJ, &BOB), 1_000_250_000_000_000_000); assert_eq!(Tokens::free_balance(DNAR, &BOB), 999_761_335_318_602_905); assert_eq!(Tokens::free_balance(CHFJ, &BOB), 1_000_000_005_000_000_000); @@ -1189,9 +1189,9 @@ fn initialize_added_liquidity_pools_genesis_work() { .execute_with(|| { System::set_block_number(1); - assert_eq!(DexModule::get_liquidity(USDJ, DNAR), (1000000, 2000000)); - assert_eq!(Tokens::free_balance(USDJ, &DexModule::account_id()), 2000000); - assert_eq!(Tokens::free_balance(DNAR, &DexModule::account_id()), 3000000); + assert_eq!(SetheumDEX::get_liquidity(USDJ, DNAR), (1000000, 2000000)); + assert_eq!(Tokens::free_balance(USDJ, &SetheumDEX::account_id()), 2000000); + assert_eq!(Tokens::free_balance(DNAR, &SetheumDEX::account_id()), 3000000); assert_eq!( Tokens::free_balance(USDJ_DNAR_PAIR.get_dex_share_currency_id().unwrap(), &ALICE), 4000000 diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index b938fbd43..a6c4045e7 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -217,7 +217,7 @@ impl serp_treasury::Config for Runtime { type CharityFundSerpupRatio = CharityFundSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); @@ -290,7 +290,7 @@ impl Config for Runtime { type GetNativeCurrencyId = GetNativeCurrencyId; type GetSetterCurrencyId = GetSetterCurrencyId; type SerpTreasury = SerpTreasuryModule; - type Dex = DexModule; + type Dex = SetheumDEX; type PriceSource = MockPriceSource; type UnsignedPriority = UnsignedPriority; type WeightInfo = (); @@ -310,7 +310,7 @@ construct_runtime!( Tokens: orml_tokens::{Module, Storage, Event, Config}, AuctionModule: orml_auction::{Module, Storage, Call, Event}, SerpTreasuryModule: serp_treasury::{Module, Storage, Call, Event}, - DexModule: dex::{Module, Storage, Call, Event, Config}, + SetheumDEX: dex::{Module, Storage, Call, Event, Config}, } ); diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index 8f95d59da..0fdb7c262 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -36,6 +36,7 @@ pub type AuctionId = u32; pub const ALICE: AccountId = 0; pub const BOB: AccountId = 1; +pub const CHARITY_FUND: AccountId = 2; // Currencies constants - CurrencyId/TokenSymbol pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); @@ -275,6 +276,9 @@ parameter_types! { pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/treasury"); + pub const SettPayTreasuryPalletId: PalletId = PalletId(*b"set/settpay"); + pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. @@ -293,9 +297,12 @@ impl Config for Runtime { type SettPaySerpupRatio = SettPaySerpupRatio; type SetheumTreasurySerpupRatio = SetheumTreasurySerpupRatio; type CharityFundSerpupRatio = CharityFundSerpupRatio; + type SettPayTreasuryAcc = SettPayTreasuryPalletId; + type SetheumTreasuryAcc = SetheumTreasuryPalletId; + type CharityFundAcc = CHARITY_FUND; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); @@ -315,7 +322,7 @@ construct_runtime!( Currencies: orml_currencies::{Module, Call, Event}, Tokens: orml_tokens::{Module, Storage, Event, Config}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, - DexModule: dex::{Module, Storage, Call, Event, Config}, + SetheumDEX: dex::{Module, Storage, Call, Event, Config}, } ); @@ -331,6 +338,8 @@ impl Default for ExtBuilder { (ALICE, CHFJ, 1000), (BOB, USDJ, 1000), (BOB, CHFJ, 1000), + (CHARITY_FUND, USDJ, 1000), + (CHARITY_FUND, CHFJ, 1000), ], } } diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index ee5540ca4..f409cc9af 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -270,7 +270,7 @@ impl serp_treasury::Config for Runtime { type CharityFundSerpupRatio = CharityFundSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index 1e79cf98a..f1a69c5c6 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -307,7 +307,7 @@ impl serp_treasury::Config for Runtime { type CharityFundSerpupRatio = CharityFundSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); @@ -396,7 +396,7 @@ impl Config for Runtime { type SerpTreasury = SerpTreasuryModule; type UpdateOrigin = EnsureSignedBy; type MaxSlippageSwapWithDex = MaxSlippageSwapWithDex; - type Dex = DexModule; + type Dex = SetheumDEX; type UnsignedPriority = UnsignedPriority; type WeightInfo = (); } @@ -417,7 +417,7 @@ construct_runtime!( Tokens: orml_tokens::{Module, Storage, Event, Config}, SettersManagerModule: setters_manager::{Module, Storage, Call, Event}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, - DexModule: dex::{Module, Storage, Call, Event, Config}, + SetheumDEX: dex::{Module, Storage, Call, Event, Config}, } ); diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index d5fd087b8..eaed23b15 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -256,7 +256,7 @@ impl serp_treasury::Config for Runtime { type CharityFundSerpupRatio = CharityFundSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = (); diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index f98a0afe7..cb8c06c25 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -950,7 +950,7 @@ impl serp_treasury::Config for Runtime { type CharityFundSerpupRatio = CharityFundSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = weights::serp_treasury::WeightInfo; diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index ef5374b57..32df80292 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -951,7 +951,7 @@ impl serp_treasury::Config for Runtime { type CharityFundSerpupRatio = CharityFundSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = weights::serp_treasury::WeightInfo; diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index 82c2d836f..ef558d920 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -951,7 +951,7 @@ impl serp_treasury::Config for Runtime { type CharityFundSerpupRatio = CharityFundSerpupRatio; type SerpAuctionManagerHandler = MockSerpAuctionManager; type UpdateOrigin = EnsureSignedBy; - type Dex = DexModule; + type Dex = SetheumDEX; type MaxAuctionsCount = MaxAuctionsCount; type PalletId = SerpTreasuryPalletId; type WeightInfo = weights::serp_treasury::WeightInfo; From f4384f78582cf7605ddd98e6800d7a1dbce42738 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 00:37:04 +0800 Subject: [PATCH 49/83] Update SettWay --- lib-serml/serp-treasury/src/mock.rs | 6 ++--- lib-serml/serp-treasury/src/tests.rs | 25 +++++++---------- lib-serml/settway/src/lib.rs | 30 ++++++++++++++++----- lib-serml/settway/src/tests.rs | 6 ++--- lib-serml/settway/src/weights.rs | 6 ++--- runtime/neom/src/weights/setheum_serp.rs | 2 +- runtime/newrome/src/benchmarking/serp.rs | 2 +- runtime/newrome/src/weights/setheum_serp.rs | 2 +- runtime/setheum/src/weights/setheum_serp.rs | 2 +- 9 files changed, 45 insertions(+), 36 deletions(-) diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index 0fdb7c262..ff37d9a01 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -335,11 +335,11 @@ impl Default for ExtBuilder { Self { endowed_accounts: vec![ (ALICE, USDJ, 1000), - (ALICE, CHFJ, 1000), + (ALICE, SETT, 1000), (BOB, USDJ, 1000), - (BOB, CHFJ, 1000), + (BOB, SETT, 1000), (CHARITY_FUND, USDJ, 1000), - (CHARITY_FUND, CHFJ, 1000), + (CHARITY_FUND, SETT, 1000), ], } } diff --git a/lib-serml/serp-treasury/src/tests.rs b/lib-serml/serp-treasury/src/tests.rs index 342f1f716..7e97a1f6a 100644 --- a/lib-serml/serp-treasury/src/tests.rs +++ b/lib-serml/serp-treasury/src/tests.rs @@ -29,15 +29,12 @@ use sp_runtime::traits::BadOrigin; fn issue_standard_works() { ExtBuilder::default().build().execute_with(|| { assert_eq!(Currencies::free_balance(USDJ, &ALICE), 1000); - assert_eq!(SerpTreasuryModule::standard_pool(), 0); assert_ok!(SerpTreasuryModule::issue_standard(&ALICE, 1000)); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 2000); - assert_eq!(SerpTreasuryModule::standard_pool(), 0); assert_ok!(SerpTreasuryModule::issue_standard(&ALICE, 1000)); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 3000); - assert_eq!(SerpTreasuryModule::standard_pool(), 1000); }); } @@ -45,10 +42,8 @@ fn issue_standard_works() { fn burn_standard_works() { ExtBuilder::default().build().execute_with(|| { assert_eq!(Currencies::free_balance(USDJ, &ALICE), 1000); - assert_eq!(SerpTreasuryModule::standard_pool(), 0); assert_ok!(SerpTreasuryModule::burn_standard(&ALICE, 300)); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 700); - assert_eq!(SerpTreasuryModule::standard_pool(), 0); }); } @@ -79,25 +74,23 @@ fn deposit_serplus_works() { ExtBuilder::default().build().execute_with(|| { assert_eq!(Currencies::free_balance(USDJ, &ALICE), 1000); assert_eq!(Currencies::free_balance(USDJ, &SerpTreasuryModule::account_id()), 0); - assert_eq!(SerpTreasuryModule::serplus_pool(), 0); - assert_ok!(SerpTreasuryModule::deposit_serplus(&ALICE, 300)); + assert_ok!(SerpTreasuryModule::deposit_serplus(USDJ, &ALICE, 300)); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 700); assert_eq!(Currencies::free_balance(USDJ, &SerpTreasuryModule::account_id()), 300); - assert_eq!(SerpTreasuryModule::serplus_pool(), 300); }); } #[test] fn deposit_setter_works() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 0); - assert_eq!(Currencies::free_balance(BTC, &SerpTreasuryModule::account_id()), 0); - assert_eq!(Currencies::free_balance(BTC, &ALICE), 1000); - assert_eq!(SerpTreasuryModule::deposit_setter(&ALICE, BTC, 10000).is_ok(), false); - assert_ok!(SerpTreasuryModule::deposit_setter(&ALICE, BTC, 500)); - assert_eq!(SerpTreasuryModule::total_reserve(BTC), 500); - assert_eq!(Currencies::free_balance(BTC, &SerpTreasuryModule::account_id()), 500); - assert_eq!(Currencies::free_balance(BTC, &ALICE), 500); + assert_eq!(SerpTreasuryModule::total_reserve(SETT), 0); + assert_eq!(Currencies::free_balance(SETT, &SerpTreasuryModule::account_id()), 0); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + assert_eq!(SerpTreasuryModule::deposit_setter(&ALICE, SETT, 10000).is_ok(), false); + assert_ok!(SerpTreasuryModule::deposit_setter(&ALICE, SETT, 500)); + assert_eq!(SerpTreasuryModule::total_reserve(SETT), 500); + assert_eq!(Currencies::free_balance(SETT, &SerpTreasuryModule::account_id()), 500); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 500); }); } diff --git a/lib-serml/settway/src/lib.rs b/lib-serml/settway/src/lib.rs index 88f43e052..2888aa1d7 100644 --- a/lib-serml/settway/src/lib.rs +++ b/lib-serml/settway/src/lib.rs @@ -27,13 +27,14 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::unused_unit)] -use frame_support::{pallet_prelude::*, transactional}; +use frame_support::{pallet_prelude::*, traits::ReservableCurrency, transactional}; use frame_system::pallet_prelude::*; -use primitives::{Amount, CurrencyId}; +use primitives::{Amount, Balance, CurrencyId}; use sp_runtime::{ traits::{StaticLookup, Zero}, DispatchResult, }; +use sp_std::vec::Vec; mod mock; mod tests; @@ -50,6 +51,12 @@ pub mod module { pub trait Config: frame_system::Config + settmint_engine::Config { type Event: From> + IsType<::Event>; + /// Currency for authorization reserved. + type Currency: ReservableCurrency; + + /// Reserved amount per authorization. + type DepositPerAuthorization: Get; + /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; } @@ -74,11 +81,20 @@ pub mod module { } /// The authorization relationship map from - /// Authorizer -> (ReserveType, Authorizee) -> Authorized + /// Authorizer -> (CollateralType, Authorizee) -> Authorized + /// + /// Authorization: double_map AccountId, (CurrencyId, T::AccountId) => Option #[pallet::storage] #[pallet::getter(fn authorization)] - pub type Authorization = - StorageDoubleMap<_, Twox64Concat, T::AccountId, Blake2_128Concat, (CurrencyId, T::AccountId), bool, ValueQuery>; + pub type Authorization = StorageDoubleMap< + _, + Twox64Concat, + T::AccountId, + Blake2_128Concat, + (CurrencyId, T::AccountId), + Balance, + OptionQuery, + >; #[pallet::pallet] pub struct Pallet(_); @@ -123,9 +139,9 @@ pub mod module { /// /// - `currency_id`: reserve currency id. /// - `from`: authorizer account - #[pallet::weight(::WeightInfo::transfer_reserve_from())] + #[pallet::weight(::WeightInfo::transfer_settmint_from())] #[transactional] - pub fn transfer_reserve_from( + pub fn transfer_settmint_from( origin: OriginFor, currency_id: CurrencyId, from: ::Source, diff --git a/lib-serml/settway/src/tests.rs b/lib-serml/settway/src/tests.rs index 80e2e5597..27d706107 100644 --- a/lib-serml/settway/src/tests.rs +++ b/lib-serml/settway/src/tests.rs @@ -78,11 +78,11 @@ fn unauthorize_all_should_work() { } #[test] -fn transfer_reserve_from_should_work() { +fn transfer_settmint_from_should_work() { ExtBuilder::default().build().execute_with(|| { assert_ok!(SettwayModule::adjust_setter(Origin::signed(ALICE), SETT, 100, 50)); assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettwayModule::transfer_reserve_from(Origin::signed(BOB), SETT, ALICE)); + assert_ok!(SettwayModule::transfer_settmint_from(Origin::signed(BOB), SETT, ALICE)); assert_eq!(SettersManagerModule::positions(SETT, BOB).reserve, 100); assert_eq!(SettersManagerModule::positions(SETT, BOB).standard, 50); }); @@ -92,7 +92,7 @@ fn transfer_reserve_from_should_work() { fn transfer_unauthorization_setters_should_not_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SettwayModule::transfer_reserve_from(Origin::signed(ALICE), SETT, BOB), + SettwayModule::transfer_settmint_from(Origin::signed(ALICE), SETT, BOB), Error::::NoAuthorization, ); }); diff --git a/lib-serml/settway/src/weights.rs b/lib-serml/settway/src/weights.rs index b7a43fc01..3dff5f473 100644 --- a/lib-serml/settway/src/weights.rs +++ b/lib-serml/settway/src/weights.rs @@ -51,7 +51,7 @@ pub trait WeightInfo { fn unauthorize() -> Weight; fn unauthorize_all(c: u32, ) -> Weight; fn adjust_setter() -> Weight; - fn transfer_reserve_from() -> Weight; + fn transfer_settmint_from() -> Weight; } /// Weights for setheum_settway using the Setheum node and recommended hardware. @@ -76,7 +76,7 @@ impl WeightInfo for SetheumWeight { .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_reserve_from() -> Weight { + fn transfer_settmint_from() -> Weight { (114_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) @@ -104,7 +104,7 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(24 as Weight)) .saturating_add(RocksDbWeight::get().writes(11 as Weight)) } - fn transfer_reserve_from() -> Weight { + fn transfer_settmint_from() -> Weight { (114_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(21 as Weight)) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) diff --git a/runtime/neom/src/weights/setheum_serp.rs b/runtime/neom/src/weights/setheum_serp.rs index 6252c38d3..3db5a2d91 100644 --- a/runtime/neom/src/weights/setheum_serp.rs +++ b/runtime/neom/src/weights/setheum_serp.rs @@ -61,7 +61,7 @@ impl setheum_settway::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_reserve_from() -> Weight { + fn transfer_settmint_from() -> Weight { (220_884_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) diff --git a/runtime/newrome/src/benchmarking/serp.rs b/runtime/newrome/src/benchmarking/serp.rs index 342b3c510..bc6037ede 100644 --- a/runtime/newrome/src/benchmarking/serp.rs +++ b/runtime/newrome/src/benchmarking/serp.rs @@ -94,7 +94,7 @@ runtime_benchmarks! { SetheumOracle::feed_values(RawOrigin::Root.into(), vec![(currency_id, reserve_price)])?; }: _(RawOrigin::Signed(caller), currency_id, reserve_amount.try_into().unwrap(), standard_amount) - transfer_reserve_from { + transfer_settmint_from { let currency_id: CurrencyId = ReserveCurrencyIds::get()[0]; let sender: AccountId = account("sender", 0, SEED); let sender_lookup = Indices::unlookup(sender.clone()); diff --git a/runtime/newrome/src/weights/setheum_serp.rs b/runtime/newrome/src/weights/setheum_serp.rs index 692562cc8..75bb66200 100644 --- a/runtime/newrome/src/weights/setheum_serp.rs +++ b/runtime/newrome/src/weights/setheum_serp.rs @@ -61,7 +61,7 @@ impl setheum_settway::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_reserve_from() -> Weight { + fn transfer_settmint_from() -> Weight { (221_574_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) diff --git a/runtime/setheum/src/weights/setheum_serp.rs b/runtime/setheum/src/weights/setheum_serp.rs index 2a259328b..b08babc6a 100644 --- a/runtime/setheum/src/weights/setheum_serp.rs +++ b/runtime/setheum/src/weights/setheum_serp.rs @@ -61,7 +61,7 @@ impl setheum_settway::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_reserve_from() -> Weight { + fn transfer_settmint_from() -> Weight { (116_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) From 1dffc8e20ab1c92e7a642b00cc391f2ae29f0caa Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 00:47:11 +0800 Subject: [PATCH 50/83] pdate settway mock --- lib-serml/setters-manager/src/mock.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index f409cc9af..caed309b2 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -26,7 +26,10 @@ use frame_system::EnsureSignedBy; use orml_traits::parameter_type_with_key; use primitives::TokenSymbol; use sp_core::H256; -use sp_runtime::{testing::Header, traits::IdentityLookup}; +use sp_runtime::{ + testing::Header, + traits::{AccountIdConversion, IdentityLookup}, +}; use support::{SerpAuctionManager, StandardValidator}; pub type AccountId = u128; @@ -112,6 +115,7 @@ impl frame_system::Config for Runtime { type BaseCallFilter = (); type SystemWeightInfo = (); type SS58Prefix = (); + type OnSetCode = (); } parameter_type_with_key! { From d9b7a639ff1ee4555302b342fa1cb813fb4d0dc0 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 11:21:33 +0800 Subject: [PATCH 51/83] Remove VND --- primitives/src/currency.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index 5ae568585..01067616c 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -221,8 +221,7 @@ create_currency_id! { TZSJ("Setheum Tanzanian Shilling", 12) = 38, UAHJ("Setheum Ukranian Hryvnia", 12) = 39, USDJ("Setheum US Dollar", 12) = 40, - VNDJ("Setheum Vietnamese Dong") = 41, - ZARJ("Setheum South African Rand", 12) = 42, + ZARJ("Setheum South African Rand", 12) = 41, // Foreign System Currencies (Alphabetical Order) RENBTC("renBTC", 8) = 43, /// Ends at 85 (41 places left yet reserved for Setheum Network) @@ -271,8 +270,7 @@ create_currency_id! { JTZS("Neom Tanzanian Shilling", 12) = 124, JUAH("Neom Ukranian Hryvnia", 12) = 125, JUSD("Neom US Dollar", 12) = 126, - JVND("Neom Vietnamese Dong") = 127, - JZAR("Neom South African Rand", 12) = 128, + JZAR("Neom South African Rand", 12) = 127, // Foreign System Currencies (Alphabetical Order) RENBTC("renBTC", 8) = 4, /// Ends at 170 (41 places left yet reserved for Neom Network) @@ -318,14 +316,13 @@ create_currency_id! { TZS("Fiat Tanzanian Shilling", 12) = 206, UAH("Fiat Ukranian Hryvnia", 12) = 207, USD("Fiat US Dollar", 12) = 208, - VND("Fiat Vietnamese Dong") = 209, - ZAR("Fiat South African Rand", 12) = 210, - KWD("Fiat Kuwaiti Dinar", 12) = 211, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - JOD("Fiat Jordanian Dinar", 12) = 212, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - BHD("Fiat Bahraini Dirham", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - KYD("Fiat Cayman Islands Dollar", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - OMR("Fiat Omani Riyal", 12) = 215, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - GIP("Fiat Gibraltar Pound", 12) = 216, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + ZAR("Fiat South African Rand", 12) = 209, + KWD("Fiat Kuwaiti Dinar", 12) = 210, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + JOD("Fiat Jordanian Dinar", 12) = 211, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + BHD("Fiat Bahraini Dirham", 12) = 212, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + KYD("Fiat Cayman Islands Dollar", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + OMR("Fiat Omani Riyal", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + GIP("Fiat Gibraltar Pound", 12) = 215, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. /// Ends at 255 (39 places left yet reserved for Fiat-Pegs). /// /// A total of 255 (with a total of 121 places left yet reserved) From 040f3d54767348cee62c7ba1565282965a6c44ab Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 11:35:38 +0800 Subject: [PATCH 52/83] remove UAH and re-index currencies --- primitives/src/currency.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index 01067616c..41ef134d7 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -219,11 +219,10 @@ create_currency_id! { TRYJ("Setheum Turkish Lira", 12) = 36, TWDJ("Setheum New Taiwan Dollar", 12) = 37, TZSJ("Setheum Tanzanian Shilling", 12) = 38, - UAHJ("Setheum Ukranian Hryvnia", 12) = 39, - USDJ("Setheum US Dollar", 12) = 40, - ZARJ("Setheum South African Rand", 12) = 41, + USDJ("Setheum US Dollar", 12) = 39, + ZARJ("Setheum South African Rand", 12) = 40, // Foreign System Currencies (Alphabetical Order) - RENBTC("renBTC", 8) = 43, + RENBTC("renBTC", 8) = 41, /// Ends at 85 (41 places left yet reserved for Setheum Network) /// Neom Network >---------------------->> @@ -268,11 +267,10 @@ create_currency_id! { JTRY("Neom Turkish Lira", 12) = 122, JTWD("Neom New Taiwan Dollar", 12) = 123, JTZS("Neom Tanzanian Shilling", 12) = 124, - JUAH("Neom Ukranian Hryvnia", 12) = 125, - JUSD("Neom US Dollar", 12) = 126, - JZAR("Neom South African Rand", 12) = 127, + JUSD("Neom US Dollar", 12) = 125, + JZAR("Neom South African Rand", 12) = 126, // Foreign System Currencies (Alphabetical Order) - RENBTC("renBTC", 8) = 4, + RENBTC("renBTC", 8) = 127, /// Ends at 170 (41 places left yet reserved for Neom Network) /// Fiat Currencies as Pegs @@ -314,15 +312,14 @@ create_currency_id! { TRY("Fiat Turkish Lira", 12) = 204, TWD("Fiat New Taiwan Dollar", 12) = 205, TZS("Fiat Tanzanian Shilling", 12) = 206, - UAH("Fiat Ukranian Hryvnia", 12) = 207, - USD("Fiat US Dollar", 12) = 208, - ZAR("Fiat South African Rand", 12) = 209, - KWD("Fiat Kuwaiti Dinar", 12) = 210, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - JOD("Fiat Jordanian Dinar", 12) = 211, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - BHD("Fiat Bahraini Dirham", 12) = 212, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - KYD("Fiat Cayman Islands Dollar", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - OMR("Fiat Omani Riyal", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. - GIP("Fiat Gibraltar Pound", 12) = 215, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + USD("Fiat US Dollar", 12) = 207, + ZAR("Fiat South African Rand", 12) = 208, + KWD("Fiat Kuwaiti Dinar", 12) = 209, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + JOD("Fiat Jordanian Dinar", 12) = 210, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + BHD("Fiat Bahraini Dirham", 12) = 211, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + KYD("Fiat Cayman Islands Dollar", 12) = 212, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + OMR("Fiat Omani Riyal", 12) = 213, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. + GIP("Fiat Gibraltar Pound", 12) = 214, // part of the Setter pegs, not having single settcurrencies they peg like the rest of the fiats here. /// Ends at 255 (39 places left yet reserved for Fiat-Pegs). /// /// A total of 255 (with a total of 121 places left yet reserved) From faed22a2d036ab634f2b17bc314097be48d3b3fc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 11:51:34 +0800 Subject: [PATCH 53/83] Remove ARS and UAH --- lib-serml/prices/src/mock.rs | 14 -------------- lib-serml/serp-treasury/src/mock.rs | 4 ---- lib-serml/setters-manager/src/mock.rs | 6 ------ lib-serml/settmint-engine/src/mock.rs | 6 ------ lib-serml/settway/src/mock.rs | 4 ---- 5 files changed, 34 deletions(-) diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index 95ad66578..a3211c9f6 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -45,7 +45,6 @@ pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); -pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); @@ -81,7 +80,6 @@ pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); -pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); @@ -93,7 +91,6 @@ CurrencyId::DexShare(DexShare::Token(TokenSymbol::USDJ), DexShare::Token(TokenSy // Currencies constants - FiatCurrencyIds (CurrencyId/TokenSymbol) pub const AED: CurrencyId = CurrencyId::Token(TokenSymbol::AED); -pub const ARS: CurrencyId = CurrencyId::Token(TokenSymbol::ARS); pub const AUD: CurrencyId = CurrencyId::Token(TokenSymbol::AUD); pub const BRL: CurrencyId = CurrencyId::Token(TokenSymbol::BRL); pub const CAD: CurrencyId = CurrencyId::Token(TokenSymbol::CAD); @@ -129,7 +126,6 @@ pub const THB: CurrencyId = CurrencyId::Token(TokenSymbol::THB); pub const TRY: CurrencyId = CurrencyId::Token(TokenSymbol::TRY); pub const TWD: CurrencyId = CurrencyId::Token(TokenSymbol::TWD); pub const TZS: CurrencyId = CurrencyId::Token(TokenSymbol::TZS); -pub const UAH: CurrencyId = CurrencyId::Token(TokenSymbol::UAH); pub const USD: CurrencyId = CurrencyId::Token(TokenSymbol::USD); pub const ZAR: CurrencyId = CurrencyId::Token(TokenSymbol::ZAR); pub const KWD: CurrencyId = CurrencyId::Token(TokenSymbol::KWD); @@ -271,12 +267,7 @@ parameter_type_with_key! { parameter_type_with_key! { pub PegCurrencyIds: |_currency_id: CurrencyId| -> CurrencyId { match currency_id { - &USDJ => &USD, - &GBPJ => &GBP, - &EURJ => &EUR, - &CHFJ => &CHF, &AEDJ => &AED, - &ARSJ => &ARS, &AUDJ => &AUD, &BRLJ => &BRL, &CADJ => &CAD, @@ -312,7 +303,6 @@ parameter_type_with_key! { &TRYJ => &TRY, &TWDJ => &TWD, &TZSJ => &TZS, - &UAHJ => &UAH, &USDJ => &USD, &ZARJ => &ZAR, _ => None, @@ -353,7 +343,6 @@ parameter_types! { pub StableCurrencyIds: Vec = vec![ SETT, AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -389,13 +378,11 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; pub FiatCurrencyIds: Vec = vec![ AED, - ARS, AUD, BRL, CAD, @@ -431,7 +418,6 @@ parameter_types! { TRY, TWD, TZS, - UAH, USD, ZAR, KWD, diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index ff37d9a01..0376d10b1 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -43,7 +43,6 @@ pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); -pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); @@ -79,7 +78,6 @@ pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); -pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); @@ -232,7 +230,6 @@ parameter_types! { pub StableCurrencyIds: Vec = vec![ SETT, AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -268,7 +265,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index caed309b2..315bfdd31 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -44,7 +44,6 @@ pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); -pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); @@ -80,7 +79,6 @@ pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); -pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); @@ -205,7 +203,6 @@ parameter_types! { pub StableCurrencyIds: Vec = vec![ SETT, AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -241,7 +238,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; @@ -307,7 +303,6 @@ impl StandardValidator for MockStandard parameter_types! { pub StandardCurrencyIds: Vec = vec![ AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -343,7 +338,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index f1a69c5c6..9fcfed01d 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -45,7 +45,6 @@ pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); -pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); @@ -81,7 +80,6 @@ pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); -pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); @@ -243,7 +241,6 @@ parameter_types! { pub StableCurrencyIds: Vec = vec![ SETT, AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -279,7 +276,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; @@ -338,7 +334,6 @@ ord_parameter_types! { parameter_types! { pub StandardCurrencyIds: Vec = vec![ AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -374,7 +369,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index eaed23b15..3d461ba9e 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -192,7 +192,6 @@ parameter_types! { pub StableCurrencyIds: Vec = vec![ SETT, AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -228,7 +227,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; @@ -265,7 +263,6 @@ impl serp_treasury::Config for Runtime { parameter_types! { pub StandardCurrencyIds: Vec = vec![ AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -301,7 +298,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; From 120874078651a9a0304e51325b93f7282b5b1854 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 11:52:00 +0800 Subject: [PATCH 54/83] Remove ARS and UAH --- lib-serml/serp-auction/src/mock.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index a6c4045e7..b5955861e 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -47,7 +47,6 @@ pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); pub const SDEX: CurrencyId = CurrencyId::Token(TokenSymbol::SDEX); pub const SETT: CurrencyId = CurrencyId::Token(TokenSymbol::SETT); pub const AEDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AEDJ); -pub const ARSJ: CurrencyId = CurrencyId::Token(TokenSymbol::ARSJ); pub const AUDJ: CurrencyId = CurrencyId::Token(TokenSymbol::AUDJ); pub const BRLJ: CurrencyId = CurrencyId::Token(TokenSymbol::BRLJ); pub const CADJ: CurrencyId = CurrencyId::Token(TokenSymbol::CADJ); @@ -83,7 +82,6 @@ pub const THBJ: CurrencyId = CurrencyId::Token(TokenSymbol::THBJ); pub const TRYJ: CurrencyId = CurrencyId::Token(TokenSymbol::TRYJ); pub const TWDJ: CurrencyId = CurrencyId::Token(TokenSymbol::TWDJ); pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); -pub const UAHJ: CurrencyId = CurrencyId::Token(TokenSymbol::UAHJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); @@ -153,7 +151,6 @@ parameter_types! { pub StableCurrencyIds: Vec = vec![ SETT, AEDJ, - ARSJ, AUDJ, BRLJ, CADJ, @@ -189,7 +186,6 @@ parameter_types! { TRYJ, TWDJ, TZSJ, - UAHJ, USDJ, ZARJ, ]; From 4603327b339dd7139841fc98c6f037f9ca30f413 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 12:11:00 +0800 Subject: [PATCH 55/83] fix rename weights and benchmarking and rename setter position in settway --- lib-serml/settway/src/lib.rs | 8 ++++---- lib-serml/settway/src/tests.rs | 12 ++++++------ lib-serml/settway/src/weights.rs | 12 ++++++------ ...setheum_settmint_treasury.rs => serp_treasury.rs} | 0 ...setheum_auction_manager.rs => setheum_auction.rs} | 0 .../neom/src/weights/{setheum_serp.rs => settway.rs} | 4 ++-- runtime/newrome/src/benchmarking/mod.rs | 3 +-- .../{settmint_treasury.rs => serp_treasury.rs} | 0 .../newrome/src/benchmarking/{serp.rs => settway.rs} | 12 ++++++------ ...setheum_settmint_treasury.rs => serp_treasury.rs} | 0 ...setheum_auction_manager.rs => setheum_auction.rs} | 0 .../src/weights/{setheum_serp.rs => settway.rs} | 4 ++-- ...setheum_settmint_treasury.rs => serp_treasury.rs} | 0 ...setheum_auction_manager.rs => setheum_auction.rs} | 0 .../src/weights/{setheum_serp.rs => settway.rs} | 4 ++-- 15 files changed, 29 insertions(+), 30 deletions(-) rename runtime/neom/src/weights/{setheum_settmint_treasury.rs => serp_treasury.rs} (100%) rename runtime/neom/src/weights/{setheum_auction_manager.rs => setheum_auction.rs} (100%) rename runtime/neom/src/weights/{setheum_serp.rs => settway.rs} (96%) rename runtime/newrome/src/benchmarking/{settmint_treasury.rs => serp_treasury.rs} (100%) rename runtime/newrome/src/benchmarking/{serp.rs => settway.rs} (96%) rename runtime/newrome/src/weights/{setheum_settmint_treasury.rs => serp_treasury.rs} (100%) rename runtime/newrome/src/weights/{setheum_auction_manager.rs => setheum_auction.rs} (100%) rename runtime/newrome/src/weights/{setheum_serp.rs => settway.rs} (96%) rename runtime/setheum/src/weights/{setheum_settmint_treasury.rs => serp_treasury.rs} (100%) rename runtime/setheum/src/weights/{setheum_auction_manager.rs => setheum_auction.rs} (100%) rename runtime/setheum/src/weights/{setheum_serp.rs => settway.rs} (96%) diff --git a/lib-serml/settway/src/lib.rs b/lib-serml/settway/src/lib.rs index 2888aa1d7..20b4dc45d 100644 --- a/lib-serml/settway/src/lib.rs +++ b/lib-serml/settway/src/lib.rs @@ -115,9 +115,9 @@ pub mod module { /// amount of `currency_id` to caller according to the standard adjustment, /// negative means caller will payback some amount of `currency_id` (standard settcurrency) to /// Settmint according to to the standard adjustment. - #[pallet::weight(::WeightInfo::adjust_setter())] + #[pallet::weight(::WeightInfo::adjust_position())] #[transactional] - pub fn adjust_setter( + pub fn adjust_position( origin: OriginFor, currency_id: CurrencyId, reserve_adjustment: Amount, @@ -139,9 +139,9 @@ pub mod module { /// /// - `currency_id`: reserve currency id. /// - `from`: authorizer account - #[pallet::weight(::WeightInfo::transfer_settmint_from())] + #[pallet::weight(::WeightInfo::transfer_position_from())] #[transactional] - pub fn transfer_settmint_from( + pub fn transfer_position_from( origin: OriginFor, currency_id: CurrencyId, from: ::Source, diff --git a/lib-serml/settway/src/tests.rs b/lib-serml/settway/src/tests.rs index 27d706107..1eb222553 100644 --- a/lib-serml/settway/src/tests.rs +++ b/lib-serml/settway/src/tests.rs @@ -78,11 +78,11 @@ fn unauthorize_all_should_work() { } #[test] -fn transfer_settmint_from_should_work() { +fn transfer_position_from_should_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettwayModule::adjust_setter(Origin::signed(ALICE), SETT, 100, 50)); + assert_ok!(SettwayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettwayModule::transfer_settmint_from(Origin::signed(BOB), SETT, ALICE)); + assert_ok!(SettwayModule::transfer_position_from(Origin::signed(BOB), SETT, ALICE)); assert_eq!(SettersManagerModule::positions(SETT, BOB).reserve, 100); assert_eq!(SettersManagerModule::positions(SETT, BOB).standard, 50); }); @@ -92,16 +92,16 @@ fn transfer_settmint_from_should_work() { fn transfer_unauthorization_setters_should_not_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SettwayModule::transfer_settmint_from(Origin::signed(ALICE), SETT, BOB), + SettwayModule::transfer_position_from(Origin::signed(ALICE), SETT, BOB), Error::::NoAuthorization, ); }); } #[test] -fn adjust_setter_should_work() { +fn adjust_position_should_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettwayModule::adjust_setter(Origin::signed(ALICE), SETT, 100, 50)); + assert_ok!(SettwayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 100); assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 50); }); diff --git a/lib-serml/settway/src/weights.rs b/lib-serml/settway/src/weights.rs index 3dff5f473..44cccedc4 100644 --- a/lib-serml/settway/src/weights.rs +++ b/lib-serml/settway/src/weights.rs @@ -50,8 +50,8 @@ pub trait WeightInfo { fn authorize() -> Weight; fn unauthorize() -> Weight; fn unauthorize_all(c: u32, ) -> Weight; - fn adjust_setter() -> Weight; - fn transfer_settmint_from() -> Weight; + fn adjust_position() -> Weight; + fn transfer_position_from() -> Weight; } /// Weights for setheum_settway using the Setheum node and recommended hardware. @@ -71,12 +71,12 @@ impl WeightInfo for SetheumWeight { .saturating_add((1_018_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) } - fn adjust_setter() -> Weight { + fn adjust_position() -> Weight { (160_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_settmint_from() -> Weight { + fn transfer_position_from() -> Weight { (114_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) @@ -99,12 +99,12 @@ impl WeightInfo for () { .saturating_add((1_018_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) } - fn adjust_setter() -> Weight { + fn adjust_position() -> Weight { (160_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(24 as Weight)) .saturating_add(RocksDbWeight::get().writes(11 as Weight)) } - fn transfer_settmint_from() -> Weight { + fn transfer_position_from() -> Weight { (114_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(21 as Weight)) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) diff --git a/runtime/neom/src/weights/setheum_settmint_treasury.rs b/runtime/neom/src/weights/serp_treasury.rs similarity index 100% rename from runtime/neom/src/weights/setheum_settmint_treasury.rs rename to runtime/neom/src/weights/serp_treasury.rs diff --git a/runtime/neom/src/weights/setheum_auction_manager.rs b/runtime/neom/src/weights/setheum_auction.rs similarity index 100% rename from runtime/neom/src/weights/setheum_auction_manager.rs rename to runtime/neom/src/weights/setheum_auction.rs diff --git a/runtime/neom/src/weights/setheum_serp.rs b/runtime/neom/src/weights/settway.rs similarity index 96% rename from runtime/neom/src/weights/setheum_serp.rs rename to runtime/neom/src/weights/settway.rs index 3db5a2d91..c41796d33 100644 --- a/runtime/neom/src/weights/setheum_serp.rs +++ b/runtime/neom/src/weights/settway.rs @@ -56,12 +56,12 @@ impl setheum_settway::WeightInfo for WeightInfo { .saturating_add((1_680_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) } - fn adjust_setter() -> Weight { + fn adjust_position() -> Weight { (307_959_000 as Weight) .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_settmint_from() -> Weight { + fn transfer_position_from() -> Weight { (220_884_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) diff --git a/runtime/newrome/src/benchmarking/mod.rs b/runtime/newrome/src/benchmarking/mod.rs index 4c99f55c3..283122730 100644 --- a/runtime/newrome/src/benchmarking/mod.rs +++ b/runtime/newrome/src/benchmarking/mod.rs @@ -18,9 +18,8 @@ #![cfg(feature = "runtime-benchmarks")] -// module benchmarking +// module benchmarking (SERML) pub mod serp_auction; -pub mod settmint_engine; pub mod serp_treasury; pub mod dex; pub mod settway; diff --git a/runtime/newrome/src/benchmarking/settmint_treasury.rs b/runtime/newrome/src/benchmarking/serp_treasury.rs similarity index 100% rename from runtime/newrome/src/benchmarking/settmint_treasury.rs rename to runtime/newrome/src/benchmarking/serp_treasury.rs diff --git a/runtime/newrome/src/benchmarking/serp.rs b/runtime/newrome/src/benchmarking/settway.rs similarity index 96% rename from runtime/newrome/src/benchmarking/serp.rs rename to runtime/newrome/src/benchmarking/settway.rs index bc6037ede..29112a47f 100644 --- a/runtime/newrome/src/benchmarking/serp.rs +++ b/runtime/newrome/src/benchmarking/settway.rs @@ -74,9 +74,9 @@ runtime_benchmarks! { } }: _(RawOrigin::Signed(caller)) - // `adjust_setter`, best case: + // `adjust_position`, best case: // adjust both reserve and standard - adjust_setter { + adjust_position { let caller: AccountId = account("caller", 0, SEED); let currency_id: CurrencyId = ReserveCurrencyIds::get()[0]; let reserve_price = Price::one(); // 1 USD @@ -94,7 +94,7 @@ runtime_benchmarks! { SetheumOracle::feed_values(RawOrigin::Root.into(), vec![(currency_id, reserve_price)])?; }: _(RawOrigin::Signed(caller), currency_id, reserve_amount.try_into().unwrap(), standard_amount) - transfer_settmint_from { + transfer_position_from { let currency_id: CurrencyId = ReserveCurrencyIds::get()[0]; let sender: AccountId = account("sender", 0, SEED); let sender_lookup = Indices::unlookup(sender.clone()); @@ -116,7 +116,7 @@ runtime_benchmarks! { SetheumOracle::feed_values(RawOrigin::Root.into(), vec![(currency_id, Price::one())])?; // initialize sender's setter - Settway::adjust_setter( + Settway::adjust_position( RawOrigin::Signed(sender.clone()).into(), currency_id, reserve_amount.try_into().unwrap(), @@ -166,9 +166,9 @@ mod tests { } #[test] - fn test_adjust_setter() { + fn test_adjust_position() { new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_adjust_setter()); + assert_ok!(test_benchmark_adjust_position()); }); } } diff --git a/runtime/newrome/src/weights/setheum_settmint_treasury.rs b/runtime/newrome/src/weights/serp_treasury.rs similarity index 100% rename from runtime/newrome/src/weights/setheum_settmint_treasury.rs rename to runtime/newrome/src/weights/serp_treasury.rs diff --git a/runtime/newrome/src/weights/setheum_auction_manager.rs b/runtime/newrome/src/weights/setheum_auction.rs similarity index 100% rename from runtime/newrome/src/weights/setheum_auction_manager.rs rename to runtime/newrome/src/weights/setheum_auction.rs diff --git a/runtime/newrome/src/weights/setheum_serp.rs b/runtime/newrome/src/weights/settway.rs similarity index 96% rename from runtime/newrome/src/weights/setheum_serp.rs rename to runtime/newrome/src/weights/settway.rs index 75bb66200..fbccc8f22 100644 --- a/runtime/newrome/src/weights/setheum_serp.rs +++ b/runtime/newrome/src/weights/settway.rs @@ -56,12 +56,12 @@ impl setheum_settway::WeightInfo for WeightInfo { .saturating_add((1_762_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) } - fn adjust_setter() -> Weight { + fn adjust_position() -> Weight { (307_688_000 as Weight) .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_settmint_from() -> Weight { + fn transfer_position_from() -> Weight { (221_574_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) diff --git a/runtime/setheum/src/weights/setheum_settmint_treasury.rs b/runtime/setheum/src/weights/serp_treasury.rs similarity index 100% rename from runtime/setheum/src/weights/setheum_settmint_treasury.rs rename to runtime/setheum/src/weights/serp_treasury.rs diff --git a/runtime/setheum/src/weights/setheum_auction_manager.rs b/runtime/setheum/src/weights/setheum_auction.rs similarity index 100% rename from runtime/setheum/src/weights/setheum_auction_manager.rs rename to runtime/setheum/src/weights/setheum_auction.rs diff --git a/runtime/setheum/src/weights/setheum_serp.rs b/runtime/setheum/src/weights/settway.rs similarity index 96% rename from runtime/setheum/src/weights/setheum_serp.rs rename to runtime/setheum/src/weights/settway.rs index b08babc6a..e36da847a 100644 --- a/runtime/setheum/src/weights/setheum_serp.rs +++ b/runtime/setheum/src/weights/settway.rs @@ -56,12 +56,12 @@ impl setheum_settway::WeightInfo for WeightInfo { .saturating_add((900_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) } - fn adjust_setter() -> Weight { + fn adjust_position() -> Weight { (160_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(24 as Weight)) .saturating_add(T::DbWeight::get().writes(11 as Weight)) } - fn transfer_settmint_from() -> Weight { + fn transfer_position_from() -> Weight { (116_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(21 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) From 21f3797fae819a7a55a881a4a67c311bce0daaf2 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 12:19:18 +0800 Subject: [PATCH 56/83] setheum-evm-manager --- lib-serml/evm-manager/Cargo.toml | 6 +++--- lib-serml/evm-manager/src/mock.rs | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib-serml/evm-manager/Cargo.toml b/lib-serml/evm-manager/Cargo.toml index 9c3c45f71..7a753c69d 100644 --- a/lib-serml/evm-manager/Cargo.toml +++ b/lib-serml/evm-manager/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "module-evm-manager" +name = "setheum-evm-manager" version = "1.0.0" authors = ["Setheum-Labs"] edition = "2018" @@ -25,8 +25,8 @@ orml-currencies = { path = "../../orml/currencies" } orml-tokens = { path = "../../orml/tokens" } orml-traits = { path = "../../orml/traits" } orml-utilities = { path = "../../orml/utilities" } -module-evm = { path = "../evm" } -module-evm-bridge = { path = "../evm-bridge" } +setheum-evm = { path = "../evm" } +setheum-evm-bridge = { path = "../evm-bridge" } [features] default = ["std"] diff --git a/lib-serml/evm-manager/src/mock.rs b/lib-serml/evm-manager/src/mock.rs index 465487d99..a6bf98676 100644 --- a/lib-serml/evm-manager/src/mock.rs +++ b/lib-serml/evm-manager/src/mock.rs @@ -23,7 +23,7 @@ use super::*; use frame_support::{assert_ok, construct_runtime, ord_parameter_types, parameter_types}; use frame_system::EnsureSignedBy; -use module_support::{mocks::MockAddressMapping, AddressMapping}; +use setheum_support::{mocks::MockAddressMapping, AddressMapping}; use orml_traits::parameter_type_with_key; use primitives::{Amount, Balance, CurrencyId, TokenSymbol}; use sp_core::{bytes::from_hex, crypto::AccountId32, H256}; @@ -135,7 +135,7 @@ ord_parameter_types! { pub const DeploymentFee: u64 = 200; } -impl module_evm::Config for Runtime { +impl setheum_evm::Config for Runtime { type AddressMapping = MockAddressMapping; type Currency = Balances; type TransferAll = (); @@ -159,7 +159,7 @@ impl module_evm::Config for Runtime { type WeightInfo = (); } -impl module_evm_bridge::Config for Runtime { +impl setheum_evm_bridge::Config for Runtime { type EVM = EVM; } @@ -180,7 +180,7 @@ pub fn erc20_address_not_exists() -> EvmAddress { } pub fn alice() -> AccountId { - ::AddressMapping::get_account_id(&alice_evm_addr()) + ::AddressMapping::get_account_id(&alice_evm_addr()) } pub fn alice_evm_addr() -> EvmAddress { @@ -199,8 +199,8 @@ construct_runtime!( Tokens: orml_tokens::{Pallet, Storage, Event, Config}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Currencies: orml_currencies::{Pallet, Call, Event}, - EVM: module_evm::{Pallet, Config, Call, Storage, Event}, - EVMBridge: module_evm_bridge::{Pallet}, + EVM: setheum_evm::{Pallet, Config, Call, Storage, Event}, + EVMBridge: setheum_evm_bridge::{Pallet}, } ); @@ -214,7 +214,7 @@ pub fn deploy_contracts() { 10000 )); - let event = Event::module_evm(module_evm::Event::Created(erc20_address())); + let event = Event::setheum_evm(setheum_evm::Event::Created(erc20_address())); assert_eq!(System::events().iter().last().unwrap().event, event); assert_ok!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), erc20_address())); @@ -249,7 +249,7 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - module_evm::GenesisConfig::::default() + setheum_evm::GenesisConfig::::default() .assimilate_storage(&mut t) .unwrap(); From 2173cef3e3cc4289991f0cd349e6d568fb56a4ad Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 12:23:32 +0800 Subject: [PATCH 57/83] Setheum EVM --- lib-serml/evm/rpc/Cargo.toml | 2 +- lib-serml/evm/src/mock.rs | 6 +++--- lib-serml/evm/src/tests.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib-serml/evm/rpc/Cargo.toml b/lib-serml/evm/rpc/Cargo.toml index dc519accf..c851a9fe0 100644 --- a/lib-serml/evm/rpc/Cargo.toml +++ b/lib-serml/evm/rpc/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "evm-rpc" +name = "setheum-evm-rpc" version = "1.0.0" authors = ["Setheum Labs"] edition = "2018" diff --git a/lib-serml/evm/src/mock.rs b/lib-serml/evm/src/mock.rs index 1bef3af54..5f0953f47 100644 --- a/lib-serml/evm/src/mock.rs +++ b/lib-serml/evm/src/mock.rs @@ -33,7 +33,7 @@ use sp_runtime::{ use std::{collections::BTreeMap, str::FromStr}; use support::mocks::MockAddressMapping; -mod evm_mod { +mod setheum_evm { pub use super::super::*; } @@ -178,7 +178,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Storage, Config, Event}, - EVM: evm_mod::{Pallet, Config, Call, Storage, Event}, + EVM: setheum_evm::{Pallet, Config, Call, Storage, Event}, Tokens: orml_tokens::{Pallet, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Currencies: orml_currencies::{Pallet, Call, Event}, @@ -253,7 +253,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig::::default() .assimilate_storage(&mut t) .unwrap(); - evm_mod::GenesisConfig:: { + setheum_evm::GenesisConfig:: { accounts, treasury: Default::default(), } diff --git a/lib-serml/evm/src/tests.rs b/lib-serml/evm/src/tests.rs index b8ab24db2..2c10f9952 100644 --- a/lib-serml/evm/src/tests.rs +++ b/lib-serml/evm/src/tests.rs @@ -594,7 +594,7 @@ fn create_network_contract_works() { Pallet::::account_basic(&NetworkContractSource::get()).nonce, 2.into() ); - System::assert_last_event(Event::evm_mod(crate::Event::Created(H160::from_low_u64_be( + System::assert_last_event(Event::setheum_evm(crate::Event::Created(H160::from_low_u64_be( MIRRORED_NFT_ADDRESS_START, )))); assert_eq!(EVM::network_contract_index(), MIRRORED_NFT_ADDRESS_START + 1); @@ -666,7 +666,7 @@ fn should_transfer_maintainer() { result.address, bob() )); - System::assert_last_event(Event::evm_mod(crate::Event::TransferredMaintainer( + System::assert_last_event(Event::setheum_evm(crate::Event::TransferredMaintainer( result.address, bob(), ))); From 1b03c840266108ccaf0c13f7bd7488e199b5746e Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Fri, 25 Jun 2021 12:25:22 +0800 Subject: [PATCH 58/83] fix naming --- lib-serml/evm-manager/src/lib.rs | 2 +- lib-serml/evm-manager/src/tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib-serml/evm-manager/src/lib.rs b/lib-serml/evm-manager/src/lib.rs index 0b76dc3f6..e4370aa79 100644 --- a/lib-serml/evm-manager/src/lib.rs +++ b/lib-serml/evm-manager/src/lib.rs @@ -27,7 +27,7 @@ #![allow(clippy::unused_unit)] use frame_support::{ensure, pallet_prelude::*, require_transactional, traits::Currency}; -use module_support::{CurrencyIdMapping, EVMBridge, InvokeContext}; +use setheum_support::{CurrencyIdMapping, EVMBridge, InvokeContext}; use primitives::{ currency::TokenInfo, evm::{Erc20Info, EvmAddress}, diff --git a/lib-serml/evm-manager/src/tests.rs b/lib-serml/evm-manager/src/tests.rs index 8a8298617..6f7273633 100644 --- a/lib-serml/evm-manager/src/tests.rs +++ b/lib-serml/evm-manager/src/tests.rs @@ -65,7 +65,7 @@ fn set_erc20_mapping_works() { with_transaction_result(|| -> DispatchResult { EvmCurrencyIdMapping::::set_erc20_mapping(erc20_address_not_exists()) }), - module_evm_bridge::Error::::InvalidReturnValue, + setheum_evm_bridge::Error::::InvalidReturnValue, ); }); } From c23e38aebabca6a9c8faf4a10108b9e7487f7c42 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 00:32:40 +0800 Subject: [PATCH 59/83] update runtime common --- runtime/common/Cargo.toml | 18 +++++--- runtime/common/src/lib.rs | 95 ++++++++++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 057287c69..9bd247252 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -7,8 +7,10 @@ edition = "2018" [dependencies] # external dependencies static_assertions = "1.1.0" +num_enum = { version = "0.5.1", default-features = false } serde = { version = "1.0.101", optional = true, default-features = false } codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } +max-encoded-len = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4", default-features = false } # Substrate dependencies sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } @@ -23,23 +25,28 @@ orml-oracle = { path = "../../lib-openrml/oracle", default-features = false } orml-traits = { path = "../../lib-openrml/traits", default-features = false } # local dependencies +setheum-evm = { path = "../../lib-serml/evm", default-features = false } setheum-support = { path = "../../lib-serml/support", default-features = false } setheum-transaction-payment = { path = "../../lib-serml/transaction-payment", default-features = false } primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } [dev-dependencies] serde_json = "1.0.41" +sha3 = { version = "0.9.1" } hex-literal = "0.3.1" -sp-io = "3.0.0" -pallet-timestamp = "3.0.0" -pallet-balances = "3.0.0" -pallet-proxy = "3.0.0" -pallet-utility = "3.0.0" +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-proxy = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.4" } +setheum-service = { path = "../../node/setheum/service" } orml-tokens = { path = "../../lib-openrml/tokens" } orml-nft = { path = "../../lib-openrml/nft" } setheum-currencies = { path = "../../lib-serml/currencies" } setheum-nft = { path = "../../lib-serml/nft" } setheum-dex = { path = "../../lib-serml/dex" } +setheum-prices = { path = "../../lib-serml/prices" } +setheum-transaction-payment = { path = "../../lib-serml/transaction-payment" } [features] default = ["std"] @@ -58,3 +65,4 @@ std = [ "primitives/std", "setheum-transaction-payment/std", ] +with-ethereum-compatibility = [] diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 8ff624ebd..35b0b6069 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -23,19 +23,17 @@ use frame_support::{ parameter_types, weights::{ - constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_PER_SECOND}, + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_PER_MILLIS}, DispatchClass, Weight, }, }; use frame_system::limits; -pub use setheum_support::{ExchangeRate, PrecompileCallerFilter, Price, Rate, Ratio}; -use primitives::{Balance, CurrencyId}; -use sp_core::H160; -use sp_runtime::{ - traits::{Convert, Saturating}, - transaction_validity::TransactionPriority, - FixedPointNumber, FixedPointOperand, Perbill, +pub use module_support::{ExchangeRate, PrecompileCallerFilter, Price, Rate, Ratio}; +use primitives::{ + Balance, CurrencyId, PRECOMPILE_ADDRESS_START, PREDEPLOY_ADDRESS_START, SYSTEM_CONTRACT_ADDRESS_PREFIX, }; +use sp_core::H160; +use sp_runtime::{traits::Convert, transaction_validity::TransactionPriority, Perbill}; use static_assertions::const_assert; pub mod precompile; @@ -44,7 +42,49 @@ pub use precompile::{ StateRentPrecompile, }; pub use primitives::currency::{ - GetDecimals, DNAR, SETT, USDJ, NEOM, NSETT, JUSD, ROME, rSETT, rUSD, + TokenInfo, + DNAR, NEOM, + SDEX, HALAL, + SETT, NSETT, + AEDJ, JAED, + AUDJ, JAUD, + BRLJ, JBRL, + CADJ, JCAD, + CHFJ, JCHF, + CLPJ, JCLP, + CNYJ, JCNY, + COPJ, JCOP, + EURJ, JEUR, + GBPJ, JGBP, + HKDJ, JHKD, + HUFJ, JHUF, + IDRJ, JIDR, + JPYJ, JJPY, + KESJ, JKES, + KRWJ, JKRW, + KZTJ, JKZT, + MXNJ, JMXN, + MYRJ, JMYR, + NGNJ, JNGN, + NOKJ, JNOK, + NZDJ, JNZD, + PENJ, JPEN, + PHPJ, JPHP, + PKRJ, JPKR, + PLNJ, JPLN, + QARJ, JQAR, + RONJ, JRON, + RUBJ, JRUB, + SARJ, JSAR, + SEKJ, JSEK, + SGDJ, JSGD, + THBJ, JTHB, + TRYJ, JTRY, + TWDJ, JTWD, + TZSJ, JTZS, + USDJ, JUSD, + ZARJ, JZAR, + RENBTC, }; pub type TimeStampedPrice = orml_oracle::TimestampedValue; @@ -216,12 +256,42 @@ parameter_types! { ]; } +/// Check if the given `address` is a system contract. +/// +/// It's system contract if the address starts with SYSTEM_CONTRACT_ADDRESS_PREFIX. +pub fn is_system_contract(address: H160) -> bool { + address.as_bytes().starts_with(&SYSTEM_CONTRACT_ADDRESS_PREFIX) +} + +pub fn is_setheum_precompile(address: H160) -> bool { + address >= H160::from_low_u64_be(PRECOMPILE_ADDRESS_START) + && address < H160::from_low_u64_be(PREDEPLOY_ADDRESS_START) +} + +/// The call is allowed only if caller is a system contract. +pub struct SystemContractsFilter; +impl PrecompileCallerFilter for SystemContractsFilter { + fn is_allowed(caller: H160) -> bool { + is_system_contract(caller) + } +} + +/// Convert gas to weight +pub struct GasToWeight; +impl Convert for GasToWeight { + fn convert(a: u64) -> u64 { + // TODO: estimate this + a as Weight + } +} + +// TODO: somehow estimate this value. Start from a conservative value. pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_perthousand(25); /// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be /// used by Operational extrinsics. const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); -/// We allow for 2 seconds of compute with a 6 second average block time. -pub const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND; +/// We allow for 1 second of compute with a 3 second average block time. +pub const MAXIMUM_BLOCK_WEIGHT: Weight = 1 * WEIGHT_PER_SECOND; const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct()); @@ -262,8 +332,9 @@ parameter_types! { .saturating_sub(BlockExecutionWeight::get()); } +// TODO: make those const fn pub fn dollar(currency_id: CurrencyId) -> Balance { - 10u128.saturating_pow(currency_id.decimals()) + 10u128.saturating_pow(currency_id.decimals().expect("Not support Erc20 decimals").into()) } pub fn cent(currency_id: CurrencyId) -> Balance { From 5f8ac4db5feb36642d3ca81b63e3765cfcfb6e1c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 00:34:09 +0800 Subject: [PATCH 60/83] remove duplicate currency --- primitives/src/currency.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index 41ef134d7..c7b2fe28e 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -269,8 +269,6 @@ create_currency_id! { JTZS("Neom Tanzanian Shilling", 12) = 124, JUSD("Neom US Dollar", 12) = 125, JZAR("Neom South African Rand", 12) = 126, - // Foreign System Currencies (Alphabetical Order) - RENBTC("renBTC", 8) = 127, /// Ends at 170 (41 places left yet reserved for Neom Network) /// Fiat Currencies as Pegs From 5f5c2b04af2c92c0073e128c323c290a43c3186c Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 00:38:08 +0800 Subject: [PATCH 61/83] remove FeeRateMatrix --- runtime/common/src/lib.rs | 159 -------------------------------------- 1 file changed, 159 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 35b0b6069..166187d35 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -97,165 +97,6 @@ parameter_types! { pub const SerpAuctionManagerUnsignedPriority: TransactionPriority = TransactionPriority::max_value() - 1; } -parameter_types! { - pub FeeRateMatrix: [[Rate; 11]; 11] = [ - // when used_buffer_percent is 0% - [ - Rate::zero(), - Rate::saturating_from_rational(231487, 100000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(526013, 100000000), // 20% - Rate::saturating_from_rational(106148, 10000000), // 30% - Rate::saturating_from_rational(243221, 10000000), // 40% - Rate::saturating_from_rational(597041, 10000000), // 50% - Rate::saturating_from_rational(126422, 1000000), // 60% - Rate::saturating_from_rational(214815, 1000000), // 70% - Rate::saturating_from_rational(311560, 1000000), // 80% - Rate::saturating_from_rational(410715, 1000000), // 90% - Rate::saturating_from_rational(510500, 1000000), // 100% - ], - // when used_buffer_percent is 10% - [ - Rate::zero(), - Rate::saturating_from_rational(260999, 100000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(584962, 100000000), // 20% - Rate::saturating_from_rational(114942, 10000000), // 30% - Rate::saturating_from_rational(254703, 10000000), // 40% - Rate::saturating_from_rational(610531, 10000000), // 50% - Rate::saturating_from_rational(127866, 1000000), // 60% - Rate::saturating_from_rational(216285, 1000000), // 70% - Rate::saturating_from_rational(313035, 1000000), // 80% - Rate::saturating_from_rational(412191, 1000000), // 90% - Rate::saturating_from_rational(511976, 1000000), // 100% - ], - // when used_buffer_percent is 20% - [ - Rate::zero(), - Rate::saturating_from_rational(376267, 100000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(815202, 100000000), // 20% - Rate::saturating_from_rational(149288, 10000000), // 30% - Rate::saturating_from_rational(299546, 10000000), // 40% - Rate::saturating_from_rational(663214, 10000000), // 50% - Rate::saturating_from_rational(133503, 1000000), // 60% - Rate::saturating_from_rational(222025, 1000000), // 70% - Rate::saturating_from_rational(318797, 1000000), // 80% - Rate::saturating_from_rational(417955, 1000000), // 90% - Rate::saturating_from_rational(517741, 1000000), // 100% - ], - // when used_buffer_percent is 30% - [ - Rate::zero(), - Rate::saturating_from_rational(807626, 100000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(167679, 10000000), // 20% - Rate::saturating_from_rational(277809, 10000000), // 30% - Rate::saturating_from_rational(467319, 10000000), // 40% - Rate::saturating_from_rational(860304, 10000000), // 50% - Rate::saturating_from_rational(154595, 1000000), // 60% - Rate::saturating_from_rational(243507, 1000000), // 70% - Rate::saturating_from_rational(340357, 1000000), // 80% - Rate::saturating_from_rational(439528, 1000000), // 90% - Rate::saturating_from_rational(539315, 1000000), // 100% - ], - // when used_buffer_percent is 40% - [ - Rate::zero(), - Rate::saturating_from_rational(219503, 10000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(444770, 10000000), // 20% - Rate::saturating_from_rational(691029, 10000000), // 30% - Rate::saturating_from_rational(100646, 1000000), // 40% - Rate::saturating_from_rational(149348, 1000000), // 50% - Rate::saturating_from_rational(222388, 1000000), // 60% - Rate::saturating_from_rational(312586, 1000000), // 70% - Rate::saturating_from_rational(409701, 1000000), // 80% - Rate::saturating_from_rational(508916, 1000000), // 90% - Rate::saturating_from_rational(608707, 1000000), // 100% - ], - // when used_buffer_percent is 50% - [ - Rate::zero(), - Rate::saturating_from_rational(511974, 10000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(102871, 1000000), // 20% - Rate::saturating_from_rational(156110, 1000000), // 30% - Rate::saturating_from_rational(213989, 1000000), // 40% - Rate::saturating_from_rational(282343, 1000000), // 50% - Rate::saturating_from_rational(364989, 1000000), // 60% - Rate::saturating_from_rational(458110, 1000000), // 70% - Rate::saturating_from_rational(555871, 1000000), // 80% - Rate::saturating_from_rational(655197, 1000000), // 90% - Rate::saturating_from_rational(755000, 1000000), // 100% - ], - // when used_buffer_percent is 60% - [ - Rate::zero(), - Rate::saturating_from_rational(804354, 10000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(161193, 1000000), // 20% - Rate::saturating_from_rational(242816, 1000000), // 30% - Rate::saturating_from_rational(326520, 1000000), // 40% - Rate::saturating_from_rational(414156, 1000000), // 50% - Rate::saturating_from_rational(506779, 1000000), // 60% - Rate::saturating_from_rational(603334, 1000000), // 70% - Rate::saturating_from_rational(701969, 1000000), // 80% - Rate::saturating_from_rational(801470, 1000000), // 90% - Rate::saturating_from_rational(901293, 1000000), // 100% - ], - // when used_buffer_percent is 70% - [ - Rate::zero(), - Rate::saturating_from_rational(942895, 10000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(188758, 1000000), // 20% - Rate::saturating_from_rational(283590, 1000000), // 30% - Rate::saturating_from_rational(379083, 1000000), // 40% - Rate::saturating_from_rational(475573, 1000000), // 50% - Rate::saturating_from_rational(573220, 1000000), // 60% - Rate::saturating_from_rational(671864, 1000000), // 70% - Rate::saturating_from_rational(771169, 1000000), // 80% - Rate::saturating_from_rational(870838, 1000000), // 90% - Rate::saturating_from_rational(970685, 1000000), // 100% - ], - // when used_buffer_percent is 80% - [ - Rate::zero(), - Rate::saturating_from_rational(985811, 10000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(197241, 1000000), // 20% - Rate::saturating_from_rational(296017, 1000000), // 30% - Rate::saturating_from_rational(394949, 1000000), // 40% - Rate::saturating_from_rational(494073, 1000000), // 50% - Rate::saturating_from_rational(593401, 1000000), // 60% - Rate::saturating_from_rational(692920, 1000000), // 70% - Rate::saturating_from_rational(792596, 1000000), // 80% - Rate::saturating_from_rational(892388, 1000000), // 90% - Rate::saturating_from_rational(992259, 1000000), // 100% - ], - // when used_buffer_percent is 90% - [ - Rate::zero(), - Rate::saturating_from_rational(997132, 10000000), // when demand_in_available_percent is 10% - Rate::saturating_from_rational(199444, 1000000), // 20% - Rate::saturating_from_rational(299194, 1000000), // 30% - Rate::saturating_from_rational(398965, 1000000), // 40% - Rate::saturating_from_rational(498757, 1000000), // 50% - Rate::saturating_from_rational(598570, 1000000), // 60% - Rate::saturating_from_rational(698404, 1000000), // 70% - Rate::saturating_from_rational(798259, 1000000), // 80% - Rate::saturating_from_rational(898132, 1000000), // 90% - Rate::saturating_from_rational(998024, 1000000), // 100% - ], - // when used_buffer_percent is 100% - [ - Rate::zero(), - Rate::one(), // when demand_in_available_percent is 10% - Rate::one(), // 20% - Rate::one(), // 30% - Rate::one(), // 40% - Rate::one(), // 50% - Rate::one(), // 60% - Rate::one(), // 70% - Rate::one(), // 80% - Rate::one(), // 90% - Rate::one(), // 100% - ], - ]; -} - /// Check if the given `address` is a system contract. /// /// It's system contract if the address starts with SYSTEM_CONTRACT_ADDRESS_PREFIX. From 30ae1ab2e47a400eb53c18cb488ce2713c8eae33 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 00:42:50 +0800 Subject: [PATCH 62/83] upda weights --- lib-serml/chainbridge/src/weights.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib-serml/chainbridge/src/weights.rs b/lib-serml/chainbridge/src/weights.rs index da01d0ee0..02c88170b 100644 --- a/lib-serml/chainbridge/src/weights.rs +++ b/lib-serml/chainbridge/src/weights.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Autogenerated weights for module_cdp_engine +//! Autogenerated weights for setheum-chainbridge //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-06-01, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] From aedd910199827a7413f853f0c080db89176c5039 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 00:50:33 +0800 Subject: [PATCH 63/83] setheum modules --- lib-serml/currencies/src/mock.rs | 4 ++-- lib-serml/currencies/src/weights.rs | 4 ++-- lib-serml/evm-accounts/src/lib.rs | 2 +- lib-serml/evm-manager/src/lib.rs | 2 +- lib-serml/evm-manager/src/mock.rs | 2 +- lib-serml/evm-manager/src/tests.rs | 2 +- lib-serml/nft/src/weights.rs | 4 ++-- lib-serml/transaction-payment/src/tests.rs | 4 ++-- runtime/common/src/lib.rs | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib-serml/currencies/src/mock.rs b/lib-serml/currencies/src/mock.rs index aac487a8f..f965c3c43 100644 --- a/lib-serml/currencies/src/mock.rs +++ b/lib-serml/currencies/src/mock.rs @@ -245,7 +245,7 @@ pub fn deploy_contracts() { 10000 )); - let event = Event::module_evm(module_evm::Event::Created(erc20_address())); + let event = Event::setheum_evm(setheum_evm::Event::Created(erc20_address())); assert_eq!(System::events().iter().last().unwrap().event, event); assert_ok!(EVM::deploy_free(Origin::signed(CouncilAccount::get()), erc20_address())); @@ -305,7 +305,7 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - module_evm::GenesisConfig::::default() + setheum_evm::GenesisConfig::::default() .assimilate_storage(&mut t) .unwrap(); diff --git a/lib-serml/currencies/src/weights.rs b/lib-serml/currencies/src/weights.rs index df7837faa..b3d01c45a 100644 --- a/lib-serml/currencies/src/weights.rs +++ b/lib-serml/currencies/src/weights.rs @@ -51,7 +51,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for module_currencies. +/// Weight functions needed for setheum_currencies. pub trait WeightInfo { fn transfer_non_native_currency() -> Weight; fn transfer_native_currency() -> Weight; @@ -60,7 +60,7 @@ pub trait WeightInfo { fn update_balance_native_currency_killing() -> Weight; } -/// Weights for module_currencies using the Setheum node and recommended hardware. +/// Weights for setheum_currencies using the Setheum node and recommended hardware. pub struct SetheumWeight(PhantomData); impl WeightInfo for SetheumWeight { fn transfer_non_native_currency() -> Weight { diff --git a/lib-serml/evm-accounts/src/lib.rs b/lib-serml/evm-accounts/src/lib.rs index 77c6aa158..e50d6229a 100644 --- a/lib-serml/evm-accounts/src/lib.rs +++ b/lib-serml/evm-accounts/src/lib.rs @@ -34,7 +34,7 @@ use frame_support::{ transactional, }; use frame_system::{ensure_signed, pallet_prelude::*}; -use module_support::AddressMapping; +use setheum_support::AddressMapping; use orml_traits::{currency::TransferAll, Handler}; use primitives::{evm::EvmAddress, AccountIndex}; use sp_core::{crypto::AccountId32, ecdsa}; diff --git a/lib-serml/evm-manager/src/lib.rs b/lib-serml/evm-manager/src/lib.rs index e4370aa79..a9acb0da2 100644 --- a/lib-serml/evm-manager/src/lib.rs +++ b/lib-serml/evm-manager/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum-Labs. +// Copyright (C) 2019-2021 Setheum-Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm-manager/src/mock.rs b/lib-serml/evm-manager/src/mock.rs index a6bf98676..3cfe218cc 100644 --- a/lib-serml/evm-manager/src/mock.rs +++ b/lib-serml/evm-manager/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum-Labs. +// Copyright (C) 2019-2021 Setheum-Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/evm-manager/src/tests.rs b/lib-serml/evm-manager/src/tests.rs index 6f7273633..670519356 100644 --- a/lib-serml/evm-manager/src/tests.rs +++ b/lib-serml/evm-manager/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Setheum. -// Copyright (C) 2020-2021 Setheum-Labs. +// Copyright (C) 2019-2021 Setheum-Labs. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify diff --git a/lib-serml/nft/src/weights.rs b/lib-serml/nft/src/weights.rs index c8ad40da1..742322f80 100644 --- a/lib-serml/nft/src/weights.rs +++ b/lib-serml/nft/src/weights.rs @@ -44,7 +44,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for module_nft. +/// Weight functions needed for setheum_nft. pub trait WeightInfo { fn create_class() -> Weight; fn mint(i: u32, ) -> Weight; @@ -54,7 +54,7 @@ pub trait WeightInfo { fn destroy_class() -> Weight; } -/// Weights for module_nft using the Setheum node and recommended hardware. +/// Weights for setheum_nft using the Setheum node and recommended hardware. pub struct SetheumWeight(PhantomData); impl WeightInfo for SetheumWeight { fn create_class() -> Weight { diff --git a/lib-serml/transaction-payment/src/tests.rs b/lib-serml/transaction-payment/src/tests.rs index 5e452c1fd..5ce4835cb 100644 --- a/lib-serml/transaction-payment/src/tests.rs +++ b/lib-serml/transaction-payment/src/tests.rs @@ -33,10 +33,10 @@ use orml_traits::MultiCurrency; use sp_runtime::{testing::TestXt, traits::One}; const CALL: &::Call = - &Call::Currencies(module_currencies::Call::transfer(BOB, SETT, 12)); + &Call::Currencies(setheum_currencies::Call::transfer(BOB, SETT, 12)); const CALL2: &::Call = - &Call::Currencies(module_currencies::Call::transfer_native_currency(BOB, 12)); + &Call::Currencies(setheum_currencies::Call::transfer_native_currency(BOB, 12)); const INFO: DispatchInfo = DispatchInfo { weight: 1000, diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 166187d35..c78045ab9 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -28,7 +28,7 @@ use frame_support::{ }, }; use frame_system::limits; -pub use module_support::{ExchangeRate, PrecompileCallerFilter, Price, Rate, Ratio}; +pub use setheum_support::{ExchangeRate, PrecompileCallerFilter, Price, Rate, Ratio}; use primitives::{ Balance, CurrencyId, PRECOMPILE_ADDRESS_START, PREDEPLOY_ADDRESS_START, SYSTEM_CONTRACT_ADDRESS_PREFIX, }; From 08d3168a20692904c01e47368714a1ee0677ecbd Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:08:43 +0800 Subject: [PATCH 64/83] update pallet_id --- lib-serml/dex/src/mock.rs | 2 +- lib-serml/incentives/src/mock.rs | 2 +- lib-serml/transaction-payment/src/mock.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib-serml/dex/src/mock.rs b/lib-serml/dex/src/mock.rs index c24ab25e4..e5649e37e 100644 --- a/lib-serml/dex/src/mock.rs +++ b/lib-serml/dex/src/mock.rs @@ -111,7 +111,7 @@ ord_parameter_types! { parameter_types! { pub const GetExchangeFee: (u32, u32) = (1, 100); pub const TradingPathLimit: u32 = 3; - pub const DexPalletId: PalletId = PalletId(*b"dnr/sdex"); + pub const DexPalletId: PalletId = PalletId(*b"set/sdex"); } impl Config for Runtime { diff --git a/lib-serml/incentives/src/mock.rs b/lib-serml/incentives/src/mock.rs index 0388450ae..25d5e1c8e 100644 --- a/lib-serml/incentives/src/mock.rs +++ b/lib-serml/incentives/src/mock.rs @@ -295,7 +295,7 @@ parameter_types! { CHFJ, // Setheum CHF (Swiss Franc stablecoin) GIPJ, // Setheum GIP (Gibraltar Pound stablecoin) ]; - pub const IncentivesPalletId: PalletId = PalletId(*b"dnr/inct"); + pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); } ord_parameter_types! { diff --git a/lib-serml/transaction-payment/src/mock.rs b/lib-serml/transaction-payment/src/mock.rs index 969f6df3b..dcc70b9c1 100644 --- a/lib-serml/transaction-payment/src/mock.rs +++ b/lib-serml/transaction-payment/src/mock.rs @@ -144,7 +144,7 @@ ord_parameter_types! { } parameter_types! { - pub const DexPalletId: PalletId = PalletId(*b"dnr/sdex"); + pub const DexPalletId: PalletId = PalletId(*b"set/sdex"); pub const GetExchangeFee: (u32, u32) = (0, 100); pub const TradingPathLimit: u32 = 3; pub EnabledTradingPairs : Vec = vec![TradingPair::new(SETT, DNAR), TradingPair::new(SETT, DOT)]; From 51ab5770bd70a6327a3d8509a33f053ebea6a0e5 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:18:25 +0800 Subject: [PATCH 65/83] TODO: Update to add claim cashdrop - `claim: bool` --- lib-serml/currencies/src/lib.rs | 11 +++++++++++ lib-serml/evm-bridge/src/lib.rs | 1 + 2 files changed, 12 insertions(+) diff --git a/lib-serml/currencies/src/lib.rs b/lib-serml/currencies/src/lib.rs index 1abcc6dea..f3779b826 100644 --- a/lib-serml/currencies/src/lib.rs +++ b/lib-serml/currencies/src/lib.rs @@ -125,6 +125,7 @@ pub mod module { #[pallet::call] impl Pallet { + // TODO: Update to add "claim_cashdrop" using `claim: bool` /// Transfer some balance to another account under `currency_id`. /// /// The dispatch origin for this call must be `Signed` by the @@ -143,6 +144,7 @@ pub mod module { } /// Transfer some native currency to another account. + // TODO: Update to add "claim_cashdrop" using `claim: bool` /// /// The dispatch origin for this call must be `Signed` by the /// transactor. @@ -260,6 +262,7 @@ impl MultiCurrency for Pallet { } } + // TODO: Update to add "claim_cashdrop" using `claim: bool` fn transfer( currency_id: Self::CurrencyId, from: &T::AccountId, @@ -276,6 +279,7 @@ impl MultiCurrency for Pallet { let origin = T::EVMBridge::get_origin().unwrap_or_default(); let origin_address = T::AddressMapping::get_or_create_evm_address(&origin); let address = T::AddressMapping::get_or_create_evm_address(&to); + // TODO: Update to add "claim_cashdrop" using `claim: bool` T::EVMBridge::transfer( InvokeContext { contract, @@ -427,6 +431,10 @@ impl MultiReservableCurrency for Pallet { } } + // TODO: Update to add "claim_cashdrop" using `claim: bool` - + // TODO: - Maybe add Claim cashdrop to reserve too, since it - + // TODO: - transfers, to "claim_cashdrop" or make it false `claimed: bool = false`. + // TODO: - BUT I LEAN TOWARDS THE LATTER. fn reserve(currency_id: Self::CurrencyId, who: &T::AccountId, value: Self::Balance) -> DispatchResult { match currency_id { CurrencyId::Erc20(contract) => { @@ -584,6 +592,7 @@ where >::ensure_can_withdraw(GetCurrencyId::get(), who, amount) } + // TODO: Update to add "claim_cashdrop" using `claim: bool` - fn transfer(from: &T::AccountId, to: &T::AccountId, amount: Self::Balance) -> DispatchResult { as MultiCurrency>::transfer(GetCurrencyId::get(), from, to, amount) } @@ -716,6 +725,7 @@ where Currency::ensure_can_withdraw(who, amount, WithdrawReasons::all(), new_balance) } + // TODO: Update to add "claim_cashdrop" using `claim: bool` - fn transfer(from: &AccountId, to: &AccountId, amount: Self::Balance) -> DispatchResult { Currency::transfer(from, to, amount, ExistenceRequirement::AllowDeath) } @@ -833,6 +843,7 @@ where } } + // TODO: Update to add "claim_cashdrop" using `claim: bool` - impl TransferAll for Pallet { #[transactional] fn transfer_all(source: &T::AccountId, dest: &T::AccountId) -> DispatchResult { diff --git a/lib-serml/evm-bridge/src/lib.rs b/lib-serml/evm-bridge/src/lib.rs index 3d36f5f93..3b3a68f43 100644 --- a/lib-serml/evm-bridge/src/lib.rs +++ b/lib-serml/evm-bridge/src/lib.rs @@ -152,6 +152,7 @@ impl EVMBridgeTrait, BalanceOf> for Pallet { .saturated_into::>()) } + // TODO: Update to add "claim_cashdrop" using `claim: bool` // Calls the transfer method on an ERC20 contract using the given context. fn transfer(context: InvokeContext, to: H160, value: BalanceOf) -> DispatchResult { // ERC20.transfer method hash From dfb11cf5fece890c98d2434ce38aff5d8bd28424 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:34:23 +0800 Subject: [PATCH 66/83] add currency precompile --- .../common/src/precompile/multicurrency.rs | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 runtime/common/src/precompile/multicurrency.rs diff --git a/runtime/common/src/precompile/multicurrency.rs b/runtime/common/src/precompile/multicurrency.rs new file mode 100644 index 000000000..98abd6d5d --- /dev/null +++ b/runtime/common/src/precompile/multicurrency.rs @@ -0,0 +1,195 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use frame_support::log; +use setheum_evm::{Context, ExitError, ExitSucceed, Precompile}; +use setheum_support::{AddressMapping as AddressMappingT, CurrencyIdMapping as CurrencyIdMappingT}; +use sp_core::U256; +use sp_std::{fmt::Debug, marker::PhantomData, prelude::*, result}; + +use orml_traits::MultiCurrency as MultiCurrencyT; + +use super::input::{Input, InputT}; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use primitives::{Balance, CurrencyId}; + +/// The `MultiCurrency` impl precompile. +/// +/// +/// `input` data starts with `action` and `currency_id`. +/// +/// Actions: +/// - Query total issuance. +/// - Query balance. Rest `input` bytes: `account_id`. +/// - Transfer. Rest `input` bytes: `from`, `to`, `amount`. +pub struct MultiCurrencyPrecompile( + PhantomData<(AccountId, AddressMapping, CurrencyIdMapping, MultiCurrency)>, +); + +#[derive(Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Action { + QueryName = 0x06fdde03, + QuerySymbol = 0x95d89b41, + QueryDecimals = 0x313ce567, + QueryTotalIssuance = 0x18160ddd, + QueryBalance = 0x70a08231, + Transfer = 0xbeabacc8, +} + +impl Precompile + for MultiCurrencyPrecompile +where + AccountId: Debug + Clone, + AddressMapping: AddressMappingT, + CurrencyIdMapping: CurrencyIdMappingT, + MultiCurrency: MultiCurrencyT, +{ + fn execute( + input: &[u8], + _target_gas: Option, + context: &Context, + ) -> result::Result<(ExitSucceed, Vec, u64), ExitError> { + //TODO: evaluate cost + + log::debug!(target: "evm", "multicurrency: input: {:?}", input); + + let input = Input::::new(input); + + let action = input.action()?; + let currency_id = CurrencyIdMapping::decode_evm_address(context.caller) + .ok_or_else(|| ExitError::Other("invalid currency id".into()))?; + + log::debug!(target: "evm", "multicurrency: currency id: {:?}", currency_id); + + match action { + Action::QueryName => { + let name = + CurrencyIdMapping::name(currency_id).ok_or_else(|| ExitError::Other("Get name failed".into()))?; + log::debug!(target: "evm", "multicurrency: name: {:?}", name); + + Ok((ExitSucceed::Returned, vec_u8_from_str(&name), 0)) + } + Action::QuerySymbol => { + let symbol = CurrencyIdMapping::symbol(currency_id) + .ok_or_else(|| ExitError::Other("Get symbol failed".into()))?; + log::debug!(target: "evm", "multicurrency: symbol: {:?}", symbol); + + Ok((ExitSucceed::Returned, vec_u8_from_str(&symbol), 0)) + } + Action::QueryDecimals => { + let decimals = CurrencyIdMapping::decimals(currency_id) + .ok_or_else(|| ExitError::Other("Get decimals failed".into()))?; + log::debug!(target: "evm", "multicurrency: decimals: {:?}", decimals); + + Ok((ExitSucceed::Returned, vec_u8_from_u8(decimals), 0)) + } + Action::QueryTotalIssuance => { + let total_issuance = vec_u8_from_balance(MultiCurrency::total_issuance(currency_id)); + log::debug!(target: "evm", "multicurrency: total issuance: {:?}", total_issuance); + + Ok((ExitSucceed::Returned, total_issuance, 0)) + } + Action::QueryBalance => { + let who = input.account_id_at(1)?; + log::debug!(target: "evm", "multicurrency: who: {:?}", who); + + let balance = vec_u8_from_balance(MultiCurrency::total_balance(currency_id, &who)); + log::debug!(target: "evm", "multicurrency: balance: {:?}", balance); + + Ok((ExitSucceed::Returned, balance, 0)) + } + // TODO: Update to add "claim_cashdrop" using `claim: bool` + Action::Transfer => { + let from = input.account_id_at(1)?; + let to = input.account_id_at(2)?; + let amount = input.balance_at(3)?; + + log::debug!(target: "evm", "multicurrency: from: {:?}", from); + log::debug!(target: "evm", "multicurrency: to: {:?}", to); + log::debug!(target: "evm", "multicurrency: amount: {:?}", amount); + + MultiCurrency::transfer(currency_id, &from, &to, amount).map_err(|e| { + let err_msg: &str = e.into(); + ExitError::Other(err_msg.into()) + })?; + + log::debug!(target: "evm", "multicurrency: transfer success!"); + + Ok((ExitSucceed::Returned, vec![], 0)) + } + } + } +} + +fn vec_u8_from_balance(balance: Balance) -> Vec { + let mut be_bytes = [0u8; 32]; + U256::from(balance).to_big_endian(&mut be_bytes[..]); + be_bytes.to_vec() +} + +fn vec_u8_from_u8(b: u8) -> Vec { + let mut be_bytes = [0u8; 32]; + U256::from(b).to_big_endian(&mut be_bytes[..]); + be_bytes.to_vec() +} + +fn vec_u8_from_str(b: &[u8]) -> Vec { + let mut be_bytes = [0u8; 32]; + U256::from_big_endian(b).to_big_endian(&mut be_bytes[..]); + be_bytes.to_vec() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::precompile::mock::get_function_selector; + + #[test] + fn function_selector_match() { + assert_eq!( + u32::from_be_bytes(get_function_selector("name()")), + Into::::into(Action::QueryName) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("symbol()")), + Into::::into(Action::QuerySymbol) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("decimals()")), + Into::::into(Action::QueryDecimals) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("totalSupply()")), + Into::::into(Action::QueryTotalIssuance) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("balanceOf(address)")), + Into::::into(Action::QueryBalance) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("transfer(address,address,uint256)")), + Into::::into(Action::Transfer) + ); + } +} From b3d8ffe1dd8ca41a69fed552dcb61692347a5831 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:34:33 +0800 Subject: [PATCH 67/83] add dex precompile --- runtime/common/src/precompile/dex.rs | 333 +++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 runtime/common/src/precompile/dex.rs diff --git a/runtime/common/src/precompile/dex.rs b/runtime/common/src/precompile/dex.rs new file mode 100644 index 000000000..b98ad5c3b --- /dev/null +++ b/runtime/common/src/precompile/dex.rs @@ -0,0 +1,333 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use super::input::{Input, InputT}; +use frame_support::log; +use setheum_evm::{Context, ExitError, ExitSucceed, Precompile}; +use setheum_support::{AddressMapping as AddressMappingT, CurrencyIdMapping as CurrencyIdMappingT, DEXManager}; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use primitives::{Balance, CurrencyId}; +use sp_core::U256; +use sp_std::{fmt::Debug, marker::PhantomData, prelude::*, result}; + +/// The `DEX` impl precompile. +/// +/// +/// `input` data starts with `action`. +/// +/// Actions: +/// - Get liquidity. Rest `input` bytes: `currency_id_a`, `currency_id_b`. +/// - Swap with exact supply. Rest `input` bytes: `who`, `currency_id_a`, `currency_id_b`, +/// `supply_amount`, `min_target_amount`. +pub struct DexPrecompile( + PhantomData<(AccountId, AddressMapping, CurrencyIdMapping, Dex)>, +); + +#[derive(Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Action { + GetLiquidityPool = 0xf4f31ede, + GetLiquidityTokenAddress = 0xffd73c4a, + GetSwapTargetAmount = 0x4d60beb1, + GetSwapSupplyAmount = 0xdbcd19a2, + SwapWithExactSupply = 0x579baa18, + SwapWithExactTarget = 0x9782ac81, + AddLiquidity = 0x67088D59, + RemoveLiquidity = 0x35315332, +} + +impl Precompile + for DexPrecompile +where + AccountId: Debug + Clone, + AddressMapping: AddressMappingT, + CurrencyIdMapping: CurrencyIdMappingT, + Dex: DEXManager, +{ + fn execute( + input: &[u8], + _target_gas: Option, + _context: &Context, + ) -> result::Result<(ExitSucceed, Vec, u64), ExitError> { + //TODO: evaluate cost + + log::debug!(target: "evm", "dex: input: {:?}", input); + + let input = Input::::new(input); + + let action = input.action()?; + + match action { + Action::GetLiquidityPool => { + let currency_id_a = input.currency_id_at(1)?; + let currency_id_b = input.currency_id_at(2)?; + log::debug!( + target: "evm", + "dex: get_liquidity_pool currency_id_a: {:?}, currency_id_b: {:?}", + currency_id_a, currency_id_b + ); + + let (balance_a, balance_b) = Dex::get_liquidity_pool(currency_id_a, currency_id_b); + + // output + let mut be_bytes = [0u8; 64]; + U256::from(balance_a).to_big_endian(&mut be_bytes[..32]); + U256::from(balance_b).to_big_endian(&mut be_bytes[32..64]); + + Ok((ExitSucceed::Returned, be_bytes.to_vec(), 0)) + } + Action::GetLiquidityTokenAddress => { + let currency_id_a = input.currency_id_at(1)?; + let currency_id_b = input.currency_id_at(2)?; + log::debug!( + target: "evm", + "dex: get_liquidity_token address currency_id_a: {:?}, currency_id_b: {:?}", + currency_id_a, currency_id_b + ); + + let value = Dex::get_liquidity_token_address(currency_id_a, currency_id_b) + .ok_or_else(|| ExitError::Other("Dex get_liquidity_token_address failed".into()))?; + + // output + let mut be_bytes = [0u8; 32]; + U256::from(value.as_bytes()).to_big_endian(&mut be_bytes[..32]); + + Ok((ExitSucceed::Returned, be_bytes.to_vec(), 0)) + } + Action::GetSwapTargetAmount => { + // solidity abi enocde array will add an offset at input[1] + let supply_amount = input.balance_at(2)?; + let path_len = input.u32_at(3)?; + let mut path = vec![]; + for i in 0..path_len { + path.push(input.currency_id_at((4 + i) as usize)?); + } + log::debug!( + target: "evm", + "dex: get_swap_target_amount path: {:?}, supply_amount: {:?}", + path, supply_amount + ); + + let value = Dex::get_swap_target_amount(&path, supply_amount, None) + .ok_or_else(|| ExitError::Other("Dex get_swap_target_amount failed".into()))?; + + // output + let mut be_bytes = [0u8; 32]; + U256::from(value).to_big_endian(&mut be_bytes[..32]); + + Ok((ExitSucceed::Returned, be_bytes.to_vec(), 0)) + } + Action::GetSwapSupplyAmount => { + // solidity abi enocde array will add an offset at input[1] + let target_amount = input.balance_at(2)?; + let path_len = input.u32_at(3)?; + let mut path = vec![]; + for i in 0..path_len { + path.push(input.currency_id_at((4 + i) as usize)?); + } + log::debug!( + target: "evm", + "dex: get_swap_supply_amount path: {:?}, target_amount: {:?}", + path, target_amount + ); + + let value = Dex::get_swap_supply_amount(&path, target_amount, None) + .ok_or_else(|| ExitError::Other("Dex get_swap_supply_amount failed".into()))?; + + // output + let mut be_bytes = [0u8; 32]; + U256::from(value).to_big_endian(&mut be_bytes[..32]); + + Ok((ExitSucceed::Returned, be_bytes.to_vec(), 0)) + } + Action::SwapWithExactSupply => { + let who = input.account_id_at(1)?; + // solidity abi enocde array will add an offset at input[2] + let supply_amount = input.balance_at(3)?; + let min_target_amount = input.balance_at(4)?; + let path_len = input.u32_at(5)?; + let mut path = vec![]; + for i in 0..path_len { + path.push(input.currency_id_at((6 + i) as usize)?); + } + log::debug!( + target: "evm", + "dex: swap_with_exact_supply who: {:?}, path: {:?}, supply_amount: {:?}, min_target_amount: {:?}", + who, path, supply_amount, min_target_amount + ); + + let value = + Dex::swap_with_exact_supply(&who, &path, supply_amount, min_target_amount, None).map_err(|e| { + let err_msg: &str = e.into(); + ExitError::Other(err_msg.into()) + })?; + + // output + let mut be_bytes = [0u8; 32]; + U256::from(value).to_big_endian(&mut be_bytes[..32]); + + Ok((ExitSucceed::Returned, be_bytes.to_vec(), 0)) + } + Action::SwapWithExactTarget => { + let who = input.account_id_at(1)?; + // solidity abi enocde array will add an offset at input[2] + let target_amount = input.balance_at(3)?; + let max_supply_amount = input.balance_at(4)?; + let path_len = input.u32_at(5)?; + let mut path = vec![]; + for i in 0..path_len { + path.push(input.currency_id_at((6 + i) as usize)?); + } + log::debug!( + target: "evm", + "dex: swap_with_exact_target who: {:?}, path: {:?}, target_amount: {:?}, max_supply_amount: {:?}", + who, path, target_amount, max_supply_amount + ); + + let value = + Dex::swap_with_exact_target(&who, &path, target_amount, max_supply_amount, None).map_err(|e| { + let err_msg: &str = e.into(); + ExitError::Other(err_msg.into()) + })?; + + // output + let mut be_bytes = [0u8; 32]; + U256::from(value).to_big_endian(&mut be_bytes[..32]); + + Ok((ExitSucceed::Returned, be_bytes.to_vec(), 0)) + } + Action::AddLiquidity => { + let who = input.account_id_at(1)?; + let currency_id_a = input.currency_id_at(2)?; + let currency_id_b = input.currency_id_at(3)?; + let max_amount_a = input.balance_at(4)?; + let max_amount_b = input.balance_at(5)?; + let min_share_increment = input.balance_at(6)?; + + log::debug!( + target: "evm", + "dex: add_liquidity who: {:?}, currency_id_a: {:?}, currency_id_b: {:?}, max_amount_a: {:?}, max_amount_b: {:?}, min_share_increment: {:?}", + who, currency_id_a, currency_id_b, max_amount_a, max_amount_b, min_share_increment, + ); + + Dex::add_liquidity( + &who, + currency_id_a, + currency_id_b, + max_amount_a, + max_amount_b, + min_share_increment, + false, + ) + .map_err(|e| { + let err_msg: &str = e.into(); + ExitError::Other(err_msg.into()) + })?; + + Ok((ExitSucceed::Returned, vec![], 0)) + } + Action::RemoveLiquidity => { + let who = input.account_id_at(1)?; + let currency_id_a = input.currency_id_at(2)?; + let currency_id_b = input.currency_id_at(3)?; + let remove_share = input.balance_at(4)?; + let min_withdrawn_a = input.balance_at(5)?; + let min_withdrawn_b = input.balance_at(6)?; + + log::debug!( + target: "evm", + "dex: remove_liquidity who: {:?}, currency_id_a: {:?}, currency_id_b: {:?}, remove_share: {:?}, min_withdrawn_a: {:?}, min_withdrawn_b: {:?}", + who, currency_id_a, currency_id_b, remove_share, min_withdrawn_a, min_withdrawn_b, + ); + + Dex::remove_liquidity( + &who, + currency_id_a, + currency_id_b, + remove_share, + min_withdrawn_a, + min_withdrawn_b, + false, + ) + .map_err(|e| { + let err_msg: &str = e.into(); + ExitError::Other(err_msg.into()) + })?; + + Ok((ExitSucceed::Returned, vec![], 0)) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::precompile::mock::get_function_selector; + + #[test] + fn function_selector_match() { + assert_eq!( + u32::from_be_bytes(get_function_selector("getLiquidityPool(address,address)")), + Into::::into(Action::GetLiquidityPool) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("getLiquidityTokenAddress(address,address)")), + Into::::into(Action::GetLiquidityTokenAddress) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("getSwapTargetAmount(address[],uint256)")), + Into::::into(Action::GetSwapTargetAmount) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("getSwapSupplyAmount(address[],uint256)")), + Into::::into(Action::GetSwapSupplyAmount) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector( + "swapWithExactSupply(address,address[],uint256,uint256)" + )), + Into::::into(Action::SwapWithExactSupply) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector( + "swapWithExactTarget(address,address[],uint256,uint256)" + )), + Into::::into(Action::SwapWithExactTarget) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector( + "addLiquidity(address,address,address,uint256,uint256,uint256)" + )), + Into::::into(Action::AddLiquidity) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector( + "removeLiquidity(address,address,address,uint256,uint256,uint256)" + )), + Into::::into(Action::RemoveLiquidity) + ); + } +} From 793f0f0ade2d3232d7c432bfb81dfbbd4a8ba701 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:34:44 +0800 Subject: [PATCH 68/83] add nft precompile --- runtime/common/src/precompile/nft.rs | 143 +++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 runtime/common/src/precompile/nft.rs diff --git a/runtime/common/src/precompile/nft.rs b/runtime/common/src/precompile/nft.rs new file mode 100644 index 000000000..e8e50c594 --- /dev/null +++ b/runtime/common/src/precompile/nft.rs @@ -0,0 +1,143 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use frame_support::log; +use setheum_evm::{Context, ExitError, ExitSucceed, Precompile}; +use setheum_support::{AddressMapping as AddressMappingT, CurrencyIdMapping as CurrencyIdMappingT}; +use sp_core::{H160, U256}; +use sp_std::{borrow::Cow, fmt::Debug, marker::PhantomData, prelude::*, result}; + +use orml_traits::NFT as NFTT; + +use super::input::{Input, InputT}; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use primitives::NFTBalance; + +/// The `NFT` impl precompile. +/// +/// `input` data starts with `action`. +/// +/// Actions: +/// - Query balance. Rest `input` bytes: `account_id`. +/// - Query owner. Rest `input` bytes: `class_id`, `token_id`. +/// - Transfer. Rest `input`bytes: `from`, `to`, `class_id`, `token_id`. +pub struct NFTPrecompile( + PhantomData<(AccountId, AddressMapping, CurrencyIdMapping, NFT)>, +); + +#[derive(Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Action { + QueryBalance = 0x70a08231, + QueryOwner = 0xd9dad80d, + Transfer = 0x411b252, +} + +impl Precompile + for NFTPrecompile +where + AccountId: Clone + Debug, + AddressMapping: AddressMappingT, + CurrencyIdMapping: CurrencyIdMappingT, + NFT: NFTT, +{ + fn execute( + input: &[u8], + _target_gas: Option, + _context: &Context, + ) -> result::Result<(ExitSucceed, Vec, u64), ExitError> { + log::debug!(target: "evm", "nft: input: {:?}", input); + + let input = Input::::new(input); + + let action = input.action()?; + + match action { + Action::QueryBalance => { + let who = input.account_id_at(1)?; + + log::debug!(target: "evm", "nft: query_balance who: {:?}", who); + + let balance = vec_u8_from_balance(NFT::balance(&who)); + + Ok((ExitSucceed::Returned, balance, 0)) + } + Action::QueryOwner => { + let class_id = input.u32_at(1)?; + let token_id = input.u64_at(2)?; + + log::debug!(target: "evm", "nft: query_owner class_id: {:?}, token_id: {:?}", class_id, token_id); + + let owner: H160 = if let Some(o) = NFT::owner((class_id, token_id)) { + AddressMapping::get_evm_address(&o).unwrap_or_else(|| AddressMapping::get_default_evm_address(&o)) + } else { + Default::default() + }; + + let mut address = [0u8; 32]; + address[12..].copy_from_slice(&owner.as_bytes().to_vec()); + + Ok((ExitSucceed::Returned, address.to_vec(), 0)) + } + Action::Transfer => { + let from = input.account_id_at(1)?; + let to = input.account_id_at(2)?; + + let class_id = input.u32_at(3)?; + let token_id = input.u64_at(4)?; + + log::debug!(target: "evm", "nft: transfer from: {:?}, to: {:?}, class_id: {:?}, token_id: {:?}", from, to, class_id, token_id); + + NFT::transfer(&from, &to, (class_id, token_id)) + .map_err(|e| ExitError::Other(Cow::Borrowed(e.into())))?; + + Ok((ExitSucceed::Returned, vec![], 0)) + } + } + } +} + +fn vec_u8_from_balance(b: NFTBalance) -> Vec { + let mut be_bytes = [0u8; 32]; + U256::from(b).to_big_endian(&mut be_bytes[..]); + be_bytes.to_vec() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::precompile::mock::get_function_selector; + + #[test] + fn function_selector_match() { + assert_eq!( + u32::from_be_bytes(get_function_selector("balanceOf(address)")), + Into::::into(Action::QueryBalance) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("ownerOf(uint256,uint256)")), + Into::::into(Action::QueryOwner) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("transfer(address,address,uint256,uint256)")), + Into::::into(Action::Transfer) + ); + } +} From c9e75b664467d5ab3c908304a11d03019faf7bbc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:34:58 +0800 Subject: [PATCH 69/83] add oracle precompile --- runtime/common/src/precompile/oracle.rs | 125 ++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 runtime/common/src/precompile/oracle.rs diff --git a/runtime/common/src/precompile/oracle.rs b/runtime/common/src/precompile/oracle.rs new file mode 100644 index 000000000..fc51f596b --- /dev/null +++ b/runtime/common/src/precompile/oracle.rs @@ -0,0 +1,125 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use frame_support::{log, sp_runtime::FixedPointNumber}; +use setheum_evm::{Context, ExitError, ExitSucceed, Precompile}; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use primitives::CurrencyId; +use sp_core::U256; +use sp_std::{fmt::Debug, marker::PhantomData, prelude::*, result}; + +use super::input::{Input, InputT}; +use setheum_support::{ + AddressMapping as AddressMappingT, CurrencyIdMapping as CurrencyIdMappingT, Price, PriceProvider as PriceProviderT, +}; + +/// The `Oracle` impl precompile. +/// +/// +/// `input` data starts with `action`. +/// +/// Actions: +/// - Get price. Rest `input` bytes: `currency_id`. +pub struct OraclePrecompile( + PhantomData<(AccountId, AddressMapping, CurrencyIdMapping, PriceProvider)>, +); + +#[derive(Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Action { + GetPrice = 0x41976e09, +} + +impl Precompile + for OraclePrecompile +where + AccountId: Debug + Clone, + AddressMapping: AddressMappingT, + CurrencyIdMapping: CurrencyIdMappingT, + PriceProvider: PriceProviderT, +{ + fn execute( + input: &[u8], + _target_gas: Option, + _context: &Context, + ) -> result::Result<(ExitSucceed, Vec, u64), ExitError> { + //TODO: evaluate cost + + log::debug!(target: "evm", "oracle: input: {:?}", input); + + let input = Input::::new(input); + + let action = input.action()?; + + match action { + Action::GetPrice => { + let currency_id = input.currency_id_at(1)?; + let mut price = PriceProvider::get_price(currency_id).unwrap_or_default(); + + let maybe_decimals = CurrencyIdMapping::decimals(currency_id); + let decimals = match maybe_decimals { + Some(decimals) => decimals, + None => { + // If the option is none, let price = 0 to return 0. + // Solidity should handle the situation of price 0. + price = Default::default(); + Default::default() + } + }; + + let maybe_adjustment_multiplier = 10u128.checked_pow((18 - decimals).into()); + let adjustment_multiplier = match maybe_adjustment_multiplier { + Some(adjustment_multiplier) => adjustment_multiplier, + None => { + // If the option is none, let price = 0 to return 0. + // Solidity should handle the situation of price 0. + price = Default::default(); + Default::default() + } + }; + + log::debug!(target: "evm", "oracle: getPrice currency_id: {:?}, price: {:?}, adjustment_multiplier: {:?}", currency_id, price, adjustment_multiplier); + Ok(( + ExitSucceed::Returned, + vec_u8_from_price(price, adjustment_multiplier), + 0, + )) + } + } + } +} + +fn vec_u8_from_price(price: Price, adjustment_multiplier: u128) -> Vec { + let mut be_bytes = [0u8; 32]; + U256::from(price.into_inner().wrapping_div(adjustment_multiplier)).to_big_endian(&mut be_bytes[..32]); + be_bytes.to_vec() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::precompile::mock::get_function_selector; + + #[test] + fn function_selector_match() { + assert_eq!( + u32::from_be_bytes(get_function_selector("getPrice(address)")), + Into::::into(Action::GetPrice) + ); + } +} From 6cd09c0717f04b2a68e6ae8679465a932dd943af Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:35:15 +0800 Subject: [PATCH 70/83] add schedule_call precompile --- .../common/src/precompile/schedule_call.rs | 313 ++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 runtime/common/src/precompile/schedule_call.rs diff --git a/runtime/common/src/precompile/schedule_call.rs b/runtime/common/src/precompile/schedule_call.rs new file mode 100644 index 000000000..c70eb3eb3 --- /dev/null +++ b/runtime/common/src/precompile/schedule_call.rs @@ -0,0 +1,313 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Disable the following lints +#![allow(clippy::type_complexity)] + +use frame_support::{ + dispatch::Dispatchable, + ensure, log, parameter_types, + traits::{ + schedule::{DispatchTime, Named as ScheduleNamed}, + Currency, IsType, OriginTrait, + }, +}; +use setheum_evm::{Context, ExitError, ExitSucceed, Precompile}; +use setheum_support::{AddressMapping as AddressMappingT, CurrencyIdMapping as CurrencyIdMappingT, TransactionPayment}; +use primitives::{Balance, BlockNumber}; +use sp_core::{H160, U256}; +use sp_runtime::RuntimeDebug; +use sp_std::{fmt::Debug, marker::PhantomData, prelude::*, result}; + +use super::input::{Input, InputT}; +use codec::{Decode, Encode}; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use pallet_scheduler::TaskAddress; + +parameter_types! { + pub storage EvmSchedulerNextID: u32 = 0u32; +} + +#[derive(RuntimeDebug, PartialEq, Encode, Decode)] +pub struct TaskInfo { + pub prefix: Vec, + pub id: u32, + pub sender: H160, + #[codec(compact)] + pub fee: Balance, +} + +/// The `ScheduleCall` impl precompile. +/// +/// +/// `input` data starts with `action`. +/// +/// Actions: +/// - ScheduleCall. Rest `input` bytes: `from`, `target`, `value`, `gas_limit`, `storage_limit`, +/// `min_delay`, `input_len`, `input_data`. +pub struct ScheduleCallPrecompile< + AccountId, + AddressMapping, + CurrencyIdMapping, + Scheduler, + ChargeTransactionPayment, + Call, + Origin, + PalletsOrigin, + Runtime, +>( + PhantomData<( + AccountId, + AddressMapping, + CurrencyIdMapping, + Scheduler, + ChargeTransactionPayment, + Call, + Origin, + PalletsOrigin, + Runtime, + )>, +); + +#[derive(Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Action { + Schedule = 0x64c91905, + Cancel = 0x93e32661, + Reschedule = 0x28302f34, +} + +type PalletBalanceOf = + <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + +impl< + AccountId, + AddressMapping, + CurrencyIdMapping, + Scheduler, + ChargeTransactionPayment, + Call, + Origin, + PalletsOrigin, + Runtime, + > Precompile + for ScheduleCallPrecompile< + AccountId, + AddressMapping, + CurrencyIdMapping, + Scheduler, + ChargeTransactionPayment, + Call, + Origin, + PalletsOrigin, + Runtime, + > where + AccountId: Debug + Clone, + AddressMapping: AddressMappingT, + CurrencyIdMapping: CurrencyIdMappingT, + Scheduler: ScheduleNamed>, + ChargeTransactionPayment: TransactionPayment, NegativeImbalanceOf>, + Call: Dispatchable + Debug + From>, + Origin: IsType<::Origin> + + OriginTrait, + PalletsOrigin: Into<::Origin> + From> + Clone, + Runtime: setheum_evm::Config + frame_system::Config, + PalletBalanceOf: IsType, +{ + fn execute( + input: &[u8], + _target_gas: Option, + _context: &Context, + ) -> result::Result<(ExitSucceed, Vec, u64), ExitError> { + log::debug!(target: "evm", "schedule call: input: {:?}", input); + + let input = Input::::new(input); + + let action = input.action()?; + + match action { + Action::Schedule => { + let from = input.evm_address_at(1)?; + let target = input.evm_address_at(2)?; + + let value = input.balance_at(3)?; + let gas_limit = input.u64_at(4)?; + let storage_limit = input.u32_at(5)?; + let min_delay = input.u32_at(6)?; + // solidity abi enocde bytes will add an length at input[7] + let input_len = input.u32_at(8)?; + let input_data = input.bytes_at(9, input_len as usize)?; + + log::debug!( + target: "evm", + "schedule call: from: {:?}, target: {:?}, value: {:?}, gas_limit: {:?}, storage_limit: {:?}, min_delay: {:?}, input_len: {:?}, input_data: {:?}", + from, + target, + value, + gas_limit, + storage_limit, + min_delay, + input_len, + input_data, + ); + + let mut _fee: PalletBalanceOf = Default::default(); + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + // reserve the transaction fee for gas_limit + use sp_runtime::traits::Convert; + let from_account = AddressMapping::get_account_id(&from); + let weight = ::GasToWeight::convert(gas_limit); + _fee = ChargeTransactionPayment::reserve_fee(&from_account, weight).map_err(|e| { + let err_msg: &str = e.into(); + ExitError::Other(err_msg.into()) + })?; + } + + let call = setheum_evm::Call::::scheduled_call( + from, + target, + input_data, + value.into(), + gas_limit, + storage_limit, + ) + .into(); + + let current_id = EvmSchedulerNextID::get(); + let next_id = current_id + .checked_add(1) + .ok_or_else(|| ExitError::Other("Scheduler next id overflow".into()))?; + EvmSchedulerNextID::set(&next_id); + + let task_id = TaskInfo { + prefix: b"ScheduleCall".to_vec(), + id: current_id, + sender: from, + fee: _fee.into(), + } + .encode(); + + log::debug!( + target: "evm", + "schedule call: task_id: {:?}", + task_id, + ); + + Scheduler::schedule_named( + task_id.clone(), + DispatchTime::After(min_delay), + None, + 0, + Origin::root().caller().clone(), + call, + ) + .map_err(|_| ExitError::Other("Schedule failed".into()))?; + + // add task_id len prefix + let mut task_id_with_len = [0u8; 96]; + U256::from(task_id.len()).to_big_endian(&mut task_id_with_len[0..32]); + task_id_with_len[32..32 + task_id.len()].copy_from_slice(&task_id[..]); + + Ok((ExitSucceed::Returned, task_id_with_len.to_vec(), 0)) + } + Action::Cancel => { + let from = input.evm_address_at(1)?; + // solidity abi enocde bytes will add an length at input[2] + let task_id_len = input.u32_at(3)?; + let task_id = input.bytes_at(4, task_id_len as usize)?; + + log::debug!( + target: "evm", + "cancel call: from: {:?}, task_id: {:?}", + from, + task_id, + ); + + let task_info = TaskInfo::decode(&mut &task_id[..]) + .map_err(|_| ExitError::Other("Decode task_id failed".into()))?; + ensure!(task_info.sender == from, ExitError::Other("NoPermission".into())); + + Scheduler::cancel_named(task_id).map_err(|_| ExitError::Other("Cancel schedule failed".into()))?; + + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + // unreserve the transaction fee for gas_limit + let from_account = AddressMapping::get_account_id(&from); + ChargeTransactionPayment::unreserve_fee(&from_account, task_info.fee.into()); + } + + Ok((ExitSucceed::Returned, vec![], 0)) + } + Action::Reschedule => { + let from = input.evm_address_at(1)?; + let min_delay = input.u32_at(2)?; + // solidity abi enocde bytes will add an length at input[3] + let task_id_len = input.u32_at(4)?; + let task_id = input.bytes_at(5, task_id_len as usize)?; + + log::debug!( + target: "evm", + "reschedule call: from: {:?}, task_id: {:?}, min_delay: {:?}", + from, + task_id, + min_delay, + ); + + let task_info = TaskInfo::decode(&mut &task_id[..]) + .map_err(|_| ExitError::Other("Decode task_id failed".into()))?; + ensure!(task_info.sender == from, ExitError::Other("NoPermission".into())); + + Scheduler::reschedule_named(task_id, DispatchTime::After(min_delay)).map_err(|e| { + let err_msg: &str = e.into(); + ExitError::Other(err_msg.into()) + })?; + + Ok((ExitSucceed::Returned, vec![], 0)) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::precompile::mock::get_function_selector; + + #[test] + fn function_selector_match() { + assert_eq!( + u32::from_be_bytes(get_function_selector( + "scheduleCall(address,address,uint256,uint256,uint256,bytes)" + )), + Into::::into(Action::Schedule) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("cancelCall(address,bytes)")), + Into::::into(Action::Cancel) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("rescheduleCall(address,uint256,bytes)")), + Into::::into(Action::Reschedule) + ); + } +} From dd38ea39e1e9511460d4ebf6a5e3e85069caf098 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:35:27 +0800 Subject: [PATCH 71/83] add state rent precompile --- runtime/common/src/precompile/state_rent.rs | 171 ++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 runtime/common/src/precompile/state_rent.rs diff --git a/runtime/common/src/precompile/state_rent.rs b/runtime/common/src/precompile/state_rent.rs new file mode 100644 index 000000000..7b6562481 --- /dev/null +++ b/runtime/common/src/precompile/state_rent.rs @@ -0,0 +1,171 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use frame_support::log; +use setheum_evm::{Context, ExitError, ExitSucceed, Precompile}; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use sp_core::U256; +use sp_std::{borrow::Cow, fmt::Debug, marker::PhantomData, prelude::*, result}; + +use setheum_support::{AddressMapping as AddressMappingT, CurrencyIdMapping as CurrencyIdMappingT, EVMStateRentTrait}; + +use super::input::{Input, InputT}; +use primitives::Balance; + +/// The `EVM` impl precompile. +/// +/// `input` data starts with `action`. +/// +/// Actions: +/// - QueryNewContractExtraBytes. +/// - QueryStorageDepositPerByte. +/// - QueryMaintainer. +/// - QueryDeveloperDeposit. +/// - QueryDeploymentFee. +/// - TransferMaintainer. Rest `input` bytes: `from`, `contract`, `new_maintainer`. +pub struct StateRentPrecompile( + PhantomData<(AccountId, AddressMapping, CurrencyIdMapping, EVM)>, +); + +#[derive(Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Action { + QueryNewContractExtraBytes = 0xa23e8b82, + QueryStorageDepositPerByte = 0x6e043998, + QueryMaintainer = 0x06ad1355, + QueryDeveloperDeposit = 0x68a18855, + QueryDeploymentFee = 0xf2cff57f, + TransferMaintainer = 0xee0d2e12, +} + +impl Precompile + for StateRentPrecompile +where + AccountId: Clone + Debug, + AddressMapping: AddressMappingT, + CurrencyIdMapping: CurrencyIdMappingT, + EVM: EVMStateRentTrait, +{ + fn execute( + input: &[u8], + _target_gas: Option, + _context: &Context, + ) -> result::Result<(ExitSucceed, Vec, u64), ExitError> { + log::debug!(target: "evm", "state_rent input: {:?}", input); + let input = Input::::new(input); + + let action = input.action()?; + + match action { + Action::QueryNewContractExtraBytes => { + let bytes = vec_u8_from_u32(EVM::query_new_contract_extra_bytes()); + Ok((ExitSucceed::Returned, bytes, 0)) + } + Action::QueryStorageDepositPerByte => { + let deposit = vec_u8_from_balance(EVM::query_storage_deposit_per_byte()); + Ok((ExitSucceed::Returned, deposit, 0)) + } + Action::QueryMaintainer => { + let contract = input.evm_address_at(1)?; + + let maintainer = + EVM::query_maintainer(contract).map_err(|e| ExitError::Other(Cow::Borrowed(e.into())))?; + + let mut address = [0u8; 32]; + address[12..].copy_from_slice(&maintainer.as_bytes().to_vec()); + + Ok((ExitSucceed::Returned, address.to_vec(), 0)) + } + Action::QueryDeveloperDeposit => { + let deposit = vec_u8_from_balance(EVM::query_developer_deposit()); + Ok((ExitSucceed::Returned, deposit, 0)) + } + Action::QueryDeploymentFee => { + let fee = vec_u8_from_balance(EVM::query_deployment_fee()); + Ok((ExitSucceed::Returned, fee, 0)) + } + Action::TransferMaintainer => { + let from = input.account_id_at(1)?; + let contract = input.evm_address_at(2)?; + let new_maintainer = input.evm_address_at(3)?; + + log::debug!( + target: "evm", + "state_rent: from: {:?}, contract: {:?}, new_maintainer: {:?}", + from, contract, new_maintainer, + ); + + EVM::transfer_maintainer(from, contract, new_maintainer) + .map_err(|e| ExitError::Other(Cow::Borrowed(e.into())))?; + + Ok((ExitSucceed::Returned, vec![], 0)) + } + } + } +} + +fn vec_u8_from_balance(b: Balance) -> Vec { + let mut be_bytes = [0u8; 32]; + U256::from(b).to_big_endian(&mut be_bytes[..]); + be_bytes.to_vec() +} + +fn vec_u8_from_u32(b: u32) -> Vec { + let mut be_bytes = [0u8; 32]; + U256::from(b).to_big_endian(&mut be_bytes[..]); + be_bytes.to_vec() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::precompile::mock::get_function_selector; + + #[test] + fn function_selector_match() { + assert_eq!( + u32::from_be_bytes(get_function_selector("newContractExtraBytes()")), + Into::::into(Action::QueryNewContractExtraBytes) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("storageDepositPerByte()")), + Into::::into(Action::QueryStorageDepositPerByte) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("maintainerOf(address)")), + Into::::into(Action::QueryMaintainer) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("developerDeposit()")), + Into::::into(Action::QueryDeveloperDeposit) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("deploymentFee()")), + Into::::into(Action::QueryDeploymentFee) + ); + + assert_eq!( + u32::from_be_bytes(get_function_selector("transferMaintainer(address,address,address)")), + Into::::into(Action::TransferMaintainer) + ); + } +} From e7ca6f0759a59171a4601ca5f86e1a647a76fd61 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:35:46 +0800 Subject: [PATCH 72/83] Add precompiles --- runtime/common/src/lib.rs | 46 ++ runtime/common/src/precompile/input.rs | 311 +++++++++ runtime/common/src/precompile/mock.rs | 594 +++++++++++++++++ runtime/common/src/precompile/mod.rs | 135 ++++ runtime/common/src/precompile/tests.rs | 863 +++++++++++++++++++++++++ 5 files changed, 1949 insertions(+) create mode 100644 runtime/common/src/precompile/input.rs create mode 100644 runtime/common/src/precompile/mock.rs create mode 100644 runtime/common/src/precompile/mod.rs create mode 100644 runtime/common/src/precompile/tests.rs diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index c78045ab9..817853f1c 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -193,3 +193,49 @@ pub fn microcent(currency_id: CurrencyId) -> Balance { pub fn deposit(items: u32, bytes: u32, currency_id: CurrencyId) -> Balance { items as Balance * 15 * cent(currency_id) + (bytes as Balance) * 6 * cent(currency_id) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn system_contracts_filter_works() { + assert!(SystemContractsFilter::is_allowed(H160::from_low_u64_be(1))); + + let mut max_allowed_addr = [0u8; 20]; + max_allowed_addr[SYSTEM_CONTRACT_ADDRESS_PREFIX.len()] = 127u8; + assert!(SystemContractsFilter::is_allowed(max_allowed_addr.into())); + + let mut min_blocked_addr = [0u8; 20]; + min_blocked_addr[SYSTEM_CONTRACT_ADDRESS_PREFIX.len() - 1] = 1u8; + assert!(!SystemContractsFilter::is_allowed(min_blocked_addr.into())); + } + + #[test] + fn is_system_contract_works() { + assert!(is_system_contract(H160::from_low_u64_be(0))); + assert!(is_system_contract(H160::from_low_u64_be(u64::max_value()))); + + let mut bytes = [0u8; 20]; + bytes[SYSTEM_CONTRACT_ADDRESS_PREFIX.len() - 1] = 1u8; + + assert!(!is_system_contract(bytes.into())); + + bytes = [0u8; 20]; + bytes[0] = 1u8; + + assert!(!is_system_contract(bytes.into())); + } + + #[test] + fn is_setheum_precompile_works() { + assert!(!is_setheum_precompile(H160::from_low_u64_be(0))); + assert!(!is_setheum_precompile(H160::from_low_u64_be( + PRECOMPILE_ADDRESS_START - 1 + ))); + assert!(is_setheum_precompile(H160::from_low_u64_be(PRECOMPILE_ADDRESS_START))); + assert!(is_setheum_precompile(H160::from_low_u64_be(PREDEPLOY_ADDRESS_START - 1))); + assert!(!is_setheum_precompile(H160::from_low_u64_be(PREDEPLOY_ADDRESS_START))); + assert!(!is_setheum_precompile([1u8; 20].into())); + } +} diff --git a/runtime/common/src/precompile/input.rs b/runtime/common/src/precompile/input.rs new file mode 100644 index 000000000..4d4914b17 --- /dev/null +++ b/runtime/common/src/precompile/input.rs @@ -0,0 +1,311 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use frame_support::ensure; +use sp_std::{ + convert::{TryFrom, TryInto}, + marker::PhantomData, + mem, + result::Result, + vec::Vec, +}; + +use setheum_evm::ExitError; +use setheum_support::{AddressMapping as AddressMappingT, CurrencyIdMapping as CurrencyIdMappingT}; +use primitives::{Amount, Balance, CurrencyId}; +use sp_core::H160; + +pub const INPUT_BYTES_LENGTH: usize = 32; +pub const FUNCTION_SELECTOR_LENGTH: usize = 4; +pub const PER_PARAM_BYTES: usize = 32; +pub const ACTION_INDEX: usize = 0; + +pub const BALANCE_BYTES: usize = mem::size_of::(); +pub const AMOUNT_BYTES: usize = mem::size_of::(); +pub const U64_BYTES: usize = mem::size_of::(); +pub const U32_BYTES: usize = mem::size_of::(); + +pub trait InputT { + type Error; + type Action; + type AccountId; + + fn nth_param(&self, n: usize, len: Option) -> Result<&[u8], Self::Error>; + fn action(&self) -> Result; + + fn account_id_at(&self, index: usize) -> Result; + fn evm_address_at(&self, index: usize) -> Result; + fn currency_id_at(&self, index: usize) -> Result; + + fn balance_at(&self, index: usize) -> Result; + fn amount_at(&self, index: usize) -> Result; + + fn u64_at(&self, index: usize) -> Result; + fn u32_at(&self, index: usize) -> Result; + + fn bytes_at(&self, start: usize, len: usize) -> Result, Self::Error>; +} + +pub struct Input<'a, Action, AccountId, AddressMapping, CurrencyIdMapping> { + content: &'a [u8], + _marker: PhantomData<(Action, AccountId, AddressMapping, CurrencyIdMapping)>, +} +impl<'a, Action, AccountId, AddressMapping, CurrencyIdMapping> + Input<'a, Action, AccountId, AddressMapping, CurrencyIdMapping> +{ + pub fn new(content: &'a [u8]) -> Self { + Self { + content, + _marker: PhantomData, + } + } +} + +impl InputT + for Input<'_, Action, AccountId, AddressMapping, CurrencyIdMapping> +where + Action: TryFrom, + AddressMapping: AddressMappingT, + CurrencyIdMapping: CurrencyIdMappingT, +{ + type Error = ExitError; + type Action = Action; + type AccountId = AccountId; + + fn nth_param(&self, n: usize, len: Option) -> Result<&[u8], Self::Error> { + // Solidity dynamic bytes will add the size to the front of the input, + // pre-compile needs to deal with the INPUT_BYTES_LENGTH `size`. + let (start, end) = if n == 0 { + // ACTION_INDEX + let start = INPUT_BYTES_LENGTH; + let end = start + FUNCTION_SELECTOR_LENGTH; + (start, end) + } else { + let start = INPUT_BYTES_LENGTH + FUNCTION_SELECTOR_LENGTH + PER_PARAM_BYTES * (n - 1); + let end = start + len.unwrap_or(PER_PARAM_BYTES); + (start, end) + }; + + ensure!(end <= self.content.len(), ExitError::Other("invalid input".into())); + + Ok(&self.content[start..end]) + } + + fn action(&self) -> Result { + let param = self.nth_param(ACTION_INDEX, None)?; + let action = u32::from_be_bytes( + param + .try_into() + .map_err(|_| ExitError::Other("invalid action".into()))?, + ); + + action.try_into().map_err(|_| ExitError::Other("invalid action".into())) + } + + fn account_id_at(&self, index: usize) -> Result { + let param = self.nth_param(index, None)?; + + let mut address = [0u8; 20]; + address.copy_from_slice(¶m[12..]); + + Ok(AddressMapping::get_account_id(&address.into())) + } + + fn evm_address_at(&self, index: usize) -> Result { + let param = self.nth_param(index, None)?; + + let mut address = [0u8; 20]; + address.copy_from_slice(¶m[12..]); + + Ok(H160::from_slice(&address)) + } + + fn currency_id_at(&self, index: usize) -> Result { + let address = self.evm_address_at(index)?; + + CurrencyIdMapping::decode_evm_address(address).ok_or_else(|| ExitError::Other("invalid currency id".into())) + } + + fn balance_at(&self, index: usize) -> Result { + let param = self.nth_param(index, None)?; + + let mut balance = [0u8; BALANCE_BYTES]; + let start = PER_PARAM_BYTES - BALANCE_BYTES; + balance[..].copy_from_slice(¶m[start..]); + + Ok(Balance::from_be_bytes(balance)) + } + + fn amount_at(&self, index: usize) -> Result { + let param = self.nth_param(index, None)?; + + let mut amount = [0u8; AMOUNT_BYTES]; + let start = PER_PARAM_BYTES - AMOUNT_BYTES; + amount[..].copy_from_slice(¶m[start..]); + + Ok(Amount::from_be_bytes(amount)) + } + + fn u64_at(&self, index: usize) -> Result { + let param = self.nth_param(index, None)?; + + let mut num = [0u8; U64_BYTES]; + let start = PER_PARAM_BYTES - U64_BYTES; + num[..].copy_from_slice(¶m[start..]); + + Ok(u64::from_be_bytes(num)) + } + + fn u32_at(&self, index: usize) -> Result { + let param = self.nth_param(index, None)?; + + let mut num = [0u8; U32_BYTES]; + let start = PER_PARAM_BYTES - U32_BYTES; + num[..].copy_from_slice(¶m[start..]); + + Ok(u32::from_be_bytes(num)) + } + + fn bytes_at(&self, index: usize, len: usize) -> Result, Self::Error> { + let bytes = self.nth_param(index, Some(len))?; + + Ok(bytes.to_vec()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use frame_support::{assert_err, assert_ok}; + use num_enum::TryFromPrimitive; + use sp_core::H160; + + use setheum_support::mocks::{MockAddressMapping, MockCurrencyIdMapping}; + use primitives::{AccountId, CurrencyId, TokenSymbol}; + + #[derive(Debug, PartialEq, Eq, TryFromPrimitive)] + #[repr(u32)] + pub enum Action { + QueryBalance = 0, + Transfer = 1, + Unknown = 2, + } + + pub type TestInput<'a> = Input<'a, Action, AccountId, MockAddressMapping, MockCurrencyIdMapping>; + + #[test] + fn nth_param_works() { + let input = TestInput::new(&[1u8; 68][..]); + assert_ok!(input.nth_param(1, None), &[1u8; 32][..]); + assert_err!(input.nth_param(2, None), ExitError::Other("invalid input".into())); + } + + #[test] + fn action_works() { + let input = TestInput::new(&[0u8; 68][..]); + assert_ok!(input.action(), Action::QueryBalance); + + let mut raw_input = [0u8; 68]; + raw_input[35] = 1; + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.action(), Action::Transfer); + + let mut raw_input = [0u8; 68]; + raw_input[35] = 2; + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.action(), Action::Unknown); + + let mut raw_input = [0u8; 68]; + raw_input[35] = 3; + let input = TestInput::new(&raw_input[..]); + assert_eq!(input.action(), Err(ExitError::Other("invalid action".into()))); + } + + #[test] + fn account_id_works() { + let mut address = [0u8; 20]; + address[19] = 1; + let account_id = MockAddressMapping::get_account_id(&address.into()); + + let mut raw_input = [0u8; 68]; + raw_input[67] = 1; + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.account_id_at(1), account_id); + } + + #[test] + fn evm_address_works() { + let mut address = [0u8; 20]; + address[19] = 1; + let evm_address = H160::from_slice(&address); + + let mut raw_input = [0u8; 68]; + raw_input[67] = 1; + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.evm_address_at(1), evm_address); + } + + #[test] + fn currency_id_works() { + let input = TestInput::new(&[0u8; 100][..]); + assert_err!(input.currency_id_at(1), ExitError::Other("invalid currency id".into())); + + let mut raw_input = [0u8; 68]; + raw_input[64] = 1; + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.currency_id_at(1), CurrencyId::Token(TokenSymbol::DNAR)); + + raw_input[67] = 1; + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.currency_id_at(1), CurrencyId::Token(TokenSymbol::USDJ)); + } + + #[test] + fn balance_works() { + let balance = 127u128; + let balance_bytes = balance.to_be_bytes(); + + let mut raw_input = [0u8; 68]; + raw_input[52..].copy_from_slice(&balance_bytes); + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.balance_at(1), balance); + } + + #[test] + fn amount_works() { + let amount = 127i128; + let amount_bytes = amount.to_be_bytes(); + + let mut raw_input = [0u8; 68]; + raw_input[52..].copy_from_slice(&amount_bytes); + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.amount_at(1), amount); + } + + #[test] + fn u64_works() { + let u64_num = 127u64; + let u64_bytes = u64_num.to_be_bytes(); + + let mut raw_input = [0u8; 68]; + raw_input[60..].copy_from_slice(&u64_bytes); + let input = TestInput::new(&raw_input[..]); + assert_ok!(input.u64_at(1), u64_num); + } +} diff --git a/runtime/common/src/precompile/mock.rs b/runtime/common/src/precompile/mock.rs new file mode 100644 index 000000000..87ee86d47 --- /dev/null +++ b/runtime/common/src/precompile/mock.rs @@ -0,0 +1,594 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(test)] + +use crate::{AllPrecompiles, Ratio, RuntimeBlockWeights, SystemContractsFilter, Weight}; +use Setheum_service::chain_spec::evm_genesis; +use codec::{Decode, Encode}; +use frame_support::{ + assert_ok, ord_parameter_types, parameter_types, + traits::{GenesisBuild, InstanceFilter, MaxEncodedLen, OnFinalize, OnInitialize, SortedMembers}, + weights::IdentityFee, + PalletId, RuntimeDebug, +}; +use frame_system::{EnsureRoot, EnsureSignedBy}; +use setheum_support::{ + mocks::MockAddressMapping, AddressMapping as AddressMappingT, DEXIncentives, ExchangeRate, ExchangeRateProvider, +}; +use orml_traits::{parameter_type_with_key, MultiReservableCurrency}; +pub use primitives::{ + evm::EvmAddress, Amount, BlockNumber, CurrencyId, DexShare, Header, Nonce, TokenSymbol, TradingPair, +}; +use sha3::{Digest, Keccak256}; +use sp_core::{crypto::AccountId32, H160, H256}; +use sp_runtime::{ + traits::{BlakeTwo256, Convert, IdentityLookup, One as OneT}, + DispatchResult, FixedPointNumber, FixedU128, Perbill, +}; +use sp_std::{ + collections::btree_map::BTreeMap, + convert::{TryFrom, TryInto}, + str::FromStr, +}; + +pub type AccountId = AccountId32; +type Key = CurrencyId; +pub type Price = FixedU128; +type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u32 = 250; +} +impl frame_system::Config for Test { + type BaseCallFilter = (); + type BlockWeights = RuntimeBlockWeights; + type BlockLength = (); + type Origin = Origin; + type Call = Call; + type Index = u32; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub const MinimumCount: u32 = 1; + pub const ExpiresIn: u32 = 600; + pub const RootOperatorAccountId: AccountId = ALICE; + pub static OracleMembers: Vec = vec![ALICE, BOB, EVA]; +} + +pub struct Members; + +impl SortedMembers for Members { + fn sorted_members() -> Vec { + OracleMembers::get() + } +} + +impl orml_oracle::Config for Test { + type Event = Event; + type OnNewData = (); + type CombineData = orml_oracle::DefaultCombineData; + type Time = Timestamp; + type OracleKey = Key; + type OracleValue = Price; + type RootOperatorAccountId = RootOperatorAccountId; + type Members = Members; + type WeightInfo = (); +} + +impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = (); + type WeightInfo = (); +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Test { + type Event = Event; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = (); +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1; +} + +impl pallet_balances::Config for Test { + type Balance = Balance; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = (); +} + +pub const DNAR: CurrencyId = CurrencyId::Token(TokenSymbol::DNAR); +pub const RENBTC: CurrencyId = CurrencyId::Token(TokenSymbol::RENBTC); +pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); +pub const DOT: CurrencyId = CurrencyId::Token(TokenSymbol::DOT); +pub const LDOT: CurrencyId = CurrencyId::Token(TokenSymbol::LDOT); +pub const LP_DNAR_USDJ: CurrencyId = + CurrencyId::DexShare(DexShare::Token(TokenSymbol::DNAR), DexShare::Token(TokenSymbol::USDJ)); + +parameter_types! { + pub const GetNativeCurrencyId: CurrencyId = DNAR; +} + +impl setheum_currencies::Config for Test { + type Event = Event; + type MultiCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type GetNativeCurrencyId = GetNativeCurrencyId; + type WeightInfo = (); + type AddressMapping = MockAddressMapping; + type EVMBridge = EVMBridge; +} + +impl setheum_evm_bridge::Config for Test { + type EVM = ModuleEVM; +} + +impl setheum_evm_manager::Config for Test { + type Currency = Balances; + type EVMBridge = EVMBridge; +} + +parameter_types! { + pub const CreateClassDeposit: Balance = 200; + pub const CreateTokenDeposit: Balance = 100; + pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); +} +impl setheum_nft::Config for Test { + type Event = Event; + type CreateClassDeposit = CreateClassDeposit; + type CreateTokenDeposit = CreateTokenDeposit; + type PalletId = NftPalletId; + type WeightInfo = (); +} + +parameter_types! { + pub MaxClassMetadata: u32 = 1024; + pub MaxTokenMetadata: u32 = 1024; +} + +impl orml_nft::Config for Test { + type ClassId = u32; + type TokenId = u64; + type ClassData = setheum_nft::ClassData; + type TokenData = setheum_nft::TokenData; + type MaxClassMetadata = MaxClassMetadata; + type MaxTokenMetadata = MaxTokenMetadata; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 10; + pub const GetStableCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); + pub AllNonNativeCurrencyIds: Vec = vec![CurrencyId::Token(TokenSymbol::USDJ)]; + pub MaxSlippageSwapWithDEX: Ratio = Ratio::one(); +} + +impl setheum_transaction_payment::Config for Test { + type AllNonNativeCurrencyIds = AllNonNativeCurrencyIds; + type NativeCurrencyId = GetNativeCurrencyId; + type StableCurrencyId = GetStableCurrencyId; + type Currency = Balances; + type MultiCurrency = Currencies; + type OnTransactionPayment = (); + type TransactionByteFee = TransactionByteFee; + type WeightToFee = IdentityFee; + type FeeMultiplierUpdate = (); + type DEX = (); + type MaxSlippageSwapWithDEX = MaxSlippageSwapWithDEX; + type WeightInfo = (); +} +pub type ChargeTransactionPayment = setheum_transaction_payment::ChargeTransactionPayment; + +parameter_types! { + pub const ProxyDepositBase: u64 = 1; + pub const ProxyDepositFactor: u64 = 1; + pub const MaxProxies: u16 = 4; + pub const MaxPending: u32 = 2; + pub const AnnouncementDepositBase: u64 = 1; + pub const AnnouncementDepositFactor: u64 = 1; +} + +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)] +pub enum ProxyType { + Any, + JustTransfer, + JustUtility, +} +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} +impl InstanceFilter for ProxyType { + fn filter(&self, c: &Call) -> bool { + match self { + ProxyType::Any => true, + ProxyType::JustTransfer => matches!(c, Call::Balances(pallet_balances::Call::transfer(..))), + ProxyType::JustUtility => matches!(c, Call::Utility(..)), + } + } + fn is_superset(&self, o: &Self) -> bool { + self == &ProxyType::Any || self == o + } +} + +impl pallet_proxy::Config for Test { + type Event = Event; + type Call = Call; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = (); + type CallHasher = BlakeTwo256; + type MaxPending = MaxPending; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +} + +impl pallet_utility::Config for Test { + type Event = Event; + type Call = Call; + type WeightInfo = (); +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(10) * RuntimeBlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; +} + +impl pallet_scheduler::Config for Test { + type Event = Event; + type Origin = Origin; + type PalletsOrigin = OriginCaller; + type Call = Call; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = (); +} + +pub struct MockDEXIncentives; +impl DEXIncentives for MockDEXIncentives { + fn do_deposit_dex_share(who: &AccountId, lp_currency_id: CurrencyId, amount: Balance) -> DispatchResult { + Tokens::reserve(lp_currency_id, who, amount) + } + + fn do_withdraw_dex_share(who: &AccountId, lp_currency_id: CurrencyId, amount: Balance) -> DispatchResult { + let _ = Tokens::unreserve(lp_currency_id, who, amount); + Ok(()) + } +} + +ord_parameter_types! { + pub const ListingOrigin: AccountId = ALICE; +} + +parameter_types! { + pub const GetExchangeFee: (u32, u32) = (1, 100); + pub const TradingPathLimit: u32 = 3; + pub const DEXPalletId: PalletId = PalletId(*b"set/sdex"); +} + +impl setheum_dex::Config for Test { + type Event = Event; + type Currency = Tokens; + type GetExchangeFee = GetExchangeFee; + type TradingPathLimit = TradingPathLimit; + type PalletId = DEXPalletId; + type CurrencyIdMapping = EvmCurrencyIdMapping; + type WeightInfo = (); + type DEXIncentives = MockDEXIncentives; + type ListingOrigin = EnsureSignedBy; +} + +pub type AdaptedBasicCurrency = setheum_currencies::BasicCurrencyAdapter; + +pub type EvmCurrencyIdMapping = setheum_evm_manager::EvmCurrencyIdMapping; +pub type MultiCurrencyPrecompile = + crate::MultiCurrencyPrecompile; + +pub type NFTPrecompile = crate::NFTPrecompile; +pub type StateRentPrecompile = + crate::StateRentPrecompile; +pub type OraclePrecompile = crate::OraclePrecompile; +pub type ScheduleCallPrecompile = crate::ScheduleCallPrecompile< + AccountId, + MockAddressMapping, + EvmCurrencyIdMapping, + Scheduler, + ChargeTransactionPayment, + Call, + Origin, + OriginCaller, + Test, +>; +pub type DexPrecompile = crate::DexPrecompile; + +parameter_types! { + pub NetworkContractSource: H160 = alice_evm_addr(); +} + +ord_parameter_types! { + pub const CouncilAccount: AccountId32 = AccountId32::from([1u8; 32]); + pub const TreasuryAccount: AccountId32 = AccountId32::from([2u8; 32]); + pub const NetworkContractAccount: AccountId32 = AccountId32::from([0u8; 32]); + pub const NewContractExtraBytes: u32 = 100; + pub const StorageDepositPerByte: u64 = 10; + pub const DeveloperDeposit: u64 = 1000; + pub const DeploymentFee: u64 = 200; + pub const MaxCodeSize: u32 = 60 * 1024; + pub const ChainId: u64 = 1; +} + +pub struct GasToWeight; +impl Convert for GasToWeight { + fn convert(a: u64) -> u64 { + a as Weight + } +} + +impl setheum_evm::Config for Test { + type AddressMapping = MockAddressMapping; + type Currency = Balances; + type TransferAll = Currencies; + type NewContractExtraBytes = NewContractExtraBytes; + type StorageDepositPerByte = StorageDepositPerByte; + type MaxCodeSize = MaxCodeSize; + type Event = Event; + type Precompiles = AllPrecompiles< + SystemContractsFilter, + MultiCurrencyPrecompile, + NFTPrecompile, + StateRentPrecompile, + OraclePrecompile, + ScheduleCallPrecompile, + DexPrecompile, + >; + type ChainId = ChainId; + type GasToWeight = GasToWeight; + type ChargeTransactionPayment = ChargeTransactionPayment; + type NetworkContractOrigin = EnsureSignedBy; + type NetworkContractSource = NetworkContractSource; + type DeveloperDeposit = DeveloperDeposit; + type DeploymentFee = DeploymentFee; + type TreasuryAccount = TreasuryAccount; + type FreeDeploymentOrigin = EnsureSignedBy; + type WeightInfo = (); +} + +pub struct MockLiquidStakingExchangeProvider; +impl ExchangeRateProvider for MockLiquidStakingExchangeProvider { + fn get_exchange_rate() -> ExchangeRate { + ExchangeRate::saturating_from_rational(1, 2) + } +} + +parameter_types! { + pub StableCurrencyFixedPrice: Price = Price::saturating_from_rational(1, 1); + pub const GetStakingCurrencyId: CurrencyId = DOT; + pub const GetLiquidCurrencyId: CurrencyId = LDOT; +} + +ord_parameter_types! { + pub const One: AccountId = AccountId::new([1u8; 32]); +} + +impl setheum_prices::Config for Test { + type Event = Event; + type Source = Oracle; + type GetStableCurrencyId = GetStableCurrencyId; + type StableCurrencyFixedPrice = StableCurrencyFixedPrice; + type GetStakingCurrencyId = GetStakingCurrencyId; + type GetLiquidCurrencyId = GetLiquidCurrencyId; + type LockOrigin = EnsureSignedBy; + type LiquidStakingExchangeRateProvider = MockLiquidStakingExchangeProvider; + type DEX = DexModule; + type Currency = Currencies; + type CurrencyIdMapping = EvmCurrencyIdMapping; + type WeightInfo = (); +} + +pub const ALICE: AccountId = AccountId::new([1u8; 32]); +pub const BOB: AccountId = AccountId::new([2u8; 32]); +pub const EVA: AccountId = AccountId::new([5u8; 32]); + +pub fn alice() -> AccountId { + ::AddressMapping::get_account_id(&alice_evm_addr()) +} + +pub fn alice_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000001").unwrap() +} + +pub fn bob() -> AccountId { + ::AddressMapping::get_account_id(&bob_evm_addr()) +} + +pub fn bob_evm_addr() -> EvmAddress { + EvmAddress::from_str("1000000000000000000000000000000000000002").unwrap() +} + +pub fn dnar_evm_address() -> EvmAddress { + EvmAddress::try_from(DNAR).unwrap() +} + +pub fn usdj_evm_address() -> EvmAddress { + EvmAddress::try_from(USDJ).unwrap() +} + +pub fn renbtc_evm_address() -> EvmAddress { + EvmAddress::try_from(RENBTC).unwrap() +} + +pub fn lp_dnar_usdj_evm_address() -> EvmAddress { + EvmAddress::try_from(LP_DNAR_USDJ).unwrap() +} + +pub fn erc20_address_not_exists() -> EvmAddress { + EvmAddress::from_str("0000000000000000000000000000000200000001").unwrap() +} + +pub const INITIAL_BALANCE: Balance = 1_000_000_000_000; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Oracle: orml_oracle::{Pallet, Storage, Call, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Currencies: setheum_currencies::{Pallet, Call, Event}, + EVMBridge: setheum_evm_bridge::{Pallet}, + EVMManager: setheum_evm_manager::{Pallet, Storage}, + NFTModule: setheum_nft::{Pallet, Call, Event}, + TransactionPayment: setheum_transaction_payment::{Pallet, Call, Storage}, + Prices: setheum_prices::{Pallet, Storage, Call, Event}, + Proxy: pallet_proxy::{Pallet, Call, Storage, Event}, + Utility: pallet_utility::{Pallet, Call, Event}, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, + DexModule: setheum_dex::{Pallet, Storage, Call, Event, Config}, + ModuleEVM: setheum_evm::{Pallet, Config, Call, Storage, Event}, + } +); + +// This function basically just builds a genesis storage key/value store +// according to our desired mockup. +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + let mut accounts = BTreeMap::new(); + let mut evm_genesis_accounts = evm_genesis(); + accounts.append(&mut evm_genesis_accounts); + + accounts.insert( + alice_evm_addr(), + setheum_evm::GenesisAccount { + nonce: 1, + balance: INITIAL_BALANCE, + storage: Default::default(), + code: Default::default(), + }, + ); + accounts.insert( + bob_evm_addr(), + setheum_evm::GenesisAccount { + nonce: 1, + balance: INITIAL_BALANCE, + storage: Default::default(), + code: Default::default(), + }, + ); + + pallet_balances::GenesisConfig::::default() + .assimilate_storage(&mut storage) + .unwrap(); + setheum_evm::GenesisConfig:: { + accounts, + treasury: Default::default(), + } + .assimilate_storage(&mut storage) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(storage); + ext.execute_with(|| { + System::set_block_number(1); + Timestamp::set_timestamp(1); + + assert_ok!(Currencies::update_balance( + Origin::root(), + ALICE, + RENBTC, + 1_000_000_000_000 + )); + assert_ok!(Currencies::update_balance(Origin::root(), ALICE, USDJ, 1_000_000_000)); + + assert_ok!(Currencies::update_balance( + Origin::root(), + MockAddressMapping::get_account_id(&alice_evm_addr()), + RENBTC, + 1_000 + )); + }); + ext +} + +pub fn run_to_block(n: u32) { + while System::block_number() < n { + Scheduler::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + Scheduler::on_initialize(System::block_number()); + } +} +pub fn get_task_id(output: Vec) -> Vec { + let mut num = [0u8; 4]; + num[..].copy_from_slice(&output[32 - 4..32]); + let task_id_len: u32 = u32::from_be_bytes(num); + return output[32..32 + task_id_len as usize].to_vec(); +} + +pub fn get_function_selector(s: &str) -> [u8; 4] { + // create a SHA3-256 object + let mut hasher = Keccak256::new(); + // write input message + hasher.update(s); + // read hash digest + let result = hasher.finalize(); + result[..4].try_into().unwrap() +} diff --git a/runtime/common/src/precompile/mod.rs b/runtime/common/src/precompile/mod.rs new file mode 100644 index 000000000..c55d29920 --- /dev/null +++ b/runtime/common/src/precompile/mod.rs @@ -0,0 +1,135 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! The precompiles for EVM, includes standard Ethereum precompiles, and more: +//! - MultiCurrency at address `H160::from_low_u64_be(1024)`. + +#![allow(clippy::upper_case_acronyms)] + +mod mock; +mod tests; + +use crate::is_setheum_precompile; +use frame_support::log; +use setheum_evm::{ + precompiles::{ + ECRecover, ECRecoverPublicKey, EvmPrecompiles, Identity, Precompile, Precompiles, Ripemd160, Sha256, + Sha3FIPS256, Sha3FIPS512, + }, + Context, ExitError, ExitSucceed, +}; +use setheum_support::PrecompileCallerFilter as PrecompileCallerFilterT; +use primitives::PRECOMPILE_ADDRESS_START; +use sp_core::H160; +use sp_std::{marker::PhantomData, prelude::*}; + +pub mod dex; +pub mod input; +pub mod multicurrency; +pub mod nft; +pub mod oracle; +pub mod schedule_call; +pub mod state_rent; + +pub use dex::DexPrecompile; +pub use multicurrency::MultiCurrencyPrecompile; +pub use nft::NFTPrecompile; +pub use oracle::OraclePrecompile; +pub use schedule_call::ScheduleCallPrecompile; +pub use state_rent::StateRentPrecompile; + +pub struct AllPrecompiles< + PrecompileCallerFilter, + MultiCurrencyPrecompile, + NFTPrecompile, + StateRentPrecompile, + OraclePrecompile, + ScheduleCallPrecompile, + DexPrecompile, +>( + PhantomData<( + PrecompileCallerFilter, + MultiCurrencyPrecompile, + NFTPrecompile, + StateRentPrecompile, + OraclePrecompile, + ScheduleCallPrecompile, + DexPrecompile, + )>, +); + +impl< + PrecompileCallerFilter, + MultiCurrencyPrecompile, + NFTPrecompile, + StateRentPrecompile, + OraclePrecompile, + ScheduleCallPrecompile, + DexPrecompile, + > Precompiles + for AllPrecompiles< + PrecompileCallerFilter, + MultiCurrencyPrecompile, + NFTPrecompile, + StateRentPrecompile, + OraclePrecompile, + ScheduleCallPrecompile, + DexPrecompile, + > where + MultiCurrencyPrecompile: Precompile, + NFTPrecompile: Precompile, + StateRentPrecompile: Precompile, + OraclePrecompile: Precompile, + ScheduleCallPrecompile: Precompile, + PrecompileCallerFilter: PrecompileCallerFilterT, + DexPrecompile: Precompile, +{ + #[allow(clippy::type_complexity)] + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + context: &Context, + ) -> Option, u64), ExitError>> { + EvmPrecompiles::::execute( + address, input, target_gas, context, + ) + .or_else(|| { + if is_setheum_precompile(address) && !PrecompileCallerFilter::is_allowed(context.caller) { + log::debug!(target: "evm", "Precompile no permission"); + return Some(Err(ExitError::Other("no permission".into()))); + } + + if address == H160::from_low_u64_be(PRECOMPILE_ADDRESS_START) { + Some(MultiCurrencyPrecompile::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(PRECOMPILE_ADDRESS_START + 1) { + Some(NFTPrecompile::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(PRECOMPILE_ADDRESS_START + 2) { + Some(StateRentPrecompile::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(PRECOMPILE_ADDRESS_START + 3) { + Some(OraclePrecompile::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(PRECOMPILE_ADDRESS_START + 4) { + Some(ScheduleCallPrecompile::execute(input, target_gas, context)) + } else if address == H160::from_low_u64_be(PRECOMPILE_ADDRESS_START + 5) { + Some(DexPrecompile::execute(input, target_gas, context)) + } else { + None + } + }) + } +} diff --git a/runtime/common/src/precompile/tests.rs b/runtime/common/src/precompile/tests.rs new file mode 100644 index 000000000..41b1eab37 --- /dev/null +++ b/runtime/common/src/precompile/tests.rs @@ -0,0 +1,863 @@ +// This file is part of Setheum. + +// Copyright (C) 2020-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(test)] +use super::*; +use crate::precompile::{ + mock::{ + dnar_evm_address, alice, alice_evm_addr, usdj_evm_address, bob, bob_evm_addr, erc20_address_not_exists, + get_task_id, lp_dnar_usdj_evm_address, new_test_ext, renbtc_evm_address, run_to_block, Balances, DexModule, + DexPrecompile, Event as TestEvent, MultiCurrencyPrecompile, Oracle, OraclePrecompile, Origin, Price, + ScheduleCallPrecompile, System, Test, ALICE, USDJ, INITIAL_BALANCE, RENBTC, + }, + schedule_call::TaskInfo, +}; +use codec::Encode; +use frame_support::{assert_noop, assert_ok}; +use hex_literal::hex; +use setheum_evm::ExitError; +use setheum_support::AddressMapping; +use orml_traits::DataFeeder; +use primitives::{Balance, PREDEPLOY_ADDRESS_START}; +use sp_core::{H160, U256}; +use sp_runtime::FixedPointNumber; +use std::str::FromStr; + +pub struct DummyPrecompile; +impl Precompile for DummyPrecompile { + fn execute( + _input: &[u8], + _target_gas: Option, + _context: &Context, + ) -> core::result::Result<(ExitSucceed, Vec, u64), ExitError> { + Ok((ExitSucceed::Stopped, vec![], 0)) + } +} + +pub type WithSystemContractFilter = AllPrecompiles< + crate::SystemContractsFilter, + DummyPrecompile, + DummyPrecompile, + DummyPrecompile, + DummyPrecompile, + DummyPrecompile, + DummyPrecompile, +>; + +#[test] +fn precompile_filter_works_on_Setheum_precompiles() { + let precompile = H160::from_low_u64_be(PRECOMPILE_ADDRESS_START); + + let mut non_system = [0u8; 20]; + non_system[0] = 1; + + let non_system_caller_context = Context { + address: precompile, + caller: non_system.into(), + apparent_value: 0.into(), + }; + assert_eq!( + WithSystemContractFilter::execute(precompile, &[0u8; 1], None, &non_system_caller_context), + Some(Err(ExitError::Other("no permission".into()))), + ); +} + +#[test] +fn precompile_filter_does_not_work_on_system_contracts() { + let system = H160::from_low_u64_be(PREDEPLOY_ADDRESS_START); + + let mut non_system = [0u8; 20]; + non_system[0] = 1; + + let non_system_caller_context = Context { + address: system, + caller: non_system.into(), + apparent_value: 0.into(), + }; + assert!( + WithSystemContractFilter::execute(non_system.into(), &[0u8; 1], None, &non_system_caller_context).is_none() + ); +} + +#[test] +fn precompile_filter_does_not_work_on_non_system_contracts() { + let mut non_system = [0u8; 20]; + non_system[0] = 1; + let mut another_non_system = [0u8; 20]; + another_non_system[0] = 2; + + let non_system_caller_context = Context { + address: non_system.into(), + caller: another_non_system.into(), + apparent_value: 0.into(), + }; + assert!( + WithSystemContractFilter::execute(non_system.into(), &[0u8; 1], None, &non_system_caller_context).is_none() + ); +} + +#[test] +fn multicurrency_precompile_should_work() { + new_test_ext().execute_with(|| { + let mut context = Context { + address: Default::default(), + caller: Default::default(), + apparent_value: Default::default(), + }; + + // call with not exists erc20 + context.caller = erc20_address_not_exists(); + let mut input = [0u8; 68]; + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(multicurrency::Action::QuerySymbol).to_be_bytes()); + assert_noop!( + MultiCurrencyPrecompile::execute(&input, None, &context), + ExitError::Other("invalid currency id".into()) + ); + + // 1.QueryName + let mut input = [0u8; 36]; + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(multicurrency::Action::QueryName).to_be_bytes()); + + // Token + context.caller = dnar_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[27..32].copy_from_slice(&b"Setheum"[..]); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // DexShare + context.caller = lp_dnar_usdj_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[9..32].copy_from_slice(&b"LP Setheum - Setheum Dollar"[..]); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // 2.QuerySymbol + let mut input = [0u8; 36]; + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(multicurrency::Action::QuerySymbol).to_be_bytes()); + + // Token + context.caller = dnar_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[29..32].copy_from_slice(&b"DNAR"[..]); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // DexShare + context.caller = lp_dnar_usdj_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[21..32].copy_from_slice(&b"LP_DNAR_USDJ"[..]); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // 3.QueryDecimals + let mut input = [0u8; 36]; + // action + input[1 * 32..4 + 1 * 32] + .copy_from_slice(&Into::::into(multicurrency::Action::QueryDecimals).to_be_bytes()); + + // Token + context.caller = dnar_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[31] = 12; + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // DexShare + context.caller = lp_dnar_usdj_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[31] = 12; + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // 4.QueryTotalIssuance + let mut input = [0u8; 36]; + // action + input[1 * 32..4 + 1 * 32] + .copy_from_slice(&Into::::into(multicurrency::Action::QueryTotalIssuance).to_be_bytes()); + + // Token + context.caller = dnar_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[16..32].copy_from_slice(&(INITIAL_BALANCE * 2).to_be_bytes()[..]); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // DexShare + context.caller = lp_dnar_usdj_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let expected_output = [0u8; 32]; + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // 5.QueryBalance + let mut input = [0u8; 4 + 2 * 32]; + // action + input[1 * 32..4 + 1 * 32] + .copy_from_slice(&Into::::into(multicurrency::Action::QueryBalance).to_be_bytes()); + // from + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + + // Token + context.caller = dnar_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let mut expected_output = [0u8; 32]; + expected_output[16..32].copy_from_slice(&INITIAL_BALANCE.to_be_bytes()[..]); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // DexShare + context.caller = lp_dnar_usdj_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let expected_output = [0u8; 32]; + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + + // TODO: Update to add "claim_cashdrop" using `claim: bool` + // 6.Transfer + let mut input = [0u8; 4 + 4 * 32]; + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(multicurrency::Action::Transfer).to_be_bytes()); + // from + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + // to + U256::from(bob_evm_addr().as_bytes()).to_big_endian(&mut input[4 + 2 * 32..4 + 3 * 32]); + // amount + U256::from(1).to_big_endian(&mut input[4 + 3 * 32..4 + 4 * 32]); + let from_balance = Balances::free_balance(alice()); + let to_balance = Balances::free_balance(bob()); + // TODO The claim cashdrop goes here as ` let claim = false`. then do another test that says `true`. + + // Token + context.caller = dnar_evm_address(); + let (reason, output, used_gas) = MultiCurrencyPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + let expected_output: Vec = vec![]; + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + assert_eq!(Balances::free_balance(alice()), from_balance - 1); + assert_eq!(Balances::free_balance(bob()), to_balance + 1); + + // DexShare + context.caller = lp_dnar_usdj_evm_address(); + assert_noop!( + MultiCurrencyPrecompile::execute(&input, None, &context), + ExitError::Other("BalanceTooLow".into()) + ); + }); +} + +#[test] +fn oracle_precompile_should_work() { + new_test_ext().execute_with(|| { + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + let price = Price::from(30_000); + + // action + currency_id + let mut input = [0u8; 68]; + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(oracle::Action::GetPrice).to_be_bytes()); + // RENBTC + U256::from_big_endian(&renbtc_evm_address().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + + // no price yet + let (reason, output, used_gas) = OraclePrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(output, [0u8; 32]); + assert_eq!(used_gas, 0); + + assert_ok!(Oracle::feed_value(ALICE, RENBTC, price)); + assert_eq!( + Oracle::get_no_op(&RENBTC), + Some(orml_oracle::TimestampedValue { + value: price, + timestamp: 1 + }) + ); + + // returned price + timestamp + let mut expected_output = [0u8; 32]; + U256::from(price.into_inner()).to_big_endian(&mut expected_output[..]); + + let (reason, output, used_gas) = OraclePrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + }); +} + +#[test] +fn oracle_precompile_should_handle_invalid_input() { + new_test_ext().execute_with(|| { + assert_noop!( + OraclePrecompile::execute( + &[0u8; 0], + None, + &Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default() + } + ), + ExitError::Other("invalid input".into()) + ); + + assert_noop!( + OraclePrecompile::execute( + &[0u8; 32], + None, + &Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default() + } + ), + ExitError::Other("invalid input".into()) + ); + + assert_noop!( + OraclePrecompile::execute( + &[1u8; 64], + None, + &Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default() + } + ), + ExitError::Other("invalid action".into()) + ); + }); +} + +#[test] +fn schedule_call_precompile_should_work() { + new_test_ext().execute_with(|| { + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + let mut input = [0u8; 12 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(schedule_call::Action::Schedule).to_be_bytes()); + // from + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + // target + U256::from(dnar_evm_address().as_bytes()).to_big_endian(&mut input[4 + 2 * 32..4 + 3 * 32]); + // value + U256::from(0).to_big_endian(&mut input[4 + 3 * 32..4 + 4 * 32]); + // gas_limit + U256::from(300000).to_big_endian(&mut input[4 + 4 * 32..4 + 5 * 32]); + // storage_limit + U256::from(100).to_big_endian(&mut input[4 + 5 * 32..4 + 6 * 32]); + // min_delay + U256::from(1).to_big_endian(&mut input[4 + 6 * 32..4 + 7 * 32]); + // skip offset + // input_len + U256::from(4 + 32 + 32).to_big_endian(&mut input[4 + 8 * 32..4 + 9 * 32]); + + // input_data + let mut transfer_to_bob = [0u8; 68]; + // transfer bytes4(keccak256(signature)) 0xa9059cbb + transfer_to_bob[0..4].copy_from_slice(&hex!("a9059cbb")); + // to address + U256::from(bob_evm_addr().as_bytes()).to_big_endian(&mut transfer_to_bob[4..36]); + // amount + U256::from(1000).to_big_endian(&mut transfer_to_bob[36..68]); + + U256::from(&transfer_to_bob[0..32]).to_big_endian(&mut input[4 + 9 * 32..4 + 10 * 32]); + U256::from(&transfer_to_bob[32..64]).to_big_endian(&mut input[4 + 10 * 32..4 + 11 * 32]); + input[4 + 11 * 32..4 + 11 * 32 + 4].copy_from_slice(&transfer_to_bob[64..68]); + + let (reason, output, used_gas) = ScheduleCallPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(used_gas, 0); + let event = TestEvent::pallet_scheduler(pallet_scheduler::Event::::Scheduled(3, 0)); + assert!(System::events().iter().any(|record| record.event == event)); + + // cancel schedule + let task_id = get_task_id(output); + let mut cancel_input = [0u8; 6 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + cancel_input[1 * 32..4 + 1 * 32] + .copy_from_slice(&Into::::into(schedule_call::Action::Cancel).to_be_bytes()); + // from + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut cancel_input[4 + 1 * 32..4 + 2 * 32]); + // skip offset + // task_id_len + U256::from(task_id.len()).to_big_endian(&mut cancel_input[4 + 3 * 32..4 + 4 * 32]); + // task_id + cancel_input[4 + 4 * 32..4 + 4 * 32 + task_id.len()].copy_from_slice(&task_id[..]); + + let (reason, _output, used_gas) = ScheduleCallPrecompile::execute(&cancel_input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(used_gas, 0); + let event = TestEvent::pallet_scheduler(pallet_scheduler::Event::::Canceled(3, 0)); + assert!(System::events().iter().any(|record| record.event == event)); + + let (reason, output, used_gas) = ScheduleCallPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(used_gas, 0); + + run_to_block(2); + + // reschedule call + let task_id = get_task_id(output); + let mut reschedule_input = [0u8; 7 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + reschedule_input[1 * 32..4 + 1 * 32] + .copy_from_slice(&Into::::into(schedule_call::Action::Reschedule).to_be_bytes()); + // from + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut reschedule_input[4 + 1 * 32..4 + 2 * 32]); + // min_delay + U256::from(2).to_big_endian(&mut reschedule_input[4 + 2 * 32..4 + 3 * 32]); + // skip offset + // task_id_len + U256::from(task_id.len()).to_big_endian(&mut reschedule_input[4 + 4 * 32..4 + 5 * 32]); + // task_id + reschedule_input[4 + 5 * 32..4 + 5 * 32 + task_id.len()].copy_from_slice(&task_id[..]); + + let (reason, _output, used_gas) = ScheduleCallPrecompile::execute(&reschedule_input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(used_gas, 0); + let event = TestEvent::pallet_scheduler(pallet_scheduler::Event::::Scheduled(5, 0)); + assert!(System::events().iter().any(|record| record.event == event)); + + let from_account = ::AddressMapping::get_account_id(&alice_evm_addr()); + let to_account = ::AddressMapping::get_account_id(&bob_evm_addr()); + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + assert_eq!(Balances::free_balance(from_account.clone()), 999999700000); + assert_eq!(Balances::reserved_balance(from_account.clone()), 300000); + assert_eq!(Balances::free_balance(to_account.clone()), 1000000000000); + } + #[cfg(feature = "with-ethereum-compatibility")] + { + assert_eq!(Balances::free_balance(from_account.clone()), 1000000000000); + assert_eq!(Balances::reserved_balance(from_account.clone()), 0); + assert_eq!(Balances::free_balance(to_account.clone()), 1000000000000); + } + + run_to_block(5); + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + assert_eq!(Balances::free_balance(from_account.clone()), 999999894290); + assert_eq!(Balances::reserved_balance(from_account), 0); + assert_eq!(Balances::free_balance(to_account), 1000000001000); + } + #[cfg(feature = "with-ethereum-compatibility")] + { + assert_eq!(Balances::free_balance(from_account.clone()), 999999999000); + assert_eq!(Balances::reserved_balance(from_account), 0); + assert_eq!(Balances::free_balance(to_account), 1000000001000); + } + }); +} + +#[test] +fn schedule_call_precompile_should_handle_invalid_input() { + new_test_ext().execute_with(|| { + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + let mut input = [0u8; 10 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(schedule_call::Action::Schedule).to_be_bytes()); + // from + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + // target + U256::from(dnar_evm_address().as_bytes()).to_big_endian(&mut input[4 + 2 * 32..4 + 3 * 32]); + // value + U256::from(0).to_big_endian(&mut input[4 + 3 * 32..4 + 4 * 32]); + // gas_limit + U256::from(300000).to_big_endian(&mut input[4 + 4 * 32..4 + 5 * 32]); + // storage_limit + U256::from(100).to_big_endian(&mut input[4 + 5 * 32..4 + 6 * 32]); + // min_delay + U256::from(1).to_big_endian(&mut input[4 + 6 * 32..4 + 7 * 32]); + // skip offset + // input_len + U256::from(1).to_big_endian(&mut input[4 + 8 * 32..4 + 9 * 32]); + + // input_data = 0x12 + input[4 + 9 * 32] = hex!("12")[0]; + + let (reason, output, used_gas) = ScheduleCallPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(used_gas, 0); + + let from_account = ::AddressMapping::get_account_id(&alice_evm_addr()); + let to_account = ::AddressMapping::get_account_id(&bob_evm_addr()); + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + assert_eq!(Balances::free_balance(from_account.clone()), 999999700000); + assert_eq!(Balances::reserved_balance(from_account.clone()), 300000); + assert_eq!(Balances::free_balance(to_account.clone()), 1000000000000); + } + #[cfg(feature = "with-ethereum-compatibility")] + { + assert_eq!(Balances::free_balance(from_account.clone()), 1000000000000); + assert_eq!(Balances::reserved_balance(from_account.clone()), 0); + assert_eq!(Balances::free_balance(to_account.clone()), 1000000000000); + } + + // cancel schedule + let task_id = get_task_id(output); + let mut cancel_input = [0u8; 7 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + cancel_input[1 * 32..4 + 1 * 32] + .copy_from_slice(&Into::::into(schedule_call::Action::Cancel).to_be_bytes()); + // from + U256::from(bob_evm_addr().as_bytes()).to_big_endian(&mut cancel_input[4 + 1 * 32..4 + 2 * 32]); + // skip offset + // task_id_len + U256::from(task_id.len()).to_big_endian(&mut cancel_input[4 + 3 * 32..4 + 4 * 32]); + // task_id + cancel_input[4 + 4 * 32..4 + 4 * 32 + task_id.len()].copy_from_slice(&task_id[..]); + + assert_eq!( + ScheduleCallPrecompile::execute(&cancel_input, None, &context), + Err(ExitError::Other("NoPermission".into())) + ); + + run_to_block(4); + #[cfg(not(feature = "with-ethereum-compatibility"))] + { + assert_eq!(Balances::free_balance(from_account.clone()), 999999898614); + assert_eq!(Balances::reserved_balance(from_account), 0); + assert_eq!(Balances::free_balance(to_account), 1000000000000); + } + #[cfg(feature = "with-ethereum-compatibility")] + { + assert_eq!(Balances::free_balance(from_account.clone()), 1000000000000); + assert_eq!(Balances::reserved_balance(from_account.clone()), 0); + assert_eq!(Balances::free_balance(to_account.clone()), 1000000000000); + } + }); +} + +#[test] +fn dex_precompile_get_liquidity_should_work() { + new_test_ext().execute_with(|| { + // enable RENBTC/USDJ + assert_ok!(DexModule::enable_trading_pair(Origin::signed(ALICE), RENBTC, USDJ,)); + + assert_ok!(DexModule::add_liquidity( + Origin::signed(ALICE), + RENBTC, + USDJ, + 1_000, + 1_000_000, + 0, + true + )); + + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + // array_size + action + currency_id_a + currency_id_b + let mut input = [0u8; 4 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(dex::Action::GetLiquidityPool).to_be_bytes()); + // RENBTC + U256::from_big_endian(&renbtc_evm_address().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + // USDJ + U256::from_big_endian(&usdj_evm_address().as_bytes()).to_big_endian(&mut input[4 + 2 * 32..4 + 3 * 32]); + + let mut expected_output = [0u8; 64]; + U256::from(1_000).to_big_endian(&mut expected_output[..32]); + U256::from(1_000_000).to_big_endian(&mut expected_output[32..64]); + + let (reason, output, used_gas) = DexPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + }); +} + +#[test] +fn dex_precompile_get_swap_target_amount_should_work() { + new_test_ext().execute_with(|| { + // enable RENBTC/USDJ + assert_ok!(DexModule::enable_trading_pair(Origin::signed(ALICE), RENBTC, USDJ,)); + + assert_ok!(DexModule::add_liquidity( + Origin::signed(ALICE), + RENBTC, + USDJ, + 1_000, + 1_000_000, + 0, + true + )); + + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + // array_size + action + path_len + currency_id_a + currency_id_b + + // supply_amount + let mut input = [0u8; 7 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(dex::Action::GetSwapTargetAmount).to_be_bytes()); + // skip offset + // supply_amount + U256::from(1).to_big_endian(&mut input[4 + 2 * 32..4 + 3 * 32]); + // path_len + U256::from(2).to_big_endian(&mut input[4 + 3 * 32..4 + 4 * 32]); + // RENBTC + U256::from_big_endian(&renbtc_evm_address().as_bytes()).to_big_endian(&mut input[4 + 4 * 32..4 + 5 * 32]); + // USDJ + U256::from_big_endian(&usdj_evm_address().as_bytes()).to_big_endian(&mut input[4 + 5 * 32..4 + 6 * 32]); + + let mut expected_output = [0u8; 32]; + U256::from(989).to_big_endian(&mut expected_output[..32]); + + let (reason, output, used_gas) = DexPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + }); +} + +#[test] +fn dex_precompile_get_swap_supply_amount_should_work() { + new_test_ext().execute_with(|| { + // enable RENBTC/USDJ + assert_ok!(DexModule::enable_trading_pair(Origin::signed(ALICE), RENBTC, USDJ,)); + + assert_ok!(DexModule::add_liquidity( + Origin::signed(ALICE), + RENBTC, + USDJ, + 1_000, + 1_000_000, + 0, + true + )); + + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + // array_size + action + path_len + currency_id_a + currency_id_b + + // target_amount + let mut input = [0u8; 7 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(dex::Action::GetSwapSupplyAmount).to_be_bytes()); + // skip offset + // target_amount + U256::from(1).to_big_endian(&mut input[4 + 2 * 32..4 + 3 * 32]); + // path_len + U256::from(2).to_big_endian(&mut input[4 + 3 * 32..4 + 4 * 32]); + // RENBTC + U256::from_big_endian(&renbtc_evm_address().as_bytes()).to_big_endian(&mut input[4 + 4 * 32..4 + 5 * 32]); + // USDJ + U256::from_big_endian(&usdj_evm_address().as_bytes()).to_big_endian(&mut input[4 + 5 * 32..4 + 6 * 32]); + + let mut expected_output = [0u8; 32]; + U256::from(1).to_big_endian(&mut expected_output[..32]); + + let (reason, output, used_gas) = DexPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + }); +} + +#[test] +fn dex_precompile_swap_with_exact_supply_should_work() { + new_test_ext().execute_with(|| { + // enable RENBTC/USDJ + assert_ok!(DexModule::enable_trading_pair(Origin::signed(ALICE), RENBTC, USDJ,)); + + assert_ok!(DexModule::add_liquidity( + Origin::signed(ALICE), + RENBTC, + USDJ, + 1_000, + 1_000_000, + 0, + true + )); + + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + // array_size + action + who + path_len + currency_id_a + currency_id_b + + // supply_amount + min_target_amount + let mut input = [0u8; 9 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(dex::Action::SwapWithExactSupply).to_be_bytes()); + // who + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + // skip offset + // supply_amount + U256::from(1).to_big_endian(&mut input[4 + 3 * 32..4 + 4 * 32]); + // min_target_amount + U256::from(0).to_big_endian(&mut input[4 + 4 * 32..4 + 5 * 32]); + // path_len + U256::from(2).to_big_endian(&mut input[4 + 5 * 32..4 + 6 * 32]); + // RENBTC + U256::from_big_endian(&renbtc_evm_address().as_bytes()).to_big_endian(&mut input[4 + 6 * 32..4 + 7 * 32]); + // USDJ + U256::from_big_endian(&usdj_evm_address().as_bytes()).to_big_endian(&mut input[4 + 7 * 32..4 + 8 * 32]); + + let mut expected_output = [0u8; 32]; + U256::from(989).to_big_endian(&mut expected_output[..32]); + + let (reason, output, used_gas) = DexPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + }); +} + +#[test] +fn dex_precompile_swap_with_exact_target_should_work() { + new_test_ext().execute_with(|| { + // enable RENBTC/USDJ + assert_ok!(DexModule::enable_trading_pair(Origin::signed(ALICE), RENBTC, USDJ,)); + + assert_ok!(DexModule::add_liquidity( + Origin::signed(ALICE), + RENBTC, + USDJ, + 1_000, + 1_000_000, + 0, + true + )); + + let context = Context { + address: Default::default(), + caller: alice_evm_addr(), + apparent_value: Default::default(), + }; + + // array_size + action + who + path_len + currency_id_a + currency_id_b + + // target_amount + max_supply_amount + let mut input = [0u8; 9 * 32]; + // array size + U256::default().to_big_endian(&mut input[0 * 32..1 * 32]); + // action + input[1 * 32..4 + 1 * 32].copy_from_slice(&Into::::into(dex::Action::SwapWithExactTarget).to_be_bytes()); + // who + U256::from(alice_evm_addr().as_bytes()).to_big_endian(&mut input[4 + 1 * 32..4 + 2 * 32]); + // skip offset + // target_amount + U256::from(1).to_big_endian(&mut input[4 + 3 * 32..4 + 4 * 32]); + // max_supply_amount + U256::from(1).to_big_endian(&mut input[4 + 4 * 32..4 + 5 * 32]); + // path_len + U256::from(2).to_big_endian(&mut input[4 + 5 * 32..4 + 6 * 32]); + // RENBTC + U256::from_big_endian(&renbtc_evm_address().as_bytes()).to_big_endian(&mut input[4 + 6 * 32..4 + 7 * 32]); + // USDJ + U256::from_big_endian(&usdj_evm_address().as_bytes()).to_big_endian(&mut input[4 + 7 * 32..4 + 8 * 32]); + + let mut expected_output = [0u8; 32]; + U256::from(1).to_big_endian(&mut expected_output[..32]); + + let (reason, output, used_gas) = DexPrecompile::execute(&input, None, &context).unwrap(); + assert_eq!(reason, ExitSucceed::Returned); + assert_eq!(output, expected_output); + assert_eq!(used_gas, 0); + }); +} + +#[test] +fn task_id_max_and_min() { + let task_id = TaskInfo { + prefix: b"ScheduleCall".to_vec(), + id: u32::MAX, + sender: H160::default(), + fee: Balance::MAX, + } + .encode(); + + assert_eq!(54, task_id.len()); + + let task_id = TaskInfo { + prefix: b"ScheduleCall".to_vec(), + id: u32::MIN, + sender: H160::default(), + fee: Balance::MIN, + } + .encode(); + + assert_eq!(38, task_id.len()); +} From 96d39b8d61f50507bd7f9bfd853fb5296454dd83 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:44:52 +0800 Subject: [PATCH 73/83] Rename SerpTreasury PalleId --- lib-serml/serp-auction/src/mock.rs | 2 +- lib-serml/serp-treasury/src/mock.rs | 2 +- lib-serml/setters-manager/src/mock.rs | 2 +- lib-serml/settmint-engine/src/mock.rs | 2 +- lib-serml/settway/src/mock.rs | 2 +- runtime/neom/src/lib.rs | 2 +- runtime/newrome/src/lib.rs | 2 +- runtime/setheum/src/lib.rs | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib-serml/serp-auction/src/mock.rs b/lib-serml/serp-auction/src/mock.rs index b5955861e..0355fb195 100644 --- a/lib-serml/serp-auction/src/mock.rs +++ b/lib-serml/serp-auction/src/mock.rs @@ -192,7 +192,7 @@ parameter_types! { pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. diff --git a/lib-serml/serp-treasury/src/mock.rs b/lib-serml/serp-treasury/src/mock.rs index 0376d10b1..922bb4e95 100644 --- a/lib-serml/serp-treasury/src/mock.rs +++ b/lib-serml/serp-treasury/src/mock.rs @@ -271,7 +271,7 @@ parameter_types! { pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/treasury"); pub const SettPayTreasuryPalletId: PalletId = PalletId(*b"set/settpay"); diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/setters-manager/src/mock.rs index 315bfdd31..60aae271a 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/setters-manager/src/mock.rs @@ -249,7 +249,7 @@ parameter_types! { pub EnabledTradingPairs: Vec = vec![TradingPair::new(USDJ, SETT)]; pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index 9fcfed01d..c65c99ced 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -282,7 +282,7 @@ parameter_types! { pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index 3d461ba9e..a3a236408 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -233,7 +233,7 @@ parameter_types! { pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT pub const GetDexerCurrencyId: CurrencyId = SDEX; // SettinDEX currency ticker is SDEX - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index cb8c06c25..1372e6eb5 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -129,7 +129,7 @@ parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index 32df80292..f95273b7f 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -131,7 +131,7 @@ parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index ef558d920..7b2ea3206 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -130,7 +130,7 @@ parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); @@ -931,7 +931,7 @@ impl dex::Config for Runtime { parameter_types! { pub const MaxAuctionsCount: u32 = 258; - pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/settmintt"); + pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks pub SerplusSerpupRatio: Permill = Permill::from_percent(10); // 10% of SerpUp to buy back & burn NativeCurrency. pub SettPaySerpupRatio: Permill = Permill::from_percent(60); // 60% of SerpUp to SettPay as Cashdrops. From d680e02cd80a56d24c70290e7346ec0ad320dbda Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 01:48:44 +0800 Subject: [PATCH 74/83] Rename SettersManager to SettmintManager --- Cargo.lock | 12 +- lib-serml/setters-manager/src/tests.rs | 167 ------------------ lib-serml/settmint-engine/Cargo.toml | 4 +- lib-serml/settmint-engine/src/lib.rs | 8 +- lib-serml/settmint-engine/src/mock.rs | 8 +- lib-serml/settmint-engine/src/tests.rs | 12 +- .../Cargo.toml | 2 +- .../src/lib.rs | 6 +- .../src/mock.rs | 10 +- lib-serml/settmint-manager/src/tests.rs | 167 ++++++++++++++++++ lib-serml/settway/Cargo.toml | 4 +- lib-serml/settway/src/lib.rs | 2 +- lib-serml/settway/src/mock.rs | 8 +- lib-serml/settway/src/tests.rs | 8 +- runtime/neom/Cargo.toml | 6 +- runtime/neom/src/lib.rs | 10 +- runtime/newrome/Cargo.toml | 6 +- .../newrome/src/benchmarking/incentives.rs | 2 +- runtime/newrome/src/lib.rs | 10 +- runtime/setheum/Cargo.toml | 6 +- runtime/setheum/src/lib.rs | 10 +- 21 files changed, 234 insertions(+), 234 deletions(-) delete mode 100644 lib-serml/setters-manager/src/tests.rs rename lib-serml/{setters-manager => settmint-manager}/Cargo.toml (98%) rename lib-serml/{setters-manager => settmint-manager}/src/lib.rs (98%) rename lib-serml/{setters-manager => settmint-manager}/src/mock.rs (97%) create mode 100644 lib-serml/settmint-manager/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 1a0c032f2..80eaa2360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4105,7 +4105,7 @@ dependencies = [ "setheum-settway", "setheum-support", "setheum-transaction-payment", - "setters-manager", + "settmint-manager", "smallvec 1.6.1", "sp-api 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -4198,7 +4198,7 @@ dependencies = [ "setheum-settway", "setheum-support", "setheum-transaction-payment", - "setters-manager", + "settmint-manager", "smallvec 1.6.1", "sp-api 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -7829,7 +7829,7 @@ dependencies = [ "setheum-settway", "setheum-support", "setheum-transaction-payment", - "setters-manager", + "settmint-manager", "smallvec 1.6.1", "sp-api 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -7915,7 +7915,7 @@ dependencies = [ "setheum-dex", "setheum-primitives", "setheum-support", - "setters-manager", + "settmint-manager", "sp-application-crypto 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp-io 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -7939,7 +7939,7 @@ dependencies = [ "setheum-primitives", "setheum-settmint-engine", "setheum-support", - "setters-manager", + "settmint-manager", "sp-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp-io 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp-runtime 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", @@ -7985,7 +7985,7 @@ dependencies = [ ] [[package]] -name = "setters-manager" +name = "settmint-manager" version = "0.7.1" dependencies = [ "frame-support 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", diff --git a/lib-serml/setters-manager/src/tests.rs b/lib-serml/setters-manager/src/tests.rs deleted file mode 100644 index 0e91eb4f7..000000000 --- a/lib-serml/setters-manager/src/tests.rs +++ /dev/null @@ -1,167 +0,0 @@ -// This file is part of Setheum. - -// Copyright (C) 2019-2021 Setheum Labs. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// 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 General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Unit tests for the setters-manager module. - -#![cfg(test)] - -use super::*; -use frame_support::{assert_noop, assert_ok}; -use mock::{Event, *}; - -#[test] -fn standards_key() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); - assert_ok!(SettersManagerModule::adjust_position(&ALICE, EURJ, 100, 100)); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 100); - assert_ok!(SettersManagerModule::adjust_position(&ALICE, EURJ, -100, -100)); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); - }); -} - -#[test] -fn check_update_reserve_overflow_work() { - ExtBuilder::default().build().execute_with(|| { - // reserve underflow - assert_noop!( - SettersManagerModule::update_reserve(&ALICE, EURJ, -100, 0), - Error::::ReserveTooLow, - ); - - // standard underflow - assert_noop!( - SettersManagerModule::update_reserve(&ALICE, EURJ, 0, -100), - Error::::StandardTooLow, - ); - }); -} - -#[test] -fn adjust_position_should_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - - // balance too low - assert_eq!(SettersManagerModule::adjust_position(&ALICE, EURJ, 2000, 0).is_ok(), false); - - // mock can't pass position valid check - assert_eq!(SettersManagerModule::adjust_position(&ALICE, USDJ, 500, 0).is_ok(), false); - - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - assert_eq!(Currencies::free_balance(EURJ, &SettersManagerModule::account_id()), 0); - assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 0); - assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 0); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(Currencies::free_balance(EURJ, &ALICE), 0); - - // success - assert_ok!(SettersManagerModule::adjust_position(&ALICE, EURJ, 500, 300)); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 500); - assert_eq!(Currencies::free_balance(SETT, &SettersManagerModule::account_id()), 500); - assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 300); - assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 500); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 300); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 500); - assert_eq!(Currencies::free_balance(EURJ, &ALICE), 150); - - System::assert_last_event(Event::setters_manager(crate::Event::PositionUpdated(ALICE, EURJ, 500, 300))); - }); -} - -#[test] -fn transfer_reserve_should_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - assert_ok!(SettersManagerModule::update_reserve(&ALICE, EURJ, 400, 500)); - assert_ok!(SettersManagerModule::update_reserve(&BOB, EURJ, 100, 600)); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 500); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 400); - assert_eq!(SettersManagerModule::positions(EURJ, &BOB).standard, 600); - assert_eq!(SettersManagerModule::positions(EURJ, &BOB).reserve, 100); - - assert_ok!(SettersManagerModule::transfer_reserve(&ALICE, &BOB, EURJ)); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(SettersManagerModule::positions(EURJ, &BOB).standard, 1100); - assert_eq!(SettersManagerModule::positions(EURJ, &BOB).reserve, 500); - - System::assert_last_event(Event::setters_manager(crate::Event::TransferReserve(ALICE, BOB, EURJ))); - }); -} - -#[test] -fn update_reserve_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Currencies::free_balance(SETT, &SettersManagerModule::account_id()), 0); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 0); - assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 0); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(>::contains_key(EURJ, &ALICE), false); - - let alice_ref_count_0 = System::consumers(&ALICE); - - assert_ok!(SettersManagerModule::update_reserve(&ALICE, EURJ, 3000, 2000)); - - // just update records - assert_eq!(SettersManagerModule::total_positions(EURJ).standard, 2000); - assert_eq!(SettersManagerModule::total_positions(EURJ).reserve, 3000); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 2000); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 3000); - - // increase ref count when open new position - let alice_ref_count_1 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_1, alice_ref_count_0 + 1); - - // dot not manipulate balance - assert_eq!(Currencies::free_balance(SETT, &SettersManagerModule::account_id()), 0); - assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); - - // should remove position storage if zero - assert_eq!(>::contains_key(EURJ, &ALICE), true); - assert_ok!(SettersManagerModule::update_reserve(&ALICE, EURJ, -3000, -2000)); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).standard, 0); - assert_eq!(SettersManagerModule::positions(EURJ, &ALICE).reserve, 0); - assert_eq!(>::contains_key(EURJ, &ALICE), false); - - // decrease ref count after remove position - let alice_ref_count_2 = System::consumers(&ALICE); - assert_eq!(alice_ref_count_2, alice_ref_count_1 - 1); - }); -} - -#[test] -fn total_reserve_works() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(SettersManagerModule::total_reserve(0); - assert_ok!(Currencies::deposit(SETT,&SettersManagerModule::account_id()), 10)); - assert_eq!(SettersManagerModule::total_reserve(10); - }); -} - -#[test] -fn get_total_reserve_works() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettersManagerModule::deposit_setter(&ALICE, 500)); - assert_eq!(SettersManagerModule::get_total_reserve(500); - }); -} diff --git a/lib-serml/settmint-engine/Cargo.toml b/lib-serml/settmint-engine/Cargo.toml index eeb765a77..39d6e7f20 100644 --- a/lib-serml/settmint-engine/Cargo.toml +++ b/lib-serml/settmint-engine/Cargo.toml @@ -24,7 +24,7 @@ orml-utilities = { path = "../../lib-openrml/utilities", default-features = fals # local dependencies support = { package = "setheum-support", path = "../support", default-features = false } -setters-manager = { package = "setters-manager", path = "../setters-manager", default-features = false } +settmint-manager = { package = "settmint-manager", path = "../settmint-manager", default-features = false } primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } [dev-dependencies] @@ -48,7 +48,7 @@ std = [ "sp-runtime/std", "sp-std/std", "support/std", - "setters-manager/std", + "settmint-manager/std", "primitives/std", "orml-utilities/std", ] diff --git a/lib-serml/settmint-engine/src/lib.rs b/lib-serml/settmint-engine/src/lib.rs index 335c3e3b6..ca0571774 100644 --- a/lib-serml/settmint-engine/src/lib.rs +++ b/lib-serml/settmint-engine/src/lib.rs @@ -33,7 +33,7 @@ use frame_system::{ offchain::{SendTransactionTypes, SubmitTransaction}, pallet_prelude::*, }; -use setters_manager::Position; +use settmint_manager::Position; use orml_traits::Change; use orml_utilities::{IterableStorageDoubleMapExtended, OffchainErr}; use primitives::{Amount, Balance, CurrencyId}; @@ -65,7 +65,7 @@ pub const OFFCHAIN_WORKER_MAX_ITERATIONS: &[u8] = b"setheum/settmint-engine/max- pub const LOCK_DURATION: u64 = 100; pub const DEFAULT_MAX_ITERATIONS: u32 = 1000; -pub type SettersManagerOf = setters_manager::Module; +pub type SettmintManagerOf = settmint_manager::Module; // typedef to help polkadot.js disambiguate Change with different generic // parameters @@ -78,7 +78,7 @@ pub mod module { use super::*; #[pallet::config] - pub trait Config: frame_system::Config + setters_manager::Config + SendTransactionTypes> { + pub trait Config: frame_system::Config + settmint_manager::Config + SendTransactionTypes> { type Event: From> + IsType<::Event>; /// The list of valid standard currency types @@ -187,7 +187,7 @@ impl Pallet { T::StandardCurrencyIds::get().contains(¤cy_id), Error::::InvalidStandardType, ); - >::adjust_position(who, currency_id, reserve_adjustment, standard_adjustment)?; + >::adjust_position(who, currency_id, reserve_adjustment, standard_adjustment)?; Ok(()) } } diff --git a/lib-serml/settmint-engine/src/mock.rs b/lib-serml/settmint-engine/src/mock.rs index c65c99ced..ff14066e4 100644 --- a/lib-serml/settmint-engine/src/mock.rs +++ b/lib-serml/settmint-engine/src/mock.rs @@ -161,16 +161,16 @@ impl orml_currencies::Config for Runtime { } parameter_types! { - pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); } -impl setters_manager::Config for Runtime { +impl settmint_manager::Config for Runtime { type Event = Event; type Convert = StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngineModule; type SerpTreasury = SerpTreasuryModule; - type PalletId = SettersManagerPalletId; + type PalletId = SettmintManagerPalletId; type OnUpdateSetter = (); } @@ -409,7 +409,7 @@ construct_runtime!( SerpTreasuryModule: serp_treasury::{Module, Storage, Call, Config, Event}, Currencies: orml_currencies::{Module, Call, Event}, Tokens: orml_tokens::{Module, Storage, Event, Config}, - SettersManagerModule: setters_manager::{Module, Storage, Call, Event}, + SettmintManagerModule: settmint_manager::{Module, Storage, Call, Event}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, SetheumDEX: dex::{Module, Storage, Call, Event, Config}, } diff --git a/lib-serml/settmint-engine/src/tests.rs b/lib-serml/settmint-engine/src/tests.rs index f6a873f4a..e769ad57e 100644 --- a/lib-serml/settmint-engine/src/tests.rs +++ b/lib-serml/settmint-engine/src/tests.rs @@ -79,19 +79,19 @@ fn adjust_position_work() { ); assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 0); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 0); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 0); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).standard, 0); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).reserve, 0); assert_ok!(SettmintEngineModule::adjust_position(&ALICE, SETT, 100, 50)); assert_eq!(Currencies::free_balance(SETT, &ALICE), 900); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 50); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 50); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 100); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).standard, 50); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).reserve, 100); assert_eq!(SettmintEngineModule::adjust_position(&ALICE, SETT, 0, 20).is_ok(), false); assert_ok!(SettmintEngineModule::adjust_position(&ALICE, SETT, 0, -20)); assert_eq!(Currencies::free_balance(SETT, &ALICE), 900); assert_eq!(Currencies::free_balance(USDJ, &ALICE), 30); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 30); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 100); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).standard, 30); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).reserve, 100); }); } diff --git a/lib-serml/setters-manager/Cargo.toml b/lib-serml/settmint-manager/Cargo.toml similarity index 98% rename from lib-serml/setters-manager/Cargo.toml rename to lib-serml/settmint-manager/Cargo.toml index b1401bb46..8439cca28 100644 --- a/lib-serml/setters-manager/Cargo.toml +++ b/lib-serml/settmint-manager/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "setters-manager" +name = "settmint-manager" version = "0.7.1" authors = ["Setheum Labs"] edition = "2018" diff --git a/lib-serml/setters-manager/src/lib.rs b/lib-serml/settmint-manager/src/lib.rs similarity index 98% rename from lib-serml/setters-manager/src/lib.rs rename to lib-serml/settmint-manager/src/lib.rs index 351eaa234..39927f697 100644 --- a/lib-serml/setters-manager/src/lib.rs +++ b/lib-serml/settmint-manager/src/lib.rs @@ -16,11 +16,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! # SettersManager Module +//! # SettmintManager Module //! //! ## Overview //! -//! SettersManager module manages Settmint's reserve asset (Setter) +//! SettmintManager module manages Settmint's reserve asset (Setter) //! and the standards backed by the asset (SettCurrencies). #![cfg_attr(not(feature = "std"), no_std)] @@ -64,7 +64,7 @@ pub mod module { type Convert: Convert<(CurrencyId, Balance), Balance>; /// Currency type for deposit/withdraw reserve assets - /// to/from setters-manager module + /// to/from settmint-manager module type Currency: MultiCurrencyExtended< Self::AccountId, CurrencyId = CurrencyId, diff --git a/lib-serml/setters-manager/src/mock.rs b/lib-serml/settmint-manager/src/mock.rs similarity index 97% rename from lib-serml/setters-manager/src/mock.rs rename to lib-serml/settmint-manager/src/mock.rs index 60aae271a..7171c155b 100644 --- a/lib-serml/setters-manager/src/mock.rs +++ b/lib-serml/settmint-manager/src/mock.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Mocks for the setters-manager module. +//! Mocks for the settmint-manager module. #![cfg(test)] @@ -82,7 +82,7 @@ pub const TZSJ: CurrencyId = CurrencyId::Token(TokenSymbol::TZSJ); pub const USDJ: CurrencyId = CurrencyId::Token(TokenSymbol::USDJ); pub const ZARJ: CurrencyId = CurrencyId::Token(TokenSymbol::ZARJ); -mod setters_manager { +mod settmint_manager { pub use super::super::*; } @@ -342,7 +342,7 @@ parameter_types! { ZARJ, ]; pub const GetReserveCurrencyId: CurrencyId = SETT; - pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); } @@ -354,7 +354,7 @@ impl Config for Runtime { type GetReserveCurrencyId = GetReserveCurrencyId; type StandardValidator = MockStandardValidator; type SerpTreasury = SerpTreasuryModule; - type PalletId = SettersManagerPalletId; + type PalletId = SettmintManagerPalletId; type OnUpdateSetter = (); } @@ -368,7 +368,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Module, Call, Storage, Config, Event}, - SettersManagerModule: setters_manager::{Module, Storage, Call, Event}, + SettmintManagerModule: settmint_manager::{Module, Storage, Call, Event}, Tokens: orml_tokens::{Module, Storage, Event, Config}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, Currencies: orml_currencies::{Module, Call, Event}, diff --git a/lib-serml/settmint-manager/src/tests.rs b/lib-serml/settmint-manager/src/tests.rs new file mode 100644 index 000000000..1f5519829 --- /dev/null +++ b/lib-serml/settmint-manager/src/tests.rs @@ -0,0 +1,167 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Unit tests for the settmint-manager module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::{Event, *}; + +#[test] +fn standards_key() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_ok!(SettmintManagerModule::adjust_position(&ALICE, EURJ, 100, 100)); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 100); + assert_ok!(SettmintManagerModule::adjust_position(&ALICE, EURJ, -100, -100)); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0); + }); +} + +#[test] +fn check_update_reserve_overflow_work() { + ExtBuilder::default().build().execute_with(|| { + // reserve underflow + assert_noop!( + SettmintManagerModule::update_reserve(&ALICE, EURJ, -100, 0), + Error::::ReserveTooLow, + ); + + // standard underflow + assert_noop!( + SettmintManagerModule::update_reserve(&ALICE, EURJ, 0, -100), + Error::::StandardTooLow, + ); + }); +} + +#[test] +fn adjust_position_should_work() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + + // balance too low + assert_eq!(SettmintManagerModule::adjust_position(&ALICE, EURJ, 2000, 0).is_ok(), false); + + // mock can't pass position valid check + assert_eq!(SettmintManagerModule::adjust_position(&ALICE, USDJ, 500, 0).is_ok(), false); + + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + assert_eq!(Currencies::free_balance(EURJ, &SettmintManagerModule::account_id()), 0); + assert_eq!(SettmintManagerModule::total_positions(EURJ).standard, 0); + assert_eq!(SettmintManagerModule::total_positions(EURJ).reserve, 0); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(Currencies::free_balance(EURJ, &ALICE), 0); + + // success + assert_ok!(SettmintManagerModule::adjust_position(&ALICE, EURJ, 500, 300)); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 500); + assert_eq!(Currencies::free_balance(SETT, &SettmintManagerModule::account_id()), 500); + assert_eq!(SettmintManagerModule::total_positions(EURJ).standard, 300); + assert_eq!(SettmintManagerModule::total_positions(EURJ).reserve, 500); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 300); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 500); + assert_eq!(Currencies::free_balance(EURJ, &ALICE), 150); + + System::assert_last_event(Event::settmint_manager(crate::Event::PositionUpdated(ALICE, EURJ, 500, 300))); + }); +} + +#[test] +fn transfer_reserve_should_work() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + assert_ok!(SettmintManagerModule::update_reserve(&ALICE, EURJ, 400, 500)); + assert_ok!(SettmintManagerModule::update_reserve(&BOB, EURJ, 100, 600)); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 500); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 400); + assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).standard, 600); + assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).reserve, 100); + + assert_ok!(SettmintManagerModule::transfer_reserve(&ALICE, &BOB, EURJ)); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).standard, 1100); + assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).reserve, 500); + + System::assert_last_event(Event::settmint_manager(crate::Event::TransferReserve(ALICE, BOB, EURJ))); + }); +} + +#[test] +fn update_reserve_should_work() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(Currencies::free_balance(SETT, &SettmintManagerModule::account_id()), 0); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + assert_eq!(SettmintManagerModule::total_positions(EURJ).standard, 0); + assert_eq!(SettmintManagerModule::total_positions(EURJ).reserve, 0); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(>::contains_key(EURJ, &ALICE), false); + + let alice_ref_count_0 = System::consumers(&ALICE); + + assert_ok!(SettmintManagerModule::update_reserve(&ALICE, EURJ, 3000, 2000)); + + // just update records + assert_eq!(SettmintManagerModule::total_positions(EURJ).standard, 2000); + assert_eq!(SettmintManagerModule::total_positions(EURJ).reserve, 3000); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 2000); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 3000); + + // increase ref count when open new position + let alice_ref_count_1 = System::consumers(&ALICE); + assert_eq!(alice_ref_count_1, alice_ref_count_0 + 1); + + // dot not manipulate balance + assert_eq!(Currencies::free_balance(SETT, &SettmintManagerModule::account_id()), 0); + assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000); + + // should remove position storage if zero + assert_eq!(>::contains_key(EURJ, &ALICE), true); + assert_ok!(SettmintManagerModule::update_reserve(&ALICE, EURJ, -3000, -2000)); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0); + assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 0); + assert_eq!(>::contains_key(EURJ, &ALICE), false); + + // decrease ref count after remove position + let alice_ref_count_2 = System::consumers(&ALICE); + assert_eq!(alice_ref_count_2, alice_ref_count_1 - 1); + }); +} + +#[test] +fn total_reserve_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(SettmintManagerModule::total_reserve(0); + assert_ok!(Currencies::deposit(SETT,&SettmintManagerModule::account_id()), 10)); + assert_eq!(SettmintManagerModule::total_reserve(10); + }); +} + +#[test] +fn get_total_reserve_works() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(SettmintManagerModule::deposit_setter(&ALICE, 500)); + assert_eq!(SettmintManagerModule::get_total_reserve(500); + }); +} diff --git a/lib-serml/settway/Cargo.toml b/lib-serml/settway/Cargo.toml index c260ca811..dbd62a8ff 100644 --- a/lib-serml/settway/Cargo.toml +++ b/lib-serml/settway/Cargo.toml @@ -20,7 +20,7 @@ orml-tokens = { path = "../../lib-openrml/tokens", default-features = false } # local dependencies settmint-engine = { package = "setheum-settmint-engine", path = "../settmint-engine", default-features = false } -setters-manager= { package = "setters-manager", path = "../setters-manager", default-features = false } +settmint-manager= { package = "settmint-manager", path = "../settmint-manager", default-features = false } support = { package = "setheum-support", path = "../support", default-features = false } primitives = { package = "setheum-primitives", path = "../../primitives", default-features = false } @@ -42,7 +42,7 @@ std = [ "frame-system/std", "sp-std/std", "orml-tokens/std", - "setters-manager/std", + "settmint-manager/std", "settmint-engine/std", "support/std", "primitives/std", diff --git a/lib-serml/settway/src/lib.rs b/lib-serml/settway/src/lib.rs index 20b4dc45d..9ab1e1e1c 100644 --- a/lib-serml/settway/src/lib.rs +++ b/lib-serml/settway/src/lib.rs @@ -149,7 +149,7 @@ pub mod module { let to = ensure_signed(origin)?; let from = T::Lookup::lookup(from)?; Self::check_authorization(&from, &to, currency_id)?; - >::transfer_reserve(&from, &to, currency_id)?; + >::transfer_reserve(&from, &to, currency_id)?; Ok(().into()) } diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settway/src/mock.rs index a3a236408..ccbd4855a 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settway/src/mock.rs @@ -325,10 +325,10 @@ impl settmint_engine::Config for Runtime { } parameter_types! { - pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); } -impl setters_manager::Config for Runtime { +impl settmint_manager::Config for Runtime { type Event = Event; type Convert = settmint_engine::StandardExchangeRateConvertor; type Currency = Tokens; @@ -336,7 +336,7 @@ impl setters_manager::Config for Runtime { type GetReserveCurrencyId = GetReserveCurrencyId; type StandardValidator = SettmintEngineModule; type SerpTreasury = SerpTreasuryModule; - type PalletId = SettersManagerPalletId; + type PalletId = SettmintManagerPalletId; type OnUpdateSetter = (); } @@ -354,7 +354,7 @@ construct_runtime!( Tokens: orml_tokens::{Module, Storage, Event, Config}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, Currencies: orml_currencies::{Module, Call, Event}, - SettersManagerModule: setters_manager::{Module, Storage, Call, Event}, + SettmintManagerModule: settmint_manager::{Module, Storage, Call, Event}, SerpTreasuryModule: serp_treasury::{Module, Storage, Call, Event}, SettmintEngineModule: settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, } diff --git a/lib-serml/settway/src/tests.rs b/lib-serml/settway/src/tests.rs index 1eb222553..060856def 100644 --- a/lib-serml/settway/src/tests.rs +++ b/lib-serml/settway/src/tests.rs @@ -83,8 +83,8 @@ fn transfer_position_from_should_work() { assert_ok!(SettwayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); assert_ok!(SettwayModule::transfer_position_from(Origin::signed(BOB), SETT, ALICE)); - assert_eq!(SettersManagerModule::positions(SETT, BOB).reserve, 100); - assert_eq!(SettersManagerModule::positions(SETT, BOB).standard, 50); + assert_eq!(SettmintManagerModule::positions(SETT, BOB).reserve, 100); + assert_eq!(SettmintManagerModule::positions(SETT, BOB).standard, 50); }); } @@ -102,7 +102,7 @@ fn transfer_unauthorization_setters_should_not_work() { fn adjust_position_should_work() { ExtBuilder::default().build().execute_with(|| { assert_ok!(SettwayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).reserve, 100); - assert_eq!(SettersManagerModule::positions(SETT, ALICE).standard, 50); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).reserve, 100); + assert_eq!(SettmintManagerModule::positions(SETT, ALICE).standard, 50); }); } diff --git a/runtime/neom/Cargo.toml b/runtime/neom/Cargo.toml index 8051edf3d..b191fb963 100644 --- a/runtime/neom/Cargo.toml +++ b/runtime/neom/Cargo.toml @@ -78,7 +78,7 @@ serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = fal setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-settway = { path = "../../lib-serml/settway", default-features = false } -setters-manager = { path = "../../lib-serml/setters-manager", default-features = false } +settmint-manager = { path = "../../lib-serml/settmint-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } setheum-incentives = { path = "../../lib-serml/incentives", default-features = false } @@ -155,7 +155,7 @@ std = [ "setheum-dex/std", "setheum-currencies/std", "setheum-settway/std", - "setters-manager/std", + "settmint-manager/std", "setheum-nft/std", "setheum-prices/std", "setheum-incentives/std", @@ -230,7 +230,7 @@ try-runtime = [ "setheum-currencies/try-runtime", "setheum-dex/try-runtime", "setheum-settway/try-runtime", - "setters-manager/try-runtime", + "settmint-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", "setheum-incentives/try-runtime", diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index 1372e6eb5..9671d64c6 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -127,7 +127,7 @@ impl_opaque_keys! { // Module accounts of runtime parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); - pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); @@ -139,7 +139,7 @@ parameter_types! { pub fn get_all_setheum_accounts() -> Vec { vec![ SetheumTreasuryPalletId::get().into_account(), - SettersManagerPalletId::get().into_account(), + SettmintManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), @@ -812,13 +812,13 @@ impl serp_auction::Config for Runtime { type WeightInfo = weights::serp_auction::WeightInfo; } -impl setters_manager::Config for Runtime { +impl settmint_manager::Config for Runtime { type Event = Event; type Convert = setheum_settmint_engine::StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngine; type SerpTreasury = SerpTreasury; - type PalletId = SettersManagerPalletId; + type PalletId = SettmintManagerPalletId; type OnUpdateSetter = setheum_incentives::OnUpdateSetter; } @@ -1125,7 +1125,7 @@ construct_runtime!( // Settway SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, - SettersManager: setters_manager::{Module, Storage, Call, Event}, + SettmintManager: settmint_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, diff --git a/runtime/newrome/Cargo.toml b/runtime/newrome/Cargo.toml index 9e12898c2..5b51b01ca 100644 --- a/runtime/newrome/Cargo.toml +++ b/runtime/newrome/Cargo.toml @@ -80,7 +80,7 @@ serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = fal setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-settway = { path = "../../lib-serml/settway", default-features = false } -setters-manager = { path = "../../lib-serml/setters-manager", default-features = false } +settmint-manager = { path = "../../lib-serml/settmint-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } setheum-incentives = { path = "../../lib-serml/incentives", default-features = false } @@ -159,7 +159,7 @@ std = [ "setheum-dex/std", "setheum-currencies/std", "setheum-settway/std", - "setters-manager/std", + "settmint-manager/std", "setheum-nft/std", "setheum-prices/std", "setheum-incentives/std", @@ -236,7 +236,7 @@ try-runtime = [ "setheum-currencies/try-runtime", "setheum-dex/try-runtime", "setheum-settway/try-runtime", - "setters-manager/try-runtime", + "settmint-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", "setheum-incentives/try-runtime", diff --git a/runtime/newrome/src/benchmarking/incentives.rs b/runtime/newrome/src/benchmarking/incentives.rs index 4b4d29be1..48c2e7b5e 100644 --- a/runtime/newrome/src/benchmarking/incentives.rs +++ b/runtime/newrome/src/benchmarking/incentives.rs @@ -53,7 +53,7 @@ runtime_benchmarks! { claim_rewards { let caller: AccountId = account("caller", 0, SEED); - let pool_id = PoolId::SettersManager(rSETT); + let pool_id = PoolId::SettmintManager(rSETT); Rewards::add_share(&caller, pool_id, 100); orml_rewards::Pools::::mutate(pool_id, |pool_info| { diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index f95273b7f..44ba1552c 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -129,7 +129,7 @@ impl_opaque_keys! { // Module accounts of runtime parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); - pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); @@ -140,7 +140,7 @@ pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub fn get_all_setheum_accounts() -> Vec { vec![ SetheumTreasuryPalletId::get().into_account(), - SettersManagerPalletId::get().into_account(), + SettmintManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), @@ -813,13 +813,13 @@ impl serp_auction::Config for Runtime { type WeightInfo = weights::serp_auction::WeightInfo; } -impl setters_manager::Config for Runtime { +impl settmint_manager::Config for Runtime { type Event = Event; type Convert = setheum_settmint_engine::StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngine; type SerpTreasury = SerpTreasury; - type PalletId = SettersManagerPalletId; + type PalletId = SettmintManagerPalletId; type OnUpdateSetter = setheum_incentives::OnUpdateSetter; } @@ -1126,7 +1126,7 @@ construct_runtime!( // Settway SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, - SettersManager: setters_manager::{Module, Storage, Call, Event}, + SettmintManager: settmint_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, diff --git a/runtime/setheum/Cargo.toml b/runtime/setheum/Cargo.toml index 27fa3073a..980a8325a 100644 --- a/runtime/setheum/Cargo.toml +++ b/runtime/setheum/Cargo.toml @@ -77,7 +77,7 @@ serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = fal setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } setheum-settway = { path = "../../lib-serml/settway", default-features = false } -setters-manager = { path = "../../lib-serml/setters-manager", default-features = false } +settmint-manager = { path = "../../lib-serml/settmint-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } setheum-incentives = { path = "../../lib-serml/incentives", default-features = false } @@ -154,7 +154,7 @@ std = [ "setheum-currencies/std", "setheum-dex/std", "setheum-settway/std", - "setters-manager/std", + "settmint-manager/std", "setheum-nft/std", "setheum-prices/std", "setheum-incentives/std", @@ -232,7 +232,7 @@ try-runtime = [ "setheum-currencies/try-runtime", "setheum-dex/try-runtime", "setheum-settway/try-runtime", - "setters-manager/try-runtime", + "settmint-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", "setheum-incentives/try-runtime", diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index 7b2ea3206..f1d09a1d7 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -128,7 +128,7 @@ impl_opaque_keys! { // Module accounts of runtime parameter_types! { pub const SetheumTreasuryPalletId: PalletId = PalletId(*b"set/trsy"); - pub const SettersManagerPalletId: PalletId = PalletId(*b"set/setter"); + pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); @@ -139,7 +139,7 @@ parameter_types! { pub fn get_all_setheum_accounts() -> Vec { vec![ SetheumTreasuryPalletId::get().into_account(), - SettersManagerPalletId::get().into_account(), + SettmintManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), SettwayTreasuryPalletId::get().into_account(), @@ -813,13 +813,13 @@ impl serp_auction::Config for Runtime { type WeightInfo = weights::serp_auction::WeightInfo; } -impl setters_manager::Config for Runtime { +impl settmint_manager::Config for Runtime { type Event = Event; type Convert = setheum_settmint_engine::StandardExchangeRateConvertor; type Currency = Currencies; type StandardValidator = SettmintEngine; type SerpTreasury = SerpTreasury; - type PalletId = SettersManagerPalletId; + type PalletId = SettmintManagerPalletId; type OnUpdateSetter = setheum_incentives::OnUpdateSetter; } @@ -1126,7 +1126,7 @@ construct_runtime!( // Settway SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, - SettersManager: setters_manager::{Module, Storage, Call, Event}, + SettmintManager: settmint_manager::{Module, Storage, Call, Event}, Settway: setheum_settway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, From 89a3437c1c29abd76e77ce014d004cf2a555d615 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 02:08:15 +0800 Subject: [PATCH 75/83] Rename settway to settmint_gateway and remove SettwayTreasury --- Cargo.lock | 8 ++-- .../{settway => settmint-gateway}/Cargo.toml | 2 +- .../{settway => settmint-gateway}/src/lib.rs | 2 +- .../{settway => settmint-gateway}/src/mock.rs | 8 ++-- .../src/tests.rs | 40 ++++++++-------- .../src/weights.rs | 10 ++-- .../service/src/chain_spec/newrome.rs | 8 ++-- node/setheum/service/src/chain_spec/neom.rs | 4 +- .../setheum/service/src/chain_spec/newrome.rs | 8 ++-- .../setheum/service/src/chain_spec/setheum.rs | 4 +- runtime/neom/Cargo.toml | 6 +-- runtime/neom/src/authority.rs | 16 ++----- runtime/neom/src/lib.rs | 48 +++++++++---------- runtime/neom/src/weights/mod.rs | 2 +- runtime/neom/src/weights/settway.rs | 6 +-- runtime/newrome/Cargo.toml | 6 +-- runtime/newrome/src/authority.rs | 15 ++---- runtime/newrome/src/benchmarking/mod.rs | 2 +- runtime/newrome/src/benchmarking/settway.rs | 12 ++--- runtime/newrome/src/lib.rs | 48 +++++++++---------- runtime/newrome/src/weights/mod.rs | 2 +- runtime/newrome/src/weights/settway.rs | 6 +-- runtime/setheum/Cargo.toml | 6 +-- runtime/setheum/src/authority.rs | 15 ++---- runtime/setheum/src/lib.rs | 48 +++++++++---------- runtime/setheum/src/weights/mod.rs | 2 +- runtime/setheum/src/weights/settway.rs | 8 ++-- 27 files changed, 154 insertions(+), 188 deletions(-) rename lib-serml/{settway => settmint-gateway}/Cargo.toml (98%) rename lib-serml/{settway => settmint-gateway}/src/lib.rs (99%) rename lib-serml/{settway => settmint-gateway}/src/mock.rs (98%) rename lib-serml/{settway => settmint-gateway}/src/tests.rs (57%) rename lib-serml/{settway => settmint-gateway}/src/weights.rs (93%) diff --git a/Cargo.lock b/Cargo.lock index 80eaa2360..70fbb73fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4102,7 +4102,7 @@ dependencies = [ "setheum-prices", "setheum-primitives", "setheum-settmint-engine", - "setheum-settway", + "settmint-gateway", "setheum-support", "setheum-transaction-payment", "settmint-manager", @@ -4195,7 +4195,7 @@ dependencies = [ "setheum-prices", "setheum-primitives", "setheum-settmint-engine", - "setheum-settway", + "settmint-gateway", "setheum-support", "setheum-transaction-payment", "settmint-manager", @@ -7826,7 +7826,7 @@ dependencies = [ "setheum-prices", "setheum-primitives", "setheum-settmint-engine", - "setheum-settway", + "settmint-gateway", "setheum-support", "setheum-transaction-payment", "settmint-manager", @@ -7924,7 +7924,7 @@ dependencies = [ ] [[package]] -name = "setheum-settway" +name = "settmint-gateway" version = "0.7.1" dependencies = [ "frame-support 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", diff --git a/lib-serml/settway/Cargo.toml b/lib-serml/settmint-gateway/Cargo.toml similarity index 98% rename from lib-serml/settway/Cargo.toml rename to lib-serml/settmint-gateway/Cargo.toml index dbd62a8ff..0e6124783 100644 --- a/lib-serml/settway/Cargo.toml +++ b/lib-serml/settmint-gateway/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "setheum-settway" +name = "settmint-gateway" version = "0.7.1" authors = ["Setheum Labs"] edition = "2018" diff --git a/lib-serml/settway/src/lib.rs b/lib-serml/settmint-gateway/src/lib.rs similarity index 99% rename from lib-serml/settway/src/lib.rs rename to lib-serml/settmint-gateway/src/lib.rs index 9ab1e1e1c..97325e919 100644 --- a/lib-serml/settway/src/lib.rs +++ b/lib-serml/settmint-gateway/src/lib.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! # Settway Module +//! # SettmintGateway Module //! //! ## Overview //! diff --git a/lib-serml/settway/src/mock.rs b/lib-serml/settmint-gateway/src/mock.rs similarity index 98% rename from lib-serml/settway/src/mock.rs rename to lib-serml/settmint-gateway/src/mock.rs index ccbd4855a..3b61f6a55 100644 --- a/lib-serml/settway/src/mock.rs +++ b/lib-serml/settmint-gateway/src/mock.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Mocks for the settway module. +//! Mocks for the settmint_gateway module. #![cfg(test)] @@ -34,7 +34,7 @@ use sp_runtime::{ use sp_std::cell::RefCell; use support::{SerpAuctionManager, ExchangeRate, Price, PriceProvider, Rate, Ratio}; -mod settway { +mod settmint_gateway { pub use super::super::*; } @@ -350,7 +350,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Module, Call, Storage, Config, Event}, - Settway: settway::{Module, Storage, Call, Event}, + SettmintGateway: settmint_gateway::{Module, Storage, Call, Event}, Tokens: orml_tokens::{Module, Storage, Event, Config}, PalletBalances: pallet_balances::{Module, Call, Storage, Event}, Currencies: orml_currencies::{Module, Call, Event}, @@ -375,7 +375,7 @@ impl Config for Runtime { type Event = Event; type WeightInfo = (); } -pub type SettwayModule = Module; +pub type SettmintGatewayModule = Module; pub struct ExtBuilder { endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>, diff --git a/lib-serml/settway/src/tests.rs b/lib-serml/settmint-gateway/src/tests.rs similarity index 57% rename from lib-serml/settway/src/tests.rs rename to lib-serml/settmint-gateway/src/tests.rs index 060856def..e771aeaa8 100644 --- a/lib-serml/settway/src/tests.rs +++ b/lib-serml/settmint-gateway/src/tests.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Unit tests for the settway module. +//! Unit tests for the settmint_gateway module. #![cfg(test)] @@ -31,11 +31,11 @@ use support::{Rate, Ratio}; fn authorize_should_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - System::assert_last_event(Event::settway(crate::Event::Authorization(ALICE, BOB, SETT))); + System::assert_last_event(Event::settmint_gateway(crate::Event::Authorization(ALICE, BOB, SETT))); - assert_ok!(SettwayModule::check_authorization(&ALICE, &BOB, SETT)); + assert_ok!(SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT)); }); } @@ -43,14 +43,14 @@ fn authorize_should_work() { fn unauthorize_should_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettwayModule::check_authorization(&ALICE, &BOB, SETT)); - assert_ok!(SettwayModule::unauthorize(Origin::signed(ALICE), SETT, BOB)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); + assert_ok!(SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT)); + assert_ok!(SettmintGatewayModule::unauthorize(Origin::signed(ALICE), SETT, BOB)); - System::assert_last_event(Event::settway(crate::Event::UnAuthorization(ALICE, BOB, SETT))); + System::assert_last_event(Event::settmint_gateway(crate::Event::UnAuthorization(ALICE, BOB, SETT))); assert_noop!( - SettwayModule::check_authorization(&ALICE, &BOB, SETT), + SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT), Error::::NoAuthorization ); }); @@ -60,18 +60,18 @@ fn unauthorize_should_work() { fn unauthorize_all_should_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, CAROL)); - assert_ok!(SettwayModule::unauthorize_all(Origin::signed(ALICE))); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, CAROL)); + assert_ok!(SettmintGatewayModule::unauthorize_all(Origin::signed(ALICE))); - System::assert_last_event(Event::settway(crate::Event::UnAuthorizationAll(ALICE))); + System::assert_last_event(Event::settmint_gateway(crate::Event::UnAuthorizationAll(ALICE))); assert_noop!( - SettwayModule::check_authorization(&ALICE, &BOB, SETT), + SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT), Error::::NoAuthorization ); assert_noop!( - SettwayModule::check_authorization(&ALICE, &BOB, SETT), + SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT), Error::::NoAuthorization ); }); @@ -80,9 +80,9 @@ fn unauthorize_all_should_work() { #[test] fn transfer_position_from_should_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettwayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); - assert_ok!(SettwayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettwayModule::transfer_position_from(Origin::signed(BOB), SETT, ALICE)); + assert_ok!(SettmintGatewayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); + assert_ok!(SettmintGatewayModule::transfer_position_from(Origin::signed(BOB), SETT, ALICE)); assert_eq!(SettmintManagerModule::positions(SETT, BOB).reserve, 100); assert_eq!(SettmintManagerModule::positions(SETT, BOB).standard, 50); }); @@ -92,7 +92,7 @@ fn transfer_position_from_should_work() { fn transfer_unauthorization_setters_should_not_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SettwayModule::transfer_position_from(Origin::signed(ALICE), SETT, BOB), + SettmintGatewayModule::transfer_position_from(Origin::signed(ALICE), SETT, BOB), Error::::NoAuthorization, ); }); @@ -101,7 +101,7 @@ fn transfer_unauthorization_setters_should_not_work() { #[test] fn adjust_position_should_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettwayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); + assert_ok!(SettmintGatewayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); assert_eq!(SettmintManagerModule::positions(SETT, ALICE).reserve, 100); assert_eq!(SettmintManagerModule::positions(SETT, ALICE).standard, 50); }); diff --git a/lib-serml/settway/src/weights.rs b/lib-serml/settmint-gateway/src/weights.rs similarity index 93% rename from lib-serml/settway/src/weights.rs rename to lib-serml/settmint-gateway/src/weights.rs index 44cccedc4..ff02ee1d3 100644 --- a/lib-serml/settway/src/weights.rs +++ b/lib-serml/settmint-gateway/src/weights.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . -//! Autogenerated weights for setheum_settway +//! Autogenerated weights for settmint_gateway //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-02-26, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] @@ -28,12 +28,12 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=setheum_settway +// --pallet=settmint_gateway // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./lib-serml/settway/src/weights.rs +// --output=./lib-serml/settmint-gateway/src/weights.rs // --template=./templates/setheum-weight-template.hbs @@ -45,7 +45,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for setheum_settway. +/// Weight functions needed for settmint_gateway. pub trait WeightInfo { fn authorize() -> Weight; fn unauthorize() -> Weight; @@ -54,7 +54,7 @@ pub trait WeightInfo { fn transfer_position_from() -> Weight; } -/// Weights for setheum_settway using the Setheum node and recommended hardware. +/// Weights for settmint_gateway using the Setheum node and recommended hardware. pub struct SetheumWeight(_); impl WeightInfo for SetheumWeight { fn authorize() -> Weight { diff --git a/node/setheum-dev/service/src/chain_spec/newrome.rs b/node/setheum-dev/service/src/chain_spec/newrome.rs index 819a6c123..9f7d8d630 100644 --- a/node/setheum-dev/service/src/chain_spec/newrome.rs +++ b/node/setheum-dev/service/src/chain_spec/newrome.rs @@ -217,7 +217,7 @@ fn testnet_genesis( use newrome_runtime::{ dollar, get_all_setheum_accounts, SetheumOracleConfig, BabeConfig, Balance, BalancesConfig, BandOracleConfig, SettmintEngineConfig, SerpTreasuryConfig, DexConfig, EnabledTradingPairs, - GeneralCouncilMembershipConfig, GrandpaConfig, SettwayCouncilMembershipConfig, + GeneralCouncilMembershipConfig, GrandpaConfig, MonetaryCouncilMembershipConfig, IndicesConfig, NativeTokenExistentialDeposit, OperatorMembershipSetheumConfig, OperatorMembershipBandConfig, OrmlNFTConfig, RenVmBridgeConfig, SessionConfig, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeMembershipConfig, TokensConfig, TradingPair, VestingConfig, DNAR, SETT, USDJ, @@ -290,7 +290,7 @@ fn testnet_genesis( phantom: Default::default(), }), pallet_collective_Instance2: Some(Default::default()), - pallet_membership_Instance2: Some(SettwayCouncilMembershipConfig { + pallet_membership_Instance2: Some(MonetaryCouncilMembershipConfig { members: vec![root_key.clone()], phantom: Default::default(), }), @@ -362,7 +362,7 @@ fn newrome_genesis( cent, dollar, get_all_setheum_accounts, SetheumOracleConfig, BabeConfig, Balance, BalancesConfig, BandOracleConfig, SettmintEngineConfig, SerpTreasuryConfig, DexConfig, EnabledTradingPairs, GeneralCouncilMembershipConfig, GrandpaConfig, - SettwayCouncilMembershipConfig, IndicesConfig, NativeTokenExistentialDeposit, OperatorMembershipSetheumConfig, + MonetaryCouncilMembershipConfig, IndicesConfig, NativeTokenExistentialDeposit, OperatorMembershipSetheumConfig, OperatorMembershipBandConfig, OrmlNFTConfig, RenVmBridgeConfig, SessionConfig, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeMembershipConfig, TokensConfig, VestingConfig, DNAR, sett, USDJ, @@ -435,7 +435,7 @@ fn newrome_genesis( phantom: Default::default(), }), pallet_collective_Instance2: Some(Default::default()), - pallet_membership_Instance2: Some(SettwayCouncilMembershipConfig { + pallet_membership_Instance2: Some(MonetaryCouncilMembershipConfig { members: vec![root_key.clone()], phantom: Default::default(), }), diff --git a/node/setheum/service/src/chain_spec/neom.rs b/node/setheum/service/src/chain_spec/neom.rs index d0f6c6a79..45572dc7d 100644 --- a/node/setheum/service/src/chain_spec/neom.rs +++ b/node/setheum/service/src/chain_spec/neom.rs @@ -126,7 +126,7 @@ fn neom_genesis( use neom_runtime::{ cent, dollar, get_all_setheum_accounts, SetheumOracleConfig, BabeConfig, Balance, BalancesConfig, BandOracleConfig, SettmintEngineConfig, SerpTreasuryConfig, DexConfig, EnabledTradingPairs, - GeneralCouncilMembershipConfig, GrandpaConfig, SettwayCouncilMembershipConfig, + GeneralCouncilMembershipConfig, GrandpaConfig, MonetaryCouncilMembershipConfig, IndicesConfig, NativeTokenExistentialDeposit, OperatorMembershipSetheumConfig, OperatorMembershipBandConfig, OrmlNFTConfig, SessionConfig, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeMembershipConfig, TokensConfig, VestingConfig, NEOM, NSETT, JUSD, @@ -198,7 +198,7 @@ fn neom_genesis( phantom: Default::default(), }), pallet_collective_Instance2: Some(Default::default()), - pallet_membership_Instance2: Some(SettwayCouncilMembershipConfig { + pallet_membership_Instance2: Some(MonetaryCouncilMembershipConfig { members: vec![root_key.clone()], phantom: Default::default(), }), diff --git a/node/setheum/service/src/chain_spec/newrome.rs b/node/setheum/service/src/chain_spec/newrome.rs index 383ccef64..64bc407d4 100644 --- a/node/setheum/service/src/chain_spec/newrome.rs +++ b/node/setheum/service/src/chain_spec/newrome.rs @@ -220,7 +220,7 @@ fn testnet_genesis( use newrome_runtime::{ dollar, get_all_setheum_accounts, SetheumOracleConfig, BabeConfig, Balance, BalancesConfig, BandOracleConfig, SettmintEngineConfig, SerpTreasuryConfig, DexConfig, EnabledTradingPairs, - GeneralCouncilMembershipConfig, GrandpaConfig, SettwayCouncilMembershipConfig, + GeneralCouncilMembershipConfig, GrandpaConfig, MonetaryCouncilMembershipConfig, IndicesConfig, NativeTokenExistentialDeposit, OperatorMembershipSetheumConfig, OperatorMembershipBandConfig, OrmlNFTConfig, RenVmBridgeConfig, SessionConfig, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeMembershipConfig, TokensConfig, VestingConfig, DNAR, SETT, USDJ, @@ -292,7 +292,7 @@ fn testnet_genesis( phantom: Default::default(), }), pallet_collective_Instance2: Some(Default::default()), - pallet_membership_Instance2: Some(SettwayCouncilMembershipConfig { + pallet_membership_Instance2: Some(MonetaryCouncilMembershipConfig { members: vec![root_key.clone()], phantom: Default::default(), }), @@ -350,7 +350,7 @@ fn newrome_genesis( use newrome_runtime::{ cent, dollar, get_all_setheum_accounts, SetheumOracleConfig, BabeConfig, Balance, BalancesConfig, BandOracleConfig, SettmintEngineConfig, SerpTreasuryConfig, - DexConfig, EnabledTradingPairs, GeneralCouncilMembershipConfig, GrandpaConfig, SettwayCouncilMembershipConfig, + DexConfig, EnabledTradingPairs, GeneralCouncilMembershipConfig, GrandpaConfig, MonetaryCouncilMembershipConfig, IndicesConfig, NativeTokenExistentialDeposit, OperatorMembershipSetheumConfig, OperatorMembershipBandConfig, OrmlNFTConfig, SessionConfig, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeMembershipConfig, TokensConfig, VestingConfig, DNAR, SETT, USDJ, @@ -422,7 +422,7 @@ fn newrome_genesis( phantom: Default::default(), }), pallet_collective_Instance2: Some(Default::default()), - pallet_membership_Instance2: Some(SettwayCouncilMembershipConfig { + pallet_membership_Instance2: Some(MonetaryCouncilMembershipConfig { members: vec![root_key.clone()], phantom: Default::default(), }), diff --git a/node/setheum/service/src/chain_spec/setheum.rs b/node/setheum/service/src/chain_spec/setheum.rs index af79d782d..ab57be18b 100644 --- a/node/setheum/service/src/chain_spec/setheum.rs +++ b/node/setheum/service/src/chain_spec/setheum.rs @@ -126,7 +126,7 @@ fn setheum_genesis( use setheum_runtime::{ cent, dollar, get_all_setheum_accounts, SetheumOracleConfig, BabeConfig, Balance, BalancesConfig, BandOracleConfig, SettmintEngineConfig, SerpTreasuryConfig, DexConfig, EnabledTradingPairs, - GeneralCouncilMembershipConfig, GrandpaConfig,SettwayCouncilMembershipConfig, + GeneralCouncilMembershipConfig, GrandpaConfig,MonetaryCouncilMembershipConfig, IndicesConfig, NativeTokenExistentialDeposit, OperatorMembershipSetheumConfig, OperatorMembershipBandConfig, OrmlNFTConfig, RenVmBridgeConfig, SessionConfig, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeMembershipConfig, TokensConfig, VestingConfig, DNAR, SETT, USDJ, @@ -199,7 +199,7 @@ fn setheum_genesis( phantom: Default::default(), }), pallet_collective_Instance2: Some(Default::default()), - pallet_membership_Instance2: Some(SettwayCouncilMembershipConfig { + pallet_membership_Instance2: Some(MonetaryCouncilMembershipConfig { members: vec![root_key.clone()], phantom: Default::default(), }), diff --git a/runtime/neom/Cargo.toml b/runtime/neom/Cargo.toml index b191fb963..04a509aa5 100644 --- a/runtime/neom/Cargo.toml +++ b/runtime/neom/Cargo.toml @@ -77,7 +77,7 @@ setheum-settmint-engine = { path = "../../lib-serml/settmint-engine", default-fe serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = false } setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } -setheum-settway = { path = "../../lib-serml/settway", default-features = false } +settmint-gateway = { path = "../../lib-serml/settmint-gateway", default-features = false } settmint-manager = { path = "../../lib-serml/settmint-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } @@ -154,7 +154,7 @@ std = [ "serp-treasury/std", "setheum-dex/std", "setheum-currencies/std", - "setheum-settway/std", + "settmint-gateway/std", "settmint-manager/std", "setheum-nft/std", "setheum-prices/std", @@ -229,7 +229,7 @@ try-runtime = [ "serp-treasury/try-runtime", "setheum-currencies/try-runtime", "setheum-dex/try-runtime", - "setheum-settway/try-runtime", + "settmint-gateway/try-runtime", "settmint-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", diff --git a/runtime/neom/src/authority.rs b/runtime/neom/src/authority.rs index 8b6989d91..722878286 100644 --- a/runtime/neom/src/authority.rs +++ b/runtime/neom/src/authority.rs @@ -20,9 +20,9 @@ use crate::{ SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, - DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfSettwayCouncil, + DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfMonetaryCouncil, EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, - EnsureRootOrTwoThirdsTechnicalCommittee, SettwayTreasuryPalletId, OneDay, Origin, + EnsureRootOrTwoThirdsTechnicalCommittee, OneDay, Origin, OriginCaller, SevenDays, ZeroDay, HOURS, }; pub use frame_support::traits::{schedule::Priority, EnsureOrigin, OriginTrait}; @@ -34,7 +34,7 @@ impl orml_authority::AuthorityConfig for Auth fn check_schedule_dispatch(origin: Origin, _priority: Priority) -> DispatchResult { EnsureRoot::::try_origin(origin) .or_else(|o| EnsureRootOrHalfGeneralCouncil::try_origin(o).map(|_| ())) - .or_else(|o| EnsureRootOrHalfSettwayCouncil::try_origin(o).map(|_| ())) + .or_else(|o| EnsureRootOrHalfMonetaryCouncil::try_origin(o).map(|_| ())) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) } @@ -80,10 +80,6 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { AuthoritysOriginId::SetheumTreasury => Origin::signed(SetheumTreasuryPalletId::get().into_account()) .caller() .clone(), - AuthoritysOriginId::SettwayTreasury => Origin::signed(SettwayTreasuryPalletId::get().into_account()) - .caller() - .clone(), - } } fn check_dispatch_from(&self, origin: Origin) -> DispatchResult { @@ -102,12 +98,6 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { >>::ensure_origin(origin) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) } - AuthoritysOriginId::SettwayTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } } }) } diff --git a/runtime/neom/src/lib.rs b/runtime/neom/src/lib.rs index 9671d64c6..989635b76 100644 --- a/runtime/neom/src/lib.rs +++ b/runtime/neom/src/lib.rs @@ -130,7 +130,6 @@ parameter_types! { pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); - pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } @@ -142,7 +141,6 @@ pub fn get_all_setheum_accounts() -> Vec { SettmintManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), - SettwayTreasuryPalletId::get().into_account(), IncentivesPalletId::get().into_account(), ZeroAccountId::get(), ] @@ -285,10 +283,10 @@ type EnsureRootOrHalfGeneralCouncil = EnsureOneOf< pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, GeneralCouncilInstance>, >; -type EnsureRootOrHalfSettwayCouncil = EnsureOneOf< +type EnsureRootOrHalfMonetaryCouncil = EnsureOneOf< AccountId, EnsureRoot, - pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, SettwayCouncilInstance>, + pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, MonetaryCouncilInstance>, >; type EnsureRootOrTwoThirdsGeneralCouncil = EnsureOneOf< @@ -346,33 +344,33 @@ impl pallet_membership::Config for Runtime { } parameter_types! { - pub const SettwayCouncilMotionDuration: BlockNumber = 7 * DAYS; - pub const SettwayCouncilMaxProposals: u32 = 100; - pub const SettwayCouncilMaxMembers: u32 = 100; + pub const MonetaryCouncilMotionDuration: BlockNumber = 7 * DAYS; + pub const MonetaryCouncilMaxProposals: u32 = 100; + pub const MonetaryCouncilMaxMembers: u32 = 100; } -type SettwayCouncilInstance = pallet_collective::Instance2; -impl pallet_collective::Config for Runtime { +type MonetaryCouncilInstance = pallet_collective::Instance2; +impl pallet_collective::Config for Runtime { type Origin = Origin; type Proposal = Call; type Event = Event; - type MotionDuration = SettwayCouncilMotionDuration; - type MaxProposals = SettwayCouncilMaxProposals; - type MaxMembers = SettwayCouncilMaxMembers; + type MotionDuration = MonetaryCouncilMotionDuration; + type MaxProposals = MonetaryCouncilMaxProposals; + type MaxMembers = MonetaryCouncilMaxMembers; type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = (); } -type SettwayCouncilMembershipInstance = pallet_membership::Instance2; -impl pallet_membership::Config for Runtime { +type MonetaryCouncilMembershipInstance = pallet_membership::Instance2; +impl pallet_membership::Config for Runtime { type Event = Event; type AddOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type RemoveOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type SwapOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type ResetOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type PrimeOrigin = EnsureRootOrTwoThirdsGeneralCouncil; - type MembershipInitialized = SettwayCouncil; - type MembershipChanged = SettwayCouncil; + type MembershipInitialized = MonetaryCouncil; + type MembershipChanged = MonetaryCouncil; } parameter_types! { @@ -895,16 +893,16 @@ impl setheum_settmint_engine::Config for Runtime { type MinimumStandardValue = MinimumStandardValue; type GetStableCurrencyId = GetStableCurrencyId; type SerpTreasury = SerpTreasury; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; + type UpdateOrigin = EnsureRootOrHalfMonetaryCouncil; type MaxSlippageSwapWithDex = MaxSlippageSwapWithDex; type Dex = Dex; type UnsignedPriority = runtime_common::SettmintEngineUnsignedPriority; type WeightInfo = weights::setheum_settmint_engine::WeightInfo; } -impl setheum_settway::Config for Runtime { +impl settmint_gateway::Config for Runtime { type Event = Event; - type WeightInfo = weights::setheum_settway::WeightInfo; + type WeightInfo = weights::settmint_gateway::WeightInfo; } parameter_types! { @@ -994,7 +992,7 @@ impl setheum_incentives::Config for Runtime { type AccumulatePeriod = AccumulatePeriod; type IncentiveCurrencyId = GetNativeCurrencyId; type SavingCurrencyId = GetStableCurrencyId; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; + type UpdateOrigin = EnsureRootOrHalfMonetaryCouncil; type SerpTreasury = SerpTreasury; type Currency = Currencies; type Dex = Dex; @@ -1097,8 +1095,8 @@ construct_runtime!( // Governance GeneralCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, GeneralCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, - SettwayCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, - SettwayCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, + MonetaryCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, + MonetaryCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, TechnicalCommittee: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommitteeMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, @@ -1123,10 +1121,10 @@ construct_runtime!( // Dex Dex: dex::{Module, Storage, Call, Event, Config}, - // Settway + // SettmintGateway SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, SettmintManager: settmint_manager::{Module, Storage, Call, Event}, - Settway: setheum_settway::{Module, Storage, Call, Event}, + SettmintGateway: settmint_gateway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, @@ -1411,7 +1409,7 @@ impl_runtime_apis! { // orml_add_benchmark!(params, batches, dex, benchmarking::dex); // orml_add_benchmark!(params, batches, serp_auction, benchmarking::serp_auction); // orml_add_benchmark!(params, batches, settmint_engine, benchmarking::settmint_engine); - // orml_add_benchmark!(params, batches, settway, benchmarking::settway); + // orml_add_benchmark!(params, batches, settmint_gateway, benchmarking::settmint_gateway); // orml_add_benchmark!(params, batches, serp_treasury, benchmarking::serp_treasury); // orml_add_benchmark!(params, batches, accounts, benchmarking::accounts); // orml_add_benchmark!(params, batches, incentives, benchmarking::incentives); diff --git a/runtime/neom/src/weights/mod.rs b/runtime/neom/src/weights/mod.rs index a729bd3c6..7d9290485 100644 --- a/runtime/neom/src/weights/mod.rs +++ b/runtime/neom/src/weights/mod.rs @@ -24,7 +24,7 @@ pub mod setheum_settmint_engine; pub mod serp_treasury; pub mod setheum_currencies; pub mod dex; -pub mod setheum_settway; +pub mod settmint_gateway; pub mod setheum_incentives; pub mod setheum_nft; pub mod setheum_prices; diff --git a/runtime/neom/src/weights/settway.rs b/runtime/neom/src/weights/settway.rs index c41796d33..b9b1d21fd 100644 --- a/runtime/neom/src/weights/settway.rs +++ b/runtime/neom/src/weights/settway.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Autogenerated weights for setheum_settway +//! Autogenerated weights for settmint_gateway //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-03-01, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] @@ -41,9 +41,9 @@ use frame_support::{traits::Get, weights::Weight}; use sp_std::marker::PhantomData; -/// Weight functions for setheum_settway. +/// Weight functions for settmint_gateway. pub struct WeightInfo(_); -impl setheum_settway::WeightInfo for WeightInfo { +impl settmint_gateway::WeightInfo for WeightInfo { fn authorize() -> Weight { (25_781_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } diff --git a/runtime/newrome/Cargo.toml b/runtime/newrome/Cargo.toml index 5b51b01ca..85de8f35f 100644 --- a/runtime/newrome/Cargo.toml +++ b/runtime/newrome/Cargo.toml @@ -79,7 +79,7 @@ setheum-settmint-engine = { path = "../../lib-serml/settmint-engine", default-fe serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = false } setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } -setheum-settway = { path = "../../lib-serml/settway", default-features = false } +settmint-gateway = { path = "../../lib-serml/settmint-gateway", default-features = false } settmint-manager = { path = "../../lib-serml/settmint-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } @@ -158,7 +158,7 @@ std = [ "serp-treasury/std", "setheum-dex/std", "setheum-currencies/std", - "setheum-settway/std", + "settmint-gateway/std", "settmint-manager/std", "setheum-nft/std", "setheum-prices/std", @@ -235,7 +235,7 @@ try-runtime = [ "serp-treasury/try-runtime", "setheum-currencies/try-runtime", "setheum-dex/try-runtime", - "setheum-settway/try-runtime", + "settmint-gateway/try-runtime", "settmint-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", diff --git a/runtime/newrome/src/authority.rs b/runtime/newrome/src/authority.rs index 8b6989d91..9c0343786 100644 --- a/runtime/newrome/src/authority.rs +++ b/runtime/newrome/src/authority.rs @@ -20,9 +20,9 @@ use crate::{ SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, - DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfSettwayCouncil, + DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfMonetaryCouncil, EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, - EnsureRootOrTwoThirdsTechnicalCommittee, SettwayTreasuryPalletId, OneDay, Origin, + EnsureRootOrTwoThirdsTechnicalCommittee, OneDay, Origin, OriginCaller, SevenDays, ZeroDay, HOURS, }; pub use frame_support::traits::{schedule::Priority, EnsureOrigin, OriginTrait}; @@ -34,7 +34,7 @@ impl orml_authority::AuthorityConfig for Auth fn check_schedule_dispatch(origin: Origin, _priority: Priority) -> DispatchResult { EnsureRoot::::try_origin(origin) .or_else(|o| EnsureRootOrHalfGeneralCouncil::try_origin(o).map(|_| ())) - .or_else(|o| EnsureRootOrHalfSettwayCouncil::try_origin(o).map(|_| ())) + .or_else(|o| EnsureRootOrHalfMonetaryCouncil::try_origin(o).map(|_| ())) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) } @@ -80,9 +80,6 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { AuthoritysOriginId::SetheumTreasury => Origin::signed(SetheumTreasuryPalletId::get().into_account()) .caller() .clone(), - AuthoritysOriginId::SettwayTreasury => Origin::signed(SettwayTreasuryPalletId::get().into_account()) - .caller() - .clone(), } } @@ -102,12 +99,6 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { >>::ensure_origin(origin) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) } - AuthoritysOriginId::SettwayTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } } }) } diff --git a/runtime/newrome/src/benchmarking/mod.rs b/runtime/newrome/src/benchmarking/mod.rs index 283122730..754070132 100644 --- a/runtime/newrome/src/benchmarking/mod.rs +++ b/runtime/newrome/src/benchmarking/mod.rs @@ -22,7 +22,7 @@ pub mod serp_auction; pub mod serp_treasury; pub mod dex; -pub mod settway; +pub mod settmint_gateway; pub mod incentives; pub mod prices; pub mod transaction_payment; diff --git a/runtime/newrome/src/benchmarking/settway.rs b/runtime/newrome/src/benchmarking/settway.rs index 29112a47f..9ae2243c4 100644 --- a/runtime/newrome/src/benchmarking/settway.rs +++ b/runtime/newrome/src/benchmarking/settway.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use crate::{ - dollar, SetheumOracle, AccountId, Amount, SettmintEngine, ReserveCurrencyIds, CurrencyId, Settway, Indices, Price, Rate, + dollar, SetheumOracle, AccountId, Amount, SettmintEngine, ReserveCurrencyIds, CurrencyId, SettmintGateway, Indices, Price, Rate, Ratio, Runtime, rUSD, rSETT, }; @@ -36,7 +36,7 @@ use sp_std::prelude::*; const SEED: u32 = 0; runtime_benchmarks! { - { Runtime, setheum_settway } + { Runtime, settmint_gateway } _ {} @@ -50,7 +50,7 @@ runtime_benchmarks! { let caller: AccountId = account("caller", 0, SEED); let to: AccountId = account("to", 0, SEED); let to_lookup = Indices::unlookup(to); - Settway::authorize( + SettmintGateway::authorize( RawOrigin::Signed(caller.clone()).into(), rSETT, to_lookup.clone() @@ -66,7 +66,7 @@ runtime_benchmarks! { let to_lookup = Indices::unlookup(to); for i in 0 .. c { - Settway::authorize( + SettmintGateway::authorize( RawOrigin::Signed(caller.clone()).into(), currency_ids[i as usize], to_lookup.clone(), @@ -116,7 +116,7 @@ runtime_benchmarks! { SetheumOracle::feed_values(RawOrigin::Root.into(), vec![(currency_id, Price::one())])?; // initialize sender's setter - Settway::adjust_position( + SettmintGateway::adjust_position( RawOrigin::Signed(sender.clone()).into(), currency_id, reserve_amount.try_into().unwrap(), @@ -124,7 +124,7 @@ runtime_benchmarks! { )?; // authorize receiver - Settway::authorize( + SettmintGateway::authorize( RawOrigin::Signed(sender.clone()).into(), currency_id, receiver_lookup, diff --git a/runtime/newrome/src/lib.rs b/runtime/newrome/src/lib.rs index 44ba1552c..bd749f868 100644 --- a/runtime/newrome/src/lib.rs +++ b/runtime/newrome/src/lib.rs @@ -132,7 +132,6 @@ parameter_types! { pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); - pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } @@ -143,7 +142,6 @@ pub fn get_all_setheum_accounts() -> Vec { SettmintManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), - SettwayTreasuryPalletId::get().into_account(), IncentivesPalletId::get().into_account(), ZeroAccountId::get(), ] @@ -286,10 +284,10 @@ type EnsureRootOrHalfGeneralCouncil = EnsureOneOf< pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, GeneralCouncilInstance>, >; -type EnsureRootOrHalfSettwayCouncil = EnsureOneOf< +type EnsureRootOrHalfMonetaryCouncil = EnsureOneOf< AccountId, EnsureRoot, - pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, SettwayCouncilInstance>, + pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, MonetaryCouncilInstance>, >; type EnsureRootOrTwoThirdsGeneralCouncil = EnsureOneOf< @@ -347,33 +345,33 @@ impl pallet_membership::Config for Runtime { } parameter_types! { - pub const SettwayCouncilMotionDuration: BlockNumber = 7 * DAYS; - pub const SettwayCouncilMaxProposals: u32 = 100; - pub const SettwayCouncilMaxMembers: u32 = 100; + pub const MonetaryCouncilMotionDuration: BlockNumber = 7 * DAYS; + pub const MonetaryCouncilMaxProposals: u32 = 100; + pub const MonetaryCouncilMaxMembers: u32 = 100; } -type SettwayCouncilInstance = pallet_collective::Instance2; -impl pallet_collective::Config for Runtime { +type MonetaryCouncilInstance = pallet_collective::Instance2; +impl pallet_collective::Config for Runtime { type Origin = Origin; type Proposal = Call; type Event = Event; - type MotionDuration = SettwayCouncilMotionDuration; - type MaxProposals = SettwayCouncilMaxProposals; - type MaxMembers = SettwayCouncilMaxMembers; + type MotionDuration = MonetaryCouncilMotionDuration; + type MaxProposals = MonetaryCouncilMaxProposals; + type MaxMembers = MonetaryCouncilMaxMembers; type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = (); } -type SettwayCouncilMembershipInstance = pallet_membership::Instance2; -impl pallet_membership::Config for Runtime { +type MonetaryCouncilMembershipInstance = pallet_membership::Instance2; +impl pallet_membership::Config for Runtime { type Event = Event; type AddOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type RemoveOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type SwapOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type ResetOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type PrimeOrigin = EnsureRootOrTwoThirdsGeneralCouncil; - type MembershipInitialized = SettwayCouncil; - type MembershipChanged = SettwayCouncil; + type MembershipInitialized = MonetaryCouncil; + type MembershipChanged = MonetaryCouncil; } parameter_types! { @@ -896,16 +894,16 @@ impl setheum_settmint_engine::Config for Runtime { type MinimumStandardValue = MinimumStandardValue; type GetStableCurrencyId = GetStableCurrencyId; type SerpTreasury = SerpTreasury; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; + type UpdateOrigin = EnsureRootOrHalfMonetaryCouncil; type MaxSlippageSwapWithDex = MaxSlippageSwapWithDex; type Dex = Dex; type UnsignedPriority = runtime_common::SettmintEngineUnsignedPriority; type WeightInfo = weights::setheum_settmint_engine::WeightInfo; } -impl setheum_settway::Config for Runtime { +impl settmint_gateway::Config for Runtime { type Event = Event; - type WeightInfo = weights::setheum_settway::WeightInfo; + type WeightInfo = weights::settmint_gateway::WeightInfo; } parameter_types! { @@ -995,7 +993,7 @@ impl setheum_incentives::Config for Runtime { type AccumulatePeriod = AccumulatePeriod; type IncentiveCurrencyId = GetNativeCurrencyId; type SavingCurrencyId = GetStableCurrencyId; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; + type UpdateOrigin = EnsureRootOrHalfMonetaryCouncil; type SerpTreasury = SerpTreasury; type Currency = Currencies; type Dex = Dex; @@ -1098,8 +1096,8 @@ construct_runtime!( // Governance GeneralCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, GeneralCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, - SettwayCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, - SettwayCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, + MonetaryCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, + MonetaryCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, TechnicalCommittee: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommitteeMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, @@ -1124,10 +1122,10 @@ construct_runtime!( // Dex Dex: dex::{Module, Storage, Call, Event, Config}, - // Settway + // SettmintGateway SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, SettmintManager: settmint_manager::{Module, Storage, Call, Event}, - Settway: setheum_settway::{Module, Storage, Call, Event}, + SettmintGateway: settmint_gateway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, @@ -1413,7 +1411,7 @@ impl_runtime_apis! { orml_add_benchmark!(params, batches, dex, benchmarking::dex); orml_add_benchmark!(params, batches, serp_auction, benchmarking::serp_auction); orml_add_benchmark!(params, batches, setheum_settmint_engine, benchmarking::settmint_engine); - orml_add_benchmark!(params, batches, setheum_settway, benchmarking::settway); + orml_add_benchmark!(params, batches, settmint_gateway, benchmarking::settmint_gateway); orml_add_benchmark!(params, batches, serp_treasury, benchmarking::serp_treasury); orml_add_benchmark!(params, batches, setheum_transaction_payment, benchmarking::transaction_payment); orml_add_benchmark!(params, batches, setheum_incentives, benchmarking::incentives); diff --git a/runtime/newrome/src/weights/mod.rs b/runtime/newrome/src/weights/mod.rs index a729bd3c6..7d9290485 100644 --- a/runtime/newrome/src/weights/mod.rs +++ b/runtime/newrome/src/weights/mod.rs @@ -24,7 +24,7 @@ pub mod setheum_settmint_engine; pub mod serp_treasury; pub mod setheum_currencies; pub mod dex; -pub mod setheum_settway; +pub mod settmint_gateway; pub mod setheum_incentives; pub mod setheum_nft; pub mod setheum_prices; diff --git a/runtime/newrome/src/weights/settway.rs b/runtime/newrome/src/weights/settway.rs index fbccc8f22..c309d52f7 100644 --- a/runtime/newrome/src/weights/settway.rs +++ b/runtime/newrome/src/weights/settway.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Autogenerated weights for setheum_settway +//! Autogenerated weights for settmint_gateway //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-03-01, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] @@ -41,9 +41,9 @@ use frame_support::{traits::Get, weights::Weight}; use sp_std::marker::PhantomData; -/// Weight functions for setheum_settway. +/// Weight functions for settmint_gateway. pub struct WeightInfo(_); -impl setheum_settway::WeightInfo for WeightInfo { +impl settmint_gateway::WeightInfo for WeightInfo { fn authorize() -> Weight { (25_888_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } diff --git a/runtime/setheum/Cargo.toml b/runtime/setheum/Cargo.toml index 980a8325a..db2bb871c 100644 --- a/runtime/setheum/Cargo.toml +++ b/runtime/setheum/Cargo.toml @@ -76,7 +76,7 @@ setheum-settmint-engine = { path = "../../lib-serml/settmint-engine", default-fe serp-treasury = { path = "../../lib-serml/serp-treasury", default-features = false } setheum-dex = { path = "../../lib-serml/dex", default-features = false } setheum-currencies = { path = "../../lib-serml/currencies", default-features = false } -setheum-settway = { path = "../../lib-serml/settway", default-features = false } +settmint-gateway = { path = "../../lib-serml/settmint-gateway", default-features = false } settmint-manager = { path = "../../lib-serml/settmint-manager", default-features = false } setheum-nft = { path = "../../lib-serml/nft", default-features = false } setheum-prices = { path = "../../lib-serml/prices", default-features = false } @@ -153,7 +153,7 @@ std = [ "serp-treasury/std", "setheum-currencies/std", "setheum-dex/std", - "setheum-settway/std", + "settmint-gateway/std", "settmint-manager/std", "setheum-nft/std", "setheum-prices/std", @@ -231,7 +231,7 @@ try-runtime = [ "serp-treasury/try-runtime", "setheum-currencies/try-runtime", "setheum-dex/try-runtime", - "setheum-settway/try-runtime", + "settmint-gateway/try-runtime", "settmint-manager/try-runtime", "setheum-nft/try-runtime", "setheum-prices/try-runtime", diff --git a/runtime/setheum/src/authority.rs b/runtime/setheum/src/authority.rs index 5c286a4bc..3e23a66e7 100644 --- a/runtime/setheum/src/authority.rs +++ b/runtime/setheum/src/authority.rs @@ -21,8 +21,8 @@ use crate::{ SetheumTreasuryPalletId, AccountId, AccountIdConversion, AuthoritysOriginId, BadOrigin, BlockNumber, DispatchResult, EnsureRoot, EnsureRootOrHalfGeneralCouncil, - EnsureRootOrHalfSettwayCouncil, EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, - EnsureRootOrTwoThirdsTechnicalCommittee, SettwayTreasuryPalletId, OneDay, Origin, + EnsureRootOrHalfMonetaryCouncil, EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, + EnsureRootOrTwoThirdsTechnicalCommittee, OneDay, Origin, OriginCaller, SevenDays, ZeroDay, HOURS, }; pub use frame_support::traits::{schedule::Priority, EnsureOrigin, OriginTrait}; @@ -34,7 +34,7 @@ impl orml_authority::AuthorityConfig for Auth fn check_schedule_dispatch(origin: Origin, _priority: Priority) -> DispatchResult { EnsureRoot::::try_origin(origin) .or_else(|o| EnsureRootOrHalfGeneralCouncil::try_origin(o).map(|_| ())) - .or_else(|o| EnsureRootOrHalfSettwayCouncil::try_origin(o).map(|_| ())) + .or_else(|o| EnsureRootOrHalfMonetaryCouncil::try_origin(o).map(|_| ())) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) } @@ -80,9 +80,6 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { AuthoritysOriginId::SetheumTreasury => Origin::signed(SetheumTreasuryPalletId::get().into_account()) .caller() .clone(), - AuthoritysOriginId::SettwayTreasury => Origin::signed(SettwayTreasuryPalletId::get().into_account()) - .caller() - .clone(), } } @@ -102,12 +99,6 @@ impl orml_authority::AsOriginId for AuthoritysOriginId { >>::ensure_origin(origin) .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) } - AuthoritysOriginId::SettwayTreasury => { - as EnsureOrigin< - Origin, - >>::ensure_origin(origin) - .map_or_else(|_| Err(BadOrigin.into()), |_| Ok(())) - } } }) } diff --git a/runtime/setheum/src/lib.rs b/runtime/setheum/src/lib.rs index f1d09a1d7..3e8fa9c86 100644 --- a/runtime/setheum/src/lib.rs +++ b/runtime/setheum/src/lib.rs @@ -131,7 +131,6 @@ parameter_types! { pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/setter"); pub const DexPalletId: PalletId = PalletId(*b"set/dexm"); pub const SerpTreasuryPalletId: PalletId = PalletId(*b"set/serp"); - pub const SettwayTreasuryPalletId: PalletId = PalletId(*b"set/stwy"); pub const IncentivesPalletId: PalletId = PalletId(*b"set/inct"); pub const NftPalletId: PalletId = PalletId(*b"set/sNFT"); } @@ -142,7 +141,6 @@ pub fn get_all_setheum_accounts() -> Vec { SettmintManagerPalletId::get().into_account(), DexPalletId::get().into_account(), SerpTreasuryPalletId::get().into_account(), - SettwayTreasuryPalletId::get().into_account(), IncentivesPalletId::get().into_account(), ZeroAccountId::get(), ] @@ -285,10 +283,10 @@ type EnsureRootOrHalfGeneralCouncil = EnsureOneOf< pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, GeneralCouncilInstance>, >; -type EnsureRootOrHalfSettwayCouncil = EnsureOneOf< +type EnsureRootOrHalfMonetaryCouncil = EnsureOneOf< AccountId, EnsureRoot, - pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, SettwayCouncilInstance>, + pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, MonetaryCouncilInstance>, >; type EnsureRootOrTwoThirdsGeneralCouncil = EnsureOneOf< @@ -346,33 +344,33 @@ impl pallet_membership::Config for Runtime { } parameter_types! { - pub const SettwayCouncilMotionDuration: BlockNumber = 7 * DAYS; - pub const SettwayCouncilMaxProposals: u32 = 100; - pub const SettwayCouncilMaxMembers: u32 = 100; + pub const MonetaryCouncilMotionDuration: BlockNumber = 7 * DAYS; + pub const MonetaryCouncilMaxProposals: u32 = 100; + pub const MonetaryCouncilMaxMembers: u32 = 100; } -type SettwayCouncilInstance = pallet_collective::Instance2; -impl pallet_collective::Config for Runtime { +type MonetaryCouncilInstance = pallet_collective::Instance2; +impl pallet_collective::Config for Runtime { type Origin = Origin; type Proposal = Call; type Event = Event; - type MotionDuration = SettwayCouncilMotionDuration; - type MaxProposals = SettwayCouncilMaxProposals; - type MaxMembers = SettwayCouncilMaxMembers; + type MotionDuration = MonetaryCouncilMotionDuration; + type MaxProposals = MonetaryCouncilMaxProposals; + type MaxMembers = MonetaryCouncilMaxMembers; type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = (); } -type SettwayCouncilMembershipInstance = pallet_membership::Instance2; -impl pallet_membership::Config for Runtime { +type MonetaryCouncilMembershipInstance = pallet_membership::Instance2; +impl pallet_membership::Config for Runtime { type Event = Event; type AddOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type RemoveOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type SwapOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type ResetOrigin = EnsureRootOrTwoThirdsGeneralCouncil; type PrimeOrigin = EnsureRootOrTwoThirdsGeneralCouncil; - type MembershipInitialized = SettwayCouncil; - type MembershipChanged = SettwayCouncil; + type MembershipInitialized = MonetaryCouncil; + type MembershipChanged = MonetaryCouncil; } parameter_types! { @@ -896,16 +894,16 @@ impl setheum_settmint_engine::Config for Runtime { type MinimumStandardValue = MinimumStandardValue; type GetStableCurrencyId = GetStableCurrencyId; type SerpTreasury = SerpTreasury; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; + type UpdateOrigin = EnsureRootOrHalfMonetaryCouncil; type MaxSlippageSwapWithDex = MaxSlippageSwapWithDex; type Dex = Dex; type UnsignedPriority = runtime_common::SettmintEngineUnsignedPriority; type WeightInfo = weights::setheum_settmint_engine::WeightInfo; } -impl setheum_settway::Config for Runtime { +impl settmint_gateway::Config for Runtime { type Event = Event; - type WeightInfo = weights::setheum_settway::WeightInfo; + type WeightInfo = weights::settmint_gateway::WeightInfo; } parameter_types! { @@ -995,7 +993,7 @@ impl setheum_incentives::Config for Runtime { type AccumulatePeriod = AccumulatePeriod; type IncentiveCurrencyId = GetNativeCurrencyId; type SavingCurrencyId = GetStableCurrencyId; - type UpdateOrigin = EnsureRootOrHalfSettwayCouncil; + type UpdateOrigin = EnsureRootOrHalfMonetaryCouncil; type SerpTreasury = SerpTreasury; type Currency = Currencies; type Dex = Dex; @@ -1098,8 +1096,8 @@ construct_runtime!( // Governance GeneralCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, GeneralCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, - SettwayCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, - SettwayCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, + MonetaryCouncil: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, + MonetaryCouncilMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, TechnicalCommittee: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommitteeMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, @@ -1124,10 +1122,10 @@ construct_runtime!( // Dex Dex: dex::{Module, Storage, Call, Event, Config}, - // Settway + // SettmintGateway SerpAuctionManager: serp_auction::{Module, Storage, Call, Event, ValidateUnsigned}, SettmintManager: settmint_manager::{Module, Storage, Call, Event}, - Settway: setheum_settway::{Module, Storage, Call, Event}, + SettmintGateway: settmint_gateway::{Module, Storage, Call, Event}, SerpTreasury: serp_treasury::{Module, Storage, Call, Config, Event}, SettmintEngine: setheum_settmint_engine::{Module, Storage, Call, Event, Config, ValidateUnsigned}, @@ -1413,7 +1411,7 @@ impl_runtime_apis! { // orml_add_benchmark!(params, batches, dex, benchmarking::dex); // orml_add_benchmark!(params, batches, serp_auction, benchmarking::serp_auction); // orml_add_benchmark!(params, batches, settmint_engine, benchmarking::settmint_engine); - // orml_add_benchmark!(params, batches, settway, benchmarking::settway); + // orml_add_benchmark!(params, batches, settmint_gateway, benchmarking::settmint_gateway); // orml_add_benchmark!(params, batches, serp_treasury, benchmarking::serp_treasury); // orml_add_benchmark!(params, batches, transaction_payment, benchmarking::transaction_payment); // orml_add_benchmark!(params, batches, incentives, benchmarking::incentives); diff --git a/runtime/setheum/src/weights/mod.rs b/runtime/setheum/src/weights/mod.rs index a729bd3c6..7d9290485 100644 --- a/runtime/setheum/src/weights/mod.rs +++ b/runtime/setheum/src/weights/mod.rs @@ -24,7 +24,7 @@ pub mod setheum_settmint_engine; pub mod serp_treasury; pub mod setheum_currencies; pub mod dex; -pub mod setheum_settway; +pub mod settmint_gateway; pub mod setheum_incentives; pub mod setheum_nft; pub mod setheum_prices; diff --git a/runtime/setheum/src/weights/settway.rs b/runtime/setheum/src/weights/settway.rs index e36da847a..dfaa9af61 100644 --- a/runtime/setheum/src/weights/settway.rs +++ b/runtime/setheum/src/weights/settway.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Autogenerated weights for setheum_settway +//! Autogenerated weights for settmint_gateway //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-02-26, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] @@ -28,7 +28,7 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=setheum_settway +// --pallet=settmint_gateway // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -41,9 +41,9 @@ use frame_support::{traits::Get, weights::Weight}; use sp_std::marker::PhantomData; -/// Weight functions for setheum_settway. +/// Weight functions for settmint_gateway. pub struct WeightInfo(_); -impl setheum_settway::WeightInfo for WeightInfo { +impl settmint_gateway::WeightInfo for WeightInfo { fn authorize() -> Weight { (14_000_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } From 34c9a952c03fbf1e56ec6f3d210b991cc44909dc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 02:30:15 +0800 Subject: [PATCH 76/83] fix adjust_position - reserve adjust convert --- lib-serml/settmint-manager/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib-serml/settmint-manager/src/lib.rs b/lib-serml/settmint-manager/src/lib.rs index 39927f697..2df55053d 100644 --- a/lib-serml/settmint-manager/src/lib.rs +++ b/lib-serml/settmint-manager/src/lib.rs @@ -168,9 +168,11 @@ impl Pallet { ); if reserve_adjustment.is_positive() { - T::Currency::transfer(reserve_currency, who, &setheum_account, reserve_balance_adjustment)?; + T::Currency::transfer(reserve_currency, who, &setheum_account, + T::Convert::convert((reserve_currency, reserve_balance_adjustment)))?; } else if reserve_adjustment.is_negative() { - T::Currency::transfer(reserve_currency, &setheum_account, who, reserve_balance_adjustment)?; + T::Currency::transfer(reserve_currency, &setheum_account, who, + T::Convert::convert((reserve_currency, reserve_balance_adjustment)))?; } if standard_adjustment.is_positive() { From 1b6b97715d19e998bd9ba798c97a58319665ea27 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 02:30:56 +0800 Subject: [PATCH 77/83] remove unnecessary ensure --- lib-serml/settmint-engine/src/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib-serml/settmint-engine/src/lib.rs b/lib-serml/settmint-engine/src/lib.rs index ca0571774..542684c09 100644 --- a/lib-serml/settmint-engine/src/lib.rs +++ b/lib-serml/settmint-engine/src/lib.rs @@ -182,11 +182,6 @@ impl Pallet { reserve_adjustment: Amount, standard_adjustment: Amount, ) -> DispatchResult { - // ensure the currency is a settcurrency standard - ensure!( - T::StandardCurrencyIds::get().contains(¤cy_id), - Error::::InvalidStandardType, - ); >::adjust_position(who, currency_id, reserve_adjustment, standard_adjustment)?; Ok(()) } From d3b94ad983898a63e8ca72084f7725e769352bdf Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Sun, 27 Jun 2021 02:31:41 +0800 Subject: [PATCH 78/83] update settmint-gateway tests and mock --- lib-serml/settmint-gateway/src/lib.rs | 15 +++------ lib-serml/settmint-gateway/src/mock.rs | 6 ++++ lib-serml/settmint-gateway/src/tests.rs | 42 ++++++++++++------------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/lib-serml/settmint-gateway/src/lib.rs b/lib-serml/settmint-gateway/src/lib.rs index 97325e919..1b1de4201 100644 --- a/lib-serml/settmint-gateway/src/lib.rs +++ b/lib-serml/settmint-gateway/src/lib.rs @@ -124,20 +124,15 @@ pub mod module { standard_adjustment: Amount, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - // ensure the currency is a settcurrency standard - ensure!( - T::StandardCurrencyIds::get().contains(¤cy_id), - Error::::InvalidStandardType, - ); >::adjust_position(&who, currency_id, reserve_adjustment, standard_adjustment)?; Ok(().into()) } /// Transfer the whole Settmint of `from` under `currency_id` to caller's Settmint /// under the same `currency_id`, caller must have the authorization of - /// `from` for the specific reserve type + /// `from` for the specific STANDARD type /// - /// - `currency_id`: reserve currency id. + /// - `currency_id`: STANDARD currency id. /// - `from`: authorizer account #[pallet::weight(::WeightInfo::transfer_position_from())] #[transactional] @@ -155,7 +150,7 @@ pub mod module { /// Authorize `to` to manipulate the setter under `currency_id` /// - /// - `currency_id`: reserve currency id. + /// - `currency_id`: STANDARD currency id. /// - `to`: authorizee account #[pallet::weight(::WeightInfo::authorize())] #[transactional] @@ -173,7 +168,7 @@ pub mod module { /// Cancel the authorization for `to` under `currency_id` /// - /// - `currency_id`: reserve currency id. + /// - `currency_id`: STANDARD currency id. /// - `to`: authorizee account #[pallet::weight(::WeightInfo::unauthorize())] #[transactional] @@ -202,7 +197,7 @@ pub mod module { } impl Pallet { - /// Check if `from` has the authorization of `to` under `currency_id` + /// Check if `from` has the authorization of `to` under STANDARD `currency_id` fn check_authorization(from: &T::AccountId, to: &T::AccountId, currency_id: CurrencyId) -> DispatchResult { ensure!( from == to || Self::authorization(from, (currency_id, to)), diff --git a/lib-serml/settmint-gateway/src/mock.rs b/lib-serml/settmint-gateway/src/mock.rs index 3b61f6a55..6335e4f10 100644 --- a/lib-serml/settmint-gateway/src/mock.rs +++ b/lib-serml/settmint-gateway/src/mock.rs @@ -385,8 +385,14 @@ impl Default for ExtBuilder { fn default() -> Self { Self { endowed_accounts: vec![ + (ALICE, DNAR, 1000), + (BOB, DNAR, 1000), + (ALICE, SDEX, 1000), + (BOB, SDEX, 1000), (ALICE, SETT, 1000), (BOB, SETT, 1000), + (ALICE, USDJ, 1000), + (BOB, USDJ, 1000), ], } } diff --git a/lib-serml/settmint-gateway/src/tests.rs b/lib-serml/settmint-gateway/src/tests.rs index e771aeaa8..af88a3046 100644 --- a/lib-serml/settmint-gateway/src/tests.rs +++ b/lib-serml/settmint-gateway/src/tests.rs @@ -31,11 +31,11 @@ use support::{Rate, Ratio}; fn authorize_should_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), USDJ, BOB)); - System::assert_last_event(Event::settmint_gateway(crate::Event::Authorization(ALICE, BOB, SETT))); + System::assert_last_event(Event::settmint_gateway(crate::Event::Authorization(ALICE, BOB, USDJ))); - assert_ok!(SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT)); + assert_ok!(SettmintGatewayModule::check_authorization(&ALICE, &BOB, USDJ)); }); } @@ -43,14 +43,14 @@ fn authorize_should_work() { fn unauthorize_should_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT)); - assert_ok!(SettmintGatewayModule::unauthorize(Origin::signed(ALICE), SETT, BOB)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), USDJ, BOB)); + assert_ok!(SettmintGatewayModule::check_authorization(&ALICE, &BOB, USDJ)); + assert_ok!(SettmintGatewayModule::unauthorize(Origin::signed(ALICE), USDJ, BOB)); - System::assert_last_event(Event::settmint_gateway(crate::Event::UnAuthorization(ALICE, BOB, SETT))); + System::assert_last_event(Event::settmint_gateway(crate::Event::UnAuthorization(ALICE, BOB, USDJ))); assert_noop!( - SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT), + SettmintGatewayModule::check_authorization(&ALICE, &BOB, USDJ), Error::::NoAuthorization ); }); @@ -60,18 +60,18 @@ fn unauthorize_should_work() { fn unauthorize_all_should_work() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); - assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, CAROL)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), USDJ, BOB)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), USDJ, CAROL)); assert_ok!(SettmintGatewayModule::unauthorize_all(Origin::signed(ALICE))); System::assert_last_event(Event::settmint_gateway(crate::Event::UnAuthorizationAll(ALICE))); assert_noop!( - SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT), + SettmintGatewayModule::check_authorization(&ALICE, &BOB, USDJ), Error::::NoAuthorization ); assert_noop!( - SettmintGatewayModule::check_authorization(&ALICE, &BOB, SETT), + SettmintGatewayModule::check_authorization(&ALICE, &BOB, USDJ), Error::::NoAuthorization ); }); @@ -80,11 +80,11 @@ fn unauthorize_all_should_work() { #[test] fn transfer_position_from_should_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettmintGatewayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); - assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), SETT, BOB)); - assert_ok!(SettmintGatewayModule::transfer_position_from(Origin::signed(BOB), SETT, ALICE)); - assert_eq!(SettmintManagerModule::positions(SETT, BOB).reserve, 100); - assert_eq!(SettmintManagerModule::positions(SETT, BOB).standard, 50); + assert_ok!(SettmintGatewayModule::adjust_position(Origin::signed(ALICE), USDJ, 100, 50)); + assert_ok!(SettmintGatewayModule::authorize(Origin::signed(ALICE), USDJ, BOB)); + assert_ok!(SettmintGatewayModule::transfer_position_from(Origin::signed(BOB), USDJ, ALICE)); + assert_eq!(SettmintManagerModule::positions(USDJ, BOB).reserve, 100); + assert_eq!(SettmintManagerModule::positions(USDJ, BOB).standard, 50); }); } @@ -92,7 +92,7 @@ fn transfer_position_from_should_work() { fn transfer_unauthorization_setters_should_not_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - SettmintGatewayModule::transfer_position_from(Origin::signed(ALICE), SETT, BOB), + SettmintGatewayModule::transfer_position_from(Origin::signed(ALICE), USDJ, BOB), Error::::NoAuthorization, ); }); @@ -101,8 +101,8 @@ fn transfer_unauthorization_setters_should_not_work() { #[test] fn adjust_position_should_work() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(SettmintGatewayModule::adjust_position(Origin::signed(ALICE), SETT, 100, 50)); - assert_eq!(SettmintManagerModule::positions(SETT, ALICE).reserve, 100); - assert_eq!(SettmintManagerModule::positions(SETT, ALICE).standard, 50); + assert_ok!(SettmintGatewayModule::adjust_position(Origin::signed(ALICE), USDJ, 100, 50)); + assert_eq!(SettmintManagerModule::positions(USDJ, ALICE).reserve, 100); + assert_eq!(SettmintManagerModule::positions(USDJ, ALICE).standard, 50); }); } From 7e6334d443061939540b2b46546a565a244ac62a Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Mon, 28 Jun 2021 03:01:40 +0800 Subject: [PATCH 79/83] add predeploy --- .gitmodules | 3 +++ predeploy-contracts | 1 + 2 files changed, 4 insertions(+) create mode 160000 predeploy-contracts diff --git a/.gitmodules b/.gitmodules index a0341be62..6a32e7a26 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "lib-openrml"] path = lib-openrml url = https://github.com/open-web3-stack/open-runtime-module-library +[submodule "predeploy-contracts"] + path = predeploy-contracts + url = https://github.com/Setheum-Labs/predeploy-contracts diff --git a/predeploy-contracts b/predeploy-contracts new file mode 160000 index 000000000..7e573bc81 --- /dev/null +++ b/predeploy-contracts @@ -0,0 +1 @@ +Subproject commit 7e573bc8149bea00736e337cd029b0a7305e4491 From 65f4fff5b40c508f4e2249da21b1847de6397a94 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Mon, 28 Jun 2021 03:10:39 +0800 Subject: [PATCH 80/83] Create update-neom.sh --- scripts/update-neom.sh | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 scripts/update-neom.sh diff --git a/scripts/update-neom.sh b/scripts/update-neom.sh new file mode 100755 index 000000000..87f668a2d --- /dev/null +++ b/scripts/update-neom.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e + +# cargo clean +WASM_BUILD_TYPE=release cargo run --manifest-path node/setheum/Cargo.toml --features=on-chain-release-build -- build-spec --raw --chain neom-latest > ./resources/neom-dist.json From 289c5b466c2e45e29bb943de5b7905a3cdf584bc Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Mon, 28 Jun 2021 03:10:43 +0800 Subject: [PATCH 81/83] Update Makefile --- Makefile | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index b5045d5ae..6ef2ba1d9 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ run: githooks cargo run --manifest-path node/setheum-dev/Cargo.toml -- --dev -lruntime=debug --instant-sealing +.PHONY: run-sevm +run: githooks + cargo run --manifest-path node/setheum-dev/Cargo.toml --features with-sevm -- --dev -lruntime=debug -levm=debug --instant-sealing + .PHONY: toolchain toolchain: ./scripts/init.sh @@ -56,8 +60,15 @@ check-try-runtime: test: githooks SKIP_WASM_BUILD= cargo test --all +.PHONY: test-sevm +test: githooks + SKIP_WASM_BUILD= cargo test --all --features with-sevm test_setheum_evm + SKIP_WASM_BUILD= cargo test --all --features with-sevm should_not_kill_contract_on_transfer_all + SKIP_WASM_BUILD= cargo test --all --features with-sevm schedule_call_precompile_should_work + SKIP_WASM_BUILD= cargo test --all --features with-sevm schedule_call_precompile_should_handle_invalid_input + .PHONY: test-all -test-all: test-dev test-setheum +test-all: test-dev test-sevm test-setheum test-benchmarking .PHONY: test-dev test-dev: @@ -67,9 +78,15 @@ test-dev: test-setheum: SKIP_WASM_BUILD= cargo test --manifest-path node/setheum/Cargo.toml --all --features with-all-runtime +.PHONY: check-benchmarking +test-benchmarking: + SKIP_WASM_BUILD= cargo check --manifest-path node/setheum-dev/Cargo.toml --features runtime-benchmarks --no-default-features --target=wasm32-unknown-unknown -p newrome-runtime + .PHONY: test-benchmarking test-benchmarking: - SKIP_WASM_BUILD= cargo test --manifest-path node/setheum-dev/Cargo.toml --features runtime-benchmarks -p newrome-runtime benchmarking + SKIP_WASM_BUILD= cargo test --manifest-path node/setheum-dev/Cargo.toml --features runtime-benchmarks --no-default-features --target=wasm32-unknown-unknown -p newrome-runtime + SKIP_WASM_BUILD= cargo test --manifest-path node/setheum/Cargo.toml --features runtime-benchmarks --no-default-features --target=wasm32-unknown-unknown -p neom-runtime + .PHONY: build build: githooks @@ -110,10 +127,24 @@ update-orml: git add lib-openrml .PHONY: update -update: update-orml +update: update-orml cargo-update check-all + +.PHONY: cargo-update +cargo-update: cargo update - make check .PHONY: build-wasm-newrome build-wasm-newrome: - ./scripts/build-only-wasm.sh newrome-runtime + ./scripts/build-only-wasm.sh -p newrome-runtime --features=with-sevm + +.PHONY: build-wasm-neom +build-wasm-newrome: + ./scripts/build-only-wasm.sh -p neom-runtime --features=on-chain-release-build + +.PHONY: srtool-build-wasm-neom +srtool-build-wasm-neom: + PACKAGE=neom-runtime BUILD_OPTS="--features on-chain-release-build" ./scripts/srtool-build.sh + +.PHONY: generate-tokens +generate-tokens: + ./scripts/generate-tokens-and-predeploy-contracts.sh From c0da2be69d7f68f39c846e964f8b1fce270f0de4 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Mon, 28 Jun 2021 23:55:16 +0800 Subject: [PATCH 82/83] renamen get_setheum_usd_fixed_price to get_settusd_fixed_price --- lib-serml/prices/src/lib.rs | 2 +- lib-serml/support/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index 72e26fb65..58328b208 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -246,7 +246,7 @@ impl PriceProvider for Pallet { Self::locked_price(fiat_currency_id).or_else(|| T::Source::get(&fiat_currency_id)); } - fn get_setheum_usd_fixed_price() -> Option{ + fn get_settusd_fixed_price() -> Option{ let currency_id = T::GetSettUSDCurrencyId::get(); Self::get_peg_price(¤cy_id) } diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index 09f1ef0af..4c7a32a74 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -246,7 +246,7 @@ pub trait SerpTreasuryExtended: SerpTreasury { pub trait PriceProvider { fn get_fiat_price(fiat_currency_id: CurrencyId) -> Option; fn get_peg_price(currency_id: CurrencyId) -> Option; - fn get_setheum_usd_fixed_price() -> Option; + fn get_settusd_fixed_price() -> Option; fn get_stablecoin_fixed_price(currency_id: CurrencyId) -> Option; fn get_stablecoin_market_price(currency_id: CurrencyId) -> Option; fn get_relative_price(base: CurrencyId, quote: CurrencyId) -> Option; From 21896faf0f3a6cfc64615b3596fcf3c494a751d3 Mon Sep 17 00:00:00 2001 From: Muhammad-Jibril Date: Tue, 29 Jun 2021 02:26:45 +0800 Subject: [PATCH 83/83] refactor prices module to using fixed USD denominations and get_market_price for SERP while get_price is pointing fixed pegs for stablecurrencies refactor prices module to using fixed USD denominations and get_market_price for SERP while get_price is pointing fixed pegs for stablecurrencies --- lib-serml/prices/src/lib.rs | 123 +++++++++++++--- lib-serml/prices/src/mock.rs | 10 +- lib-serml/prices/src/tests.rs | 217 +++++++++++++++++++++++++++-- lib-serml/serp-treasury/src/lib.rs | 6 +- lib-serml/support/src/lib.rs | 6 +- 5 files changed, 322 insertions(+), 40 deletions(-) diff --git a/lib-serml/prices/src/lib.rs b/lib-serml/prices/src/lib.rs index 58328b208..cc9fa2364 100644 --- a/lib-serml/prices/src/lib.rs +++ b/lib-serml/prices/src/lib.rs @@ -76,6 +76,25 @@ pub mod module { /// The SettUSD currency id, it should be USDJ in Setheum. type GetSettUSDCurrencyId: Get; + /// The stable currency ids + type StableCurrencyIds: Get>; + + /// The peg currency of a stablecoin. + type PegCurrencyIds: GetByKey; + + /// The list of valid Fiat currency types that define the stablecoin pegs + type FiatCurrencyIds: Get>; + + #[pallet::constant] + /// The FiatUSD currency id, it should be USD. + type GetFiatUSDCurrencyId: Get; + + /// The fixed price of SettUsd, it should be 1 USD in Setheum. + /// This represents the value of the US dollar which is used - + /// for price feed provided in USD by the oracles in Setheum. + #[pallet::constant] + type FiatUsdFixedPrice: Get; + #[pallet::constant] /// The Setter Peg One currency id, it should be USDJ in Setheum. type GetSetterPegOneCurrencyId: Get; @@ -116,15 +135,6 @@ pub mod module { /// The Setter Peg Ten currency id, it should be GIPJ in Setheum. type GetSetterPegTenCurrencyId: Get; - /// The stable currency ids - type StableCurrencyIds: Get>; - - /// The peg currency of a stablecoin. - type PegCurrencyIds: GetByKey; - - /// The list of valid Fiat currency types that define the stablecoin pegs - type FiatCurrencyIds: Get>; - /// The origin which may lock and unlock prices feed to system. type LockOrigin: EnsureOrigin; @@ -228,8 +238,14 @@ impl PriceProvider for Pallet { T::PegCurrencyIds::get(¤cy_id) == &fiat_currency_id, Error::::InvalidPegPair, ); - // if locked price exists, return it, otherwise return latest price from oracle. - Self::locked_price(fiat_currency_id).or_else(|| T::Source::get(&fiat_currency_id)); + if currency_id == T::GetSetterCurrencyId::get() { + Self::get_setter_fixed_price() + } else if { currency_id == T::GetSettUSDCurrencyId::get() { + Self::get_settusd_fixed_price() + } else { + // if locked price exists, return it, otherwise return latest price from oracle. + Self::locked_price(fiat_currency_id).or_else(|| T::Source::get(&fiat_currency_id)); + } } /// get the price of a fiat currency @@ -242,13 +258,18 @@ impl PriceProvider for Pallet { T::FiatCurrencyIds::get().contains(&fiat_currency_id), Error::::InvalidFiatCurrencyType, ); + if { fiat_currency_id == T::GetFiatUSDCurrencyId::get() { + Self::get_fiat_usd_fixed_price() + } // if locked price exists, return it, otherwise return latest price from oracle. Self::locked_price(fiat_currency_id).or_else(|| T::Source::get(&fiat_currency_id)); } + fn get_fiat_usd_fixed_price() -> Option{ + Some(T::FiatUsdFixedPrice::get()) + } fn get_settusd_fixed_price() -> Option{ - let currency_id = T::GetSettUSDCurrencyId::get(); - Self::get_peg_price(¤cy_id) + Self::get_fiat_usd_fixed_price() } /// get the fixed price of a specific settcurrency/stablecoin currency type @@ -257,9 +278,6 @@ impl PriceProvider for Pallet { T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, ); - if currency_id == T::GetSetterCurrencyId::get() { - Self::get_setter_fixed_price() - } else { Self::get_peg_price(¤cy_id) } } @@ -271,7 +289,7 @@ impl PriceProvider for Pallet { T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, ); - Self::get_price(currency_id) + Self::get_market_price(currency_id) } /// get exchange rate between two currency types @@ -286,6 +304,18 @@ impl PriceProvider for Pallet { } } + /// get exchange rate between two currency types + /// Note: this returns the price for 1 basic unit + fn get_market_relative_price(base_currency_id: CurrencyId, quote_currency_id: CurrencyId) -> Option { + if let (Some(base_price), Some(quote_price)) = + (Self::get_market_price(base_currency_id), Self::get_market_price(quote_currency_id)) + { + base_price.checked_div("e_price) + } else { + None + } + } + fn get_coin_to_peg_relative_price(currency_id: CurrencyId) -> Option { ensure!( T::StableCurrencyIds::get().contains(¤cy_id), @@ -293,7 +323,7 @@ impl PriceProvider for Pallet { ); if currency_id == T::GetSetterCurrencyId::get() { let basket_price = Self::get_setter_fixed_price(); - let coin_price = Self::get_price(currency_id); + let coin_price = Self::get_market_price(currency_id); coin_price.checked_div(&basket_price) } else if !currency_id == T::GetSetterCurrencyId::get() { let fiat_currency_id = Self::get_peg_currency_by_currency_id(¤cy_id); @@ -301,7 +331,7 @@ impl PriceProvider for Pallet { T::FiatCurrencyIds::get().contains(&fiat_currency_id), Error::::InvalidFiatCurrencyType, ); - Self::get_relative_price(¤cy_id, &fiat_currency_id) + Self::get_market_relative_price(¤cy_id, &fiat_currency_id) } else { None } @@ -364,12 +394,61 @@ impl PriceProvider for Pallet { Self::get_setter_basket_peg_price() } + /// get the exchange rate of a specific SettCurrency to USD + /// Note: this returns the price for 1 basic unit + /// For the SERP TO USE WHEN STABILISING SettCurrency prices. + fn get_market_price(currency_id: CurrencyId) -> Option{ + let maybe_feed_price = if T::FiatCurrencyIds::get().contains(¤cy_id) { + // if it is a FiatCurrency, return fiat price + let fiat_currency_id = ¤cy_id; + Self::get_fiat_price(&fiat_currency_id)) + } else if let CurrencyId::DexShare(symbol_0, symbol_1) = currency_id { + let token_0 = match symbol_0 { + DexShare::Token(token) => CurrencyId::Token(token), + DexShare::Erc20(address) => CurrencyId::Erc20(address), + }; + let token_1 = match symbol_1 { + DexShare::Token(token) => CurrencyId::Token(token), + DexShare::Erc20(address) => CurrencyId::Erc20(address), + }; + let (pool_0, _) = T::DEX::get_liquidity_pool(token_0, token_1); + let total_shares = T::Currency::total_issuance(currency_id); + + return { + if let (Some(ratio), Some(price_0)) = ( + Price::checked_from_rational(pool_0, total_shares), + Self::get_price(token_0), + ) { + ratio + .checked_mul(&price_0) + .and_then(|n| n.checked_mul(&Price::saturating_from_integer(2))) + } else { + None + } + }; + } else { + // if locked price exists, return it, otherwise return latest price from oracle. + Self::locked_price(currency_id).or_else(|| T::Source::get(¤cy_id)) + }; + let maybe_adjustment_multiplier = 10u128.checked_pow(T::CurrencyIdMapping::decimals(currency_id)?.into()); + + if let (Some(feed_price), Some(adjustment_multiplier)) = (maybe_feed_price, maybe_adjustment_multiplier) { + Price::checked_from_rational(feed_price.into_inner(), adjustment_multiplier) + } else { + None + } + } + /// get the exchange rate of specific currency to USD /// Note: this returns the price for 1 basic unit fn get_price(currency_id: CurrencyId) -> Option { - let maybe_feed_price = if currency_id == T::GetSetterCurrencyId::get() { - // if is Setter (SETT) basket currency, return fixed price - Some(Self::get_setter_fixed_price()) + let maybe_feed_price = if T::FiatCurrencyIds::get().contains(¤cy_id) { + // if it is a FiatCurrency, return fiat price + let fiat_currency_id = ¤cy_id; + Self::get_fiat_price(&fiat_currency_id)) + } else if T::StableCurrencyIds::get().contains(¤cy_id) { + // if it is a SettCurrency, return fixed price + Some(Self::get_stablecoin_fixed_price(¤cy_id)) } else if let CurrencyId::DexShare(symbol_0, symbol_1) = currency_id { let token_0 = match symbol_0 { DexShare::Token(token) => CurrencyId::Token(token), diff --git a/lib-serml/prices/src/mock.rs b/lib-serml/prices/src/mock.rs index a3211c9f6..3889960c0 100644 --- a/lib-serml/prices/src/mock.rs +++ b/lib-serml/prices/src/mock.rs @@ -326,9 +326,11 @@ ord_parameter_types! { } parameter_types! { - pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT - pub const GetSettUSDCurrencyId: CurrencyId = USDJ; // SettUSD currency ticker is USDJ - + pub const GetSetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT. + pub const GetSettUSDCurrencyId: CurrencyId = USDJ; // SettUSD currency ticker is USDJ. + pub const GetFiatUSDCurrencyId: CurrencyId = USD; // The USD Fiat currency denomination. + pub FiatUsdFixedPrice: Price = Price::one(); // Fixed 1 USD Fiat denomination for pricing. + pub const GetSetterPegOneCurrencyId: CurrencyId = GBP; // Fiat pegs of the Setter (SETT). pub const GetSetterPegTwoCurrencyId: CurrencyId = EUR; // Fiat pegs of the Setter (SETT). pub const GetSetterPegThreeCurrencyId: CurrencyId = KWD; // Fiat pegs of the Setter (SETT). @@ -434,6 +436,8 @@ impl Config for Runtime { type Source = MockDataProvider; type GetSetterCurrencyId = GetSetterCurrencyId; type GetSettUSDCurrencyId = GetSettUSDCurrencyId; + type GetFiatUSDCurrencyId = GetFiatUSDCurrencyId; + type FiatUsdFixedPrice = FiatUsdFixedPrice; type GetSetterPegOneCurrencyId = GetSetterPegOneCurrencyId; type GetSetterPegTwoCurrencyId = GetSetterPegTwoCurrencyId; type GetSetterPegThreeCurrencyId = GetSetterPegThreeCurrencyId; diff --git a/lib-serml/prices/src/tests.rs b/lib-serml/prices/src/tests.rs index 44d52bc3f..934909318 100644 --- a/lib-serml/prices/src/tests.rs +++ b/lib-serml/prices/src/tests.rs @@ -28,6 +28,139 @@ use sp_runtime::{ FixedPointNumber }; +#[test] +fn get_peg_currency_by_currency_id_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_peg_currency_by_currency_id(JCHF), + CHF + ); + assert_eq!( + SetheumPrices::get_peg_currency_by_currency_id(USDJ), + USD + ); + assert_eq!( + SetheumPrices::get_peg_currency_by_currency_id(EURJ), + EUR + ); + assert_eq!( + SetheumPrices::get_peg_currency_by_currency_id(SETT), + None + ); + assert_eq!( + SetheumPrices::get_peg_currency_by_currency_id(USD), + None + ); + assert_eq!( + SetheumPrices::get_peg_currency_by_currency_id(DNAR), + None + ); + }); +} + +#[test] +fn get_peg_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_peg_price(JCHF), + Some(Price::saturating_from_integer(1500000u128)) + ); // 1.5 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_peg_price(USDJ), + Some(Price::saturating_from_integer(1000000u128)) + ); // 1 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_peg_price(SETT), + Some(Price::saturating_from_integer(1500000u128)) + ); // 1.5 USD, right shift the decimal point (18-12) places + assert_eq!(SetheumPrices::get_peg_price(DNAR), Some(Price::zero())); + assert_eq!(SetheumPrices::get_peg_price(USD), Some(Price::zero())); + }); +} + +#[test] +fn get_fiat_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_fiat_price(CHF), + Some(Price::saturating_from_integer(1500000u128)) + ); // 1.5 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_fiat_price(USD), + Some(Price::saturating_from_integer(1000000u128)) + ); // 1 USD, right shift the decimal point (18-12) places + assert_eq!(SetheumPrices::get_fiat_price(DNAR), Some(Price::zero())); + assert_eq!(SetheumPrices::get_fiat_price(SETT), Some(Price::zero())); + assert_eq!(SetheumPrices::get_fiat_price(USDJ), Some(Price::zero())); + }); +} + +#[test] +fn get_fiat_usd_fixed_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_fiat_usd_fixed_price(), + Some(Price::saturating_from_integer(1000000u128)) + ); // 1 USD, right shift the decimal point (18-12) places + }); +} + +#[test] +fn get_settusd_fixed_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_settusd_fixed_price(), + Some(Price::saturating_from_integer(1606750u128)) + ); // 1.60675 USD, right shift the decimal point (18-12) places + }); +} + +#[test] +fn get_stablecoin_fixed_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_stablecoin_fixed_price(USDJ), + Some(Price::saturating_from_integer(1000000u128)) + ); // 1 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_stablecoin_fixed_price(JUSD), + Some(Price::saturating_from_integer(1000000u128)) + ); // 1 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_stablecoin_fixed_price(SETT), + Some(Price::saturating_from_integer(1560000u128)) + ); // 1.56 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_stablecoin_fixed_price(EURJ), + Some(Price::saturating_from_integer(1200000u128)) + ); // 1.2 USD, right shift the decimal point (18-12) places + assert_eq!(SetheumPrices::get_stablecoin_fixed_price(DNAR), Some(Price::zero())); + }); +} + +#[test] +fn get_stablecoin_market_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_stablecoin_market_price(USDJ), + Some(Price::saturating_from_integer(1000000u128)) + ); // 1 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_stablecoin_market_price(JUSD), + Some(Price::saturating_from_integer(1000000u128)) + ); // 1 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_stablecoin_market_price(SETT), + Some(Price::saturating_from_integer(1560000u128)) + ); // 1.56 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_stablecoin_market_price(EURJ), + Some(Price::saturating_from_integer(1200000u128)) + ); // 1.2 USD, right shift the decimal point (18-12) places + assert_eq!(SetheumPrices::get_stablecoin_market_price(DNAR), Some(Price::zero())); + }); +} + #[test] fn get_price_from_oracle() { ExtBuilder::default().build().execute_with(|| { @@ -53,16 +186,6 @@ fn get_price_of_stable_currency_id() { }); } -#[test] -fn get_price_of_setter_basket_currency_id() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - SetheumPrices::get_price(SETT), - Some(Price::saturating_from_integer(1606750)) - ); // 1.60675 USD, right shift the decimal point (18-12) places - }); -} - #[test] fn get_price_of_lp_token_currency_id() { ExtBuilder::default().build().execute_with(|| { @@ -102,12 +225,49 @@ fn get_relative_price_works() { ); assert_eq!( SetheumPrices::get_relative_price(USDJ, USDJ), - Some(Price::saturating_from_rational(1, 1)) // 1USDJ = 1USDJ, right shift the decimal point (10-10) places + Some(Price::saturating_from_rational(1, 1)) // 1USDJ = 1USDJ + ); + assert_eq!( + SetheumPrices::get_relative_price(USDJ, USD), + Some(Price::saturating_from_rational(1, 1)) // 1USDJ = 1USD + ); + assert_eq!( + SetheumPrices::get_relative_price(EUR, USD), + Some(Price::saturating_from_rational(10, 8)) // 1EUR = 1.25USD ); assert_eq!(SetheumPrices::get_relative_price(USDJ, DNAR), None); }); } +#[test] +fn get_market_relative_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_market_relative_price(DNAR, USDJ), + Some(Price::saturating_from_rational(10000, 1)) /* 1DNAR = 100USDJ, right shift the decimal point (12-10) + * places */ + ); + assert_eq!( + SetheumPrices::get_market_relative_price(JCHF, USDJ), + Some(Price::saturating_from_rational(500000000, 1)) /* 1JCHF = 50000USDJ, right shift the decimal point + * (12-8) places */ + ); + assert_eq!( + SetheumPrices::get_market_relative_price(USDJ, USDJ), + Some(Price::saturating_from_rational(1, 1)) // 1USDJ = 1USDJ + ); + assert_eq!( + SetheumPrices::get_market_relative_price(USDJ, USD), + Some(Price::saturating_from_rational(1, 1)) // 1USDJ = 1USD + ); + assert_eq!( + SetheumPrices::get_market_relative_price(EUR, USD), + Some(Price::saturating_from_rational(10, 8)) // 1EUR = 1.25USD + ); + assert_eq!(SetheumPrices::get_market_relative_price(USDJ, DNAR), None); + }); +} + #[test] fn get_coin_to_peg_relative_price_works() { ExtBuilder::default().build().execute_with(|| { @@ -144,6 +304,41 @@ fn get_coin_to_peg_relative_price_works() { }); } +#[test] +fn get_setter_basket_peg_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_setter_basket_peg_price(), + Some(Price::saturating_from_integer(1500750)) + ); // 1.500750 USD, right shift the decimal point (18-12) places + }); +} + +#[test] +fn get_setter_fixed_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_setter_fixed_price(), + Some(Price::saturating_from_integer(1600000)) + ); // 1.600000 USD, right shift the decimal point (18-12) places + }); +} + +#[test] +fn get_market_price_works() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + SetheumPrices::get_market_price(JCHF), + Some(Price::saturating_from_integer(1500000u128)) + ); // 1.5 USD, right shift the decimal point (18-12) places + assert_eq!( + SetheumPrices::get_market_price(DNAR), + Some(Price::saturating_from_integer(10000000000u128)) + ); + assert_eq!(SetheumPrices::get_market_price(DNAR), Some(Price::zero())); + }); +} + #[test] fn lock_price_work() { ExtBuilder::default().build().execute_with(|| { diff --git a/lib-serml/serp-treasury/src/lib.rs b/lib-serml/serp-treasury/src/lib.rs index c1e64da04..347e10bc4 100644 --- a/lib-serml/serp-treasury/src/lib.rs +++ b/lib-serml/serp-treasury/src/lib.rs @@ -364,7 +364,7 @@ impl SerpTreasury for Pallet { T::SerpAuctionManagerHandler::new_diamond_auction(&initial_amount, &amount) } else { - let settcurrency_fixed_price = T::Price::get_stablecoin_fixed_price(currency_id); + let settcurrency_fixed_price = T::Price::get_stablecoin_fixed_price(currency_id)?; let relative_price = setter_fixed_price.checked_div(&settcurrency_fixed_price); /// the initial amount is the equivalent of the serpdown amount - /// but in the (higher) fixed price not the (lower) market price @@ -390,8 +390,8 @@ impl SerpTreasury for Pallet { T::StableCurrencyIds::get().contains(¤cy_id), Error::::InvalidCurrencyType, ); - let market_price = T::Prices::get_stablecoin_market_price(¤cy_id); - let fixed_price = T::Prices::get_stablecoin_fixed_price(¤cy_id); + let market_price = T::Prices::get_stablecoin_market_price(¤cy_id)?; + let fixed_price = T::Prices::get_stablecoin_fixed_price(¤cy_id)?; let fixed_price_amount = T::Prices::amount_try_from_price_abs(&fixed_price)?; let market_price_amount = T::Prices::amount_try_from_price_abs(&market_price)?; let fixed_price_percent_amount = fixed_price_amount.checked_div(100); diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index 4c7a32a74..e319698be 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -244,15 +244,19 @@ pub trait SerpTreasuryExtended: SerpTreasury { } pub trait PriceProvider { - fn get_fiat_price(fiat_currency_id: CurrencyId) -> Option; + fn get_peg_currency_by_currency_id(currency_id: CurrencyId) -> Self::CurrencyId>; fn get_peg_price(currency_id: CurrencyId) -> Option; + fn get_fiat_price(fiat_currency_id: CurrencyId) -> Option; + fn get_fiat_usd_fixed_price() -> Option; fn get_settusd_fixed_price() -> Option; fn get_stablecoin_fixed_price(currency_id: CurrencyId) -> Option; fn get_stablecoin_market_price(currency_id: CurrencyId) -> Option; fn get_relative_price(base: CurrencyId, quote: CurrencyId) -> Option; + fn get_market_relative_price(base: CurrencyId, quote: CurrencyId) -> Option; fn get_coin_to_peg_relative_price(currency_id: CurrencyId) -> Option; fn get_setter_basket_peg_price() -> Option; fn get_setter_fixed_price() -> Option; + fn get_market_price(currency_id: CurrencyId) -> Option; fn get_price(currency_id: CurrencyId) -> Option; fn lock_price(currency_id: CurrencyId); fn unlock_price(currency_id: CurrencyId);