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

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

            
66
/// ERC20 metadata for the native token.
67
pub struct NativeErc20Metadata;
68

            
69
impl Erc20Metadata for NativeErc20Metadata {
70
	/// Returns the name of the token.
71
	fn name() -> &'static str {
72
		"DEV token"
73
	}
74

            
75
	/// Returns the symbol of the token.
76
	fn symbol() -> &'static str {
77
		"DEV"
78
	}
79

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

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

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

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

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

            
107
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
108

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

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

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

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

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

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