diff --git a/Cargo.lock b/Cargo.lock
index 28f586a9b3..e82eced0c5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7146,6 +7146,20 @@ dependencies = [
"sp-std",
]
+[[package]]
+name = "pallet-dynamic-evm-base-fee"
+version = "0.1.0"
+dependencies = [
+ "fp-evm",
+ "frame-support",
+ "frame-system",
+ "pallet-transaction-payment",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-runtime",
+]
+
[[package]]
name = "pallet-election-provider-multi-phase"
version = "4.0.0-dev"
diff --git a/pallets/dynamic-evm-base-fee/Cargo.toml b/pallets/dynamic-evm-base-fee/Cargo.toml
new file mode 100644
index 0000000000..6ba0e41c13
--- /dev/null
+++ b/pallets/dynamic-evm-base-fee/Cargo.toml
@@ -0,0 +1,43 @@
+[package]
+name = "pallet-dynamic-evm-base-fee"
+version = "0.1.0"
+license = "GPL-3.0-or-later"
+description = "Handler for dynamic EVM base fee for Astar tokenomics v2."
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+parity-scale-codec = { workspace = true }
+scale-info = { workspace = true }
+
+# Substrate
+frame-support = { workspace = true }
+frame-system = { workspace = true }
+sp-core = { workspace = true }
+sp-runtime = { workspace = true }
+pallet-transaction-payment = { workspace = true }
+
+# Frontier
+fp-evm = { workspace = true }
+
+[features]
+default = ["std"]
+std = [
+ "parity-scale-codec/std",
+ "scale-info/std",
+ # Substrate
+ "frame-support/std",
+ "frame-system/std",
+ "sp-core/std",
+ "sp-runtime/std",
+ "pallet-transaction-payment/std",
+ # Frontier
+ "fp-evm/std",
+]
+try-runtime = [
+ "frame-support/try-runtime",
+ "frame-system/try-runtime",
+ "pallet-transaction-payment/try-runtime",
+]
diff --git a/pallets/dynamic-evm-base-fee/src/lib.rs b/pallets/dynamic-evm-base-fee/src/lib.rs
new file mode 100644
index 0000000000..7ed9c2cebc
--- /dev/null
+++ b/pallets/dynamic-evm-base-fee/src/lib.rs
@@ -0,0 +1,118 @@
+// This file is part of Astar.
+
+// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+// Astar 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.
+
+// Astar 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 Astar. If not, see .
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use frame_support::{traits::Get, weights::Weight};
+use sp_core::U256;
+use sp_runtime::{traits::Convert, traits::UniqueSaturatedInto};
+
+pub use self::pallet::*;
+
+#[frame_support::pallet]
+pub mod pallet {
+ use frame_support::pallet_prelude::*;
+ use frame_system::pallet_prelude::*;
+
+ use super::*;
+
+ #[pallet::pallet]
+ pub struct Pallet(PhantomData);
+
+ #[pallet::config]
+ pub trait Config: frame_system::Config {
+ type RuntimeEvent: From + IsType<::RuntimeEvent>;
+ type DefaultBaseFeePerGas: Get;
+ type MinBaseFeePerGas: Get;
+ type MaxBaseFeePerGas: Get;
+ type AdjustmentLogic: Convert;
+ }
+
+ #[pallet::genesis_config]
+ pub struct GenesisConfig {
+ pub base_fee_per_gas: U256,
+ _marker: PhantomData,
+ }
+
+ impl Default for GenesisConfig {
+ fn default() -> Self {
+ Self {
+ base_fee_per_gas: T::DefaultBaseFeePerGas::get(),
+ _marker: PhantomData,
+ }
+ }
+ }
+
+ #[pallet::genesis_build]
+ impl GenesisBuild for GenesisConfig {
+ fn build(&self) {
+ BaseFeePerGas::::put(self.base_fee_per_gas);
+ }
+ }
+
+ #[pallet::type_value]
+ pub fn DefaultBaseFeePerGas() -> U256 {
+ T::DefaultBaseFeePerGas::get()
+ }
+
+ #[pallet::storage]
+ pub type BaseFeePerGas = StorageValue<_, U256, ValueQuery, DefaultBaseFeePerGas>;
+
+ #[pallet::event]
+ #[pallet::generate_deposit(pub(super) fn deposit_event)]
+ pub enum Event {
+ NewBaseFeePerGas { fee: U256 },
+ }
+
+ #[pallet::hooks]
+ impl Hooks> for Pallet {
+ fn on_initialize(_: T::BlockNumber) -> Weight {
+ // TODO: benchmark this!
+ let db_weight = ::DbWeight::get();
+ db_weight.reads_writes(2, 1)
+ }
+
+ fn on_finalize(_n: ::BlockNumber) {
+ BaseFeePerGas::::mutate(|base_fee_per_gas| {
+ let new_base_fee_per_gas =
+ T::AdjustmentLogic::convert(base_fee_per_gas.clone().unique_saturated_into());
+
+ *base_fee_per_gas = U256::from(new_base_fee_per_gas)
+ .clamp(T::MinBaseFeePerGas::get(), T::MaxBaseFeePerGas::get());
+ })
+ }
+ }
+
+ #[pallet::call]
+ impl Pallet {
+ #[pallet::call_index(0)]
+ #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())]
+ pub fn set_base_fee_per_gas(origin: OriginFor, fee: U256) -> DispatchResult {
+ ensure_root(origin)?;
+ BaseFeePerGas::::put(fee);
+ Self::deposit_event(Event::NewBaseFeePerGas { fee });
+ Ok(())
+ }
+ }
+}
+
+impl fp_evm::FeeCalculator for Pallet {
+ fn min_gas_price() -> (U256, Weight) {
+ (BaseFeePerGas::::get(), T::DbWeight::get().reads(1))
+ }
+}
diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs
index 24c352cc60..2ffdf7848f 100644
--- a/runtime/shibuya/src/lib.rs
+++ b/runtime/shibuya/src/lib.rs
@@ -103,7 +103,7 @@ pub const MICROSBY: Balance = 1_000_000_000_000;
pub const MILLISBY: Balance = 1_000 * MICROSBY;
pub const SBY: Balance = 1_000 * MILLISBY;
-pub const STORAGE_BYTE_FEE: Balance = 100 * MICROSBY;
+pub const STORAGE_BYTE_FEE: Balance = MICROSBY;
/// Charge fee for stored bytes and items.
pub const fn deposit(items: u32, bytes: u32) -> Balance {
@@ -117,7 +117,7 @@ pub const fn deposit(items: u32, bytes: u32) -> Balance {
///
/// TODO: using this requires storage migration (good to test on Shibuya first!)
pub const fn contracts_deposit(items: u32, bytes: u32) -> Balance {
- items as Balance * 4 * MILLISBY + (bytes as Balance) * STORAGE_BYTE_FEE
+ items as Balance * 40 * MICROSBY + (bytes as Balance) * STORAGE_BYTE_FEE
}
/// Change this to adjust the block time.
@@ -735,11 +735,12 @@ impl WeightToFeePolynomial for WeightToFee {
pub struct DealWithFees;
impl OnUnbalanced for DealWithFees {
fn on_unbalanceds(mut fees_then_tips: impl Iterator- ) {
- if let Some(mut fees) = fees_then_tips.next() {
+ if let Some(fees) = fees_then_tips.next() {
+ // Burn 80% of fees, rest goes to collators, including 100% of the tips.
+ let (to_burn, mut collators) = fees.ration(80, 20);
if let Some(tips) = fees_then_tips.next() {
- tips.merge_into(&mut fees);
+ tips.merge_into(&mut collators);
}
- let (to_burn, collators) = fees.ration(20, 80);
// burn part of fees
drop(to_burn);