Skip to content

Commit 3fa19cd

Browse files
committed
fixing skeleton of lib script
1 parent 7ff104b commit 3fa19cd

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

target_chains/stylus/contracts/pyth-receiver/src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ pub enum PythReceiverError {
2323
InvalidGovernanceMessage,
2424
InvalidGovernanceTarget,
2525
InvalidGovernanceAction,
26+
InvalidGovernanceDataSource,
27+
OldGovernanceMessage,
28+
GovernanceMessageAlreadyExecuted,
2629
}
2730

2831
impl core::fmt::Debug for PythReceiverError {
@@ -55,6 +58,9 @@ impl From<PythReceiverError> for Vec<u8> {
5558
PythReceiverError::InvalidGovernanceMessage => 19,
5659
PythReceiverError::InvalidGovernanceTarget => 20,
5760
PythReceiverError::InvalidGovernanceAction => 21,
61+
PythReceiverError::InvalidGovernanceDataSource => 22,
62+
PythReceiverError::OldGovernanceMessage => 23,
63+
PythReceiverError::GovernanceMessageAlreadyExecuted => 24,
5864
}]
5965
}
6066
}

target_chains/stylus/contracts/pyth-receiver/src/lib.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use stylus_sdk::{
2828
};
2929

3030
use error::PythReceiverError;
31+
use governance_structs::*;
3132
use pythnet_sdk::{
3233
accumulators::merkle::{MerklePath, MerkleRoot},
3334
hashers::keccak256_160::Keccak160,
@@ -515,6 +516,73 @@ impl PythReceiver {
515516
price_feeds
516517
}
517518

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+
518586
fn is_no_older_than(&self, publish_time: U64, max_age: u64) -> bool {
519587
self.get_current_timestamp()
520588
.saturating_sub(publish_time.to::<u64>())

0 commit comments

Comments
 (0)