state.move 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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 ID of the chain this contract is deployed on
  43. struct ChainID has key {
  44. chain_id: u64,
  45. }
  46. /// The last executed governance VAA sequence number
  47. struct LastExecutedGovernanceSequence has key {
  48. sequence: u64,
  49. }
  50. /// The hash of the code of the authorized contract upgrade
  51. struct ContractUpgradeAuthorized has key {
  52. hash: Hash,
  53. }
  54. // Initialization
  55. public(friend) fun init(
  56. pyth: &signer,
  57. chain_id: u64,
  58. stale_price_threshold: u64,
  59. update_fee: u64,
  60. governance_data_source: DataSource,
  61. signer_capability: account::SignerCapability) {
  62. move_to(pyth, ChainID{
  63. chain_id: chain_id,
  64. });
  65. move_to(pyth, StalePriceThreshold{
  66. threshold_secs: stale_price_threshold,
  67. });
  68. move_to(pyth, UpdateFee{
  69. fee: update_fee,
  70. });
  71. move_to(pyth, DataSources{
  72. sources: set::new<DataSource>(),
  73. });
  74. move_to(pyth, GovernanceDataSource{
  75. source: governance_data_source,
  76. });
  77. move_to(pyth, LastExecutedGovernanceSequence{
  78. sequence: 0,
  79. });
  80. move_to(pyth, SignerCapability{
  81. signer_capability: signer_capability,
  82. });
  83. move_to(pyth, LatestPriceInfo{
  84. info: table::new<PriceIdentifier, PriceInfo>(),
  85. })
  86. }
  87. // Accessors
  88. public fun get_stale_price_threshold_secs(): u64 acquires StalePriceThreshold {
  89. borrow_global<StalePriceThreshold>(@pyth).threshold_secs
  90. }
  91. public fun get_update_fee(): u64 acquires UpdateFee {
  92. borrow_global<UpdateFee>(@pyth).fee
  93. }
  94. public fun is_valid_data_source(data_source: DataSource): bool acquires DataSources {
  95. set::contains(&borrow_global<DataSources>(@pyth).sources, data_source)
  96. }
  97. public fun is_valid_governance_data_source(source: DataSource): bool acquires GovernanceDataSource {
  98. let governance_data_source = borrow_global<GovernanceDataSource>(@pyth);
  99. governance_data_source.source == source
  100. }
  101. public fun get_last_executed_governance_sequence(): u64 acquires LastExecutedGovernanceSequence {
  102. let last_executed_governance_sequence = borrow_global<LastExecutedGovernanceSequence>(@pyth);
  103. last_executed_governance_sequence.sequence
  104. }
  105. public fun price_info_cached(price_identifier: PriceIdentifier): bool acquires LatestPriceInfo {
  106. let latest_price_info = borrow_global<LatestPriceInfo>(@pyth);
  107. table::contains(&latest_price_info.info, price_identifier)
  108. }
  109. public fun get_latest_price_info(price_identifier: PriceIdentifier): PriceInfo acquires LatestPriceInfo {
  110. assert!(price_info_cached(price_identifier), error::unknown_price_feed());
  111. let latest_price_info = borrow_global<LatestPriceInfo>(@pyth);
  112. *table::borrow(&latest_price_info.info, price_identifier)
  113. }
  114. public fun get_contract_upgrade_authorized_hash(): Hash acquires ContractUpgradeAuthorized {
  115. assert!(exists<ContractUpgradeAuthorized>(@pyth), error::unauthorized_upgrade());
  116. let ContractUpgradeAuthorized { hash } = move_from<ContractUpgradeAuthorized>(@pyth);
  117. hash
  118. }
  119. public fun get_chain_id(): u64 acquires ChainID {
  120. borrow_global<ChainID>(@pyth).chain_id
  121. }
  122. // Setters
  123. public(friend) fun set_data_sources(new_sources: vector<DataSource>) acquires DataSources {
  124. let sources = &mut borrow_global_mut<DataSources>(@pyth).sources;
  125. set::empty(sources);
  126. while (!vector::is_empty(&new_sources)) {
  127. set::add(sources, vector::pop_back(&mut new_sources));
  128. }
  129. }
  130. public(friend) fun set_latest_price_info(price_identifier: PriceIdentifier, price_info: PriceInfo) acquires LatestPriceInfo {
  131. let latest_price_info = borrow_global_mut<LatestPriceInfo>(@pyth);
  132. table::upsert(&mut latest_price_info.info, price_identifier, price_info)
  133. }
  134. public(friend) fun set_last_executed_governance_sequence(sequence: u64) acquires LastExecutedGovernanceSequence {
  135. let last_executed_governance_sequence = borrow_global_mut<LastExecutedGovernanceSequence>(@pyth);
  136. last_executed_governance_sequence.sequence = sequence
  137. }
  138. public(friend) fun pyth_signer(): signer acquires SignerCapability {
  139. account::create_signer_with_capability(&borrow_global<SignerCapability>(@pyth).signer_capability)
  140. }
  141. public(friend) fun set_contract_upgrade_authorized_hash(hash: Hash) acquires ContractUpgradeAuthorized, SignerCapability {
  142. if (exists<ContractUpgradeAuthorized>(@pyth)) {
  143. let ContractUpgradeAuthorized { hash: _ } = move_from<ContractUpgradeAuthorized>(@pyth);
  144. };
  145. move_to(&pyth_signer(), ContractUpgradeAuthorized { hash });
  146. }
  147. public(friend) fun set_governance_data_source(source: DataSource) acquires GovernanceDataSource {
  148. let valid_governance_data_source = borrow_global_mut<GovernanceDataSource>(@pyth);
  149. valid_governance_data_source.source = source;
  150. }
  151. public(friend) fun set_update_fee(fee: u64) acquires UpdateFee {
  152. let update_fee = borrow_global_mut<UpdateFee>(@pyth);
  153. update_fee.fee = fee
  154. }
  155. public(friend) fun set_stale_price_threshold_secs(threshold_secs: u64) acquires StalePriceThreshold {
  156. let stale_price_threshold = borrow_global_mut<StalePriceThreshold>(@pyth);
  157. stale_price_threshold.threshold_secs = threshold_secs
  158. }
  159. }