Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/evm fee burning #1390

Merged
merged 5 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 59 additions & 3 deletions primitives/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,18 @@

use crate::{AccountId, AssetId};

use frame_support::ensure;
use pallet_evm::{AddressMapping, HashedAddressMapping};
use frame_support::{
ensure,
traits::{
fungible::{Balanced, Credit},
tokens::{fungible::Inspect, imbalance::OnUnbalanced},
},
};
use pallet_evm::{AddressMapping, HashedAddressMapping, OnChargeEVMTransaction};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::{Hasher, H160, H256};
use sp_core::{Hasher, H160, H256, U256};
use sp_runtime::traits::UniqueSaturatedInto;
use sp_std::marker::PhantomData;

use pallet_assets::AssetsCallback;
Expand Down Expand Up @@ -139,3 +146,52 @@ impl<Address> UnifiedAddress<Address> {
}
}
}

/// Wrapper around the `EvmFungibleAdapter` from the `pallet-evm`.
///
/// While it provides most of the functionality we need,
/// it doesn't allow the tip to be deposited into an arbitrary account.
/// This adapter allows us to do that.
///
/// Two separate `OnUnbalanced` handers are used:
/// - `UOF` for the fee
/// - `OUT` for the tip
pub struct EVMFungibleAdapterWrapper<F, FeeHandler, TipHandler>(
core::marker::PhantomData<(F, FeeHandler, TipHandler)>,
);
impl<T, F, FeeHandler, TipHandler> OnChargeEVMTransaction<T>
for EVMFungibleAdapterWrapper<F, FeeHandler, TipHandler>
where
T: pallet_evm::Config,
F: Balanced<T::AccountId>,
FeeHandler: OnUnbalanced<Credit<T::AccountId, F>>,
TipHandler: OnUnbalanced<Credit<T::AccountId, F>>,
U256: UniqueSaturatedInto<<F as Inspect<<T as frame_system::Config>::AccountId>>::Balance>,
{
// Kept type as Option to satisfy bound of Default
type LiquidityInfo = Option<Credit<T::AccountId, F>>;

fn withdraw_fee(who: &H160, fee: U256) -> Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
pallet_evm::EVMFungibleAdapter::<F, FeeHandler>::withdraw_fee(who, fee)
}

fn correct_and_deposit_fee(
who: &H160,
corrected_fee: U256,
base_fee: U256,
already_withdrawn: Self::LiquidityInfo,
) -> Self::LiquidityInfo {
<pallet_evm::EVMFungibleAdapter::<F, FeeHandler> as OnChargeEVMTransaction<T>>::correct_and_deposit_fee(
who,
corrected_fee,
base_fee,
already_withdrawn,
)
}

fn pay_priority_fee(tip: Self::LiquidityInfo) {
if let Some(tip) = tip {
TipHandler::on_unbalanceds(Some(tip).into_iter());
}
}
}
37 changes: 15 additions & 22 deletions runtime/astar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ use astar_primitives::{
AccountCheck as DappStakingAccountCheck, CycleConfiguration, DAppId, EraNumber,
PeriodNumber, RankedTier, SmartContract, StandardTierSlots,
},
evm::EvmRevertCodeHandler,
evm::{EVMFungibleAdapterWrapper, EvmRevertCodeHandler},
governance::{
CommunityCouncilCollectiveInst, CommunityCouncilMembershipInst, CommunityTreasuryInst,
EnsureRootOrAllMainCouncil, EnsureRootOrAllTechnicalCommittee,
Expand Down Expand Up @@ -474,7 +474,7 @@ impl pallet_inflation::PayoutPerBlock<Credit<AccountId, Balances>> for Inflation
}

fn collators(reward: Credit<AccountId, Balances>) {
ToStakingPot::on_unbalanced(reward);
CollatorRewardPot::on_unbalanced(reward);
}
}

Expand Down Expand Up @@ -614,8 +614,8 @@ parameter_types! {
pub TreasuryAccountId: AccountId = TreasuryPalletId::get().into_account_truncating();
}

pub struct ToStakingPot;
impl OnUnbalanced<Credit<AccountId, Balances>> for ToStakingPot {
pub struct CollatorRewardPot;
impl OnUnbalanced<Credit<AccountId, Balances>> for CollatorRewardPot {
fn on_nonzero_unbalanced(amount: Credit<AccountId, Balances>) {
let staking_pot = PotId::get().into_account_truncating();
let _ = Balances::resolve(&staking_pot, amount);
Expand Down Expand Up @@ -838,9 +838,13 @@ impl OnUnbalanced<Credit<AccountId, Balances>> for DealWithFees {
drop(to_burn);

// pay fees to collator
<ToStakingPot as OnUnbalanced<_>>::on_unbalanced(collator);
<CollatorRewardPot as OnUnbalanced<_>>::on_unbalanced(collator);
}
}

fn on_unbalanced(amount: Credit<AccountId, Balances>) {
Self::on_unbalanceds(Some(amount).into_iter());
}
}

impl pallet_transaction_payment::Config for Runtime {
Expand Down Expand Up @@ -946,7 +950,7 @@ impl pallet_evm::Config for Runtime {
type PrecompilesType = Precompiles;
type PrecompilesValue = PrecompilesValue;
type ChainId = ChainId;
type OnChargeTransaction = pallet_evm::EVMFungibleAdapter<Balances, ToStakingPot>;
type OnChargeTransaction = EVMFungibleAdapterWrapper<Balances, DealWithFees, CollatorRewardPot>;
type BlockGasLimit = BlockGasLimit;
type Timestamp = Timestamp;
type OnCreate = ();
Expand Down Expand Up @@ -1026,7 +1030,7 @@ pub enum ProxyType {
/// Allows all runtime calls for proxy account
Any,
/// Allows only NonTransfer runtime calls for proxy account
/// To know exact calls check InstanceFilter inmplementation for ProxyTypes
/// To know exact calls check InstanceFilter implementation for ProxyTypes
NonTransfer,
/// All Runtime calls from Pallet Balances allowed for proxy account
Balances,
Expand Down Expand Up @@ -1062,26 +1066,15 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
c,
RuntimeCall::System(..)
| RuntimeCall::Identity(..)
| RuntimeCall::Timestamp(..)
| RuntimeCall::Multisig(..)
| RuntimeCall::Proxy(..)
| RuntimeCall::ParachainSystem(..)
| RuntimeCall::ParachainInfo(..)
// Skip entire Balances pallet
| RuntimeCall::Vesting(pallet_vesting::Call::vest{..})
| RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..})
// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
| RuntimeCall::Vesting(
pallet_vesting::Call::vest { .. }
| pallet_vesting::Call::vest_other { .. }
)
| RuntimeCall::DappStaking(..)
// Skip entire Assets pallet
| RuntimeCall::CollatorSelection(..)
| RuntimeCall::Session(..)
| RuntimeCall::XcmpQueue(..)
| RuntimeCall::PolkadotXcm(..)
| RuntimeCall::CumulusXcm(..)
| RuntimeCall::XcAssetConfig(..)
// Skip entire EVM pallet
// Skip entire Ethereum pallet
| RuntimeCall::DynamicEvmBaseFee(..) // Skip entire Contracts pallet
)
}
ProxyType::Balances => {
Expand Down
14 changes: 4 additions & 10 deletions runtime/local/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,18 +811,12 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
matches!(
c,
RuntimeCall::System(..)
| RuntimeCall::Timestamp(..)
| RuntimeCall::Scheduler(..)
| RuntimeCall::Proxy(..)
| RuntimeCall::Grandpa(..)
// Skip entire Balances pallet
| RuntimeCall::Vesting(pallet_vesting::Call::vest{..})
| RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..})
// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
| RuntimeCall::Vesting(
pallet_vesting::Call::vest { .. }
| pallet_vesting::Call::vest_other { .. }
)
| RuntimeCall::DappStaking(..)
// Skip entire EVM pallet
// Skip entire Ethereum pallet
| RuntimeCall::DynamicEvmBaseFee(..) // Skip entire Contracts pallet
)
}
// All Runtime calls from Pallet Balances allowed for proxy account
Expand Down
37 changes: 14 additions & 23 deletions runtime/shibuya/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ use astar_primitives::{
AccountCheck as DappStakingAccountCheck, CycleConfiguration, DAppId, EraNumber,
PeriodNumber, RankedTier, SmartContract, StandardTierSlots,
},
evm::{EvmRevertCodeHandler, HashedDefaultMappings},
evm::{EVMFungibleAdapterWrapper, EvmRevertCodeHandler, HashedDefaultMappings},
governance::{
CommunityCouncilCollectiveInst, CommunityCouncilMembershipInst, CommunityTreasuryInst,
EnsureRootOrAllMainCouncil, EnsureRootOrAllTechnicalCommittee,
Expand Down Expand Up @@ -497,7 +497,7 @@ impl pallet_inflation::PayoutPerBlock<Credit<AccountId, Balances>> for Inflation
}

fn collators(reward: Credit<AccountId, Balances>) {
ToStakingPot::on_unbalanced(reward);
CollatorRewardPot::on_unbalanced(reward);
}
}

Expand Down Expand Up @@ -638,8 +638,8 @@ parameter_types! {
pub TreasuryAccountId: AccountId = TreasuryPalletId::get().into_account_truncating();
}

pub struct ToStakingPot;
impl OnUnbalanced<Credit<AccountId, Balances>> for ToStakingPot {
pub struct CollatorRewardPot;
impl OnUnbalanced<Credit<AccountId, Balances>> for CollatorRewardPot {
fn on_nonzero_unbalanced(amount: Credit<AccountId, Balances>) {
let staking_pot = PotId::get().into_account_truncating();
let _ = Balances::resolve(&staking_pot, amount);
Expand Down Expand Up @@ -834,9 +834,13 @@ impl OnUnbalanced<Credit<AccountId, Balances>> for DealWithFees {
drop(to_burn);

// pay fees to collator
<ToStakingPot as OnUnbalanced<_>>::on_unbalanced(collator);
<CollatorRewardPot as OnUnbalanced<_>>::on_unbalanced(collator);
}
}

fn on_unbalanced(amount: Credit<AccountId, Balances>) {
Self::on_unbalanceds(Some(amount).into_iter());
}
}

impl pallet_transaction_payment::Config for Runtime {
Expand Down Expand Up @@ -947,7 +951,7 @@ impl pallet_evm::Config for Runtime {
// Ethereum-compatible chain_id:
// * Shibuya: 81
type ChainId = EVMChainId;
type OnChargeTransaction = pallet_evm::EVMFungibleAdapter<Balances, ToStakingPot>;
type OnChargeTransaction = EVMFungibleAdapterWrapper<Balances, DealWithFees, CollatorRewardPot>;
type BlockGasLimit = BlockGasLimit;
type Timestamp = Timestamp;
type OnCreate = ();
Expand Down Expand Up @@ -1042,27 +1046,14 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
c,
RuntimeCall::System(..)
| RuntimeCall::Identity(..)
| RuntimeCall::Timestamp(..)
| RuntimeCall::Multisig(..)
| RuntimeCall::Scheduler(..)
| RuntimeCall::Proxy(..)
| RuntimeCall::ParachainSystem(..)
| RuntimeCall::ParachainInfo(..)
// Skip entire Balances pallet
| RuntimeCall::Vesting(pallet_vesting::Call::vest{..})
| RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..})
// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
| RuntimeCall::Vesting(
pallet_vesting::Call::vest { .. }
| pallet_vesting::Call::vest_other { .. }
)
| RuntimeCall::DappStaking(..)
// Skip entire Assets pallet
| RuntimeCall::CollatorSelection(..)
| RuntimeCall::Session(..)
| RuntimeCall::XcmpQueue(..)
| RuntimeCall::PolkadotXcm(..)
| RuntimeCall::CumulusXcm(..)
| RuntimeCall::XcAssetConfig(..)
// Skip entire EVM pallet
// Skip entire Ethereum pallet
| RuntimeCall::DynamicEvmBaseFee(..) // Skip entire Contracts pallet
)
}
// All Runtime calls from Pallet Balances allowed for proxy account
Expand Down
36 changes: 14 additions & 22 deletions runtime/shiden/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ use astar_primitives::{
AccountCheck as DappStakingAccountCheck, CycleConfiguration, DAppId, EraNumber,
PeriodNumber, RankedTier, SmartContract, TierSlots as TierSlotsFunc,
},
evm::EvmRevertCodeHandler,
evm::{EVMFungibleAdapterWrapper, EvmRevertCodeHandler},
governance::OracleMembershipInst,
oracle::{CurrencyAmount, CurrencyId, DummyCombineData, Price},
xcm::AssetLocationIdConverter,
Expand Down Expand Up @@ -462,7 +462,7 @@ impl pallet_inflation::PayoutPerBlock<Credit<AccountId, Balances>> for Inflation
}

fn collators(reward: Credit<AccountId, Balances>) {
ToStakingPot::on_unbalanced(reward);
CollatorRewardPot::on_unbalanced(reward);
}
}

Expand Down Expand Up @@ -601,8 +601,8 @@ parameter_types! {
pub TreasuryAccountId: AccountId = TreasuryPalletId::get().into_account_truncating();
}

pub struct ToStakingPot;
impl OnUnbalanced<Credit<AccountId, Balances>> for ToStakingPot {
pub struct CollatorRewardPot;
impl OnUnbalanced<Credit<AccountId, Balances>> for CollatorRewardPot {
fn on_nonzero_unbalanced(amount: Credit<AccountId, Balances>) {
let staking_pot = PotId::get().into_account_truncating();
let _ = Balances::resolve(&staking_pot, amount);
Expand Down Expand Up @@ -813,9 +813,13 @@ impl OnUnbalanced<Credit<AccountId, Balances>> for DealWithFees {
drop(to_burn);

// pay fees to collator
<ToStakingPot as OnUnbalanced<_>>::on_unbalanced(collator);
<CollatorRewardPot as OnUnbalanced<_>>::on_unbalanced(collator);
}
}

fn on_unbalanced(amount: Credit<AccountId, Balances>) {
Self::on_unbalanceds(Some(amount).into_iter());
}
}

impl pallet_transaction_payment::Config for Runtime {
Expand Down Expand Up @@ -920,7 +924,7 @@ impl pallet_evm::Config for Runtime {
type PrecompilesType = Precompiles;
type PrecompilesValue = PrecompilesValue;
type ChainId = ChainId;
type OnChargeTransaction = pallet_evm::EVMFungibleAdapter<Balances, ToStakingPot>;
type OnChargeTransaction = EVMFungibleAdapterWrapper<Balances, DealWithFees, CollatorRewardPot>;
type BlockGasLimit = BlockGasLimit;
type Timestamp = Timestamp;
type OnCreate = ();
Expand Down Expand Up @@ -1007,26 +1011,14 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
c,
RuntimeCall::System(..)
| RuntimeCall::Identity(..)
| RuntimeCall::Timestamp(..)
| RuntimeCall::Multisig(..)
| RuntimeCall::Proxy(..)
| RuntimeCall::ParachainSystem(..)
| RuntimeCall::ParachainInfo(..)
// Skip entire Balances pallet
| RuntimeCall::Vesting(pallet_vesting::Call::vest{..})
| RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..})
// Specifically omitting Vesting `vested_transfer`, and `force_vested_transfer`
| RuntimeCall::Vesting(
pallet_vesting::Call::vest { .. }
| pallet_vesting::Call::vest_other { .. }
)
| RuntimeCall::DappStaking(..)
// Skip entire Assets pallet
| RuntimeCall::CollatorSelection(..)
| RuntimeCall::Session(..)
| RuntimeCall::XcmpQueue(..)
| RuntimeCall::PolkadotXcm(..)
| RuntimeCall::CumulusXcm(..)
| RuntimeCall::XcAssetConfig(..)
// Skip entire EVM pallet
// Skip entire Ethereum pallet
| RuntimeCall::DynamicEvmBaseFee(..) // Skip entire Contracts pallet
)
}
ProxyType::Balances => {
Expand Down
Loading
Loading