@@ -10,6 +10,7 @@ use crate::{
10
10
config:: Config ,
11
11
error:: NTTError ,
12
12
peer:: NttManagerPeer ,
13
+ pending_token_authority:: PendingTokenAuthority ,
13
14
queue:: { inbox:: InboxRateLimit , outbox:: OutboxRateLimit , rate_limit:: RateLimitState } ,
14
15
registered_transceiver:: RegisteredTransceiver ,
15
16
} ;
@@ -174,20 +175,124 @@ pub struct SetTokenAuthority<'info> {
174
175
/// CHECK: the mint address matches the config
175
176
pub mint : InterfaceAccount < ' info , token_interface:: Mint > ,
176
177
178
+ #[ account(
179
+ seeds = [ crate :: TOKEN_AUTHORITY_SEED ] ,
180
+ bump,
181
+ constraint = mint. mint_authority. unwrap( ) == token_authority. key( ) @ NTTError :: InvalidMintAuthority
182
+ ) ]
183
+ /// CHECK: The constraints enforce this is valid mint authority
184
+ pub token_authority : UncheckedAccount < ' info > ,
185
+
186
+ /// CHECK: This account will be the signer in the [claim_token_authority] instruction.
187
+ pub new_authority : UncheckedAccount < ' info > ,
188
+ }
189
+
190
+ #[ derive( Accounts ) ]
191
+ pub struct SetTokenAuthorityChecked < ' info > {
192
+ pub common : SetTokenAuthority < ' info > ,
193
+
194
+ #[ account( mut ) ]
195
+ pub payer : Signer < ' info > ,
196
+
197
+ #[ account(
198
+ init_if_needed,
199
+ space = 8 + PendingTokenAuthority :: INIT_SPACE ,
200
+ payer = payer,
201
+ seeds = [ PendingTokenAuthority :: SEED_PREFIX ] ,
202
+ bump
203
+ ) ]
204
+ pub pending_token_authority : Account < ' info , PendingTokenAuthority > ,
205
+
206
+ pub system_program : Program < ' info , System > ,
207
+ }
208
+
209
+ pub fn set_token_authority ( ctx : Context < SetTokenAuthorityChecked > ) -> Result < ( ) > {
210
+ ctx. accounts
211
+ . pending_token_authority
212
+ . set_inner ( PendingTokenAuthority {
213
+ bump : ctx. bumps . pending_token_authority ,
214
+ pending_authority : ctx. accounts . common . new_authority . key ( ) ,
215
+ rent_payer : ctx. accounts . payer . key ( ) ,
216
+ } ) ;
217
+ Ok ( ( ) )
218
+ }
219
+
220
+ #[ derive( Accounts ) ]
221
+ pub struct SetTokenAuthorityUnchecked < ' info > {
222
+ pub common : SetTokenAuthority < ' info > ,
223
+
177
224
pub token_program : Interface < ' info , token_interface:: TokenInterface > ,
225
+ }
226
+
227
+ pub fn set_token_authority_one_step_unchecked (
228
+ ctx : Context < SetTokenAuthorityUnchecked > ,
229
+ ) -> Result < ( ) > {
230
+ token_interface:: set_authority (
231
+ CpiContext :: new_with_signer (
232
+ ctx. accounts . token_program . to_account_info ( ) ,
233
+ token_interface:: SetAuthority {
234
+ account_or_mint : ctx. accounts . common . mint . to_account_info ( ) ,
235
+ current_authority : ctx. accounts . common . token_authority . to_account_info ( ) ,
236
+ } ,
237
+ & [ & [
238
+ crate :: TOKEN_AUTHORITY_SEED ,
239
+ & [ ctx. bumps . common . token_authority ] ,
240
+ ] ] ,
241
+ ) ,
242
+ AuthorityType :: MintTokens ,
243
+ Some ( ctx. accounts . common . new_authority . key ( ) ) ,
244
+ )
245
+ }
246
+
247
+ #[ derive( Accounts ) ]
248
+ pub struct ClaimTokenAuthority < ' info > {
249
+ #[ account(
250
+ constraint = config. paused @ NTTError :: NotPaused ,
251
+ ) ]
252
+ pub config : Account < ' info , Config > ,
253
+
254
+ #[ account(
255
+ mut ,
256
+ address = pending_token_authority. rent_payer @ NTTError :: IncorrectRentPayer ,
257
+ ) ]
258
+ pub payer : Signer < ' info > ,
259
+
260
+ #[ account(
261
+ mut ,
262
+ address = config. mint,
263
+ ) ]
264
+ /// CHECK: the mint address matches the config
265
+ pub mint : InterfaceAccount < ' info , token_interface:: Mint > ,
178
266
179
267
#[ account(
180
268
seeds = [ crate :: TOKEN_AUTHORITY_SEED ] ,
181
269
bump,
182
270
) ]
183
- /// CHECK: token_program will ensure this is the valid mint_authority.
271
+ /// CHECK: The seeds constraint enforces that this is the correct address
184
272
pub token_authority : UncheckedAccount < ' info > ,
185
273
186
- /// CHECK: This is unsafe as is so should be used with caution
187
- pub new_authority : UncheckedAccount < ' info > ,
274
+ #[ account(
275
+ constraint = (
276
+ new_authority. key( ) == pending_token_authority. pending_authority
277
+ || new_authority. key( ) == token_authority. key( )
278
+ ) @ NTTError :: InvalidPendingTokenAuthority
279
+ ) ]
280
+ pub new_authority : Signer < ' info > ,
281
+
282
+ #[ account(
283
+ mut ,
284
+ seeds = [ PendingTokenAuthority :: SEED_PREFIX ] ,
285
+ bump = pending_token_authority. bump,
286
+ close = payer
287
+ ) ]
288
+ pub pending_token_authority : Account < ' info , PendingTokenAuthority > ,
289
+
290
+ pub token_program : Interface < ' info , token_interface:: TokenInterface > ,
291
+
292
+ pub system_program : Program < ' info , System > ,
188
293
}
189
294
190
- pub fn set_token_authority_one_step_unchecked ( ctx : Context < SetTokenAuthority > ) -> Result < ( ) > {
295
+ pub fn claim_token_authority ( ctx : Context < ClaimTokenAuthority > ) -> Result < ( ) > {
191
296
token_interface:: set_authority (
192
297
CpiContext :: new_with_signer (
193
298
ctx. accounts . token_program . to_account_info ( ) ,
0 commit comments