@@ -66,7 +66,8 @@ pub enum GovernanceModule {
6666}
6767
6868/// 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.
7071///
7172/// [ref:chain_structure] This type uses a [u8; 32] for contract upgrades which differs from other
7273/// chains, see the reference for more details.
@@ -269,11 +270,6 @@ impl Pyth {
269270 // Convert to local VAA type to catch API changes.
270271 let vaa = Vaa :: from ( vaa) ;
271272
272- ensure ! (
273- self . executed_governance_vaa < vaa. sequence,
274- VaaVerificationFailed
275- ) ;
276-
277273 // Confirm the VAA is coming from a trusted source chain.
278274 ensure ! (
279275 self . gov_source
@@ -339,6 +335,16 @@ impl Pyth {
339335 InvalidPayload
340336 ) ;
341337
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+
342348 match GovernanceInstruction :: deserialize ( rest) ?. action {
343349 SetDataSources { data_sources } => self . set_sources ( data_sources) ,
344350 SetFee { base, expo } => self . set_update_fee ( base, expo) ?,
@@ -360,10 +366,13 @@ impl Pyth {
360366 AuthorizeGovernanceDataSourceTransfer { claim_vaa } => {
361367 let claim_vaa = hex:: encode ( claim_vaa) ;
362368
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.
364373 return Ok ( PromiseOrValue :: Promise (
365374 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 ) )
367376 . verify_vaa ( claim_vaa. clone ( ) )
368377 . then (
369378 Self :: ext ( env:: current_account_id ( ) )
@@ -384,14 +393,13 @@ impl Pyth {
384393 }
385394 }
386395
387- self . executed_governance_vaa = vaa. sequence ;
388-
389396 // Refund storage difference to `account_id` after storage execution.
390- self . refund_storage_usage (
397+ Self :: refund_storage_usage (
391398 account_id,
392399 storage,
393400 env:: storage_usage ( ) ,
394401 env:: attached_deposit ( ) ,
402+ None ,
395403 )
396404 . map ( |v| PromiseOrValue :: Value ( v) )
397405 }
@@ -416,6 +424,9 @@ impl Pyth {
416424 storage : u64 ,
417425 #[ callback_result] _result : Result < u32 , near_sdk:: PromiseError > ,
418426 ) -> Result < ( ) , Error > {
427+ // If VAA verification failed we should bail.
428+ ensure ! ( is_promise_success( ) , VaaVerificationFailed ) ;
429+
419430 let vaa = hex:: decode ( claim_vaa) . map_err ( |_| InvalidPayload ) ?;
420431 let ( vaa, rest) : ( wormhole:: Vaa < ( ) > , _ ) =
421432 serde_wormhole:: from_slice_with_payload ( & vaa) . expect ( "Failed to deserialize VAA" ) ;
@@ -459,11 +470,12 @@ impl Pyth {
459470 }
460471
461472 // Refund storage difference to `account_id` after storage execution.
462- self . refund_storage_usage (
473+ Self :: refund_storage_usage (
463474 account_id,
464475 storage,
465476 env:: storage_usage ( ) ,
466477 env:: attached_deposit ( ) ,
478+ None ,
467479 )
468480 }
469481
@@ -503,7 +515,7 @@ impl Pyth {
503515 amount : u128 ,
504516 storage : u64 ,
505517 ) -> 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 )
507519 }
508520}
509521
0 commit comments