Prechádzať zdrojové kódy

feat(target_chains/starknet): add fee configuration (#1525)

Pavel Strakhov 1 rok pred
rodič
commit
a8dbabc7f9

+ 4 - 0
target_chains/starknet/contracts/deploy/local_deploy

@@ -22,6 +22,8 @@ wormhole_hash=$(starkli declare target/dev/pyth_wormhole.contract_class.json)
 # prefunded katana account
 owner=0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03
 
+fee_token_address=0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7
+
 # deploying wormhole with mainnet guardians
 
 ${sleep}
@@ -117,6 +119,8 @@ ${sleep}
 pyth_address=$(starkli deploy "${pyth_hash}" \
     "${owner}" \
     "${wormhole_address}" \
+    "${fee_token_address}" \
+    1000 0 `# fee amount` \
     1 `# num_data_sources` \
     26 `# emitter_chain_id` \
     58051393581875729396504816158954007153 299086580781278228892874716333010393740 `# emitter_address` \

+ 30 - 12
target_chains/starknet/contracts/src/pyth.cairo

@@ -9,7 +9,10 @@ pub use pyth::{Event, PriceFeedUpdateEvent};
 pub trait IPyth<T> {
     fn get_price_unsafe(self: @T, price_id: u256) -> Result<Price, GetPriceUnsafeError>;
     fn get_ema_price_unsafe(self: @T, price_id: u256) -> Result<Price, GetPriceUnsafeError>;
-    fn set_data_sources(ref self: T, sources: Array<DataSource>) -> Result<(), SetDataSourcesError>;
+    fn set_data_sources(
+        ref self: T, sources: Array<DataSource>
+    ) -> Result<(), GovernanceActionError>;
+    fn set_fee(ref self: T, single_update_fee: u256) -> Result<(), GovernanceActionError>;
     fn update_price_feeds(ref self: T, data: ByteArray) -> Result<(), UpdatePriceFeedsError>;
 }
 
@@ -35,14 +38,13 @@ impl GetPriceUnsafeErrorIntoFelt252 of Into<GetPriceUnsafeError, felt252> {
     }
 }
 
-
 #[derive(Copy, Drop, Debug, Serde, PartialEq)]
-pub enum SetDataSourcesError {
+pub enum GovernanceActionError {
     AccessDenied,
 }
 
-pub impl SetDataSourcesErrorUnwrapWithFelt252<T> of UnwrapWithFelt252<T, SetDataSourcesError> {
-    fn unwrap_with_felt252(self: Result<T, SetDataSourcesError>) -> T {
+pub impl GovernanceActionErrorUnwrapWithFelt252<T> of UnwrapWithFelt252<T, GovernanceActionError> {
+    fn unwrap_with_felt252(self: Result<T, GovernanceActionError>) -> T {
         match self {
             Result::Ok(v) => v,
             Result::Err(err) => core::panic_with_felt252(err.into()),
@@ -50,10 +52,10 @@ pub impl SetDataSourcesErrorUnwrapWithFelt252<T> of UnwrapWithFelt252<T, SetData
     }
 }
 
-impl SetDataSourcesErrorIntoFelt252 of Into<SetDataSourcesError, felt252> {
-    fn into(self: SetDataSourcesError) -> felt252 {
+impl GovernanceActionErrorIntoFelt252 of Into<GovernanceActionError, felt252> {
+    fn into(self: GovernanceActionError) -> felt252 {
         match self {
-            SetDataSourcesError::AccessDenied => 'access denied',
+            GovernanceActionError::AccessDenied => 'access denied',
         }
     }
 }
@@ -116,10 +118,10 @@ mod pyth {
     use pyth::reader::{Reader, ReaderImpl};
     use pyth::byte_array::{ByteArray, ByteArrayImpl};
     use core::panic_with_felt252;
-    use core::starknet::{ContractAddress, get_caller_address};
+    use core::starknet::{ContractAddress, get_caller_address, get_execution_info};
     use pyth::wormhole::{IWormholeDispatcher, IWormholeDispatcherTrait};
     use super::{
-        DataSource, UpdatePriceFeedsError, PriceInfo, SetDataSourcesError, Price,
+        DataSource, UpdatePriceFeedsError, PriceInfo, GovernanceActionError, Price,
         GetPriceUnsafeError
     };
     use pyth::merkle_tree::{read_and_verify_proof, MerkleVerificationError};
@@ -220,6 +222,8 @@ mod pyth {
     #[storage]
     struct Storage {
         wormhole_address: ContractAddress,
+        fee_contract_address: ContractAddress,
+        single_update_fee: u256,
         owner: ContractAddress,
         data_sources: LegacyMap<usize, DataSource>,
         num_data_sources: usize,
@@ -233,10 +237,14 @@ mod pyth {
         ref self: ContractState,
         owner: ContractAddress,
         wormhole_address: ContractAddress,
+        fee_contract_address: ContractAddress,
+        single_update_fee: u256,
         data_sources: Array<DataSource>
     ) {
         self.owner.write(wormhole_address);
         self.wormhole_address.write(wormhole_address);
+        self.fee_contract_address.write(fee_contract_address);
+        self.single_update_fee.write(single_update_fee);
         write_data_sources(ref self, data_sources);
     }
 
@@ -308,14 +316,24 @@ mod pyth {
 
         fn set_data_sources(
             ref self: ContractState, sources: Array<DataSource>
-        ) -> Result<(), SetDataSourcesError> {
+        ) -> Result<(), GovernanceActionError> {
             if self.owner.read() != get_caller_address() {
-                return Result::Err(SetDataSourcesError::AccessDenied);
+                return Result::Err(GovernanceActionError::AccessDenied);
             }
             write_data_sources(ref self, sources);
             Result::Ok(())
         }
 
+        fn set_fee(
+            ref self: ContractState, single_update_fee: u256
+        ) -> Result<(), GovernanceActionError> {
+            if self.owner.read() != get_caller_address() {
+                return Result::Err(GovernanceActionError::AccessDenied);
+            }
+            self.single_update_fee.write(single_update_fee);
+            Result::Ok(())
+        }
+
         fn update_price_feeds(
             ref self: ContractState, data: ByteArray
         ) -> Result<(), UpdatePriceFeedsError> {

+ 9 - 2
target_chains/starknet/contracts/tests/pyth.cairo

@@ -35,6 +35,8 @@ fn update_price_feeds_works() {
     let pyth = deploy(
         owner,
         wormhole.contract_address,
+        0x42.try_into().unwrap(),
+        1000,
         array![
             DataSource {
                 emitter_chain_id: 26,
@@ -78,10 +80,15 @@ fn update_price_feeds_works() {
 }
 
 fn deploy(
-    owner: ContractAddress, wormhole_address: ContractAddress, data_sources: Array<DataSource>
+    owner: ContractAddress,
+    wormhole_address: ContractAddress,
+    fee_contract_address: ContractAddress,
+    single_update_fee: u256,
+    data_sources: Array<DataSource>
 ) -> IPythDispatcher {
     let mut args = array![];
-    (owner, wormhole_address, data_sources).serialize(ref args);
+    (owner, wormhole_address, fee_contract_address, single_update_fee).serialize(ref args);
+    data_sources.serialize(ref args);
     let contract = declare("pyth");
     let contract_address = match contract.deploy(@args) {
         Result::Ok(v) => { v },