Vaultinator Facet Overview
The Vaultinator Facet serves as the core component of the Vaultinator Protocol, providing fundamental vault management functionality and coordinating interactions between specialized facets.
Architecture
The Vaultinator Facet follows a modular architecture that enables seamless integration with other facets while maintaining a clear separation of concerns:
┌─────────────────────────────────────────────────────────────┐
│ Diamond Contract │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────┴───────────┐
│ │
┌───────────────▼───────────┐ ┌───────▼───────────────┐
│ Vaultinator Facet │ │ Specialized Facets │
│ (Core Functionality) │ │ │
│ │ │ ┌─────────────────┐ │
│ - Vault Management │◄──┼──┤ Yieldinator │ │
│ - Asset Management │ │ └─────────────────┘ │
│ - Access Control │ │ ┌─────────────────┐ │
│ - Cross-Facet Coordination◄──┼──┤ Collatinator │ │
│ - Protocol Administration│ │ └─────────────────┘ │
│ │ │ ┌─────────────────┐ │
└───────────────────────────┘ │ │ Stakinator │ │
│ └─────────────────┘ │
└───────────────────────┘Core Components
1. Vault System
The vault system is the foundation of the Vaultinator Protocol, providing secure storage and management of digital assets:
Vault Types:
Personal Vaults: Single-user vaults for individual asset management
Shared Vaults: Multi-user vaults with configurable access control
Institutional Vaults: Enterprise-grade vaults with advanced features
Vault Configuration:
Customizable vault parameters
Strategy assignment for automated asset management
Fee settings and distribution rules
2. Asset Management System
The asset management system handles all operations related to assets within vaults:
Supported Asset Types:
ERC-20 tokens (fungible tokens)
ERC-721 tokens (non-fungible tokens)
ERC-1155 tokens (semi-fungible tokens)
Native ETH (with automatic wrapping/unwrapping)
Asset Operations:
Secure deposit mechanisms
Controlled withdrawal processes
Inter-vault transfers
Asset swaps and exchanges
3. Access Control System
The access control system ensures that only authorized users can perform specific actions:
Role-Based Access Control:
Predefined roles (OWNER, MANAGER, DEPOSITOR, WITHDRAWER)
Custom role creation and assignment
Role hierarchy and inheritance
Multi-Signature Authorization:
Configurable signature thresholds
Time-locked execution for critical operations
Signature verification and validation
4. Cross-Facet Coordination
The cross-facet coordination system enables seamless interaction between different facets:
Facet Registry:
Central registry of active facets
Facet capability discovery
Version tracking and compatibility checking
Inter-Facet Communication:
Standardized message passing
Event-based notifications
Callback mechanisms for complex operations
5. Protocol Administration
The protocol administration system provides tools for managing the protocol:
Fee Management:
Configurable fee structures
Automated fee collection
Fee distribution to stakeholders
Protocol Parameters:
Global configuration settings
Facet-specific parameters
Upgrade controls and versioning
Implementation Details
Storage Layout
The Vaultinator Facet uses a structured storage layout following the Diamond pattern:
struct VaultinatorStorage {
// Vault management
mapping(uint256 => Vault) vaults;
mapping(address => uint256[]) userVaults;
uint256 nextVaultId;
// Access control
mapping(uint256 => mapping(address => mapping(bytes32 => bool))) vaultRoles;
mapping(bytes32 => RoleDefinition) roleDefinitions;
// Protocol configuration
uint256 protocolFee;
bool paused;
address feeCollector;
// Facet registry
mapping(bytes4 => address) facetAddresses;
mapping(address => bytes4[]) facetFunctionSelectors;
address[] facetAddressList;
// Other storage variables
}Function Selectors
The Vaultinator Facet provides the following function selectors for Diamond registration:
// Vault management selectors
bytes4 constant CREATE_VAULT_SELECTOR = bytes4(keccak256("createVault(string,uint8)"));
bytes4 constant DEPOSIT_SELECTOR = bytes4(keccak256("deposit(uint256,address,uint256)"));
bytes4 constant WITHDRAW_SELECTOR = bytes4(keccak256("withdraw(uint256,address,uint256)"));
// Access control selectors
bytes4 constant GRANT_ACCESS_SELECTOR = bytes4(keccak256("grantAccess(uint256,address,bytes32)"));
bytes4 constant REVOKE_ACCESS_SELECTOR = bytes4(keccak256("revokeAccess(uint256,address,bytes32)"));
bytes4 constant HAS_ROLE_SELECTOR = bytes4(keccak256("hasRole(uint256,address,bytes32)"));
// Protocol administration selectors
bytes4 constant UPDATE_PROTOCOL_PARAMS_SELECTOR = bytes4(keccak256("updateProtocolParams(bytes)"));
bytes4 constant SET_PROTOCOL_FEE_SELECTOR = bytes4(keccak256("setProtocolFee(uint256)"));
bytes4 constant PAUSE_PROTOCOL_SELECTOR = bytes4(keccak256("pauseProtocol()"));
bytes4 constant UNPAUSE_PROTOCOL_SELECTOR = bytes4(keccak256("unpauseProtocol()"));Integration with Other Facets
Yieldinator Integration
The Vaultinator Facet integrates with the Yieldinator Facet to enable yield generation on vault assets:
function deployToYieldProtocol(
uint256 vaultId,
address asset,
uint256 amount,
address adapter
) external onlyVaultManager(vaultId) returns (bool) {
// Validate inputs
require(amount > 0, "Amount must be greater than zero");
require(asset != address(0), "Invalid asset address");
// Get storage
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
// Check if vault has sufficient assets
require(s.vaults[vaultId].assets[asset] >= amount, "Insufficient assets in vault");
// Reduce vault balance
s.vaults[vaultId].assets[asset] -= amount;
// Get Yieldinator facet
IYieldinatorFacet yieldinator = IYieldinatorFacet(address(this));
// Deploy to yield protocol
yieldinator.deposit(adapter, asset, amount);
// Record deployment
s.vaultYieldDeployments[vaultId][asset][adapter] += amount;
emit AssetsDeployedToYield(vaultId, asset, amount, adapter);
return true;
}Collatinator Integration
The Vaultinator Facet integrates with the Collatinator Facet to enable collateralized positions:
function createCollateralizedPosition(
uint256 vaultId,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount,
address protocol
) external onlyVaultManager(vaultId) returns (uint256 positionId) {
// Validate inputs
require(collateralAmount > 0, "Collateral amount must be greater than zero");
require(debtAmount > 0, "Debt amount must be greater than zero");
// Get storage
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
// Check if vault has sufficient collateral
require(s.vaults[vaultId].assets[collateralAsset] >= collateralAmount, "Insufficient collateral in vault");
// Reduce vault balance
s.vaults[vaultId].assets[collateralAsset] -= collateralAmount;
// Get Collatinator facet
ICollatinatorFacet collatinator = ICollatinatorFacet(address(this));
// Create collateralized position
positionId = collatinator.createPosition(
protocol,
collateralAsset,
collateralAmount,
debtAsset,
debtAmount
);
// Record position
s.vaultCollateralPositions[vaultId].push(positionId);
emit CollateralPositionCreated(vaultId, positionId, protocol);
return positionId;
}Stakinator Integration
The Vaultinator Facet integrates with the Stakinator Facet to enable staking:
function stakeVaultAssets(
uint256 vaultId,
address asset,
uint256 amount,
uint256 poolId,
uint256 lockDuration
) external onlyVaultManager(vaultId) returns (uint256 stakeId) {
// Validate inputs
require(amount > 0, "Amount must be greater than zero");
// Get storage
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
// Check if vault has sufficient assets
require(s.vaults[vaultId].assets[asset] >= amount, "Insufficient assets in vault");
// Reduce vault balance
s.vaults[vaultId].assets[asset] -= amount;
// Get Stakinator facet
IStakinatorFacet stakinator = IStakinatorFacet(address(this));
// Stake assets
stakeId = stakinator.stake(poolId, amount, lockDuration);
// Record stake
s.vaultStakes[vaultId].push(stakeId);
emit AssetsStaked(vaultId, asset, amount, poolId, stakeId);
return stakeId;
}Security Considerations
The Vaultinator Facet implements several security measures:
Access Control
All vault operations are protected by a role-based access control system:
modifier onlyVaultOwner(uint256 vaultId) {
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
require(s.vaults[vaultId].owner == msg.sender, "Not vault owner");
_;
}
modifier onlyVaultManager(uint256 vaultId) {
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
require(
s.vaults[vaultId].owner == msg.sender ||
s.vaultRoles[vaultId][msg.sender][MANAGER_ROLE],
"Not vault manager"
);
_;
}
modifier onlyRole(bytes32 role) {
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
require(s.globalRoles[msg.sender][role], "Missing required role");
_;
}Reentrancy Protection
All functions that interact with external contracts use reentrancy guards:
modifier nonReentrant() {
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
require(s.reentrancyStatus != ENTERED, "ReentrancyGuard: reentrant call");
s.reentrancyStatus = ENTERED;
_;
s.reentrancyStatus = NOT_ENTERED;
}Pausability
The protocol can be paused in emergency situations:
modifier whenNotPaused() {
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
require(!s.paused, "Protocol is paused");
_;
}
function pauseProtocol() external onlyRole(EMERGENCY_ROLE) {
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
s.paused = true;
emit ProtocolPaused(msg.sender);
}
function unpauseProtocol() external onlyRole(ADMIN_ROLE) {
LibVaultinatorStorage.VaultinatorStorage storage s = LibVaultinatorStorage.vaultinatorStorage();
s.paused = false;
emit ProtocolUnpaused(msg.sender);
}Event System
The Vaultinator Facet emits events for all significant actions to enable off-chain monitoring and indexing:
// Vault events
event VaultCreated(uint256 indexed vaultId, address indexed owner, string name, VaultType vaultType);
event Deposited(uint256 indexed vaultId, address indexed asset, uint256 amount, address depositor);
event Withdrawn(uint256 indexed vaultId, address indexed asset, uint256 amount, address recipient);
event VaultStrategyUpdated(uint256 indexed vaultId, address indexed strategy);
// Access control events
event AccessGranted(uint256 indexed vaultId, address indexed user, bytes32 indexed role);
event AccessRevoked(uint256 indexed vaultId, address indexed user, bytes32 indexed role);
// Protocol events
event ProtocolFeeUpdated(uint256 oldFee, uint256 newFee);
event ProtocolPaused(address operator);
event ProtocolUnpaused(address operator);
// Integration events
event AssetsDeployedToYield(uint256 indexed vaultId, address indexed asset, uint256 amount, address adapter);
event CollateralPositionCreated(uint256 indexed vaultId, uint256 indexed positionId, address protocol);
event AssetsStaked(uint256 indexed vaultId, address indexed asset, uint256 amount, uint256 poolId, uint256 stakeId);Future Enhancements
The Vaultinator Facet roadmap includes several planned enhancements:
Advanced Vault Strategies: Implementation of automated vault strategies for optimal asset allocation
Cross-Chain Vault Support: Extension of vault functionality to multiple blockchains
Vault Analytics: Enhanced reporting and analytics for vault performance
Vault Templates: Predefined vault configurations for common use cases
Social Recovery: Implementation of social recovery mechanisms for vault access