From 7bb8b29f746d3a6bd521faafaf56921744e1aa5b Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Fri, 29 Nov 2024 08:56:20 -0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20add=20multiple=20rebalance=20scenar?= =?UTF-8?q?ios=20and=20error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/contracts/vault/src/test/rebalance.rs | 279 ++++++++++++++++++++- 1 file changed, 277 insertions(+), 2 deletions(-) diff --git a/apps/contracts/vault/src/test/rebalance.rs b/apps/contracts/vault/src/test/rebalance.rs index dffb1e7a..d81888ab 100644 --- a/apps/contracts/vault/src/test/rebalance.rs +++ b/apps/contracts/vault/src/test/rebalance.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{vec as sorobanvec, String, Vec}; +use soroban_sdk::{vec as sorobanvec, InvokeError, String, Vec}; use crate::test::{ create_strategy_params_token0, @@ -13,9 +13,10 @@ use crate::test::{ }, DeFindexVaultTest, }; +use crate::test::defindex_vault::ContractError; #[test] -fn rebalance() { +fn rebalance_multi_instructions() { let test = DeFindexVaultTest::setup(); test.env.mock_all_auths(); let strategy_params_token0 = create_strategy_params_token0(&test); @@ -105,3 +106,277 @@ fn rebalance() { let vault_balance = test.token0.balance(&test.defindex_contract.address); assert_eq!(vault_balance, instruction_amount_1); } + +#[test] +fn rebalance_one_instruction() { + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + let strategy_params_token0 = create_strategy_params_token0(&test); + let assets: Vec = sorobanvec![ + &test.env, + AssetStrategySet { + address: test.token0.address.clone(), + strategies: strategy_params_token0.clone() + } + ]; + + test.defindex_contract.initialize( + &assets, + &test.manager, + &test.emergency_manager, + &test.vault_fee_receiver, + &2000u32, + &test.defindex_protocol_receiver, + &test.defindex_factory, + &String::from_str(&test.env, "TestVault"), + &String::from_str(&test.env, "TSTV"), + ); + let amount = 987654321i128; + + let users = DeFindexVaultTest::generate_random_users(&test.env, 1); + + test.token0_admin_client.mint(&users[0], &amount); + let user_balance = test.token0.balance(&users[0]); + assert_eq!(user_balance, amount); + + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, 0i128); + + test.defindex_contract.deposit( + &sorobanvec![&test.env, amount], + &sorobanvec![&test.env, amount], + &users[0], + ); + + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, amount - 1000); + + let investments = sorobanvec![ + &test.env, + Some(AssetInvestmentAllocation { + asset: test.token0.address.clone(), + strategy_investments: sorobanvec![ + &test.env, + Some(StrategyInvestment { + strategy: test.strategy_client_token0.address.clone(), + amount: amount, + }), + ], + }), + ]; + + test.defindex_contract.invest(&investments); + + let vault_balance = test.token0.balance(&test.defindex_contract.address); + assert_eq!(vault_balance, 0); + + // REBALANCE + + let instruction_amount_0 = 200i128; + + let instructions = sorobanvec![ + &test.env, + Instruction { + action: ActionType::Withdraw, + strategy: Some(test.strategy_client_token0.address.clone()), + amount: Some(instruction_amount_0), + swap_details_exact_in: OptionalSwapDetailsExactIn::None, + swap_details_exact_out: OptionalSwapDetailsExactOut::None, + }, + ]; + + test.defindex_contract.rebalance(&instructions); + + let vault_balance = test.token0.balance(&test.defindex_contract.address); + assert_eq!(vault_balance, instruction_amount_0); +} + +#[test] +fn rebalance_empty_instructions(){ + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + + let strategy_params_token0 = create_strategy_params_token0(&test); + let assets: Vec = sorobanvec![ + &test.env, + AssetStrategySet { + address: test.token0.address.clone(), + strategies: strategy_params_token0.clone() + } + ]; + test.defindex_contract.initialize( + &assets, + &test.manager, + &test.emergency_manager, + &test.vault_fee_receiver, + &100u32, + &test.defindex_protocol_receiver, + &test.defindex_factory, + &String::from_str(&test.env, "testVault"), + &String::from_str(&test.env, "TSTV"), + ); + let amount: i128 = 987654321; + let users = DeFindexVaultTest::generate_random_users(&test.env, 1); + test.token0_admin_client.mint(&users[0], &amount); + let vault_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(vault_balance, 0i128); + + test.defindex_contract.deposit( + &sorobanvec![&test.env, amount], + &sorobanvec![&test.env, amount], + &users[0], + ); + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, amount - 1000); + + let instructions = sorobanvec![ + &test.env, + Instruction { + action: ActionType::Withdraw, + strategy: None, + amount: None, + swap_details_exact_in: OptionalSwapDetailsExactIn::None, + swap_details_exact_out: OptionalSwapDetailsExactOut::None, + }, + ]; + let rebalance = test.defindex_contract.try_rebalance(&instructions); + assert_eq!(rebalance, Err(Ok(ContractError::MissingInstructionData))); + + let no_strategy_instructions = sorobanvec![ + &test.env, + Instruction { + action: ActionType::Withdraw, + strategy: Some(test.strategy_client_token0.address.clone()), + amount: None, + swap_details_exact_in: OptionalSwapDetailsExactIn::None, + swap_details_exact_out: OptionalSwapDetailsExactOut::None, + }, + ]; + let rebalance = test.defindex_contract.try_rebalance(&no_strategy_instructions); + assert_eq!(rebalance, Err(Ok(ContractError::MissingInstructionData))); + + let no_amount_instructions = sorobanvec![ + &test.env, + Instruction { + action: ActionType::Withdraw, + strategy: Some(test.strategy_client_token0.address.clone()), + amount: None, + swap_details_exact_in: OptionalSwapDetailsExactIn::None, + swap_details_exact_out: OptionalSwapDetailsExactOut::None, + }, + ]; + let rebalance = test.defindex_contract.try_rebalance(&no_amount_instructions); + assert_eq!(rebalance, Err(Ok(ContractError::MissingInstructionData))); +} + +#[test] +fn rebalance_no_instructions(){ + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + + let strategy_params_token0 = create_strategy_params_token0(&test); + let assets: Vec = sorobanvec![ + &test.env, + AssetStrategySet { + address: test.token0.address.clone(), + strategies: strategy_params_token0.clone() + } + ]; + test.defindex_contract.initialize( + &assets, + &test.manager, + &test.emergency_manager, + &test.vault_fee_receiver, + &100u32, + &test.defindex_protocol_receiver, + &test.defindex_factory, + &String::from_str(&test.env, "testVault"), + &String::from_str(&test.env, "TSTV"), + ); + let amount: i128 = 987654321; + let users = DeFindexVaultTest::generate_random_users(&test.env, 1); + test.token0_admin_client.mint(&users[0], &amount); + let vault_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(vault_balance, 0i128); + + test.defindex_contract.deposit( + &sorobanvec![&test.env, amount], + &sorobanvec![&test.env, amount], + &users[0], + ); + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, amount - 1000); + + let rebalance = test.defindex_contract.try_rebalance(&sorobanvec![&test.env]); + assert_eq!(rebalance, Err(Ok(ContractError::NoInstructions))); +} + +#[test] +fn rebalance_insufficient_balance(){ + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + + let strategy_params_token0 = create_strategy_params_token0(&test); + let assets: Vec = sorobanvec![ + &test.env, + AssetStrategySet { + address: test.token0.address.clone(), + strategies: strategy_params_token0.clone() + } + ]; + test.defindex_contract.initialize( + &assets, + &test.manager, + &test.emergency_manager, + &test.vault_fee_receiver, + &100u32, + &test.defindex_protocol_receiver, + &test.defindex_factory, + &String::from_str(&test.env, "testVault"), + &String::from_str(&test.env, "TSTV"), + ); + let amount: i128 = 987654321; + let users = DeFindexVaultTest::generate_random_users(&test.env, 1); + test.token0_admin_client.mint(&users[0], &amount); + let vault_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(vault_balance, 0i128); + + test.defindex_contract.deposit( + &sorobanvec![&test.env, amount], + &sorobanvec![&test.env, amount], + &users[0], + ); + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, amount - 1000); + + let withdraw_instructions = sorobanvec![ + &test.env, + Instruction { + action: ActionType::Withdraw, + strategy: Some(test.strategy_client_token0.address.clone()), + amount: Some(amount + 1), + swap_details_exact_in: OptionalSwapDetailsExactIn::None, + swap_details_exact_out: OptionalSwapDetailsExactOut::None, + }, + ]; + let rebalance = test.defindex_contract.try_rebalance(&withdraw_instructions); + assert_eq!(rebalance, Err(Ok(ContractError::StrategyWithdrawError))); + + let invest_instructions = sorobanvec!( + &test.env, + Instruction { + action: ActionType::Invest, + strategy: Some(test.strategy_client_token0.address.clone()), + amount: Some(amount + 1), + swap_details_exact_in: OptionalSwapDetailsExactIn::None, + swap_details_exact_out: OptionalSwapDetailsExactOut::None, + }, + ); + let rebalance = test.defindex_contract.try_rebalance(&invest_instructions); + if rebalance == Err(Err(InvokeError::Contract(10))) { + return; + } else { + panic!("Expected error not returned"); + } +} +