Cluster Deployment & Management using scripts
The euler-vault-scripts repository provides a robust, script-based framework for deploying, configuring, and managing clusters of EVK vaults. It is the recommended tool for advanced users, DAOs, and protocol developers who need automation and support for complex, governed markets.
What is a Cluster?
A cluster is a collection of vaults that accept each other as collateral and share a common governor. Clusters are defined and managed in Solidity scripts, enabling programmable, auditable, and reproducible market deployments.
Key Features
- Automated deployment and delta management
- Support for Safe multisigs, timelocks, and risk stewards
- Batching, emergency operations, and governance contract integration
Defining a Cluster: Example
Below are annotated snippets from a typical cluster script (Cluster.s.sol
).
1. Define Cluster Assets
function defineCluster() internal override {
// List the assets for which vaults will be deployed
cluster.assets = [WETH, USDC, USDT, sUSDS];
}
This sets up the vaults in your cluster. Each asset will have its own vault. Do not define more than one vault per asset.
2. Configure Cluster Parameters
function configureCluster() internal override {
// Set the governor addresses for vaults and oracle routers
cluster.oracleRoutersGovernor = getDeployer();
cluster.vaultsGovernor = getDeployer();
// Set the unit of account (e.g., USD)
cluster.unitOfAccount = USD;
// Set protocol-wide parameters
cluster.feeReceiver = address(0);
cluster.interestFee = 0.1e4; // 1%
cluster.maxLiquidationDiscount = 0.15e4; // 1.5%
cluster.liquidationCoolOffTime = 1; // seconds
// Set hooks, config flags, etc. as needed
cluster.hookTarget = address(0);
cluster.hookedOps = 0;
cluster.configFlags = 0;
}
This block configures governance, risk, and operational parameters for the cluster. You can override parameters per asset if needed.
3. Set Oracle Providers
// Assign oracle adapters or external vaults for each asset
cluster.oracleProviders[WETH ] = "0x10674C8C1aE2072d4a75FE83f1E159425fd84E1D";
cluster.oracleProviders[USDC ] = "0x6213f24332D35519039f2afa7e3BffE105a37d3F";
cluster.oracleProviders[USDT ] = "0x587CABe0521f5065b561A6e68c25f338eD037FF9";
cluster.oracleProviders[sUSDS] = "ExternalVault|0xD0dAb9eDb2b1909802B03090eFBF14743E7Ff967";
Each asset must have a price source. For underlying assets being ERC-4626 vaults, use the ExternalVault|
prefix to resolve via convertToAssets
.
Before configuring oracle providers, check the Euler Oracles Dashboard to see if there are existing oracles that meet your needs. The dashboard provides a comprehensive overview of all available oracles, their configurations, and their current status. Using an existing oracle can save time and reduce deployment complexity.
4. Set Supply and Borrow Caps
cluster.supplyCaps[WETH ] = 10_000;
cluster.supplyCaps[USDC ] = 10_000_000;
cluster.supplyCaps[USDT ] = 10_000_000;
cluster.supplyCaps[sUSDS] = 10_000_000;
cluster.borrowCaps[WETH ] = 9_000;
cluster.borrowCaps[USDC ] = 9_000_000;
cluster.borrowCaps[USDT ] = 9_000_000;
cluster.borrowCaps[sUSDS] = type(uint256).max; // no cap
Caps control the maximum supply and borrowable amounts for each vault.
5. Assign Interest Rate Models (IRMs)
uint256[4] memory irmETH = [uint256(0), uint256(194425692), uint256(41617711740), uint256(3865470566)];
uint256[4] memory irmUSD = [uint256(0), uint256(399976852), uint256(39767751304), uint256(3865470566)];
cluster.kinkIRMParams[WETH ] = irmETH;
cluster.kinkIRMParams[USDC ] = irmUSD;
cluster.kinkIRMParams[USDT ] = irmUSD;
Interest rate models are set per asset. Use the provided scripts/utilities or Creator UI to generate IRM parameters as needed.
6. Configure LTVs and Liquidation Parameters
// Liquidation LTV matrix: columns = liability vaults, rows = collateral vaults
cluster.ltvs = [
// WETH USDC USDT sUSDS
[uint16(0.00e4), 0.85e4, 0.85e4, 0.00e4], // WETH
[uint16(0.87e4), 0.00e4, 0.95e4, 0.00e4], // USDC
[uint16(0.87e4), 0.95e4, 0.00e4, 0.00e4], // USDT
[uint16(0.87e4), 0.95e4, 0.95e4, 0.00e4] // sUSDS
];
7. Configure Spread LTV
// Set the spread LTV for the entire cluster
cluster.spreadLTV = 0.02e4; // 2% spread
The spread LTV represents the difference between the liquidation threshold and the maximum LTV for all assets in the cluster. This creates a buffer zone before liquidation can occur, providing protection against immediate liquidations when positions approach their maximum LTV.
Environment Setup and Running Scripts
Prerequisites
- Install Foundry:
curl -L https://foundry.paradigm.xyz | bash
foundryup
- Clone the repository:
git clone https://github.com/euler-xyz/euler-vault-scripts.git
cd euler-vault-scripts
-
Prepare the
.env
file using.env.example
as a template. Define the RPC URLs for all the chain IDs you need. -
Install dependencies:
./install.sh
- Compile the contracts:
forge clean && forge compile
Running Scripts
Use the ExecuteSolidityScript.sh
script to run the management script:
./script/ExecuteSolidityScript.sh script/clusters/[CLUSTER_FILE] [options]
Replace [CLUSTER_FILE]
with your cluster-specific file name (e.g., Cluster.s.sol
).
Important Options:
--dry-run
: Simulates the script without executing transactions--rpc-url URL|CHAIN_ID
: Required ifDEPLOYMENT_RPC_URL
not defined in.env
--account ACCOUNT
or--ledger
: Required ifDEPLOYER_KEY
not defined in.env
--batch-via-safe
: Creates a batch payload file for Safe multisig execution--safe-address SAFE_ADDRESS
: Authorized Safe multisig address--timelock-address
: Schedules transactions in the timelock controller--risk-steward-address
: Executes transactions via the risk steward contract
Example Commands:
Initial deployment:
./script/ExecuteSolidityScript.sh ./script/clusters/Cluster.s.sol --account DEPLOYER --rpc-url 1
Managing a deployed cluster with governance contracts:
./script/ExecuteSolidityScript.sh ./script/clusters/Cluster.s.sol --batch-via-safe --safe-address DAO --timelock-address wildcard --rpc-url 1
Important Notes
- Always use
--dry-run
first to simulate transactions and check for potential issues - Environment variables in
.env
take precedence over command line arguments - After deployment, commit the generated
.json
files in the scripts directory as they serve as the deployed contracts addresses cache