@@ -110,4 +110,111 @@ impl<T: Config> Pallet<T> {
110
110
// -- 10. Ok and return.
111
111
Ok ( ( ) )
112
112
}
113
+
114
+ /// Transfers stake from one coldkey to another, optionally moving from one subnet to another,
115
+ /// while keeping the same hotkey.
116
+ ///
117
+ /// # Arguments
118
+ /// * `origin` - The origin of the transaction, which must be signed by the `origin_coldkey`.
119
+ /// * `destination_coldkey` - The account ID of the coldkey to which the stake is being transferred.
120
+ /// * `hotkey` - The account ID of the hotkey associated with this stake.
121
+ /// * `origin_netuid` - The network ID (subnet) from which the stake is being transferred.
122
+ /// * `destination_netuid` - The network ID (subnet) to which the stake is being transferred.
123
+ /// * `alpha_amount` - The amount of stake to transfer.
124
+ ///
125
+ /// # Returns
126
+ /// * `DispatchResult` - Indicates success or failure.
127
+ ///
128
+ /// # Errors
129
+ /// This function will return an error if:
130
+ /// * The transaction is not signed by the `origin_coldkey`.
131
+ /// * The subnet (`origin_netuid` or `destination_netuid`) does not exist.
132
+ /// * The `hotkey` does not exist.
133
+ /// * The `(origin_coldkey, hotkey, origin_netuid)` does not have enough stake for `alpha_amount`.
134
+ /// * The amount to be transferred is below the minimum stake requirement.
135
+ /// * There is a failure in staking or unstaking logic.
136
+ ///
137
+ /// # Events
138
+ /// Emits a `StakeTransferred` event upon successful completion of the transfer.
139
+ pub fn do_transfer_stake (
140
+ origin : T :: RuntimeOrigin ,
141
+ destination_coldkey : T :: AccountId ,
142
+ hotkey : T :: AccountId ,
143
+ origin_netuid : u16 ,
144
+ destination_netuid : u16 ,
145
+ alpha_amount : u64 ,
146
+ ) -> dispatch:: DispatchResult {
147
+ // 1. Ensure the extrinsic is signed by the origin_coldkey.
148
+ let coldkey = ensure_signed ( origin) ?;
149
+
150
+ // 2. Ensure both subnets exist.
151
+ ensure ! (
152
+ Self :: if_subnet_exist( origin_netuid) ,
153
+ Error :: <T >:: SubnetNotExists
154
+ ) ;
155
+ ensure ! (
156
+ Self :: if_subnet_exist( destination_netuid) ,
157
+ Error :: <T >:: SubnetNotExists
158
+ ) ;
159
+
160
+ // 3. Check that the hotkey exists.
161
+ ensure ! (
162
+ Self :: hotkey_account_exists( & hotkey) ,
163
+ Error :: <T >:: HotKeyAccountNotExists
164
+ ) ;
165
+
166
+ // 4. Check that the signed coldkey actually owns the given hotkey.
167
+ ensure ! (
168
+ Self :: coldkey_owns_hotkey( & coldkey, & hotkey) ,
169
+ Error :: <T >:: NonAssociatedColdKey
170
+ ) ;
171
+
172
+ // 5. Get current stake.
173
+ let origin_alpha =
174
+ Self :: get_stake_for_hotkey_and_coldkey_on_subnet ( & hotkey, & coldkey, origin_netuid) ;
175
+ ensure ! (
176
+ alpha_amount <= origin_alpha,
177
+ Error :: <T >:: NotEnoughStakeToWithdraw
178
+ ) ;
179
+
180
+ // 6. Unstake from the origin coldkey; this returns an amount of TAO.
181
+ let origin_tao = Self :: unstake_from_subnet ( & hotkey, & coldkey, origin_netuid, alpha_amount) ;
182
+
183
+ // 7. Ensure the returned TAO meets a minimum stake requirement (if required).
184
+ ensure ! (
185
+ origin_tao >= DefaultMinStake :: <T >:: get( ) ,
186
+ Error :: <T >:: AmountTooLow
187
+ ) ;
188
+
189
+ // 8. Stake the TAO into `(destination_coldkey, hotkey)` on the destination subnet.
190
+ // Create the account if it does not exist.
191
+ Self :: stake_into_subnet (
192
+ & hotkey,
193
+ & destination_coldkey,
194
+ destination_netuid,
195
+ origin_tao,
196
+ ) ;
197
+
198
+ // 9. Emit an event for logging/monitoring.
199
+ log:: info!(
200
+ "StakeTransferred(origin_coldkey: {:?}, destination_coldkey: {:?}, hotkey: {:?}, origin_netuid: {:?}, destination_netuid: {:?}, amount: {:?})" ,
201
+ coldkey,
202
+ destination_coldkey,
203
+ hotkey,
204
+ origin_netuid,
205
+ destination_netuid,
206
+ origin_tao
207
+ ) ;
208
+ Self :: deposit_event ( Event :: StakeTransferred (
209
+ coldkey,
210
+ destination_coldkey,
211
+ hotkey,
212
+ origin_netuid,
213
+ destination_netuid,
214
+ origin_tao,
215
+ ) ) ;
216
+
217
+ // 10. Return success.
218
+ Ok ( ( ) )
219
+ }
113
220
}
0 commit comments