state.move 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. module pyth::state {
  2. use pyth::price_identifier::PriceIdentifier;
  3. use pyth::contract_upgrade_hash::Hash;
  4. use pyth::data_source::DataSource;
  5. use pyth::price_info::PriceInfo;
  6. use std::table::{Self, Table};
  7. use pyth::set::{Self, Set};
  8. use std::vector;
  9. use pyth::error;
  10. use std::account;
  11. friend pyth::pyth;
  12. friend pyth::governance;
  13. friend pyth::contract_upgrade;
  14. friend pyth::set_governance_data_source;
  15. friend pyth::set_update_fee;
  16. friend pyth::set_stale_price_threshold;
  17. friend pyth::set_data_sources;
  18. /// The valid data sources an attestation VAA can be emitted from
  19. struct DataSources has key {
  20. sources: Set<DataSource>,
  21. }
  22. /// How long a cached price is considered valid for
  23. struct StalePriceThreshold has key {
  24. threshold_secs: u64,
  25. }
  26. /// The fee charged per batch update
  27. struct UpdateFee has key {
  28. fee: u64,
  29. }
  30. /// The Pyth contract signer capability
  31. struct SignerCapability has key {
  32. signer_capability: account::SignerCapability,
  33. }
  34. /// Mapping of cached price information
  35. struct LatestPriceInfo has key {
  36. info: Table<PriceIdentifier, PriceInfo>,
  37. }
  38. /// The allowed data source for governance VAAs
  39. struct GovernanceDataSource has key {
  40. source: DataSource,
  41. }
  42. /// The last executed governance VAA sequence number
  43. struct LastExecutedGovernanceSequence has key {
  44. sequence: u64,
  45. }
  46. /// The hash of the code of the authorized contract upgrade
  47. struct ContractUpgradeAuthorized has key {
  48. hash: Hash,
  49. }
  50. // Initialization
  51. public(friend) fun init(
  52. pyth: &signer,
  53. stale_price_threshold: u64,
  54. update_fee: u64,
  55. governance_data_source: DataSource,
  56. data_sources: vector<DataSource>,
  57. signer_capability: account::SignerCapability) {
  58. move_to(pyth, StalePriceThreshold{
  59. threshold_secs: stale_price_threshold,
  60. });
  61. move_to(pyth, UpdateFee{
  62. fee: update_fee,
  63. });
  64. let sources = set::new<DataSource>();
  65. while (!vector::is_empty(&data_sources)) {
  66. set::add(&mut sources, vector::pop_back(&mut data_sources));
  67. };
  68. move_to(pyth, DataSources{
  69. sources,
  70. });
  71. move_to(pyth, GovernanceDataSource{
  72. source: governance_data_source,
  73. });
  74. move_to(pyth, LastExecutedGovernanceSequence{
  75. sequence: 0,
  76. });
  77. move_to(pyth, SignerCapability{
  78. signer_capability: signer_capability,
  79. });
  80. move_to(pyth, LatestPriceInfo{
  81. info: table::new<PriceIdentifier, PriceInfo>(),
  82. });
  83. }
  84. // Accessors
  85. public fun get_stale_price_threshold_secs(): u64 acquires StalePriceThreshold {
  86. borrow_global<StalePriceThreshold>(@pyth).threshold_secs
  87. }
  88. public fun get_update_fee(): u64 acquires UpdateFee {
  89. borrow_global<UpdateFee>(@pyth).fee
  90. }
  91. public fun is_valid_data_source(data_source: DataSource): bool acquires DataSources {
  92. set::contains(&borrow_global<DataSources>(@pyth).sources, data_source)
  93. }
  94. public fun is_valid_governance_data_source(source: DataSource): bool acquires GovernanceDataSource {
  95. let governance_data_source = borrow_global<GovernanceDataSource>(@pyth);
  96. governance_data_source.source == source
  97. }
  98. public fun get_last_executed_governance_sequence(): u64 acquires LastExecutedGovernanceSequence {
  99. let last_executed_governance_sequence = borrow_global<LastExecutedGovernanceSequence>(@pyth);
  100. last_executed_governance_sequence.sequence
  101. }
  102. public fun price_info_cached(price_identifier: PriceIdentifier): bool acquires LatestPriceInfo {
  103. let latest_price_info = borrow_global<LatestPriceInfo>(@pyth);
  104. table::contains(&latest_price_info.info, price_identifier)
  105. }
  106. public fun get_latest_price_info(price_identifier: PriceIdentifier): PriceInfo acquires LatestPriceInfo {
  107. assert!(price_info_cached(price_identifier), error::unknown_price_feed());
  108. let latest_price_info = borrow_global<LatestPriceInfo>(@pyth);
  109. *table::borrow(&latest_price_info.info, price_identifier)
  110. }
  111. public fun get_contract_upgrade_authorized_hash(): Hash acquires ContractUpgradeAuthorized {
  112. assert!(exists<ContractUpgradeAuthorized>(@pyth), error::unauthorized_upgrade());
  113. let ContractUpgradeAuthorized { hash } = move_from<ContractUpgradeAuthorized>(@pyth);
  114. hash
  115. }
  116. // Setters
  117. public(friend) fun set_data_sources(new_sources: vector<DataSource>) acquires DataSources {
  118. let sources = &mut borrow_global_mut<DataSources>(@pyth).sources;
  119. set::empty(sources);
  120. while (!vector::is_empty(&new_sources)) {
  121. set::add(sources, vector::pop_back(&mut new_sources));
  122. }
  123. }
  124. public(friend) fun set_latest_price_info(price_identifier: PriceIdentifier, price_info: PriceInfo) acquires LatestPriceInfo {
  125. let latest_price_info = borrow_global_mut<LatestPriceInfo>(@pyth);
  126. table::upsert(&mut latest_price_info.info, price_identifier, price_info)
  127. }
  128. public(friend) fun set_last_executed_governance_sequence(sequence: u64) acquires LastExecutedGovernanceSequence {
  129. let last_executed_governance_sequence = borrow_global_mut<LastExecutedGovernanceSequence>(@pyth);
  130. last_executed_governance_sequence.sequence = sequence
  131. }
  132. public(friend) fun pyth_signer(): signer acquires SignerCapability {
  133. account::create_signer_with_capability(&borrow_global<SignerCapability>(@pyth).signer_capability)
  134. }
  135. public(friend) fun set_contract_upgrade_authorized_hash(hash: Hash) acquires ContractUpgradeAuthorized, SignerCapability {
  136. if (exists<ContractUpgradeAuthorized>(@pyth)) {
  137. let ContractUpgradeAuthorized { hash: _ } = move_from<ContractUpgradeAuthorized>(@pyth);
  138. };
  139. move_to(&pyth_signer(), ContractUpgradeAuthorized { hash });
  140. }
  141. public(friend) fun set_governance_data_source(source: DataSource) acquires GovernanceDataSource {
  142. let valid_governance_data_source = borrow_global_mut<GovernanceDataSource>(@pyth);
  143. valid_governance_data_source.source = source;
  144. }
  145. public(friend) fun set_update_fee(fee: u64) acquires UpdateFee {
  146. let update_fee = borrow_global_mut<UpdateFee>(@pyth);
  147. update_fee.fee = fee
  148. }
  149. public(friend) fun set_stale_price_threshold_secs(threshold_secs: u64) acquires StalePriceThreshold {
  150. let stale_price_threshold = borrow_global_mut<StalePriceThreshold>(@pyth);
  151. stale_price_threshold.threshold_secs = threshold_secs
  152. }
  153. }