Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript tests for Rebalance #193

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"publish-addresses": "tsc && node dist/publish_addresses.js",
"test": "tsc && node dist/test.js",
"test-vault": "tsc && node dist/tests/testOnlyVault.js",
"test-dev": "tsc && node dist/tests/dev.js"
"test-dev": "tsc && node dist/tests/dev.js",
"test-rebalance": "tsc && node dist/tests/rebalanceTest.js"
},
"type": "module",
"devDependencies": {
Expand Down
233 changes: 233 additions & 0 deletions apps/contracts/src/tests/rebalanceTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import { depositToVault } from "./vault.js";
import { AddressBook } from "../utils/address_book.js";
import { airdropAccount, invokeContract, invokeCustomContract } from "../utils/contract.js";
import { config } from "../utils/env_config.js";
import { checkUserBalance } from "./strategy.js";

import {
Address,
Asset,
nativeToScVal,
Networks,
scValToNative,
xdr,
Keypair
} from "@stellar/stellar-sdk";
import { randomBytes } from "crypto";

export async function deploy_vault(addressBook: AddressBook) {
if (network !== "mainnet") await airdropAccount(loadedConfig.admin);
console.log("Admin publicKey:", loadedConfig.admin.publicKey());

console.log("-------------------------------------------------------");
console.log("Deploying DeFindex Vault");
console.log("-------------------------------------------------------");

// Setup roles
const emergencyManager = loadedConfig.getUser("DEFINDEX_EMERGENCY_MANAGER_SECRET_KEY");
const feeReceiver = loadedConfig.getUser("DEFINDEX_FEE_RECEIVER_SECRET_KEY");
const manager = loadedConfig.getUser("DEFINDEX_MANAGER_SECRET_KEY");

// Airdrop to role accounts if not on mainnet
if (network !== "mainnet") {
await Promise.all([
airdropAccount(emergencyManager),
airdropAccount(feeReceiver),
airdropAccount(manager)
]);
}

const assets = [
{
address: new Address(xlm.contractId(passphrase)),
strategies: [
{
name: "Strategy 1",
address: addressBook.getContractId("hodl_strategy"),
paused: false
}
]
}
];

const assetAllocations = assets.map((asset) => {
return xdr.ScVal.scvMap([
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("address"),
val: asset.address.toScVal(),
}),
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("strategies"),
val: xdr.ScVal.scvVec(
asset.strategies.map((strategy) =>
xdr.ScVal.scvMap([
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("address"),
val: new Address(strategy.address).toScVal(),
}),
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("name"),
val: nativeToScVal(strategy.name, { type: "string" }),
}),
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("paused"),
val: nativeToScVal(strategy.paused, { type: "bool" }),
}),
])
)
),
}),
]);
});

const createDeFindexParams: xdr.ScVal[] = [
new Address(emergencyManager.publicKey()).toScVal(),
new Address(feeReceiver.publicKey()).toScVal(),
nativeToScVal(100, { type: "u32" }), // Setting vault_fee as 100 bps
nativeToScVal("Test Vault", { type: "string" }),
nativeToScVal("DFT-Test-Vault", { type: "string" }),
new Address(manager.publicKey()).toScVal(),
xdr.ScVal.scvVec(assetAllocations),
nativeToScVal(randomBytes(32)),
];

const result = await invokeContract(
'defindex_factory',
addressBook,
'create_defindex_vault',
createDeFindexParams,
loadedConfig.admin
);

const deployedVault = scValToNative(result.returnValue);
console.log('🚀 DeFindex Vault created with address:', deployedVault);
return { deployedVault, manager };
}

const network = process.argv[2];
const addressBook = AddressBook.loadFromFile(network);
const xlm: Asset = Asset.native();
const passphrase = network === "mainnet" ? Networks.PUBLIC : network === "testnet" ? Networks.TESTNET : Networks.STANDALONE;
const loadedConfig = config(network);

async function investInStrategy(
deployedVault: string,
strategyAddress: string,
investmentAmount: number | bigint,
manager: Keypair
) {
console.log('🚀 « manager:', manager);
console.log("\nStep 4: Manager investing in strategy...");

// Prepare asset address
const xlmAddress = new Address(xlm.contractId(passphrase));
console.log("XLM address:", xlmAddress);

// Create parameter structure
const someParam = [
{
asset: xlmAddress,
strategy_investments: [
{
amount: BigInt(investmentAmount),
strategy: new Address(strategyAddress),
}
]
}
];

// Map parameter structure to ScVal
const mappedParam = xdr.ScVal.scvVec(
someParam.map((entry) =>
xdr.ScVal.scvMap([
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("asset"),
val: 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((investment) =>
xdr.ScVal.scvMap([
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("amount"),
val: nativeToScVal(BigInt(investment.amount), { type: "i128" }), // Ensure i128 conversion
}),
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol("strategy"),
val: investment.strategy.toScVal(), // Convert strategy address
}),
])
)
),
}),
])
)
);

try {
// Invoke contract with the mapped parameters
const investResult = await invokeCustomContract(
deployedVault,
"invest",
[mappedParam], // Pass the ScVal array as an argument
manager
);
console.log("Investment successful:", scValToNative(investResult.returnValue));
return investResult;
} catch (error) {
console.error("Investment failed:", error);
throw error;
}
}

async function main() {
// // Step 1: Deploy the vault and get the manager
// console.log("Step 1: Deploying vault...");
// const { deployedVault, manager } = await deploy_vault(addressBook);
// console.log("Vault deployed at:", deployedVault);
// console.log("Manager address:", manager.publicKey());

// // Step 2: Create and fund a new user for deposit
// console.log("\nStep 2: Creating new user for deposit...");
// const depositUser = Keypair.random();
// console.log("Generated deposit user public key:", depositUser.publicKey());
// console.log("Generated deposit user secret key:", depositUser.secret());
// if (network !== "mainnet") await airdropAccount(depositUser);
// console.log("Deposit user created with address:", depositUser.publicKey());

// // Step 3: User deposits into vault
// console.log("\nStep 3: Making deposit...");
// const depositAmount = 1000000000; // 100 XLM
// const { balanceBefore: depositBalanceBefore, balanceAfter: depositBalanceAfter }
// = await depositToVault(deployedVault, depositAmount, depositUser);
// console.log("Deposit completed - Balance before:", depositBalanceBefore, "Balance after:", depositBalanceAfter);

// // Step 4: Manager investing in strategy
// const deployedVault = "CCRUI2UGJCGHAGYISQGD22YBHADRCUWAE7GQ6CWMJNYXXZPMQ5J643QF"; // Replace with your vault address
// const manager = loadedConfig.getUser("DEFINDEX_MANAGER_SECRET_KEY");
// const depositUser = Keypair.fromSecret("SBPAP2WHWOOAUB6DARBU2UQ6BUK77LSSMLHSJY4JDBJF26LSRGTL7Y6R");

// Step 4: Manager investing in strategy
const deployedVault = "CC4USANGI47STLELFD4GNDHBIDMOHEGSE3RLRQ723JMYTRHEDUQH2U5A"; // Replace with your vault address
const manager = loadedConfig.getUser("DEFINDEX_MANAGER_SECRET_KEY");
const depositUser = Keypair.fromSecret("SBQUFFGELWDAUJDBNCW3E3LA575MVG3WYWCYBFBYT73PXFGUAMVA3UHG");

const strategyAddress = addressBook.getContractId("hodl_strategy");
const investmentAmount = 100000000; // 100 XLM

await investInStrategy(
deployedVault,
strategyAddress,
investmentAmount,
manager,
// depositUser
);

// // Step 5: Check strategy balance
// const strategyBalance = await checkUserBalance(strategyAddress, depositUser.publicKey(), depositUser);
// console.log("Strategy balance after investment:", strategyBalance);
}

// Run the test
main().catch(console.error);
6 changes: 2 additions & 4 deletions apps/contracts/src/utils/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ export async function bumpContractInstance(
txBuilder.addOperation(Operation.extendFootprintTtl({ extendTo: 535670 })); // 1 year
txBuilder.setSorobanData(bumpTransactionData);
const result = await invokeTransaction(txBuilder.build(), source, false);
//@ts-ignore
console.log(result.status, "\n");
console.log('status' in result ? result.status : "No status", "\n");
}

export async function bumpContractCode(
Expand Down Expand Up @@ -230,8 +229,7 @@ export async function bumpContractCode(
txBuilder.addOperation(Operation.extendFootprintTtl({ extendTo: 535670 })); // 1 year
txBuilder.setSorobanData(bumpTransactionData);
const result = await invokeTransaction(txBuilder.build(), source, false);
//@ts-ignore
console.log(result.status, "\n");
console.log('status' in result ? result.status : "No status", "\n");
}

export async function airdropAccount(user: Keypair) {
Expand Down
Loading
Loading