From 534e3c80247fec03725ba004a29ea3a3c9b63f5e Mon Sep 17 00:00:00 2001 From: sparqet <37338401+sparqet@users.noreply.github.com> Date: Thu, 9 May 2024 01:05:50 +0300 Subject: [PATCH] Test/all test demo (#650) * refactor integration tests * tests for demo * add coverage long test --- tests/integration/test_long_integration.cairo | 1182 ++++++++++++++++- 1 file changed, 1181 insertions(+), 1 deletion(-) diff --git a/tests/integration/test_long_integration.cairo b/tests/integration/test_long_integration.cairo index 1e66ac5b..9becbcfe 100644 --- a/tests/integration/test_long_integration.cairo +++ b/tests/integration/test_long_integration.cairo @@ -471,7 +471,7 @@ const INITIAL_TOKENS_MINTED: felt252 = 1000; // } #[test] -fn test_long_decimals_market_integration() { +fn test_long_demo_market_integration() { // ********************************************************************************************* // * SETUP * // ********************************************************************************************* @@ -906,6 +906,1186 @@ fn test_long_decimals_market_integration() { 'long pos dec SUCCEEDED'.print(); + let first_position_dec = data_store.get_position(position_key_1); + + 'size tokens before'.print(); + first_position.size_in_tokens.print(); + 'size in usd before'.print(); + first_position.size_in_usd.print(); + + 'size tokens'.print(); + first_position_dec.size_in_tokens.print(); + 'size in usd'.print(); + first_position_dec.size_in_usd.print(); + + let balance_of_mkt_after = IERC20Dispatcher { + contract_address: contract_address_const::<'USDC'>() + } + .balance_of(caller_address); + 'balance of mkt after'.print(); + balance_of_mkt_after.print(); + + /// close all position + oracle.set_primary_prices(market.long_token, 7000); + + start_prank(market.market_token, caller_address); + start_prank(market.long_token, caller_address); + let order_params_long_dec_2 = CreateOrderParams { + receiver: caller_address, + callback_contract: contract_address, + ui_fee_receiver: contract_address, + market: market.market_token, + initial_collateral_token: market.long_token, + swap_path: Array32Trait::::span32(@array![market.market_token]), + size_delta_usd: 7000000000000000000000, // 6000 + initial_collateral_delta_amount: 1000000000000000000, // 1 ETH 10^18 + trigger_price: 7000, + acceptable_price: 7000, + execution_fee: 0, + callback_gas_limit: 0, + min_output_amount: 7000000000000000000000, // 6000 + order_type: OrderType::MarketDecrease(()), + decrease_position_swap_type: DecreasePositionSwapType::NoSwap(()), + is_long: true, + referral_code: 0 + }; + // Create the long order. + start_roll(order_handler.contract_address, 1950); + 'try to create order'.print(); + start_prank(order_handler.contract_address, caller_address); + let key_long_dec_2 = order_handler.create_order(caller_address, order_params_long_dec_2); + 'long decrease created'.print(); + let got_order_long_dec = data_store.get_order(key_long_dec_2); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), ); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), 1000000); + // Execute the swap order. + + let keeper_address = contract_address_const::<'keeper'>(); + role_store.grant_role(keeper_address, role::ORDER_KEEPER); + + + let signatures: Span = array![0].span(); + let set_price_params_dec2 = SetPricesParams { + signer_info: 2, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1910, 1910], + compacted_max_oracle_block_numbers: array![1920, 1920], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![1, 1], + compacted_min_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + stop_prank(order_handler.contract_address); + start_prank(order_handler.contract_address, keeper_address); + start_roll(order_handler.contract_address, 1955); + // TODO add real signatures check on Oracle Account + order_handler.execute_order_keeper(key_long_dec_2, set_price_params_dec2, keeper_address); + 'long pos dec SUCCEEDED'.print(); + + + let first_position_dec = data_store.get_position(position_key_1); + + 'size tokens before 2'.print(); + first_position.size_in_tokens.print(); + 'size in usd before 2'.print(); + first_position.size_in_usd.print(); + + 'size tokens 2'.print(); + let token_size_dec = first_position_dec.size_in_tokens; + assert(token_size_dec == 0, 'wrong token size'); + 'size in usd 2'.print(); + first_position_dec.size_in_usd.print(); + + let balance_of_mkt_after = IERC20Dispatcher { + contract_address: contract_address_const::<'USDC'>() + } + .balance_of(caller_address); + 'balance of mkt after 2'.print(); + balance_of_mkt_after.print(); + + assert(balance_of_mkt_after == 63000000000000000000000, 'wrong balance final size'); + + + /// ------ TEST SWAP -------- + + start_prank(contract_address_const::<'ETH'>(), caller_address); //change to switch swap + // Send token to order_vault in multicall with create_order + IERC20Dispatcher { contract_address: contract_address_const::<'ETH'>() } //change to switch swap + .transfer(order_vault.contract_address, 1000000000000000000); + + // Create order_params Struct + let contract_address = contract_address_const::<0>(); + start_prank(market.long_token, caller_address); //change to switch swap + + let order_params = CreateOrderParams { + receiver: caller_address, + callback_contract: contract_address, + ui_fee_receiver: contract_address, + market: contract_address, + initial_collateral_token: market.long_token, //change to switch swap + swap_path: Array32Trait::::span32(@array![market.market_token]), + size_delta_usd: 7000000000000000000, + initial_collateral_delta_amount: 1000000000000000000, // 10^18 + trigger_price: 0, + acceptable_price: 0, + execution_fee: 0, + callback_gas_limit: 0, + min_output_amount: 0, + order_type: OrderType::MarketSwap(()), + decrease_position_swap_type: DecreasePositionSwapType::NoSwap(()), + is_long: false, + referral_code: 0 + }; + // Create the swap order. + start_roll(order_handler.contract_address, 1960); + //here we create the order but we do not execute it yet + start_prank(order_handler.contract_address, caller_address); //change to switch swap + + let key = order_handler.create_order(caller_address, order_params); + + let got_order = data_store.get_order(key); + + // data_store + // .set_u256( + // keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), + // 50000000000000000000000000000 + // ); + // data_store + // .set_u256( + // keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), + // 50000000000000000000000000000 + // ); + + // Execute the swap order. + let signatures: Span = array![0].span(); + let set_price_params = SetPricesParams { + signer_info: 2, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1910, 1910], + compacted_max_oracle_block_numbers: array![1920, 1920], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![1, 1], + compacted_min_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + let keeper_address = contract_address_const::<'keeper'>(); + role_store.grant_role(keeper_address, role::ORDER_KEEPER); + + stop_prank(order_handler.contract_address); + start_prank(order_handler.contract_address, keeper_address); + start_roll(order_handler.contract_address, 1965); + // TODO add real signatures check on Oracle Account -> Later + order_handler.execute_order_keeper(key, set_price_params, keeper_address); //execute order + + let balance_of_swap = IERC20Dispatcher { + contract_address: contract_address_const::<'USDC'>() + }.balance_of(caller_address); + + assert(balance_of_swap == 70000000000000000000000, 'wrong balance final swap'); + // ********************************************************************************************* + // * TEARDOWN * + // ********************************************************************************************* + teardown(data_store, market_factory); +} + +#[test] +fn test_long_18_decrease_close_integration() { + // ********************************************************************************************* + // * SETUP * + // ********************************************************************************************* + let ( + caller_address, + market_factory_address, + role_store_address, + data_store_address, + market_token_class_hash, + market_factory, + role_store, + data_store, + event_emitter, + exchange_router, + deposit_handler, + deposit_vault, + oracle, + order_handler, + order_vault, + reader, + referal_storage, + withdrawal_handler, + withdrawal_vault, + ) = + setup(); + + // ********************************************************************************************* + // * TEST LOGIC * + // ********************************************************************************************* + + // Create a market. + let market = data_store.get_market(create_market(market_factory)); + + // Set params in data_store + data_store.set_address(keys::fee_token(), market.index_token); + data_store.set_u256(keys::max_swap_path_length(), 5); + + // Set max pool amount. + data_store + .set_u256( + keys::max_pool_amount_key(market.market_token, market.long_token), + 5000000000000000000000000000000000000000000 //500 000 ETH + ); + data_store + .set_u256( + keys::max_pool_amount_key(market.market_token, market.short_token), + 2500000000000000000000000000000000000000000000 //250 000 000 USDC + ); + + let factor_for_deposits: felt252 = keys::max_pnl_factor_for_deposits(); + data_store + .set_u256( + keys::max_pnl_factor_key(factor_for_deposits, market.market_token, true), + 50000000000000000000000000000000000000000000000 + ); + let factor_for_withdrawal: felt252 = keys::max_pnl_factor_for_withdrawals(); + data_store + .set_u256( + keys::max_pnl_factor_key(factor_for_withdrawal, market.market_token, true), + 50000000000000000000000000000000000000000000000 + ); + + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); + + 'fill the pool'.print(); + // Fill the pool. + IERC20Dispatcher { contract_address: market.long_token } + .mint(market.market_token, 50000000000000000000000000000000000000); // 5 ETH + IERC20Dispatcher { contract_address: market.short_token } + .mint(market.market_token, 25000000000000000000000000000000000000000); // 25000 USDC + 'filled pool 1'.print(); + + IERC20Dispatcher { contract_address: market.long_token } + .mint(caller_address, 9999999999999000000); // 9.999 ETH + IERC20Dispatcher { contract_address: market.short_token } + .mint(caller_address, 49999999999999999000000); // 49.999 UDC + 'filled account'.print(); + + // INITIAL LONG TOKEN IN POOL : 5 ETH + // INITIAL SHORT TOKEN IN POOL : 25000 USDC + + // TODO Check why we don't need to set pool_amount_key + // // Set pool amount in data_store. + // let mut key = keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()); + + let balance_deposit_vault_before = IERC20Dispatcher { contract_address: market.short_token } + .balance_of(deposit_vault.contract_address); + let balance_caller_ETH = IERC20Dispatcher { contract_address: market.long_token } + .balance_of(caller_address); + let balance_caller_USDC = IERC20Dispatcher { contract_address: market.short_token } + .balance_of(caller_address); + + assert(balance_deposit_vault_before == 0, 'balance deposit should be 0'); + assert(balance_caller_ETH == 10000000000000000000, 'balanc ETH should be 10 ETH'); + assert(balance_caller_USDC == 50000000000000000000000, 'USDC be 50 000 USDC'); + + // Send token to deposit in the deposit vault (this should be in a multi call with create_deposit) + 'get balances'.print(); + // start_prank(market.long_token, caller_address); + // IERC20Dispatcher { contract_address: market.long_token } + // .transfer(deposit_vault.contract_address, 5000000000000000000); // 5 ETH + + // start_prank(market.short_token, caller_address); + // IERC20Dispatcher { contract_address: market.short_token } + // .transfer(deposit_vault.contract_address, 25000000000000000000000); // 25000 USDC + // 'make transfer'.print(); + + IERC20Dispatcher { contract_address: market.long_token } + .mint(deposit_vault.contract_address, 50000000000000000000000000000); // 50 000 000 000 + IERC20Dispatcher { contract_address: market.short_token } + .mint(deposit_vault.contract_address, 50000000000000000000000000000); // 50 000 000 000 + // Create Deposit + + let addresss_zero: ContractAddress = 0.try_into().unwrap(); + + let params = CreateDepositParams { + receiver: caller_address, + callback_contract: addresss_zero, + ui_fee_receiver: addresss_zero, + market: market.market_token, + initial_long_token: market.long_token, + initial_short_token: market.short_token, + long_token_swap_path: Array32Trait::::span32(@array![]), + short_token_swap_path: Array32Trait::::span32(@array![]), + min_market_tokens: 0, + execution_fee: 0, + callback_gas_limit: 0, + }; + 'create deposit'.print(); + + start_roll(deposit_handler.contract_address, 1910); + let key = deposit_handler.create_deposit(caller_address, params); + let first_deposit = data_store.get_deposit(key); + + 'created deposit'.print(); + + assert(first_deposit.account == caller_address, 'Wrong account depositer'); + assert(first_deposit.receiver == caller_address, 'Wrong account receiver'); + assert(first_deposit.initial_long_token == market.long_token, 'Wrong initial long token'); + assert( + first_deposit.initial_long_token_amount == 50000000000000000000000000000, + 'Wrong initial long token amount' + ); + assert( + first_deposit.initial_short_token_amount == 50000000000000000000000000000, + 'Wrong init short token amount' + ); + + let price_params = SetPricesParams { // TODO + signer_info: 1, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1900, 1900], + compacted_max_oracle_block_numbers: array![1910, 1910], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![18, 18], + compacted_min_prices: array![4294967346000000], // 50000000, 1000000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![4294967346000000], // 50000000, 1000000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + start_prank(role_store.contract_address, caller_address); + + role_store.grant_role(caller_address, role::ORDER_KEEPER); + role_store.grant_role(caller_address, role::ROLE_ADMIN); + role_store.grant_role(caller_address, role::CONTROLLER); + role_store.grant_role(caller_address, role::MARKET_KEEPER); + + 'execute deposit'.print(); + + // Execute Deposit + start_roll(deposit_handler.contract_address, 1915); + deposit_handler.execute_deposit(key, price_params); + + 'executed deposit'.print(); + + // let pool_value_info = market_utils::get_pool_value_info( + // data_store, + // market, + // Price { min: 2000, max: 2000 }, + // Price { min: 2000, max: 2000 }, + // Price { min: 2000, max: 2000 }, + // keys::max_pnl_factor_for_deposits(), + // true, + // ); + + // assert(pool_value_info.pool_value.mag == 42000000000000000000000, 'wrong pool value amount'); + // assert(pool_value_info.long_token_amount == 6000000000000000000, 'wrong long token amount'); + // assert(pool_value_info.short_token_amount == 30000000000000000000000, 'wrong short token amount'); + + let not_deposit = data_store.get_deposit(key); + let default_deposit: Deposit = Default::default(); + assert(not_deposit == default_deposit, 'Still existing deposit'); + + let market_token_dispatcher = IMarketTokenDispatcher { contract_address: market.market_token }; + let balance_market_token = market_token_dispatcher.balance_of(caller_address); + + assert(balance_market_token != 0, 'should receive market token'); + + let balance_deposit_vault_after = IERC20Dispatcher { contract_address: market.short_token } + .balance_of(deposit_vault.contract_address); + + // let pool_value_info = market_utils::get_pool_value_info( + // data_store, + // market, + // Price { min: 5000, max: 5000, }, + // Price { min: 5000, max: 5000, }, + // Price { min: 1, max: 1, }, + // keys::max_pnl_factor_for_deposits(), + // true, + // ); + + // pool_value_info.pool_value.mag.print(); // 10000 000000000000000000 + // pool_value_info.long_token_amount.print(); // 5 000000000000000000 + // pool_value_info.short_token_amount.print(); // 25000 000000000000000000 + + // ************************************* TEST LONG ********************************************* + + 'Begining of LONG TEST'.print(); + + let key_open_interest = keys::open_interest_key( + market.market_token, contract_address_const::<'ETH'>(), true + ); + data_store.set_u256(key_open_interest, 1); + let max_key_open_interest = keys::max_open_interest_key(market.market_token, true); + data_store.set_u256(max_key_open_interest, 1000000000000000000000000000000000000000000000000000); // 1 000 000 + + // Send token to order_vault in multicall with create_order + start_prank(contract_address_const::<'ETH'>(), caller_address); + IERC20Dispatcher { contract_address: contract_address_const::<'ETH'>() } + .transfer(order_vault.contract_address, 2000000000000000000); // 2ETH + + 'transfer made'.print(); + // Create order_params Struct + let contract_address = contract_address_const::<0>(); + start_prank(market.market_token, caller_address); + start_prank(market.long_token, caller_address); + let order_params_long = CreateOrderParams { + receiver: caller_address, + callback_contract: contract_address, + ui_fee_receiver: contract_address, + market: market.market_token, + initial_collateral_token: market.long_token, + swap_path: Array32Trait::::span32(@array![]), + size_delta_usd: 10000000000000000000000, + initial_collateral_delta_amount: 2000000000000000000, // 10^18 + trigger_price: 5000, + acceptable_price: 5500, + execution_fee: 0, + callback_gas_limit: 0, + min_output_amount: 0, + order_type: OrderType::MarketIncrease(()), + decrease_position_swap_type: DecreasePositionSwapType::NoSwap(()), + is_long: true, + referral_code: 0 + }; + // Create the swap order. + start_roll(order_handler.contract_address, 1930); + 'try to create prder'.print(); + start_prank(order_handler.contract_address, caller_address); + let key_long = order_handler.create_order(caller_address, order_params_long); + 'long created'.print(); + let got_order_long = data_store.get_order(key_long); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), ); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), 1000000); + // Execute the swap order. + + data_store + .set_u256( + keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), + 50000000000000000000000000000 + ); + data_store + .set_u256( + keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), + 50000000000000000000000000000 + ); + + let signatures: Span = array![0].span(); + let set_price_params = SetPricesParams { + signer_info: 2, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1910, 1910], + compacted_max_oracle_block_numbers: array![1920, 1920], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![1, 1], + compacted_min_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + let keeper_address = contract_address_const::<'keeper'>(); + role_store.grant_role(keeper_address, role::ORDER_KEEPER); + + stop_prank(order_handler.contract_address); + start_prank(order_handler.contract_address, keeper_address); + start_roll(order_handler.contract_address, 1935); + // TODO add real signatures check on Oracle Account + order_handler.execute_order_keeper(key_long, set_price_params, keeper_address); + 'long position SUCCEEDED'.print(); + let position_key = data_store.get_account_position_keys(caller_address, 0, 10); + + let position_key_1: felt252 = *position_key.at(0); + let first_position = data_store.get_position(position_key_1); + let market_prices = market_utils::MarketPrices { + index_token_price: Price { min: 8000, max: 8000, }, + long_token_price: Price { min: 8000, max: 8000, }, + short_token_price: Price { min: 1, max: 1, }, + }; + 'size tokens'.print(); + first_position.size_in_tokens.print(); + 'size in usd'.print(); + first_position.size_in_usd.print(); + 'OKAAAAAYYYYYY'.print(); + 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(); + 'size in usd after pump'.print(); + first_position_after_pump.size_in_usd.print(); + + let position_info = reader + .get_position_info( + data_store, + referal_storage, + position_key_1, + market_prices, + 0, + contract_address, + true + ); + 'pnl'.print(); + position_info.base_pnl_usd.mag.print(); + + // let second_swap_pool_value_info = market_utils::get_pool_value_info( + // data_store, + // market, + // Price { min: 5000, max: 5000, }, + // Price { min: 5000, max: 5000, }, + // Price { min: 1, max: 1, }, + // keys::max_pnl_factor_for_deposits(), + // true, + // ); + + // second_swap_pool_value_info.pool_value.mag.print(); + // second_swap_pool_value_info.long_token_amount.print(); + // second_swap_pool_value_info.short_token_amount.print(); + // let (position_pnl_usd, uncapped_position_pnl_usd, size_delta_in_tokens) = + // position_utils::get_position_pnl_usd( + // data_store, market, market_prices, first_position, 5000 + // ); + // position_pnl_usd.mag.print(); + + //////////////////////////////////// CLOSING POSITION ////////////////////////////////////// + 'CLOOOOSE POSITION'.print(); + + let balance_of_mkt_before = IERC20Dispatcher { + contract_address: contract_address_const::<'USDC'>() + } + .balance_of(caller_address); + 'balance of mkt before'.print(); + balance_of_mkt_before.print(); + + start_prank(market.market_token, caller_address); + start_prank(market.long_token, caller_address); + let order_params_long_dec = CreateOrderParams { + receiver: caller_address, + callback_contract: contract_address, + ui_fee_receiver: contract_address, + market: market.market_token, + initial_collateral_token: market.long_token, + swap_path: Array32Trait::::span32(@array![market.market_token]), + size_delta_usd: 6000000000000000000000, // 6000 + initial_collateral_delta_amount: 1000000000000000000, // 1 ETH 10^18 + trigger_price: 6000, + acceptable_price: 6000, + execution_fee: 0, + callback_gas_limit: 0, + min_output_amount: 6000000000000000000000, // 6000 + order_type: OrderType::MarketDecrease(()), + decrease_position_swap_type: DecreasePositionSwapType::NoSwap(()), + is_long: true, + referral_code: 0 + }; + // Create the long order. + start_roll(order_handler.contract_address, 1940); + 'try to create order'.print(); + start_prank(order_handler.contract_address, caller_address); + let key_long_dec = order_handler.create_order(caller_address, order_params_long_dec); + 'long decrease created'.print(); + let got_order_long_dec = data_store.get_order(key_long_dec); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), ); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), 1000000); + // Execute the swap order. + + let signatures: Span = array![0].span(); + let set_price_params_dec = SetPricesParams { + signer_info: 2, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1910, 1910], + compacted_max_oracle_block_numbers: array![1920, 1920], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![1, 1], + compacted_min_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + let keeper_address = contract_address_const::<'keeper'>(); + role_store.grant_role(keeper_address, role::ORDER_KEEPER); + + stop_prank(order_handler.contract_address); + start_prank(order_handler.contract_address, keeper_address); + start_roll(order_handler.contract_address, 1945); + // TODO add real signatures check on Oracle Account + order_handler.execute_order_keeper(key_long_dec, set_price_params_dec, keeper_address); + 'long pos dec SUCCEEDED'.print(); + + + let first_position_dec = data_store.get_position(position_key_1); + + 'size tokens before'.print(); + first_position.size_in_tokens.print(); + 'size in usd before'.print(); + first_position.size_in_usd.print(); + + 'size tokens'.print(); + first_position_dec.size_in_tokens.print(); + 'size in usd'.print(); + first_position_dec.size_in_usd.print(); + + let balance_of_mkt_after = IERC20Dispatcher { + contract_address: contract_address_const::<'USDC'>() + } + .balance_of(caller_address); + 'balance of mkt after'.print(); + balance_of_mkt_after.print(); + + /// close all position + oracle.set_primary_prices(market.long_token, 7000); + + start_prank(market.market_token, caller_address); + start_prank(market.long_token, caller_address); + let order_params_long_dec_2 = CreateOrderParams { + receiver: caller_address, + callback_contract: contract_address, + ui_fee_receiver: contract_address, + market: market.market_token, + initial_collateral_token: market.long_token, + swap_path: Array32Trait::::span32(@array![market.market_token]), + size_delta_usd: 7000000000000000000000, // 6000 + initial_collateral_delta_amount: 1000000000000000000, // 1 ETH 10^18 + trigger_price: 7000, + acceptable_price: 7000, + execution_fee: 0, + callback_gas_limit: 0, + min_output_amount: 7000000000000000000000, // 6000 + order_type: OrderType::MarketDecrease(()), + decrease_position_swap_type: DecreasePositionSwapType::NoSwap(()), + is_long: true, + referral_code: 0 + }; + // Create the long order. + start_roll(order_handler.contract_address, 1950); + 'try to create order'.print(); + start_prank(order_handler.contract_address, caller_address); + let key_long_dec_2 = order_handler.create_order(caller_address, order_params_long_dec_2); + 'long decrease created'.print(); + let got_order_long_dec = data_store.get_order(key_long_dec_2); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), ); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), 1000000); + // Execute the swap order. + + let keeper_address = contract_address_const::<'keeper'>(); + role_store.grant_role(keeper_address, role::ORDER_KEEPER); + + + let signatures: Span = array![0].span(); + let set_price_params_dec2 = SetPricesParams { + signer_info: 2, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1910, 1910], + compacted_max_oracle_block_numbers: array![1920, 1920], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![1, 1], + compacted_min_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + stop_prank(order_handler.contract_address); + start_prank(order_handler.contract_address, keeper_address); + start_roll(order_handler.contract_address, 1955); + // TODO add real signatures check on Oracle Account + order_handler.execute_order_keeper(key_long_dec_2, set_price_params_dec2, keeper_address); + 'long pos dec SUCCEEDED'.print(); + + + let first_position_dec = data_store.get_position(position_key_1); + + 'size tokens before 2'.print(); + first_position.size_in_tokens.print(); + 'size in usd before 2'.print(); + first_position.size_in_usd.print(); + + 'size tokens 2'.print(); + let token_size_dec = first_position_dec.size_in_tokens; + assert(token_size_dec == 0, 'wrong token size'); + 'size in usd 2'.print(); + first_position_dec.size_in_usd.print(); + + let balance_of_mkt_after = IERC20Dispatcher { + contract_address: contract_address_const::<'USDC'>() + } + .balance_of(caller_address); + 'balance of mkt after 2'.print(); + balance_of_mkt_after.print(); + + assert(balance_of_mkt_after == 63000000000000000000000, 'wrong balance final size'); + + // ********************************************************************************************* + // * TEARDOWN * + // ********************************************************************************************* + teardown(data_store, market_factory); +} + +#[test] +fn test_long_18_close_integration() { + // ********************************************************************************************* + // * SETUP * + // ********************************************************************************************* + let ( + caller_address, + market_factory_address, + role_store_address, + data_store_address, + market_token_class_hash, + market_factory, + role_store, + data_store, + event_emitter, + exchange_router, + deposit_handler, + deposit_vault, + oracle, + order_handler, + order_vault, + reader, + referal_storage, + withdrawal_handler, + withdrawal_vault, + ) = + setup(); + + // ********************************************************************************************* + // * TEST LOGIC * + // ********************************************************************************************* + + // Create a market. + let market = data_store.get_market(create_market(market_factory)); + + // Set params in data_store + data_store.set_address(keys::fee_token(), market.index_token); + data_store.set_u256(keys::max_swap_path_length(), 5); + + // Set max pool amount. + data_store + .set_u256( + keys::max_pool_amount_key(market.market_token, market.long_token), + 5000000000000000000000000000000000000000000 //500 000 ETH + ); + data_store + .set_u256( + keys::max_pool_amount_key(market.market_token, market.short_token), + 2500000000000000000000000000000000000000000000 //250 000 000 USDC + ); + + let factor_for_deposits: felt252 = keys::max_pnl_factor_for_deposits(); + data_store + .set_u256( + keys::max_pnl_factor_key(factor_for_deposits, market.market_token, true), + 50000000000000000000000000000000000000000000000 + ); + let factor_for_withdrawal: felt252 = keys::max_pnl_factor_for_withdrawals(); + data_store + .set_u256( + keys::max_pnl_factor_key(factor_for_withdrawal, market.market_token, true), + 50000000000000000000000000000000000000000000000 + ); + + oracle.set_primary_prices(market.long_token, 5000); + oracle.set_primary_prices(market.short_token, 1); + + 'fill the pool'.print(); + // Fill the pool. + IERC20Dispatcher { contract_address: market.long_token } + .mint(market.market_token, 50000000000000000000000000000000000000); // 5 ETH + IERC20Dispatcher { contract_address: market.short_token } + .mint(market.market_token, 25000000000000000000000000000000000000000); // 25000 USDC + 'filled pool 1'.print(); + + IERC20Dispatcher { contract_address: market.long_token } + .mint(caller_address, 9999999999999000000); // 9.999 ETH + IERC20Dispatcher { contract_address: market.short_token } + .mint(caller_address, 49999999999999999000000); // 49.999 UDC + 'filled account'.print(); + + // INITIAL LONG TOKEN IN POOL : 5 ETH + // INITIAL SHORT TOKEN IN POOL : 25000 USDC + + // TODO Check why we don't need to set pool_amount_key + // // Set pool amount in data_store. + // let mut key = keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()); + + let balance_deposit_vault_before = IERC20Dispatcher { contract_address: market.short_token } + .balance_of(deposit_vault.contract_address); + let balance_caller_ETH = IERC20Dispatcher { contract_address: market.long_token } + .balance_of(caller_address); + let balance_caller_USDC = IERC20Dispatcher { contract_address: market.short_token } + .balance_of(caller_address); + + assert(balance_deposit_vault_before == 0, 'balance deposit should be 0'); + assert(balance_caller_ETH == 10000000000000000000, 'balanc ETH should be 10 ETH'); + assert(balance_caller_USDC == 50000000000000000000000, 'USDC be 50 000 USDC'); + + // Send token to deposit in the deposit vault (this should be in a multi call with create_deposit) + 'get balances'.print(); + // start_prank(market.long_token, caller_address); + // IERC20Dispatcher { contract_address: market.long_token } + // .transfer(deposit_vault.contract_address, 5000000000000000000); // 5 ETH + + // start_prank(market.short_token, caller_address); + // IERC20Dispatcher { contract_address: market.short_token } + // .transfer(deposit_vault.contract_address, 25000000000000000000000); // 25000 USDC + // 'make transfer'.print(); + + IERC20Dispatcher { contract_address: market.long_token } + .mint(deposit_vault.contract_address, 50000000000000000000000000000); // 50 000 000 000 + IERC20Dispatcher { contract_address: market.short_token } + .mint(deposit_vault.contract_address, 50000000000000000000000000000); // 50 000 000 000 + // Create Deposit + + let addresss_zero: ContractAddress = 0.try_into().unwrap(); + + let params = CreateDepositParams { + receiver: caller_address, + callback_contract: addresss_zero, + ui_fee_receiver: addresss_zero, + market: market.market_token, + initial_long_token: market.long_token, + initial_short_token: market.short_token, + long_token_swap_path: Array32Trait::::span32(@array![]), + short_token_swap_path: Array32Trait::::span32(@array![]), + min_market_tokens: 0, + execution_fee: 0, + callback_gas_limit: 0, + }; + 'create deposit'.print(); + + start_roll(deposit_handler.contract_address, 1910); + let key = deposit_handler.create_deposit(caller_address, params); + let first_deposit = data_store.get_deposit(key); + + 'created deposit'.print(); + + assert(first_deposit.account == caller_address, 'Wrong account depositer'); + assert(first_deposit.receiver == caller_address, 'Wrong account receiver'); + assert(first_deposit.initial_long_token == market.long_token, 'Wrong initial long token'); + assert( + first_deposit.initial_long_token_amount == 50000000000000000000000000000, + 'Wrong initial long token amount' + ); + assert( + first_deposit.initial_short_token_amount == 50000000000000000000000000000, + 'Wrong init short token amount' + ); + + let price_params = SetPricesParams { // TODO + signer_info: 1, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1900, 1900], + compacted_max_oracle_block_numbers: array![1910, 1910], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![18, 18], + compacted_min_prices: array![4294967346000000], // 50000000, 1000000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![4294967346000000], // 50000000, 1000000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + start_prank(role_store.contract_address, caller_address); + + role_store.grant_role(caller_address, role::ORDER_KEEPER); + role_store.grant_role(caller_address, role::ROLE_ADMIN); + role_store.grant_role(caller_address, role::CONTROLLER); + role_store.grant_role(caller_address, role::MARKET_KEEPER); + + 'execute deposit'.print(); + + // Execute Deposit + start_roll(deposit_handler.contract_address, 1915); + deposit_handler.execute_deposit(key, price_params); + + 'executed deposit'.print(); + + // let pool_value_info = market_utils::get_pool_value_info( + // data_store, + // market, + // Price { min: 2000, max: 2000 }, + // Price { min: 2000, max: 2000 }, + // Price { min: 2000, max: 2000 }, + // keys::max_pnl_factor_for_deposits(), + // true, + // ); + + // assert(pool_value_info.pool_value.mag == 42000000000000000000000, 'wrong pool value amount'); + // assert(pool_value_info.long_token_amount == 6000000000000000000, 'wrong long token amount'); + // assert(pool_value_info.short_token_amount == 30000000000000000000000, 'wrong short token amount'); + + let not_deposit = data_store.get_deposit(key); + let default_deposit: Deposit = Default::default(); + assert(not_deposit == default_deposit, 'Still existing deposit'); + + let market_token_dispatcher = IMarketTokenDispatcher { contract_address: market.market_token }; + let balance_market_token = market_token_dispatcher.balance_of(caller_address); + + assert(balance_market_token != 0, 'should receive market token'); + + let balance_deposit_vault_after = IERC20Dispatcher { contract_address: market.short_token } + .balance_of(deposit_vault.contract_address); + + // let pool_value_info = market_utils::get_pool_value_info( + // data_store, + // market, + // Price { min: 5000, max: 5000, }, + // Price { min: 5000, max: 5000, }, + // Price { min: 1, max: 1, }, + // keys::max_pnl_factor_for_deposits(), + // true, + // ); + + // pool_value_info.pool_value.mag.print(); // 10000 000000000000000000 + // pool_value_info.long_token_amount.print(); // 5 000000000000000000 + // pool_value_info.short_token_amount.print(); // 25000 000000000000000000 + + // ************************************* TEST LONG ********************************************* + + 'Begining of LONG TEST'.print(); + + let key_open_interest = keys::open_interest_key( + market.market_token, contract_address_const::<'ETH'>(), true + ); + data_store.set_u256(key_open_interest, 1); + let max_key_open_interest = keys::max_open_interest_key(market.market_token, true); + data_store.set_u256(max_key_open_interest, 1000000000000000000000000000000000000000000000000000); // 1 000 000 + + // Send token to order_vault in multicall with create_order + start_prank(contract_address_const::<'ETH'>(), caller_address); + IERC20Dispatcher { contract_address: contract_address_const::<'ETH'>() } + .transfer(order_vault.contract_address, 2000000000000000000); // 2ETH + + 'transfer made'.print(); + // Create order_params Struct + let contract_address = contract_address_const::<0>(); + start_prank(market.market_token, caller_address); + start_prank(market.long_token, caller_address); + let order_params_long = CreateOrderParams { + receiver: caller_address, + callback_contract: contract_address, + ui_fee_receiver: contract_address, + market: market.market_token, + initial_collateral_token: market.long_token, + swap_path: Array32Trait::::span32(@array![]), + size_delta_usd: 10000000000000000000000, + initial_collateral_delta_amount: 2000000000000000000, // 10^18 + trigger_price: 5000, + acceptable_price: 5500, + execution_fee: 0, + callback_gas_limit: 0, + min_output_amount: 0, + order_type: OrderType::MarketIncrease(()), + decrease_position_swap_type: DecreasePositionSwapType::NoSwap(()), + is_long: true, + referral_code: 0 + }; + // Create the swap order. + start_roll(order_handler.contract_address, 1930); + 'try to create prder'.print(); + start_prank(order_handler.contract_address, caller_address); + let key_long = order_handler.create_order(caller_address, order_params_long); + 'long created'.print(); + let got_order_long = data_store.get_order(key_long); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), ); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), 1000000); + // Execute the swap order. + + data_store + .set_u256( + keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), + 50000000000000000000000000000 + ); + data_store + .set_u256( + keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), + 50000000000000000000000000000 + ); + + let signatures: Span = array![0].span(); + let set_price_params = SetPricesParams { + signer_info: 2, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1910, 1910], + compacted_max_oracle_block_numbers: array![1920, 1920], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![1, 1], + compacted_min_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + let keeper_address = contract_address_const::<'keeper'>(); + role_store.grant_role(keeper_address, role::ORDER_KEEPER); + + stop_prank(order_handler.contract_address); + start_prank(order_handler.contract_address, keeper_address); + start_roll(order_handler.contract_address, 1935); + // TODO add real signatures check on Oracle Account + order_handler.execute_order_keeper(key_long, set_price_params, keeper_address); + 'long position SUCCEEDED'.print(); + let position_key = data_store.get_account_position_keys(caller_address, 0, 10); + + let position_key_1: felt252 = *position_key.at(0); + let first_position = data_store.get_position(position_key_1); + let market_prices = market_utils::MarketPrices { + index_token_price: Price { min: 8000, max: 8000, }, + long_token_price: Price { min: 8000, max: 8000, }, + short_token_price: Price { min: 1, max: 1, }, + }; + 'size tokens'.print(); + first_position.size_in_tokens.print(); + 'size in usd'.print(); + first_position.size_in_usd.print(); + 'OKAAAAAYYYYYY'.print(); + 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(); + 'size in usd after pump'.print(); + first_position_after_pump.size_in_usd.print(); + + let position_info = reader + .get_position_info( + data_store, + referal_storage, + position_key_1, + market_prices, + 0, + contract_address, + true + ); + 'pnl'.print(); + position_info.base_pnl_usd.mag.print(); + + // let second_swap_pool_value_info = market_utils::get_pool_value_info( + // data_store, + // market, + // Price { min: 5000, max: 5000, }, + // Price { min: 5000, max: 5000, }, + // Price { min: 1, max: 1, }, + // keys::max_pnl_factor_for_deposits(), + // true, + // ); + + // second_swap_pool_value_info.pool_value.mag.print(); + // second_swap_pool_value_info.long_token_amount.print(); + // second_swap_pool_value_info.short_token_amount.print(); + // let (position_pnl_usd, uncapped_position_pnl_usd, size_delta_in_tokens) = + // position_utils::get_position_pnl_usd( + // data_store, market, market_prices, first_position, 5000 + // ); + // position_pnl_usd.mag.print(); + + //////////////////////////////////// CLOSING POSITION ////////////////////////////////////// + 'CLOOOOSE POSITION'.print(); + + let balance_of_mkt_before = IERC20Dispatcher { + contract_address: contract_address_const::<'USDC'>() + } + .balance_of(caller_address); + 'balance of mkt before'.print(); + balance_of_mkt_before.print(); + + start_prank(market.market_token, caller_address); + start_prank(market.long_token, caller_address); + let order_params_long_dec = CreateOrderParams { + receiver: caller_address, + callback_contract: contract_address, + ui_fee_receiver: contract_address, + market: market.market_token, + initial_collateral_token: market.long_token, + swap_path: Array32Trait::::span32(@array![market.market_token]), + size_delta_usd: 12000000000000000000000, // 12000 + initial_collateral_delta_amount: 2000000000000000000, // 2 ETH 10^18 + trigger_price: 6000, + acceptable_price: 6000, + execution_fee: 0, + callback_gas_limit: 0, + min_output_amount: 12000000000000000000000, // 12000 + order_type: OrderType::MarketDecrease(()), + decrease_position_swap_type: DecreasePositionSwapType::NoSwap(()), + is_long: true, + referral_code: 0 + }; + // Create the long order. + start_roll(order_handler.contract_address, 1940); + 'try to create order'.print(); + start_prank(order_handler.contract_address, caller_address); + let key_long_dec = order_handler.create_order(caller_address, order_params_long_dec); + 'long decrease created'.print(); + let got_order_long_dec = data_store.get_order(key_long_dec); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'USDC'>()), ); + // data_store.set_u256(keys::pool_amount_key(market.market_token, contract_address_const::<'ETH'>()), 1000000); + // Execute the swap order. + + let signatures: Span = array![0].span(); + let set_price_params_dec = SetPricesParams { + signer_info: 2, + tokens: array![contract_address_const::<'ETH'>(), contract_address_const::<'USDC'>()], + compacted_min_oracle_block_numbers: array![1910, 1910], + compacted_max_oracle_block_numbers: array![1920, 1920], + compacted_oracle_timestamps: array![9999, 9999], + compacted_decimals: array![1, 1], + compacted_min_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_min_prices_indexes: array![0], + compacted_max_prices: array![2147483648010000], // 500000, 10000 compacted + compacted_max_prices_indexes: array![0], + signatures: array![ + array!['signatures1', 'signatures2'].span(), array!['signatures1', 'signatures2'].span() + ], + price_feed_tokens: array![] + }; + + let keeper_address = contract_address_const::<'keeper'>(); + role_store.grant_role(keeper_address, role::ORDER_KEEPER); + + stop_prank(order_handler.contract_address); + start_prank(order_handler.contract_address, keeper_address); + start_roll(order_handler.contract_address, 1945); + // TODO add real signatures check on Oracle Account + order_handler.execute_order_keeper(key_long_dec, set_price_params_dec, keeper_address); + 'long pos dec SUCCEEDED'.print(); + + let first_position_dec = data_store.get_position(position_key_1); 'size tokens before'.print();