From 06f9223ddf62d22579d8ea91709922f313d70a09 Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:11:50 -0300 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8Test=20blend=20vault?= 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 insertions(+) create mode 100644 apps/contracts/src/tests/blend/test.ts diff --git a/apps/contracts/package.json b/apps/contracts/package.json index 4ef8a7bc..7f349d64 100644 --- a/apps/contracts/package.json +++ b/apps/contracts/package.json @@ -11,6 +11,7 @@ "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 new file mode 100644 index 00000000..d9a36d77 --- /dev/null +++ b/apps/contracts/src/tests/blend/test.ts @@ -0,0 +1,232 @@ +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 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 2/4] =?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 3/4] =?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 4/4] =?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