Skip to content

Commit

Permalink
[Moonbase] Enable pallet-xcm precompile (#2803)
Browse files Browse the repository at this point in the history
* add pallet-xcm precompile to moonbase

* update moonkit pin

* fix rust tests

* update moonkit branch

* update moonkit pin

* fix moonkit imports

* add some comments

* pr suggestions

* apply changes to Erc20Match
  • Loading branch information
Agusrodri authored May 20, 2024
1 parent efd89b1 commit f2cd74e
Show file tree
Hide file tree
Showing 18 changed files with 547 additions and 185 deletions.
338 changes: 185 additions & 153 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ pallet-author-inherent = { git = "https://github.com/Moonsong-Labs/moonkit", bra
pallet-author-mapping = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v1.7.2", default-features = false }
pallet-author-slot-filter = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v1.7.2", default-features = false }
pallet-emergency-para-xcm = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v1.7.2", default-features = false }
pallet-evm-precompile-xcm = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v1.7.2", default-features = false }
pallet-maintenance-mode = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v1.7.2", default-features = false }
pallet-migrations = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v1.7.2", default-features = false }
pallet-randomness = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v1.7.2", default-features = false }
Expand Down
4 changes: 4 additions & 0 deletions precompiles/assets-erc20/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ sp-std = { workspace = true }
fp-evm = { workspace = true }
pallet-evm = { workspace = true, features = [ "forbid-evm-reentrancy" ] }

# Moonkit
moonkit-xcm-primitives = { workspace = true }

[dev-dependencies]
derive_more = { workspace = true }
hex-literal = { workspace = true }
Expand All @@ -51,6 +54,7 @@ std = [
"fp-evm/std",
"frame-support/std",
"frame-system/std",
"moonkit-xcm-primitives/std",
"pallet-assets/std",
"pallet-balances/std",
"pallet-evm/std",
Expand Down
11 changes: 1 addition & 10 deletions precompiles/assets-erc20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use frame_support::{
dispatch::{GetDispatchInfo, PostDispatchInfo},
sp_runtime::traits::StaticLookup,
};
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use pallet_evm::AddressMapping;
use precompile_utils::prelude::*;
use sp_runtime::traits::{Bounded, Dispatchable};
Expand Down Expand Up @@ -59,16 +60,6 @@ pub type BalanceOf<Runtime, Instance = ()> = <Runtime as pallet_assets::Config<I
/// Alias for the Asset Id type for the provided Runtime and Instance.
pub type AssetIdOf<Runtime, Instance = ()> = <Runtime as pallet_assets::Config<Instance>>::AssetId;

/// This trait ensure we can convert AccountIds to AssetIds
/// We will require Runtime to have this trait implemented
pub trait AccountIdAssetIdConversion<Account, AssetId> {
// Get assetId and prefix from account
fn account_to_asset_id(account: Account) -> Option<(Vec<u8>, AssetId)>;

// Get AccountId from AssetId and prefix
fn asset_id_to_account(prefix: &[u8], asset_id: AssetId) -> Account;
}

/// The following distribution has been decided for the precompiles
/// 0-1023: Ethereum Mainnet Precompiles
/// 1024-2047 Precompiles that are not in Ethereum Mainnet but are neither Moonbeam specific
Expand Down
2 changes: 2 additions & 0 deletions runtime/moonbase/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ pallet-async-backing = { workspace = true }
pallet-author-inherent = { workspace = true }
pallet-author-slot-filter = { workspace = true }
pallet-emergency-para-xcm = { workspace = true }
pallet-evm-precompile-xcm = { workspace = true }
pallet-relay-storage-roots = { workspace = true }

# Benchmarking
Expand Down Expand Up @@ -251,6 +252,7 @@ std = [
"pallet-evm-precompile-referenda/std",
"pallet-evm-precompile-registry/std",
"pallet-evm-precompile-relay-verifier/std",
"pallet-evm-precompile-xcm/std",
"pallet-evm-precompile-xcm-transactor/std",
"pallet-evm-precompile-xcm-utils/std",
"pallet-evm-precompile-xtokens/std",
Expand Down
2 changes: 1 addition & 1 deletion runtime/moonbase/src/asset_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use super::{
};

use moonbeam_runtime_common::weights as moonbeam_weights;
use pallet_evm_precompileset_assets_erc20::AccountIdAssetIdConversion;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;

use frame_support::{
dispatch::GetDispatchInfo,
Expand Down
38 changes: 33 additions & 5 deletions runtime/moonbase/src/precompiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.

use crate::{
asset_config::ForeignAssetInstance, xcm_config::XcmExecutorConfig, OpenTechCommitteeInstance,
TreasuryCouncilInstance,
asset_config::ForeignAssetInstance,
xcm_config::{AssetType, XcmExecutorConfig},
OpenTechCommitteeInstance, TreasuryCouncilInstance,
};
use crate::{AssetId, H160};
use crate::{AccountId, AssetId, AssetManager, Balances, Erc20XcmBridge, Runtime, H160};
use frame_support::parameter_types;
use moonkit_xcm_primitives::{
location_matcher::{Erc20PalletMatcher, ForeignAssetMatcher, SingleAddressMatcher},
AccountIdAssetIdConversion,
};
use pallet_evm_precompile_author_mapping::AuthorMappingPrecompile;
use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata};
use pallet_evm_precompile_batch::BatchPrecompile;
Expand All @@ -43,14 +48,16 @@ use pallet_evm_precompile_relay_verifier::RelayDataVerifierPrecompile;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
use pallet_evm_precompile_storage_cleaner::StorageCleanerPrecompile;
use pallet_evm_precompile_xcm::PalletXcmPrecompile;
use pallet_evm_precompile_xcm_transactor::{
v1::XcmTransactorPrecompileV1, v2::XcmTransactorPrecompileV2, v3::XcmTransactorPrecompileV3,
};
use pallet_evm_precompile_xcm_utils::{AllExceptXcmExecute, XcmUtilsPrecompile};
use pallet_evm_precompile_xtokens::XtokensPrecompile;
use pallet_evm_precompileset_assets_erc20::{AccountIdAssetIdConversion, Erc20AssetsPrecompileSet};
use pallet_evm_precompileset_assets_erc20::Erc20AssetsPrecompileSet;
use precompile_utils::precompile_set::*;
use sp_std::prelude::*;
use xcm_primitives::AsAssetType;

/// ERC20 metadata for the native token.
pub struct NativeErc20Metadata;
Expand Down Expand Up @@ -85,13 +92,29 @@ pub const FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4];
/// to Erc20AssetsPrecompileSet being marked as local
pub const LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8, 255u8, 255u8, 254u8];

/// Const to identify ERC20_BALANCES_PRECOMPILE address
pub const ERC20_BALANCES_PRECOMPILE: u64 = 2050;

parameter_types! {
pub ForeignAssetPrefix: &'static [u8] = FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX;
pub LocalAssetPrefix: &'static [u8] = LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX;
}

type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);

// Pallet-xcm precompile types.
// Type that converts AssetId into Location
type AssetIdToLocationManager = AsAssetType<AssetId, AssetType, AssetManager>;

// The pallet-balances address is identified by ERC20_BALANCES_PRECOMPILE const
type SingleAddressMatch = SingleAddressMatcher<AccountId, ERC20_BALANCES_PRECOMPILE, Balances>;

// Type that matches an AccountId with a foreign asset address (if any)
type ForeignAssetMatch = ForeignAssetMatcher<AccountId, AssetId, Runtime, AssetIdToLocationManager>;

// Erc20XcmBridge pallet is used to match ERC20s
type Erc20Match = Erc20PalletMatcher<AccountId, Erc20XcmBridge>;

#[precompile_utils::precompile_name_from_address]
type MoonbasePrecompilesAt<R> = (
// Ethereum precompiles:
Expand Down Expand Up @@ -122,7 +145,7 @@ type MoonbasePrecompilesAt<R> = (
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2050>,
AddressU64<ERC20_BALANCES_PRECOMPILE>,
Erc20BalancesPrecompile<R, NativeErc20Metadata>,
(CallableByContract, CallableByPrecompile),
>,
Expand Down Expand Up @@ -240,6 +263,11 @@ type MoonbasePrecompilesAt<R> = (
RelayDataVerifierPrecompile<R>,
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2074>,
PalletXcmPrecompile<R, (SingleAddressMatch, ForeignAssetMatch, Erc20Match)>,
(CallableByContract, CallableByPrecompile),
>,
);

pub struct DisabledLocalAssets<Runtime>(sp_std::marker::PhantomData<Runtime>);
Expand Down
2 changes: 1 addition & 1 deletion runtime/moonbase/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use super::{
};
use crate::OpenTechCommitteeInstance;
use moonbeam_runtime_common::weights as moonbeam_weights;
use pallet_evm_precompileset_assets_erc20::AccountIdAssetIdConversion;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use sp_runtime::{
traits::{Hash as THash, MaybeEquivalence, PostDispatchInfoOf},
DispatchErrorWithPostInfo,
Expand Down
7 changes: 3 additions & 4 deletions runtime/moonbase/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,10 @@ use xcm_builder::{ParentIsPreset, SiblingParachainConvertsVia};
use xcm_executor::traits::ConvertLocation;

use moonbeam_xcm_benchmarks::weights::XcmWeight;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use nimbus_primitives::NimbusId;
use pallet_evm::PrecompileSet;
use pallet_evm_precompileset_assets_erc20::{
AccountIdAssetIdConversion, SELECTOR_LOG_APPROVAL, SELECTOR_LOG_TRANSFER,
};
use pallet_evm_precompileset_assets_erc20::{SELECTOR_LOG_APPROVAL, SELECTOR_LOG_TRANSFER};
use pallet_transaction_payment::Multiplier;
use pallet_xcm_transactor::{Currency, CurrencyPayment, HrmpOperation, TransactWeights};
use parity_scale_codec::Encode;
Expand Down Expand Up @@ -2529,7 +2528,7 @@ fn precompile_existence() {
let precompile_addresses: std::collections::BTreeSet<_> = vec![
1, 2, 3, 4, 5, 6, 7, 8, 9, 1024, 1025, 1026, 1027, 2048, 2049, 2050, 2051, 2052, 2053,
2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067,
2068, 2069, 2070, 2071, 2072, 2073,
2068, 2069, 2070, 2071, 2072, 2073, 2074,
]
.into_iter()
.map(H160::from_low_u64_be)
Expand Down
2 changes: 1 addition & 1 deletion runtime/moonbeam/src/asset_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use frame_support::{
weights::Weight,
};
use moonbeam_runtime_common::weights as moonbeam_weights;
use pallet_evm_precompileset_assets_erc20::AccountIdAssetIdConversion;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;

use frame_system::{EnsureNever, EnsureRoot};
use sp_core::H160;
Expand Down
3 changes: 2 additions & 1 deletion runtime/moonbeam/src/precompiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
};
use crate::{AssetId, H160};
use frame_support::parameter_types;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use pallet_evm_precompile_author_mapping::AuthorMappingPrecompile;
use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata};
use pallet_evm_precompile_batch::BatchPrecompile;
Expand Down Expand Up @@ -47,7 +48,7 @@ use pallet_evm_precompile_xcm_transactor::{
};
use pallet_evm_precompile_xcm_utils::XcmUtilsPrecompile;
use pallet_evm_precompile_xtokens::XtokensPrecompile;
use pallet_evm_precompileset_assets_erc20::{AccountIdAssetIdConversion, Erc20AssetsPrecompileSet};
use pallet_evm_precompileset_assets_erc20::Erc20AssetsPrecompileSet;
use precompile_utils::precompile_set::*;
use sp_std::prelude::*;

Expand Down
2 changes: 1 addition & 1 deletion runtime/moonbeam/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use frame_support::{
traits::{EitherOfDiverse, Everything, Nothing, PalletInfoAccess, TransformOrigin},
};
use moonbeam_runtime_common::weights as moonbeam_weights;
use pallet_evm_precompileset_assets_erc20::AccountIdAssetIdConversion;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use sp_runtime::{
traits::{Hash as THash, MaybeEquivalence, PostDispatchInfoOf},
DispatchErrorWithPostInfo,
Expand Down
5 changes: 2 additions & 3 deletions runtime/moonbeam/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ use moonbeam_runtime::{
FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
};
use moonbeam_xcm_benchmarks::weights::XcmWeight;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use nimbus_primitives::NimbusId;
use pallet_evm::PrecompileSet;
use pallet_evm_precompileset_assets_erc20::{
AccountIdAssetIdConversion, SELECTOR_LOG_APPROVAL, SELECTOR_LOG_TRANSFER,
};
use pallet_evm_precompileset_assets_erc20::{SELECTOR_LOG_APPROVAL, SELECTOR_LOG_TRANSFER};
use pallet_transaction_payment::Multiplier;
use pallet_xcm_transactor::{Currency, CurrencyPayment, TransactWeights};
use parity_scale_codec::Encode;
Expand Down
2 changes: 1 addition & 1 deletion runtime/moonriver/src/asset_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use super::{
};

use moonbeam_runtime_common::weights as moonbeam_weights;
use pallet_evm_precompileset_assets_erc20::AccountIdAssetIdConversion;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;

use frame_support::{
dispatch::GetDispatchInfo,
Expand Down
2 changes: 1 addition & 1 deletion runtime/moonriver/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use frame_support::{
traits::{EitherOfDiverse, Everything, Nothing, PalletInfoAccess, TransformOrigin},
};
use moonbeam_runtime_common::weights as moonbeam_weights;
use pallet_evm_precompileset_assets_erc20::AccountIdAssetIdConversion;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use sp_runtime::{
traits::{Hash as THash, MaybeEquivalence, PostDispatchInfoOf},
DispatchErrorWithPostInfo,
Expand Down
5 changes: 2 additions & 3 deletions runtime/moonriver/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use frame_support::{
StorageHasher, Twox128,
};
use moonbeam_xcm_benchmarks::weights::XcmWeight;
use moonkit_xcm_primitives::AccountIdAssetIdConversion;
use moonriver_runtime::{
asset_config::ForeignAssetInstance,
xcm_config::{CurrencyId, SelfReserve},
Expand All @@ -42,9 +43,7 @@ use moonriver_runtime::{
};
use nimbus_primitives::NimbusId;
use pallet_evm::PrecompileSet;
use pallet_evm_precompileset_assets_erc20::{
AccountIdAssetIdConversion, SELECTOR_LOG_APPROVAL, SELECTOR_LOG_TRANSFER,
};
use pallet_evm_precompileset_assets_erc20::{SELECTOR_LOG_APPROVAL, SELECTOR_LOG_TRANSFER};
use pallet_transaction_payment::Multiplier;
use pallet_xcm_transactor::{Currency, CurrencyPayment, TransactWeights};
use parity_scale_codec::Encode;
Expand Down
102 changes: 102 additions & 0 deletions test/contracts/src/XcmInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.3;

/// @dev The XCM contract's address.
address constant XCM_CONTRACT_ADDRESS = 0x000000000000000000000000000000000000081A;

/// @dev The XCM contract's instance.
XCM constant XCM_CONTRACT = XCM(XCM_CONTRACT_ADDRESS);

/// @author The Moonbeam Team
/// @title XCM precompile Interface
/// @dev The interface that Solidity contracts use to interact with the substrate pallet-xcm.
interface XCM {
// A location is defined by its number of parents and the encoded junctions (interior)
struct Location {
uint8 parents;
bytes[] interior;
}

// Support for Weights V2
struct Weight {
uint64 refTime;
uint64 proofSize;
}

// A way to represent fungible assets in XCM using Location format
struct AssetLocationInfo {
Location location;
uint256 amount;
}

// A way to represent fungible assets in XCM using address format
struct AssetAddressInfo {
address asset;
uint256 amount;
}

/// @dev Function to send assets via XCM using transfer_assets() pallet-xcm extrinsic.
/// @custom:selector 59df8416
/// @param dest The destination chain.
/// @param beneficiary The actual account that will receive the tokens on dest.
/// @param assets The combination (array) of assets to send.
/// @param feeAssetItem The index of the asset that will be used to pay for fees.
/// @param weight The weight to be used for the whole XCM operation.
/// (uint64::MAX in refTime means Unlimited weight)
function transferAssetsLocation(
Location memory dest,
Location memory beneficiary,
AssetLocationInfo[] memory assets,
uint32 feeAssetItem,
Weight memory weight
) external;

/// @dev Function to send assets via XCM to a 20 byte-like parachain
/// using transfer_assets() pallet-xcm extrinsic.
/// @custom:selector b489262e
/// @param paraId The para-id of the destination chain.
/// @param beneficiary The actual account that will receive the tokens on paraId destination.
/// @param assets The combination (array) of assets to send.
/// @param feeAssetItem The index of the asset that will be used to pay for fees.
/// @param weight The weight to be used for the whole XCM operation.
/// (uint64::MAX in refTime means Unlimited weight)
function transferAssetsToPara20(
uint32 paraId,
address beneficiary,
AssetAddressInfo[] memory assets,
uint32 feeAssetItem,
Weight memory weight
) external;

/// @dev Function to send assets via XCM to a 32 byte-like parachain
/// using transfer_assets() pallet-xcm extrinsic.
/// @custom:selector 4461e6f5
/// @param paraId The para-id of the destination chain.
/// @param beneficiary The actual account that will receive the tokens on paraId destination.
/// @param assets The combination (array) of assets to send.
/// @param feeAssetItem The index of the asset that will be used to pay for fees.
/// @param weight The weight to be used for the whole XCM operation.
/// (uint64::MAX in refTime means Unlimited weight)
function transferAssetsToPara32(
uint32 paraId,
bytes32 beneficiary,
AssetAddressInfo[] memory assets,
uint32 feeAssetItem,
Weight memory weight
) external;

/// @dev Function to send assets via XCM to the relay chain
/// using transfer_assets() pallet-xcm extrinsic.
/// @custom:selector d7c89659
/// @param beneficiary The actual account that will receive the tokens on the relay chain.
/// @param assets The combination (array) of assets to send.
/// @param feeAssetItem The index of the asset that will be used to pay for fees.
/// @param weight The weight to be used for the whole XCM operation.
/// (uint64::MAX in refTime means Unlimited weight)
function transferAssetsToRelay(
bytes32 beneficiary,
AssetAddressInfo[] memory assets,
uint32 feeAssetItem,
Weight memory weight
) external;
}
Loading

0 comments on commit f2cd74e

Please sign in to comment.