Asset Manager
Overview
This document outlines the design for a hub-and-spoke asset management system that enables cross-network asset transfers with optional execution of additional logic. The system consists of a central Hub Asset Manager (in Solidity) and multiple Spoke Asset Managers that can be implemented in any language/platform.
Hub Asset Manager
System Design
Core Components
The hub asset manager maintains several key components:
Connection Module: Handles cross-chain message verification
Wallet Factory: Generates deterministic user wallets on the hub chain
Asset Tokens: Manages wrapped versions of spoke chain assets
Network Mappings: Maps spoke chain asset managers and their assets
State Variables
IConnection public connection; // Cross-chain messaging
IWalletFactory public walletFactory; // User wallet management
address public assetImplementation; // Asset token implementation
mapping(uint256 => bytes) public spokeAssetManager; // Authorized spoke managers
mapping(uint256 => mapping(bytes => address)) public assets; // Spoke assets to hub tokens
Transfer Data Structure
struct Transfer {
bytes token; // Original token address on source chain
bytes from; // Sender address on source chain
bytes to; // Recipient address on destination chain
uint256 amount; // Amount to transfer
bytes data; // Optional execution data
}
Core Operations
Receiving Cross-Chain Transfers
function recvMessage(
uint256 nonce,
uint256 srcChainId,
bytes calldata srcAddress,
bytes memory payload,
bytes[] memory signatures
) external {
// Verify the sender is authorized
require(keccak256(srcAddress) == keccak256(spokeAssetManager[srcChainId]));
// Verify cross-chain message
connection.verifyMessage(srcChainId, srcAddress, payload, signatures);
Transfer memory _transfer = payload.decode();
// Mint wrapped tokens
address token = assets[srcChainId][_transfer.token];
IAssetToken(token).mintTo(_transfer.to.toAddress(), _transfer.amount);
// Execute optional actions through user's wallet
if (_transfer.data.length > 0) {
address wallet = walletFactory.getWallet(srcChainId, _transfer.from);
IWallet(wallet).assetManagerHook(_transfer.data);
}
}
Initiating Cross-Chain Transfers
function transfer(
address token,
bytes calldata to,
uint256 amount,
bytes calldata data
) external payable {
// Burn wrapped tokens on hub
AssetInfo memory info = assetInfo[token];
IAssetToken(token).burnFrom(msg.sender, amount);
// Construct transfer message
Transfer memory _transfer = Transfer(
info.spokeAddress,
msg.sender.toBytes(),
to,
amount,
data
);
// Send message to spoke chain
bytes memory manager = spokeAssetManager[info.chainID];
connection.sendMessage{value:msg.value}(
info.chainID,
manager,
_transfer.encode()
);
}
Spoke Asset Manager Specification
Required Implementation
Spoke chains must implement an asset manager that can:
Receive and verify cross-chain messages from the hub
Lock/unlock native assets
Send properly formatted messages to the hub
Enforce rate limits on withdrawals
Required Functions
Receive Message
// Implementation language may vary
function recvMessage(
sourceChainId: number,
sourceAddress: Bytes,
connSn: number,
payload: Bytes,
signatures: Bytes[]
): void {
// 1. Verify message is from hub
// 2. Decode transfer data
// 3. Verify withdrawal is within rate limits
// 4. Release locked tokens to recipient
// 5. Execute any additional logic in data
}
Send Transfer
// Implementation language may vary
function transfer(
token: Address,
recipient: Bytes,
amount: BigInt,
data: Bytes
): void {
// 1. Lock tokens
// 2. Construct transfer message
// 3. Send message to hub
}
Security Considerations
Hub Chain
Only authorized spoke managers can send messages
Asset tokens must be properly wrapped/unwrapped
Wallet hooks must be properly validated
Spoke Chains
Must verify messages come from hub
Must properly lock/unlock native assets
Must implement proper access controls
Must enforce rate limits on withdrawals
Must use consistent function naming (recvMessage)
Cross-Chain
Asset mappings must be carefully managed
Withdrawal limits must be properly configured and enforced
Last updated