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::moonriver_weights;
18
use crate::{
19
	asset_config::ForeignAssetInstance,
20
	xcm_config::{AssetType, XcmExecutorConfig},
21
	AccountId, AssetId, AssetManager, Balances, Erc20XcmBridge, EvmForeignAssets,
22
	OpenTechCommitteeInstance, Runtime, TreasuryCouncilInstance,
23
};
24
use frame_support::parameter_types;
25
use moonkit_xcm_primitives::location_matcher::{
26
	Erc20PalletMatcher, ForeignAssetMatcher, SingleAddressMatcher,
27
};
28
use pallet_evm_precompile_author_mapping::AuthorMappingPrecompile;
29
use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata};
30
use pallet_evm_precompile_batch::BatchPrecompile;
31
use pallet_evm_precompile_blake2::Blake2F;
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::XcmUtilsPrecompile;
56
use pallet_evm_precompile_xtokens::XtokensPrecompile;
57
use pallet_evm_precompileset_assets_erc20::Erc20AssetsPrecompileSet;
58
use pallet_precompile_benchmarks::WeightInfo;
59
use precompile_utils::precompile_set::*;
60
use xcm_primitives::AsAssetType;
61

            
62
parameter_types! {
63
	pub P256VerifyWeight: frame_support::weights::Weight =
64
		moonriver_weights::pallet_precompile_benchmarks::WeightInfo::<Runtime>::p256_verify();
65
}
66

            
67
pub struct NativeErc20Metadata;
68

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

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

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

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

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

            
97
/// Const to identify ERC20_BALANCES_PRECOMPILE address
98
pub const ERC20_BALANCES_PRECOMPILE: u64 = 2050;
99

            
100
parameter_types! {
101
	pub ForeignAssetPrefix: &'static [u8] = FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX;
102
}
103

            
104
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
105

            
106
// Pallet-xcm precompile types.
107
// Type that converts AssetId into Location
108
type AssetIdToLocationManager = (
109
	AsAssetType<AssetId, AssetType, AssetManager>,
110
	EvmForeignAssets,
111
);
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 MoonriverPrecompilesAt<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
	// (0x100 => 256) https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md
136
	PrecompileAt<AddressU64<256>, P256Verify<P256VerifyWeight>, EthereumPrecompilesChecks>,
137
	// Non-Moonbeam specific nor Ethereum precompiles :
138
	PrecompileAt<AddressU64<1024>, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>,
139
	RemovedPrecompileAt<AddressU64<1025>>, // Dispatch<R>
140
	PrecompileAt<AddressU64<1026>, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>,
141
	// Moonbeam specific precompiles:
142
	PrecompileAt<
143
		AddressU64<2048>,
144
		ParachainStakingPrecompile<R>,
145
		(CallableByContract, CallableByPrecompile),
146
	>,
147
	PrecompileAt<
148
		AddressU64<2049>,
149
		CrowdloanRewardsPrecompile<R>,
150
		(CallableByContract, CallableByPrecompile),
151
	>,
152
	PrecompileAt<
153
		AddressU64<ERC20_BALANCES_PRECOMPILE>,
154
		Erc20BalancesPrecompile<R, NativeErc20Metadata>,
155
		(CallableByContract, CallableByPrecompile),
156
	>,
157
	RemovedPrecompileAt<AddressU64<2051>>, // DemocracyPrecompile
158
	PrecompileAt<
159
		AddressU64<2052>,
160
		XtokensPrecompile<R>,
161
		(
162
			SubcallWithMaxNesting<1>,
163
			CallableByContract,
164
			CallableByPrecompile,
165
		),
166
	>,
167
	PrecompileAt<
168
		AddressU64<2053>,
169
		RelayEncoderPrecompile<R>,
170
		(CallableByContract, CallableByPrecompile),
171
	>,
172
	PrecompileAt<
173
		AddressU64<2054>,
174
		XcmTransactorPrecompileV1<R>,
175
		(CallableByContract, CallableByPrecompile),
176
	>,
177
	PrecompileAt<
178
		AddressU64<2055>,
179
		AuthorMappingPrecompile<R>,
180
		(CallableByContract, CallableByPrecompile),
181
	>,
182
	PrecompileAt<
183
		AddressU64<2056>,
184
		BatchPrecompile<R>,
185
		(
186
			SubcallWithMaxNesting<2>,
187
			// Batch is the only precompile allowed to call Batch.
188
			CallableByPrecompile<OnlyFrom<AddressU64<2056>>>,
189
		),
190
	>,
191
	PrecompileAt<
192
		AddressU64<2057>,
193
		RandomnessPrecompile<R>,
194
		(SubcallWithMaxNesting<0>, CallableByContract),
195
	>,
196
	PrecompileAt<
197
		AddressU64<2058>,
198
		CallPermitPrecompile<R>,
199
		(SubcallWithMaxNesting<0>, CallableByContract),
200
	>,
201
	PrecompileAt<
202
		AddressU64<2059>,
203
		ProxyPrecompile<R>,
204
		(
205
			CallableByContract<OnlyIsProxyAndProxy<R>>,
206
			SubcallWithMaxNesting<0>,
207
			// Batch is the only precompile allowed to call Proxy.
208
			CallableByPrecompile<OnlyFrom<AddressU64<2056>>>,
209
		),
210
	>,
211
	PrecompileAt<
212
		AddressU64<2060>,
213
		XcmUtilsPrecompile<R, XcmExecutorConfig>,
214
		CallableByContract<
215
			pallet_evm_precompile_xcm_utils::AllExceptXcmExecute<R, XcmExecutorConfig>,
216
		>,
217
	>,
218
	PrecompileAt<
219
		AddressU64<2061>,
220
		XcmTransactorPrecompileV2<R>,
221
		(CallableByContract, CallableByPrecompile),
222
	>,
223
	RemovedPrecompileAt<AddressU64<2062>>, //CouncilInstance
224
	RemovedPrecompileAt<AddressU64<2063>>, // TechCommitteeInstance
225
	PrecompileAt<
226
		AddressU64<2064>,
227
		CollectivePrecompile<R, TreasuryCouncilInstance>,
228
		(CallableByContract, CallableByPrecompile),
229
	>,
230
	PrecompileAt<
231
		AddressU64<2065>,
232
		ReferendaPrecompile<R, crate::governance::custom_origins::Origin>,
233
		(CallableByContract, CallableByPrecompile),
234
	>,
235
	PrecompileAt<
236
		AddressU64<2066>,
237
		ConvictionVotingPrecompile<R>,
238
		(CallableByContract, CallableByPrecompile),
239
	>,
240
	PrecompileAt<
241
		AddressU64<2067>,
242
		PreimagePrecompile<R>,
243
		(CallableByContract, CallableByPrecompile),
244
	>,
245
	PrecompileAt<
246
		AddressU64<2068>,
247
		CollectivePrecompile<R, OpenTechCommitteeInstance>,
248
		(CallableByContract, CallableByPrecompile),
249
	>,
250
	PrecompileAt<
251
		AddressU64<2069>,
252
		PrecompileRegistry<R>,
253
		(CallableByContract, CallableByPrecompile),
254
	>,
255
	PrecompileAt<AddressU64<2070>, GmpPrecompile<R>, SubcallWithMaxNesting<0>>,
256
	PrecompileAt<
257
		AddressU64<2071>,
258
		XcmTransactorPrecompileV3<R>,
259
		(CallableByContract, CallableByPrecompile),
260
	>,
261
	PrecompileAt<
262
		AddressU64<2072>,
263
		IdentityPrecompile<R, crate::MaxAdditionalFields>,
264
		(CallableByContract, CallableByPrecompile),
265
	>,
266
	PrecompileAt<
267
		AddressU64<2073>,
268
		RelayDataVerifierPrecompile<
269
			R,
270
			moonriver_weights::pallet_precompile_benchmarks::WeightInfo<Runtime>,
271
		>,
272
		(CallableByContract, CallableByPrecompile),
273
	>,
274
	PrecompileAt<
275
		AddressU64<2074>,
276
		PalletXcmPrecompile<R, (SingleAddressMatch, ForeignAssetMatch, Erc20Match)>,
277
		(
278
			CallableByContract,
279
			CallableByPrecompile,
280
			SubcallWithMaxNesting<1>,
281
		),
282
	>,
283
);
284

            
285
/// The PrecompileSet installed in the Moonriver runtime.
286
/// We include the nine Istanbul precompiles
287
/// (https://github.com/ethereum/go-ethereum/blob/3c46f557/core/vm/contracts.go#L69)
288
/// The following distribution has been decided for the precompiles
289
/// 0-1023: Ethereum Mainnet Precompiles
290
/// 1024-2047 Precompiles that are not in Ethereum Mainnet but are neither Moonbeam specific
291
/// 2048-4095 Moonbeam specific precompiles
292
pub type MoonriverPrecompiles<R> = PrecompileSetBuilder<
293
	R,
294
	(
295
		// Skip precompiles if out of range.
296
		PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<4095>), MoonriverPrecompilesAt<R>>,
297
		// Prefixed precompile sets (XC20)
298
		PrecompileSetStartingWith<
299
			ForeignAssetPrefix,
300
			Erc20AssetsPrecompileSet<R, ForeignAssetInstance>,
301
			CallableByContract,
302
		>,
303
		// Moonriver never had any local assets (No blacklist needed
304
		// https://moonriver.subscan.io/event?module=localassets&event_id=created
305
		// https://moonriver.subscan.io/event?module=localassets&event_id=forcecreated
306
	),
307
>;