Technical Architecture
CCDM (Cross-chain Deposit Module)
Deposit on Ethereum Flow
// miAsset contract interface
interface IVault is IERC20 {
// deposit LRT
function deposit(uint256 amount, address receiver) external;
function deposit(uint256 amount, address receiver, bytes calldata permitData) external;
...
}
// EETH deposit helper contract
abstract contract EETHHelper {
function deposit(uint256 amount, address vault) external {
...
// wrap eETH to weETH
_deposit(_wrap(amount), vault);
}
// also support EIP-2612 permit
function deposit(uint256 amount, address receiver, bytes calldata permitData) external {};
...
}
If the deposit and mint happen on the same chain (L1, the Ethereum chain), the miAsset mint method is similar to that of the ERC-4626 Tokenized Vault. However, note that miAsset does not fully implement ERC-4626 until the strategy vault is implemented. miAsset is not a rebased token until then. Therefore, to deposit rebase tokens, users need to call the corresponding helper (e.g., EETHHelper), which wraps the tokens into c-token format before depositing them to the Mitosis Vault.
- The user calls
deposit()
. - The miAsset contract calls ERC20's
_mint()
.- The receiver is the address of the miAsset receiver.
Redeem Flow
// miAsset contract interface
interface IVault is IERC20 {
// redeem miAsset
function redeem(uint256 amount) external;
// claim asset(LRT)
function claim(uint256 amount, address receiver) external;
...
}
- The user calls
redeem()
. - After the optional unstaking period, the user calls
claim()
. - The miAsset contract calls ERC20's
_burn()
.
CCDM Mint Flow
interface ICCDMHost {
// deposit L1 token and mint miAsset on L2
function deposit(uint32 domain, address token, address receiver, address refundTo, uint256 amount)
external
payable;
function deposit(
uint32 domain,
address token,
address receiver,
address refundTo,
uint256 amount,
bytes calldata permitData
) external payable;
...
}
interface ICCDMClient {
// Hyperlane message processor
function handle(uint32 origin, bytes32 sender, bytes calldata message) external payable;
...
}
CCDM Host is the L1 side and CCDM Client is the L2 side.
CCDM improves UX by enabling users to deposit assets on L2s directly with their assets on Ethereum. CCDM does not support rebase assets just like the deposit on L1 explained above. To deposit rebase tokens, users need to call depositTo
in the corresponding helper (e.g., EETHHelper) that wraps the tokens into c-token format before depositing them to the Mitosis Vault.
- The user calls
deposit()
in CCDMHost. - The CCDMHost calls
dispatch()
to pass the message to L2 through Hyperlane. - Hyperlane relays the message.
- Once the message is validated and finalized, Hyperlane Mailbox calls
handle()
in CCDMClient. - The CCDMClient calls miAsset's
manualDeposit()
byhandle()
. - The miAsset contract calls
_mint()
.handle()
function is the official L2 message handler in Hyperlane protocol.
CCDM Bridge Flow
interface ICCDMClient {
// dispatch MsgBridge for asset bridging
function adjust() external payable;
...
}
interface ICCDMHost {
// Hyperlane message processor
function handle(uint32 _origin, bytes32 _sender, bytes calldata _message) external payable;
...
}
// wrapped canonical bridge call
interface IBridgeAdapter {
// bridge asset by canonical bridge
// e.g.) Arbitrum Gateway's `outboundTransfer`
function bridgeAsset(address destAddr, address l1Asset, address, uint256 amount) external;
...
}
Minting miAssets on L2s and bridging the original assets to corresponding L2s happen asynchronously. While minting happens immediately, bridging is postponed so users can save on the bridging fee and gas cost. Mitosis batches the transactions and leverages the canonical bridge of each L2 to bridge the assets. BridgeAdapter handles the MsgBridge to dispatch dispatched by CCDMClient on CCDMHost.
- When a certain point is reached, CCDMClient's
adjust()
is called. - CCDMClient calls
dispatch()
to notify L1 that miAsset is minted. Hyperlane relays MsgBridge from L2 to L1. - CCDMHost calls BridgeAdapter's
bridgeAsset()
so BridgeAdapter can handle the MsgBridge. - BridgeAdapter calls each chain’s canonical bridge’s bridging function.
With CCDM's semantic batching, users do not need to call deposit()
every time they deposit.