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::moonbase_weights;
18
use crate::{
19
	asset_config::ForeignAssetInstance,
20
	xcm_config::{AssetType, XcmExecutorConfig},
21
	OpenTechCommitteeInstance, TreasuryCouncilInstance,
22
};
23
use crate::{
24
	AccountId, AssetId, AssetManager, Balances, Erc20XcmBridge, EvmForeignAssets, Runtime, H160,
25
};
26
use frame_support::parameter_types;
27
use moonkit_xcm_primitives::{
28
	location_matcher::{Erc20PalletMatcher, ForeignAssetMatcher, SingleAddressMatcher},
29
	AccountIdAssetIdConversion,
30
};
31
use pallet_evm_precompile_author_mapping::AuthorMappingPrecompile;
32
use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata};
33
use pallet_evm_precompile_batch::BatchPrecompile;
34
use pallet_evm_precompile_blake2::Blake2F;
35
use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing};
36
use pallet_evm_precompile_call_permit::CallPermitPrecompile;
37
use pallet_evm_precompile_collective::CollectivePrecompile;
38
use pallet_evm_precompile_conviction_voting::ConvictionVotingPrecompile;
39
use pallet_evm_precompile_crowdloan_rewards::CrowdloanRewardsPrecompile;
40
use pallet_evm_precompile_gmp::GmpPrecompile;
41
use pallet_evm_precompile_identity::IdentityPrecompile;
42
use pallet_evm_precompile_modexp::Modexp;
43
use pallet_evm_precompile_p256verify::P256Verify;
44
use pallet_evm_precompile_parachain_staking::ParachainStakingPrecompile;
45
use pallet_evm_precompile_preimage::PreimagePrecompile;
46
use pallet_evm_precompile_proxy::{OnlyIsProxyAndProxy, ProxyPrecompile};
47
use pallet_evm_precompile_randomness::RandomnessPrecompile;
48
use pallet_evm_precompile_referenda::ReferendaPrecompile;
49
use pallet_evm_precompile_registry::PrecompileRegistry;
50
use pallet_evm_precompile_relay_encoder::RelayEncoderPrecompile;
51
use pallet_evm_precompile_relay_verifier::RelayDataVerifierPrecompile;
52
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
53
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
54
use pallet_evm_precompile_storage_cleaner::StorageCleanerPrecompile;
55
use pallet_evm_precompile_xcm::PalletXcmPrecompile;
56
use pallet_evm_precompile_xcm_transactor::{
57
	v1::XcmTransactorPrecompileV1, v2::XcmTransactorPrecompileV2, v3::XcmTransactorPrecompileV3,
58
};
59
use pallet_evm_precompile_xcm_utils::{AllExceptXcmExecute, XcmUtilsPrecompile};
60
use pallet_evm_precompile_xtokens::XtokensPrecompile;
61
use pallet_evm_precompileset_assets_erc20::Erc20AssetsPrecompileSet;
62
use pallet_precompile_benchmarks::WeightInfo;
63
use precompile_foreign_asset_migrator::ForeignAssetMigratorPrecompile;
64
use precompile_utils::precompile_set::*;
65
use sp_std::prelude::*;
66
use xcm_primitives::AsAssetType;
67

            
68
parameter_types! {
69
	pub P256VerifyWeight: frame_support::weights::Weight =
70
		moonbase_weights::pallet_precompile_benchmarks::WeightInfo::<Runtime>::p256_verify();
71
}
72

            
73
/// ERC20 metadata for the native token.
74
pub struct NativeErc20Metadata;
75

            
76
impl Erc20Metadata for NativeErc20Metadata {
77
	/// Returns the name of the token.
78
	fn name() -> &'static str {
79
		"DEV token"
80
	}
81

            
82
	/// Returns the symbol of the token.
83
	fn symbol() -> &'static str {
84
		"DEV"
85
	}
86

            
87
	/// Returns the decimals places of the token.
88
	fn decimals() -> u8 {
89
		18
90
	}
91

            
92
	/// Must return `true` only if it represents the main native currency of
93
	/// the network. It must be the currency used in `pallet_evm`.
94
8
	fn is_native_currency() -> bool {
95
8
		true
96
8
	}
97
}
98

            
99
/// The asset precompile address prefix. Addresses that match against this prefix will be routed
100
/// to Erc20AssetsPrecompileSet being marked as foreign
101
pub const FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4];
102
/// The asset precompile address prefix. Addresses that match against this prefix will be routed
103
/// to Erc20AssetsPrecompileSet being marked as local
104
pub const LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8, 255u8, 255u8, 254u8];
105

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

            
109
parameter_types! {
110
	pub ForeignAssetPrefix: &'static [u8] = FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX;
111
	pub LocalAssetPrefix: &'static [u8] = LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX;
112
}
113

            
114
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
115

            
116
// Pallet-xcm precompile types.
117
// Type that converts AssetId into Location
118
type AssetIdToLocationManager = (
119
	AsAssetType<AssetId, AssetType, AssetManager>,
120
	EvmForeignAssets,
121
);
122

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

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

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

            
132
#[precompile_utils::precompile_name_from_address]
133
type MoonbasePrecompilesAt<R> = (
134
	// Ethereum precompiles:
135
	// We allow DELEGATECALL to stay compliant with Ethereum behavior.
136
	PrecompileAt<AddressU64<1>, ECRecover, EthereumPrecompilesChecks>,
137
	PrecompileAt<AddressU64<2>, Sha256, EthereumPrecompilesChecks>,
138
	PrecompileAt<AddressU64<3>, Ripemd160, EthereumPrecompilesChecks>,
139
	PrecompileAt<AddressU64<4>, Identity, EthereumPrecompilesChecks>,
140
	PrecompileAt<AddressU64<5>, Modexp, EthereumPrecompilesChecks>,
141
	PrecompileAt<AddressU64<6>, Bn128Add, EthereumPrecompilesChecks>,
142
	PrecompileAt<AddressU64<7>, Bn128Mul, EthereumPrecompilesChecks>,
143
	PrecompileAt<AddressU64<8>, Bn128Pairing, EthereumPrecompilesChecks>,
144
	PrecompileAt<AddressU64<9>, Blake2F, 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<AddressU64<1024>, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>,
149
	RemovedPrecompileAt<AddressU64<1025>>, // Dispatch<R>
150
	PrecompileAt<AddressU64<1026>, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>,
151
	PrecompileAt<AddressU64<1027>, StorageCleanerPrecompile<R>, CallableByPrecompile>,
152
	// Moonbeam specific precompiles:
153
	PrecompileAt<
154
		AddressU64<2048>,
155
		ParachainStakingPrecompile<R>,
156
		(CallableByContract, CallableByPrecompile),
157
	>,
158
	PrecompileAt<
159
		AddressU64<2049>,
160
		CrowdloanRewardsPrecompile<R>,
161
		(CallableByContract, CallableByPrecompile),
162
	>,
163
	PrecompileAt<
164
		AddressU64<ERC20_BALANCES_PRECOMPILE>,
165
		Erc20BalancesPrecompile<R, NativeErc20Metadata>,
166
		(CallableByContract, CallableByPrecompile),
167
	>,
168
	RemovedPrecompileAt<AddressU64<2051>>, // DemocracyPrecompile
169
	PrecompileAt<
170
		AddressU64<2052>,
171
		XtokensPrecompile<R>,
172
		(
173
			SubcallWithMaxNesting<1>,
174
			CallableByContract,
175
			CallableByPrecompile,
176
		),
177
	>,
178
	PrecompileAt<
179
		AddressU64<2053>,
180
		RelayEncoderPrecompile<R>,
181
		(CallableByContract, CallableByPrecompile),
182
	>,
183
	PrecompileAt<
184
		AddressU64<2054>,
185
		XcmTransactorPrecompileV1<R>,
186
		(CallableByContract, CallableByPrecompile),
187
	>,
188
	PrecompileAt<
189
		AddressU64<2055>,
190
		AuthorMappingPrecompile<R>,
191
		(CallableByContract, CallableByPrecompile),
192
	>,
193
	PrecompileAt<
194
		AddressU64<2056>,
195
		BatchPrecompile<R>,
196
		(
197
			SubcallWithMaxNesting<2>,
198
			// Batch is the only precompile allowed to call Batch.
199
			CallableByPrecompile<OnlyFrom<AddressU64<2056>>>,
200
		),
201
	>,
202
	PrecompileAt<
203
		AddressU64<2057>,
204
		RandomnessPrecompile<R>,
205
		(SubcallWithMaxNesting<0>, CallableByContract),
206
	>,
207
	PrecompileAt<
208
		AddressU64<2058>,
209
		CallPermitPrecompile<R>,
210
		(SubcallWithMaxNesting<0>, CallableByContract),
211
	>,
212
	PrecompileAt<
213
		AddressU64<2059>,
214
		ProxyPrecompile<R>,
215
		(
216
			CallableByContract<OnlyIsProxyAndProxy<R>>,
217
			SubcallWithMaxNesting<0>,
218
			// Batch is the only precompile allowed to call Proxy.
219
			CallableByPrecompile<OnlyFrom<AddressU64<2056>>>,
220
		),
221
	>,
222
	PrecompileAt<
223
		AddressU64<2060>,
224
		XcmUtilsPrecompile<R, XcmExecutorConfig>,
225
		CallableByContract<AllExceptXcmExecute<R, XcmExecutorConfig>>,
226
	>,
227
	PrecompileAt<
228
		AddressU64<2061>,
229
		XcmTransactorPrecompileV2<R>,
230
		(CallableByContract, CallableByPrecompile),
231
	>,
232
	// CouncilCollective precompile
233
	RemovedPrecompileAt<AddressU64<2062>>,
234
	// TechCommitteeCollective precompile
235
	RemovedPrecompileAt<AddressU64<2063>>,
236
	PrecompileAt<
237
		AddressU64<2064>,
238
		CollectivePrecompile<R, TreasuryCouncilInstance>,
239
		(CallableByContract, CallableByPrecompile),
240
	>,
241
	PrecompileAt<
242
		AddressU64<2065>,
243
		ReferendaPrecompile<R, crate::governance::custom_origins::Origin>,
244
		(CallableByContract, CallableByPrecompile),
245
	>,
246
	PrecompileAt<
247
		AddressU64<2066>,
248
		ConvictionVotingPrecompile<R>,
249
		(CallableByContract, CallableByPrecompile),
250
	>,
251
	PrecompileAt<
252
		AddressU64<2067>,
253
		PreimagePrecompile<R>,
254
		(CallableByContract, CallableByPrecompile),
255
	>,
256
	PrecompileAt<
257
		AddressU64<2068>,
258
		CollectivePrecompile<R, OpenTechCommitteeInstance>,
259
		(CallableByContract, CallableByPrecompile),
260
	>,
261
	PrecompileAt<
262
		AddressU64<2069>,
263
		PrecompileRegistry<R>,
264
		(CallableByContract, CallableByPrecompile),
265
	>,
266
	PrecompileAt<AddressU64<2070>, GmpPrecompile<R>, SubcallWithMaxNesting<0>>,
267
	PrecompileAt<
268
		AddressU64<2071>,
269
		XcmTransactorPrecompileV3<R>,
270
		(CallableByContract, CallableByPrecompile),
271
	>,
272
	PrecompileAt<
273
		AddressU64<2072>,
274
		IdentityPrecompile<R, crate::MaxAdditionalFields>,
275
		(CallableByContract, CallableByPrecompile),
276
	>,
277
	PrecompileAt<
278
		AddressU64<2073>,
279
		RelayDataVerifierPrecompile<
280
			R,
281
			moonbase_weights::pallet_precompile_benchmarks::WeightInfo<Runtime>,
282
		>,
283
		(CallableByContract, CallableByPrecompile),
284
	>,
285
	PrecompileAt<
286
		AddressU64<2074>,
287
		PalletXcmPrecompile<R, (SingleAddressMatch, ForeignAssetMatch, Erc20Match)>,
288
		(
289
			CallableByContract,
290
			CallableByPrecompile,
291
			SubcallWithMaxNesting<1>,
292
		),
293
	>,
294
	PrecompileAt<AddressU64<2075>, ForeignAssetMigratorPrecompile<R>, ()>,
295
);
296

            
297
pub struct DisabledLocalAssets<Runtime>(sp_std::marker::PhantomData<Runtime>);
298

            
299
impl<Runtime> sp_core::Get<Vec<H160>> for DisabledLocalAssets<Runtime>
300
where
301
	Runtime: frame_system::Config,
302
	Runtime::AccountId: Into<H160>,
303
	Runtime: AccountIdAssetIdConversion<Runtime::AccountId, AssetId>,
304
{
305
12546
	fn get() -> Vec<H160> {
306
12546
		vec![
307
12546
			// https://moonbase.subscan.io/extrinsic/5245322-6?event=5245322-22
308
12546
			182085191673801920759598290391359780050u128,
309
12546
			// https://moonbase.subscan.io/extrinsic/3244752-4?event=3244752-9
310
12546
			282223684955665977914983262584256755878u128,
311
12546
			// https://moonbase.subscan.io/extrinsic/3158280-4?event=3158280-9
312
12546
			235962050501460763853961856666389569138u128,
313
12546
			// https://moonbase.subscan.io/block/3045900?tab=event&&event=3045900-4
314
12546
			45350527686064227409532032051821627910u128,
315
12546
			// https://moonbase.subscan.io/extrinsic/3024306-4?event=3024306-9
316
12546
			199439015574556113723291251263369885338u128,
317
12546
			// https://moonbase.subscan.io/extrinsic/2921640-4?event=2921640-9
318
12546
			236426850287284823323011839750645103615u128,
319
12546
			// https://moonbase.subscan.io/extrinsic/2748867-4?event=2748867-9
320
12546
			14626673838203901761839010613793775004u128,
321
12546
			// https://moonbase.subscan.io/extrinsic/2709788-4?event=2709788-9
322
12546
			95328064580428769161981851380106820590u128,
323
12546
			// https://moonbase.subscan.io/extrinsic/2670844-4?event=2670844-9
324
12546
			339028723712074529056817184013808486301u128,
325
12546
			// https://moonbase.subscan.io/extrinsic/2555083-4?event=2555083-9
326
12546
			100481493116602214283160747599845770751u128,
327
12546
			// https://moonbase.subscan.io/extrinsic/2473880-3?event=2473880-8
328
12546
			319515966007349957795820176952936446433u128,
329
12546
			// https://moonbase.subscan.io/extrinsic/2346438-3?event=2346438-6
330
12546
			337110116006454532607322340792629567158u128,
331
12546
			// https://moonbase.subscan.io/extrinsic/2239102-3?event=2239102-6
332
12546
			255225902946708983196362678630947296516u128,
333
12546
			// https://moonbase.subscan.io/extrinsic/2142964-4?event=2142964-12
334
12546
			3356866138193769031598374869367363824u128,
335
12546
			// https://moonbase.subscan.io/extrinsic/1967538-6?event=1967538-28
336
12546
			144992676743556815849525085098140609495u128,
337
12546
		]
338
12546
		.iter()
339
188190
		.map(|id| Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, *id).into())
340
12546
		.collect()
341
12546
	}
342
}
343

            
344
/// The PrecompileSet installed in the Moonbase runtime.
345
/// We include the nine Istanbul precompiles
346
/// (https://github.com/ethereum/go-ethereum/blob/3c46f557/core/vm/contracts.go#L69)
347
/// The following distribution has been decided for the precompiles
348
/// 0-1023: Ethereum Mainnet Precompiles
349
/// 1024-2047 Precompiles that are not in Ethereum Mainnet but are neither Moonbeam specific
350
/// 2048-4095 Moonbeam specific precompiles
351
pub type MoonbasePrecompiles<R> = PrecompileSetBuilder<
352
	R,
353
	(
354
		// Skip precompiles if out of range.
355
		PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<4095>), MoonbasePrecompilesAt<R>>,
356
		// Prefixed precompile sets (XC20)
357
		PrecompileSetStartingWith<
358
			ForeignAssetPrefix,
359
			Erc20AssetsPrecompileSet<R, ForeignAssetInstance>,
360
			(CallableByContract, CallableByPrecompile),
361
		>,
362
		RemovedPrecompilesAt<DisabledLocalAssets<R>>,
363
	),
364
>;