@@ -66,7 +66,8 @@ pub enum GovernanceModule {
66
66
}
67
67
68
68
/// A `GovernanceAction` represents the different actions that can be voted on and executed by the
69
- /// governance system.
69
+ /// governance system. Note that this implementation is NEAR specific, for example within the
70
+ /// UpgradeContract variant we use a codehash unlike a code_id in Cosmwasm, or a Pubkey in Solana.
70
71
///
71
72
/// [ref:chain_structure] This type uses a [u8; 32] for contract upgrades which differs from other
72
73
/// chains, see the reference for more details.
@@ -269,11 +270,6 @@ impl Pyth {
269
270
// Convert to local VAA type to catch API changes.
270
271
let vaa = Vaa :: from ( vaa) ;
271
272
272
- ensure ! (
273
- self . executed_governance_vaa < vaa. sequence,
274
- VaaVerificationFailed
275
- ) ;
276
-
277
273
// Confirm the VAA is coming from a trusted source chain.
278
274
ensure ! (
279
275
self . gov_source
@@ -339,6 +335,16 @@ impl Pyth {
339
335
InvalidPayload
340
336
) ;
341
337
338
+ // Ensure the VAA is ahead in sequence, this check is here instead of during
339
+ // `execute_governance_instruction` as otherwise someone would be able to slip
340
+ // competing actions into the execution stream before the sequence is updated.
341
+ ensure ! (
342
+ self . executed_governance_vaa < vaa. sequence,
343
+ VaaVerificationFailed
344
+ ) ;
345
+
346
+ self . executed_governance_vaa = vaa. sequence ;
347
+
342
348
match GovernanceInstruction :: deserialize ( rest) ?. action {
343
349
SetDataSources { data_sources } => self . set_sources ( data_sources) ,
344
350
SetFee { base, expo } => self . set_update_fee ( base, expo) ?,
@@ -360,10 +366,13 @@ impl Pyth {
360
366
AuthorizeGovernanceDataSourceTransfer { claim_vaa } => {
361
367
let claim_vaa = hex:: encode ( claim_vaa) ;
362
368
363
- // Return early, the callback has to perform the rest of the processing.
369
+ // Return early, the callback has to perform the rest of the processing. Normally
370
+ // VAA processing will complete and the code below this match statement will
371
+ // execute. But because the VAA verification is async, we must return here instead
372
+ // and the logic below is duplicated within the authorize_gov_source_transfer function.
364
373
return Ok ( PromiseOrValue :: Promise (
365
374
ext_wormhole:: ext ( self . wormhole . clone ( ) )
366
- . with_static_gas ( Gas ( 30_000_000_000_000 ) )
375
+ . with_static_gas ( Gas ( 10_000_000_000_000 ) )
367
376
. verify_vaa ( claim_vaa. clone ( ) )
368
377
. then (
369
378
Self :: ext ( env:: current_account_id ( ) )
@@ -384,14 +393,13 @@ impl Pyth {
384
393
}
385
394
}
386
395
387
- self . executed_governance_vaa = vaa. sequence ;
388
-
389
396
// Refund storage difference to `account_id` after storage execution.
390
- self . refund_storage_usage (
397
+ Self :: refund_storage_usage (
391
398
account_id,
392
399
storage,
393
400
env:: storage_usage ( ) ,
394
401
env:: attached_deposit ( ) ,
402
+ None ,
395
403
)
396
404
. map ( |v| PromiseOrValue :: Value ( v) )
397
405
}
@@ -416,6 +424,9 @@ impl Pyth {
416
424
storage : u64 ,
417
425
#[ callback_result] _result : Result < u32 , near_sdk:: PromiseError > ,
418
426
) -> Result < ( ) , Error > {
427
+ // If VAA verification failed we should bail.
428
+ ensure ! ( is_promise_success( ) , VaaVerificationFailed ) ;
429
+
419
430
let vaa = hex:: decode ( claim_vaa) . map_err ( |_| InvalidPayload ) ?;
420
431
let ( vaa, rest) : ( wormhole:: Vaa < ( ) > , _ ) =
421
432
serde_wormhole:: from_slice_with_payload ( & vaa) . expect ( "Failed to deserialize VAA" ) ;
@@ -459,11 +470,12 @@ impl Pyth {
459
470
}
460
471
461
472
// Refund storage difference to `account_id` after storage execution.
462
- self . refund_storage_usage (
473
+ Self :: refund_storage_usage (
463
474
account_id,
464
475
storage,
465
476
env:: storage_usage ( ) ,
466
477
env:: attached_deposit ( ) ,
478
+ None ,
467
479
)
468
480
}
469
481
@@ -503,7 +515,7 @@ impl Pyth {
503
515
amount : u128 ,
504
516
storage : u64 ,
505
517
) -> Result < ( ) , Error > {
506
- self . refund_storage_usage ( account_id, storage, env:: storage_usage ( ) , amount)
518
+ Self :: refund_storage_usage ( account_id, storage, env:: storage_usage ( ) , amount, None )
507
519
}
508
520
}
509
521
0 commit comments