26
26
//
27
27
28
28
use crate :: precompiles:: {
29
- contract_to_origin, get_method_id, get_pubkey, get_slice, parse_netuid,
30
- try_dispatch_runtime_call,
29
+ get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call,
31
30
} ;
32
31
use crate :: { ProxyType , Runtime , RuntimeCall } ;
32
+ use frame_system:: RawOrigin ;
33
33
use pallet_evm:: {
34
- BalanceConverter , ExitError , ExitSucceed , PrecompileFailure , PrecompileHandle ,
35
- PrecompileOutput , PrecompileResult ,
34
+ AddressMapping , BalanceConverter , ExitError , ExitSucceed , HashedAddressMapping ,
35
+ PrecompileFailure , PrecompileHandle , PrecompileOutput , PrecompileResult ,
36
36
} ;
37
37
use sp_core:: U256 ;
38
- use sp_runtime:: traits:: { StaticLookup , UniqueSaturatedInto } ;
38
+ use sp_runtime:: traits:: { BlakeTwo256 , Dispatchable , StaticLookup , UniqueSaturatedInto } ;
39
+ use sp_runtime:: AccountId32 ;
39
40
use sp_std:: vec;
40
41
41
42
pub const STAKING_PRECOMPILE_INDEX : u64 = 2049 ;
@@ -75,27 +76,37 @@ impl StakingPrecompile {
75
76
}
76
77
77
78
fn add_stake ( handle : & mut impl PrecompileHandle , data : & [ u8 ] ) -> PrecompileResult {
79
+ let account_id =
80
+ <HashedAddressMapping < BlakeTwo256 > as AddressMapping < AccountId32 > >:: into_account_id (
81
+ handle. context ( ) . caller ,
82
+ ) ;
83
+
78
84
let ( hotkey, _) = get_pubkey ( data) ?;
79
85
let amount: U256 = handle. context ( ) . apparent_value ;
80
86
let netuid = Self :: parse_netuid ( data, 0x3E ) ?;
81
87
88
+ if !amount. is_zero ( ) {
89
+ Self :: transfer_back_to_caller ( & account_id, amount) ?;
90
+ }
91
+
82
92
let amount_sub =
83
93
<Runtime as pallet_evm:: Config >:: BalanceConverter :: into_substrate_balance ( amount)
84
94
. ok_or ( ExitError :: OutOfFund ) ?;
85
95
86
- // let (account_id_src, _) = get_pubkey(&CONTRACT_ADDRESS_SS58)?;
87
- // Create the add_stake call
88
96
let call = RuntimeCall :: SubtensorModule ( pallet_subtensor:: Call :: < Runtime > :: add_stake {
89
97
hotkey,
90
98
netuid,
91
99
amount_staked : amount_sub. unique_saturated_into ( ) ,
92
100
} ) ;
93
- // let origin = RawOrigin::Signed(account_id_src);
94
- // Dispatch the add_stake call
95
- try_dispatch_runtime_call ( handle, call, contract_to_origin ( & CONTRACT_ADDRESS_SS58 ) ?)
101
+
102
+ try_dispatch_runtime_call ( handle, call, RawOrigin :: Signed ( account_id) )
96
103
}
97
104
98
105
fn remove_stake ( handle : & mut impl PrecompileHandle , data : & [ u8 ] ) -> PrecompileResult {
106
+ let account_id =
107
+ <HashedAddressMapping < BlakeTwo256 > as AddressMapping < AccountId32 > >:: into_account_id (
108
+ handle. context ( ) . caller ,
109
+ ) ;
99
110
let ( hotkey, _) = get_pubkey ( data) ?;
100
111
let netuid = Self :: parse_netuid ( data, 0x5E ) ?;
101
112
@@ -115,10 +126,14 @@ impl StakingPrecompile {
115
126
netuid,
116
127
amount_unstaked : amount_sub. unique_saturated_into ( ) ,
117
128
} ) ;
118
- try_dispatch_runtime_call ( handle, call, contract_to_origin ( & CONTRACT_ADDRESS_SS58 ) ? )
129
+ try_dispatch_runtime_call ( handle, call, RawOrigin :: Signed ( account_id ) )
119
130
}
120
131
121
132
fn add_proxy ( handle : & mut impl PrecompileHandle , data : & [ u8 ] ) -> PrecompileResult {
133
+ let account_id =
134
+ <HashedAddressMapping < BlakeTwo256 > as AddressMapping < AccountId32 > >:: into_account_id (
135
+ handle. context ( ) . caller ,
136
+ ) ;
122
137
let ( delegate, _) = get_pubkey ( data) ?;
123
138
let delegate = <Runtime as frame_system:: Config >:: Lookup :: unlookup ( delegate) ;
124
139
let call = RuntimeCall :: Proxy ( pallet_proxy:: Call :: < Runtime > :: add_proxy {
@@ -127,10 +142,14 @@ impl StakingPrecompile {
127
142
delay : 0 ,
128
143
} ) ;
129
144
130
- try_dispatch_runtime_call ( handle, call, contract_to_origin ( & CONTRACT_ADDRESS_SS58 ) ? )
145
+ try_dispatch_runtime_call ( handle, call, RawOrigin :: Signed ( account_id ) )
131
146
}
132
147
133
148
fn remove_proxy ( handle : & mut impl PrecompileHandle , data : & [ u8 ] ) -> PrecompileResult {
149
+ let account_id =
150
+ <HashedAddressMapping < BlakeTwo256 > as AddressMapping < AccountId32 > >:: into_account_id (
151
+ handle. context ( ) . caller ,
152
+ ) ;
134
153
let ( delegate, _) = get_pubkey ( data) ?;
135
154
let delegate = <Runtime as frame_system:: Config >:: Lookup :: unlookup ( delegate) ;
136
155
let call = RuntimeCall :: Proxy ( pallet_proxy:: Call :: < Runtime > :: remove_proxy {
@@ -139,7 +158,7 @@ impl StakingPrecompile {
139
158
delay : 0 ,
140
159
} ) ;
141
160
142
- try_dispatch_runtime_call ( handle, call, contract_to_origin ( & CONTRACT_ADDRESS_SS58 ) ? )
161
+ try_dispatch_runtime_call ( handle, call, RawOrigin :: Signed ( account_id ) )
143
162
}
144
163
145
164
fn get_stake ( data : & [ u8 ] ) -> PrecompileResult {
@@ -167,17 +186,37 @@ impl StakingPrecompile {
167
186
} )
168
187
}
169
188
170
- fn parse_netuid ( data : & [ u8 ] , offset : usize ) -> Result < u16 , PrecompileFailure > {
171
- if data. len ( ) < offset + 2 {
189
+ fn transfer_back_to_caller (
190
+ account_id : & AccountId32 ,
191
+ amount : U256 ,
192
+ ) -> Result < ( ) , PrecompileFailure > {
193
+ let smart_contract_account_id: AccountId32 = CONTRACT_ADDRESS_SS58 . into ( ) ;
194
+
195
+ let amount_sub =
196
+ <Runtime as pallet_evm:: Config >:: BalanceConverter :: into_substrate_balance ( amount)
197
+ . ok_or ( ExitError :: OutOfFund ) ?;
198
+
199
+ // Create a transfer call from the smart contract to the caller
200
+ let transfer_call =
201
+ RuntimeCall :: Balances ( pallet_balances:: Call :: < Runtime > :: transfer_allow_death {
202
+ dest : account_id. clone ( ) . into ( ) ,
203
+ value : amount_sub. unique_saturated_into ( ) ,
204
+ } ) ;
205
+
206
+ // Execute the transfer
207
+ let transfer_result =
208
+ transfer_call. dispatch ( RawOrigin :: Signed ( smart_contract_account_id) . into ( ) ) ;
209
+
210
+ if let Err ( dispatch_error) = transfer_result {
211
+ log:: error!(
212
+ "Transfer back to caller failed. Error: {:?}" ,
213
+ dispatch_error
214
+ ) ;
172
215
return Err ( PrecompileFailure :: Error {
173
- exit_status : ExitError :: InvalidRange ,
216
+ exit_status : ExitError :: Other ( "Transfer back to caller failed" . into ( ) ) ,
174
217
} ) ;
175
218
}
176
219
177
- let mut netuid_bytes = [ 0u8 ; 2 ] ;
178
- netuid_bytes. copy_from_slice ( get_slice ( data, offset, offset + 2 ) ?) ;
179
- let netuid: u16 = netuid_bytes[ 1 ] as u16 | ( ( netuid_bytes[ 0 ] as u16 ) << 8u16 ) ;
180
-
181
- Ok ( netuid)
220
+ Ok ( ( ) )
182
221
}
183
222
}
0 commit comments