diff --git a/src/oracle/oracle.cairo b/src/oracle/oracle.cairo index 2957ad7b..768f59b5 100644 --- a/src/oracle/oracle.cairo +++ b/src/oracle/oracle.cairo @@ -37,57 +37,7 @@ trait IOracle { pragma_address: ContractAddress, ); - /// Validate and store signed prices - /// - /// The set_prices function is used to set the prices of tokens in the Oracle contract. - /// It accepts an array of tokens and a signer_info parameter. The signer_info parameter - /// contains information about the signers that have signed the transaction to set the prices. - /// The first 16 bits of the signer_info parameter contain the number of signers, and the following - /// bits contain the index of each signer in the oracle_store. The function checks that the number - /// of signers is greater than or equal to the minimum number of signers required, and that - /// the signer indices are unique and within the maximum signer index. The function then calls - /// set_primary_prices and set_prices_from_price_feeds to set the prices of the tokens. - /// - /// Oracle prices are signed as a value together with a precision, this allows - /// prices to be compacted as uint32 values. - /// - /// The signed prices represent the price of one unit of the token using a value - /// with 30 decimals of precision. - /// - /// # Arguments - /// * `data_store` - The data store. - /// * `event_emitter` - The event emitter. - /// * `params` - The set price params. - fn set_prices( - ref self: TContractState, - data_store: IDataStoreDispatcher, - event_emitter: IEventEmitterDispatcher, - params: SetPricesParams, - ); - - /// Set the primary price - /// # Arguments - /// * `token` - The token to set the price for. - /// * `price` - The price value to set to. - fn set_primary_price(ref self: TContractState, token: ContractAddress, price: Price); - - /// Clear all prices - fn clear_all_prices(ref self: TContractState); - - /// Get the length of tokens_with_prices - /// # Returns - /// The length of tokens_with_prices - fn get_tokens_with_prices_count(self: @TContractState) -> u32; - - /// Get the tokens_with_prices from start to end. - /// # Arguments - /// * `start` - The start index, the value for this index will be included. - /// * `end` - The end index, the value for this index will be excluded. - /// # Returns - /// The tokens of tokens_with_prices for the specified indexes. - fn get_tokens_with_prices( - self: @TContractState, start: u32, end: u32 - ) -> Array; + fn set_primary_prices(ref self: TContractState, token: ContractAddress, price: u256); /// Get the primary price of a token. /// # Arguments @@ -96,40 +46,8 @@ trait IOracle { /// The primary price of a token. fn get_primary_price(self: @TContractState, token: ContractAddress) -> Price; - /// Get the stable price of a token. - /// # Arguments - /// * `token` - The token to get the price for. - /// # Returns - /// The stable price of a token. - fn get_stable_price( - self: @TContractState, data_store: IDataStoreDispatcher, token: ContractAddress - ) -> u256; - - /// Get the multiplier value to convert the external price feed price to the price of 1 unit of the token - /// represented with 30 decimals. - /// For example, if USDC has 6 decimals and a price of 1 USD, one unit of USDC would have a price of - /// 1 / (10 ^ 6) * (10 ^ 30) => 1 * (10 ^ 24) - /// if the external price feed has 8 decimals, the price feed price would be 1 * (10 ^ 8) - /// in this case the priceFeedMultiplier should be 10 ^ 46 - /// the conversion of the price feed price would be 1 * (10 ^ 8) * (10 ^ 46) / (10 ^ 30) => 1 * (10 ^ 24) - /// formula for decimals for price feed multiplier: 60 - (external price feed decimals) - (token decimals) - /// # Arguments - /// * `data_store` - The data store dispatcher. - /// * `token` - The token to get the price for. - /// # Returns - /// The price feed multiplier. - fn get_price_feed_multiplier( - self: @TContractState, data_store: IDataStoreDispatcher, token: ContractAddress, - ) -> u256; - fn set_price_testing_eth(ref self: TContractState, new_price: u256); - /// Validate prices in `params` for oracles. - /// # Arguments - /// * `data_store` - The `DataStore` contract dispatcher. - /// * `params` - The parameters used to set prices in oracle. - fn validate_prices( - self: @TContractState, data_store: IDataStoreDispatcher, params: SetPricesParams, - ) -> Array; + } /// A price that has been validated in validate_prices(). @@ -273,7 +191,6 @@ mod Oracle { self.initialize(role_store_address, oracle_store_address, pragma_address); } - // ************************************************************************* // EXTERNAL FUNCTIONS // ************************************************************************* @@ -296,97 +213,13 @@ mod Oracle { self.price_feed.write(IPriceFeedDispatcher { contract_address: pragma_address }); } - fn set_prices( - ref self: ContractState, - data_store: IDataStoreDispatcher, - event_emitter: IEventEmitterDispatcher, - params: SetPricesParams, - ) { - let state: RoleModule::ContractState = RoleModule::unsafe_new_contract_state(); - IRoleModule::only_controller(@state); - let tokens_with_prices_len = self.tokens_with_prices.read().len(); - if !tokens_with_prices_len.is_zero() { - OracleError::NON_EMPTY_TOKENS_WITH_PRICES(tokens_with_prices_len); - }; - - self.set_prices_from_price_feeds(data_store, event_emitter, @params.price_feed_tokens); - // it is possible for transactions to be executed using just params.priceFeedTokens - // in this case if params.tokens is empty, the function can return - if params.tokens.len().is_zero() { - return; - } - - self.set_prices_(data_store, event_emitter, params); - } - - // Set the primary price - // Arguments - // * `token` - The token to set the price for. - // * `price` - The price value to set to. - fn set_primary_price(ref self: ContractState, token: ContractAddress, price: Price,) { - let state: RoleModule::ContractState = RoleModule::unsafe_new_contract_state(); - IRoleModule::only_controller(@state); - self.set_primary_price_(token, price); - } - // Only for testing fn set_price_testing_eth(ref self: ContractState, new_price: u256) { self.eth_price.write(Price { min: new_price, max: new_price }) } - fn clear_all_prices(ref self: ContractState) { - let state: RoleModule::ContractState = RoleModule::unsafe_new_contract_state(); - IRoleModule::only_controller(@state); - loop { - if self.tokens_with_prices.read().len() == Zeroable::zero() { - break; - } - let token = self.tokens_with_prices.read().get(0).expect('array get failed'); - self.remove_primary_price(token); - }; - self.tokens_with_prices.read().len().print(); - } - - - fn get_tokens_with_prices_count(self: @ContractState) -> u32 { - let token_with_prices = self.tokens_with_prices.read(); - let tokens_with_prices_len = token_with_prices.len(); - let mut count = 0; - let mut i = 0; - loop { - if i == tokens_with_prices_len { - break; - } - if !token_with_prices.get(i).expect('array get failed').is_zero() { - count += 1; - } - i += 1; - }; - count - } - - fn get_tokens_with_prices( - self: @ContractState, start: u32, mut end: u32 - ) -> Array { - let mut arr: Array = array![]; - let tokens_with_prices = self.tokens_with_prices.read(); - let tokens_with_prices_len = tokens_with_prices.len(); - if end > tokens_with_prices_len { - end = tokens_with_prices_len; - } - if tokens_with_prices.len().is_zero() { - return arr; - } - let mut arr: Array = array![]; - let mut index = start; - loop { - if index >= end { - break; - } - arr.append(tokens_with_prices[index]); - index += 1; - }; - arr + fn set_primary_prices(ref self: ContractState, token: ContractAddress, price: u256) { + self.primary_prices.write(token, Price { min: price, max: price }); } fn get_primary_price(self: @ContractState, token: ContractAddress) -> Price { @@ -394,41 +227,12 @@ mod Oracle { return Price { min: 0, max: 0 }; } let price = self.primary_prices.read(token); - if token == contract_address_const::<'ETH'>() { - return self.eth_price.read(); - } - if token == contract_address_const::<'USDC'>() { - return Price { min: 1, max: 1 }; - } + if price.is_zero() { OracleError::EMPTY_PRIMARY_PRICE(); } price } - - - fn get_stable_price( - self: @ContractState, data_store: IDataStoreDispatcher, token: ContractAddress - ) -> u256 { - data_store.get_u256(keys::stable_price_key(token)) - } - - fn get_price_feed_multiplier( - self: @ContractState, data_store: IDataStoreDispatcher, token: ContractAddress, - ) -> u256 { - let multiplier = data_store.get_u256(keys::price_feed_multiplier_key(token)); - - if multiplier.is_zero() { - OracleError::EMPTY_PRICE_FEED_MULTIPLIER(); - } - multiplier - } - - fn validate_prices( - self: @ContractState, data_store: IDataStoreDispatcher, params: SetPricesParams, - ) -> Array { - self.validate_prices_(data_store, params) - } } // ************************************************************************* @@ -436,562 +240,7 @@ mod Oracle { // ************************************************************************* #[generate_trait] impl InternalImpl of InternalTrait { - /// Validate and set prices. - /// The _set_prices() function is a helper function that is called by the - /// setPrices() function. It takes in several parameters: a DataStore contract - /// instance, an EventEmitter contract instance, an array of signers, and an - /// OracleUtils.SetPricesParams struct containing information about the tokens - /// and their prices. - /// The function first initializes a SetPricesCache struct to store some temporary - /// values that will be used later in the function. It then loops through the array - /// of tokens and sets the corresponding values in the cache struct. For each token, - /// the function also loops through the array of signers and validates the signatures - /// for the min and max prices for that token. If the signatures are valid, the - /// function calculates the median min and max prices and sets them in the DataStore - /// contract. - /// Finally, the function emits an event to signal that the prices have been set. - /// # Arguments - /// * `data_store` - The data store. - /// * `event_emitter` - The event emitter. - /// * `params` - The set price params. - fn set_prices_( - ref self: ContractState, - data_store: IDataStoreDispatcher, - event_emitter: IEventEmitterDispatcher, - params: SetPricesParams, - ) { - let validated_prices = self.validate_prices(data_store, params); - - let mut len = 0; - loop { - if len == validated_prices.len() { - break; - } - - let validated_price = *validated_prices.at(len); - if !self.primary_prices.read(validated_price.token).is_zero() { - OracleError::DUPLICATED_TOKEN_PRICE(); - } - self - .emit_oracle_price_updated( - event_emitter, - validated_price.token, - validated_price.min, - validated_price.max, - false - ); - self - .set_primary_price_( - validated_price.token, - Price { min: validated_price.min, max: validated_price.max } - ); - len += 1; - }; - } - - /// Validate prices in params. - /// # Arguments - /// * `data_store` - The data store. - /// * `params` - The set price params. - fn validate_prices_( - self: @ContractState, data_store: IDataStoreDispatcher, params: SetPricesParams, - ) -> Array { - let signers = self.get_signers_(data_store, @params); - - let mut cache: SetPricesCache = Default::default(); - cache - .min_block_confirmations = data_store - .get_u256(keys::min_oracle_block_confirmations()) - .try_into() - .expect('get_u256 into u64 failed'); - - cache - .max_price_age = data_store - .get_u256(keys::max_oracle_price_age()) - .try_into() - .expect('get_u256 into u64 failed'); - - cache - .max_ref_price_deviation_factor = data_store - .get_u256(keys::max_oracle_ref_price_deviation_factor()); - - let mut i = 0; - loop { - let mut report_info: ReportInfo = Default::default(); - let mut inner_cache: SetPricesInnerCache = Default::default(); - if i == params.tokens.len() { - break; - } - - report_info - .min_oracle_block_number = - oracle_utils::get_uncompacted_oracle_block_number( - params.compacted_min_oracle_block_numbers.span(), i.into() - ); - - report_info - .max_oracle_block_number = - oracle_utils::get_uncompacted_oracle_block_number( - params.compacted_max_oracle_block_numbers.span(), i.into() - ); - - if report_info.min_oracle_block_number > report_info.max_oracle_block_number { - OracleError::INVALID_MIN_MAX_BLOCK_NUMBER( - report_info.min_oracle_block_number, report_info.max_oracle_block_number - ); - } - - report_info - .oracle_timestamp = - oracle_utils::get_uncompacted_oracle_timestamp( - params.compacted_oracle_timestamps.span(), i - ); - if report_info.min_oracle_block_number > get_block_number() { - OracleError::INVALID_BLOCK_NUMBER( - report_info.min_oracle_block_number, get_block_number() - ); - } - - if report_info.oracle_timestamp + cache.max_price_age < get_block_timestamp() { - OracleError::MAX_PRICE_EXCEEDED( - report_info.oracle_timestamp, get_block_timestamp() - ); - } - - if report_info.min_oracle_block_number < cache.prev_min_oracle_block_number { - OracleError::BLOCK_NUMBER_NOT_SORTED( - report_info.min_oracle_block_number, cache.prev_min_oracle_block_number - ); - } - - cache.prev_min_oracle_block_number = report_info.min_oracle_block_number; - - if get_block_number() - - report_info.max_oracle_block_number <= cache.min_block_confirmations { - report_info - .block_hash = get_block_hash_syscall(report_info.max_oracle_block_number) - .unwrap_syscall(); - } - - report_info.token = *params.tokens.at(i); - - report_info - .precision = - pow( - 10, - oracle_utils::get_uncompacted_decimal( - params.compacted_decimals.span(), i.into() - ) - .try_into() - .expect('u256 into u32 failed') - ); - - report_info - .token_oracle_type = data_store - .get_felt252(keys::oracle_type_key(report_info.token)); - - let mut j = 0; - let signers_len = signers.len(); - let compacted_min_prices_span = params.compacted_min_prices.span(); - let compacted_max_prices_span = params.compacted_max_prices.span(); - loop { - if j == signers_len { - break; - } - inner_cache.price_index = (i * signers_len + j).into(); - inner_cache - .min_prices - .append( - oracle_utils::get_uncompacted_price( - compacted_min_prices_span, inner_cache.price_index - ) - ); - - inner_cache - .max_prices - .append( - oracle_utils::get_uncompacted_price( - compacted_max_prices_span, inner_cache.price_index - ) - ); - if j != 0 { - if *inner_cache.min_prices.at(j - 1) > *inner_cache.min_prices.at(j) { - OracleError::MIN_PRICES_NOT_SORTED( - report_info.token, - *inner_cache.min_prices.at(j), - *inner_cache.min_prices.at(j - 1) - ); - } - - if *inner_cache.max_prices.at(j - 1) > *inner_cache.max_prices.at(j) { - OracleError::MAX_PRICES_NOT_SORTED( - report_info.token, - *inner_cache.max_prices.at(j), - *inner_cache.max_prices.at(j - 1) - ); - } - } - j += 1; - }; - - let compacted_min_indexes_span = params.compacted_min_prices_indexes.span(); - let compacted_max_indexes_span = params.compacted_max_prices_indexes.span(); - let inner_cache_save = @inner_cache; - let signatures_span = params.signatures.span(); - let signers_span = signers.span(); - let mut j = 0; - loop { - if j == signers_len { - break; - } - - inner_cache.signature_index = (i * signers_len + j).into(); - - inner_cache - .min_price_index = - oracle_utils::get_uncompacted_price_index( - compacted_min_indexes_span, inner_cache.signature_index - ); - inner_cache - .max_price_index = - oracle_utils::get_uncompacted_price_index( - compacted_max_indexes_span, inner_cache.signature_index - ); - if inner_cache.signature_index >= signatures_span.len() { - OracleError::ARRAY_OUT_OF_BOUNDS_FELT252( - signatures_span, inner_cache.signature_index, 'signatures' - ); - } - if inner_cache.min_price_index >= inner_cache.min_prices.len().into() { - OracleError::ARRAY_OUT_OF_BOUNDS_U256( - inner_cache.min_prices.span(), inner_cache.min_price_index, 'min_prices' - ); - } - - if inner_cache.max_price_index >= inner_cache.max_prices.len().into() { - OracleError::ARRAY_OUT_OF_BOUNDS_U256( - inner_cache.max_prices.span(), inner_cache.max_price_index, 'max_prices' - ); - } - - // since minPrices, maxPrices have the same length as the signers array - // and the signers array length is less than MAX_SIGNERS - // minPriceIndexMask and maxPriceIndexMask should be able to store the indexes - // using Uint256Mask - validate_unique_and_set_index( - ref inner_cache.min_price_index_mask, inner_cache.min_price_index - ); - - validate_unique_and_set_index( - ref inner_cache.max_price_index_mask, inner_cache.max_price_index - ); - - report_info - .min_price = *inner_cache - .min_prices - .at(inner_cache.min_price_index.try_into().expect('array at failed')); - - report_info - .max_price = *inner_cache - .max_prices - .at(inner_cache.max_price_index.try_into().expect('array at failed')); - - if report_info.min_price > report_info.max_price { - OracleError::INVALID_SIGNER_MIN_MAX_PRICE( - report_info.min_price, report_info.max_price - ); - } - // oracle_utils::validate_signer( - // self.get_salt(), - // report_info, - // *signatures_span.at(inner_cache.signature_index), - // signers_span.at(j) - // ); - - j += 1; - }; - - let median_min_price = arrays::get_median(inner_cache_save.min_prices.span()) - * report_info.precision; - - let median_max_price = arrays::get_median(inner_cache_save.max_prices.span()) - * report_info.precision; - - let (has_price_feed, ref_price) = self - .get_price_feed_price(data_store, report_info.token); - - if has_price_feed { - self - .validate_ref_price( - report_info.token, - median_min_price, - ref_price, - cache.max_ref_price_deviation_factor - ); - - self - .validate_ref_price( - report_info.token, - median_max_price, - ref_price, - cache.max_ref_price_deviation_factor - ); - } - - if median_min_price.is_zero() || median_max_price.is_zero() { - OracleError::INVALID_ORACLE_PRICE(report_info.token); - } - - if median_min_price > median_max_price { - OracleError::INVALID_MEDIAN_MIN_MAX_PRICE(median_min_price, median_max_price); - } - - let validated_price = ValidatedPrice { - token: report_info.token, - min: median_min_price, - max: median_max_price, - timestamp: report_info.oracle_timestamp, - min_block_number: report_info.min_oracle_block_number, - max_block_number: report_info.max_oracle_block_number - }; - - cache.validated_prices.append(validated_price); - - i += 1; - }; - cache.validated_prices - } - - /// Get the signers - /// # Arguments - /// * `data_store` - The data store dispatcher. - /// * `token` - The token to get the price for. - /// # Returns - /// The signers - fn get_signers_( - self: @ContractState, data_store: IDataStoreDispatcher, params: @SetPricesParams, - ) -> Array { - let mut signers: Array = array![]; - - let signers_len = *params.signer_info & bits::BITMASK_16; - if signers_len < data_store.get_u256(keys::min_oracle_signers()) { - OracleError::MIN_ORACLE_SIGNERS( - signers_len, data_store.get_u256(keys::min_oracle_signers()) - ); - } - - if signers_len > MAX_SIGNERS { - OracleError::MAX_ORACLE_SIGNERS(signers_len, MAX_SIGNERS); - } - - let mut signers_index_mask = Mask { bits: 0 }; - - let mut len = 0; - loop { - if len == signers_len { - break; - } - - let signer_index: u256 = BitShift::shr( - *params.signer_info, (8 + 8 * len) & bits::BITMASK_16 - ); - - if signer_index >= MAX_SIGNER_INDEX { - OracleError::MAX_SIGNERS_INDEX(signer_index, MAX_SIGNER_INDEX); - } - - signers_index_mask.validate_unique_and_set_index(signer_index); - - signers - .append( - self - .oracle_store - .read() - .get_signer(signer_index.try_into().expect('u256 into u32 failed')) - ); - - if (*signers.at(len.try_into().expect('u256 into u32 failed'))).is_zero() { - OracleError::EMPTY_SIGNER(signer_index); - } - - len += 1; - }; - - signers - } - - /// Compute a salt for validate_signer(). - /// # Returns - /// The computed salt. - fn get_salt(self: @ContractState,) -> felt252 { - let data: Array = array![ - starknet::info::get_tx_info().unbox().chain_id, 'xget-oracle-v1' - ]; - poseidon_hash_span(data.span()) - } - - /// Validate that price does not deviate too much from ref_price. - /// # Arguments - /// * `token` - The token the price is check from. - /// * `price` - The price to validate. - /// * `ref_price` - The reference price. - /// * `max_ref_price_deviation_from_factor` - The max ref_price deviation factor allowed. - fn validate_ref_price( - self: @ContractState, - token: ContractAddress, - price: u256, - ref_price: u256, - max_ref_price_deviation_factor: u256, - ) { - let diff = calc::diff(price, ref_price); - - let diff_factor = precision::to_factor(diff, ref_price); - if diff_factor > max_ref_price_deviation_factor { - OracleError::MAX_REFPRICE_DEVIATION_EXCEEDED( - token, price, ref_price, max_ref_price_deviation_factor - ); - } - } - - /// Set the primary price. - /// # Arguments - /// * `token` - The token to set the price for. - /// * `price` - The price value to set to. - fn set_primary_price_(ref self: ContractState, token: ContractAddress, price: Price) { - match self.get_token_with_price_index(token) { - Option::Some(i) => (), - Option::None(_) => { - self.primary_prices.write(token, price); - - let mut tokens_with_prices = self.tokens_with_prices.read(); - let index_of_zero = self.get_token_with_price_index(Zeroable::zero()); - // If an entry with zero address is found the entry is set to the new token, - // otherwise the new token is appended to the list. This is to avoid the list - // to grow indefinitely. - match index_of_zero { - Option::Some(i) => { tokens_with_prices.set(i, token); }, - Option::None => { tokens_with_prices.append(token); } - } - } - } - } - - /// Remove the primary price. - /// # Arguments - /// * `token` - The token to set the price for. - fn remove_primary_price(ref self: ContractState, token: ContractAddress) { - self.primary_prices.write(token, Zeroable::zero()); - let mut tokens_prices = self.tokens_with_prices.read(); - tokens_prices.pop_front(); - self.tokens_with_prices.write(tokens_prices); - } - - /// Get the price feed prices. - /// There is a small risk of stale pricing due to latency in price updates or if the chain is down. - /// This is meant to be for temporary use until low latency price feeds are supported for all tokens. - /// # Arguments - /// * `data_store` - The data store. - /// * `token` - The token to get the price for. - /// # Returns - /// The price feed multiplier. - fn get_price_feed_price( - self: @ContractState, data_store: IDataStoreDispatcher, token: ContractAddress, - ) -> (bool, u256) { - let token_id = data_store.get_token_id(token); - if token_id == 0 { - return (false, 0); - } - let response = self.price_feed.read().get_data_median(DataType::SpotEntry(token_id)); - - if response.price <= 0 { - OracleError::INVALID_PRICE_FEED(token, response.price); - } - - let heart_beat_duration = data_store - .get_u256(keys::price_feed_heartbeat_duration_key(token)); - - let current_timestamp = get_block_timestamp(); - if current_timestamp > response.last_updated_timestamp && current_timestamp - - response - .last_updated_timestamp > heart_beat_duration - .try_into() - .expect('u256 into u32 failed') { - OracleError::PRICE_FEED_NOT_UPDATED( - token, response.last_updated_timestamp, heart_beat_duration - ); - } - - let precision_ = self.get_price_feed_multiplier(data_store, token); - let adjusted_price = precision::mul_div( - response.price, precision_, precision::FLOAT_PRECISION - ); - - (true, adjusted_price) - } - - /// Set prices using external price feeds to save costs for tokens with stable prices. - /// # Arguments - /// * `data_store` - The data store. - /// * `event_emitter` - The event emitter. - /// * `price_feed_tokens` - The tokens to set the prices using the price feeds for. - fn set_prices_from_price_feeds( - ref self: ContractState, - data_store: IDataStoreDispatcher, - event_emitter: IEventEmitterDispatcher, - price_feed_tokens: @Array, - ) { - let self_copy = @self; - let mut len = 0; - - loop { - if len == price_feed_tokens.len() { - break; - } - - let token = *price_feed_tokens.at(len); - - let stored_price = self.primary_prices.read(token); - if !stored_price.is_zero() { - OracleError::PRICE_ALREADY_SET(token, stored_price.min, stored_price.max); - } - - let (has_price_feed, price) = self_copy.get_price_feed_price(data_store, token); - - if (!has_price_feed) { - OracleError::EMPTY_PRICE_FEED(token); - } - - let stable_price = self.get_stable_price(data_store, token); - - let mut price_props: Price = Zeroable::zero(); - - if !stable_price.is_zero() { - price_props = - Price { - min: if price < stable_price { - price - } else { - stable_price - }, - max: if price < stable_price { - stable_price - } else { - price - } - } - } else { - price_props = Price { min: price, max: price } - } - - self.set_primary_price_(token, price_props); - - self - .emit_oracle_price_updated( - event_emitter, token, price_props.min, price_props.max, true - ); - len += 1; - }; - } + /// Emits an `OraclePriceUpdated` event for a specific token. /// # Parameters /// * `event_emitter`: Dispatcher used for emitting events. @@ -1009,36 +258,6 @@ mod Oracle { ) { event_emitter.emit_oracle_price_updated(token, min_price, max_price, is_price_feed); } - - /// Returns the index of a given `token` in the `tokens_with_prices` list. - /// # Arguments - /// * `token` - A `ContractAddress` representing the token whose index we want to find. - /// # Returns - /// * `Option` - Returns `Some(index)` if the token is found. - /// Returns `None` if the token is not found. - fn get_token_with_price_index( - self: @ContractState, token: ContractAddress - ) -> Option { - let mut tokens_with_prices = self.tokens_with_prices.read(); - let mut index = Option::None; - let mut len = 0; - loop { - if len == tokens_with_prices.len() { - break; - } - let token_with_price = tokens_with_prices.get(len); - match token_with_price { - Option::Some(t) => { - if token_with_price.unwrap() == token { - index = Option::Some(len); - } - }, - Option::None => (), - } - len += 1; - }; - index - } } } diff --git a/tests/integration/swap_test.cairo b/tests/integration/swap_test.cairo index c03b5dc7..9f6de9f8 100644 --- a/tests/integration/swap_test.cairo +++ b/tests/integration/swap_test.cairo @@ -99,7 +99,9 @@ fn test_deposit_market_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_price_testing_eth(5000); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); + // Fill the pool. IERC20Dispatcher { contract_address: market.long_token }.mint(market.market_token, 50000000000); IERC20Dispatcher { contract_address: market.short_token } @@ -427,7 +429,8 @@ fn test_swap_18_deposit_market_integration() { 2500000000000000000000000000000000000000000000 ); - oracle.set_price_testing_eth(5000); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); 'fill the pool'.print(); // Fill the pool. diff --git a/tests/integration/test_deposit_withdrawal.cairo b/tests/integration/test_deposit_withdrawal.cairo index 9d1b6ac4..76e35b7f 100644 --- a/tests/integration/test_deposit_withdrawal.cairo +++ b/tests/integration/test_deposit_withdrawal.cairo @@ -507,7 +507,8 @@ fn test_deposit_market_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_price_testing_eth(5000); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); // Fill the pool. IERC20Dispatcher { contract_address: market.long_token }.mint(market.market_token, 50000000000); @@ -685,7 +686,8 @@ fn test_deposit_withdraw_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_price_testing_eth(5000); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); // Fill the pool. IERC20Dispatcher { contract_address: market.long_token }.mint(market.market_token, 50000000000); diff --git a/tests/integration/test_long_integration.cairo b/tests/integration/test_long_integration.cairo index 40d33e36..1982e44a 100644 --- a/tests/integration/test_long_integration.cairo +++ b/tests/integration/test_long_integration.cairo @@ -112,7 +112,7 @@ const INITIAL_TOKENS_MINTED: felt252 = 1000; // keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 // ); -// oracle.set_price_testing_eth(5000); +// oracle.set_primary_prices(market.long_token, 5000); // // Fill the pool. // IERC20Dispatcher { contract_address: market.long_token }.mint(market.market_token, 50000000000); @@ -382,7 +382,8 @@ const INITIAL_TOKENS_MINTED: felt252 = 1000; // .balance_of(caller_address); // 'balance of mkt before'.print(); // balance_of_mkt_before.print(); -// oracle.set_price_testing_eth(6000); +// oracle.set_primary_prices(market.long_token, 6000); + // start_prank(market.market_token, caller_address); // start_prank(market.long_token, caller_address); @@ -527,7 +528,8 @@ fn test_long_decimals_market_integration() { 50000000000000000000000000000000000000000000000 ); - oracle.set_price_testing_eth(5000); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); 'fill the pool'.print(); // Fill the pool. @@ -788,7 +790,7 @@ fn test_long_decimals_market_integration() { 'size in usd'.print(); first_position.size_in_usd.print(); 'OKAAAAAYYYYYY'.print(); - oracle.set_price_testing_eth(6000); + oracle.set_primary_prices(market.long_token, 6000); let first_position_after_pump = data_store.get_position(position_key_1); 'size tokens after pump'.print(); first_position_after_pump.size_in_tokens.print(); diff --git a/tests/integration/test_short_integration.cairo b/tests/integration/test_short_integration.cairo index dff36b8b..b5e6c6c6 100644 --- a/tests/integration/test_short_integration.cairo +++ b/tests/integration/test_short_integration.cairo @@ -113,7 +113,8 @@ fn test_short_market_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_price_testing_eth(5000); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); // Fill the pool. IERC20Dispatcher { contract_address: market.long_token }.mint(market.market_token, 50000000000);