deploying a vault.md
For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to page URLs; this page is available as Markdown.
Deploying a Vault
A vault is created in a single transaction against the Vault Deployer for the asset you want to hold. The deployer pulls your initial deposit and mints shares to your wallet in the same call.
Pick the right deployer
One deployer per asset:
| Asset | Deployer |
|---|---|
| USDC | 0xe4D85722dB649d3890f9DBA4510F1A16AD942FD9 |
| WBTC | 0x55073cdF0b0E42C8B807A265EADff69973274a8d |
| WETH | 0x6701241e65d4baFC399Ca4358E95960aF3C041C4 |
Read the current minimum initial deposit
Before deploying, read the minimum initial deposit from the deployer — it's configured per asset and can change, so read it on-chain rather than hard-coding.
const deployerAbi = [
{type: 'function', stateMutability: 'view', name: 'minInitialDeposit',
inputs: [], outputs: [{type: 'uint256'}]},
] as const
const minDeposit = await client.readContract({
address: deployer, abi: deployerAbi, functionName: 'minInitialDeposit',
})
Approve the initial deposit
The deployer needs to be able to pull initialDeposit of the underlying asset from your wallet:
const assetAbi = [{
type: 'function', stateMutability: 'nonpayable', name: 'approve',
inputs: [{type: 'address'}, {type: 'uint256'}],
outputs: [{type: 'bool'}],
}] as const
await walletClient.writeContract({
address: underlyingToken,
abi: assetAbi, functionName: 'approve',
args: [deployer, initialDeposit],
})
If the underlying token supports EIP‑2612 permit (USDC does), you can skip the separate approval transaction by using deployVaultWithPermit instead — see below.
Call deployVault
const deployAbi = [{
type: 'function', stateMutability: 'nonpayable', name: 'deployVault',
inputs: [
{name: 'initialDeposit', type: 'uint256'},
{name: 'maxManagementFee', type: 'uint256'},
{name: 'maxPerformanceFee', type: 'uint256'},
],
outputs: [/* FusionInstance struct — read from the event instead */],
}] as const
// Fees are in basis points (100 bps = 1%). Default DCV terms are
// 0.25% management (25 bps) and 30% performance (3000 bps) — pass those
// as the slippage caps, unless you've agreed different terms with Tesseract.
const MAX_MGMT_FEE = 25n // 0.25%
const MAX_PERF_FEE = 3000n // 30%
const hash = await walletClient.writeContract({
address: deployer,
abi: deployAbi,
functionName: 'deployVault',
args: [initialDeposit, MAX_MGMT_FEE, MAX_PERF_FEE],
})
const receipt = await client.waitForTransactionReceipt({hash})
maxManagementFee and maxPerformanceFee are slippage guards — the transaction reverts if the deployer's currently configured fees exceed them. Use the agreed contractual values so an accidental on-chain fee bump can't deploy a vault with fees higher than what you signed up for.
Extract the vault address
The deployer emits a VaultDeployed event. Parse it from the receipt:
import {parseAbiItem, decodeEventLog} from 'viem'
const vaultDeployedEvent = parseAbiItem(
'event VaultDeployed(address indexed plasmaVault, address indexed owner, address accessManager, address feeManager, address rewardsManager, address withdrawManager, address contextManager, address priceManager)'
)
const log = receipt.logs.find(l => l.address.toLowerCase() === deployer.toLowerCase())
const decoded = decodeEventLog({abi: [vaultDeployedEvent], data: log.data, topics: log.topics})
const vault = decoded.args.plasmaVault
const withdrawManager = decoded.args.withdrawManager
Save plasmaVault (the vault address you'll interact with for deposits / withdrawals) and withdrawManager (per-vault manager for scheduled withdrawals). Both are also discoverable later via the Public API.
Using permit (one transaction)
For underlying tokens that support EIP‑2612, you can skip the separate approval and deploy in a single transaction:
// 1. Generate a permit signature for `initialDeposit` to `deployer`
const {v, r, s, deadline} = await signPermit({...})
// 2. Call the permit variant
await walletClient.writeContract({
address: deployer,
abi: /* deployVaultWithPermit ABI */,
functionName: 'deployVaultWithPermit',
args: [initialDeposit, mgmtFee, perfFee, deadline, v, r, s],
})
Once your vault exists, continue to Strategy Assignment to start managing it, or Deposits if you want to add more capital first.