Buying Shares in an Enzyme Vault

Investing in a vault

The process to buy shares requires two steps; you must first approve the vault to spend the user's ERC-20 denomination asset tokens, then execute the swap of those tokens for Vault shares.

import { ComptrollerLib, StandardToken } from '@enzymefinance/protocol';
import { providers, BigNumber, Wallet, constants, utils } from 'ethers';

// the address of the vault's denomination asset
const denominationAsset = '0x23fs...'; 

// create a local signer connected to your chosen Ethereum node
const provider = providers.StaticJsonRpcProvider(ethNodeAddress, ethNetwork); 
const signer = new Wallet(investorsEthPrivateKey, provider);

// instantiate the denomination asset's Token contract
const tokenContract = new StandardToken(denominationAsset, signer);

// generate an amount of the denomination asset to invest (1 is arbitrary)
const investmentAmount = utils.parseUnits('1', 18);

// construct the approve transaction
const approveTx = tokenContract.approve.args(comptrollerProxy, investmentAmount);

// send it. passing false returns the promise of a receipt that will provide the transaction hash
const approvedTxReceipt = await approveTx.send();
console.log('Pending transaction:', approvedTxReceipt.transactionHash);
console.log('Transaction included in block number:', approvedTxReceipt.blockNumber);

// the vault's comptroller address, available on the app dashboard (app.enzyme.finance/{vaultAddress})
const vaultComptrollerAddress = '0x0sdofso...';

// instantiate the vault's comptroller contract
const comptrollerContract = new ComptrollerLib(vaultComptrollerAddress, signer);

const investTx = comptrollerContract.buyShares.args(
    [signer.address],
    [investmentAmount],
    [constants.Zero],
);    

const investTxReceipt = investTx.send();
console.log('Pending transaction:', investTxReceipt.transactionHash);
console.log('Transaction included in block number:', investTxReceipt.blockNumber);


It's useful to calculate the number of shares you expect to receive from a given transaction; one way of doing that calculation is below. The resulting expectedSharesWithSlippage would be passed instead of constants.Zero on line 34 in the example above.

// call the function to get the expected shares returned based on the investment amount
const [expectedShares] = await comptrollerContract.buyShares.args(
    [signer.address], 
    [investmentAmount],
    [constants.Zero], // note => this parameter is the minimum shares you expect to receive. 
    // since the purpose of this call is to generate that number, we're setting it to zero here.
).call();

// Since the share price of a vault may be updated between when you
// generate the expectedShares value and when you send the buyShares 
// transaction, it's probably a good idea to build some slippage tolerance
// into the amount you actually pass to the function below. 
const expectedSharesWithSlippage = expectedShares.mul(
    utils.parseEth('97')).div(utils.parseEth('100')
);

Last updated