Skip to content

Commit 77e662c

Browse files
authored
Merge pull request #52 from BrianSeong99/vault-bridge-doc
Vault Bridge Integration Guide
2 parents 16bed0c + 925cfe7 commit 77e662c

File tree

14 files changed

+1565
-89
lines changed

14 files changed

+1565
-89
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
title: Vault Bridge Architecture
3+
---
4+
5+
<!-- Page Header Component -->
6+
<h1 style="text-align: left; font-size: 38px; font-weight: 700; font-family: 'Inter Tight', sans-serif;">
7+
Vault Bridge Architecture
8+
</h1>
9+
10+
<div style="text-align: left; margin: 0.5rem 0;">
11+
<p style="font-size: 18px; color: #666; max-width: 640px; margin: 0;">
12+
How Vault Bridge mints yield-bearing vbTokens on Ethereum and distributes them safely across Agglayer and other bridge routes
13+
</p>
14+
</div>
15+
16+
## High-Level Overview
17+
18+
Vault Bridge wraps blue-chip assets on Ethereum (Layer&nbsp;X) into ERC‑4626 vbTokens that accrue yield from curated vaults. Those vbTokens can be bridged to Layer&nbsp;Y networks through multiple transport layers (Agglayer today, Hyperlane for yield routes, more coming). The architecture is intentionally modular: Layer&nbsp;X contracts handle collateralization and yield, Layer&nbsp;Y contracts focus on user experience and liquidity, and bridge adapters provide the cross-network plumbing.
19+
20+
| Location | Component | Responsibility |
21+
|----------|-----------|----------------|
22+
| Layer&nbsp;X (Ethereum) | `VaultBridgeToken` | ERC‑4626 vault that holds the underlying, enforces risk controls, and mints/burns vbTokens. |
23+
| Layer&nbsp;X | `VaultBridgeTokenPart2` | Operational add-on providing reserve management, migration completion, and admin utilities. |
24+
| Layer&nbsp;X | `MigrationManager` | Singleton that receives migrated backing from Layer&nbsp;Y and completes vbToken mint + bridge locking. |
25+
| Layer&nbsp;Y | `AgglayerBridge` / bridge adapters | Receive vbTokens (or mapped tokens), emit exit roots, and send messages back to Ethereum. |
26+
| Layer&nbsp;Y | `CustomToken` (optional) | ERC‑20 wrapper that maps a vbToken into the local token conventions on Layer&nbsp;Y. |
27+
| Layer&nbsp;Y | `NativeConverter` (optional) | Local pseudo-ERC‑4626 vault that swaps between bridged underlying tokens and Custom Tokens. |
28+
| Off-chain | Bridge service + relayers | Provide Merkle proofs, manage Hyperlane warp routes, or automate migration finalization. |
29+
30+
## Core Flows
31+
32+
### 1. Deposit & Bridge (Layer&nbsp;X → Layer&nbsp;Y)
33+
34+
1. User approves the underlying asset (e.g., USDC) to the vbToken.
35+
2. `VaultBridgeToken.depositAndBridge()` pulls the underlying, mints vbTokens 1:1, and reserves part of the assets for instant withdrawals.
36+
3. vbTokens are either minted to the user (staying on Ethereum) or bridged via the selected transport:
37+
- **Agglayer**: vbTokens are locked in the Agglayer bridge and emitted on the destination network.
38+
- **Hyperlane**: vbTokens remain on Sepolia (testnet) while synthetic HypERC20s represent them on remote chains.
39+
4. Optional `NativeConverter` on Layer&nbsp;Y lets users trade local bridged assets for vbTokens.
40+
41+
### 2. Redeem & Withdraw (Layer&nbsp;Y → Layer&nbsp;X)
42+
43+
1. Users call the bridge on Layer&nbsp;Y (`bridgeAsset`) to send vbTokens back to Ethereum.
44+
2. After finality, the Bridge Service API supplies SMT proofs.
45+
3. On Ethereum, users execute `claimAndRedeem()` (or `claimAsset()` + `redeem()`) to receive the underlying asset.
46+
4. `VaultBridgeToken` enforces solvency checks, redeeming first from reserves, then withdrawing from the yield vault if needed.
47+
48+
### 3. Migration (Native Converter → Layer&nbsp;X)
49+
50+
1. Layer&nbsp;Y operators call `NativeConverter.migrateBackingToLayerX()` to send accumulated backing (bridged underlying) to Layer&nbsp;X.
51+
2. The converter bridges both assets and an instruction message to `MigrationManager`.
52+
3. `MigrationManager` claims the assets, calls `VaultBridgeTokenPart2.completeMigration()`, and mints vbTokens that are locked on the origin Layer&nbsp;Y bridge to maintain 1:1 backing.
53+
4. Migration fees fund and reserve rebalancing protect against fee-on-transfer assets.
54+
55+
## Layer X Contracts
56+
57+
### VaultBridgeToken (per asset)
58+
59+
The VaultBridgeToken contract combines ERC‑20, ERC‑4626, and permit extensions. It keeps an internal reserve of the underlying asset, enforcing a configurable minimum reserve ratio that powers instant withdrawals. Excess collateral is deposited into external yield strategies such as Morpho or Yearn, subject to slippage limits and solvency checks. Whenever users invoke bridge-aware entry points like `depositAndBridge`, the vbToken handles minting and routes the newly issued shares through the selected bridge adapter.
60+
61+
### VaultBridgeTokenPart2
62+
63+
VaultBridgeTokenPart2 augments the base vault with operational controls. It exposes functions for reserve rebalancing, scheduled yield collection, and administrative parameter changes. During migrations, Part2 mints the vbTokens corresponding to the returned backing and locks them on the appropriate Layer&nbsp;Y bridge, keeping cross-network supply balanced. The module also accepts donations—both for general yield distribution and for topping up the migration fee fund when bridging fee-on-transfer assets.
64+
65+
### MigrationManager (singleton)
66+
67+
MigrationManager lives on Ethereum and acts as the trusted orchestrator for any Native Converter. It maintains the mapping between Layer&nbsp;Y converters, their corresponding vbTokens, and the underlying collateral. When a converter bridges backing home, the manager consumes the accompanying message or proof, verifies the mapping, and finalizes the migration. If the collateral arrives as a native gas token, MigrationManager wraps it into the ERC‑20 representation (e.g., WETH) before completing the handoff.
68+
69+
## Layer Y Components
70+
71+
### Bridge Adapters
72+
73+
- **Agglayer Bridge**
74+
- Canonical path for production deployments.
75+
- Tracks exit roots, processes `bridgeAsset`, and exposes claim APIs.
76+
- Works with any network onboarded to the Agglayer unified bridge.
77+
78+
- **Hyperlane Yield Routes**
79+
- Maintains vbToken collateral on Sepolia, issues synthetic HypERC20s on partner chains (e.g., Polygon Amoy, Optimism Sepolia).
80+
- Uses Hyperlane Mailboxes and Interchain Gas Paymasters to relay messages.
81+
- Mailbox security dictates blast radius; see [Hyperlane Route](../routes/hyperlane.md) for specifics.
82+
83+
### Custom Token (optional)
84+
85+
Custom Token is an ERC‑20 with permit deployed on Layer&nbsp;Y that mirrors the decimal precision of the original underlying. Minting and burning rights are restricted to the bridge adapter and the Native Converter, ensuring supply changes always align with collateral movements. Projects typically deploy a Custom Token when they want a first-class vbToken representation rather than reusing generic bridge wrappers.
86+
87+
### Native Converter (optional)
88+
89+
The Native Converter is a pseudo ERC‑4626 vault that lives on Layer&nbsp;Y. It holds the bridged version of the underlying asset and issues the local Custom Token 1:1, giving users a way to move into and out of vbTokens without touching Ethereum. Internally it tracks a backing ledger so operators know how much collateral can be migrated back to Layer&nbsp;X at any time. Deposits can use permit flows, deconversions can bridge assets to other networks, and periodic migrations keep Layer&nbsp;Y liquidity synced with the main vault through MigrationManager.
90+
91+
## Optional Modules & Standards
92+
93+
### Bridged USDC Standard
94+
95+
vbUSDC supports Circle’s [Bridged USDC Standard](https://www.circle.com/blog/bridged-usdc-standard). By adopting the interface and lifecycle requirements upfront, Vault Bridge chains can upgrade to Circle-native USDC without forcing users through manual migrations. Behind the scenes, the same migration tooling moves balances between representations while preserving 1:1 backing.
96+
97+
### Yield Routing Integrations
98+
99+
Bridge adapters are pluggable. Agglayer and Hyperlane are live today, and additional transports can be onboarded without touching Layer&nbsp;X contracts. Regardless of the route, adapters must enforce the invariant that remote supply mirrors underlying collateral on Ethereum—any deviation triggers migration workflows or pause procedures.
100+
101+
## Operational Considerations
102+
103+
**Monitoring** should extend across both layers: watch `BridgeEvent`, `Deposit`, `Withdraw`, and `MigrationCompleted` logs, and maintain dashboards for reserve ratios and yield vault balances.
104+
**Security controls** rely on pauser roles across vbTokens, Native Converters, and bridge adapters, backed by safeguards such as `yieldVaultMaximumSlippagePercentage` and solvency checks that prevent unhealthy vault interactions.
105+
**Documentation links** worth bookmarking include [Assets & Vaults](../reference/assets-and-vaults.md), the [Agglayer Route](../routes/agglayer.md), the [Hyperlane Route](../routes/hyperlane.md), and the [Native Converter guide](native-converter.md).
106+
107+
## Roadmap
108+
109+
- Expand transport support beyond Agglayer + Hyperlane to additional EVM and non-EVM ecosystems.
110+
- Standardize health dashboards and on-call runbooks for operators.
111+
- Continue refining migration automation so Layer&nbsp;Y liquidity self-rebalances with minimal human intervention.
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
title: Native Converter Integration
3+
---
4+
5+
<!-- Page Header Component -->
6+
<h1 style="text-align: left; font-size: 38px; font-weight: 700; font-family: 'Inter Tight', sans-serif;">
7+
Native Converter Integration
8+
</h1>
9+
10+
<div style="text-align: left; margin: 0.5rem 0;">
11+
<p style="font-size: 18px; color: #666; max-width: 600px; margin: 0;">
12+
Enable local vbToken conversion on L2 without bridging to Ethereum
13+
</p>
14+
</div>
15+
16+
## Overview
17+
18+
The Native Converter is an optional Layer&nbsp;Y component that upgrades the user experience. Instead of bridging back to Ethereum every time they want to access yield, users can swap local bridged assets (such as bridged USDC) directly into vbTokens, or deconvert back to the local asset when they need liquidity. The diagrams below illustrate the difference between operating with and without a converter.
19+
20+
**Without Native Converter:**
21+
22+
```mermaid
23+
flowchart TD
24+
subgraph Layer_2
25+
direction TB
26+
A[User has bridged USDC on L2]
27+
D[Bridge vbUSDC back to L2]
28+
E[Receive vbUSDC on L2]
29+
F[Total time 40-60 minutes<br/>Two bridge transactions]
30+
end
31+
32+
subgraph Layer_1
33+
direction TB
34+
B[Bridge USDC to Ethereum]
35+
C[Deposit to VaultBridgeToken]
36+
end
37+
38+
A --> B
39+
B --> C
40+
C --> D
41+
D --> E
42+
E --> F
43+
```
44+
45+
**With Native Converter:**
46+
47+
```mermaid
48+
flowchart LR
49+
subgraph Layer_2
50+
direction LR
51+
A2[User has bridged USDC on L2] --> B2[Call convert on Native Converter]
52+
B2 --> C2[Receive vbUSDC instantly on L2]
53+
end
54+
```
55+
56+
## How Native Converter Works
57+
58+
### Core Concept
59+
60+
At its core, the converter keeps a backing pool of the bridged underlying token on Layer&nbsp;Y. When users convert, the contract mints Custom Tokens (or bridged vbTokens) 1:1 against that pool. Periodically, operators call `migrateBackingToLayerX()`, which bridges the accumulated backing to Ethereum, hands it to the MigrationManager, and deposits it into the VaultBridgeToken so the assets continue earning yield. The process is summarized below.
61+
62+
```mermaid
63+
flowchart TD
64+
subgraph Layer_2
65+
A[User on L2<br/>Has bridged USDC] --> B[Native Converter<br/>convert]
66+
B --> C[Mint vbToken]
67+
C --> D[User receives vbToken on L2]
68+
D -->|Later| E[Native Converter<br/>migrateBackingToLayerX]
69+
end
70+
subgraph Layer_1
71+
E --> F[Bridge underlying to L1]
72+
F --> G[Migration Manager]
73+
G --> H[Deposit backing into VaultBridgeToken]
74+
H --> I[Yield generated in L1 vault]
75+
end
76+
```
77+
78+
### Components
79+
80+
The Layer&nbsp;Y `NativeConverter` contract owns the conversion logic, while the Layer&nbsp;X `MigrationManager` finalizes migrations and updates vbToken supply. Together they keep local liquidity aligned with the vault’s collateral on Ethereum.
81+
82+
## Using Native Converter
83+
84+
### Convert & Deconvert
85+
86+
```solidity
87+
// SPDX-License-Identifier: MIT
88+
pragma solidity ^0.8.20;
89+
90+
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
91+
92+
interface INativeConverter {
93+
function convert(uint256 assets, address receiver) external returns (uint256 shares);
94+
function deconvert(uint256 shares, address receiver) external returns (uint256 assets);
95+
function maxDeconvert(address owner) external view returns (uint256);
96+
}
97+
98+
/// @title VbTokenVault
99+
/// @notice Simple vault that uses Native Converter for yield access
100+
contract VbTokenVault {
101+
IERC20 public immutable underlyingToken;
102+
IERC20 public immutable vbToken;
103+
INativeConverter public immutable nativeConverter;
104+
105+
mapping(address => uint256) public userShares;
106+
uint256 public totalShares;
107+
108+
event Deposited(address indexed user, uint256 underlyingAmount, uint256 shares);
109+
event Withdrawn(address indexed user, uint256 shares, uint256 underlyingAmount);
110+
111+
constructor(
112+
address _underlyingToken,
113+
address _vbToken,
114+
address _nativeConverter
115+
) {
116+
underlyingToken = IERC20(_underlyingToken);
117+
vbToken = IERC20(_vbToken);
118+
nativeConverter = INativeConverter(_nativeConverter);
119+
}
120+
121+
/// @notice Deposit underlying and convert to vbToken
122+
function deposit(uint256 amount) external {
123+
// Take underlying from user
124+
underlyingToken.transferFrom(msg.sender, address(this), amount);
125+
126+
// Convert to vbToken via Native Converter
127+
underlyingToken.approve(address(nativeConverter), amount);
128+
uint256 shares = nativeConverter.convert(amount, address(this));
129+
130+
// Track user's share
131+
userShares[msg.sender] += shares;
132+
totalShares += shares;
133+
134+
emit Deposited(msg.sender, amount, shares);
135+
}
136+
137+
/// @notice Withdraw by deconverting vbToken back to underlying
138+
function withdraw(uint256 shares) external {
139+
require(userShares[msg.sender] >= shares, "Insufficient balance");
140+
141+
// Check if deconversion is possible
142+
uint256 maxDeconvertable = nativeConverter.maxDeconvert(address(this));
143+
require(shares <= maxDeconvertable, "Insufficient backing on L2");
144+
145+
// Approve and deconvert
146+
vbToken.approve(address(nativeConverter), shares);
147+
uint256 assets = nativeConverter.deconvert(shares, msg.sender);
148+
149+
// Update tracking
150+
userShares[msg.sender] -= shares;
151+
totalShares -= shares;
152+
153+
emit Withdrawn(msg.sender, shares, assets);
154+
}
155+
156+
/// @notice Check user's vbToken balance
157+
function balanceOf(address user) external view returns (uint256) {
158+
return userShares[user];
159+
}
160+
}
161+
```
162+

0 commit comments

Comments
 (0)