1
1
use anchor_lang:: prelude:: * ;
2
+ use anchor_spl:: { token_2022:: spl_token_2022:: instruction:: AuthorityType , token_interface} ;
2
3
use ntt_messages:: chain_id:: ChainId ;
3
4
use wormhole_solana_utils:: cpi:: bpf_loader_upgradeable:: { self , BpfLoaderUpgradeable } ;
4
5
@@ -9,6 +10,7 @@ use crate::{
9
10
config:: Config ,
10
11
error:: NTTError ,
11
12
peer:: NttManagerPeer ,
13
+ pending_token_authority:: PendingTokenAuthority ,
12
14
queue:: { inbox:: InboxRateLimit , outbox:: OutboxRateLimit , rate_limit:: RateLimitState } ,
13
15
registered_transceiver:: RegisteredTransceiver ,
14
16
} ;
@@ -154,6 +156,210 @@ pub fn claim_ownership(ctx: Context<ClaimOwnership>) -> Result<()> {
154
156
)
155
157
}
156
158
159
+ // * Set token authority
160
+
161
+ #[ derive( Accounts ) ]
162
+ pub struct AcceptTokenAuthority < ' info > {
163
+ #[ account(
164
+ has_one = mint,
165
+ constraint = config. paused @ NTTError :: NotPaused ,
166
+ ) ]
167
+ pub config : Account < ' info , Config > ,
168
+
169
+ #[ account( mut ) ]
170
+ pub mint : InterfaceAccount < ' info , token_interface:: Mint > ,
171
+
172
+ #[ account(
173
+ seeds = [ crate :: TOKEN_AUTHORITY_SEED ] ,
174
+ bump,
175
+ ) ]
176
+ /// CHECK: The constraints enforce this is valid mint authority
177
+ pub token_authority : UncheckedAccount < ' info > ,
178
+
179
+ pub current_authority : Signer < ' info > ,
180
+
181
+ pub token_program : Interface < ' info , token_interface:: TokenInterface > ,
182
+ }
183
+
184
+ pub fn accept_token_authority ( ctx : Context < AcceptTokenAuthority > ) -> Result < ( ) > {
185
+ token_interface:: set_authority (
186
+ CpiContext :: new (
187
+ ctx. accounts . token_program . to_account_info ( ) ,
188
+ token_interface:: SetAuthority {
189
+ account_or_mint : ctx. accounts . mint . to_account_info ( ) ,
190
+ current_authority : ctx. accounts . current_authority . to_account_info ( ) ,
191
+ } ,
192
+ ) ,
193
+ AuthorityType :: MintTokens ,
194
+ Some ( ctx. accounts . token_authority . key ( ) ) ,
195
+ )
196
+ }
197
+
198
+ #[ derive( Accounts ) ]
199
+ pub struct SetTokenAuthority < ' info > {
200
+ #[ account(
201
+ has_one = owner,
202
+ has_one = mint,
203
+ constraint = config. paused @ NTTError :: NotPaused ,
204
+ ) ]
205
+ pub config : Account < ' info , Config > ,
206
+
207
+ pub owner : Signer < ' info > ,
208
+
209
+ #[ account( mut ) ]
210
+ pub mint : InterfaceAccount < ' info , token_interface:: Mint > ,
211
+
212
+ #[ account(
213
+ seeds = [ crate :: TOKEN_AUTHORITY_SEED ] ,
214
+ bump,
215
+ ) ]
216
+ /// CHECK: The constraints enforce this is valid mint authority
217
+ pub token_authority : UncheckedAccount < ' info > ,
218
+
219
+ /// CHECK: This account will be the signer in the [claim_token_authority] instruction.
220
+ pub new_authority : UncheckedAccount < ' info > ,
221
+ }
222
+
223
+ #[ derive( Accounts ) ]
224
+ pub struct SetTokenAuthorityChecked < ' info > {
225
+ #[ account(
226
+ constraint = common. token_authority. key( ) == common. mint. mint_authority. unwrap( ) @ NTTError :: InvalidMintAuthority
227
+ ) ]
228
+ pub common : SetTokenAuthority < ' info > ,
229
+
230
+ #[ account( mut ) ]
231
+ pub rent_payer : Signer < ' info > ,
232
+
233
+ #[ account(
234
+ init_if_needed,
235
+ space = 8 + PendingTokenAuthority :: INIT_SPACE ,
236
+ payer = rent_payer,
237
+ seeds = [ PendingTokenAuthority :: SEED_PREFIX ] ,
238
+ bump
239
+ ) ]
240
+ pub pending_token_authority : Account < ' info , PendingTokenAuthority > ,
241
+
242
+ pub system_program : Program < ' info , System > ,
243
+ }
244
+
245
+ pub fn set_token_authority ( ctx : Context < SetTokenAuthorityChecked > ) -> Result < ( ) > {
246
+ ctx. accounts
247
+ . pending_token_authority
248
+ . set_inner ( PendingTokenAuthority {
249
+ bump : ctx. bumps . pending_token_authority ,
250
+ pending_authority : ctx. accounts . common . new_authority . key ( ) ,
251
+ rent_payer : ctx. accounts . rent_payer . key ( ) ,
252
+ } ) ;
253
+ Ok ( ( ) )
254
+ }
255
+
256
+ #[ derive( Accounts ) ]
257
+ pub struct SetTokenAuthorityUnchecked < ' info > {
258
+ pub common : SetTokenAuthority < ' info > ,
259
+
260
+ pub token_program : Interface < ' info , token_interface:: TokenInterface > ,
261
+ }
262
+
263
+ pub fn set_token_authority_one_step_unchecked (
264
+ ctx : Context < SetTokenAuthorityUnchecked > ,
265
+ ) -> Result < ( ) > {
266
+ token_interface:: set_authority (
267
+ CpiContext :: new_with_signer (
268
+ ctx. accounts . token_program . to_account_info ( ) ,
269
+ token_interface:: SetAuthority {
270
+ account_or_mint : ctx. accounts . common . mint . to_account_info ( ) ,
271
+ current_authority : ctx. accounts . common . token_authority . to_account_info ( ) ,
272
+ } ,
273
+ & [ & [
274
+ crate :: TOKEN_AUTHORITY_SEED ,
275
+ & [ ctx. bumps . common . token_authority ] ,
276
+ ] ] ,
277
+ ) ,
278
+ AuthorityType :: MintTokens ,
279
+ Some ( ctx. accounts . common . new_authority . key ( ) ) ,
280
+ )
281
+ }
282
+
283
+ // * Claim token authority
284
+
285
+ #[ derive( Accounts ) ]
286
+ pub struct ClaimTokenAuthorityBase < ' info > {
287
+ #[ account(
288
+ has_one = mint,
289
+ constraint = config. paused @ NTTError :: NotPaused ,
290
+ ) ]
291
+ pub config : Account < ' info , Config > ,
292
+
293
+ #[ account( mut ) ]
294
+ pub mint : InterfaceAccount < ' info , token_interface:: Mint > ,
295
+
296
+ #[ account(
297
+ seeds = [ crate :: TOKEN_AUTHORITY_SEED ] ,
298
+ bump,
299
+ ) ]
300
+ /// CHECK: The seeds constraint enforces that this is the correct address
301
+ pub token_authority : UncheckedAccount < ' info > ,
302
+
303
+ #[ account( mut ) ]
304
+ /// CHECK: the `pending_token_authority` constraint enforces that this is the correct address
305
+ pub rent_payer : UncheckedAccount < ' info > ,
306
+
307
+ #[ account(
308
+ mut ,
309
+ seeds = [ PendingTokenAuthority :: SEED_PREFIX ] ,
310
+ bump = pending_token_authority. bump,
311
+ has_one = rent_payer @ NTTError :: IncorrectRentPayer ,
312
+ close = rent_payer
313
+ ) ]
314
+ pub pending_token_authority : Account < ' info , PendingTokenAuthority > ,
315
+
316
+ pub token_program : Interface < ' info , token_interface:: TokenInterface > ,
317
+
318
+ pub system_program : Program < ' info , System > ,
319
+ }
320
+
321
+ #[ derive( Accounts ) ]
322
+ pub struct RevertTokenAuthority < ' info > {
323
+ pub common : ClaimTokenAuthorityBase < ' info > ,
324
+
325
+ #[ account(
326
+ address = common. config. owner
327
+ ) ]
328
+ pub owner : Signer < ' info > ,
329
+ }
330
+
331
+ pub fn revert_token_authority ( _ctx : Context < RevertTokenAuthority > ) -> Result < ( ) > {
332
+ Ok ( ( ) )
333
+ }
334
+
335
+ #[ derive( Accounts ) ]
336
+ pub struct ClaimTokenAuthority < ' info > {
337
+ pub common : ClaimTokenAuthorityBase < ' info > ,
338
+
339
+ #[ account(
340
+ address = common. pending_token_authority. pending_authority @ NTTError :: InvalidPendingTokenAuthority
341
+ ) ]
342
+ pub new_authority : Signer < ' info > ,
343
+ }
344
+
345
+ pub fn claim_token_authority ( ctx : Context < ClaimTokenAuthority > ) -> Result < ( ) > {
346
+ token_interface:: set_authority (
347
+ CpiContext :: new_with_signer (
348
+ ctx. accounts . common . token_program . to_account_info ( ) ,
349
+ token_interface:: SetAuthority {
350
+ account_or_mint : ctx. accounts . common . mint . to_account_info ( ) ,
351
+ current_authority : ctx. accounts . common . token_authority . to_account_info ( ) ,
352
+ } ,
353
+ & [ & [
354
+ crate :: TOKEN_AUTHORITY_SEED ,
355
+ & [ ctx. bumps . common . token_authority ] ,
356
+ ] ] ,
357
+ ) ,
358
+ AuthorityType :: MintTokens ,
359
+ Some ( ctx. accounts . new_authority . key ( ) ) ,
360
+ )
361
+ }
362
+
157
363
// * Set peers
158
364
159
365
#[ derive( Accounts ) ]
@@ -267,7 +473,7 @@ pub fn register_transceiver(ctx: Context<RegisterTransceiver>) -> Result<()> {
267
473
#[ derive( Accounts ) ]
268
474
pub struct SetOutboundLimit < ' info > {
269
475
#[ account(
270
- constraint = config . owner == owner . key ( )
476
+ has_one = owner,
271
477
) ]
272
478
pub config : Account < ' info , Config > ,
273
479
@@ -294,7 +500,7 @@ pub fn set_outbound_limit(
294
500
#[ instruction( args: SetInboundLimitArgs ) ]
295
501
pub struct SetInboundLimit < ' info > {
296
502
#[ account(
297
- constraint = config . owner == owner . key ( )
503
+ has_one = owner,
298
504
) ]
299
505
pub config : Account < ' info , Config > ,
300
506
0 commit comments