governance.move 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. module pyth::governance {
  2. use sui::tx_context::{TxContext};
  3. use pyth::data_source::{Self};
  4. use pyth::governance_instruction;
  5. use pyth::governance_action;
  6. use pyth::contract_upgrade;
  7. use pyth::set_governance_data_source;
  8. use pyth::set_data_sources;
  9. use pyth::set_stale_price_threshold;
  10. use pyth::state::{State};
  11. use pyth::set_update_fee;
  12. use pyth::state;
  13. use wormhole::vaa::{Self, VAA};
  14. use wormhole::state::{State as WormState};
  15. const E_GOVERNANCE_CONTRACT_UPGRADE_CHAIN_ID_ZERO: u64 = 0;
  16. const E_INVALID_GOVERNANCE_ACTION: u64 = 1;
  17. const E_INVALID_GOVERNANCE_DATA_SOURCE: u64 = 2;
  18. const E_INVALID_GOVERNANCE_SEQUENCE_NUMBER: u64 = 3;
  19. public entry fun execute_governance_instruction(
  20. pyth_state : &mut State,
  21. worm_state: &WormState,
  22. vaa_bytes: vector<u8>,
  23. ctx: &mut TxContext
  24. ) {
  25. let parsed_vaa = parse_and_verify_governance_vaa(pyth_state, worm_state, vaa_bytes, ctx);
  26. let instruction = governance_instruction::from_byte_vec(vaa::take_payload(parsed_vaa));
  27. // Dispatch the instruction to the appropiate handler
  28. let action = governance_instruction::get_action(&instruction);
  29. if (action == governance_action::new_contract_upgrade()) {
  30. assert!(governance_instruction::get_target_chain_id(&instruction) != 0,
  31. E_GOVERNANCE_CONTRACT_UPGRADE_CHAIN_ID_ZERO);
  32. contract_upgrade::execute(worm_state, pyth_state, governance_instruction::destroy(instruction));
  33. } else if (action == governance_action::new_set_governance_data_source()) {
  34. set_governance_data_source::execute(pyth_state, governance_instruction::destroy(instruction));
  35. } else if (action == governance_action::new_set_data_sources()) {
  36. set_data_sources::execute(pyth_state, governance_instruction::destroy(instruction));
  37. } else if (action == governance_action::new_set_update_fee()) {
  38. set_update_fee::execute(pyth_state, governance_instruction::destroy(instruction));
  39. } else if (action == governance_action::new_set_stale_price_threshold()) {
  40. set_stale_price_threshold::execute(pyth_state, governance_instruction::destroy(instruction));
  41. } else {
  42. governance_instruction::destroy(instruction);
  43. assert!(false, E_INVALID_GOVERNANCE_ACTION);
  44. }
  45. }
  46. fun parse_and_verify_governance_vaa(
  47. pyth_state: &mut State,
  48. worm_state: &WormState,
  49. bytes: vector<u8>,
  50. ctx: &mut TxContext
  51. ): VAA {
  52. let parsed_vaa = vaa::parse_and_verify(worm_state, bytes, ctx);
  53. // Check that the governance data source is valid
  54. assert!(
  55. state::is_valid_governance_data_source(
  56. pyth_state,
  57. data_source::new(
  58. (vaa::emitter_chain(&parsed_vaa) as u64),
  59. vaa::emitter_address(&parsed_vaa))),
  60. E_INVALID_GOVERNANCE_DATA_SOURCE);
  61. // Check that the sequence number is greater than the last executed governance VAA
  62. let sequence = vaa::sequence(&parsed_vaa);
  63. assert!(sequence > state::get_last_executed_governance_sequence(pyth_state), E_INVALID_GOVERNANCE_SEQUENCE_NUMBER);
  64. state::set_last_executed_governance_sequence(pyth_state, sequence);
  65. parsed_vaa
  66. }
  67. }
  68. // TODO - add tests