Eigen ERC20 Vault

This flow is for users who want to launch an EigenByzVault that accepts an ERC20 token as collateral. Make sure the ERC20 token is supported by EigenLayer and whitelisted in the strategy registry.

1. Choose a whitelisted ERC20 token

Select the ERC20 token to be used as the vault’s collateral. Ensure that it is whitelisted in the strategy factory and accepted by EigenLayer.

2. Construct the ByzVaultParams struct

You will need to populate the following fields:

  • token : The address of the ERC20 token. Must be accepted by EigenLayer. Use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for canonical ETH.

  • roleManager : The main admin who can grant/revoke all roles in the vault (except curatorFeeClaimer).

  • versionManager : The address that can upgrade the vault implementation and update the vault metadata URI.

  • depositWhitelistManager : Manages who is allowed to deposit if isPrivateVault = true. Can be set to address(0) if you want permissionless deposits.

  • depositLimitManager : Sets and toggles the depositLimit. Required if isDepositLimit = true.

  • curatorFeeClaimer : Can claim rewards earned by the vault curator. This role is managed only by the curatorFeeClaimerRoleAdmin.

  • curatorFeeClaimerRoleAdmin : Can assign or revoke the curatorFeeClaimer role.

  • curatorFee : Value between 0 and 10,000, representing 0% to 100%. For example, 1,000 = 10% curator fee.

  • depositLimit : Maximum assets that can be deposited. Required if isDepositLimit = true. Set to 0 to block new deposits.

  • isDepositLimit : Boolean to enable/disable the deposit limit mechanism.

  • isPrivateVault : If true, only whitelisted users can deposit. If false, anyone can deposit.

  • isTokenized : Set true if vault shares should be tradable (ERC20); otherwise, they remain non-transferable.

  • name and symbol : Required if isTokenized = true. Name and symbol of the ERC20 shares.

  • metadataURI : Optional metadata string (off-chain URI). Only emitted in an event. Settable only by the versionManager.

Once complete, this struct can be passed as the first argument to the createEigenByzVault function.

Refer to the full ByzVaultParams specification for a detailed description of each parameter.

3. Configure EigenParams struct

  • Choose a delegationSetRoleHolder address who will manage delegation rights.

  • Provide an initial operator if known, or set to address(0) to defer.

  • If required, include a SignatureWithExpiry and a unique approverSalt.

Refer to the full EigenLayer Parameters specification for a detailed description of each parameter.

4. Call the Factory

Prerequisites

  • An Ethereum account (EOA) or smart contract that will act as the vault creator

  • The token you want to use for the vault (must be supported by EigenLayer for EigenLayer vaults)

  • Access to the Byzantine Factory contract address

Contract Addresses

Contract
Testnet Address
Mainnet Address

Installation

System Requirements

  • Node.js (v14 or higher)

  • npm or yarn

  • TypeScript (optional but recommended)

Installation Steps

  1. Install the SDK

npm install @byzantine/vault-sdk
  1. Create Environment File Create a .env file in your project root:

RPC_URL=https://holesky.infura.io/v3/your_api_key_here

# Choose ONE of the following authentication methods:
MNEMONIC=your_wallet_mnemonic
# OR
PRIVATE_KEY=your_wallet_private_key_without_0x_prefix

DEFAULT_CHAIN_ID=17000  # 17000 for Holesky testnet, 1 for Ethereum Mainnet, 560048 for Hoodi Testnet
  1. Basic Setup

import {
  ByzantineClient,
  ETH_TOKEN_ADDRESS,
  BaseParams,
} from "@byzantine/vault-sdk";
import { ethers } from "ethers";
import * as dotenv from "dotenv";

dotenv.config();

const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = ethers.Wallet.fromPhrase(process.env.MNEMONIC).connect(provider);
// OR const wallet = new ethers.Wallet(process.env.PRIVATE_KEY).connect(provider);

const client = new ByzantineClient({
  chainId: 17000, // 17000 for Holesky, 1 for Mainnet, 560048 for Hoodi
  provider: provider,
  signer: wallet,
});

Supported Networks

  • Holesky Testnet (Chain ID: 17000)

  • Ethereum Mainnet (Chain ID: 1) - Coming Soon

  • Hoodi Testnet (Chain ID: 560048) - Coming Soon

EigenERC20ByzVault Creation

Create a vault for an ERC20 token that integrates with EigenLayer:

function createEigenByzVault(
    ByzVaultParams calldata _byzVaultParams,
    EigenParams calldata _eigenParams
) external returns (address eigenByzVault);
import { ByzantineClient, getNetworkConfig } from "@byzantine/vault-sdk";
import { ethers } from "ethers";

// Initialize with ethers provider and signer
const provider = new ethers.JsonRpcProvider(
  "https://holesky.infura.io/v3/YOUR_API_KEY"
);
const wallet = ethers.Wallet.fromPhrase("your mnemonic").connect(provider);
// OR const wallet = new ethers.Wallet(process.env.PRIVATE_KEY).connect(provider);

const client = new ByzantineClient({
  chainId: 17000, // Holesky testnet
  provider: provider,
  signer: wallet,
});

// Get the network configuration for token addresses
const networkConfig = getNetworkConfig(17000);

// Define vault parameters
const baseParams: BaseParams = {
  metadata: {
    name: "Eigenlayer stETH Vault",
    description: "An Eigenlayer vault for stETH restaking",
    image_url: "https://example.com/updated-vault-image.png",
    social_twitter: "https://x.com/byzantine_fi",
    social_discord: "https://discord.gg/byzantine",
    social_telegram: "https://t.me/byzantine",
    social_website: "https://byzantine.fi",
    social_github: "https://github.com/byzantine-finance",
  },
  token_address: networkConfig.stETHAddress,
  is_deposit_limit: true,
  deposit_limit: ethers.parseUnits("1000", 18),
  is_private: false,
  is_tokenized: true,
  token_name: "Byzantine stETH Vault",
  token_symbol: "bstETH",
  curator_fee: 500, // 5% (500 basis points)
  role_manager: wallet.address,
  role_version_manager: wallet.address,
  role_deposit_limit_manager: wallet.address,
  role_deposit_whitelist_manager: wallet.address,
  role_curator_fee_claimer: wallet.address,
  role_curator_fee_claimer_admin: wallet.address,
};

const eigenlayerParams: EigenlayerParams = {
  operator_id: "0xb564e795f9877b416cd1af86c98cf8d3d94d760d", // Replace with actual operator ID
  role_validator_manager: wallet.address,
};

// Create the vault
const tx = await client.createEigenlayerERC20Vault({
  base: baseParams,
  eigenlayer: eigenlayerParams,
});

// Wait for confirmation
const receipt = await tx.wait();
console.log(`Vault created in block ${receipt.blockNumber}`);

// Determine the vault address from the logs
const vaultAddress = receipt.logs[0].address;
console.log(`Vault created at address: ${vaultAddress}`);

✅ Once deployed, the function returns the vault’s address. You can begin interacting with the vault (e.g. deposits, restaking delegation, or admin actions) right away.


Last updated