UNPKG

@devasher/kuru-sdk

Version:

Ethers v6 SDK to interact with Kuru (forked from @kuru-labs/kuru-sdk)

263 lines 13.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Vault = void 0; // ============ External Imports ============ const ethers_1 = require("ethers"); const params_1 = require("./params"); // ============ Internal Imports ============ const utils_1 = require("../utils"); const Vault_json_1 = __importDefault(require("../../abi/Vault.json")); const MarginAccount_json_1 = __importDefault(require("../../abi/MarginAccount.json")); const IERC20_json_1 = __importDefault(require("../../abi/IERC20.json")); const txConfig_1 = __importDefault(require("../utils/txConfig")); class Vault { static async deposit(providerOrSigner, ammVaultAddress, amount1, amount2, receiver) { const vaultContract = new ethers_1.ethers.Contract(ammVaultAddress, Vault_json_1.default.abi, providerOrSigner); const tx = await vaultContract.deposit(amount1, amount2, receiver); const receipt = await tx.wait(); if (!receipt) { throw new Error('Transaction failed'); } return receipt; } static async withdraw(providerOrSigner, shares, receiver, owner) { const vaultContract = new ethers_1.ethers.Contract(owner, Vault_json_1.default.abi, providerOrSigner); const tx = await vaultContract.withdraw(shares, receiver, owner); const receipt = await tx.wait(); if (!receipt) { throw new Error('Transaction failed'); } return receipt; } /** * Return the shares owned by an address in a vault * @param vaultAddress The address of vault contract * @param signer The signer to use for the transaction * @returns A promise resolving to the number of shares of an address in a vault */ static async getVaultShares(vaultAddress, userAddress, providerOrSigner) { const vaultContract = new ethers_1.ethers.Contract(vaultAddress, Vault_json_1.default.abi, providerOrSigner); return await vaultContract.balanceOf(userAddress, { from: ethers_1.ZeroAddress, }); } /** * * @param vaultAddress The address of the vault contract * @param marketAddress The address of the market contract * @param marginAccountAddress The address of the margin account contract * @param providerOrSigner The provider or signer to use for the transaction * @returns A promise that resolves to an object containing token1 and token2 address and balance */ static async getVaultLiquidity(vaultAddress, baseAssetAddress, quoteAssetAddress, marginAccountAddress, providerOrSigner) { const marginAccountContract = new ethers_1.ethers.Contract(marginAccountAddress, MarginAccount_json_1.default.abi, providerOrSigner); const token1 = await marginAccountContract.getBalance(vaultAddress, baseAssetAddress, { from: ethers_1.ZeroAddress, }); const token2 = await marginAccountContract.getBalance(vaultAddress, quoteAssetAddress, { from: ethers_1.ZeroAddress, }); return { token1: { address: baseAssetAddress, balance: token1, }, token2: { address: quoteAssetAddress, balance: token2, }, }; } /** * Calculate the amount of tokens needed to deposit for a given number of shares * @param shares The number of shares to mint * @param vaultAddress The address of the vault contract * @param providerOrSigner The provider or signer to use for the transaction * @returns A promise that resolves to an object containing amount1 and amount2 */ static async calculateDepositForShares(shares, vaultAddress, providerOrSigner) { const vaultContract = new ethers_1.ethers.Contract(vaultAddress, Vault_json_1.default.abi, providerOrSigner); const [amount1, amount2] = await vaultContract.previewMint(shares, { from: ethers_1.ZeroAddress, }); return { amount1, amount2 }; } /** * Calculate the amount of tokens to be received for a given number of shares to withdraw * @param shares The number of shares to burn * @param vaultAddress The address of the vault contract * @param providerOrSigner The provider or signer to use for the transaction * @returns A promise that resolves to an object containing amount1 and amount2 */ static async calculateWithdrawForShares(shares, vaultAddress, providerOrSigner) { const vaultContract = new ethers_1.ethers.Contract(vaultAddress, Vault_json_1.default.abi, providerOrSigner); const [amount1, amount2] = await vaultContract.previewRedeem(shares, { from: ethers_1.ZeroAddress, }); return { amount1, amount2 }; } /** * Calculate the number of shares to be received for a given deposit of tokens * @param amount1 The amount of token1 to deposit * @param amount2 The amount of token2 to deposit * @param vaultAddress The address of the vault contract * @param providerOrSigner The provider or signer to use for the transaction * @returns A promise that resolves to the number of shares */ static async calculateSharesForDeposit(amount1, amount2, vaultAddress, providerOrSigner) { const vaultContract = new ethers_1.ethers.Contract(vaultAddress, Vault_json_1.default.abi, providerOrSigner); return await vaultContract.previewDeposit(amount1, amount2, { from: ethers_1.ZeroAddress, }); } /** * Calculate the amount of token2 needed for a specific amount of token1 based on current price * @param amount1 The amount of token1 * @param marketAddress The address of the market contract * @param providerOrSigner The provider or signer to use for the transaction * @returns A promise that resolves to the amount of token2 needed */ static async calculateAmount2ForAmount1(amount1, marketAddress, marketParams, providerOrSigner) { const vaultParams = await params_1.VaultParamFetcher.getVaultParams(providerOrSigner, marketAddress); const price = vaultParams.vaultBestAsk; const token1Decimals = await (0, utils_1.getTokenDecimals)(marketParams.baseAssetAddress, providerOrSigner); const token2Decimals = await (0, utils_1.getTokenDecimals)(marketParams.quoteAssetAddress, providerOrSigner); //amount2 = (amount1 * price * 10^token2Decimals) / (10^token1Decimals * 10^18) return ((amount1 * BigInt(price) * BigInt((0, ethers_1.parseUnits)('1', token2Decimals))) / (BigInt((0, ethers_1.parseUnits)('1', token1Decimals)) * BigInt((0, ethers_1.parseUnits)('1', 18)))); } /** * Calculate the amount of token1 needed for a specific amount of token2 based on current price * @param amount2 The amount of token2 * @param marketAddress The address of the market contract * @param providerOrSigner The provider or signer to use for the transaction * @returns A promise that resolves to the amount of token1 needed */ static async calculateAmount1ForAmount2(amount2, marketAddress, marketParams, providerOrSigner) { const vaultParams = await params_1.VaultParamFetcher.getVaultParams(providerOrSigner, marketAddress); const price = vaultParams.vaultBestAsk; const token1Decimals = await (0, utils_1.getTokenDecimals)(marketParams.baseAssetAddress, providerOrSigner); const token2Decimals = await (0, utils_1.getTokenDecimals)(marketParams.quoteAssetAddress, providerOrSigner); //amount1 = (amount2 * 10^token1Decimals * 10^18) / (price * 10^token2Decimals) return ((amount2 * BigInt((0, ethers_1.parseUnits)('1', token1Decimals)) * BigInt((0, ethers_1.parseUnits)('1', 18))) / (BigInt(price) * BigInt((0, ethers_1.parseUnits)('1', token2Decimals)))); } /** * Deposit tokens into the vault based on the number of shares to mint * @param shares The number of shares to mint * @param marketAddress The address of the market contract * @param vaultAddress The address of the vault contract * @param signer The signer to use for the transaction * @param shouldApprove Whether to approve the tokens before depositing * @returns A promise that resolves to the transaction receipt */ static async depositBasedOnShares(shares, marketParams, vaultAddress, signer, shouldApprove = false) { const vaultContract = new ethers_1.ethers.Contract(vaultAddress, Vault_json_1.default.abi, signer); const { amount1, amount2 } = await this.calculateDepositForShares(shares, vaultAddress, signer); const token1Address = marketParams.baseAssetAddress; const token2Address = marketParams.quoteAssetAddress; let overrides = {}; if (token1Address === ethers_1.ZeroAddress) { overrides = { value: amount1 }; } else if (shouldApprove) { const tokenContract = new ethers_1.ethers.Contract(token1Address, IERC20_json_1.default.abi, signer); await (0, utils_1.approveToken)(tokenContract, vaultAddress, amount1, signer); } if (token2Address === ethers_1.ZeroAddress) { overrides = { value: amount2 }; } else if (shouldApprove) { const tokenContract = new ethers_1.ethers.Contract(token2Address, IERC20_json_1.default.abi, signer); await (0, utils_1.approveToken)(tokenContract, vaultAddress, amount2, signer); } const tx = await vaultContract.mint(shares, await signer.getAddress(), overrides); const receipt = await tx.wait(); if (!receipt) { throw new Error('Transaction failed'); } return receipt; } /** * Withdraw tokens from the vault based on the number of shares to burn * @param shares The number of shares to burn * @param vaultAddress The address of the vault contract * @param signer The signer to use for the transaction * @returns A promise that resolves to the transaction receipt */ static async withdrawBasedOnShares(shares, vaultAddress, signer) { const vaultContract = new ethers_1.ethers.Contract(vaultAddress, Vault_json_1.default.abi, signer); const tx = await vaultContract.redeem(shares, await signer.getAddress(), await signer.getAddress()); const receipt = await tx.wait(); if (!receipt) { throw new Error('Transaction failed'); } return receipt; } /** * Deposit tokens into the vault with given amounts of token1 and token2 * @param amount1 The amount of token1 to deposit * @param amount2 The amount of token2 to deposit * @param marketAddress The address of the market contract * @param vaultAddress The address of the vault contract * @param signer The signer to use for the transaction * @param shouldApprove Whether to approve the tokens before depositing * @returns A promise that resolves to the transaction receipt */ static async depositWithAmounts(amount1, amount2, baseAssetAddress, quoteAssetAddress, vaultAddress, signer, shouldApprove = false) { const vaultContract = new ethers_1.ethers.Contract(vaultAddress, Vault_json_1.default.abi, signer); let overrides = {}; if (baseAssetAddress === ethers_1.ZeroAddress) { overrides.value = amount1; } else if (shouldApprove) { const tokenContract = new ethers_1.ethers.Contract(baseAssetAddress, IERC20_json_1.default.abi, signer); await (0, utils_1.approveToken)(tokenContract, vaultAddress, amount1, signer); } if (quoteAssetAddress === ethers_1.ZeroAddress) { overrides.value = amount2; } else if (shouldApprove) { const tokenContract = new ethers_1.ethers.Contract(quoteAssetAddress, IERC20_json_1.default.abi, signer); await (0, utils_1.approveToken)(tokenContract, vaultAddress, amount2, signer); } const tx = await vaultContract.deposit(amount1, amount2, await signer.getAddress(), overrides); const receipt = await tx.wait(); if (!receipt) { throw new Error('Transaction failed'); } return receipt; } static async constructDepositTransaction(amount1, amount2, baseAssetAddress, quoteAssetAddress, vaultAddress, signer, txOptions) { const address = await signer.getAddress(); const vaultInterface = new ethers_1.ethers.Interface(Vault_json_1.default.abi); const data = vaultInterface.encodeFunctionData('deposit', [amount1, amount2, address]); // Calculate the total value for native token deposits const txValue = baseAssetAddress === ethers_1.ZeroAddress ? amount1 : quoteAssetAddress === ethers_1.ZeroAddress ? amount2 : BigInt(0); return (0, txConfig_1.default)({ to: vaultAddress, from: address, data, value: txValue, txOptions, signer, }); } static async constructWithdrawTransaction(shares, vaultAddress, signer, txOptions) { const vaultInterface = new ethers_1.ethers.Interface(Vault_json_1.default.abi); const fromAddress = await signer.getAddress(); const data = vaultInterface.encodeFunctionData('withdraw', [shares, fromAddress, fromAddress]); return (0, txConfig_1.default)({ to: vaultAddress, from: fromAddress, data, txOptions, signer, }); } } exports.Vault = Vault; //# sourceMappingURL=vault.js.map