diff --git a/docs/pages/overview.mdx b/docs/pages/overview.mdx index 6889a310..1b03ad4f 100644 --- a/docs/pages/overview.mdx +++ b/docs/pages/overview.mdx @@ -2,6 +2,12 @@ The Enzyme API and the Enzyme SDK allow you to interact with the Enzyme protocol. +These documentation pages cover the technical details on how to use the Enzyme API and the Enzyme SDK. + +Related documentation: +- [User Documentation](https://docs.enzyme.finance) +- [Protocol Specs](https://specs.enzyme.finance) + ## Enzyme API The Enzyme API provides endpoints to _read_ data related to Enzyme vaults, e.g. diff --git a/docs/pages/sdk/depositor/deposit.mdx b/docs/pages/sdk/depositor/deposit.mdx index 8366fac0..9fe3080a 100644 --- a/docs/pages/sdk/depositor/deposit.mdx +++ b/docs/pages/sdk/depositor/deposit.mdx @@ -8,10 +8,7 @@ Depositing into an Enzyme vault is a two step process: ```ts import { Asset } from "@enzymefinance/sdk"; -import { encodeFunctionData, parseUnits } from "viem"; - -const denominationAsset = "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270"; -const comptrollerProxy = "0x4a8207bffcd7e92aa32df2efb9505e9b403b93ea"; +import { parseUnits } from "viem"; const approve = Asset.approve({ asset: denominationAsset, @@ -19,10 +16,7 @@ const approve = Asset.approve({ spender: comptrollerProxy }); -await walletClient.sendTransaction({ - to: approve.params.address, - data: encodeFunctionData(approve.params) -}) +await walletClient.sendTransaction(approve.params); ``` ## 2. Deposit @@ -31,31 +25,36 @@ Depositing the approved amount into the vault. ```ts import { Depositor } from "@enzymefinance/sdk"; - -const denominationAsset = "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270"; -const comptrollerProxy = "0x4a8207bffcd7e92aa32df2efb9505e9b403b93ea"; -const depositor = "0xb5680c97357e455dcdc11646bd8c8876e2cc2bb7"; +import { parseUnits } from "viem"; const deposit = Depositor.deposit({ comptrollerProxy, amount: parseUnits("1", 18), depositor, - minSharesQuantity: 1n; + minSharesvQuantity: 1n, }) + +await walletClient.sendTransaction(deposit.params); + ``` -For simplicity, we have set `minSharesQuantity` to 1 wei shares. For security reasons, we should set it to a more realistic amount. +### Expected Number of Shares + +For simplicity, we have set `minSharesQuantity` to 1 wei shares above. In real life, you should set it to a more realistic amount. The expected number of shares for a given deposit can be obtained with the `getExpectedSharesForDeposit` function, and then allowing for some slippage (e.g. 1%). ```ts import { Depositor } from "@enzymefinance/sdk"; -const expectedNumberOfShares = Depositor.getExpectedSharesForDeposit({ - comptrollerProxy, - amount: parseUnits("1", 18), - depositor, -}); +const expectedNumberOfShares = Depositor.getExpectedSharesForDeposit( + publicClient, + { + comptrollerProxy, + amount: parseUnits("1", 18), + depositor, + } +); const minSharesQuantity = expectedNumberOfShares * 99 / 100; ``` diff --git a/docs/pages/sdk/depositor/redeem.mdx b/docs/pages/sdk/depositor/redeem.mdx new file mode 100644 index 00000000..c9b2180b --- /dev/null +++ b/docs/pages/sdk/depositor/redeem.mdx @@ -0,0 +1,60 @@ +# Reedem Shares + +There are two kind of redemptions: +- Specific Assets Redemptions: the depositor receives the value of their shares in one or several assets +- In-kind redemptions: the depositor receives a slice of all assets in the vault + +## Specific Assets Redemption + +```ts +import { Depositor } from "@enzymefinance/sdk"; + +const redemption = Depositor.redeemSharesForSpecificAssets({ + comptrollerProxy, + recipient, + sharesQuantity, + payoutAssets, + payoutPercentages, +}); + +await walletClient.sendTransaction(redemption.params); +``` + +| Parameter | Description | +| ----------- | ----------- | +| `comptrollerProxy` | Address of comptrollerProxy | +| `recipient` | Address of the recipient of the redemption. Typically, this is the depositor. | +| `sharesQuantity` | Number of shares (18 decimals) | +| `payoutAssets` | List of asset addresses | +| `payoutPercentages` | List of payout percentages (in bps) | + + +## In-Kind Redemption + + +```ts +import { Depositor } from "@enzymefinance/sdk"; + +const redemption = Depositor.redeemSharesInKind({ + comptrollerProxy, + recipient, + sharesQuantity, + additionalAssets, + assetsToSkip, +}); + +await walletClient.sendTransaction(redemption.params); +``` + +| Parameter | Description | +| ----------- | ----------- | +| `comptrollerProxy` | Address of comptrollerProxy | +| `recipient` | Address of the recipient of the redemption. Typically, this is the depositor. | +| `sharesQuantity` | Number of shares (18 decimals) | +| `additionalAssets` | List of additional asset addresses (i.e. assets that the vault owns, but that are not tracked by the vault)| +| `assetsToSkip` | List of assets to skip (e.g. because they cannot be transferred) | + +:::warning +In-kind redemptions should only be used for vaults without external positions. External positions cannot be split up, +and depositors will therefore not receive their pro-rate share of an external position. +::: diff --git a/docs/pages/sdk/depositor/withdraw.mdx b/docs/pages/sdk/depositor/withdraw.mdx deleted file mode 100644 index 10d48145..00000000 --- a/docs/pages/sdk/depositor/withdraw.mdx +++ /dev/null @@ -1 +0,0 @@ -# Withdraw from an Enzyme Vault diff --git a/docs/pages/sdk/overview.mdx b/docs/pages/sdk/overview.mdx index b039d990..879d4af3 100644 --- a/docs/pages/sdk/overview.mdx +++ b/docs/pages/sdk/overview.mdx @@ -35,7 +35,6 @@ const publicClient = createPublicClient({ // [!code focus] Create a wallet client (see also [Wallet Client](https://viem.sh/docs/clients/wallet)) to be able to send transactions. ```ts -// @noErrors import { createWalletClient, http } from "viem"; import { polygon } from "viem/chains"; @@ -53,50 +52,27 @@ const walletClient = createWalletClient({ // [!code focus] Use the public client to make on-chain calls. ```ts -import { createPublicClient, http } from "viem"; -import { polygon } from "viem/chains"; -import { Vault } from "@enzymefinance/sdk"; +import { Vault } from "@enzymefinance/sdk"; -const client = createPublicClient({ - chain: polygon, - transport: http(), -}); - -const name = await Vault.getName(client, { // [!code focus] - vaultProxy: "0xbdf7a07fdbd44aa00eeeb55e655c43fccb932ab2", // [!code focus] +const name = await Vault.getName(publicClient, { // [!code focus] + vaultProxy, // [!code focus] }); // [!code focus] ``` -Use the wallet client to send a transaction. +Use the wallet client to send a transaction. The Enzyme SDK provides properly typed functions for +all transaction within the Enzyme protocol. ```ts -// @noErrors -import { createWalletClient, http, Hex, encodeFunctionData } from "viem"; -import { privateKeyToAccount } from "viem/accounts"; -import { polygon } from "viem/chains"; -import { Portfolio } from "@enzymefinance/sdk"; // [!code focus] - -const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex); - -const comptrollerProxy = "0x4a8207bffcd7e92aa32df2efb9505e9b403b93ea"; -const integrationManager = "0x92fcde09790671cf085864182b9670c77da0884b"; - -const walletClient = createWalletClient({ - account, - chain: polygon, - transport: http(), -}); +import { Portfolio } from "@enzymefinance/sdk"; const transaction = Portfolio.removeTracketAssets({ // [!code focus] removeAssets: ["0x1a13f4ca1d028320a707d99520abfefca3998b7f"], // [!code focus] comptrollerProxy, // [!code focus] integrationManager, // [!code focus] -}); +}); // [!code focus] -const transactionResult = await walletClient.sendTransaction({ // [!code focus] - to: transaction.params.address,// [!code focus] - data: encodeFunctionData(transaction.params),// [!code focus] -});// [!code focus] +const transactionResult = // [!code focus] + await walletClient.sendTransaction(transaction.params); // [!code focus] console.log("transaction hash: ", transactionResult); ``` diff --git a/docs/pages/sdk/vault-lifecycle/create-new.mdx b/docs/pages/sdk/vault-lifecycle/create-new.mdx new file mode 100644 index 00000000..ea053cd2 --- /dev/null +++ b/docs/pages/sdk/vault-lifecycle/create-new.mdx @@ -0,0 +1,94 @@ +# Create a New Vault + +When you create a new vault, you need to set the configuration of the vault. Most parameters are straight-forward. + +For more details on the various configuration options, see [Setup and Configure Your Vault](https://docs.enzyme.finance/managers/setup) + +```ts +import { LifeCycle } from "@enzymefinance/sdk"; + +const create = LifeCycle.createVault({ + fundDeployer, + owner, + name, + symbol, + denominationAsset, + sharesActionTimelockInSeconds, + feeManagerConfigData, + policyManagerConfigData, +}); + +await walletClient.sendTransaction(create.params); + +``` + +| Parameter | Description | +| ----------- | ----------- | +| `fundDeployer` | Address of the current FundDeployer contract (see [Contract Addresses](/sdk/contract-addresses.mdx)) | +| `owner` | Address of the vault owner. This usually is the same address as the sender of the transaction, however, it can also be different. | +| `name` | The name of the vault | +| `symbol` | The symbol of the vault | +| `denominationAsset` | Address of the denomination asset | +| `sharesActionTimelockInSeconds` | Timelock for redemptions (in seconds) | +| `feeManagerConfigData` | Fee configuration of the vault (see below) | +| `policyManagerConfigData` | Policy configuration of the vault (see below) | + + +## Policy configuration + +A vault can use policies if desired. Policies typically have configuration parameters. +For the addresses of the individual policies, see [Contract Addresses](/sdk/contract-addresses.mdx). + +```ts +import { Policy, Policies } from "@enzymefinance/sdk"; + +const policy1Config = Policies.MinMaxInvestment.encodeSettings({ + minInvestmentAmount, + maxInvestmentAmount +}); + +const policy2Config = + Policies.CumulativeSlippageTolerance.encodeSettings({ + slippageTolerance + } +); + +const feeManagerConfigData = Policy.encodeSettings([ + { + address: minMaxInvestmentPolicyAddress, + settings: policy1Config + }, + { + address: cumulativeSlippageTolerancePolicyAddress, + settings: policy2Config + }, +]); +``` + +## Fee configuration + +A vault can use fees if desired. Fees typically have configuration parameters. +For the addresses of the individual fees, see [Contract Addresses](/sdk/contract-addresses.mdx). + +```ts +import { Fee, Fees } from "@enzymefinance/sdk"; + +const fee1Config = Fees.Management.encodeSettings({ + perAnnumRate, +}); + +const fee2Config = Fees.Performance.encodeSettings({ + rateInBps +}); + +const feeManagerConfigData = Fee.encodeSettings([ + { + address: managementFeeAddress, + settings: fee1Config + }, + { + address: performanceFeeAddress, + settings: fee2Config + }, +]); +``` diff --git a/docs/pages/sdk/vault-lifecycle/reconfigure.mdx b/docs/pages/sdk/vault-lifecycle/reconfigure.mdx new file mode 100644 index 00000000..905ba090 --- /dev/null +++ b/docs/pages/sdk/vault-lifecycle/reconfigure.mdx @@ -0,0 +1,61 @@ +# Reconfigure a Vault + +A vault can be reconfigured within a given release. During a reconfiguration, fees and/or policies can be added and/or removed. + +Vault reconfiguration is a two-step process: +1. Create a reconfiguration request +2. Execute the reconfiguration (after a waiting period of 7 days) + +## 1. Create a Reconfiguration request + + +```ts +import { LifeCycle } from "@enzymefinance/sdk"; + +const reconfiguration = LifeCycle.createReconfigurationRequest({ + vaultProxy, + denominationAsset, + sharesActionTimelockInSeconds, + feeManagerConfigData, + policyManagerConfigData, +}); + +await walletClient.sendTransaction(reconfiguration.params); +``` + +| Parameter | Description | +| ----------- | ----------- | +| `vaultProxy` | Address of the vaultProxy | + +The remaining reconfiguration request parameters are identical to the [parameters used to create a new vault](/sdk/vault-lifecycle/create-new). + + +## 2. Execute the Reconfiguration + +A reconfiguration request can be executed after a waiting period of 7 days. + +```ts +import { LifeCycle } from "@enzymefinance/sdk"; + +const execute = LifeCyle.executeReconfiguration({ + fundDeployer, + vaultProxy +}); + +await walletClient.sendTransaction(execute.params); +``` + +## Cancel Reconfiguration + +In case needed, a reconfiguration can also be cancelled. + +```ts +import { LifeCycle } from "@enzymefinance/sdk"; + +const cancel = LifeCyle.cancelReconfiguration({ + fundDeployer, + vaultProxy +}); + +await walletClient.sendTransaction(cancel.params); +``` diff --git a/docs/vocs.config.ts b/docs/vocs.config.ts index 6be389bc..1971bfa3 100644 --- a/docs/vocs.config.ts +++ b/docs/vocs.config.ts @@ -51,6 +51,19 @@ export default defineConfig({ text: "Contract Addresses", link: "/sdk/contract-addresses", }, + { + text: "Vault Lifecycle", + items: [ + { + text: "Create", + link: "/sdk/vault-lifecycle/create-new", + }, + { + text: "Reconfigure", + link: "/sdk/vault-lifecycle/reconfigure", + }, + ], + }, { text: "Depositor Actions", items: [ @@ -59,8 +72,8 @@ export default defineConfig({ link: "/sdk/depositor/deposit", }, { - text: "Withdraw", - link: "/sdk/depositor/withdraw", + text: "Redeem", + link: "/sdk/depositor/redeem", }, ], },