governance.move 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. module pyth::governance {
  2. use pyth::governance_instruction;
  3. use pyth::governance_action;
  4. use pyth::set_governance_data_source;
  5. use pyth::set_data_sources;
  6. use pyth::set_stale_price_threshold;
  7. use pyth::set_fee_recipient;
  8. use pyth::state::{Self, State};
  9. use pyth::set_update_fee;
  10. use pyth::governance_witness::{GovernanceWitness};
  11. use wormhole::governance_message::{Self, DecreeReceipt};
  12. const E_INVALID_GOVERNANCE_ACTION: u64 = 0;
  13. const E_MUST_USE_CONTRACT_UPGRADE_MODULE_TO_DO_UPGRADES: u64 = 1;
  14. const E_CANNOT_EXECUTE_GOVERNANCE_ACTION_WITH_OBSOLETE_SEQUENCE_NUMBER: u64 = 2;
  15. /// Execute a governance instruction other than contract upgrade, which is
  16. /// handled separately in the contract_upgrade.move module.
  17. public fun execute_governance_instruction(
  18. pyth_state : &mut State,
  19. receipt: DecreeReceipt<GovernanceWitness>,
  20. ) {
  21. // This capability ensures that the current build version is used.
  22. let latest_only = state::assert_latest_only(pyth_state);
  23. // Get the sequence number of the governance VAA that was used to
  24. // generate the receipt.
  25. let sequence = governance_message::sequence(&receipt);
  26. // Require that new sequence number is greater than last executed sequence number.
  27. assert!(sequence > state::get_last_executed_governance_sequence(pyth_state),
  28. E_CANNOT_EXECUTE_GOVERNANCE_ACTION_WITH_OBSOLETE_SEQUENCE_NUMBER);
  29. // Update latest executed sequence number to current one.
  30. state::set_last_executed_governance_sequence(&latest_only, pyth_state, sequence);
  31. // governance_message::take_payload takes care of replay protection.
  32. let payload =
  33. governance_message::take_payload(
  34. state::borrow_mut_consumed_vaas(
  35. &latest_only,
  36. pyth_state
  37. ),
  38. receipt
  39. );
  40. let instruction = governance_instruction::from_byte_vec(payload);
  41. // Get the governance action.
  42. let action = governance_instruction::get_action(&instruction);
  43. // Dispatch the instruction to the appropriate handler.
  44. if (action == governance_action::new_contract_upgrade()) {
  45. abort(E_MUST_USE_CONTRACT_UPGRADE_MODULE_TO_DO_UPGRADES)
  46. } else if (action == governance_action::new_set_governance_data_source()) {
  47. set_governance_data_source::execute(&latest_only, pyth_state, governance_instruction::destroy(instruction));
  48. } else if (action == governance_action::new_set_data_sources()) {
  49. set_data_sources::execute(&latest_only, pyth_state, governance_instruction::destroy(instruction));
  50. } else if (action == governance_action::new_set_update_fee()) {
  51. set_update_fee::execute(&latest_only, pyth_state, governance_instruction::destroy(instruction));
  52. } else if (action == governance_action::new_set_stale_price_threshold()) {
  53. set_stale_price_threshold::execute(&latest_only, pyth_state, governance_instruction::destroy(instruction));
  54. } else if (action == governance_action::new_set_fee_recipient()) {
  55. set_fee_recipient::execute(&latest_only, pyth_state, governance_instruction::destroy(instruction));
  56. } else {
  57. governance_instruction::destroy(instruction);
  58. assert!(false, E_INVALID_GOVERNANCE_ACTION);
  59. }
  60. }
  61. }