1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
use super::moonbeam_weights;
18
use crate::{
19
	xcm_config::XcmExecutorConfig, AccountId, AssetId, Balances, Erc20XcmBridge, EvmForeignAssets,
20
	OpenTechCommitteeInstance, Runtime, TreasuryCouncilInstance,
21
};
22
use frame_support::parameter_types;
23
use moonkit_xcm_primitives::location_matcher::{
24
	Erc20PalletMatcher, ForeignAssetMatcher, SingleAddressMatcher,
25
};
26
use pallet_evm_precompile_author_mapping::AuthorMappingPrecompile;
27
use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata};
28
use pallet_evm_precompile_batch::BatchPrecompile;
29
use pallet_evm_precompile_blake2::Blake2F;
30
use pallet_evm_precompile_bls12381::{
31
	Bls12381G1Add, Bls12381G1MultiExp, Bls12381G2Add, Bls12381G2MultiExp, Bls12381MapG1,
32
	Bls12381MapG2, Bls12381Pairing,
33
};
34
use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing};
35
use pallet_evm_precompile_call_permit::CallPermitPrecompile;
36
use pallet_evm_precompile_collective::CollectivePrecompile;
37
use pallet_evm_precompile_conviction_voting::ConvictionVotingPrecompile;
38
use pallet_evm_precompile_crowdloan_rewards::CrowdloanRewardsPrecompile;
39
use pallet_evm_precompile_gmp::GmpPrecompile;
40
use pallet_evm_precompile_identity::IdentityPrecompile;
41
use pallet_evm_precompile_modexp::Modexp;
42
use pallet_evm_precompile_p256verify::P256Verify;
43
use pallet_evm_precompile_parachain_staking::ParachainStakingPrecompile;
44
use pallet_evm_precompile_preimage::PreimagePrecompile;
45
use pallet_evm_precompile_proxy::{OnlyIsProxyAndProxy, ProxyPrecompile};
46
use pallet_evm_precompile_randomness::RandomnessPrecompile;
47
use pallet_evm_precompile_referenda::ReferendaPrecompile;
48
use pallet_evm_precompile_registry::PrecompileRegistry;
49
use pallet_evm_precompile_relay_encoder::RelayEncoderPrecompile;
50
use pallet_evm_precompile_relay_verifier::RelayDataVerifierPrecompile;
51
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
52
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
53
use pallet_evm_precompile_xcm::PalletXcmPrecompile;
54
use pallet_evm_precompile_xcm_transactor::{
55
	v1::XcmTransactorPrecompileV1, v2::XcmTransactorPrecompileV2, v3::XcmTransactorPrecompileV3,
56
};
57
use pallet_evm_precompile_xcm_utils::XcmUtilsPrecompile;
58
use pallet_evm_precompile_xtokens::XtokensPrecompile;
59
use pallet_precompile_benchmarks::WeightInfo;
60
use precompile_utils::precompile_set::*;
61

            
62
parameter_types! {
63
	pub P256VerifyWeight: frame_support::weights::Weight =
64
		moonbeam_weights::pallet_precompile_benchmarks::WeightInfo::<Runtime>::p256_verify();
65
	pub AssetHubTransactor: crate::xcm_config::Transactors = crate::xcm_config::Transactors::AssetHub;
66
}
67

            
68
pub struct NativeErc20Metadata;
69

            
70
/// ERC20 metadata for the native token.
71
impl Erc20Metadata for NativeErc20Metadata {
72
	/// Returns the name of the token.
73
	fn name() -> &'static str {
74
		"GLMR token"
75
	}
76

            
77
	/// Returns the symbol of the token.
78
	fn symbol() -> &'static str {
79
		"GLMR"
80
	}
81

            
82
	/// Returns the decimals places of the token.
83
	fn decimals() -> u8 {
84
		18
85
	}
86

            
87
	/// Must return `true` only if it represents the main native currency of
88
	/// the network. It must be the currency used in `pallet_evm`.
89
6
	fn is_native_currency() -> bool {
90
6
		true
91
6
	}
92
}
93

            
94
/// The asset precompile address prefix. Addresses that match against this prefix will be routed
95
/// to Erc20AssetsPrecompileSet being marked as foreign
96
pub const FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4];
97
/// The asset precompile address prefix. Addresses that match against this prefix will be routed
98
/// to Erc20AssetsPrecompileSet being marked as local
99
pub const LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8, 255u8, 255u8, 254u8];
100

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

            
104
parameter_types! {
105
	pub ForeignAssetPrefix: &'static [u8] = FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX;
106
	pub LocalAssetPrefix: &'static [u8] = LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX;
107
}
108

            
109
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
110

            
111
// Pallet-xcm precompile types.
112
// Type that converts AssetId into Location
113
type AssetIdToLocationManager = (EvmForeignAssets,);
114

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

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

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

            
124
#[precompile_utils::precompile_name_from_address]
125
type MoonbeamPrecompilesAt<R> = (
126
	// Ethereum precompiles:
127
	// We allow DELEGATECALL to stay compliant with Ethereum behavior.
128
	PrecompileAt<AddressU64<1>, ECRecover, EthereumPrecompilesChecks>,
129
	PrecompileAt<AddressU64<2>, Sha256, EthereumPrecompilesChecks>,
130
	PrecompileAt<AddressU64<3>, Ripemd160, EthereumPrecompilesChecks>,
131
	PrecompileAt<AddressU64<4>, Identity, EthereumPrecompilesChecks>,
132
	PrecompileAt<AddressU64<5>, Modexp, EthereumPrecompilesChecks>,
133
	PrecompileAt<AddressU64<6>, Bn128Add, EthereumPrecompilesChecks>,
134
	PrecompileAt<AddressU64<7>, Bn128Mul, EthereumPrecompilesChecks>,
135
	PrecompileAt<AddressU64<8>, Bn128Pairing, EthereumPrecompilesChecks>,
136
	PrecompileAt<AddressU64<9>, Blake2F, EthereumPrecompilesChecks>,
137
	// 10 is not implemented, Ethereum uses this slot for Point Evaluation
138
	PrecompileAt<AddressU64<11>, Bls12381G1Add, EthereumPrecompilesChecks>,
139
	PrecompileAt<AddressU64<12>, Bls12381G1MultiExp, EthereumPrecompilesChecks>,
140
	PrecompileAt<AddressU64<13>, Bls12381G2Add, EthereumPrecompilesChecks>,
141
	PrecompileAt<AddressU64<14>, Bls12381G2MultiExp, EthereumPrecompilesChecks>,
142
	PrecompileAt<AddressU64<15>, Bls12381Pairing, EthereumPrecompilesChecks>,
143
	PrecompileAt<AddressU64<16>, Bls12381MapG1, EthereumPrecompilesChecks>,
144
	PrecompileAt<AddressU64<17>, Bls12381MapG2, EthereumPrecompilesChecks>,
145
	// (0x100 => 256) https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md
146
	PrecompileAt<AddressU64<256>, P256Verify<P256VerifyWeight>, EthereumPrecompilesChecks>,
147
	// Non-Moonbeam specific nor Ethereum precompiles :
148
	PrecompileAt<
149
		AddressU64<1024>,
150
		Sha3FIPS256<Runtime, ()>,
151
		(CallableByContract, CallableByPrecompile),
152
	>,
153
	RemovedPrecompileAt<AddressU64<1025>>, // Dispatch<R>
154
	PrecompileAt<AddressU64<1026>, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>,
155
	// Moonbeam specific precompiles:
156
	PrecompileAt<
157
		AddressU64<2048>,
158
		ParachainStakingPrecompile<R>,
159
		(CallableByContract, CallableByPrecompile),
160
	>,
161
	PrecompileAt<
162
		AddressU64<2049>,
163
		CrowdloanRewardsPrecompile<R>,
164
		(CallableByContract, CallableByPrecompile),
165
	>,
166
	PrecompileAt<
167
		AddressU64<ERC20_BALANCES_PRECOMPILE>,
168
		Erc20BalancesPrecompile<R, NativeErc20Metadata>,
169
		(CallableByContract, CallableByPrecompile),
170
	>,
171
	RemovedPrecompileAt<AddressU64<2051>>, // Democracy
172
	PrecompileAt<
173
		AddressU64<2052>,
174
		XtokensPrecompile<R>,
175
		(
176
			SubcallWithMaxNesting<1>,
177
			CallableByContract,
178
			CallableByPrecompile,
179
		),
180
	>,
181
	PrecompileAt<
182
		AddressU64<2053>,
183
		RelayEncoderPrecompile<R, AssetHubTransactor>,
184
		(CallableByContract, CallableByPrecompile),
185
	>,
186
	PrecompileAt<
187
		AddressU64<2054>,
188
		XcmTransactorPrecompileV1<R>,
189
		(
190
			SubcallWithMaxNesting<1>,
191
			CallableByContract,
192
			CallableByPrecompile,
193
		),
194
	>,
195
	PrecompileAt<
196
		AddressU64<2055>,
197
		AuthorMappingPrecompile<R>,
198
		(CallableByContract, CallableByPrecompile),
199
	>,
200
	PrecompileAt<
201
		AddressU64<2056>,
202
		BatchPrecompile<R>,
203
		(
204
			SubcallWithMaxNesting<2>,
205
			// Batch is the only precompile allowed to call Batch.
206
			CallableByPrecompile<OnlyFrom<AddressU64<2056>>>,
207
		),
208
	>,
209
	PrecompileAt<
210
		AddressU64<2057>,
211
		RandomnessPrecompile<R>,
212
		(SubcallWithMaxNesting<0>, CallableByContract),
213
	>,
214
	PrecompileAt<
215
		AddressU64<2058>,
216
		CallPermitPrecompile<R>,
217
		(SubcallWithMaxNesting<0>, CallableByContract),
218
	>,
219
	PrecompileAt<
220
		AddressU64<2059>,
221
		ProxyPrecompile<R>,
222
		(
223
			CallableByContract<OnlyIsProxyAndProxy<R>>,
224
			SubcallWithMaxNesting<0>,
225
			// Batch is the only precompile allowed to call Proxy.
226
			CallableByPrecompile<OnlyFrom<AddressU64<2056>>>,
227
		),
228
	>,
229
	PrecompileAt<
230
		AddressU64<2060>,
231
		XcmUtilsPrecompile<R, XcmExecutorConfig>,
232
		CallableByContract<
233
			pallet_evm_precompile_xcm_utils::AllExceptXcmExecute<R, XcmExecutorConfig>,
234
		>,
235
	>,
236
	PrecompileAt<
237
		AddressU64<2061>,
238
		XcmTransactorPrecompileV2<R>,
239
		(
240
			SubcallWithMaxNesting<1>,
241
			CallableByContract,
242
			CallableByPrecompile,
243
		),
244
	>,
245
	RemovedPrecompileAt<AddressU64<2062>>, //CouncilInstance
246
	RemovedPrecompileAt<AddressU64<2063>>, // TechCommitteeInstance
247
	PrecompileAt<
248
		AddressU64<2064>,
249
		CollectivePrecompile<R, TreasuryCouncilInstance>,
250
		(CallableByContract, CallableByPrecompile),
251
	>,
252
	PrecompileAt<
253
		AddressU64<2065>,
254
		ReferendaPrecompile<R, crate::governance::custom_origins::Origin>,
255
		(CallableByContract, CallableByPrecompile),
256
	>,
257
	PrecompileAt<
258
		AddressU64<2066>,
259
		ConvictionVotingPrecompile<R>,
260
		(CallableByContract, CallableByPrecompile),
261
	>,
262
	PrecompileAt<
263
		AddressU64<2067>,
264
		PreimagePrecompile<R>,
265
		(CallableByContract, CallableByPrecompile),
266
	>,
267
	PrecompileAt<
268
		AddressU64<2068>,
269
		CollectivePrecompile<R, OpenTechCommitteeInstance>,
270
		(CallableByContract, CallableByPrecompile),
271
	>,
272
	PrecompileAt<
273
		AddressU64<2069>,
274
		PrecompileRegistry<R>,
275
		(CallableByContract, CallableByPrecompile),
276
	>,
277
	PrecompileAt<AddressU64<2070>, GmpPrecompile<R>, SubcallWithMaxNesting<0>>,
278
	PrecompileAt<
279
		AddressU64<2071>,
280
		XcmTransactorPrecompileV3<R>,
281
		(
282
			SubcallWithMaxNesting<1>,
283
			CallableByContract,
284
			CallableByPrecompile,
285
		),
286
	>,
287
	PrecompileAt<
288
		AddressU64<2072>,
289
		IdentityPrecompile<R, crate::MaxAdditionalFields>,
290
		(CallableByContract, CallableByPrecompile),
291
	>,
292
	PrecompileAt<
293
		AddressU64<2073>,
294
		RelayDataVerifierPrecompile<
295
			R,
296
			moonbeam_weights::pallet_precompile_benchmarks::WeightInfo<Runtime>,
297
		>,
298
		(CallableByContract, CallableByPrecompile),
299
	>,
300
	PrecompileAt<
301
		AddressU64<2074>,
302
		PalletXcmPrecompile<R, (SingleAddressMatch, ForeignAssetMatch, Erc20Match)>,
303
		(
304
			CallableByContract,
305
			CallableByPrecompile,
306
			SubcallWithMaxNesting<1>,
307
		),
308
	>,
309
);
310

            
311
/// The PrecompileSet installed in the Moonbeam runtime.
312
/// We include the nine Istanbul precompiles
313
/// (https://github.com/ethereum/go-ethereum/blob/3c46f557/core/vm/contracts.go#L69)
314
/// as well as a special precompile for dispatching Substrate extrinsics
315
/// The following distribution has been decided for the precompiles
316
/// 0-1023: Ethereum Mainnet Precompiles
317
/// 1024-2047 Precompiles that are not in Ethereum Mainnet but are neither Moonbeam specific
318
/// 2048-4095 Moonbeam specific precompiles
319
pub type MoonbeamPrecompiles<R> = PrecompileSetBuilder<
320
	R,
321
	(
322
		// Skip precompiles if out of range.
323
		PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<4095>), MoonbeamPrecompilesAt<R>>,
324
	),
325
>;