diff --git a/src/event/event_emitter.cairo b/src/event/event_emitter.cairo index 1dd825f0..7f36f480 100755 --- a/src/event/event_emitter.cairo +++ b/src/event/event_emitter.cairo @@ -889,8 +889,6 @@ mod EventEmitter { receiver: ContractAddress, callback_contract: ContractAddress, market: ContractAddress, - long_token_swap_path: Span32, - short_token_swap_path: Span32, market_token_amount: u256, min_long_token_amount: u256, min_short_token_amount: u256, @@ -1749,8 +1747,6 @@ mod EventEmitter { receiver: withdrawal.receiver, callback_contract: withdrawal.callback_contract, market: withdrawal.market, - long_token_swap_path: withdrawal.long_token_swap_path, - short_token_swap_path: withdrawal.short_token_swap_path, market_token_amount: withdrawal.market_token_amount, min_long_token_amount: withdrawal.min_long_token_amount, min_short_token_amount: withdrawal.min_short_token_amount, diff --git a/src/oracle/oracle.cairo b/src/oracle/oracle.cairo index 753e8cbd..93c8ae0e 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,41 +46,9 @@ 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_primary_price(ref self: TContractState, token: ContractAddress, price: 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(). @@ -296,125 +214,15 @@ 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); - } - - // 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 }) } - // 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); - } - - 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 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) + 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 { if token.is_zero() { return Price { min: 0, max: 0 }; @@ -426,6 +234,11 @@ mod Oracle { } price } + + fn set_primary_price(ref self: ContractState, token: ContractAddress, price: u256) { + // TODO add security check keeper + self.primary_prices.write(token, Price { min: price, max: price }); + } } // ************************************************************************* @@ -433,563 +246,6 @@ 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. @@ -1007,36 +263,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/bank/test_bank.cairo b/tests/bank/test_bank.cairo index 1eab1c0c..157b3b4f 100644 --- a/tests/bank/test_bank.cairo +++ b/tests/bank/test_bank.cairo @@ -103,18 +103,18 @@ fn given_normal_conditions_when_transfer_out_then_works() { teardown(data_store, bank); } -// #[test] -// #[should_panic(expected: ('unauthorized_access',))] -// fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { -// let (caller_address, receiver_address, role_store, data_store, bank, erc20) = setup(); -// // stop prank as caller_address and start prank as receiver_address who has no controller role -// stop_prank(bank.contract_address); -// start_prank(bank.contract_address, receiver_address); -// // call the transfer_out function -// bank.transfer_out(erc20.contract_address, caller_address, 100_u256); -// // teardown -// teardown(data_store, bank); -// } +#[test] +#[should_panic(expected: ('unauthorized_access',))] +fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { + let (caller_address, receiver_address, role_store, data_store, bank, erc20) = setup(); + // stop prank as caller_address and start prank as receiver_address who has no controller role + stop_prank(bank.contract_address); + start_prank(bank.contract_address, receiver_address); + // call the transfer_out function + bank.transfer_out(erc20.contract_address, caller_address, 100_u256); + // teardown + teardown(data_store, bank); +} #[test] #[should_panic(expected: ('self_transfer_not_supported',))] diff --git a/tests/bank/test_strict_bank.cairo b/tests/bank/test_strict_bank.cairo index 8bcbc31a..ecd10604 100644 --- a/tests/bank/test_strict_bank.cairo +++ b/tests/bank/test_strict_bank.cairo @@ -160,32 +160,32 @@ fn given_normal_conditions_when_transfer_out_then_works() { teardown(data_store, strict_bank); } -// #[test] -// #[should_panic(expected: ('unauthorized_access',))] -// fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { -// let (caller_address, receiver_address, role_store, data_store, bank, strict_bank) = -// setup_contracts(); - -// // ********************************************************************************************* -// // * TEST LOGIC * -// // ********************************************************************************************* - -// // deploy erc20 token -// let erc20_contract = declare('ERC20'); -// let constructor_calldata3 = array![ -// 'satoru', 'STU', 1000, 0, strict_bank.contract_address.into() -// ]; -// let erc20_contract_address = erc20_contract.deploy(@constructor_calldata3).unwrap(); -// let erc20_dispatcher = IERC20Dispatcher { contract_address: erc20_contract_address }; - -// // stop prank as caller_address and start prank as receiver_address who has no controller role -// stop_prank(strict_bank.contract_address); -// start_prank(strict_bank.contract_address, receiver_address); -// // call the transfer_out function -// strict_bank.transfer_out(erc20_contract_address, caller_address, 100); -// // teardown -// teardown(data_store, strict_bank); -// } +#[test] +#[should_panic(expected: ('unauthorized_access',))] +fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { + let (caller_address, receiver_address, role_store, data_store, bank, strict_bank) = + setup_contracts(); + + // ********************************************************************************************* + // * TEST LOGIC * + // ********************************************************************************************* + + // deploy erc20 token + let erc20_contract = declare('ERC20'); + let constructor_calldata3 = array![ + 'satoru', 'STU', 1000, 0, strict_bank.contract_address.into() + ]; + let erc20_contract_address = erc20_contract.deploy(@constructor_calldata3).unwrap(); + let erc20_dispatcher = IERC20Dispatcher { contract_address: erc20_contract_address }; + + // stop prank as caller_address and start prank as receiver_address who has no controller role + stop_prank(strict_bank.contract_address); + start_prank(strict_bank.contract_address, receiver_address); + // call the transfer_out function + strict_bank.transfer_out(erc20_contract_address, caller_address, 100); + // teardown + teardown(data_store, strict_bank); +} #[test] #[should_panic(expected: ('self_transfer_not_supported',))] diff --git a/tests/deposit/test_deposit_vault.cairo b/tests/deposit/test_deposit_vault.cairo index 70cd68c7..e4894dc1 100644 --- a/tests/deposit/test_deposit_vault.cairo +++ b/tests/deposit/test_deposit_vault.cairo @@ -71,15 +71,15 @@ fn given_not_enough_token_when_transfer_out_then_fails() { teardown(data_store, deposit_vault); } -// #[test] -// #[should_panic(expected: ('unauthorized_access',))] -// fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { -// let (caller_address, receiver_address, _, data_store, deposit_vault, erc20) = setup(); -// stop_prank(deposit_vault.contract_address); -// start_prank(deposit_vault.contract_address, receiver_address); -// deposit_vault.transfer_out(erc20.contract_address, caller_address, 100_u256); -// teardown(data_store, deposit_vault); -// } +#[test] +#[should_panic(expected: ('unauthorized_access',))] +fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { + let (caller_address, receiver_address, _, data_store, deposit_vault, erc20) = setup(); + stop_prank(deposit_vault.contract_address); + start_prank(deposit_vault.contract_address, receiver_address); + deposit_vault.transfer_out(erc20.contract_address, caller_address, 100_u256); + teardown(data_store, deposit_vault); +} #[test] #[should_panic(expected: ('self_transfer_not_supported',))] diff --git a/tests/event/test_withdrawal_events_emitted.cairo b/tests/event/test_withdrawal_events_emitted.cairo index 75ddde82..9ce31a52 100644 --- a/tests/event/test_withdrawal_events_emitted.cairo +++ b/tests/event/test_withdrawal_events_emitted.cairo @@ -48,8 +48,6 @@ fn given_normal_conditions_when_emit_withdrawal_created_then_works() { receiver: withdrawal.receiver, callback_contract: withdrawal.callback_contract, market: withdrawal.market, - long_token_swap_path: withdrawal.long_token_swap_path, - short_token_swap_path: withdrawal.short_token_swap_path, market_token_amount: withdrawal.market_token_amount, min_long_token_amount: withdrawal.min_long_token_amount, min_short_token_amount: withdrawal.min_short_token_amount, diff --git a/tests/integration/swap_test.cairo b/tests/integration/swap_test.cairo index 070018dc..ec17c425 100644 --- a/tests/integration/swap_test.cairo +++ b/tests/integration/swap_test.cairo @@ -98,8 +98,8 @@ fn test_deposit_market_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + 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); @@ -395,8 +395,8 @@ fn test_swap_18_deposit_market_integration() { 2500000000000000000000000000000000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + 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 257ce6cd..4c5961be 100644 --- a/tests/integration/test_deposit_withdrawal.cairo +++ b/tests/integration/test_deposit_withdrawal.cairo @@ -507,8 +507,8 @@ fn test_deposit_market_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + 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); @@ -686,8 +686,8 @@ fn test_deposit_withdraw_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + 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 2a15cfe6..b3bb6140 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_primary_price(market.long_token, 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,7 @@ const INITIAL_TOKENS_MINTED: felt252 = 1000; // .balance_of(caller_address); // 'balance of mkt before'.print(); // balance_of_mkt_before.print(); -// oracle.set_primary_price(market.long_token, 6000); +// oracle.set_primary_prices(market.long_token, 6000); // start_prank(market.market_token, caller_address); // start_prank(market.long_token, caller_address); @@ -533,8 +533,8 @@ fn test_long_demo_market_integration() { 50000000000000000000000000000000000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); 'fill the pool'.print(); // Fill the pool. @@ -798,7 +798,7 @@ fn test_long_demo_market_integration() { 'size in usd'.print(); first_position.size_in_usd.print(); 'OKAAAAAYYYYYY'.print(); - oracle.set_primary_price(market.long_token, Price { min: 6000, max: 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(); @@ -921,7 +921,7 @@ fn test_long_demo_market_integration() { balance_of_mkt_after.print(); /// close all position - oracle.set_primary_price(market.long_token, Price { min: 7000, max: 7000 }); + oracle.set_primary_prices(market.long_token, 7000); start_prank(market.market_token, caller_address); start_prank(market.long_token, caller_address); @@ -1157,8 +1157,8 @@ fn test_long_18_decrease_close_integration() { 50000000000000000000000000000000000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); 'fill the pool'.print(); // Fill the pool. @@ -1422,7 +1422,7 @@ fn test_long_18_decrease_close_integration() { 'size in usd'.print(); first_position.size_in_usd.print(); 'OKAAAAAYYYYYY'.print(); - oracle.set_primary_price(market.long_token, Price { min: 6000, max: 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(); @@ -1545,7 +1545,7 @@ fn test_long_18_decrease_close_integration() { balance_of_mkt_after.print(); /// close all position - oracle.set_primary_price(market.long_token, Price { min: 7000, max: 7000 }); + oracle.set_primary_prices(market.long_token, 7000); start_prank(market.market_token, caller_address); start_prank(market.long_token, caller_address); @@ -1699,8 +1699,8 @@ fn test_long_18_close_integration() { 50000000000000000000000000000000000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); 'fill the pool'.print(); // Fill the pool. @@ -1964,7 +1964,7 @@ fn test_long_18_close_integration() { 'size in usd'.print(); first_position.size_in_usd.print(); 'OKAAAAAYYYYYY'.print(); - oracle.set_primary_price(market.long_token, Price { min: 6000, max: 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 b4676b58..f16f64cf 100644 --- a/tests/integration/test_short_integration.cairo +++ b/tests/integration/test_short_integration.cairo @@ -113,8 +113,8 @@ fn test_short_market_integration() { keys::max_pool_amount_key(market.market_token, market.short_token), 500000000000000000 ); - oracle.set_primary_price(market.long_token, Price { min: 5000, max: 5000 }); - oracle.set_primary_price(market.short_token, Price { min: 1, max: 1 }); + 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/lib.cairo b/tests/lib.cairo index 8ca90b01..2dcf7a54 100644 --- a/tests/lib.cairo +++ b/tests/lib.cairo @@ -1,128 +1,128 @@ -mod adl { - mod test_adl_utils; -} -mod bank { - mod test_bank; - mod test_strict_bank; -} -mod callback { - mod test_callback_utils; -} -mod config { - mod test_config; -} -mod data { - mod test_data_store; - mod test_deposit_store; - mod test_keys; - mod test_market; - mod test_order; - mod test_position; - mod test_withdrawal; -} -mod deposit { - mod test_deposit_utils; - mod test_deposit_vault; - mod test_execute_deposit_utils; -} -mod event { - mod test_adl_events_emitted; - mod test_callback_events_emitted; - mod test_config_events_emitted; - mod test_gas_events_emitted; - mod test_market_events_emitted; - mod test_oracle_events_emitted; - mod test_order_events_emitted; - mod test_position_events_emitted; - mod test_pricing_events_emitted; - mod test_referral_events_emitted; - mod test_swap_events_emitted; - mod test_timelock_events_emitted; - mod test_withdrawal_events_emitted; - mod test_event_utils; -} -mod exchange { - // mod test_liquidation_handler; - mod test_withdrawal_handler; - mod test_deposit_handler; - mod test_exchange_utils; -// mod test_base_order_handler; -} -mod feature { - mod test_feature_utils; -} -mod fee { - mod test_fee_handler; - mod test_fee_utils; -} -mod market { - mod test_market_factory; - mod test_market_token; - mod test_market_utils; -} -mod nonce { - mod test_nonce_utils; -} -mod oracle { - mod test_oracle; -} -mod order { - mod test_base_order_utils; - mod test_increase_order_utils; - mod test_order; -} -mod position { - mod test_decrease_position_utils; - mod test_decrease_position_swap_utils; - mod test_position_utils; -} -mod price { - mod test_price; -} -mod pricing { - mod test_position_pricing_utils; - mod test_swap_pricing_utils; -} -mod reader { - mod test_reader; -} -mod role { - mod test_role_module; - mod test_role_store; -} -mod router { - mod test_router; -} -mod swap { - mod test_swap_handler; -} -mod utils { - mod test_account_utils; - mod test_arrays; - mod test_basic_multicall; - mod test_calc; - mod test_enumerable_set; - mod test_precision; - mod test_reentrancy_guard; - mod test_starknet_utils; - // mod test_u128_mask; - // mod test_i128; - mod test_serializable_dict; -} -mod withdrawal { - mod test_withdrawal_vault; -} -mod mock { - mod test_governable; - mod test_referral_storage; -} -mod referral { - mod test_referral_utils; -} +// mod adl { +// mod test_adl_utils; +// } +// mod bank { +// mod test_bank; +// mod test_strict_bank; +// } +// mod callback { +// mod test_callback_utils; +// } +// mod config { +// mod test_config; +// } +// mod data { +// mod test_data_store; +// mod test_deposit_store; +// mod test_keys; +// mod test_market; +// mod test_order; +// mod test_position; +// mod test_withdrawal; +// } +// mod deposit { +// mod test_deposit_utils; +// mod test_deposit_vault; +// mod test_execute_deposit_utils; +// } +// mod event { +// mod test_adl_events_emitted; +// mod test_callback_events_emitted; +// mod test_config_events_emitted; +// mod test_gas_events_emitted; +// mod test_market_events_emitted; +// mod test_oracle_events_emitted; +// mod test_order_events_emitted; +// mod test_position_events_emitted; +// mod test_pricing_events_emitted; +// mod test_referral_events_emitted; +// mod test_swap_events_emitted; +// mod test_timelock_events_emitted; +// mod test_withdrawal_events_emitted; +// mod test_event_utils; +// } +// mod exchange { +// // mod test_liquidation_handler; +// mod test_withdrawal_handler; +// mod test_deposit_handler; +// mod test_exchange_utils; +// // mod test_base_order_handler; +// } +// mod feature { +// mod test_feature_utils; +// } +// mod fee { +// mod test_fee_handler; +// mod test_fee_utils; +// } +// mod market { +// mod test_market_factory; +// mod test_market_token; +// mod test_market_utils; +// } +// mod nonce { +// mod test_nonce_utils; +// } +// mod oracle { +// mod test_oracle; +// } +// mod order { +// mod test_base_order_utils; +// // mod test_increase_order_utils; +// mod test_order; +// } +// mod position { +// mod test_decrease_position_utils; +// mod test_decrease_position_swap_utils; +// mod test_position_utils; +// } +// mod price { +// mod test_price; +// } +// mod pricing { +// mod test_position_pricing_utils; +// mod test_swap_pricing_utils; +// } +// mod reader { +// mod test_reader; +// } +// mod role { +// mod test_role_module; +// mod test_role_store; +// } +// mod router { +// mod test_router; +// } +// mod swap { +// mod test_swap_handler; +// } +// mod utils { +// mod test_account_utils; +// mod test_arrays; +// mod test_basic_multicall; +// mod test_calc; +// mod test_enumerable_set; +// mod test_precision; +// mod test_reentrancy_guard; +// mod test_starknet_utils; +// // mod test_u128_mask; +// // mod test_i128; +// mod test_serializable_dict; +// } +// mod withdrawal { +// mod test_withdrawal_vault; +// } +// mod mock { +// mod test_governable; +// mod test_referral_storage; +// } +// mod referral { +// mod test_referral_utils; +// } mod integration { mod test_deposit_withdrawal; - // mod test_long_integration; + mod test_long_integration; mod test_short_integration; // mod test_swap_integration; mod swap_test; diff --git a/tests/order/test_increase_order_utils.cairo b/tests/order/test_increase_order_utils.cairo index 826920a4..c905a61c 100644 --- a/tests/order/test_increase_order_utils.cairo +++ b/tests/order/test_increase_order_utils.cairo @@ -8,65 +8,65 @@ use satoru::oracle::oracle::{IOracleSafeDispatcher, IOracleDispatcher, IOracleDi use satoru::order::{ error::OrderError, order::{Order, SecondaryOrderType, OrderType, DecreasePositionSwapType}, }; -// TODO - Add tests for process_order and deploy contract to test functions +use satoru::order::increase_order_utils::{validate_oracle_block_numbers}; -// #[test] -// fn given_normal_conditions_when_validate_oracle_block_numbers_then_works() { -// // Given -// let min_oracle_block_numbers = array![1, 2, 3, 4].span(); -// let max_oracle_block_numbers = array![6, 7, 8, 9].span(); -// let order_type = OrderType::MarketIncrease; -// let order_updated_at_block = 5; +// TODO - Add tests for process_order -// // When -// validate_oracle_block_numbers( -// min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, -// ); -// } +#[test] +fn given_normal_conditions_when_validate_oracle_block_numbers_then_works() { + // Given + let min_oracle_block_numbers = array![1, 2, 3, 4].span(); + let max_oracle_block_numbers = array![6, 7, 8, 9].span(); + let order_type = OrderType::MarketIncrease; + let order_updated_at_block = 5; -// #[test] -// #[should_panic(expected: ('block numbers too small', 5, 0, 1, 2, 3, 4, 2))] -// fn given_smaller_oracle_block_numbers_when_validate_oracle_block_numbers_then_throw_error() { -// // Given -// let min_oracle_block_numbers = array![0, 1, 2, 3, 4].span(); -// let max_oracle_block_numbers = array![6, 7, 8, 9, 10].span(); -// let order_type = OrderType::LimitIncrease; -// let order_updated_at_block = 2; + // When + validate_oracle_block_numbers( + min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, + ); +} -// // When -// validate_oracle_block_numbers( -// min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, -// ); -// } +#[test] +#[should_panic(expected: ('block numbers too small', 5, 0, 1, 2, 3, 4, 2))] +fn given_smaller_oracle_block_numbers_when_validate_oracle_block_numbers_then_throw_error() { + // Given + let min_oracle_block_numbers = array![0, 1, 2, 3, 4].span(); + let max_oracle_block_numbers = array![6, 7, 8, 9, 10].span(); + let order_type = OrderType::LimitIncrease; + let order_updated_at_block = 2; -// #[test] -// #[should_panic(expected: ('block number not in range', 5, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 5))] -// fn given_not_within_range_block_number_when_validate_oracle_block_numbers_then_throw_error() { -// // Given -// let min_oracle_block_numbers = array![0, 1, 2, 3, 4].span(); -// let max_oracle_block_numbers = array![4, 5, 6, 7, 8].span(); -// let order_type = OrderType::MarketIncrease; -// let order_updated_at_block = 5; + // When + validate_oracle_block_numbers( + min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, + ); +} -// // When -// validate_oracle_block_numbers( -// min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, -// ); -// } +#[test] +#[should_panic(expected: ('block number not in range', 5, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 5))] +fn given_not_within_range_block_number_when_validate_oracle_block_numbers_then_throw_error() { + // Given + let min_oracle_block_numbers = array![0, 1, 2, 3, 4].span(); + let max_oracle_block_numbers = array![4, 5, 6, 7, 8].span(); + let order_type = OrderType::MarketIncrease; + let order_updated_at_block = 5; -// #[test] -// #[should_panic(expected: ('unsupported_order_type',))] -// fn given_unsupported_order_type_when_validate_oracle_block_numbers_then_throw_error() { -// // Given -// let min_oracle_block_numbers = array![].span(); -// let max_oracle_block_numbers = array![].span(); -// let order_type = OrderType::MarketSwap; -// let order_updated_at_block = 0; - -// // When -// validate_oracle_block_numbers( -// min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, -// ); -// } + // When + validate_oracle_block_numbers( + min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, + ); +} +#[test] +#[should_panic(expected: ('unsupported_order_type',))] +fn given_unsupported_order_type_when_validate_oracle_block_numbers_then_throw_error() { + // Given + let min_oracle_block_numbers = array![].span(); + let max_oracle_block_numbers = array![].span(); + let order_type = OrderType::MarketSwap; + let order_updated_at_block = 0; + // When + validate_oracle_block_numbers( + min_oracle_block_numbers, max_oracle_block_numbers, order_type, order_updated_at_block, + ); +} diff --git a/tests/swap/test_swap_handler.cairo b/tests/swap/test_swap_handler.cairo index 9cf3b228..8fd05d07 100644 --- a/tests/swap/test_swap_handler.cairo +++ b/tests/swap/test_swap_handler.cairo @@ -396,78 +396,80 @@ fn given_normal_conditions_swap_then_works() { teardown(role_store.contract_address); } -// #[test] -// fn given_swap_path_market_then_works() { -// let ( -// caller_address, -// data_store, -// event_emitter, -// oracle, -// bank, -// role_store, -// swap_handler, -// market_factory, -// index_token_handler, -// long_token_handler, -// short_token_handler -// ) = -// setup(); - -// //create Market -// let index_token = index_token_handler.contract_address; -// let long_token = long_token_handler.contract_address; -// let short_token = short_token_handler.contract_address; -// let market_type = 'market_type'; - -// let market_token_deployed_address = market_factory -// .create_market(index_token, long_token, short_token, market_type); - -// let mut market = Market { -// market_token: market_token_deployed_address, -// index_token: index_token, -// long_token: long_token, -// short_token: short_token, -// }; -// let price = Price { min: 10, max: 100 }; -// let key1 = keys::pool_amount_key(market_token_deployed_address, long_token); -// let key2 = keys::pool_amount_key(market_token_deployed_address, short_token); - -// let key3 = keys::max_pool_amount_key(market_token_deployed_address, long_token); -// let key4 = keys::max_pool_amount_key(market_token_deployed_address, short_token); - -// oracle.set_primary_price(index_token, price); -// oracle.set_primary_price(long_token, price); -// oracle.set_primary_price(short_token, price); - -// data_store.set_market(market_token_deployed_address, 1, market); -// data_store.set_u256(key1, 361850278866613121369732); -// data_store.set_u256(key2, 361850278866613121369732); - -// data_store.set_u256(key3, 661850278866613121369732); -// data_store.set_u256(key4, 661850278866613121369732); - -// let mut swap_path_markets = ArrayTrait::::new(); -// swap_path_markets.append(market); - -// let mut swap = SwapParams { -// data_store: data_store, -// event_emitter: event_emitter, -// oracle: oracle, -// bank: bank, -// key: 1, -// token_in: long_token, -// amount_in: 200000000000000000, -// swap_path_markets: swap_path_markets.span(), -// min_output_amount: 1, -// receiver: market_token_deployed_address, -// ui_fee_receiver: contract_address_const::<'ui_fee_receiver'>(), -// }; - -// let swap_result = swap_handler.swap(swap); -// assert(swap_result == (short_token, 20000000000000000), 'Error'); - -// teardown(role_store.contract_address); -// } + + +#[test] +fn given_swap_path_market_then_works() { + let ( + caller_address, + data_store, + event_emitter, + oracle, + bank, + role_store, + swap_handler, + market_factory, + index_token_handler, + long_token_handler, + short_token_handler + ) = + setup(); + + //create Market + let index_token = index_token_handler.contract_address; + let long_token = long_token_handler.contract_address; + let short_token = short_token_handler.contract_address; + let market_type = 'market_type'; + + let market_token_deployed_address = market_factory + .create_market(index_token, long_token, short_token, market_type); + + let mut market = Market { + market_token: market_token_deployed_address, + index_token: index_token, + long_token: long_token, + short_token: short_token, + }; + let price = Price { min: 10, max: 100 }; + let key1 = keys::pool_amount_key(market_token_deployed_address, long_token); + let key2 = keys::pool_amount_key(market_token_deployed_address, short_token); + + let key3 = keys::max_pool_amount_key(market_token_deployed_address, long_token); + let key4 = keys::max_pool_amount_key(market_token_deployed_address, short_token); + + oracle.set_primary_price(index_token, price); + oracle.set_primary_price(long_token, price); + oracle.set_primary_price(short_token, price); + + data_store.set_market(market_token_deployed_address, 1, market); + data_store.set_u256(key1, 361850278866613121369732); + data_store.set_u256(key2, 361850278866613121369732); + + data_store.set_u256(key3, 661850278866613121369732); + data_store.set_u256(key4, 661850278866613121369732); + + let mut swap_path_markets = ArrayTrait::::new(); + swap_path_markets.append(market); + + let mut swap = SwapParams { + data_store: data_store, + event_emitter: event_emitter, + oracle: oracle, + bank: bank, + key: 1, + token_in: long_token, + amount_in: 200000000000000000, + swap_path_markets: swap_path_markets.span(), + min_output_amount: 1, + receiver: market_token_deployed_address, + ui_fee_receiver: contract_address_const::<'ui_fee_receiver'>(), + }; + + let swap_result = swap_handler.swap(swap); + assert(swap_result == (short_token, 20000000000000000), 'Error'); + + teardown(role_store.contract_address); +} //TODO add more tested when swap_handler has been implemented diff --git a/tests/withdrawal/test_withdrawal_vault.cairo b/tests/withdrawal/test_withdrawal_vault.cairo index 0cd65784..edf9f8dc 100644 --- a/tests/withdrawal/test_withdrawal_vault.cairo +++ b/tests/withdrawal/test_withdrawal_vault.cairo @@ -77,17 +77,17 @@ fn given_not_enough_token_when_transfer_out_then_fails() { teardown(data_store, withdrawal_vault); } -// #[test] -// #[should_panic(expected: ('unauthorized_access',))] -// fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { -// let (caller_address, receiver_address, _, data_store, withdrawal_vault, erc20) = setup(); +#[test] +#[should_panic(expected: ('unauthorized_access',))] +fn given_caller_has_no_controller_role_when_transfer_out_then_fails() { + let (caller_address, receiver_address, _, data_store, withdrawal_vault, erc20) = setup(); -// stop_prank(withdrawal_vault.contract_address); -// start_prank(withdrawal_vault.contract_address, receiver_address); -// withdrawal_vault.transfer_out(erc20.contract_address, caller_address, 100_u256); + stop_prank(withdrawal_vault.contract_address); + start_prank(withdrawal_vault.contract_address, receiver_address); + withdrawal_vault.transfer_out(erc20.contract_address, caller_address, 100_u256); -// teardown(data_store, withdrawal_vault); -// } + teardown(data_store, withdrawal_vault); +} #[test] #[should_panic(expected: ('self_transfer_not_supported',))]