Omnichain Vaults Inside LayerZero's ERC4626 OVault Standard I Matthew Krak
ETHGlobal·Thu, Oct 9, 2025, 12:00 AM
Matthew Krak, Developer Ecosystem Lead at LayerZero Labs, presents on building omnichain vaults using LayerZero’s ERC4626 OVault standard. He explains LayerZero’s permissionless, censorship-resistant, and immutable interoperability protocol, enabling developers to deploy smart contracts across any blockchain and send arbitrary data/messages using customizable security stacks (DVNs like Google, Axelar, CCIP, Wormhole). LayerZero’s architecture supports both vertical and horizontal composability, allowing complex cross-chain execution flows and atomic/non-atomic operations. The talk details how omnichain vaults simplify ERC4626 vault interactions, enabling users to deposit assets on any network and receive shares on any destination, all via a single hub chain. Krak demonstrates deploying an omnichain vault using LayerZero’s tooling, configuring networks, assets, and shares, and wiring contracts for cross-chain communication. He answers questions on vault architecture, asset/share redemption, liquidity, and customization, emphasizing the flexibility and extensibility of the OVault standard for cross-chain DeFi. 00:00 Introduction 00:27 LayerZero Overview & Interoperability 01:23 Security Stack & Message Verification 02:33 Customizable Security & Validation 03:39 Vertical vs. Horizontal Composability 04:51 Cross-Chain Token Transfers 05:41 Omnichain Vaults & ERC4626 Standard 06:53 Omnichain Vault Workflow 08:15 Live Demo: Deploying an Omnichain Vault 11:24 Configuring Networks & Contracts 12:54 Compiling & Deploying Contracts 15:16 Asset & Share Token Configuration 15:58 Wiring Contracts Across Chains 18:16 Supported Networks & Documentation 19:07 Testing Cross-Chain Vault Operations 20:49 Reverse Redemption Flow 22:07 Q&A: Vault Architecture & Liquidity 24:36 Vault Limitations & Customization 26:13 Project Resources & Closing _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 🇺🇸 *ETHGlobal New York* This workshop is specifically for ETHGlobal New York, a 3-day hackathon held August 15-17, bringing together the most skilled web3 developers, designers and product builders from all around the globe for a weekend-long adventure to advance the Ethereum ecosystem! Watch the full ETHGlobal New York 2025 playlist here: https://www.youtube.com/playlist?list=PLXzKMXK2aHh4Xze0ZeSWCSGsw25clPpvZ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ✅ *Follow LayerZero* X: https://x.com/LayerZero_Core ✅ *Follow ETHGlobal* X: https://x.com/ETHGlobal Warpcast: https://warpcast.com/ethglobal Website: https://ethglobal.com YouTube: https://www.youtube.com/c/ETHGlobal _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _Are you interested in Ethereum development and entrepreneurship?_ 👉 Sign up for the next ETHGlobal event: https://ethglobal.com/events 🎁 Get exclusive access and perks with ETHGlobal Plus! https://ethglobal.com/plus 📣 Want us to throw an event in your city? Tell us where! https://ethglobal.com/city _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Transcript
[Music] We're going to be talking about building omni chain vaults. Uh before we begin, my name is Matt. I'm a developer ecosystem lead at layer zero labs. Feel free to follow me or ask me questions afterwards at Uncrackable on Twitter or X. And one thing I wanted to mention today was about how layer zero actually powers a global ledger of blockchains.
Layer 0 is permissionless, censorship resistant, immutable bridge infrastructure. A little bit more about how layer zero works is we as an in im immutable interoperability protocol enable you the application developer to deploy smart contracts on any blockchain network, send a message through a layer zero endpoint interface and deliver a message to a destination chain using the security stack that you want and need and permissionlessly execute messages on destination blockchains. Um, getting a little bit more granular on how this works. Layer zero, the send operation enables you within your smart contract to define any arbitrary types of data that you want to send as a layer zero message. A layer zero message can be any arbitrary bite structure uh whether that's AI encoded or manually packed uh sent via the layer zero endpoint send interface here and then delivered to your chosen security stack.
A security stack within layer 0ero is a uh consortium of any type of validation provider that you want. These DVNs could be layer zero labs, the service that we run, uh Google, Axelar, CCIP, Wormhole, broadly any messaging provider or service that you'd like underneath the hood for your layer zero message and a chosen executor. These services enable you to seamlessly connect and send messages to any destination chain and move any arbitrary data assets or data and assets together. Uh once messages get emitted from a source blockchain, they are then verified by the security stack that you've chosen. Uh these verifications are delivered to a destination protocol contract called the message library.
This library enforces that the expected DVNs set by your application are the ones that are delivering the verification and that this threshold of security is met according to your config. After verification, anyone can permissionlessly execute the message by committing the verification into the endpoint contract and then delivering the final message to your destination smart contract via layer zero's LZ receive interface. This format of sending a message causing a state change on a source blockchain, delivering verification to a destination chain, and then executing finally the message is the basis for most layer zero messages on the protocol today. What this security setup gives you is the ability to define arbitrarily what security versus cost looks like for your application. Typically, when you're working with uh any type of message passing service, you're forced to fit a model of what security is depending on the provider that you're using.
Because layer 0 allows you to tailor the security providers that you use. Not only can you choose between config A or config B on this simple curve, you can choose any point in between. And as validation practices improve, for example, with new ZK proof technology that's coming out, you're able to seamlessly update your config and inherit the latest and greatest best practice when it comes to message validation across multiple blockchains. Um, on the execution side, layer zero enables complex execution flows that enable you to trigger multiple smart contract calls on destination chain. On the left here you can see vertical composability.
The idea that within the LZ receive interface you can make calls to multiple different smart contracts A, B, and C. But one problem with this approach is that what happens when a contract call reverts. Well, if contract call C reverts, everything in this call stack also reverts since blockchain operations are atomic. So layer 0 has devised a way for you to get around this limitation via horizontal composability. Using layer zero, you can define multiple steps in your destination call.
For example, if I want to update some state in the first call, LZ receive and then secondarily execute a call in LZ compose. LZ compose enables you to separate the call stack out so that if LZ compose reverts the changes that happened in LZ receive are still finalized on the blockchain. What this means is that using these tools, layer 0 provides you a way for any smart contract on any blockchain network to deliver state information to any other smart contract supported by layer 0. Zooming out a bit, if we talk about why this is relevant to you building at ETH global today. Token transfers, for example, are an easy way to convey the story.
Token transfers on a single blockchain typically involve a single transaction that updates account state between two user balances. So I take balance from one user and credit it to another user all in one atomic transaction in step. But if you try and replicate this on multiple blockchains, suddenly it becomes a lot more challenging. You're talking about multiple transactions on two different chains and the crediting of two different users across this stack. Layer zero makes this easy by enabling you to easily call via our orn chain fungeible token standard a send method that communicates with a layer zero endpoint contract uses the security stack decided by you the app developer and automatically delivers that call on your behalf to credit a user.
This operation is at the base of how omni chain vaults work. Um, when we talk about omni chain, a lot of the work that we're really talking about is making users lives easier when it comes to moving assets and moving any type of information between blockchains. Um, for an omni chain vault, the process that we're simplifying is depositing an asset and receiving a share on multiple different networks. Um, traditionally when we talk about ERC 4626, the way that this ERC vault standard works is that a user will deposit some ERC20 asset token and automatically receive minted out a share token back depending on the ratio of assets to shares defined within the vault contract. Um, but if you're a user who's trying to access deep liquidity across multiple different networks, this is actually very complicated to do with the base ERC 4626 standard.
Uh, with layer zero's omni chain vault standard, you as the user are able to deposit an asset from any network and receive a share token back on any destination network while still interacting with the same ERC4626 vault on a single hub chain. So with that in mind, let's dive a little bit deeper into how this works. Um when we talk about the omni chain vault standard, the typical flow will involve a user calling the send function on a normal layer zero of this will initiate a layer zero transfer to their target destination chain using a uh composer contract that we define a compose message for. After the layer zero transfer has been executed, uh LZ receive will be the step that delivers the tokens first followed by LZ compose in a separate transaction. LZcompose will talk to a composer contract that deposits the assets from the transfer and gets the shares minted back out before initiating another layer zero send call and delivering the shares all the way back to the original user on this flow.
The interesting thing about this workflow is that not only can I, a user on arbitrum, call send, deliver tokens to a hub chain, and then receive the shares back on arbitrum, I can also deliver them to any arbitrary network as well. So, for example, on this step, I send tokens from arbitum, receive them on optimism via shares. Uh, and from the user perspective, I never had to send any other transaction than the one that started on this source blockchain. So, with that, I'm going to try and show you now in 5 minutes or less how to deploy your own omni chain vault and get started. Um, let's jump into it.
So, I already have set up a repo in case things uh are failing for RPCs or things like that, but hopefully everything goes smoothly. Let's go ahead and jump into the actual deployment step. Um, you can access OmniChain vaults today via layer zero's create LZ OAP package. You just have to provide this flag lz enable ovaltample equals 1 with- example ovaltm. When you run this, what'll happen is it'll first check where you want to deploy your project to.
In this case, I'm going to create eth global NYC and I'm going to call it two just so I know that it's the second time I've done this. It'll see pre-selected oval evm and I will use pnpm as my package manager, but you could use npm or yarn if you wanted as well. This will pull in all of the contracts, all the dependencies that I need in order to get started. And it'll initialize your repo with both hard hat and foundry enabled. So if you want to script in Foundry, test in Foundry, you're happy to do that.
If you want to use any other type of uh scripting via like ethers or VM, you can also use that in this repo too. So no hard dependencies there. Looking at the repo that gets created, you can see that we have a pretty standard layout. We have a contracts folder that has four main contracts that we'll be deploying today. Uh we also have a hard hat config and some layer zero config files.
Um I'll get into specifically what these look like, but I think the easiest thing to start with will probably be the readme. So looking at the readme, it'll explain to you a little bit about what contracts are available in this repo. Um we'll also get some examples on how to set this up correctly. In my case, I already have av file available in this folder. Or actually, I don't have it yet.
So, I'll just copy that over really quickly. We'll grab it from our OAT example. And we'll paste it over here. So, I should get uh this pasted in here for me in just a moment. I might have to do do this really quick.
Let's see what we have here. East Global NYC.
Ah, yeah, you're right. Ott and we'll grab V. Oh, yeah. Yeah, good, good point. Good point.
We got a CD down one more level. There we go. Thanks for the the call out there. Nice. So, we'll grab our original Ovalt.
env file. Uh oh, set CD. We want to copy paste. Perfect. We'll do get init.
Hopefully that gave enough time for everything to install. Looks like yep, installer's done. Nice. I'll do a quick check. PNPMI is working.
Awesome. So the steps to actually get started with deploying this are pretty straightforward. Um add your file in. The first thing we're going to look at is our hard hat config file. This sets up our networks within the hard hat framework.
Uh in this case I want to do mainet and not test net. So I'm going to update this endpoint ID object. Uh endpoint ids are how we define the layer zero protocol contract interface on each chain. So every protocol instantiation has this eid. We're going to add optimism here.
Uh, and I'm also going to update the RPC from Optimism Sapoleia, Optimism Gateway. Also going to do that for base here. I'm going to do the same thing here. Update the RPC. Going to update this one to arbitr.
Hit save. We should be done with editing our hard hat config. If you want to add any other networks, you're welcome to do it this way just by copying pasting and then renaming and redefining. Um, and the next thing we're going to do is go into this dev tools folder and enter deploy config. Uh, same exact thing here.
You can see some definitions for what our contract names are as defined in the contracts folder. Uh, the only thing I'm going to edit in here is again uh the eids I'm going to be accessing. So in this case, update to optimism, base, and arbitrum. Uh, same for this step here as well. Update to optimism and base.
Uh, and we should be good to go. I think with our deployment. So following the readme again, uh to get started with deploying these contracts, I'm going to run uh first PNPM compile. And actually before I do that, I'm going to do one small edit. I'm just going to mint some shares on deployment or sorry mint some assets on deployment here and recompile.
hopefully goes pretty quick. Awesome. And then run pnpm hard hat lz deploy with tags ovalt. This deploy script will automatically deploy all of the necessary contracts that I need on each network. Um if arbitum base and optimism, uh I'm going to hit yes.
The deployer will run. Hopefully RPCs are going to be pretty quick here and we'll get this sorted. We should see my asset of deployed on arbitrum base and optimism. We'll also see uh the composer contract get deployed here. Uh nice.
All right, we should have all of our contracts deploy. Let's check our deployments folder. It seems we only deployed Seems like it didn't finish deploying fully. Let's just make sure that everything got deployed. Interesting.
Let's make sure our deploy config has everything that it expects. Might be missing an eid somewhere in here. Optimism base arbitum. Ah, yeah, this is where I forgot. Need to update one more eid.
And this is telling that the hub chain that we're deploying our vault on is arbitrum. Let's just run this one more time. Make sure we're good to go. Arbitron base ovault. Yes, we should see now not only the asset being deployed, but also the share.
And yes, the 4626 contract. That's our actual vault that's being deployed. We got one failed deployment from a bad RPC on base. We'll rerun. It should detect where we already have deployments and finish up on the other ones.
Awesome. I have five minutes left, so I think I can get through the rest of this. Um, awesome. Our contracts are now deployed. We look at our deployments folder.
We should see everything deployed there. Perfect. Now, there are two config files where you can configure your asset OFT and your share OFT. Since a 4626 vault includes two ERC20 tokens, we're going to update both. We're also going to update our uh eids here again to be mainet.
So, arbitrum, arbitrum, and base or optimism arbitum base. That's all we need to do on this file. Same thing for our share token. We're going to update our contract instances to say optimism base and arbitrum. Hit save on both of those.
Now, we're going to run uh one more command is defined in the readme. This is the wiring step. So, this tells uh our smart contracts in each chain basically that they're paired to one another and uh what the um what the security stack is that's involved with each of them. So, in this case, I'm going to wire asset config first. It's going to check first to see what transactions need to be submitted on chain.
In this case, there are 27. I'm going to hit yes, and hopefully we'll get through this pretty quick. Um, typically it'll wrap up in like 20 seconds or so. Uh, and what this is basically submitting on chain is contract calls to the endpoint contract which are basically telling layer zero that hey for this application we're going to use these DVNs, this executor and this configuration stack. And it's executing those calls on every single blockchain that we're deployed on.
So, this CLI simplifies the experience of just making sure that your configurations are set as expected. We should be wrapping up here in just a second. Only four more to go. We got three minutes left. Um, show of hands.
Who thinks we're going to get through this before we finish?
He thinks so. Yeah.
Yeah.
In in the env file. So earlier I actually just added um I copy and pasted my enenv but you can add your own by updating example with your private key defined here. Um now I'm going to run this for the share config. So same exact thing going to configure my share token. Uh and this should wrap up hopefully in the same time and we'll have just enough time at the end for send transaction to see that it's working and questions.
Uh any other questions in the meantime while we're waiting? Yes.
Yeah. looked at the documentation it was pretty hard to figure out which networks uh there's like multiple versions
there's v1 v2 like which you actually support
definitely so for v2 we support um 140 networks the place to find all of that is if we go to the layer zero docs here docs layer network v2 protocol contracts use all of these for v2 related contracts OP, OFT. Um, we're live on all of the chain partners here. So if you need Hideera TestNet, Flow Testnet, Flare Testnet, they're all available this way. Um, and then you can find the relevant endpoint IDs like the ones that I'm using here in uh the layer zero config file by similarly typing in, you know, flare uh flow optimism. Just like that.
Awesome. We should be good now for a transaction. Let's test really quick. Um, going back through the readme, we can see that the last step in order to actually test this is to just use the send script provided. Um, the simplest way to test, I think, is to first send to uh back to your source network.
In this case, we're going to do uh npx hard hat lz ovalt send. The arguments that I'm providing here are the source e that I'm going to be sending from uh in this case 30184 is base the destination eid 30101 is optimism and our contracts if we look in our deployments our composer and vault is deployed on arbitum. So in this transaction what our console log will show us is that we are using the hub arbitrum mainet. Our deposit flow is from base mainet into arbitrum mainet and then receiving our shares on optimism mainet. You can see a preview here based on the vault.
We're going to get exactly one one asset and share out. Um you can see that it's quoting the cost of the transaction and it sent it now on layer zero scan. So let's take a look at this transaction live. Um you can see here it's already succeeded. Um what's happened in this flow is that the asset transfer happened in destination transaction hash for LZ receive.
If we paste uh the LZ composed transaction hash in we can see that our receiving of the share token out is still happening right now. Uh it should be confirmed in just a moment now but uh just waiting and delivered. Perfect. I think that's exactly 20 minutes. So what we did in this flow was we deployed a vault contract on arbitum.
We deployed an asset on base and a share token on optimism and did that full flow end to end. If we want to get the token back now, let's say deposit a share and get our asset originally back on arbitrum. We're going to change our source e ID to 30101, our destination eid to 30184, and then token type here from asset to share. Run this one more time and do the exact same operation in reverse. So you can see now hub is still arbitrum, but now we're going and redeeming from optimism on arbitum and getting a token back out on base.
Um, again, you're pasted a layer zero scan link. If we go and check this, you can see all these operations are in flight. And if we dive in um to our previously successful message, if we get a little bit clearer view, you can see that in this transaction, if we check the logs, we transferred a share token on optimism into our wallet. And in this transaction, once it finalizes, we'll get the original asset back on base. Um I think I'll pause right there.
I threw a lot at you guys, so any questions? Let's go through them. Yes.
Good question. So for an ERC 4626 vault, the way that this standard works is that you deploy the vault on a single hub chain. So the vault only exists on arbitum, but you can deposit shares from any other network that's connected. So in this case, the term hub is just the place where your vault lives.
So that's where the highest APY.
Exactly. And the hub is basically a way of giving yourself deeper liquidity for your vault. Rather than deploying the same vault pair with asset on every network, you can just have the vault live in one place.
Exactly.
Uh yes,
definitely. If we look at the 4626 vault that we deployed here, I'm just going to bring this down. You can look into the 4626 standard a little bit more. But the way that this contract works is that basically you provide it with any ERC20 token as the asset and then define what the share token will be called. Um, when you deploy a 4626 vault, it just takes in that asset and then creates a share token out.
And within 4626, you should see in uh the function here that there is a convert to shares or convert to assets ratio that's defined. And basically there's a a view function within the 4626 vault that defines the asset ratio. So how many shares should you get out for a single asset? Um I recommend looking at the Ethereum documentation more. price assets.
Yes.
Can some of the assets on
Exactly. Yes.
Yeah. So the nice thing about this standard is that the assets and shares that are issued on other networks are onetoone redeemable for the underlying uh in the hub. So the idea is basically that because you have access and the ability to transfer instantly back into the hub, uh, arbitrage will naturally take care of any like price rebalancing that happens on other networks because you can instantly bring that back into the hub and then redeem it for a share if price changes. Does that kind of make sense? Because the the asset that you're issuing on these other networks via OFT, they're inherently onetoone compatible with the asset on the hub.
It's not like a different asset. Using OFT, it immediately burns the asset on that chain and then mints it on hub. total amount of chains.
I I see what you're saying. So, so this model only allows for a single vault to be deployed on one chain.
Um, but you could uh you could modify this composer contract to work with maybe multiple vaults. The the hard thing there is that you need to redeem um assets and shares at the correct ratio, right? If you issue shares from two different vaults, they're not inherently redeemable for the same underlying vault if they're two different hubs. So that that's the issue that you might run into.
Uh yes,
and you can change vault contract, right?
Yes, absolutely. So you can modify the 4626 vault um as long as it fits the 4626 interface. That's the only requirement. And those so the external the nonub contracts are just type pipe messages to
exactly they're just ERC20 tokens on other chains they have nothing to do with 4626 all that you're doing is in actually this composer contract called vault composer sync it basically just defines a single function lzcompose of how to handle this compose message when you're redeeming assets that are coming in from another chain or uh withdrawing the underlying asset after delivering a share. So literally just message
exactly
can we find project?
Absolutely. If you're looking for this project um feel free to scan the uh QR code here that I have at the beginning. Um let me just jump into this view one more time. Omni chain vaults. Um, this QR code will give you a link tree that gives you all of the relevant uh uh links to get to OALT and how to find the repo.
If you have questions or still having issues once this loads, there we go. Um, feel free to talk with me after. We'll get you in the correct group so you guys can get sorted. Cool. Um, and I think we're out of time, so thank you guys.
[Music]
Automatic transcript — names and jargon may be misspelled.