use pyth::reader::{Reader, ReaderImpl}; use pyth::util::UNEXPECTED_OVERFLOW; use super::GovernanceError; use core::panic_with_felt252; use core::starknet::EthAddress; // "Core" (left padded) const MODULE: u256 = 0x00000000000000000000000000000000000000000000000000000000436f7265; #[derive(Drop, Copy, Debug, PartialEq, Serde, Hash)] pub enum Action { ContractUpgrade, GuardianSetUpgrade, SetMessageFee, TransferFees, RecoverChainId, } impl U8TryIntoAction of TryInto { fn try_into(self: u8) -> Option { let value = match self { 0 => { return Option::None; }, 1 => Action::ContractUpgrade, 2 => Action::GuardianSetUpgrade, 3 => Action::SetMessageFee, 4 => Action::TransferFees, 5 => Action::RecoverChainId, _ => { return Option::None; }, }; Option::Some(value) } } /// Parsed header of a governance message. #[derive(Drop, Copy, Debug, PartialEq, Serde, Hash)] pub struct Header { /// The destination module of this instruction. pub module: u256, /// Type of action. pub action: Action, /// The destination chain ID of this instruction, /// or 0 if it's applicable to all chains. pub chain_id: u16, } /// Payload of `GuardianSetUpgrade` instruction. #[derive(Drop, Clone, Debug, PartialEq, Serde)] pub struct NewGuardianSet { /// Index of the new set. pub set_index: u32, /// Public keys of guardians, in order. pub keys: Array, } /// Parses the header of a governance instruction and verifies the module. /// `GovernanceError` enumerates possible panic payloads. pub fn parse_header(ref reader: Reader) -> Header { let module = reader.read_u256(); if module != MODULE { panic_with_felt252(GovernanceError::InvalidModule.into()); } let action = reader.read_u8().try_into().expect(GovernanceError::InvalidAction.into()); let chain_id = reader.read_u16(); Header { module, action, chain_id } } /// Parses the payload of `GuardianSetUpgrade` instruction. /// `GovernanceError` enumerates possible panic payloads. pub fn parse_new_guardian_set(ref reader: Reader) -> NewGuardianSet { let set_index = reader.read_u32(); let num_guardians = reader.read_u8(); let mut i = 0; let mut keys = array![]; while i < num_guardians { let key = reader.read_u160(); keys.append(key.try_into().expect(UNEXPECTED_OVERFLOW)); i += 1; }; assert(reader.len() == 0, GovernanceError::TrailingData.into()); NewGuardianSet { set_index, keys } }