Skip to main content

Quick reference for admins, curators, allocators, and sentinels operating an MYT vault.


Contract Structure and Roles​

There are four contract layers:

  • MYT Vault (Morpho V2) – holds funds, enforces caps, manages roles
  • Curator Contract – manages strategy registration and cap configuration (one per chain, shared by the MYTs on that chain)
  • Allocator Contract – moves funds between the vault and strategy adapters (one per MYT)
  • MYT Strategy – individual yield strategy adapters (one per yield source per MYT)

Each layer has its own role system. Holding a role on one contract does not grant access on another.

Addresses Summary​

AddressRoles Held
v3 admin SafeMYT Owner · Curator Admin · Curator Operator · Allocator Admin · Allocator Operator · Strategy Owner (every adapter)
DAO treasury multisigMYT Sentinel · Alchemist Guardian · Protocol fee receiver
Alchemix AssociationMYT Sentinel
EOAMYT Sentinel

Note: The admin Safe is not set as a direct Allocator on either MYT vault. Allocator-level MYT functions are called through the Allocator Contract: allocate, deallocate, the swap variants and setLiquidityAdapter by the admin or an operator, and setMaxRate by the admin. Only vault functions the Allocator does not wrap need proxy forwarding.


Allocation Flow​

Strategy Route Examples​

Each strategy configures which allocation and deallocation paths it supports. Using an unsupported route will revert.

Strategyallocate()allocateWithSwap()deallocate()deallocateWithSwap()deallocateWithUnwrapAndSwap()
wstETHYesYesNoYesNo
sfrxETHYesYesNoNoYes

Check the documentation for which direct / swap paths are enabled for this strategy before executing.


Allocate Reference: Amount Encodings​

TokenDecimalsExample (1 unit)
USDC61_000_000
wETH181_000_000_000_000_000_000
Relative Cap (100%)181e18

All amounts are uint256.


Liquidity Adapter​

The liquidity adapter is the default strategy the vault uses to service user deposits and withdrawals. It is set with setLiquidityAdapter(adapter, data) on the Allocator Contract (admin or operator), which calls the vault's setLiquidityAdapterAndData.

Critical: The liquidity adapter must be a strategy that supports direct (non-swap) deposit and withdrawal paths. Swap-only strategies (e.g., sfrxETH) cannot be set as the liquidity adapter, because user withdraw()/redeem() calls do not pass swap calldata. If no strategy on a given chain supports direct paths, leave the liquidity adapter unset; the vault will operate with idle assets only.


Deallocation Flow​


Constructing 0x txData​

For swap-based allocation and deallocation, you need to pass txData, the encoded calldata from the 0x Swap API.

  1. Call the 0x API with: sellToken, buyToken, sellAmount, and taker = strategy contract address (not the allocator or multisig)
  2. The API returns encoded calldata. Pass this directly as txData
  3. Quotes are time-sensitive, so fetch and submit in the same session
  4. For deallocateWithUnwrapAndSwap(): the swap is for the intermediate token (e.g., frxETH → WETH), not the held token (sfrxETH). Set minIntermediateOut to match the quote's sellAmount.

The Alchemix Admin UI should be used to construct txData when available.

For a detailed walkthrough of the unwrap+swap path, see the deallocateWithUnwrapAndSwap guide.


Proxy Forwarding​

The Curator and Allocator contracts inherit from PermissionedProxy. The admin enables a vault function selector with setPermissionedCall(selector, true), and an operator can then forward a call to the MYT vault with proxy(vault, data). This is only needed for MYT functions that the utility contracts do not wrap natively.

Natively wrapped (no proxy needed): the Allocator exposes setMaxRate(uint256) (admin only) and setLiquidityAdapter(address, bytes) (admin or operator), which calls the vault's setLiquidityAdapterAndData. See the Allocator reference.

Curator proxy: Any Morpho V2 curator function not already wrapped by the AlchemistCurator contract (for example the timelock functions) can be forwarded via proxy() after the admin has enabled its selector.

Example: forwarding an unwrapped call​

// Step 1 (admin): enable the selector on the proxy
curator.setPermissionedCall(selector, true);

// Step 2 (operator): forward the call to the vault
curator.proxy(mytVault, abi.encodeWithSelector(selector, args));

setPermissionedCall() is admin-only. proxy() is operator-only; the admin can use it only if it is also set as an operator.


Troubleshooting: "I can't call this function"​

Error / SymptomLikely CauseFix
Reverts with "PD" on Allocator ContractCaller is not admin or operator on the Allocator ContractAllocator Admin calls setOperator(yourAddress, true)
Reverts with "PD" on Curator ContractCaller is not admin or operator on the Curator ContractCurator Admin calls setOperator(yourAddress, true)
EffectiveCap revert on allocationAllocation would exceed absolute, relative, or risk capRaise the absolute or relative cap via the Curator admin (submit, then execute), raise the risk-class cap via the StrategyClassifier admin, or reduce the amount. Local risk caps bind operators only
StrategyAllocationPaused on allocateStrategy killSwitch is enabledStrategy Owner calls setKillSwitch(false) on the MYT Strategy contract
ActionNotSupported on allocate/deallocateUsing a route not configured for this strategyCheck the documentation for which direct / swap paths are enabled for this strategy
Can't call setMaxRate()Caller is not the Allocator admin, or is calling the vault directlyAllocator admin calls allocator.setMaxRate(rate)
Can't call setCurator() or setIsSentinel()Caller is not the MYT OwnerMust be called by the v3 admin Safe as MYT Owner directly on the MYT
Timelocked function won't executesubmit() was not called firstCall the corresponding submit* function first, then the execution function