Eigen Layer / Symbiotic ERC20 Vault
This section walks you through the creation of a Cross-Protocol ERC20 Vault, referred to as SuperERC20Vault
. These vaults allow deposits to be split automatically between two underlying vaults: one built on EigenLayer and one on Symbiotic.
They are initialized via the initialize()
function with a dedicated SuperVaultParams
struct containing configuration data for both protocols, as well as vault-wide parameters.
function initialize(SuperVaultParams calldata _params) external;
This function deploys and initializes a new SuperERC20Vault, sets up the underlying Symbiotic and EigenLayer vaults, and assigns deposit distribution logic.
Step-by-Step Vault Creation
1. Prepare Parameters (SuperVaultParams)
You must build a SuperVaultParams
struct with the following components:
struct SuperVaultParams {
IByzantineFactory.ByzVaultParams byzVaultParams;
uint256 symRatio;
IByzantineFactory.EigenParams eigenParams;
IByzantineFactory.SymParams symParams;
address curator;
}
byzVaultParams (type: ByzVaultParams
)
ByzVaultParams
)Vault-level configuration shared by both underlying vaults. Includes role setup, deposit constraints, tokenization settings, etc.
symRatio (uint256)
Defines the percentage (from 0 to 10_000) of assets to route to the Symbiotic vault upon deposit.
The remaining percentage (10_000 - symRatio) is allocated to the EigenLayer vault.
Example: symRatio = 6000 means 60% of new deposits go to Symbiotic.
eigenParams (type: EigenParams
)
EigenParams
)Configuration for the EigenLayer vault's delegation logic, including operator delegation and role assignments.
symParams (type: SymParams
)
SymParams
)Configuration for the Symbiotic vault: includes vault logic, delegator details, slasher behavior, and burner setup.
curator (type: adress
)
adress
)Address of the curator.
2. Call the Factory Function
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
Installation
System Requirements
Node.js (v14 or higher)
npm or yarn
TypeScript (optional but recommended)
Installation Steps
Install the SDK
npm install @byzantine/vault-sdk
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
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
SuperERC20ByzVault Creation
Create a Super Vault that integrates with the Symbiotic and Eigenlayer ecosystems:
With your SuperVaultParams
ready, call:
function createSuperERC20Vault(
ISuperERC20Vault.SuperVaultParams calldata _params
) external returns (address superVault);
// // -
// All import and initialize client as shown on the setup
// -
// Define vault parameters
const baseParams = {
metadata: {
name: "SuperVault osETH",
description: "A SuperVault for osETH with high yields",
},
token_address: networkConfig.osETHAddress, // osETH address
is_deposit_limit: true,
deposit_limit: ethers.parseUnits("1000000", 18), // 1M osETH (18 decimals)
is_private: false, // Private SuperVault
is_tokenized: true,
token_name: "Byzantine osETH SuperVault",
token_symbol: "bsosETHs",
curator_fee: 600, // 6% (600 basis points)
// Roles - replace with actual addresses in production
role_manager: address,
role_version_manager: address,
role_deposit_limit_manager: address,
role_deposit_whitelist_manager: address,
role_curator_fee_claimer: address,
role_curator_fee_claimer_admin: address,
};
const symbioticParams = {
vault_version: 1,
vault_epoch_duration: 604800, // 7 days in seconds
slasher_type: SlasherType.VETO,
slasher_veto_duration: 86400, // 1 day in seconds
slasher_number_epoch_to_set_delay: 3,
burner_delay_settings_applied: 21, // 21 days
burner_global_receiver: "0x25133c2c49A343F8312bb6e896C1ea0Ad8CD0EBd", // Global receiver for wstETH
burner_network_receiver: [],
burner_operator_network_receiver: [],
delegator_type: DelegatorType.NETWORK_RESTAKE,
delegator_hook: "0x0000000000000000000000000000000000000001", // Delegator hook address
delegator_operator: "0x0000000000000000000000000000000000000000", // Not used for NETWORK_RESTAKE
delegator_network: "0x0000000000000000000000000000000000000000", // Not used for NETWORK_RESTAKE
role_delegator_set_hook: address,
role_delegator_set_network_limit: [address],
role_delegator_set_operator_network_limit: [address],
role_burner_owner_burner: address,
};
const eigenlayerParams = {
// Eigenlayer specific params
delegation_set_role_holder: address,
operator: "0xb564e795f9877b416cd1af86c98cf8d3d94d760d", // Blockshard
approver_signature_and_expiry: {
signature: "0x", // null signature
expiry: 0, // no expiry
},
approver_salt:
"0x0000000000000000000000000000000000000000000000000000000000000000", // null salt
};
const ratio = 5000; // 50%
const curator = address;
// Create the vault
const tx = await client.createSuperVaultERC20({
base: baseParams,
symbiotic: symbioticParams,
eigenlayer: eigenlayerParams,
ratio: ratio,
curator: curator,
});
// Wait for confirmation
const receipt = await tx.wait();
const vaultAddress = receipt.logs[0].address;
console.log(`Vault created at address: ${vaultAddress}`);
This deploys and initializes the super vault and the underlying Symbiotic and Eigenlayer vaults.
✅ You receive the new vault address. You can now whitelist stakers, set delegation limits, or start deposits.
Summary
To create a SuperERC20Vault, all you need is:
The correct factory and beacon addresses
A fully populated
SuperVaultParams
structCall the ByzantineFactory
Once created, the vault handles deposit splitting, rebalancing, and cross-protocol coordination automatically.
For help with individual parameter structures, refer to:
Last updated