Collatinator Technical Details
The Collatinator Facet is a core component of the Vaultinator Protocol that provides collateralized lending functionality. This document outlines the technical implementation details, including the contract architecture, function specifications, storage layout, and security considerations.
Contract Architecture
The Collatinator Facet follows the Diamond Standard (EIP-2535) pattern and is implemented as a facet that can be added to the Vaultinator Diamond. It interacts with various lending protocols through a standardized adapter pattern.
Class Diagram
┌─────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ VaultinatorFacet│◄─────┤ CollatinatorFacet│─────►│ YieldinatorFacet │
└─────────────────┘ └───────────────────┘ └───────────────────┘
▲ │ ▲
│ │ │
│ ▼ │
┌─────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ DiamondStorage │◄─────┤CollatinatorStorage│─────►│StakinatorFacet │
└─────────────────┘ └───────────────────┘ └───────────────────┘
│
▼
┌───────────────────┐
│ AdapterRegistry │
└───────────────────┘
│
▼
┌───────────────────┐
│ Lending Adapters │
└───────────────────┘
│
▼
┌───────────────────┐
│ Lending Protocols │
└───────────────────┘Component Interaction
Collatinator Facet: The main contract that implements the collateralized lending functionality
Adapter Registry: A registry of lending protocol adapters that the Collatinator can use
Lending Adapters: Standardized adapters for interacting with different lending protocols
Lending Protocols: External protocols that provide collateralized lending services
Function Specifications
Protocol Management
function registerProtocol(address adapter) external returns (bool)Registers a new lending protocol adapter in the Collatinator.
Parameters:
adapter: The address of the lending protocol adapter
Returns:
boolindicating successAccess Control: Only administrators can call this function
Events Emitted:
ProtocolRegistered(address indexed adapter, string name)
function deregisterProtocol(address adapter) external returns (bool)Deregisters a lending protocol adapter from the Collatinator.
Parameters:
adapter: The address of the lending protocol adapter
Returns:
boolindicating successAccess Control: Only administrators can call this function
Events Emitted:
ProtocolDeregistered(address indexed adapter)
function getProtocols() external view returns (address[] memory)Gets a list of all registered lending protocol adapters.
Returns: An array of lending protocol adapter addresses
Access Control: Anyone can call this function
Position Management
function createPosition(
address protocol,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount
) external returns (uint256)Creates a new collateralized position.
Parameters:
protocol: The address of the lending protocol adaptercollateralAsset: The address of the collateral assetcollateralAmount: The amount of collateral to depositdebtAsset: The address of the debt assetdebtAmount: The amount of debt to borrow
Returns: The ID of the created position
Access Control: Anyone can call this function
Events Emitted:
PositionCreated(uint256 indexed positionId, address indexed owner, address protocol, address collateralAsset, uint256 collateralAmount, address debtAsset, uint256 debtAmount)
function addCollateral(uint256 positionId, uint256 amount) external returns (bool)Adds collateral to an existing position.
Parameters:
positionId: The ID of the positionamount: The amount of collateral to add
Returns:
boolindicating successAccess Control: Only the position owner can call this function
Events Emitted:
CollateralAdded(uint256 indexed positionId, uint256 amount)
function removeCollateral(uint256 positionId, uint256 amount) external returns (bool)Removes collateral from an existing position.
Parameters:
positionId: The ID of the positionamount: The amount of collateral to remove
Returns:
boolindicating successAccess Control: Only the position owner can call this function
Events Emitted:
CollateralRemoved(uint256 indexed positionId, uint256 amount)
function increaseBorrow(uint256 positionId, uint256 amount) external returns (bool)Increases the borrowed amount of an existing position.
Parameters:
positionId: The ID of the positionamount: The amount to increase the borrow by
Returns:
boolindicating successAccess Control: Only the position owner can call this function
Events Emitted:
BorrowIncreased(uint256 indexed positionId, uint256 amount)
function repayBorrow(uint256 positionId, uint256 amount) external returns (bool)Repays part or all of the borrowed amount of an existing position.
Parameters:
positionId: The ID of the positionamount: The amount to repay
Returns:
boolindicating successAccess Control: Only the position owner can call this function
Events Emitted:
BorrowRepaid(uint256 indexed positionId, uint256 amount)
function closePosition(uint256 positionId) external returns (bool)Closes an existing position by repaying all debt and withdrawing all collateral.
Parameters:
positionId: The ID of the position
Returns:
boolindicating successAccess Control: Only the position owner can call this function
Events Emitted:
PositionClosed(uint256 indexed positionId)
Vault Integration
function createPositionFromVault(
uint256 vaultId,
address protocol,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount
) external returns (uint256)Creates a new collateralized position using assets from a vault.
Parameters:
vaultId: The ID of the vaultprotocol: The address of the lending protocol adaptercollateralAsset: The address of the collateral assetcollateralAmount: The amount of collateral to depositdebtAsset: The address of the debt assetdebtAmount: The amount of debt to borrow
Returns: The ID of the created position
Access Control: Only vault owners or authorized users can call this function
Events Emitted:
VaultPositionCreated(uint256 indexed vaultId, uint256 indexed positionId, address protocol, address collateralAsset, uint256 collateralAmount, address debtAsset, uint256 debtAmount)
function addCollateralFromVault(uint256 vaultId, uint256 positionId, uint256 amount) external returns (bool)Adds collateral to an existing position using assets from a vault.
Parameters:
vaultId: The ID of the vaultpositionId: The ID of the positionamount: The amount of collateral to add
Returns:
boolindicating successAccess Control: Only vault owners or authorized users can call this function
Events Emitted:
VaultCollateralAdded(uint256 indexed vaultId, uint256 indexed positionId, uint256 amount)
function repayBorrowToVault(uint256 vaultId, uint256 positionId, uint256 amount) external returns (bool)Repays part or all of the borrowed amount of an existing position and sends the collateral to a vault.
Parameters:
vaultId: The ID of the vaultpositionId: The ID of the positionamount: The amount to repay
Returns:
boolindicating successAccess Control: Only vault owners or authorized users can call this function
Events Emitted:
VaultBorrowRepaid(uint256 indexed vaultId, uint256 indexed positionId, uint256 amount)
Information and Metrics
function getPosition(uint256 positionId) external view returns (Position memory)Gets information about a position.
Parameters:
positionId: The ID of the position
Returns: A
Positionstruct containing information about the positionAccess Control: Anyone can call this function
function getHealthFactor(uint256 positionId) external view returns (uint256)Gets the health factor of a position.
Parameters:
positionId: The ID of the position
Returns: The health factor of the position (scaled by 1e18)
Access Control: Anyone can call this function
function getLiquidationThreshold(address protocol, address collateralAsset) external view returns (uint256)Gets the liquidation threshold for a collateral asset in a protocol.
Parameters:
protocol: The address of the lending protocol adaptercollateralAsset: The address of the collateral asset
Returns: The liquidation threshold (scaled by 1e18)
Access Control: Anyone can call this function
function getMaxLTV(address protocol, address collateralAsset) external view returns (uint256)Gets the maximum loan-to-value ratio for a collateral asset in a protocol.
Parameters:
protocol: The address of the lending protocol adaptercollateralAsset: The address of the collateral asset
Returns: The maximum LTV (scaled by 1e18)
Access Control: Anyone can call this function
function getBorrowRate(address protocol, address debtAsset) external view returns (uint256)Gets the borrow rate for a debt asset in a protocol.
Parameters:
protocol: The address of the lending protocol adapterdebtAsset: The address of the debt asset
Returns: The borrow rate in basis points (1/100 of a percent)
Access Control: Anyone can call this function
function getSupplyRate(address protocol, address collateralAsset) external view returns (uint256)Gets the supply rate for a collateral asset in a protocol.
Parameters:
protocol: The address of the lending protocol adaptercollateralAsset: The address of the collateral asset
Returns: The supply rate in basis points (1/100 of a percent)
Access Control: Anyone can call this function
Emergency Operations
function emergencyRepay(uint256 positionId) external returns (bool)Performs an emergency repayment of a position to prevent liquidation.
Parameters:
positionId: The ID of the position
Returns:
boolindicating successAccess Control: Only the position owner can call this function
Events Emitted:
EmergencyRepaid(uint256 indexed positionId)
function pause() external returns (bool)Pauses all Collatinator operations.
Returns:
boolindicating successAccess Control: Only administrators can call this function
Events Emitted:
CollatinatorPaused(address indexed admin)
function unpause() external returns (bool)Unpauses all Collatinator operations.
Returns:
boolindicating successAccess Control: Only administrators can call this function
Events Emitted:
CollatinatorUnpaused(address indexed admin)
Storage Layout
The Collatinator Facet uses the Diamond Storage pattern to store its state. The storage layout is defined in the LibCollatinatorStorage library.
library LibCollatinatorStorage {
bytes32 constant COLLATINATOR_STORAGE_POSITION = keccak256("collatinator.core.storage");
struct CollatinatorStorage {
// Position management
mapping(uint256 => Position) positions;
mapping(address => uint256[]) userPositions;
uint256 nextPositionId;
// Protocol registry
mapping(address => Protocol) protocols;
address[] protocolList;
// Protocol configuration
mapping(address => bool) approvedAdapters;
// Protocol metrics
mapping(address => uint256) protocolTVL;
uint256 totalValueLocked;
// Reentrancy guard
uint256 reentrancyStatus;
// Pause status
bool paused;
}
struct Position {
uint256 id;
address owner;
address protocol;
address collateralAsset;
uint256 collateralAmount;
address debtAsset;
uint256 debtAmount;
uint256 createdAt;
bool active;
}
struct Protocol {
address adapter;
string name;
bool active;
uint256 registeredAt;
}
function collatinatorStorage() internal pure returns (CollatinatorStorage storage ds) {
bytes32 position = COLLATINATOR_STORAGE_POSITION;
assembly {
ds.slot := position
}
}
}Events
The Collatinator Facet emits the following events:
event ProtocolRegistered(address indexed adapter, string name);
event ProtocolDeregistered(address indexed adapter);
event PositionCreated(uint256 indexed positionId, address indexed owner, address protocol, address collateralAsset, uint256 collateralAmount, address debtAsset, uint256 debtAmount);
event CollateralAdded(uint256 indexed positionId, uint256 amount);
event CollateralRemoved(uint256 indexed positionId, uint256 amount);
event BorrowIncreased(uint256 indexed positionId, uint256 amount);
event BorrowRepaid(uint256 indexed positionId, uint256 amount);
event PositionClosed(uint256 indexed positionId);
event VaultPositionCreated(uint256 indexed vaultId, uint256 indexed positionId, address protocol, address collateralAsset, uint256 collateralAmount, address debtAsset, uint256 debtAmount);
event VaultCollateralAdded(uint256 indexed vaultId, uint256 indexed positionId, uint256 amount);
event VaultBorrowRepaid(uint256 indexed vaultId, uint256 indexed positionId, uint256 amount);
event EmergencyRepaid(uint256 indexed positionId);
event CollatinatorPaused(address indexed admin);
event CollatinatorUnpaused(address indexed admin);Security Considerations
Reentrancy Protection
The Collatinator Facet uses a reentrancy guard to prevent reentrancy attacks. All external functions that interact with other contracts are protected by the reentrancy guard.
modifier nonReentrant() {
LibCollatinatorStorage.CollatinatorStorage storage s = LibCollatinatorStorage.collatinatorStorage();
require(s.reentrancyStatus != 2, "ReentrancyGuard: reentrant call");
s.reentrancyStatus = 2;
_;
s.reentrancyStatus = 1;
}Access Control
The Collatinator Facet uses role-based access control to restrict access to certain functions. The access control is implemented through the Vaultinator Facet.
modifier onlyAdmin() {
require(LibVaultinatorStorage.vaultinatorStorage().hasRole(msg.sender, "admin"), "CollatinatorFacet: not admin");
_;
}
modifier onlyPositionOwner(uint256 positionId) {
require(LibCollatinatorStorage.collatinatorStorage().positions[positionId].owner == msg.sender, "CollatinatorFacet: not position owner");
_;
}
modifier onlyVaultOwner(uint256 vaultId) {
require(LibVaultinatorStorage.vaultinatorStorage().vaults[vaultId].owner == msg.sender, "CollatinatorFacet: not vault owner");
_;
}Pause Mechanism
The Collatinator Facet includes a pause mechanism that allows administrators to pause all operations in case of an emergency.
modifier whenNotPaused() {
require(!LibCollatinatorStorage.collatinatorStorage().paused, "CollatinatorFacet: paused");
_;
}
function pause() external onlyAdmin returns (bool) {
LibCollatinatorStorage.CollatinatorStorage storage s = LibCollatinatorStorage.collatinatorStorage();
require(!s.paused, "CollatinatorFacet: already paused");
s.paused = true;
emit CollatinatorPaused(msg.sender);
return true;
}
function unpause() external onlyAdmin returns (bool) {
LibCollatinatorStorage.CollatinatorStorage storage s = LibCollatinatorStorage.collatinatorStorage();
require(s.paused, "CollatinatorFacet: not paused");
s.paused = false;
emit CollatinatorUnpaused(msg.sender);
return true;
}Health Factor Monitoring
The Collatinator Facet includes health factor monitoring to prevent liquidations. When a position's health factor drops below a certain threshold, the contract can take action to prevent liquidation.
function monitorHealthFactor(uint256 positionId) internal view returns (bool) {
uint256 healthFactor = getHealthFactor(positionId);
uint256 threshold = 1.05e18; // 105%
return healthFactor >= threshold;
}
function autoRebalancePosition(uint256 positionId) external nonReentrant whenNotPaused onlyPositionOwner(positionId) returns (bool) {
// Implementation details...
// Check if position needs rebalancing
// Rebalance position by adding collateral or repaying debt
// More implementation details...
return true;
}Slippage Protection
The Collatinator Facet includes slippage protection for token exchanges. When creating or modifying positions, users can specify a minimum amount to receive or a maximum amount to pay.
function createPositionWithSlippage(
address protocol,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount,
uint256 minDebtAmount
) external nonReentrant whenNotPaused returns (uint256) {
// Implementation details...
require(actualDebtAmount >= minDebtAmount, "CollatinatorFacet: slippage too high");
// More implementation details...
return positionId;
}Emergency Repayment
The Collatinator Facet includes an emergency repayment function that allows users to repay their debt in case of an emergency, bypassing some of the normal checks.
function emergencyRepay(uint256 positionId) external nonReentrant onlyPositionOwner(positionId) returns (bool) {
// Implementation details...
// This function bypasses the pause check and some other checks
// More implementation details...
emit EmergencyRepaid(positionId);
return true;
}Integration with Other Facets
The Collatinator Facet integrates with other facets in the Vaultinator Protocol:
Vaultinator Facet: For vault management and access control
Yieldinator Facet: For using yield-generating assets as collateral
Stakinator Facet: For staking collateral assets
Vaultinator Integration
function createPositionFromVault(
uint256 vaultId,
address protocol,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount
) external nonReentrant whenNotPaused onlyVaultOwner(vaultId) returns (uint256) {
// Implementation details...
// Transfer assets from vault to this contract
// Create position
// Update vault balance
// More implementation details...
emit VaultPositionCreated(vaultId, positionId, protocol, collateralAsset, collateralAmount, debtAsset, debtAmount);
return positionId;
}Yieldinator Integration
function createPositionWithYield(
address protocol,
address yieldAdapter,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount
) external nonReentrant whenNotPaused returns (uint256) {
// Implementation details...
// Deposit collateral to yield adapter
// Use yield-generating asset as collateral
// Create position
// More implementation details...
return positionId;
}Stakinator Integration
function createPositionWithStaking(
address protocol,
address stakingPool,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount
) external nonReentrant whenNotPaused returns (uint256) {
// Implementation details...
// Stake collateral
// Use staked asset as collateral
// Create position
// More implementation details...
return positionId;
}Multi-Chain Support
The Collatinator Facet includes support for cross-chain collateral management, allowing users to create positions that span multiple blockchains.
Cross-Chain Position Creation
function createCrossChainPosition(
uint256 sourceChainId,
uint256 targetChainId,
address protocol,
address collateralAsset,
uint256 collateralAmount,
address debtAsset,
uint256 debtAmount
) external nonReentrant whenNotPaused returns (uint256) {
// Implementation details...
// Bridge collateral to target chain
// Create position on target chain
// More implementation details...
return positionId;
}Cross-Chain Collateral Management
function addCrossChainCollateral(
uint256 positionId,
uint256 sourceChainId,
uint256 targetChainId,
uint256 amount
) external nonReentrant whenNotPaused onlyPositionOwner(positionId) returns (bool) {
// Implementation details...
// Bridge collateral to target chain
// Add collateral to position on target chain
// More implementation details...
return true;
}Cross-Chain Debt Management
function increaseCrossChainBorrow(
uint256 positionId,
uint256 sourceChainId,
uint256 targetChainId,
uint256 amount
) external nonReentrant whenNotPaused onlyPositionOwner(positionId) returns (bool) {
// Implementation details...
// Increase borrow on target chain
// Bridge borrowed assets to source chain
// More implementation details...
return true;
}Supported Lending Protocols
The Collatinator Facet supports multiple lending protocols through its adapter pattern:
Sky.money (formerly MakerDAO): Decentralized stablecoin lending
Aave: Liquidity protocol for lending and borrowing
Compound: Algorithmic money market protocol
Euler Finance: Permissionless lending protocol
Benqi: Liquidity market protocol on Avalanche
Solend: Lending protocol on Solana
Each protocol has its own adapter that implements the ILendingAdapter interface, providing a consistent API for interacting with different protocols.
Conclusion
The Collatinator Facet is a powerful component of the Vaultinator Protocol that enables users to create and manage collateralized positions across multiple lending protocols. Its modular design, security features, and integration with other facets make it a flexible and robust solution for collateralized lending.