From 017530c10b267383f7476a2ef6d5d9a22255ae07 Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:12:37 -0300 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8Add=20tests=20to=20deposit=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/contracts/vault/src/test/deposit.rs | 237 +++++++++++++++++++++++ 1 file changed, 237 insertions(+) diff --git a/apps/contracts/vault/src/test/deposit.rs b/apps/contracts/vault/src/test/deposit.rs index 5b9ffd6f..815a738e 100644 --- a/apps/contracts/vault/src/test/deposit.rs +++ b/apps/contracts/vault/src/test/deposit.rs @@ -705,3 +705,240 @@ fn deposit_several_assets_min_greater_than_optimal() { } +//test deposit amounts_min greater than amounts_desired +#[test] +fn deposit_amounts_min_greater_than_amounts_desired(){ + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + let strategy_params_token0 = create_strategy_params_token0(&test); + let strategy_params_token1 = create_strategy_params_token1(&test); + + // initialize with 2 assets + let assets: Vec = sorobanvec![ + &test.env, + AssetStrategySet { + address: test.token0.address.clone(), + strategies: strategy_params_token0.clone() + }, + AssetStrategySet { + address: test.token1.address.clone(), + strategies: strategy_params_token1.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, "dfToken"), + &String::from_str(&test.env, "DFT"), + ); + let amount0 = 123456789i128; + let amount1 = 987654321i128; + + let users = DeFindexVaultTest::generate_random_users(&test.env, 2); + + // Balances before deposit + test.token0_admin_client.mint(&users[0], &amount0); + test.token1_admin_client.mint(&users[0], &amount1); + let user_balance0 = test.token0.balance(&users[0]); + assert_eq!(user_balance0, amount0); + let user_balance1 = test.token1.balance(&users[0]); + assert_eq!(user_balance1, amount1); + + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, 0i128); + + // deposit + let deposit_result=test.defindex_contract.try_deposit( + &sorobanvec![&test.env, amount0, amount1], + &sorobanvec![&test.env, amount0 + 1, amount1 + 1], + &users[0], + ); + + // this should fail + assert_eq!(deposit_result, Err(Ok(ContractError::InsufficientAmount))); +} + +//Test token transfer from user to vault on deposit +#[test] +fn deposit_transfers_tokens_from_user_to_vault(){ + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + let strategy_params_token0 = create_strategy_params_token0(&test); + let strategy_params_token1 = create_strategy_params_token1(&test); + + // initialize with 2 assets + let assets: Vec = sorobanvec![ + &test.env, + AssetStrategySet { + address: test.token0.address.clone(), + strategies: strategy_params_token0.clone() + }, + AssetStrategySet { + address: test.token1.address.clone(), + strategies: strategy_params_token1.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, "dfToken"), + &String::from_str(&test.env, "DFT"), + ); + let amount0 = 123456789i128; + let amount1 = 987654321i128; + + let users = DeFindexVaultTest::generate_random_users(&test.env, 2); + + // Balances before deposit + test.token0_admin_client.mint(&users[0], &amount0); + test.token1_admin_client.mint(&users[0], &amount1); + let user_balance0 = test.token0.balance(&users[0]); + assert_eq!(user_balance0, amount0); + let user_balance1 = test.token1.balance(&users[0]); + assert_eq!(user_balance1, amount1); + + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, 0i128); + + // deposit + test.defindex_contract.deposit( + &sorobanvec![&test.env, amount0, amount1], + &sorobanvec![&test.env, amount0, amount1], + &users[0], + ); + + // check balances after deposit + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, amount0 + amount1 - 1000); + + let user_balance0 = test.token0.balance(&users[0]); + assert_eq!(user_balance0, 0i128); +} + +#[test] +fn test_deposit_arithmetic_error() { + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + let strategy_params_token0 = create_strategy_params_token0(&test); + + // Initialize with 1 asset + 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, "dfToken"), + &String::from_str(&test.env, "DFT"), + ); + + // Mock the environment to provoke a division by zero + let mut mock_map = Map::new(&test.env); + mock_map.set(test.token0.address.clone(), 0i128); // Total funds for token0 is 0 + + let amount = 123456789i128; + + let users = DeFindexVaultTest::generate_random_users(&test.env, 1); + + // Mint tokens to user + test.token0_admin_client.mint(&users[0], &amount); + + let large_amount = i128::MAX / 2; + test.token0_admin_client.mint(&users[0], &large_amount); + + //first deposit to overflow the balance + test.defindex_contract.deposit( + &sorobanvec![&test.env, large_amount], + &sorobanvec![&test.env, large_amount], + &users[0], + ); + + // Try to deposit a large amount + let result = test.defindex_contract.try_deposit( + &sorobanvec![&test.env, large_amount], + &sorobanvec![&test.env, large_amount], + &users[0], + ); + + // Verify that the returned error is ContractError::ArithmeticError + assert_eq!(result, Err(Ok(ContractError::ArithmeticError))); +} + +//all amounts are cero +#[test] +fn deposit_amounts_desired_zero() { + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + let strategy_params_token0 = create_strategy_params_token0(&test); + + // Initialize with 1 asset + 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, "dfToken"), + &String::from_str(&test.env, "DFT"), + ); + + let amount = 123456789i128; + + let users = DeFindexVaultTest::generate_random_users(&test.env, 1); + + // Mint tokens to user + test.token0_admin_client.mint(&users[0], &amount); + + // Balances before deposit + let user_balance_before = test.token0.balance(&users[0]); + assert_eq!(user_balance_before, amount); + + let vault_balance_before = test.token0.balance(&test.defindex_contract.address); + assert_eq!(vault_balance_before, 0i128); + + let df_balance_before = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance_before, 0i128); + + // Attempt to deposit with amounts_desired all set to 0 + let deposit_result = test.defindex_contract.try_deposit( + &sorobanvec![&test.env, 0i128], + &sorobanvec![&test.env, 0i128], + &users[0], + ); + + // Verify that the returned error is ContractError::InsufficientAmount + assert_eq!(deposit_result, Err(Ok(ContractError::InsufficientAmount))); +} + From f20887b934a34ec5899625f2fc86825fe32ed3a2 Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:55:17 -0300 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=A8Add=20test=20for=20deposit=20with?= =?UTF-8?q?=20insufficient=20funds=20and=20error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/contracts/vault/src/test/deposit.rs | 68 +++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/apps/contracts/vault/src/test/deposit.rs b/apps/contracts/vault/src/test/deposit.rs index 815a738e..b82d872d 100644 --- a/apps/contracts/vault/src/test/deposit.rs +++ b/apps/contracts/vault/src/test/deposit.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{vec as sorobanvec, String, Vec, Map}; +use soroban_sdk::{vec as sorobanvec, InvokeError, Map, String, Vec}; use crate::test::defindex_vault::{AssetStrategySet, ContractError}; use crate::test::{ @@ -942,3 +942,69 @@ fn deposit_amounts_desired_zero() { assert_eq!(deposit_result, Err(Ok(ContractError::InsufficientAmount))); } + + // Deposit with insufficient funds and check for specific error message +#[test] +fn deposit_insufficient_funds_with_error_message() { + let test = DeFindexVaultTest::setup(); + test.env.mock_all_auths(); + let strategy_params_token0 = create_strategy_params_token0(&test); + let strategy_params_token1 = create_strategy_params_token1(&test); + + // Initialize with 2 assets + let assets: Vec = sorobanvec![ + &test.env, + AssetStrategySet { + address: test.token0.address.clone(), + strategies: strategy_params_token0.clone() + }, + AssetStrategySet { + address: test.token1.address.clone(), + strategies: strategy_params_token1.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, "dfToken"), + &String::from_str(&test.env, "DFT"), + ); + + let amount0 = 123456789i128; + let amount1 = 987654321i128; + + let users = DeFindexVaultTest::generate_random_users(&test.env, 1); + + // Mint tokens to user + test.token0_admin_client.mint(&users[0], &amount0); + test.token1_admin_client.mint(&users[0], &amount1); + + // Balances before deposit + let user_balance0 = test.token0.balance(&users[0]); + assert_eq!(user_balance0, amount0); + let user_balance1 = test.token1.balance(&users[0]); + assert_eq!(user_balance1, amount1); + + let df_balance = test.defindex_contract.balance(&users[0]); + assert_eq!(df_balance, 0i128); + + // Attempt to deposit more than available balance + let deposit_result = test.defindex_contract.try_deposit( + &sorobanvec![&test.env, amount0 + 1, amount1 + 1], + &sorobanvec![&test.env, amount0 + 1, amount1 + 1], + &users[0], + ); + + if deposit_result == Err(Err(InvokeError::Contract(10))) { + return; + } else { + panic!("Expected error not returned"); + } + +} \ No newline at end of file From 4c7a14d65c9c86d7bedf4da5d461b28a9741a53a Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Fri, 29 Nov 2024 08:54:11 -0300 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=94=A5Removed=20unnecesary=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/contracts/package.json | 1 - apps/contracts/src/tests/blend/test.ts | 232 ------------------------- 2 files changed, 233 deletions(-) delete mode 100644 apps/contracts/src/tests/blend/test.ts diff --git a/apps/contracts/package.json b/apps/contracts/package.json index 7f349d64..4ef8a7bc 100644 --- a/apps/contracts/package.json +++ b/apps/contracts/package.json @@ -11,7 +11,6 @@ "publish-addresses": "tsc && node dist/publish_addresses.js", "test": "tsc && node dist/test.js", "test-vault": "tsc && node dist/tests/testOnlyVault.js", - "test-blend": "tsc && node dist/tests/blend/test.js", "test-dev": "tsc && node dist/tests/dev.js", "test-two-strat-vault": "tsc && node dist/tests/testTwoStrategiesVault.js" }, diff --git a/apps/contracts/src/tests/blend/test.ts b/apps/contracts/src/tests/blend/test.ts deleted file mode 100644 index d9a36d77..00000000 --- a/apps/contracts/src/tests/blend/test.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { Address, Keypair, nativeToScVal, scValToNative, xdr } from "@stellar/stellar-sdk"; -import { airdropAccount, invokeCustomContract } from "../../utils/contract.js"; -import { getDfTokenBalance } from "../vault.js"; -import { randomBytes } from "crypto"; -import { TxResponse } from '@soroban-react/contracts'; -const blendStrategyAddress = "CCNFSOPH4XFQ5TNWGTJB4ZVKUUARSNQ67SETXVIQLUIW3B3F7KHA3NKJ" -const factoryAddress = "CB6RQM6ECU775ZC26NMZ6RJNKQLKQGLIJWWN2VZO6AGSE4V4DBQDL23O" -const XLMAddress = "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC" -const BlendUSDCAddress = "" -const network = process.argv[2]; -const purple = '\x1b[35m%s\x1b[0m'; -const green = '\x1b[32m%s\x1b[0m'; - - -const newVault = { - address: '', - emergencyManager: 'GCH6YKNJ3KPESGSAIGBNHRNCIYXXXSRVU7OC552RDGQFHZ4SYRI26DQE', - feeReceiver: 'GCH6YKNJ3KPESGSAIGBNHRNCIYXXXSRVU7OC552RDGQFHZ4SYRI26DQE', - manager: 'GCH6YKNJ3KPESGSAIGBNHRNCIYXXXSRVU7OC552RDGQFHZ4SYRI26DQE', - name: 'Test', - symbol: 'Test1', - vaultShare: 10, - assets: [ - { - address: 'CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC', - strategies: [ - { - address: 'CCNFSOPH4XFQ5TNWGTJB4ZVKUUARSNQ67SETXVIQLUIW3B3F7KHA3NKJ', - name: 'Blend', - paused: false - } - ], - symbol: 'XLM', - amount: 1000 - } - ], - TVL: 0 -} -export async function createVault(user?: Keypair) { - // Create and fund a new user account if not provided - console.log(purple, '--------------------------------------------------------------------') - console.log(purple, '----------------------- Creating new account -----------------------') - console.log(purple, '--------------------------------------------------------------------') - const newUser = Keypair.random(); - console.log('🚀 ~ depositToVault ~ newUser.publicKey():', newUser.publicKey()); - console.log('🚀 ~ depositToVault ~ newUser.secret():', newUser.secret()); - - console.log(green, '----------------------- New account created -------------------------') - console.log(green, 'Public key: ',newUser.publicKey()) - console.log(green, '---------------------------------------------------------------------') - - if (network !== "mainnet") { - console.log(purple, '-------------------------------------------------------------------') - console.log(purple, '----------------------- Funding new account -----------------------') - console.log(purple, '-------------------------------------------------------------------') - await airdropAccount(newUser); - } - console.log("New user publicKey:", newUser.publicKey()); - - - const indexName = "test"; - const indexSymbol = "TEST"; - const indexShare = 10; - const managerString = newUser.publicKey(); - const vaultName = nativeToScVal(indexName, { type: "string" }) - const vaultSymbol = nativeToScVal(indexSymbol, { type: "string" }) - const vaultShare = nativeToScVal(indexShare, { type: "u32" }) - const emergencyManager = new Address(managerString) - const feeReceiver = new Address(managerString) - const manager = new Address(managerString) - const salt = randomBytes(32) - - const strategyParamsScVal = xdr.ScVal.scvMap([ - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol('address'), - val: new Address(blendStrategyAddress).toScVal(), - }), - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol('name'), - val: nativeToScVal('Blend', { type: "string" }), - }), - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol('paused'), - val: nativeToScVal(false, { type: "bool" }), - }), - ]); - const strategyParamsScValVec = xdr.ScVal.scvVec([strategyParamsScVal]); - const assetsParams = xdr.ScVal.scvMap([ - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol('address'), - val: new Address(newVault.assets[0].address).toScVal(), - }), - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol('strategies'), - val: strategyParamsScValVec, - }), - ]); - const assetParamsScValVec = xdr.ScVal.scvVec([assetsParams]); - const createDefindexParams: xdr.ScVal[] = [ - emergencyManager.toScVal(), - feeReceiver.toScVal(), - vaultShare, - vaultName, - vaultSymbol, - manager.toScVal(), - assetParamsScValVec, - nativeToScVal(salt), - ]; - let result: any; - let blendVaultAddress: string; - try { - console.log(purple, '--------------------------------------------------------------') - console.log(purple, '----------------------- Creating vault -----------------------') - console.log(purple, '--------------------------------------------------------------') - result = await invokeCustomContract( - factoryAddress, - 'create_defindex_vault', - createDefindexParams, - newUser, - false - ); - blendVaultAddress = scValToNative(result.returnValue); - console.log(green, '----------------------- Vault created -------------------------') - console.log(green, 'result', blendVaultAddress) - console.log(green, '---------------------------------------------------------------') - - - // Deposit assets to the vault - - console.log(purple, '---------------------------------------------------------------------------') - console.log(purple, '----------------------- Depositing XLM to the vault -----------------------') - console.log(purple, '---------------------------------------------------------------------------') - const depositParams: xdr.ScVal[] = [ - xdr.ScVal.scvVec([nativeToScVal(987654321, { type: "i128" })]), - xdr.ScVal.scvVec([nativeToScVal(Math.ceil(987654321 * 0.9), { type: "i128" })]), - new Address(newUser.publicKey()).toScVal(), - ] - const depositResult = await invokeCustomContract( - blendVaultAddress, - 'deposit', - depositParams, - newUser, - false - ); - const depositResultValue = scValToNative(depositResult.returnValue); - - console.log(green, '------------ XLM deposited to the vault ------------') - console.log(green, 'depositResult', depositResultValue) - console.log(green, '----------------------------------------------------') - - // Withdraw assets from the vault - - console.log(purple, '------------------------------------------------------------------------------') - console.log(purple, '----------------------- Withdrawing XLM from the vault -----------------------') - console.log(purple, '------------------------------------------------------------------------------') - const withdrawAmount = Math.ceil(100); - const withdrawParams: xdr.ScVal[] = [ - nativeToScVal(withdrawAmount, { type: "i128" }), - new Address(newUser.publicKey()).toScVal(), - ] - const withdrawResult = await invokeCustomContract( - blendVaultAddress, - 'withdraw', - withdrawParams, - newUser, - false - ); - const withdrawResultValue = scValToNative(withdrawResult.returnValue); - console.log(green, '---------------- XLM withdrawn from the vault ----------------') - console.log(green, 'Withdrawed: ', withdrawResultValue, ' from the vault') - console.log(green, '--------------------------------------------------------------') - - // Invest in strategy - - console.log(purple, '---------------------------------------------------------------------------') - console.log(purple, '-------------------------- Investing in strategy --------------------------') - console.log(purple, '---------------------------------------------------------------------------') - - const investment: any = [{ - "asset": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", - "strategy_investments": [ - { - "amount": 24, - "strategy": "CCWUMJGE6LKWRDJ2IYEJBLCWJSMSUC3QCYZNI2MHTOEYPZRWZN56MIVA" - } - ], - }] - - const investmentParams = investment.map((entry:any) => - xdr.ScVal.scvMap([ - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol("asset"), - val: new Address(entry.asset).toScVal()// Convert asset address to ScVal - }), - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol("strategy_investments"), - val: xdr.ScVal.scvVec( - entry.strategy_investments.map((strategy_investment: any) => { - return xdr.ScVal.scvMap([ - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol("amount"), - val: nativeToScVal(BigInt((strategy_investment.amount ?? 0) * 10 ** 7), { type: "i128" }), // Ensure i128 conversion - }), - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol("strategy"), - val: new Address(strategy_investment.strategy).toScVal() // Convert strategy address - }), - ]) - }) - ), - }), - ]) - ) - const investmentParamsScValVec = xdr.ScVal.scvVec(investmentParams); - - const investResult = await invokeCustomContract( - blendVaultAddress, - 'invest', - [investmentParamsScValVec], - newUser, - false - ); - const investResultValue = scValToNative(investResult.returnValue); - console.log(green, '---------------------- Invested in strategy ----------------------') - console.log(green, 'Invested: ', investResultValue, ' in the strategy') - console.log(green, '------------------------------------------------------------------') - - }catch(e){ - console.log('error', e) - } -} -await createVault(); \ No newline at end of file