You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -45,6 +46,49 @@ OVault extends the ERC-4626 tokenized vault standard with LayerZero's omnichain
45
46
46
47
OVault makes it extremely easy to move assets and shares between any supported chains, while also enabling cross-chain vault operations. Users can deposit assets from any chain to receive shares on any destination chain, redeem shares from any chain to receive assets on any destination chain, or simply transfer these tokens between chains - all through a unified interface.
47
48
49
+
**Stargate Integration**: OVault is fully compatible with Stargate OFTs (USDC, USDT, etc.) as vault assets, with automatic decimal handling and no configuration required.
50
+
51
+
## Composer Types
52
+
53
+
OVault supports two types of composers to handle different asset types:
54
+
55
+
### MyOVaultComposerERC20
56
+
57
+
Use this composer when your vault's underlying asset is a standard **ERC20 token**:
58
+
59
+
- Works with any ERC20-based OFT (e.g., Stargate USDC, USDT0, WBTC)
60
+
- Direct integration with ERC-4626 vaults
61
+
- Standard approval and transfer flow
62
+
63
+
### MyOVaultComposerNative
64
+
65
+
Use this composer when your vault's underlying asset is based on the **chain's native token** (e.g., ETH, HYPE):
66
+
67
+
- Required for native token OFTs like `NativeOFTAdapter` or `StargatePoolNative`
68
+
- Automatically wraps native tokens (ETH) into WETH before depositing to the vault
69
+
- Necessary because ERC-4626 vaults only support ERC20 tokens
70
+
- Transparent to end users - they send native tokens and receive shares
71
+
72
+
> **Note**: This composer uses the WETH9 interface (`deposit()`/`withdraw()`) to convert between native and wrapped tokens. This works with standard implementations like ETH→WETH and HYPE→WHYPE. If your chain's wrapped native token uses a different interface, you must override the composer's `lzCompose()` function with the correct wrapping mechanism.
73
+
74
+
> **Issuing Your Own Native Asset**: If you plan on issuing a bridged version of the chain's native asset yourself (i.e., not `StargatePoolNative` or an already deployed `NativeOFTAdapter`), use a `NativeOFTAdapter` instead of a standard OFT. See the [native-oft-adapter example](https://github.com/LayerZero-Labs/devtools/tree/main/examples/native-oft-adapter) for details.
75
+
76
+
**Which Composer Should You Use?**
77
+
78
+
The composer type depends on your asset OFT's underlying token:
79
+
80
+
- If `assetOFT.token()` returns an ERC20 address → use `MyOVaultComposerERC20`
81
+
- If `assetOFT.token()` returns `address(0)` (native token) → use `MyOVaultComposerNative`
82
+
83
+
**Customizing Token Initialization**
84
+
85
+
The parent `VaultComposerSync` contract provides overridable functions for custom token patterns:
86
+
87
+
-`_initializeAssetToken()`: Override for non-standard asset token configurations
88
+
-`_initializeShareToken()`: Override for non-standard share token configurations
89
+
90
+
This is useful when your vault or OFT contracts don't follow the default patterns (e.g., custom ERC4626 vaults that accept ETH directly).
91
+
48
92
## Requirements
49
93
50
94
-**git**
@@ -117,6 +161,13 @@ Configure your vault deployment in `devtools/deployConfig.ts`. This file control
117
161
118
162
> **Note**: If your asset is already an OFT, you do not need to deploy a separate mesh. The only requirement is that the asset OFT supports the hub chain you are deploying to.
119
163
164
+
> **Important - Composer Selection**: Choose the correct composer type based on your asset:
165
+
>
166
+
> - Use `MyOVaultComposerERC20` for standard ERC20 asset OFTs
167
+
> - Use `MyOVaultComposerNative` for native token OFTs (e.g., `NativeOFTAdapter`, `StargatePoolNative`)
168
+
>
169
+
> See the [Composer Types](#composer-types) section for details.
// Asset OFT configuration (deployed on specified chains OR use existing address)
197
+
// NOTE: For native assets (ETH, HYPE), use 'MyAssetOFTNative' with 'MyOVaultComposerNative'
146
198
asset: {
147
-
contract: "MyAssetOFT",
199
+
contract: "MyAssetOFTERC20",
148
200
metadata: {
149
-
name: "MyAssetOFT",
201
+
name: "MyAssetOFTERC20",
150
202
symbol: "ASSET",
151
203
},
152
204
deploymentEids: [_hubEid, ..._spokeEids],
@@ -229,7 +281,7 @@ Compile your contracts:
229
281
pnpm compile`
230
282
```
231
283
232
-
>**Testing Note**: If you're deploying the asset OFT from scratch for testing purposes, you'll need to mint an initial supply. Uncomment the `_mint` line in the `MyAssetOFT` constructor to provide initial liquidity. This ensures you have tokens to test deposit and cross-chain transfer functionality.
284
+
>**Testing Note**: If you're deploying the asset OFT from scratch for testing purposes, you'll need to mint an initial supply. Uncomment the `_mint` line in the `MyAssetOFTERC20` constructor to provide initial liquidity. This ensures you have tokens to test deposit and cross-chain transfer functionality.
233
285
>
234
286
>**⚠️ Warning**: Do NOT mint share tokens directly in`MyShareOFT`. Share tokens must only be minted by the vault contract during deposits to maintain the correct share-to-asset ratio. Manually minting share tokens breaks the vault's accounting and can lead to incorrect redemption values. The mint line in `MyShareOFT` should only be uncommented for UI/integration testing, never in production.
235
287
@@ -274,17 +326,17 @@ import { OAppEnforcedOption } from "@layerzerolabs/toolbox-hardhat";
274
326
275
327
const optimismContract: OmniPointHardhat = {
276
328
eid: EndpointId.OPTSEP_V2_TESTNET.valueOf(),
277
-
contractName: "MyAssetOFT",
329
+
contractName: "MyAssetOFTERC20",
278
330
};
279
331
280
332
const arbitrumContract: OmniPointHardhat = {
281
333
eid: EndpointId.ARBSEP_V2_TESTNET.valueOf(),
282
-
contractName: "MyAssetOFT",
334
+
contractName: "MyAssetOFTERC20",
283
335
};
284
336
285
337
const baseContract: OmniPointHardhat = {
286
338
eid: EndpointId.BASESEP_V2_TESTNET.valueOf(),
287
-
contractName: "MyAssetOFT",
339
+
contractName: "MyAssetOFTERC20",
288
340
};
289
341
290
342
// Configure gas limits for message execution
@@ -650,6 +702,30 @@ npx hardhat lz:ovault:send \
650
702
-`--lz-compose-value`: Value for lzCompose operation (in wei)
651
703
-`--oft-address`: Override source OFT address
652
704
705
+
**Using Stargate Assets:**
706
+
707
+
The OVault system is fully compatible with Stargate OFTs (e.g., USDC.e) as the underlying vault asset. To use Stargate assets, specify the Stargate pool/OFT address using the `--oft-address` parameter:
708
+
709
+
```bash
710
+
# Example: Deposit Stargate USDC from Ethereum to receive shares on Base
711
+
npx hardhat lz:ovault:send \
712
+
--src-eid 30101 \
713
+
--dst-eid 30184 \
714
+
--amount 100 \
715
+
--to 0xYourRecipientAddress \
716
+
--token-type asset \
717
+
--oft-address 0xc026395860Db2d07ee33e05fE50ed7bD583189C7 # Stargate USDC pool on Ethereum
718
+
```
719
+
720
+
**Key points for Stargate integration:**
721
+
722
+
- The `--oft-address` must point to the Stargate pool/OFT address on the source chain
723
+
- Decimals are automatically detected (e.g., 6 decimals for USDC vs 18 for ETH)
724
+
- No LayerZero config files needed - addresses are read from the deployed composer
725
+
- Works with any Stargate asset that implements the IOFT interface
726
+
- Find Stargate contract addresses in the [LayerZero OFT Ecosystem Docs](https://docs.layerzero.network/v2/deployments/oft-ecosystem-stargate-assets?stages=mainnet&issuers=Stargate)
727
+
- Automatic slippage protection (0.5% default) for stablecoin transfers
728
+
653
729
**Gas Optimization:**
654
730
655
731
The task automatically optimizes gas limits based on operation type:
0 commit comments