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
//! Precompile to xcm transactor runtime methods via the EVM
18

            
19
use fp_evm::PrecompileHandle;
20
use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo};
21

            
22
use crate::functions::{CurrencyIdOf, GetDataLimit, TransactorOf, XcmTransactorWrapper};
23
use precompile_utils::prelude::*;
24
use sp_core::{H160, U256};
25
use sp_runtime::traits::Dispatchable;
26
use sp_std::{convert::TryFrom, marker::PhantomData};
27
use xcm::latest::Location;
28
use xcm_primitives::AccountIdToCurrencyId;
29

            
30
/// A precompile to wrap the functionality from xcm transactor
31
pub struct XcmTransactorPrecompileV1<Runtime>(PhantomData<Runtime>);
32

            
33
254
#[precompile_utils::precompile]
34
impl<Runtime> XcmTransactorPrecompileV1<Runtime>
35
where
36
	Runtime: pallet_xcm_transactor::Config + pallet_evm::Config + frame_system::Config,
37
	Runtime::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo,
38
	Runtime::RuntimeCall: From<pallet_xcm_transactor::Call<Runtime>>,
39
	<Runtime::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<Runtime::AccountId>>,
40
	TransactorOf<Runtime>: TryFrom<u8>,
41
	Runtime::AccountId: Into<H160>,
42
	Runtime: AccountIdToCurrencyId<Runtime::AccountId, CurrencyIdOf<Runtime>>,
43
{
44
	#[precompile::public("indexToAccount(uint16)")]
45
	#[precompile::public("index_to_account(uint16)")]
46
	#[precompile::view]
47
2
	fn index_to_account(handle: &mut impl PrecompileHandle, index: u16) -> EvmResult<Address> {
48
2
		XcmTransactorWrapper::<Runtime>::account_index(handle, index)
49
2
	}
50

            
51
	#[precompile::public("transactInfo((uint8,bytes[]))")]
52
	#[precompile::public("transact_info((uint8,bytes[]))")]
53
	#[precompile::view]
54
2
	fn transact_info(
55
2
		handle: &mut impl PrecompileHandle,
56
2
		location: Location,
57
2
	) -> EvmResult<(u64, U256, u64)> {
58
2
		XcmTransactorWrapper::<Runtime>::transact_info(handle, location)
59
2
	}
60

            
61
	#[precompile::public("transactInfoWithSigned((uint8,bytes[]))")]
62
	#[precompile::public("transact_info_with_signed((uint8,bytes[]))")]
63
	#[precompile::view]
64
2
	fn transact_info_with_signed(
65
2
		handle: &mut impl PrecompileHandle,
66
2
		location: Location,
67
2
	) -> EvmResult<(u64, u64, u64)> {
68
2
		XcmTransactorWrapper::<Runtime>::transact_info_with_signed(handle, location)
69
2
	}
70

            
71
	#[precompile::public("feePerSecond((uint8,bytes[]))")]
72
	#[precompile::public("fee_per_second((uint8,bytes[]))")]
73
	#[precompile::view]
74
2
	fn fee_per_second(handle: &mut impl PrecompileHandle, location: Location) -> EvmResult<U256> {
75
2
		XcmTransactorWrapper::<Runtime>::fee_per_second(handle, location)
76
2
	}
77

            
78
	#[precompile::public(
79
		"transactThroughDerivativeMultilocation(\
80
		uint8,\
81
		uint16,\
82
		(uint8,bytes[]),\
83
		uint64,\
84
		bytes)"
85
	)]
86
	#[precompile::public(
87
		"transact_through_derivative_multilocation(\
88
		uint8,\
89
		uint16,\
90
		(uint8,bytes[]),\
91
		uint64,\
92
		bytes)"
93
	)]
94
1
	fn transact_through_derivative_multilocation(
95
1
		handle: &mut impl PrecompileHandle,
96
1
		transactor: u8,
97
1
		index: u16,
98
1
		fee_asset: Location,
99
1
		weight: u64,
100
1
		inner_call: BoundedBytes<GetDataLimit>,
101
1
	) -> EvmResult {
102
1
		XcmTransactorWrapper::<Runtime>::transact_through_derivative_multilocation(
103
1
			handle, transactor, index, fee_asset, weight, inner_call,
104
1
		)
105
1
	}
106

            
107
	#[precompile::public("transactThroughDerivative(uint8,uint16,address,uint64,bytes)")]
108
	#[precompile::public("transact_through_derivative(uint8,uint16,address,uint64,bytes)")]
109
1
	fn transact_through_derivative(
110
1
		handle: &mut impl PrecompileHandle,
111
1
		transactor: u8,
112
1
		index: u16,
113
1
		currency_id: Address,
114
1
		weight: u64,
115
1
		inner_call: BoundedBytes<GetDataLimit>,
116
1
	) -> EvmResult {
117
1
		XcmTransactorWrapper::<Runtime>::transact_through_derivative(
118
1
			handle,
119
1
			transactor,
120
1
			index,
121
1
			currency_id,
122
1
			weight,
123
1
			inner_call,
124
1
		)
125
1
	}
126

            
127
	#[precompile::public(
128
		"transactThroughSignedMultilocation(\
129
		(uint8,bytes[]),\
130
		(uint8,bytes[]),\
131
		uint64,\
132
		bytes)"
133
	)]
134
	#[precompile::public(
135
		"transact_through_signed_multilocation(\
136
		(uint8,bytes[]),\
137
		(uint8,bytes[]),\
138
		uint64,\
139
		bytes)"
140
	)]
141
2
	fn transact_through_signed_multilocation(
142
2
		handle: &mut impl PrecompileHandle,
143
2
		dest: Location,
144
2
		fee_asset: Location,
145
2
		weight: u64,
146
2
		call: BoundedBytes<GetDataLimit>,
147
2
	) -> EvmResult {
148
2
		XcmTransactorWrapper::<Runtime>::transact_through_signed_multilocation(
149
2
			handle, dest, fee_asset, weight, call,
150
2
		)
151
2
	}
152

            
153
	#[precompile::public("transactThroughSigned((uint8,bytes[]),address,uint64,bytes)")]
154
	#[precompile::public("transact_through_signed((uint8,bytes[]),address,uint64,bytes)")]
155
1
	fn transact_through_signed(
156
1
		handle: &mut impl PrecompileHandle,
157
1
		dest: Location,
158
1
		fee_asset: Address,
159
1
		weight: u64,
160
1
		call: BoundedBytes<GetDataLimit>,
161
1
	) -> EvmResult {
162
1
		XcmTransactorWrapper::<Runtime>::transact_through_signed(
163
1
			handle, dest, fee_asset, weight, call,
164
1
		)
165
1
	}
166

            
167
	#[precompile::public("encodeUtilityAsDerivative(uint8,uint16,bytes)")]
168
	#[precompile::public("encode_utility_as_derivative(uint8,uint16,bytes)")]
169
	#[precompile::view]
170
	fn encode_utility_as_derivative(
171
		handle: &mut impl PrecompileHandle,
172
		transactor: u8,
173
		index: u16,
174
		inner_call: BoundedBytes<GetDataLimit>,
175
	) -> EvmResult<UnboundedBytes> {
176
		XcmTransactorWrapper::<Runtime>::encode_utility_as_derivative(
177
			handle, transactor, index, inner_call,
178
		)
179
	}
180
}