Skip to content

Commit

Permalink
Add support for pallet-xcm precompile (#35)
Browse files Browse the repository at this point in the history
* add pallet-xcm precompile

* update interface docs

* update comment for Unlimited weight

* add comment in record_cost

* mock cleanup

* remove custom address from solidity interface

* start converter implementation (PoC)

* use size_of in AssetIdInfo

* fmt

* refactor converter

* fmt

* add Erc20PalletMatcher and adapt mock

* remove unused import

* minor fixes

* add new functions

* refactor ForeignAssetMatcher

* rust fmt

* add more tests and handle db reads costs

* fix tests

* use proper origin in mock

* update solidity interface docs

* remove TODO comment
  • Loading branch information
Agusrodri authored Apr 24, 2024
1 parent 47ac46f commit 66edb0e
Show file tree
Hide file tree
Showing 14 changed files with 1,696 additions and 10 deletions.
40 changes: 40 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ flume = "0.11.0"
jsonrpsee = { version = "0.20.3" }
hex-literal = "0.4.1"

# Moonkit
pallet-foreign-asset-creator = { path = "pallets/foreign-asset-creator", default-features = false }

# Substrate (wasm)
frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.7.0", 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 @@ -27,6 +27,9 @@ sp-std = { workspace = true }
fp-evm = { workspace = true }
pallet-evm = { workspace = true, features = [ "forbid-evm-reentrancy" ] }

# Moonkit
xcm-primitives = { workspace = true }

[dev-dependencies]
hex-literal = { workspace = true }
libsecp256k1 = { workspace = true }
Expand Down Expand Up @@ -57,4 +60,5 @@ std = [
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
"xcm-primitives/std",
]
11 changes: 1 addition & 10 deletions precompiles/assets-erc20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use sp_std::{
convert::{TryFrom, TryInto},
marker::PhantomData,
};
use xcm_primitives::AccountIdAssetIdConversion;

mod eip2612;
use eip2612::Eip2612;
Expand All @@ -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
1 change: 1 addition & 0 deletions precompiles/assets-erc20/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use sp_runtime::{
traits::{BlakeTwo256, ConstU32, IdentityLookup},
BuildStorage,
};
use xcm_primitives::AccountIdAssetIdConversion;

pub type AccountId = MockAccount;
pub type AssetId = u128;
Expand Down
76 changes: 76 additions & 0 deletions precompiles/pallet-xcm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
[package]
name = "pallet-evm-precompile-xcm"
authors = { workspace = true }
description = "A Precompile to make pallet-xcm accessible to pallet-evm"
edition = "2021"
version = "0.1.0"

[dependencies]
log = { workspace = true }
num_enum = { workspace = true }

# Moonbeam
precompile-utils = { workspace = true }
xcm-primitives = { workspace = true }

# Substrate
frame-support = { workspace = true }
frame-system = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
sp-weights = { workspace = true }

# Frontier
evm = { workspace = true, features = [ "with-codec" ] }
fp-evm = { workspace = true }
pallet-evm = { workspace = true, features = [ "forbid-evm-reentrancy" ] }

# Polkadot
xcm = { workspace = true }
pallet-xcm = { workspace = true }

# Cumulus
cumulus-primitives-core = { workspace = true }

[dev-dependencies]
derive_more = { workspace = true }

# Moonbeam
precompile-utils = { workspace = true, features = [ "testing", "codec-xcm" ] }
xcm-primitives = { workspace = true }

# Substrate
pallet-assets = { workspace = true, features = [ "std" ] }
pallet-balances = { workspace = true, features = [ "std", "insecure_zero_ed" ] }
pallet-foreign-asset-creator = { workspace = true, features = [ "std" ] }
pallet-timestamp = { workspace = true }
parity-scale-codec = { workspace = true, features = [ "max-encoded-len" ] }
scale-info = { workspace = true, features = [ "derive" ] }
sp-io = { workspace = true }

# Polkadot
xcm-builder = { workspace = true }
xcm-executor = { workspace = true }

[features]
default = [ "std" ]
std = [
"cumulus-primitives-core/std",
"frame-support/std",
"frame-system/std",
"pallet-evm/std",
"pallet-xcm/std",
"precompile-utils/std",
"sp-core/std",
"sp-std/std",
"xcm/std",
"xcm-builder/std",
"xcm-executor/std",
"xcm-primitives/std",
]
runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
]
96 changes: 96 additions & 0 deletions precompiles/pallet-xcm/XcmInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.3;

/// @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 66edb0e

Please sign in to comment.