From 255467fb0c029d2206c8b8bc0fc38ef81a466748 Mon Sep 17 00:00:00 2001 From: maxrobot Date: Thu, 31 Oct 2024 20:16:10 +0000 Subject: [PATCH] feat: migration test --- contracts/swap/src/queries.rs | 205 +-- contracts/swap/src/swap.rs | 17 +- .../src/testing/integration_logic_tests.rs | 1593 ----------------- ...egration_realistic_tests_exact_quantity.rs | 748 ++------ contracts/swap/src/testing/migration_test.rs | 22 +- contracts/swap/src/testing/mod.rs | 3 +- contracts/swap/src/testing/queries_tests.rs | 22 +- contracts/swap/src/testing/test_utils.rs | 223 +-- 8 files changed, 271 insertions(+), 2562 deletions(-) delete mode 100644 contracts/swap/src/testing/integration_logic_tests.rs diff --git a/contracts/swap/src/queries.rs b/contracts/swap/src/queries.rs index dbce82d..1d81edf 100644 --- a/contracts/swap/src/queries.rs +++ b/contracts/swap/src/queries.rs @@ -1,7 +1,5 @@ use cosmwasm_std::{Addr, Deps, Env, StdError, StdResult}; -use injective_cosmwasm::{ - InjectiveQuerier, InjectiveQueryWrapper, MarketId, OrderSide, PriceLevel, SpotMarket, -}; +use injective_cosmwasm::{InjectiveQuerier, InjectiveQueryWrapper, MarketId, OrderSide, PriceLevel, SpotMarket}; use injective_math::utils::round_to_min_tick; use injective_math::FPDecimal; @@ -65,12 +63,8 @@ pub fn estimate_swap_result( env, &step, match swap_quantity { - SwapQuantity::InputQuantity(_) => { - SwapEstimationAmount::InputQuantity(current_swap.clone()) - } - SwapQuantity::OutputQuantity(_) => { - SwapEstimationAmount::ReceiveQuantity(current_swap.clone()) - } + SwapQuantity::InputQuantity(_) => SwapEstimationAmount::InputQuantity(current_swap.clone()), + SwapQuantity::OutputQuantity(_) => SwapEstimationAmount::ReceiveQuantity(current_swap.clone()), }, true, )?; @@ -78,9 +72,10 @@ pub fn estimate_swap_result( current_swap.amount = swap_estimate.result_quantity; current_swap.denom = swap_estimate.result_denom; - let step_fee = swap_estimate - .fee_estimate - .expect("fee estimate should be available"); + deps.api.debug(&format!("step: {:?}", step)); + deps.api.debug(&format!("current_swap: {:?}", current_swap)); + + let step_fee = swap_estimate.fee_estimate.expect("fee estimate should be available"); fees.push(step_fee); } @@ -105,34 +100,21 @@ pub fn estimate_single_swap_execution( SwapEstimationAmount::ReceiveQuantity(fp) => fp, }; - let market = querier - .query_spot_market(market_id)? - .market - .expect("market should be available"); + let market = querier.query_spot_market(market_id)?.market.expect("market should be available"); - let has_invalid_denom = - balance_in.denom != market.quote_denom && balance_in.denom != market.base_denom; + let has_invalid_denom = balance_in.denom != market.quote_denom && balance_in.denom != market.base_denom; if has_invalid_denom { - return Err(StdError::generic_err( - "Invalid swap denom - neither base nor quote", - )); + return Err(StdError::generic_err("Invalid swap denom - neither base nor quote")); } let config = CONFIG.load(deps.storage)?; let is_self_relayer = config.fee_recipient == env.contract.address; - let fee_multiplier = querier - .query_market_atomic_execution_fee_multiplier(market_id)? - .multiplier; + let fee_multiplier = querier.query_market_atomic_execution_fee_multiplier(market_id)?.multiplier; - let fee_percent = market.taker_fee_rate - * fee_multiplier - * (FPDecimal::ONE - get_effective_fee_discount_rate(&market, is_self_relayer)); + let fee_percent = market.taker_fee_rate * fee_multiplier * (FPDecimal::ONE - get_effective_fee_discount_rate(&market, is_self_relayer)); - let is_estimating_from_target = matches!( - swap_estimation_amount, - SwapEstimationAmount::ReceiveQuantity(_) - ); + let is_estimating_from_target = matches!(swap_estimation_amount, SwapEstimationAmount::ReceiveQuantity(_)); let is_buy = if is_estimating_from_target { balance_in.denom == market.base_denom @@ -166,12 +148,7 @@ fn estimate_execution_buy_from_source( ) -> StdResult { let available_swap_quote_funds = input_quote_quantity / (FPDecimal::ONE + fee_percent); - let orders = querier.query_spot_market_orderbook( - &market.market_id, - OrderSide::Sell, - None, - Some(available_swap_quote_funds), - )?; + let orders = querier.query_spot_market_orderbook(&market.market_id, OrderSide::Sell, None, Some(available_swap_quote_funds))?; let top_orders = get_minimum_liquidity_levels( deps, &orders.sells_price_level, @@ -181,8 +158,7 @@ fn estimate_execution_buy_from_source( )?; // lets overestimate amount for buys means rounding average price up -> higher buy price -> worse - let average_price = - get_average_price_from_orders(&top_orders, market.min_price_tick_size, true); + let average_price = get_average_price_from_orders(&top_orders, market.min_price_tick_size, true); let worst_price = get_worst_price_from_orders(&top_orders); let expected_base_quantity = available_swap_quote_funds / average_price; @@ -209,6 +185,9 @@ fn estimate_execution_buy_from_source( ))); } + deps.api.debug(&format!("average_price: {average_price}")); + deps.api.debug(&format!("result_quantity: {result_quantity}")); + Ok(StepExecutionEstimate { worst_price, result_quantity, @@ -230,15 +209,9 @@ fn estimate_execution_buy_from_target( fee_percent: FPDecimal, is_simulation: bool, ) -> StdResult { - let rounded_target_base_output_quantity = - round_up_to_min_tick(target_base_output_quantity, market.min_quantity_tick_size); - - let orders = querier.query_spot_market_orderbook( - &market.market_id, - OrderSide::Sell, - Some(rounded_target_base_output_quantity), - None, - )?; + let rounded_target_base_output_quantity = round_up_to_min_tick(target_base_output_quantity, market.min_quantity_tick_size); + + let orders = querier.query_spot_market_orderbook(&market.market_id, OrderSide::Sell, Some(rounded_target_base_output_quantity), None)?; let top_orders = get_minimum_liquidity_levels( deps, &orders.sells_price_level, @@ -248,8 +221,7 @@ fn estimate_execution_buy_from_target( )?; // lets overestimate amount for buys means rounding average price up -> higher buy price -> worse - let average_price = - get_average_price_from_orders(&top_orders, market.min_price_tick_size, true); + let average_price = get_average_price_from_orders(&top_orders, market.min_price_tick_size, true); let worst_price = get_worst_price_from_orders(&top_orders); let expected_exchange_quote_quantity = rounded_target_base_output_quantity * average_price; @@ -257,8 +229,7 @@ fn estimate_execution_buy_from_target( let required_input_quote_quantity = expected_exchange_quote_quantity + fee_estimate; // check if user funds + contract funds are enough to create order - let required_funds = - worst_price * rounded_target_base_output_quantity * (FPDecimal::ONE + fee_percent); + let required_funds = worst_price * rounded_target_base_output_quantity * (FPDecimal::ONE + fee_percent); let funds_in_contract = deps .querier @@ -304,31 +275,12 @@ fn estimate_execution_buy( SwapEstimationAmount::ReceiveQuantity(fp) => fp, }; - let is_estimating_from_target = matches!( - swap_estimation_amount, - SwapEstimationAmount::ReceiveQuantity(_) - ); + let is_estimating_from_target = matches!(swap_estimation_amount, SwapEstimationAmount::ReceiveQuantity(_)); if is_estimating_from_target { - estimate_execution_buy_from_target( - deps, - querier, - contract_address, - market, - amount_coin.amount, - fee_percent, - is_simulation, - ) + estimate_execution_buy_from_target(deps, querier, contract_address, market, amount_coin.amount, fee_percent, is_simulation) } else { - estimate_execution_buy_from_source( - deps, - querier, - contract_address, - market, - amount_coin.amount, - fee_percent, - is_simulation, - ) + estimate_execution_buy_from_source(deps, querier, contract_address, market, amount_coin.amount, fee_percent, is_simulation) } } @@ -339,12 +291,7 @@ fn estimate_execution_sell_from_source( input_base_quantity: FPDecimal, fee_percent: FPDecimal, ) -> StdResult { - let orders = querier.query_spot_market_orderbook( - &market.market_id, - OrderSide::Buy, - Some(input_base_quantity), - None, - )?; + let orders = querier.query_spot_market_orderbook(&market.market_id, OrderSide::Buy, Some(input_base_quantity), None)?; let top_orders = get_minimum_liquidity_levels( deps, @@ -355,14 +302,18 @@ fn estimate_execution_sell_from_source( )?; // lets overestimate amount for sells means rounding average price down -> lower sell price -> worse - let average_price = - get_average_price_from_orders(&top_orders, market.min_price_tick_size, false); + let average_price = get_average_price_from_orders(&top_orders, market.min_price_tick_size, false); let worst_price = get_worst_price_from_orders(&top_orders); + deps.api.debug(&format!("average_price: {average_price}")); + deps.api.debug(&format!("input_base_quantity: {input_base_quantity}")); + let expected_exchange_quantity = input_base_quantity * average_price; let fee_estimate = expected_exchange_quantity * fee_percent; let expected_quantity = expected_exchange_quantity - fee_estimate; + deps.api.debug(&format!("input_base_quantity: {expected_exchange_quantity}")); + Ok(StepExecutionEstimate { worst_price, result_quantity: expected_quantity, @@ -382,16 +333,10 @@ fn estimate_execution_sell_from_target( target_quote_output_quantity: FPDecimal, fee_percent: FPDecimal, ) -> StdResult { - let required_swap_quantity_in_quote = - target_quote_output_quantity / (FPDecimal::ONE - fee_percent); + let required_swap_quantity_in_quote = target_quote_output_quantity / (FPDecimal::ONE - fee_percent); let required_fee = required_swap_quantity_in_quote - target_quote_output_quantity; - let orders = querier.query_spot_market_orderbook( - &market.market_id, - OrderSide::Buy, - None, - Some(required_swap_quantity_in_quote), - )?; + let orders = querier.query_spot_market_orderbook(&market.market_id, OrderSide::Buy, None, Some(required_swap_quantity_in_quote))?; let top_orders = get_minimum_liquidity_levels( deps, &orders.buys_price_level, @@ -401,18 +346,14 @@ fn estimate_execution_sell_from_target( )?; // lets overestimate amount for sells means rounding average price down -> lower sell price -> worse - let average_price = - get_average_price_from_orders(&top_orders, market.min_price_tick_size, false); + let average_price = get_average_price_from_orders(&top_orders, market.min_price_tick_size, false); let worst_price = get_worst_price_from_orders(&top_orders); let required_swap_input_quantity_in_base = required_swap_quantity_in_quote / average_price; Ok(StepExecutionEstimate { worst_price, - result_quantity: round_up_to_min_tick( - required_swap_input_quantity_in_base, - market.min_quantity_tick_size, - ), + result_quantity: round_up_to_min_tick(required_swap_input_quantity_in_base, market.min_quantity_tick_size), result_denom: market.base_denom.to_string(), is_buy_order: false, fee_estimate: Some(FPCoin { @@ -434,10 +375,7 @@ fn estimate_execution_sell( SwapEstimationAmount::ReceiveQuantity(fp) => fp, }; - let is_estimating_from_target = matches!( - swap_estimation_amount, - SwapEstimationAmount::ReceiveQuantity(_) - ); + let is_estimating_from_target = matches!(swap_estimation_amount, SwapEstimationAmount::ReceiveQuantity(_)); if is_estimating_from_target { estimate_execution_sell_from_target(deps, querier, market, amount_coin.amount, fee_percent) @@ -458,11 +396,7 @@ pub fn get_minimum_liquidity_levels( for level in levels { let value = calc(level); - assert_ne!( - value, - FPDecimal::ZERO, - "Price level with zero value, this should not happen" - ); + assert_ne!(value, FPDecimal::ZERO, "Price level with zero value, this should not happen"); let order_to_add = if sum + value > total { let excess = value + sum - total; @@ -488,24 +422,16 @@ pub fn get_minimum_liquidity_levels( } if sum < total { - return Err(StdError::generic_err( - "Not enough liquidity to fulfill order", - )); + return Err(StdError::generic_err("Not enough liquidity to fulfill order")); } Ok(orders) } -fn get_average_price_from_orders( - levels: &[PriceLevel], - min_price_tick_size: FPDecimal, - is_rounding_up: bool, -) -> FPDecimal { +fn get_average_price_from_orders(levels: &[PriceLevel], min_price_tick_size: FPDecimal, is_rounding_up: bool) -> FPDecimal { let (total_quantity, total_notional) = levels .iter() - .fold((FPDecimal::ZERO, FPDecimal::ZERO), |acc, pl| { - (acc.0 + pl.q, acc.1 + pl.p * pl.q) - }); + .fold((FPDecimal::ZERO, FPDecimal::ZERO), |acc, pl| (acc.0 + pl.q, acc.1 + pl.p * pl.q)); assert_ne!( total_quantity, @@ -543,11 +469,7 @@ mod tests { #[test] fn test_average_price_simple() { - let levels = vec![ - create_price_level(1, 200), - create_price_level(2, 200), - create_price_level(3, 200), - ]; + let levels = vec![create_price_level(1, 200), create_price_level(2, 200), create_price_level(3, 200)]; let avg = get_average_price_from_orders(&levels, FPDecimal::must_from_str("0.01"), false); assert_eq!(avg, FPDecimal::from(2u128)); @@ -555,11 +477,7 @@ mod tests { #[test] fn test_average_price_simple_round_down() { - let levels = vec![ - create_price_level(1, 300), - create_price_level(2, 200), - create_price_level(3, 100), - ]; + let levels = vec![create_price_level(1, 300), create_price_level(2, 200), create_price_level(3, 100)]; let avg = get_average_price_from_orders(&levels, FPDecimal::must_from_str("0.01"), false); assert_eq!(avg, FPDecimal::must_from_str("1.66")); //we round down @@ -567,11 +485,7 @@ mod tests { #[test] fn test_average_price_simple_round_up() { - let levels = vec![ - create_price_level(1, 300), - create_price_level(2, 200), - create_price_level(3, 100), - ]; + let levels = vec![create_price_level(1, 300), create_price_level(2, 200), create_price_level(3, 100)]; let avg = get_average_price_from_orders(&levels, FPDecimal::must_from_str("0.01"), true); assert_eq!(avg, FPDecimal::must_from_str("1.67")); //we round up @@ -579,11 +493,7 @@ mod tests { #[test] fn test_worst_price() { - let levels = vec![ - create_price_level(1, 100), - create_price_level(2, 200), - create_price_level(3, 300), - ]; + let levels = vec![create_price_level(1, 100), create_price_level(2, 200), create_price_level(3, 300)]; let worst = get_worst_price_from_orders(&levels); assert_eq!(worst, FPDecimal::from(3u128)); @@ -601,19 +511,12 @@ mod tests { FPDecimal::must_from_str("0.01"), ); assert!(result.is_err()); - assert_eq!( - result.unwrap_err(), - StdError::generic_err("Not enough liquidity to fulfill order") - ); + assert_eq!(result.unwrap_err(), StdError::generic_err("Not enough liquidity to fulfill order")); } #[test] fn test_find_minimum_orders_with_gaps() { - let levels = vec![ - create_price_level(1, 100), - create_price_level(3, 300), - create_price_level(5, 500), - ]; + let levels = vec![create_price_level(1, 100), create_price_level(3, 300), create_price_level(5, 500)]; let result = get_minimum_liquidity_levels( &inj_mock_deps(|_| {}).as_ref(), @@ -632,11 +535,7 @@ mod tests { #[test] fn test_find_minimum_buy_orders_not_consuming_fully() { - let levels = vec![ - create_price_level(1, 100), - create_price_level(3, 300), - create_price_level(5, 500), - ]; + let levels = vec![create_price_level(1, 100), create_price_level(3, 300), create_price_level(5, 500)]; let result = get_minimum_liquidity_levels( &inj_mock_deps(|_| {}).as_ref(), @@ -658,11 +557,7 @@ mod tests { #[test] fn test_find_minimum_sell_orders_not_consuming_fully() { - let buy_levels = vec![ - create_price_level(5, 500), - create_price_level(3, 300), - create_price_level(1, 100), - ]; + let buy_levels = vec![create_price_level(5, 500), create_price_level(3, 300), create_price_level(1, 100)]; let result = get_minimum_liquidity_levels( &inj_mock_deps(|_| {}).as_ref(), diff --git a/contracts/swap/src/swap.rs b/contracts/swap/src/swap.rs index afff9a4..89b9826 100644 --- a/contracts/swap/src/swap.rs +++ b/contracts/swap/src/swap.rs @@ -158,7 +158,7 @@ pub fn execute_swap_step( pub fn handle_atomic_order_reply(deps: DepsMut, env: Env, msg: Reply) -> Result, ContractError> { let dec_scale_factor = dec_scale_factor(); // protobuf serializes Dec values with extra 10^18 factor - let order_response = MsgCreateSpotMarketOrderResponse::decode(msg.payload.as_slice()).unwrap(); + let order_response = parse_market_order_response(msg)?; let trade_data = match order_response.results { Some(trade_data) => Ok(trade_data), @@ -256,3 +256,18 @@ pub fn handle_atomic_order_reply(deps: DepsMut, env: Env, Ok(response) } + +pub fn parse_market_order_response(msg: Reply) -> StdResult { + let binding = msg.result.into_result().map_err(ContractError::SubMsgFailure).unwrap(); + + let first_messsage = binding.msg_responses.first(); + + let order_response = MsgCreateSpotMarketOrderResponse::decode(first_messsage.unwrap().value.as_slice()) + .map_err(|err| ContractError::ReplyParseFailure { + id: msg.id, + err: err.to_string(), + }) + .unwrap(); + + Ok(order_response) +} diff --git a/contracts/swap/src/testing/integration_logic_tests.rs b/contracts/swap/src/testing/integration_logic_tests.rs deleted file mode 100644 index 2c76100..0000000 --- a/contracts/swap/src/testing/integration_logic_tests.rs +++ /dev/null @@ -1,1593 +0,0 @@ -use crate::msg::{ExecuteMsg, QueryMsg}; -use crate::testing::test_utils::{ - are_fpdecimals_approximately_equal, assert_fee_is_as_expected, create_limit_order, fund_account_with_some_inj, human_to_dec, - init_contract_with_fee_recipient_and_get_address, init_default_signer_account, init_default_validator_account, init_rich_account, - init_self_relaying_contract_and_get_address, launch_realistic_atom_usdt_spot_market, launch_realistic_usdt_usdc_spot_market, - launch_realistic_weth_usdt_spot_market, must_init_account_with_funds, pause_spot_market, query_all_bank_balances, query_bank_balance, - set_route_and_assert_success, str_coin, Decimals, OrderSide, ATOM, DEFAULT_ATOMIC_MULTIPLIER, DEFAULT_RELAYER_SHARE, - DEFAULT_SELF_RELAYING_FEE_PART, DEFAULT_TAKER_FEE, ETH, INJ, USDC, USDT, -}; -use crate::types::{FPCoin, SwapEstimationResult}; -use cosmwasm_std::{coin, Addr}; -use injective_math::{round_to_min_tick, FPDecimal}; -use injective_test_tube::RunnerError::{ExecuteError, QueryError}; -use injective_test_tube::{Account, Bank, Exchange, InjectiveTestApp, Module, RunnerError, RunnerResult, SigningAccount, Wasm}; -use injective_testing::test_tube::exchange::launch_spot_market; - -/* - This suite of tests focuses on calculation logic itself and doesn't attempt to use neither - realistic market configuration nor order prices, so that we don't have to deal with scaling issues. - - Hardcoded values used in these tests come from the first tab of this spreadsheet: - https://docs.google.com/spreadsheets/d/1-0epjX580nDO_P2mm1tSjhvjJVppsvrO1BC4_wsBeyA/edit?usp=sharing -*/ - -#[test] -fn it_executes_a_swap_between_two_base_assets_with_multiple_price_levels() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - // let spot_market_1_id = launch_spot_market_custom(&exchange, &owner, "".to_string(), ETH, USDT); - // let spot_market_2_id = launch_spot_market_custom(&exchange, &owner, ATOM, USDT); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let mut query_result: SwapEstimationResult = wasm - .query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ) - .unwrap(); - - assert_eq!( - query_result.result_quantity, - FPDecimal::must_from_str("2893.886"), //slightly rounded down - "incorrect swap result estimate returned by query" - ); - - assert_eq!(query_result.expected_fees.len(), 2, "Wrong number of fee denoms received"); - - let mut expected_fees = vec![ - FPCoin { - amount: FPDecimal::must_from_str("3541.5"), - denom: "usdt".to_string(), - }, - FPCoin { - amount: FPDecimal::must_from_str("3530.891412"), - denom: "usdt".to_string(), - }, - ]; - - assert_fee_is_as_expected(&mut query_result.expected_fees, &mut expected_fees, FPDecimal::must_from_str("0.000001")); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - - wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[coin(12, ETH)], - &swapper, - ) - .unwrap(); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::ZERO, "some of the original amount wasn't swapped"); - assert_eq!(to_balance, FPDecimal::must_from_str("2893"), "swapper did not receive expected amount"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - - let contract_balance_usdt_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); - let contract_balance_usdt_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - - assert!( - contract_balance_usdt_after >= contract_balance_usdt_before, - "Contract lost some money after swap. Balance before: {contract_balance_usdt_before}, after: {contract_balance_usdt_after}", - ); - - let max_diff = human_to_dec("0.00001", Decimals::Six); - - assert!( - are_fpdecimals_approximately_equal(contract_balance_usdt_after, contract_balance_usdt_before, max_diff,), - "Contract balance changed too much. Before: {}, After: {}", - contract_balances_before[0].amount, - contract_balances_after[0].amount - ); -} - -#[test] -fn it_executes_a_swap_between_two_base_assets_with_single_price_level() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(3, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let expected_atom_estimate_quantity = FPDecimal::must_from_str("751.492"); - let mut query_result: SwapEstimationResult = wasm - .query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(3u128), - }, - ) - .unwrap(); - - assert_eq!( - query_result.result_quantity, expected_atom_estimate_quantity, - "incorrect swap result estimate returned by query" - ); - - let mut expected_fees = vec![ - FPCoin { - amount: FPDecimal::must_from_str("904.5"), - denom: "usdt".to_string(), - }, - FPCoin { - amount: FPDecimal::must_from_str("901.790564"), - denom: "usdt".to_string(), - }, - ]; - - assert_fee_is_as_expected( - &mut query_result.expected_fees, - &mut expected_fees, - human_to_dec("0.00001", Decimals::Six), - ); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(750u128), - }, - &[coin(3, ETH)], - &swapper, - ) - .unwrap(); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::ZERO, "some of the original amount wasn't swapped"); - assert_eq!( - to_balance, - expected_atom_estimate_quantity.int(), - "swapper did not receive expected amount" - ); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_executes_swap_between_markets_using_different_quote_assets() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let spot_market_3_id = launch_realistic_usdt_usdc_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("100_000", USDC, Decimals::Six), str_coin("100_000", USDT, Decimals::Six)], - ); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_3_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - //USDT-USDC - create_limit_order(&app, &trader3, &spot_market_3_id, OrderSide::Sell, 1, 100_000_000); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let mut query_result: SwapEstimationResult = wasm - .query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ) - .unwrap(); - - // expected amount is a bit lower, even though 1 USDT = 1 USDC, because of the fees - assert_eq!( - query_result.result_quantity, - FPDecimal::must_from_str("2889.64"), - "incorrect swap result estimate returned by query" - ); - - let mut expected_fees = vec![ - FPCoin { - amount: FPDecimal::must_from_str("3541.5"), - denom: "usdt".to_string(), - }, - FPCoin { - amount: FPDecimal::must_from_str("3530.891412"), - denom: "usdt".to_string(), - }, - FPCoin { - amount: FPDecimal::must_from_str("3525.603007"), - denom: "usdc".to_string(), - }, - ]; - - assert_fee_is_as_expected( - &mut query_result.expected_fees, - &mut expected_fees, - human_to_dec("0.000001", Decimals::Six), - ); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 2, "wrong number of denoms in contract balances"); - - wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[coin(12, ETH)], - &swapper, - ) - .unwrap(); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::ZERO, "some of the original amount wasn't swapped"); - assert_eq!(to_balance, FPDecimal::must_from_str("2889"), "swapper did not receive expected amount"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 2, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_reverts_swap_between_markets_using_different_quote_asset_if_one_quote_buffer_is_insufficient() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let spot_market_3_id = launch_realistic_usdt_usdc_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("0.0001", USDC, Decimals::Six), str_coin("100_000", USDT, Decimals::Six)], - ); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_3_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - //USDT-USDC - create_limit_order(&app, &trader3, &spot_market_3_id, OrderSide::Sell, 1, 100_000_000); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let query_result: RunnerResult = wasm.query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ); - - assert!(query_result.is_err(), "swap should have failed"); - assert!( - query_result.unwrap_err().to_string().contains("Swap amount too high"), - "incorrect query result error message" - ); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 2, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[coin(12, ETH)], - &swapper, - ); - - assert!(execute_result.is_err(), "swap should have failed"); - assert!( - execute_result.unwrap_err().to_string().contains("Swap amount too high"), - "incorrect query result error message" - ); - - let source_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let target_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!( - source_balance, - FPDecimal::must_from_str("12"), - "source balance should not have changed after failed swap" - ); - assert_eq!( - target_balance, - FPDecimal::ZERO, - "target balance should not have changed after failed swap" - ); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 2, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_executes_a_sell_of_base_asset_to_receive_min_output_quantity() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success(&wasm, &owner, &contr_addr, ETH, USDT, vec![spot_market_1_id.as_str().into()]); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let mut query_result: SwapEstimationResult = wasm - .query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: USDT.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ) - .unwrap(); - - // calculate how much can be USDT can be bought for 12 ETH without fees - let orders_nominal_total_value = FPDecimal::from(201_000u128) * FPDecimal::from(5u128) - + FPDecimal::from(195_000u128) * FPDecimal::from(4u128) - + FPDecimal::from(192_000u128) * FPDecimal::from(3u128); - let expected_target_quantity = orders_nominal_total_value - * (FPDecimal::ONE - - FPDecimal::must_from_str(&format!( - "{}", - DEFAULT_TAKER_FEE * DEFAULT_ATOMIC_MULTIPLIER * DEFAULT_SELF_RELAYING_FEE_PART - ))); - - assert_eq!( - query_result.result_quantity, expected_target_quantity, - "incorrect swap result estimate returned by query" - ); - - let mut expected_fees = vec![FPCoin { - amount: FPDecimal::must_from_str("3541.5"), - denom: "usdt".to_string(), - }]; - - assert_fee_is_as_expected(&mut query_result.expected_fees, &mut expected_fees, FPDecimal::must_from_str("0.000001")); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: USDT.to_string(), - min_output_quantity: FPDecimal::from(2357458u128), - }, - &[coin(12, ETH)], - &swapper, - ) - .unwrap(); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, USDT, swapper.address().as_str()); - let expected_execute_result = expected_target_quantity.int(); - - assert_eq!(from_balance, FPDecimal::ZERO, "some of the original amount wasn't swapped"); - assert_eq!(to_balance, expected_execute_result, "swapper did not receive expected amount"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_executes_a_buy_of_base_asset_to_receive_min_output_quantity() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success(&wasm, &owner, &contr_addr, ETH, USDT, vec![spot_market_1_id.as_str().into()]); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - - create_limit_order(&app, &trader1, &spot_market_1_id, OrderSide::Sell, 201_000, 5); - create_limit_order(&app, &trader2, &spot_market_1_id, OrderSide::Sell, 195_000, 4); - create_limit_order(&app, &trader2, &spot_market_1_id, OrderSide::Sell, 192_000, 3); - - app.increase_time(1); - - let swapper_usdt = 2_360_995; - let swapper = must_init_account_with_funds(&app, &[coin(swapper_usdt, USDT), str_coin("500_000", INJ, Decimals::Eighteen)]); - - // calculate how much ETH we can buy with USDT we have - let available_usdt_after_fee = FPDecimal::from(swapper_usdt) - / (FPDecimal::ONE - + FPDecimal::must_from_str(&format!( - "{}", - DEFAULT_TAKER_FEE * DEFAULT_ATOMIC_MULTIPLIER * DEFAULT_SELF_RELAYING_FEE_PART - ))); - let usdt_left_for_most_expensive_order = - available_usdt_after_fee - (FPDecimal::from(195_000u128) * FPDecimal::from(4u128) + FPDecimal::from(192_000u128) * FPDecimal::from(3u128)); - let most_expensive_order_quantity = usdt_left_for_most_expensive_order / FPDecimal::from(201_000u128); - let expected_quantity = most_expensive_order_quantity + (FPDecimal::from(4u128) + FPDecimal::from(3u128)); - - // round to min tick - let expected_quantity_rounded = round_to_min_tick(expected_quantity, FPDecimal::must_from_str("0.001")); - - // calculate dust notional value as this will be the portion of user's funds that will stay in the contract - let dust = expected_quantity - expected_quantity_rounded; - // we need to use worst priced order - let dust_value = dust * FPDecimal::from(201_000u128); - - let mut query_result: SwapEstimationResult = wasm - .query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: USDT.to_string(), - target_denom: ETH.to_string(), - from_quantity: FPDecimal::from(swapper_usdt), - }, - ) - .unwrap(); - - assert_eq!( - query_result.result_quantity, expected_quantity_rounded, - "incorrect swap result estimate returned by query" - ); - - let mut expected_fees = vec![FPCoin { - amount: FPDecimal::must_from_str("3536.188217"), - denom: "usdt".to_string(), - }]; - - assert_fee_is_as_expected(&mut query_result.expected_fees, &mut expected_fees, FPDecimal::must_from_str("0.000001")); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ETH.to_string(), - min_output_quantity: FPDecimal::from(11u128), - }, - &[coin(swapper_usdt, USDT)], - &swapper, - ) - .unwrap(); - - let from_balance = query_bank_balance(&bank, USDT, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let expected_execute_result = expected_quantity.int(); - - assert_eq!(from_balance, FPDecimal::ZERO, "some of the original amount wasn't swapped"); - assert_eq!(to_balance, expected_execute_result, "swapper did not receive expected amount"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - let mut expected_contract_balances_after = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()) + dust_value; - expected_contract_balances_after = expected_contract_balances_after.int(); - - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()), - expected_contract_balances_after, - "contract balance changed unexpectedly after swap" - ); -} - -#[test] -fn it_executes_a_swap_between_base_assets_with_external_fee_recipient() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let fee_recipient = must_init_account_with_funds(&app, &[]); - let contr_addr = init_contract_with_fee_recipient_and_get_address(&wasm, &owner, &[str_coin("10_000", USDT, Decimals::Six)], &fee_recipient); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - // calculate relayer's share of the fee based on assumptions that all orders are matched - let buy_orders_nominal_total_value = FPDecimal::from(201_000u128) * FPDecimal::from(5u128) - + FPDecimal::from(195_000u128) * FPDecimal::from(4u128) - + FPDecimal::from(192_000u128) * FPDecimal::from(3u128); - let relayer_sell_fee = buy_orders_nominal_total_value - * FPDecimal::must_from_str(&format!("{}", DEFAULT_TAKER_FEE * DEFAULT_ATOMIC_MULTIPLIER * DEFAULT_RELAYER_SHARE)); - - // calculate relayer's share of the fee based on assumptions that some of orders are matched - let expected_nominal_buy_most_expensive_match_quantity = FPDecimal::must_from_str("488.2222155454736648"); - let sell_orders_nominal_total_value = FPDecimal::from(800u128) * FPDecimal::from(800u128) - + FPDecimal::from(810u128) * FPDecimal::from(800u128) - + FPDecimal::from(820u128) * FPDecimal::from(800u128) - + FPDecimal::from(830u128) * expected_nominal_buy_most_expensive_match_quantity; - let relayer_buy_fee = sell_orders_nominal_total_value - * FPDecimal::must_from_str(&format!("{}", DEFAULT_TAKER_FEE * DEFAULT_ATOMIC_MULTIPLIER * DEFAULT_RELAYER_SHARE)); - let expected_fee_for_fee_recipient = relayer_buy_fee + relayer_sell_fee; - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let mut query_result: SwapEstimationResult = wasm - .query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ) - .unwrap(); - - assert_eq!( - query_result.result_quantity, - FPDecimal::must_from_str("2888.221"), //slightly rounded down vs spreadsheet - "incorrect swap result estimate returned by query" - ); - - let mut expected_fees = vec![ - FPCoin { - amount: FPDecimal::must_from_str("5902.5"), - denom: "usdt".to_string(), - }, - FPCoin { - amount: FPDecimal::must_from_str("5873.061097"), - denom: "usdt".to_string(), - }, - ]; - - assert_fee_is_as_expected(&mut query_result.expected_fees, &mut expected_fees, FPDecimal::must_from_str("0.000001")); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2888u128), - }, - &[coin(12, ETH)], - &swapper, - ) - .unwrap(); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - - assert_eq!(from_balance, FPDecimal::ZERO, "some of the original amount wasn't swapped"); - assert_eq!(to_balance, FPDecimal::must_from_str("2888"), "swapper did not receive expected amount"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - - let contract_balance_usdt_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); - let contract_balance_usdt_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - - assert!( - contract_balance_usdt_after >= contract_balance_usdt_before, - "Contract lost some money after swap. Balance before: {contract_balance_usdt_before}, after: {contract_balance_usdt_after}", - ); - - let max_diff = human_to_dec("0.00001", Decimals::Six); - - assert!( - are_fpdecimals_approximately_equal(contract_balance_usdt_after, contract_balance_usdt_before, max_diff,), - "Contract balance changed too much. Before: {}, After: {}", - contract_balances_before[0].amount, - contract_balances_after[0].amount - ); - - let fee_recipient_balance = query_all_bank_balances(&bank, &fee_recipient.address()); - - assert_eq!(fee_recipient_balance.len(), 1, "wrong number of denoms in fee recipient's balances"); - assert_eq!( - fee_recipient_balance[0].denom, USDT, - "fee recipient did not receive fee in expected denom" - ); - assert_eq!( - FPDecimal::must_from_str(fee_recipient_balance[0].amount.as_str()), - expected_fee_for_fee_recipient.int(), - "fee recipient did not receive expected fee" - ); -} - -#[test] -fn it_reverts_the_swap_if_there_isnt_enough_buffer_for_buying_target_asset() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("0.001", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let query_result: RunnerResult = wasm.query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ); - - assert!(query_result.is_err(), "query should fail"); - assert!( - query_result.unwrap_err().to_string().contains("Swap amount too high"), - "wrong query error message" - ); - - let contract_balances_before = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[coin(12, ETH)], - &swapper, - ); - - assert!(execute_result.is_err(), "execute should fail"); - assert!( - execute_result.unwrap_err().to_string().contains("Swap amount too high"), - "wrong execute error message" - ); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::from(12u128), "source balance changes after failed swap"); - assert_eq!(to_balance, FPDecimal::ZERO, "target balance changes after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_reverts_swap_if_no_funds_were_passed() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let contract_balances_before = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[], - &swapper, - ); - let expected_error = RunnerError::ExecuteError { - msg: "failed to execute message; message index: 0: Custom Error: \"Only one denom can be passed in funds\": execute wasm contract failed" - .to_string(), - }; - assert_eq!(execute_result.unwrap_err(), expected_error, "wrong error message"); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - - assert_eq!(from_balance, FPDecimal::from(12u128), "source balance changes after failed swap"); - assert_eq!(to_balance, FPDecimal::ZERO, "target balance changes after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_reverts_swap_if_multiple_funds_were_passed() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let eth_balance = 12u128; - let atom_balance = 10u128; - - let swapper = must_init_account_with_funds( - &app, - &[ - coin(eth_balance, ETH), - coin(atom_balance, ATOM), - str_coin("500_000", INJ, Decimals::Eighteen), - ], - ); - - let contract_balances_before = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(10u128), - }, - &[coin(10, ATOM), coin(12, ETH)], - &swapper, - ); - assert!( - execute_result.unwrap_err().to_string().contains("Only one denom can be passed in funds"), - "wrong error message" - ); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::from(eth_balance), "wrong ETH balance after failed swap"); - assert_eq!(to_balance, FPDecimal::from(atom_balance), "wrong ATOM balance after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_reverts_if_user_passes_quantities_equal_to_zero() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let query_result: RunnerResult = wasm.query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(0u128), - }, - ); - assert!( - query_result.unwrap_err().to_string().contains("source_quantity must be positive"), - "incorrect error returned by query" - ); - - let contract_balances_before = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let err = wasm - .execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::ZERO, - }, - &[coin(12, ETH)], - &swapper, - ) - .unwrap_err(); - assert!( - err.to_string().contains("Output quantity must be positive!"), - "incorrect error returned by execute" - ); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::must_from_str("12"), "swap should not have occurred"); - assert_eq!( - to_balance, - FPDecimal::must_from_str("0"), - "swapper should not have received any target tokens" - ); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_reverts_if_user_passes_negative_quantities() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let contract_balances_before = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - app.increase_time(1); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::must_from_str("-1"), - }, - &[coin(12, ETH)], - &swapper, - ); - - assert!(execute_result.is_err(), "swap with negative minimum amount to receive did not fail"); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::from(12u128), "source balance changed after failed swap"); - assert_eq!(to_balance, FPDecimal::ZERO, "target balance changed after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after failed swap" - ); -} - -#[test] -fn it_reverts_if_there_arent_enough_orders_to_satisfy_min_quantity() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - - create_limit_order(&app, &trader1, &spot_market_2_id, OrderSide::Sell, 800, 800); - create_limit_order(&app, &trader2, &spot_market_2_id, OrderSide::Sell, 810, 800); - create_limit_order(&app, &trader3, &spot_market_2_id, OrderSide::Sell, 820, 800); - create_limit_order(&app, &trader1, &spot_market_2_id, OrderSide::Sell, 830, 450); //not enough for minimum requested - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let query_result: RunnerResult = wasm.query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ); - assert_eq!( - query_result.unwrap_err(), - QueryError { - msg: "Generic error: Not enough liquidity to fulfill order: query wasm contract failed".to_string() - }, - "wrong error message" - ); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[coin(12, ETH)], - &swapper, - ); - - assert_eq!(execute_result.unwrap_err(), RunnerError::ExecuteError { msg: "failed to execute message; message index: 0: dispatch: submessages: reply: Generic error: Not enough liquidity to fulfill order: execute wasm contract failed".to_string() }, "wrong error message"); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::from(12u128), "source balance changed after failed swap"); - assert_eq!(to_balance, FPDecimal::ZERO, "target balance changed after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after swap" - ); -} - -#[test] -fn it_reverts_if_min_quantity_cannot_be_reached() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - // set the market - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - app.increase_time(1); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let min_quantity = 3500u128; - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(min_quantity), - }, - &[coin(12, ETH)], - &swapper, - ); - - assert_eq!(execute_result.unwrap_err(), RunnerError::ExecuteError { msg: format!("failed to execute message; message index: 0: dispatch: submessages: reply: dispatch: submessages: reply: Min expected swap amount ({min_quantity}) not reached: execute wasm contract failed") }, "wrong error message"); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::from(12u128), "source balance changed after failed swap"); - assert_eq!(to_balance, FPDecimal::ZERO, "target balance changed after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after failed swap" - ); -} - -#[test] -fn it_reverts_if_market_is_paused() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let signer = init_default_signer_account(&app); - let validator = init_default_validator_account(&app); - fund_account_with_some_inj(&bank, &signer, &validator); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - pause_spot_market(&app, spot_market_1_id.as_str(), &signer, &validator); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), str_coin("500_000", INJ, Decimals::Eighteen)]); - - let query_error: RunnerError = wasm - .query::( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ) - .unwrap_err(); - - assert!( - query_error.to_string().contains("Querier contract error"), - "wrong error returned by query" - ); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[coin(12, ETH)], - &swapper, - ); - - assert!( - execute_result.unwrap_err().to_string().contains("Querier contract error"), - "wrong error returned by execute" - ); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::from(12u128), "source balance changed after failed swap"); - assert_eq!(to_balance, FPDecimal::ZERO, "target balance changed after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after failed swap" - ); -} - -#[test] -fn it_reverts_if_user_doesnt_have_enough_inj_to_pay_for_gas() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let exchange = Exchange::new(&app); - let bank = Bank::new(&app); - - let _signer = init_default_signer_account(&app); - let _validator = init_default_validator_account(&app); - let owner = init_rich_account(&app); - - let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("100_000", USDT, Decimals::Six)]); - set_route_and_assert_success( - &wasm, - &owner, - &contr_addr, - ETH, - ATOM, - vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], - ); - - let swapper = must_init_account_with_funds(&app, &[coin(12, ETH), coin(10, INJ)]); - - let trader1 = init_rich_account(&app); - let trader2 = init_rich_account(&app); - let trader3 = init_rich_account(&app); - - create_eth_buy_orders(&app, &spot_market_1_id, &trader1, &trader2); - create_atom_sell_orders(&app, &spot_market_2_id, &trader1, &trader2, &trader3); - - app.increase_time(1); - - let query_result: RunnerResult = wasm.query( - &contr_addr, - &QueryMsg::GetOutputQuantity { - source_denom: ETH.to_string(), - target_denom: ATOM.to_string(), - from_quantity: FPDecimal::from(12u128), - }, - ); - - let target_quantity = query_result.unwrap().result_quantity; - - assert_eq!( - target_quantity, - FPDecimal::must_from_str("2893.886"), //slightly underestimated vs spreadsheet - "incorrect swap result estimate returned by query" - ); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::SwapMinOutput { - target_denom: ATOM.to_string(), - min_output_quantity: FPDecimal::from(2800u128), - }, - &[coin(12, ETH)], - &swapper, - ); - - assert_eq!( - execute_result.unwrap_err(), - ExecuteError { - msg: "spendable balance 10inj is smaller than 2500inj: insufficient funds: insufficient funds".to_string() - }, - "wrong error returned by execute" - ); - - let from_balance = query_bank_balance(&bank, ETH, swapper.address().as_str()); - let to_balance = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!(from_balance, FPDecimal::from(12u128), "source balance changed after failed swap"); - assert_eq!(to_balance, FPDecimal::ZERO, "target balance changed after failed swap"); - - let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balance has changed after failed swap" - ); -} - -#[test] -fn it_allows_admin_to_withdraw_all_funds_from_contract_to_his_address() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let bank = Bank::new(&app); - - let usdt_to_withdraw = str_coin("10_000", USDT, Decimals::Six); - let eth_to_withdraw = str_coin("0.00062", ETH, Decimals::Eighteen); - - let owner = must_init_account_with_funds( - &app, - &[eth_to_withdraw.clone(), str_coin("1", INJ, Decimals::Eighteen), usdt_to_withdraw.clone()], - ); - - let initial_contract_balance = &[eth_to_withdraw, usdt_to_withdraw]; - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, initial_contract_balance); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 2, "wrong number of denoms in contract balances"); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::WithdrawSupportFunds { - coins: initial_contract_balance.to_vec(), - target_address: Addr::unchecked(owner.address()), - }, - &[], - &owner, - ); - - assert!(execute_result.is_ok(), "failed to withdraw support funds"); - let contract_balances_after = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_after.len(), 0, "contract had some balances after withdraw"); - - let owner_eth_balance = query_bank_balance(&bank, ETH, owner.address().as_str()); - assert_eq!( - owner_eth_balance, - FPDecimal::from(initial_contract_balance[0].amount), - "wrong owner eth balance after withdraw" - ); - - let owner_usdt_balance = query_bank_balance(&bank, USDT, owner.address().as_str()); - assert_eq!( - owner_usdt_balance, - FPDecimal::from(initial_contract_balance[1].amount), - "wrong owner usdt balance after withdraw" - ); -} - -#[test] -fn it_allows_admin_to_withdraw_all_funds_from_contract_to_other_address() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let bank = Bank::new(&app); - - let usdt_to_withdraw = str_coin("10_000", USDT, Decimals::Six); - let eth_to_withdraw = str_coin("0.00062", ETH, Decimals::Eighteen); - - let owner = must_init_account_with_funds( - &app, - &[eth_to_withdraw.clone(), str_coin("1", INJ, Decimals::Eighteen), usdt_to_withdraw.clone()], - ); - - let initial_contract_balance = &[eth_to_withdraw, usdt_to_withdraw]; - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, initial_contract_balance); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 2, "wrong number of denoms in contract balances"); - - let random_dude = must_init_account_with_funds(&app, &[]); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::WithdrawSupportFunds { - coins: initial_contract_balance.to_vec(), - target_address: Addr::unchecked(random_dude.address()), - }, - &[], - &owner, - ); - - assert!(execute_result.is_ok(), "failed to withdraw support funds"); - let contract_balances_after = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_after.len(), 0, "contract had some balances after withdraw"); - - let random_dude_eth_balance = query_bank_balance(&bank, ETH, random_dude.address().as_str()); - assert_eq!( - random_dude_eth_balance, - FPDecimal::from(initial_contract_balance[0].amount), - "wrong owner eth balance after withdraw" - ); - - let random_dude_usdt_balance = query_bank_balance(&bank, USDT, random_dude.address().as_str()); - assert_eq!( - random_dude_usdt_balance, - FPDecimal::from(initial_contract_balance[1].amount), - "wrong owner usdt balance after withdraw" - ); -} - -#[test] -fn it_doesnt_allow_non_admin_to_withdraw_anything_from_contract() { - let app = InjectiveTestApp::new(); - let wasm = Wasm::new(&app); - let bank = Bank::new(&app); - - let usdt_to_withdraw = str_coin("10_000", USDT, Decimals::Six); - let eth_to_withdraw = str_coin("0.00062", ETH, Decimals::Eighteen); - - let owner = must_init_account_with_funds( - &app, - &[eth_to_withdraw.clone(), str_coin("1", INJ, Decimals::Eighteen), usdt_to_withdraw.clone()], - ); - - let initial_contract_balance = &[eth_to_withdraw, usdt_to_withdraw]; - let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, initial_contract_balance); - - let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!(contract_balances_before.len(), 2, "wrong number of denoms in contract balances"); - - let random_dude = must_init_account_with_funds(&app, &[coin(1_000_000_000_000, INJ)]); - - let execute_result = wasm.execute( - &contr_addr, - &ExecuteMsg::WithdrawSupportFunds { - coins: initial_contract_balance.to_vec(), - target_address: Addr::unchecked(owner.address()), - }, - &[], - &random_dude, - ); - - assert!(execute_result.is_err(), "succeeded to withdraw support funds"); - let contract_balances_after = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_after, contract_balances_before, - "contract balances changed after failed withdraw" - ); - - let random_dude_eth_balance = query_bank_balance(&bank, ETH, random_dude.address().as_str()); - assert_eq!( - random_dude_eth_balance, - FPDecimal::ZERO, - "random dude has some eth balance after failed withdraw" - ); - - let random_dude_usdt_balance = query_bank_balance(&bank, USDT, random_dude.address().as_str()); - assert_eq!( - random_dude_usdt_balance, - FPDecimal::ZERO, - "random dude has some usdt balance after failed withdraw" - ); -} - -fn create_eth_buy_orders(app: &InjectiveTestApp, market_id: &str, trader1: &SigningAccount, trader2: &SigningAccount) { - create_limit_order(app, trader1, market_id, OrderSide::Buy, 201_000, 5); - create_limit_order(app, trader2, market_id, OrderSide::Buy, 195_000, 4); - create_limit_order(app, trader2, market_id, OrderSide::Buy, 192_000, 3); -} - -fn create_atom_sell_orders(app: &InjectiveTestApp, market_id: &str, trader1: &SigningAccount, trader2: &SigningAccount, trader3: &SigningAccount) { - create_limit_order(app, trader1, market_id, OrderSide::Sell, 800, 800); - create_limit_order(app, trader2, market_id, OrderSide::Sell, 810, 800); - create_limit_order(app, trader3, market_id, OrderSide::Sell, 820, 800); - create_limit_order(app, trader1, market_id, OrderSide::Sell, 830, 800); -} diff --git a/contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs b/contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs index c3c3f7b..60cf4c9 100644 --- a/contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs +++ b/contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs @@ -1,24 +1,19 @@ +use injective_math::FPDecimal; use injective_test_tube::{Account, Bank, Exchange, InjectiveTestApp, Module, Wasm}; use std::ops::Neg; use crate::helpers::Scaled; -use injective_math::FPDecimal; use crate::msg::{ExecuteMsg, QueryMsg}; use crate::testing::test_utils::{ - are_fpdecimals_approximately_equal, assert_fee_is_as_expected, - create_ninja_inj_both_side_orders, create_realistic_atom_usdt_sell_orders_from_spreadsheet, - create_realistic_eth_usdt_buy_orders_from_spreadsheet, - create_realistic_eth_usdt_sell_orders_from_spreadsheet, - create_realistic_inj_usdt_buy_orders_from_spreadsheet, - create_realistic_inj_usdt_sell_orders_from_spreadsheet, create_realistic_limit_order, - create_realistic_usdt_usdc_both_side_orders, human_to_dec, init_rich_account, - init_self_relaying_contract_and_get_address, launch_realistic_atom_usdt_spot_market, - launch_realistic_inj_usdt_spot_market, launch_realistic_ninja_inj_spot_market, - launch_realistic_usdt_usdc_spot_market, launch_realistic_weth_usdt_spot_market, - must_init_account_with_funds, query_all_bank_balances, query_bank_balance, - set_route_and_assert_success, str_coin, Decimals, OrderSide, ATOM, ETH, INJ, INJ_2, NINJA, - USDC, USDT, + are_fpdecimals_approximately_equal, assert_fee_is_as_expected, create_ninja_inj_both_side_orders, + create_realistic_atom_usdt_sell_orders_from_spreadsheet, create_realistic_eth_usdt_buy_orders_from_spreadsheet, + create_realistic_eth_usdt_sell_orders_from_spreadsheet, create_realistic_inj_usdt_buy_orders_from_spreadsheet, + create_realistic_inj_usdt_sell_orders_from_spreadsheet, create_realistic_limit_order, create_realistic_usdt_usdc_both_side_orders, human_to_dec, + init_rich_account, init_self_relaying_contract_and_get_address, launch_realistic_atom_usdt_spot_market, launch_realistic_inj_usdt_spot_market, + launch_realistic_ninja_inj_spot_market, launch_realistic_usdt_usdc_spot_market, launch_realistic_weth_usdt_spot_market, + must_init_account_with_funds, query_all_bank_balances, query_bank_balance, set_route_and_assert_success, str_coin, Decimals, OrderSide, ATOM, + ETH, INJ, INJ_2, NINJA, USDC, USDT, }; use crate::types::{FPCoin, SwapEstimationResult}; @@ -74,9 +69,7 @@ fn it_correctly_swaps_eth_to_get_very_high_exact_amount_of_atom() { let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, &[ @@ -90,33 +83,21 @@ fn it_correctly_swaps_eth_to_get_very_high_exact_amount_of_atom() { let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, &owner, &contr_addr, ETH, ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); let trader3 = init_rich_account(&app); - create_realistic_eth_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); + create_realistic_eth_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); create_realistic_limit_order( &app, &trader1, @@ -128,13 +109,7 @@ fn it_correctly_swaps_eth_to_get_very_high_exact_amount_of_atom() { Decimals::Six, ); //order not present in the spreadsheet - create_realistic_atom_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_atom_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); create_realistic_limit_order( &app, &trader1, @@ -152,18 +127,11 @@ fn it_correctly_swaps_eth_to_get_very_high_exact_amount_of_atom() { let swapper = must_init_account_with_funds( &app, - &[ - str_coin(eth_to_swap, ETH, Decimals::Eighteen), - str_coin("1", INJ, Decimals::Eighteen), - ], + &[str_coin(eth_to_swap, ETH, Decimals::Eighteen), str_coin("1", INJ, Decimals::Eighteen)], ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let exact_quantity_to_receive = human_to_dec("1014.19", Decimals::Six); @@ -189,15 +157,11 @@ fn it_correctly_swaps_eth_to_get_very_high_exact_amount_of_atom() { ) .unwrap(); - let expected_difference = - human_to_dec(eth_to_swap, Decimals::Eighteen) - query_result.result_quantity; + let expected_difference = human_to_dec(eth_to_swap, Decimals::Eighteen) - query_result.result_quantity; let swapper_eth_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str()); let swapper_atom_balance_after = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!( - swapper_eth_balance_after, expected_difference, - "wrong amount of ETH was exchanged" - ); + assert_eq!(swapper_eth_balance_after, expected_difference, "wrong amount of ETH was exchanged"); assert!( swapper_atom_balance_after >= exact_quantity_to_receive, @@ -209,11 +173,7 @@ fn it_correctly_swaps_eth_to_get_very_high_exact_amount_of_atom() { let one_percent_diff = exact_quantity_to_receive * FPDecimal::must_from_str("0.01"); assert!( - are_fpdecimals_approximately_equal( - swapper_atom_balance_after, - exact_quantity_to_receive, - one_percent_diff, - ), + are_fpdecimals_approximately_equal(swapper_atom_balance_after, exact_quantity_to_receive, one_percent_diff,), "swapper did not receive expected exact amount +/- 1% -> expected: {} ATOM, actual: {} ATOM, max diff: {} ATOM", exact_quantity_to_receive.scaled(Decimals::Six.get_decimals().neg()), swapper_atom_balance_after.scaled(Decimals::Six.get_decimals().neg()), @@ -221,31 +181,21 @@ fn it_correctly_swaps_eth_to_get_very_high_exact_amount_of_atom() { ); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert!( contract_usdt_balance_after >= contract_usdt_balance_before, - "Contract lost some money after swap. Actual balance: {contract_usdt_balance_after}, previous balance: {contract_usdt_balance_before}", + "Contract lost some money after swap. Actual balance: {contract_usdt_balance_after}, previous balance: {contract_usdt_balance_before}", ); // contract is allowed to earn extra 0.73 USDT from the swap of ~$8450 worth of ETH let max_diff = human_to_dec("0.8", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdt_balance_after, - contract_usdt_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdt_balance_after, contract_usdt_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {}, previous balance: {}. Max diff: {}", contract_usdt_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdt_balance_before.scaled(Decimals::Six.get_decimals().neg()), @@ -287,9 +237,7 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, &[ @@ -304,33 +252,21 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { let spot_market_1_id = launch_realistic_inj_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, &owner, &contr_addr, INJ_2, ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); let trader3 = init_rich_account(&app); - create_realistic_inj_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); + create_realistic_inj_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); create_realistic_limit_order( &app, &trader1, @@ -342,13 +278,7 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { Decimals::Six, ); //order not present in the spreadsheet - create_realistic_atom_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_atom_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); create_realistic_limit_order( &app, &trader1, @@ -366,18 +296,11 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { let swapper = must_init_account_with_funds( &app, - &[ - str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), - str_coin("1", INJ, Decimals::Eighteen), - ], + &[str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), str_coin("1", INJ, Decimals::Eighteen)], ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let exact_quantity_to_receive = human_to_dec("1010.12", Decimals::Six); let max_diff_percentage = Percent("0.01"); @@ -404,15 +327,11 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { ) .unwrap(); - let expected_difference = - human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; + let expected_difference = human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; let swapper_inj_balance_after = query_bank_balance(&bank, INJ_2, swapper.address().as_str()); let swapper_atom_balance_after = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!( - swapper_inj_balance_after, expected_difference, - "wrong amount of INJ was exchanged" - ); + assert_eq!(swapper_inj_balance_after, expected_difference, "wrong amount of INJ was exchanged"); assert!( swapper_atom_balance_after >= exact_quantity_to_receive, @@ -421,15 +340,10 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { swapper_atom_balance_after.scaled(Decimals::Six.get_decimals().neg()) ); - let one_percent_diff = exact_quantity_to_receive - * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); + let one_percent_diff = exact_quantity_to_receive * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); assert!( - are_fpdecimals_approximately_equal( - swapper_atom_balance_after, - exact_quantity_to_receive, - one_percent_diff, - ), + are_fpdecimals_approximately_equal(swapper_atom_balance_after, exact_quantity_to_receive, one_percent_diff,), "swapper did not receive expected exact ATOM amount +/- {}% -> expected: {} ATOM, actual: {} ATOM, max diff: {} ATOM", max_diff_percentage.0, exact_quantity_to_receive.scaled(Decimals::Six.get_decimals().neg()), @@ -438,31 +352,21 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { ); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert!( contract_usdt_balance_after >= contract_usdt_balance_before, - "Contract lost some money after swap. Actual balance: {contract_usdt_balance_after}, previous balance: {contract_usdt_balance_before}", + "Contract lost some money after swap. Actual balance: {contract_usdt_balance_after}, previous balance: {contract_usdt_balance_before}", ); // contract is allowed to earn extra 0.7 USDT from the swap of ~$8150 worth of INJ let max_diff = human_to_dec("0.7", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdt_balance_after, - contract_usdt_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdt_balance_after, contract_usdt_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {} USDT, previous balance: {} USDT. Max diff: {} USDT", contract_usdt_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdt_balance_before.scaled(Decimals::Six.get_decimals().neg()), @@ -472,18 +376,12 @@ fn it_correctly_swaps_inj_to_get_very_high_exact_amount_of_atom() { #[test] fn it_swaps_inj_to_get_minimum_exact_amount_of_eth() { - exact_two_hop_inj_eth_swap_test_template( - human_to_dec("0.001", Decimals::Eighteen), - Percent("0"), - ) + exact_two_hop_inj_eth_swap_test_template(human_to_dec("0.001", Decimals::Eighteen), Percent("0")) } #[test] fn it_swaps_inj_to_get_low_exact_amount_of_eth() { - exact_two_hop_inj_eth_swap_test_template( - human_to_dec("0.012", Decimals::Eighteen), - Percent("0"), - ) + exact_two_hop_inj_eth_swap_test_template(human_to_dec("0.012", Decimals::Eighteen), Percent("0")) } #[test] @@ -505,9 +403,7 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, &[ @@ -521,33 +417,21 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { let spot_market_1_id = launch_realistic_inj_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, &owner, &contr_addr, INJ_2, ETH, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); let trader3 = init_rich_account(&app); - create_realistic_inj_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); + create_realistic_inj_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); create_realistic_limit_order( &app, &trader1, @@ -558,13 +442,7 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { Decimals::Eighteen, Decimals::Six, ); //order not present in the spreadsheet - create_realistic_eth_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_eth_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); create_realistic_limit_order( &app, &trader3, @@ -583,18 +461,11 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { let swapper = must_init_account_with_funds( &app, - &[ - str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), - str_coin("1", INJ, Decimals::Eighteen), - ], + &[str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), str_coin("1", INJ, Decimals::Eighteen)], ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let query_result: SwapEstimationResult = wasm .query( @@ -618,15 +489,11 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { ) .unwrap(); - let expected_difference = - human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; + let expected_difference = human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; let swapper_inj_balance_after = query_bank_balance(&bank, INJ_2, swapper.address().as_str()); let swapper_atom_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str()); - assert_eq!( - swapper_inj_balance_after, expected_difference, - "wrong amount of INJ was exchanged" - ); + assert_eq!(swapper_inj_balance_after, expected_difference, "wrong amount of INJ was exchanged"); assert!( swapper_atom_balance_after >= exact_quantity_to_receive, @@ -636,15 +503,10 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { ); let max_diff_percent = Percent("0"); - let one_percent_diff = exact_quantity_to_receive - * (FPDecimal::must_from_str(max_diff_percent.0) / FPDecimal::from(100u128)); + let one_percent_diff = exact_quantity_to_receive * (FPDecimal::must_from_str(max_diff_percent.0) / FPDecimal::from(100u128)); assert!( - are_fpdecimals_approximately_equal( - swapper_atom_balance_after, - exact_quantity_to_receive, - one_percent_diff, - ), + are_fpdecimals_approximately_equal(swapper_atom_balance_after, exact_quantity_to_receive, one_percent_diff,), "swapper did not receive expected exact ETH amount +/- {}% -> expected: {} ETH, actual: {} ETH, max diff: {} ETH", max_diff_percent.0, exact_quantity_to_receive.scaled(Decimals::Eighteen.get_decimals().neg()), @@ -653,16 +515,10 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { ); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert!( contract_usdt_balance_after >= contract_usdt_balance_before, @@ -673,11 +529,7 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() { let max_diff = human_to_dec("1.6", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdt_balance_after, - contract_usdt_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdt_balance_after, contract_usdt_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {} USDT, previous balance: {} USDT. Max diff: {} USDT", contract_usdt_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdt_balance_before.scaled(Decimals::Six.get_decimals().neg()), @@ -693,9 +545,7 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying let bank = Bank::new(&app); let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, @@ -713,10 +563,7 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying let contr_addr = init_self_relaying_contract_and_get_address( &wasm, &owner, - &[ - str_coin("10", USDC, Decimals::Six), - str_coin("500", USDT, Decimals::Six), - ], + &[str_coin("10", USDC, Decimals::Six), str_coin("500", USDT, Decimals::Six)], ); set_route_and_assert_success( &wasm, @@ -724,32 +571,18 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying &contr_addr, INJ_2, USDC, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); - create_realistic_inj_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); + create_realistic_inj_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); create_realistic_usdt_usdc_both_side_orders(&app, &spot_market_2_id, &trader1); app.increase_time(1); - let swapper = must_init_account_with_funds( - &app, - &[ - str_coin("1", INJ, Decimals::Eighteen), - str_coin("1", INJ_2, Decimals::Eighteen), - ], - ); + let swapper = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen), str_coin("1", INJ_2, Decimals::Eighteen)]); let inj_to_swap = "1"; let to_output_quantity = human_to_dec("8", Decimals::Six); @@ -788,18 +621,10 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying ]; // we don't care too much about decimal fraction of the fee - assert_fee_is_as_expected( - &mut query_result.expected_fees, - &mut expected_fees, - human_to_dec("0.1", Decimals::Six), - ); + assert_fee_is_as_expected(&mut query_result.expected_fees, &mut expected_fees, human_to_dec("0.1", Decimals::Six)); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 2, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 2, "wrong number of denoms in contract balances"); wasm.execute( &contr_addr, @@ -815,12 +640,8 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying let from_balance = query_bank_balance(&bank, INJ_2, swapper.address().as_str()); let to_balance = query_bank_balance(&bank, USDC, swapper.address().as_str()); - let expected_inj_leftover = - human_to_dec(inj_to_swap, Decimals::Eighteen) - expected_input_quantity; - assert_eq!( - from_balance, expected_inj_leftover, - "incorrect original amount was left after swap" - ); + let expected_inj_leftover = human_to_dec(inj_to_swap, Decimals::Eighteen) - expected_input_quantity; + assert_eq!(from_balance, expected_inj_leftover, "incorrect original amount was left after swap"); let expected_amount = human_to_dec("8.00711", Decimals::Six); @@ -833,17 +654,11 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying ); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 2, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 2, "wrong number of denoms in contract balances"); // let's check contract's USDT balance - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert!( contract_usdt_balance_after >= contract_usdt_balance_before, @@ -856,11 +671,7 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying let max_diff = human_to_dec("0.001", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdt_balance_after, - contract_usdt_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdt_balance_after, contract_usdt_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {} USDT, previous balance: {} USDT. Max diff: {} USDT", contract_usdt_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdt_balance_before.scaled(Decimals::Six.get_decimals().neg()), @@ -868,10 +679,8 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying ); // let's check contract's USDC balance - let contract_usdc_balance_before = - FPDecimal::must_from_str(contract_balances_before[1].amount.as_str()); - let contract_usdc_balance_after = - FPDecimal::must_from_str(contract_balances_after[1].amount.as_str()); + let contract_usdc_balance_before = FPDecimal::must_from_str(contract_balances_before[1].amount.as_str()); + let contract_usdc_balance_after = FPDecimal::must_from_str(contract_balances_after[1].amount.as_str()); assert!( contract_usdc_balance_after >= contract_usdc_balance_before, @@ -884,11 +693,7 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying let max_diff = human_to_dec("0.001", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdc_balance_after, - contract_usdc_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdc_balance_after, contract_usdc_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {} USDC, previous balance: {} USDC. Max diff: {} USDC", contract_usdc_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdc_balance_before.scaled(Decimals::Six.get_decimals().neg()), @@ -904,9 +709,7 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying let bank = Bank::new(&app); let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, @@ -937,10 +740,7 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying &contr_addr, USDT, NINJA, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); @@ -950,13 +750,7 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying app.increase_time(1); - let swapper = must_init_account_with_funds( - &app, - &[ - str_coin("1", INJ, Decimals::Eighteen), - str_coin("100000", USDT, Decimals::Six), - ], - ); + let swapper = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen), str_coin("100000", USDT, Decimals::Six)]); let usdt_to_swap = "100000"; let to_output_quantity = human_to_dec("501000", Decimals::Six); @@ -990,18 +784,12 @@ fn it_correctly_swaps_between_markets_using_different_quote_assets_self_relaying from_balance_before, expected_from_balance_before, "incorrect original amount was left after swap" ); - assert_eq!( - to_balance_before, expected_to_balance_before, - "incorrect target amount after swap" - ); + assert_eq!(to_balance_before, expected_to_balance_before, "incorrect target amount after swap"); assert_eq!( from_balance_after, expected_from_balance_after, "incorrect original amount was left after swap" ); - assert_eq!( - to_balance_after, expected_to_balance_after, - "incorrect target amount after swap" - ); + assert_eq!(to_balance_after, expected_to_balance_after, "incorrect target amount after swap"); } #[test] @@ -1013,9 +801,7 @@ fn it_doesnt_lose_buffer_if_exact_swap_of_eth_to_atom_is_executed_multiple_times let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, @@ -1030,11 +816,7 @@ fn it_doesnt_lose_buffer_if_exact_swap_of_eth_to_atom_is_executed_multiple_times let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, @@ -1042,10 +824,7 @@ fn it_doesnt_lose_buffer_if_exact_swap_of_eth_to_atom_is_executed_multiple_times &contr_addr, ETH, ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); @@ -1059,9 +838,7 @@ fn it_doesnt_lose_buffer_if_exact_swap_of_eth_to_atom_is_executed_multiple_times &app, &[ str_coin( - (FPDecimal::must_from_str(eth_to_swap) * FPDecimal::from(iterations)) - .to_string() - .as_str(), + (FPDecimal::must_from_str(eth_to_swap) * FPDecimal::from(iterations)).to_string().as_str(), ETH, Decimals::Eighteen, ), @@ -1070,28 +847,13 @@ fn it_doesnt_lose_buffer_if_exact_swap_of_eth_to_atom_is_executed_multiple_times ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let mut counter = 0; while counter < iterations { - create_realistic_eth_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); - create_realistic_atom_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_eth_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); + create_realistic_atom_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); app.increase_time(1); @@ -1110,16 +872,10 @@ fn it_doesnt_lose_buffer_if_exact_swap_of_eth_to_atom_is_executed_multiple_times } let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_balance_usdt_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); - let contract_balance_usdt_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_balance_usdt_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_balance_usdt_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); assert!( contract_balance_usdt_after >= contract_balance_usdt_before, @@ -1130,14 +886,12 @@ fn it_doesnt_lose_buffer_if_exact_swap_of_eth_to_atom_is_executed_multiple_times // won't change balance by more than 0.7 * 100 = 70 USDT let max_diff = human_to_dec("0.7", Decimals::Six) * FPDecimal::from(iterations); - assert!(are_fpdecimals_approximately_equal( - contract_balance_usdt_after, - contract_balance_usdt_before, - max_diff, - ), "Contract balance changed too much. Starting balance: {}, Current balance: {}. Max diff: {}", - contract_balance_usdt_before.scaled(Decimals::Six.get_decimals().neg()), - contract_balance_usdt_after.scaled(Decimals::Six.get_decimals().neg()), - max_diff.scaled(Decimals::Six.get_decimals().neg()) + assert!( + are_fpdecimals_approximately_equal(contract_balance_usdt_after, contract_balance_usdt_before, max_diff,), + "Contract balance changed too much. Starting balance: {}, Current balance: {}. Max diff: {}", + contract_balance_usdt_before.scaled(Decimals::Six.get_decimals().neg()), + contract_balance_usdt_after.scaled(Decimals::Six.get_decimals().neg()), + max_diff.scaled(Decimals::Six.get_decimals().neg()) ); } @@ -1150,9 +904,7 @@ fn it_reverts_when_funds_provided_are_below_required_to_get_exact_amount() { let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, &[ @@ -1167,40 +919,22 @@ fn it_reverts_when_funds_provided_are_below_required_to_get_exact_amount() { let spot_market_1_id = launch_realistic_inj_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, &owner, &contr_addr, INJ_2, ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); let trader3 = init_rich_account(&app); - create_realistic_inj_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); - create_realistic_atom_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_inj_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); + create_realistic_atom_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); app.increase_time(1); @@ -1208,18 +942,11 @@ fn it_reverts_when_funds_provided_are_below_required_to_get_exact_amount() { let swapper = must_init_account_with_funds( &app, - &[ - str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), - str_coin("1", INJ, Decimals::Eighteen), - ], + &[str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), str_coin("1", INJ, Decimals::Eighteen)], ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let exact_quantity_to_receive = human_to_dec("600", Decimals::Six); let swapper_inj_balance_before = query_bank_balance(&bank, INJ_2, swapper.address().as_str()); @@ -1247,33 +974,25 @@ fn it_reverts_when_funds_provided_are_below_required_to_get_exact_amount() { ) .unwrap_err(); - assert!(execute_result.to_string().contains("Provided amount of 608000000000000000000 is below required amount of 609714000000000000000"), "wrong error message"); + assert!( + execute_result + .to_string() + .contains("Provided amount of 608000000000000000000 is below required amount of 609714000000000000000"), + "wrong error message" + ); let swapper_inj_balance_after = query_bank_balance(&bank, INJ_2, swapper.address().as_str()); let swapper_atom_balance_after = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!( - swapper_inj_balance_before, swapper_inj_balance_after, - "some amount of INJ was exchanged" - ); + assert_eq!(swapper_inj_balance_before, swapper_inj_balance_after, "some amount of INJ was exchanged"); - assert_eq!( - FPDecimal::ZERO, - swapper_atom_balance_after, - "swapper received some ATOM" - ); + assert_eq!(FPDecimal::ZERO, swapper_atom_balance_after, "swapper received some ATOM"); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert_eq!( contract_usdt_balance_after, contract_usdt_balance_before, @@ -1284,10 +1003,7 @@ fn it_reverts_when_funds_provided_are_below_required_to_get_exact_amount() { // TEST TEMPLATES // source much more expensive than target -fn exact_two_hop_eth_atom_swap_test_template( - exact_quantity_to_receive: FPDecimal, - max_diff_percentage: Percent, -) { +fn exact_two_hop_eth_atom_swap_test_template(exact_quantity_to_receive: FPDecimal, max_diff_percentage: Percent) { let app = InjectiveTestApp::new(); let wasm = Wasm::new(&app); let exchange = Exchange::new(&app); @@ -1295,9 +1011,7 @@ fn exact_two_hop_eth_atom_swap_test_template( let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, &[ @@ -1311,40 +1025,22 @@ fn exact_two_hop_eth_atom_swap_test_template( let spot_market_1_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, &owner, &contr_addr, ETH, ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); let trader3 = init_rich_account(&app); - create_realistic_eth_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); - create_realistic_atom_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_eth_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); + create_realistic_atom_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); app.increase_time(1); @@ -1352,18 +1048,11 @@ fn exact_two_hop_eth_atom_swap_test_template( let swapper = must_init_account_with_funds( &app, - &[ - str_coin(eth_to_swap, ETH, Decimals::Eighteen), - str_coin("1", INJ, Decimals::Eighteen), - ], + &[str_coin(eth_to_swap, ETH, Decimals::Eighteen), str_coin("1", INJ, Decimals::Eighteen)], ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let query_result: SwapEstimationResult = wasm .query( @@ -1387,18 +1076,13 @@ fn exact_two_hop_eth_atom_swap_test_template( ) .unwrap(); - let expected_difference = - human_to_dec(eth_to_swap, Decimals::Eighteen) - query_result.result_quantity; + let expected_difference = human_to_dec(eth_to_swap, Decimals::Eighteen) - query_result.result_quantity; let swapper_eth_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str()); let swapper_atom_balance_after = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!( - swapper_eth_balance_after, expected_difference, - "wrong amount of ETH was exchanged" - ); + assert_eq!(swapper_eth_balance_after, expected_difference, "wrong amount of ETH was exchanged"); - let one_percent_diff = exact_quantity_to_receive - * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); + let one_percent_diff = exact_quantity_to_receive * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); assert!( swapper_atom_balance_after >= exact_quantity_to_receive, @@ -1408,11 +1092,7 @@ fn exact_two_hop_eth_atom_swap_test_template( ); assert!( - are_fpdecimals_approximately_equal( - swapper_atom_balance_after, - exact_quantity_to_receive, - one_percent_diff, - ), + are_fpdecimals_approximately_equal(swapper_atom_balance_after, exact_quantity_to_receive, one_percent_diff,), "swapper did not receive expected exact amount +/- {}% -> expected: {} ATOM, actual: {} ATOM, max diff: {} ATOM", max_diff_percentage.0, exact_quantity_to_receive.scaled(Decimals::Six.get_decimals().neg()), @@ -1421,16 +1101,10 @@ fn exact_two_hop_eth_atom_swap_test_template( ); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert!( contract_usdt_balance_after >= contract_usdt_balance_before, @@ -1441,11 +1115,7 @@ fn exact_two_hop_eth_atom_swap_test_template( let max_diff = human_to_dec("0.7", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdt_balance_after, - contract_usdt_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdt_balance_after, contract_usdt_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {} USDT, previous balance: {} USDT. Max diff: {} USDT", contract_usdt_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdt_balance_before.scaled(Decimals::Six.get_decimals().neg()), @@ -1454,10 +1124,7 @@ fn exact_two_hop_eth_atom_swap_test_template( } // source more or less similarly priced as target -fn exact_two_hop_inj_atom_swap_test_template( - exact_quantity_to_receive: FPDecimal, - max_diff_percentage: Percent, -) { +fn exact_two_hop_inj_atom_swap_test_template(exact_quantity_to_receive: FPDecimal, max_diff_percentage: Percent) { let app = InjectiveTestApp::new(); let wasm = Wasm::new(&app); let exchange = Exchange::new(&app); @@ -1465,9 +1132,7 @@ fn exact_two_hop_inj_atom_swap_test_template( let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, &[ @@ -1482,40 +1147,22 @@ fn exact_two_hop_inj_atom_swap_test_template( let spot_market_1_id = launch_realistic_inj_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_atom_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, &owner, &contr_addr, INJ_2, ATOM, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); let trader3 = init_rich_account(&app); - create_realistic_inj_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); - create_realistic_atom_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_inj_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); + create_realistic_atom_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); app.increase_time(1); @@ -1523,18 +1170,11 @@ fn exact_two_hop_inj_atom_swap_test_template( let swapper = must_init_account_with_funds( &app, - &[ - str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), - str_coin("1", INJ, Decimals::Eighteen), - ], + &[str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), str_coin("1", INJ, Decimals::Eighteen)], ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let query_result: SwapEstimationResult = wasm .query( @@ -1558,15 +1198,11 @@ fn exact_two_hop_inj_atom_swap_test_template( ) .unwrap(); - let expected_difference = - human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; + let expected_difference = human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; let swapper_inj_balance_after = query_bank_balance(&bank, INJ_2, swapper.address().as_str()); let swapper_atom_balance_after = query_bank_balance(&bank, ATOM, swapper.address().as_str()); - assert_eq!( - swapper_inj_balance_after, expected_difference, - "wrong amount of INJ was exchanged" - ); + assert_eq!(swapper_inj_balance_after, expected_difference, "wrong amount of INJ was exchanged"); assert!( swapper_atom_balance_after >= exact_quantity_to_receive, @@ -1575,15 +1211,10 @@ fn exact_two_hop_inj_atom_swap_test_template( swapper_atom_balance_after.scaled(Decimals::Six.get_decimals().neg()) ); - let one_percent_diff = exact_quantity_to_receive - * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); + let one_percent_diff = exact_quantity_to_receive * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); assert!( - are_fpdecimals_approximately_equal( - swapper_atom_balance_after, - exact_quantity_to_receive, - one_percent_diff, - ), + are_fpdecimals_approximately_equal(swapper_atom_balance_after, exact_quantity_to_receive, one_percent_diff,), "swapper did not receive expected exact ATOM amount +/- {}% -> expected: {} ATOM, actual: {} ATOM, max diff: {} ATOM", max_diff_percentage.0, exact_quantity_to_receive.scaled(Decimals::Six.get_decimals().neg()), @@ -1592,16 +1223,10 @@ fn exact_two_hop_inj_atom_swap_test_template( ); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert!( contract_usdt_balance_after >= contract_usdt_balance_before, @@ -1612,11 +1237,7 @@ fn exact_two_hop_inj_atom_swap_test_template( let max_diff = human_to_dec("0.7", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdt_balance_after, - contract_usdt_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdt_balance_after, contract_usdt_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {} USDT, previous balance: {} USDT. Max diff: {} USDT", contract_usdt_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdt_balance_before.scaled(Decimals::Six.get_decimals().neg()), @@ -1625,10 +1246,7 @@ fn exact_two_hop_inj_atom_swap_test_template( } // source much cheaper than target -fn exact_two_hop_inj_eth_swap_test_template( - exact_quantity_to_receive: FPDecimal, - max_diff_percentage: Percent, -) { +fn exact_two_hop_inj_eth_swap_test_template(exact_quantity_to_receive: FPDecimal, max_diff_percentage: Percent) { let app = InjectiveTestApp::new(); let wasm = Wasm::new(&app); let exchange = Exchange::new(&app); @@ -1636,9 +1254,7 @@ fn exact_two_hop_inj_eth_swap_test_template( let _signer = must_init_account_with_funds(&app, &[str_coin("1", INJ, Decimals::Eighteen)]); - let _validator = app - .get_first_validator_signing_account(INJ.to_string(), 1.2f64) - .unwrap(); + let _validator = app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap(); let owner = must_init_account_with_funds( &app, &[ @@ -1652,40 +1268,22 @@ fn exact_two_hop_inj_eth_swap_test_template( let spot_market_1_id = launch_realistic_inj_usdt_spot_market(&exchange, &owner); let spot_market_2_id = launch_realistic_weth_usdt_spot_market(&exchange, &owner); - let contr_addr = init_self_relaying_contract_and_get_address( - &wasm, - &owner, - &[str_coin("1_000", USDT, Decimals::Six)], - ); + let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]); set_route_and_assert_success( &wasm, &owner, &contr_addr, INJ_2, ETH, - vec![ - spot_market_1_id.as_str().into(), - spot_market_2_id.as_str().into(), - ], + vec![spot_market_1_id.as_str().into(), spot_market_2_id.as_str().into()], ); let trader1 = init_rich_account(&app); let trader2 = init_rich_account(&app); let trader3 = init_rich_account(&app); - create_realistic_inj_usdt_buy_orders_from_spreadsheet( - &app, - &spot_market_1_id, - &trader1, - &trader2, - ); - create_realistic_eth_usdt_sell_orders_from_spreadsheet( - &app, - &spot_market_2_id, - &trader1, - &trader2, - &trader3, - ); + create_realistic_inj_usdt_buy_orders_from_spreadsheet(&app, &spot_market_1_id, &trader1, &trader2); + create_realistic_eth_usdt_sell_orders_from_spreadsheet(&app, &spot_market_2_id, &trader1, &trader2, &trader3); app.increase_time(1); @@ -1693,18 +1291,11 @@ fn exact_two_hop_inj_eth_swap_test_template( let swapper = must_init_account_with_funds( &app, - &[ - str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), - str_coin("1", INJ, Decimals::Eighteen), - ], + &[str_coin(inj_to_swap, INJ_2, Decimals::Eighteen), str_coin("1", INJ, Decimals::Eighteen)], ); let contract_balances_before = query_all_bank_balances(&bank, &contr_addr); - assert_eq!( - contract_balances_before.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_before.len(), 1, "wrong number of denoms in contract balances"); let query_result: SwapEstimationResult = wasm .query( @@ -1728,15 +1319,11 @@ fn exact_two_hop_inj_eth_swap_test_template( ) .unwrap(); - let expected_difference = - human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; + let expected_difference = human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity; let swapper_inj_balance_after = query_bank_balance(&bank, INJ_2, swapper.address().as_str()); let swapper_atom_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str()); - assert_eq!( - swapper_inj_balance_after, expected_difference, - "wrong amount of INJ was exchanged" - ); + assert_eq!(swapper_inj_balance_after, expected_difference, "wrong amount of INJ was exchanged"); assert!( swapper_atom_balance_after >= exact_quantity_to_receive, @@ -1745,15 +1332,10 @@ fn exact_two_hop_inj_eth_swap_test_template( swapper_atom_balance_after.scaled(Decimals::Eighteen.get_decimals().neg()) ); - let one_percent_diff = exact_quantity_to_receive - * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); + let one_percent_diff = exact_quantity_to_receive * (FPDecimal::must_from_str(max_diff_percentage.0) / FPDecimal::from(100u128)); assert!( - are_fpdecimals_approximately_equal( - swapper_atom_balance_after, - exact_quantity_to_receive, - one_percent_diff, - ), + are_fpdecimals_approximately_equal(swapper_atom_balance_after, exact_quantity_to_receive, one_percent_diff,), "swapper did not receive expected exact ETH amount +/- {}% -> expected: {} ETH, actual: {} ETH, max diff: {} ETH", max_diff_percentage.0, exact_quantity_to_receive.scaled(Decimals::Eighteen.get_decimals().neg()), @@ -1762,16 +1344,10 @@ fn exact_two_hop_inj_eth_swap_test_template( ); let contract_balances_after = query_all_bank_balances(&bank, contr_addr.as_str()); - assert_eq!( - contract_balances_after.len(), - 1, - "wrong number of denoms in contract balances" - ); + assert_eq!(contract_balances_after.len(), 1, "wrong number of denoms in contract balances"); - let contract_usdt_balance_before = - FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); - let contract_usdt_balance_after = - FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); + let contract_usdt_balance_before = FPDecimal::must_from_str(contract_balances_before[0].amount.as_str()); + let contract_usdt_balance_after = FPDecimal::must_from_str(contract_balances_after[0].amount.as_str()); assert!( contract_usdt_balance_after >= contract_usdt_balance_before, @@ -1782,11 +1358,7 @@ fn exact_two_hop_inj_eth_swap_test_template( let max_diff = human_to_dec("0.82", Decimals::Six); assert!( - are_fpdecimals_approximately_equal( - contract_usdt_balance_after, - contract_usdt_balance_before, - max_diff, - ), + are_fpdecimals_approximately_equal(contract_usdt_balance_after, contract_usdt_balance_before, max_diff,), "Contract balance changed too much. Actual balance: {} USDT, previous balance: {} USDT. Max diff: {} USDT", contract_usdt_balance_after.scaled(Decimals::Six.get_decimals().neg()), contract_usdt_balance_before.scaled(Decimals::Six.get_decimals().neg()), diff --git a/contracts/swap/src/testing/migration_test.rs b/contracts/swap/src/testing/migration_test.rs index 73dc413..746e906 100644 --- a/contracts/swap/src/testing/migration_test.rs +++ b/contracts/swap/src/testing/migration_test.rs @@ -2,30 +2,24 @@ use crate::{ msg::{FeeRecipient, InstantiateMsg, MigrateMsg}, testing::{ integration_realistic_tests_min_quantity::happy_path_two_hops_test, - test_utils::{ - must_init_account_with_funds, store_code, str_coin, Decimals, ATOM, ETH, INJ, USDT, - }, + test_utils::{must_init_account_with_funds, str_coin, Decimals, ATOM, ETH, INJ, USDT}, }, }; -use cosmos_sdk_proto::cosmwasm::wasm::v1::{ - MsgMigrateContract, MsgMigrateContractResponse, QueryContractInfoRequest, - QueryContractInfoResponse, -}; use cosmwasm_std::Addr; +use injective_std::types::cosmwasm::wasm::v1::{MsgMigrateContract, MsgMigrateContractResponse, QueryContractInfoRequest, QueryContractInfoResponse}; use injective_test_tube::{Account, ExecuteResponse, InjectiveTestApp, Module, Runner, Wasm}; +use injective_testing::test_tube::utils::store_code; type V100InstantiateMsg = InstantiateMsg; #[test] #[cfg_attr(not(feature = "integration"), ignore)] -fn test_migration_v100_to_v101() { +fn test_migration() { let app = InjectiveTestApp::new(); let wasm = Wasm::new(&app); - let wasm_byte_code = - std::fs::read("../../contracts/swap/src/testing/test_artifacts/swap-contract-v100.wasm") - .unwrap(); + let wasm_byte_code = std::fs::read("../../contracts/swap/src/testing/test_artifacts/swap-contract-v101.wasm").unwrap(); let owner = must_init_account_with_funds( &app, @@ -37,11 +31,7 @@ fn test_migration_v100_to_v101() { ], ); - let swap_v100_code_id = wasm - .store_code(&wasm_byte_code, None, &owner) - .unwrap() - .data - .code_id; + let swap_v100_code_id = wasm.store_code(&wasm_byte_code, None, &owner).unwrap().data.code_id; let swap_v100_address: String = wasm .instantiate( diff --git a/contracts/swap/src/testing/mod.rs b/contracts/swap/src/testing/mod.rs index 0b0eead..ac28e14 100644 --- a/contracts/swap/src/testing/mod.rs +++ b/contracts/swap/src/testing/mod.rs @@ -1,9 +1,8 @@ mod authz_tests; mod config_tests; -// // mod migration_test; -mod integration_logic_tests; mod integration_realistic_tests_exact_quantity; mod integration_realistic_tests_min_quantity; +mod migration_test; mod queries_tests; mod storage_tests; mod swap_tests; diff --git a/contracts/swap/src/testing/queries_tests.rs b/contracts/swap/src/testing/queries_tests.rs index 5e714f5..e79372e 100644 --- a/contracts/swap/src/testing/queries_tests.rs +++ b/contracts/swap/src/testing/queries_tests.rs @@ -1,7 +1,7 @@ use std::ops::Neg; use std::str::FromStr; -use cosmwasm_std::testing::{mock_env, mock_info}; +use cosmwasm_std::testing::{message_info, mock_env}; use cosmwasm_std::{coin, Addr}; use crate::admin::set_route; @@ -32,7 +32,7 @@ fn test_calculate_swap_price_external_fee_recipient_from_source_quantity() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::Address(admin.to_owned()), admin: admin.to_owned(), @@ -107,7 +107,7 @@ fn test_calculate_swap_price_external_fee_recipient_from_target_quantity() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::Address(admin.to_owned()), admin: admin.to_owned(), @@ -181,7 +181,7 @@ fn test_calculate_swap_price_self_fee_recipient_from_source_quantity() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::SwapContract, admin: admin.to_owned(), @@ -252,7 +252,7 @@ fn test_calculate_swap_price_self_fee_recipient_from_target_quantity() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::SwapContract, admin: admin.to_owned(), @@ -329,7 +329,7 @@ fn test_calculate_estimate_when_selling_both_quantity_directions_simple() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::Address(admin.to_owned()), admin: admin.to_owned(), @@ -433,7 +433,7 @@ fn test_calculate_estimate_when_buying_both_quantity_directions_simple() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::Address(admin.to_owned()), admin: admin.to_owned(), @@ -522,7 +522,7 @@ fn get_all_queries_returns_empty_array_if_no_routes_are_set() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::SwapContract, admin: admin.to_owned(), @@ -544,7 +544,7 @@ fn get_all_queries_returns_expected_array_if_routes_are_set() { instantiate( deps.as_mut_deps(), mock_env(), - mock_info(admin.as_ref(), &[coin(1_000u128, "usdt")]), + message_info(&Addr::unchecked(admin), &[coin(1_000u128, "usdt")]), InstantiateMsg { fee_recipient: FeeRecipient::SwapContract, admin: admin.to_owned(), @@ -607,6 +607,6 @@ fn get_all_queries_returns_expected_array_if_routes_are_set() { "Incorrect routes returned" ); - let all_routes_result_paginated = get_all_swap_routes(deps.as_ref().storage, None, Some(1u32)).unwrap(); - assert_eq!(all_routes_result_paginated.len(), 1); + let all_routes_result_paginated = get_all_swap_routes(deps.as_ref().storage, None, Some(1u32)); + assert_eq!(all_routes_result_paginated.unwrap().len(), 1); } diff --git a/contracts/swap/src/testing/test_utils.rs b/contracts/swap/src/testing/test_utils.rs index b0c2c5a..85c8ca5 100644 --- a/contracts/swap/src/testing/test_utils.rs +++ b/contracts/swap/src/testing/test_utils.rs @@ -13,18 +13,17 @@ use injective_std::{ types::{ cosmos::{ authz::v1beta1::{Grant, MsgGrant}, - bank::v1beta1::{MsgSend, QueryAllBalancesRequest, QueryBalanceRequest}, - base::v1beta1::Coin as TubeCoin, - gov::{v1::MsgVote, v1beta1::MsgSubmitProposal}, + bank::v1beta1::{QueryAllBalancesRequest, QueryBalanceRequest}, }, cosmwasm::wasm::v1::{AcceptedMessageKeysFilter, ContractExecutionAuthorization, ContractGrant, MaxCallsLimit}, - injective::exchange::v1beta1::{ - MsgCreateSpotLimitOrder, OrderInfo, OrderType, QuerySpotMarketsRequest, SpotMarketParamUpdateProposal, SpotOrder, - }, + injective::exchange::v1beta1::{MsgCreateSpotLimitOrder, OrderInfo, OrderType, SpotOrder}, }, }; -use injective_test_tube::{Account, Authz, Bank, Exchange, Gov, InjectiveTestApp, Module, SigningAccount, Wasm}; -use injective_testing::test_tube::{exchange::launch_spot_market_custom, utils::store_code}; +use injective_test_tube::{Account, Authz, Bank, Exchange, InjectiveTestApp, Module, SigningAccount, Wasm}; +use injective_testing::{ + test_tube::{exchange::launch_spot_market_custom, utils::store_code}, + utils::scale_price_quantity_spot_market, +}; use prost::Message; use std::{collections::HashMap, str::FromStr}; @@ -47,7 +46,6 @@ pub const NINJA: &str = "ninja"; pub const DEFAULT_TAKER_FEE: f64 = 0.001; pub const DEFAULT_ATOMIC_MULTIPLIER: f64 = 2.5; pub const DEFAULT_SELF_RELAYING_FEE_PART: f64 = 0.6; -pub const DEFAULT_RELAYER_SHARE: f64 = 1.0 - DEFAULT_SELF_RELAYING_FEE_PART; #[derive(PartialEq, Eq, Debug, Copy, Clone)] #[repr(i32)] @@ -276,29 +274,16 @@ fn create_mock_spot_market(base: &str, min_price_tick_size: FPDecimal, min_quant min_quantity_tick_size, } } -pub fn get_spot_market_id(exchange: &Exchange, ticker: String) -> String { - let spot_markets = exchange - .query_spot_markets(&QuerySpotMarketsRequest { - status: "Active".to_string(), - market_ids: vec![], - }) - .unwrap() - .markets; - - let market = spot_markets.iter().find(|m| m.ticker == ticker).unwrap(); - - market.market_id.to_string() -} pub fn launch_realistic_inj_usdt_spot_market(exchange: &Exchange, signer: &SigningAccount) -> String { launch_spot_market_custom( exchange, signer, - "TICKER".to_string(), + "INJ2/USDT".to_string(), INJ_2.to_string(), USDT.to_string(), - dec_to_proto(FPDecimal::must_from_str("0.000000000000001")), - dec_to_proto(FPDecimal::must_from_str("0.0001")), + "0.000000000000001".to_string(), + "1000000000000000".to_string(), ) } @@ -309,8 +294,8 @@ pub fn launch_realistic_weth_usdt_spot_market(exchange: &Exchange (String, String) { - let price_dec = FPDecimal::must_from_str(price.replace('_', "").as_str()); - let quantity_dec = FPDecimal::must_from_str(quantity.replace('_', "").as_str()); - - let scaled_price = price_dec.scaled(quote_decimals.get_decimals() - base_decimals.get_decimals()); - let scaled_quantity = quantity_dec.scaled(base_decimals.get_decimals()); - (dec_to_proto(scaled_price), dec_to_proto(scaled_quantity)) -} - -pub fn dec_to_proto(val: FPDecimal) -> String { - val.scaled(18).to_string() -} - #[allow(clippy::too_many_arguments)] pub fn create_realistic_limit_order( app: &InjectiveTestApp, @@ -598,7 +542,7 @@ pub fn create_realistic_limit_order( base_decimals: Decimals, quote_decimals: Decimals, ) { - let (price_to_send, quantity_to_send) = scale_price_quantity_for_market(price, quantity, &base_decimals, "e_decimals); + let (price_to_send, quantity_to_send) = scale_price_quantity_spot_market(price, quantity, &(base_decimals as i32), &(quote_decimals as i32)); let exchange = Exchange::new(app); exchange @@ -645,29 +589,6 @@ pub fn init_self_relaying_contract_and_get_address(wasm: &Wasm .address } -pub fn init_contract_with_fee_recipient_and_get_address( - wasm: &Wasm, - owner: &SigningAccount, - initial_balance: &[Coin], - fee_recipient: &SigningAccount, -) -> String { - let code_id = store_code(wasm, owner, "swap_contract".to_string()); - wasm.instantiate( - code_id, - &InstantiateMsg { - fee_recipient: FeeRecipient::Address(Addr::unchecked(fee_recipient.address())), - admin: Addr::unchecked(owner.address()), - }, - Some(&owner.address()), - Some("Swap"), - initial_balance, - owner, - ) - .unwrap() - .data - .address -} - pub fn set_route_and_assert_success( wasm: &Wasm, signer: &SigningAccount, @@ -718,31 +639,6 @@ pub fn query_bank_balance(bank: &Bank, denom: &str, address: & .unwrap() } -pub fn pause_spot_market(app: &InjectiveTestApp, market_id: &str, proposer: &SigningAccount, validator: &SigningAccount) { - let gov = Gov::new(app); - pass_spot_market_params_update_proposal( - &gov, - &SpotMarketParamUpdateProposal { - title: format!("Set market {market_id} status to paused"), - description: format!("Set market {market_id} status to paused"), - market_id: market_id.to_string(), - maker_fee_rate: "".to_string(), - taker_fee_rate: "".to_string(), - relayer_fee_share_rate: "".to_string(), - min_price_tick_size: "".to_string(), - min_quantity_tick_size: "".to_string(), - status: 2, - min_notional: "0".to_string(), - ticker: "0".to_string(), - admin_info: None, - }, - proposer, - validator, - ); - - app.increase_time(10u64) -} - pub fn create_contract_authorization( app: &InjectiveTestApp, contract: String, @@ -799,56 +695,6 @@ pub fn create_contract_authorization( .unwrap(); } -pub fn pass_spot_market_params_update_proposal( - gov: &Gov, - proposal: &SpotMarketParamUpdateProposal, - proposer: &SigningAccount, - validator: &SigningAccount, -) { - let mut buf = vec![]; - SpotMarketParamUpdateProposal::encode(proposal, &mut buf).unwrap(); - - println!("submitting proposal: {proposal:?}"); - let submit_response = gov.submit_proposal_v1beta1( - MsgSubmitProposal { - content: Some(Any { - type_url: "/injective.exchange.v1beta1.SpotMarketParamUpdateProposal".to_string(), - value: buf, - }), - initial_deposit: vec![TubeCoin { - amount: "100000000000000000000".to_string(), - denom: "inj".to_string(), - }], - proposer: proposer.address(), - }, - proposer, - ); - - assert!(submit_response.is_ok(), "failed to submit proposal"); - - let proposal_id = submit_response.unwrap().data.proposal_id; - println!("voting on proposal: {proposal_id:?}"); - let vote_response = gov.vote( - MsgVote { - proposal_id, - voter: validator.address(), - option: 1, - metadata: "".to_string(), - }, - validator, - ); - - assert!(vote_response.is_ok(), "failed to vote on proposal"); -} - -pub fn init_default_validator_account(app: &InjectiveTestApp) -> SigningAccount { - app.get_first_validator_signing_account(INJ.to_string(), 1.2f64).unwrap() -} - -pub fn init_default_signer_account(app: &InjectiveTestApp) -> SigningAccount { - must_init_account_with_funds(app, &[str_coin("100_000", INJ, Decimals::Eighteen)]) -} - pub fn init_rich_account(app: &InjectiveTestApp) -> SigningAccount { must_init_account_with_funds( app, @@ -864,21 +710,6 @@ pub fn init_rich_account(app: &InjectiveTestApp) -> SigningAccount { ) } -pub fn fund_account_with_some_inj(bank: &Bank, from: &SigningAccount, to: &SigningAccount) { - bank.send( - MsgSend { - from_address: from.address(), - to_address: to.address(), - amount: vec![TubeCoin { - amount: "1000000000000000000000".to_string(), - denom: "inj".to_string(), - }], - }, - from, - ) - .unwrap(); -} - pub fn human_to_dec(raw_number: &str, decimals: Decimals) -> FPDecimal { FPDecimal::must_from_str(&raw_number.replace('_', "")).scaled(decimals.get_decimals()) } @@ -894,7 +725,7 @@ pub fn str_coin(human_amount: &str, denom: &str, decimals: Decimals) -> Coin { } mod tests { - use crate::testing::test_utils::{human_to_dec, human_to_proto, scale_price_quantity_for_market, Decimals}; + use crate::testing::test_utils::{human_to_dec, human_to_proto, scale_price_quantity_spot_market, Decimals}; use injective_math::FPDecimal; #[test] @@ -1088,7 +919,7 @@ mod tests { let base_decimals = Decimals::Eighteen; let quote_decimals = Decimals::Six; - let (scaled_price, scaled_quantity) = scale_price_quantity_for_market(price, quantity, &base_decimals, "e_decimals); + let (scaled_price, scaled_quantity) = scale_price_quantity_spot_market(price, quantity, &(base_decimals as i32), &(quote_decimals as i32)); // 1 => 1 * 10^6 - 10^18 => 0.000000000001000000 * 10^18 => 1000000 assert_eq!(scaled_price, "1000000", "price was scaled incorrectly"); @@ -1107,7 +938,7 @@ mod tests { let base_decimals = Decimals::Eighteen; let quote_decimals = Decimals::Six; - let (scaled_price, scaled_quantity) = scale_price_quantity_for_market(price, quantity, &base_decimals, "e_decimals); + let (scaled_price, scaled_quantity) = scale_price_quantity_spot_market(price, quantity, &(base_decimals as i32), &(quote_decimals as i32)); // 0.000000000008782000 * 10^18 = 8782000 assert_eq!(scaled_price, "8782000", "price was scaled incorrectly"); @@ -1125,7 +956,7 @@ mod tests { let base_decimals = Decimals::Six; let quote_decimals = Decimals::Six; - let (scaled_price, scaled_quantity) = scale_price_quantity_for_market(price, quantity, &base_decimals, "e_decimals); + let (scaled_price, scaled_quantity) = scale_price_quantity_spot_market(price, quantity, &(base_decimals as i32), &(quote_decimals as i32)); // 1 => 1.(10^18) => 1000000000000000000 assert_eq!(scaled_price, "1000000000000000000", "price was scaled incorrectly"); @@ -1141,7 +972,7 @@ mod tests { let base_decimals = Decimals::Six; let quote_decimals = Decimals::Six; - let (scaled_price, scaled_quantity) = scale_price_quantity_for_market(price, quantity, &base_decimals, "e_decimals); + let (scaled_price, scaled_quantity) = scale_price_quantity_spot_market(price, quantity, &(base_decimals as i32), &(quote_decimals as i32)); // 1.129 => 1.129(10^15) => 1129000000000000000 assert_eq!(scaled_price, "1129000000000000000", "price was scaled incorrectly"); @@ -1154,7 +985,7 @@ pub fn are_fpdecimals_approximately_equal(first: FPDecimal, second: FPDecimal, m (first - second).abs() <= max_diff } -pub fn assert_fee_is_as_expected(raw_fees: &mut Vec, expected_fees: &mut Vec, max_diff: FPDecimal) { +pub fn assert_fee_is_as_expected(raw_fees: &mut [FPCoin], expected_fees: &mut [FPCoin], max_diff: FPDecimal) { assert_eq!(raw_fees.len(), expected_fees.len(), "Wrong number of fee denoms received"); raw_fees.sort_by_key(|f| f.denom.clone());