@@ -28,6 +28,7 @@ use stylus_sdk::{
28
28
} ;
29
29
30
30
use error:: PythReceiverError ;
31
+ use governance_structs:: * ;
31
32
use pythnet_sdk:: {
32
33
accumulators:: merkle:: { MerklePath , MerkleRoot } ,
33
34
hashers:: keccak256_160:: Keccak160 ,
@@ -515,6 +516,73 @@ impl PythReceiver {
515
516
price_feeds
516
517
}
517
518
519
+ pub fn execute_governance_instruction ( & self , data : Vec < u8 > ) -> Result < ( ) , PythReceiverError > {
520
+ let wormhole: IWormholeContract = IWormholeContract :: new ( self . wormhole . get ( ) ) ;
521
+ let config = Call :: new ( ) ;
522
+ wormhole
523
+ . parse_and_verify_vm ( config, Vec :: from ( data. clone ( ) ) )
524
+ . map_err ( |_| PythReceiverError :: InvalidWormholeMessage ) ?;
525
+
526
+ let vm = Vaa :: read ( & mut Vec :: from ( data. clone ( ) ) . as_slice ( ) )
527
+ . map_err ( |_| PythReceiverError :: VaaVerificationFailed ) ?;
528
+
529
+ self . verify_governance_vm ( vm) ?;
530
+
531
+ let instruction = governance_structs:: parse_instruction ( vm. payload . to_vec ( ) )
532
+ . map_err ( |_| PythReceiverError :: InvalidGovernanceMessage ) ?;
533
+
534
+ if instruction. target_chain_id != 0 && instruction. target_chain_id != wormhole. chain_id ( ) {
535
+ return Err ( PythReceiverError :: InvalidGovernanceTarget ) ;
536
+ }
537
+
538
+ match instruction. payload {
539
+ SetFee ( payload) => { }
540
+ SetFeeInToken ( payload) => { }
541
+ SetDataSources ( payload) => { }
542
+ SetWormholeAddress ( payload) => { }
543
+ RequestGovernanceDataSourceTransfer ( _) => {
544
+ // RequestGovernanceDataSourceTransfer can be only part of
545
+ // AuthorizeGovernanceDataSourceTransfer message
546
+ return Err ( PythReceiverError :: InvalidGovernanceMessage ) ;
547
+ }
548
+ AuthorizeGovernanceDataSourceTransfer ( payload) => { }
549
+ UpgradeContract ( payload) => {
550
+ if instruction. target_chain_id == 0 {
551
+ return Err ( PythReceiverError :: InvalidGovernanceTarget ) ;
552
+ }
553
+ self . upgrade_contract ( payload. new_implementation ) ;
554
+ }
555
+ }
556
+
557
+ Ok ( ( ) )
558
+ }
559
+
560
+ fn upgrade_contract ( & self , new_implementation : Address ) {
561
+ !unimplemented ! ( "Upgrade contract not yet implemented" ) ;
562
+ }
563
+
564
+ fn verify_governance_vm ( & self , vm : Vaa ) -> Result < ( ) , PythReceiverError > {
565
+ if vm. body . emitter_chain != self . governance_data_source_chain_id . get ( ) . to :: < u16 > ( ) {
566
+ return Err ( PythReceiverError :: InvalidGovernanceMessage ) ;
567
+ }
568
+
569
+ if vm. body . emitter_address != self . governance_data_source_emitter_address . get ( ) {
570
+ return Err ( PythReceiverError :: InvalidGovernanceMessage ) ;
571
+ }
572
+
573
+ let current_sequence = vm. body . sequence . to :: < u64 > ( ) ;
574
+ let last_executed_sequence = self . last_executed_governance_sequence . get ( ) . to :: < u64 > ( ) ;
575
+
576
+ if current_sequence <= last_executed_sequence {
577
+ return Err ( PythReceiverError :: GovernanceMessageAlreadyExecuted ) ;
578
+ }
579
+
580
+ self . last_executed_governance_sequence
581
+ . set ( U64 :: from ( current_sequence) ) ;
582
+
583
+ Ok ( ( ) )
584
+ }
585
+
518
586
fn is_no_older_than ( & self , publish_time : U64 , max_age : u64 ) -> bool {
519
587
self . get_current_timestamp ( )
520
588
. saturating_sub ( publish_time. to :: < u64 > ( ) )
0 commit comments