Integration Guides
This page provides concrete patterns for the most common integration scenarios. Examples use Arbitrum One and USDC but the same patterns apply to all supported chains.
Integrating as a Depositor
CoreVault follows the ERC-4626 standard, so any contract or EOA that can interact with ERC-4626 vaults can deposit into Multyr without custom logic.
Deposit Flow
IERC20 usdc = IERC20(USDC_ADDRESS);
IERC4626 vault = IERC4626(CORE_VAULT_ADDRESS);
// 1. Approve the vault to spend USDC
usdc.approve(address(vault), amount);
// 2. Deposit USDC and receive shares
uint256 shares = vault.deposit(amount, msg.sender);
Withdrawal Flow
// Withdraw a specific USDC amount
uint256 sharesBurned = vault.withdraw(amount, msg.sender, msg.sender);
// Or redeem a specific number of shares
uint256 assetsReceived = vault.redeem(shares, msg.sender, msg.sender);
Preview Before Executing
Use the preview functions to display expected outcomes before the user confirms:
uint256 expectedShares = vault.previewDeposit(amount);
uint256 expectedAssets = vault.previewRedeem(shares);
Checking Limits
uint256 maxDepositable = vault.maxDeposit(user);
uint256 maxWithdrawable = vault.maxWithdraw(user);
If maxWithdraw returns less than the requested amount, the vault may need to unwind strategy positions. The buffer is designed to cover typical withdrawal sizes instantly.
Integrating as a Frontend
Frontends need to read vault state and translate it into user-facing metrics.
Reading Vault State
| Metric | How to Compute |
|---|---|
| Share price | vault.convertToAssets(1e18) (for 18-decimal shares) or vault.totalAssets() / vault.totalSupply() |
| User balance (USDC) | vault.convertToAssets(vault.balanceOf(user)) |
| TVL | vault.totalAssets() |
| APY | Derived off-chain by tracking share price over time, or from subgraph harvest data |
Displaying Allocation Breakdown
Call StrategyRouter.getStrategyAllocations() to retrieve per-adapter deployed amounts. Map adapter addresses to protocol names for display.
Handling Deposits in a UI
- Check
vault.maxDeposit(user)to determine if deposits are open and the cap. - Call
usdc.allowance(user, vault)-- if insufficient, prompt anapprovetransaction. - Call
vault.previewDeposit(amount)to show expected shares. - Submit
vault.deposit(amount, user). - Listen for the
Depositevent to confirm.
Handling Withdrawals in a UI
- Check
vault.maxWithdraw(user)to show available instant withdrawal. - Call
vault.previewWithdraw(amount)to show shares that will be burned. - Submit
vault.withdraw(amount, user, user). - Listen for the
Withdrawevent to confirm.
Integrating as a Keeper
Keepers trigger periodic maintenance operations: harvesting yield from strategies and rebalancing allocations.
Harvest
Calling harvest() on the StrategyRouter collects accrued yield from all active adapters and returns it to the vault, increasing totalAssets and thus the share price.
IStrategyRouter router = IStrategyRouter(STRATEGY_ROUTER_ADDRESS);
router.harvest();
Rebalance
Calling rebalance() redistributes capital across adapters to match the configured target weights.
router.rebalance();
Automation
Both harvest() and rebalance() are designed to be called by Chainlink Automation upkeeps. The expected integration pattern:
- Register a Chainlink Automation upkeep pointing at the StrategyRouter.
- The
checkUpkeep()function returnstruewhen a harvest or rebalance is due (based on time elapsed or deviation thresholds). - Chainlink nodes call
performUpkeep()which executes the harvest/rebalance.
Gas costs for keeper operations are tracked by OpsCollector and deducted from protocol revenue.
Building on Top of Multyr
Because CoreVault is a standard ERC-4626 vault, it is composable with any protocol or contract that understands the ERC-4626 interface.
Composability Examples
- Lending collateral: Use vault shares as collateral in a lending market that accepts ERC-4626 tokens.
- Structured products: Build tranched or leveraged yield products on top of Multyr shares.
- DAO treasuries: Deposit idle USDC from a DAO treasury into CoreVault to earn yield while retaining ERC-4626 share tokens as liquid, transferable assets.
- Aggregator integration: Yield aggregators and routers can treat CoreVault as one of many ERC-4626 yield sources.
Wrapping the Vault
If your protocol needs a custom wrapper:
contract MyWrapper {
IERC4626 public immutable vault;
constructor(address _vault) {
vault = IERC4626(_vault);
}
function depositAndStake(uint256 assets) external {
IERC20(vault.asset()).transferFrom(msg.sender, address(this), assets);
IERC20(vault.asset()).approve(address(vault), assets);
uint256 shares = vault.deposit(assets, address(this));
// ... stake shares in your protocol
}
}
Document version: 1.1 Last updated: 2026-03-29