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

            
64
parameter_types! {
65
	pub P256VerifyWeight: frame_support::weights::Weight =
66
		moonbeam_weights::pallet_precompile_benchmarks::WeightInfo::<Runtime>::p256_verify();
67
}
68

            
69
pub struct NativeErc20Metadata;
70

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

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

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

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

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

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

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

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

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

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

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

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

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

            
281
pub struct DisabledLocalAssets<Runtime>(sp_std::marker::PhantomData<Runtime>);
282

            
283
impl<Runtime> sp_core::Get<Vec<H160>> for DisabledLocalAssets<Runtime>
284
where
285
	Runtime: frame_system::Config,
286
	Runtime::AccountId: Into<H160>,
287
	Runtime: AccountIdAssetIdConversion<Runtime::AccountId, AssetId>,
288
{
289
12096
	fn get() -> Vec<H160> {
290
12096
		vec![
291
12096
			337110116006454532607322340792629567158u128,
292
12096
			278750993613512357835566279094880339619,
293
12096
			228256396637196286254896220398224702687,
294
12096
			270195117769614861929703564202131636628,
295
12096
		]
296
12096
		.iter()
297
48384
		.map(|id| Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, *id).into())
298
12096
		.collect()
299
12096
	}
300
}
301

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