Data Models & Relationships
Overview
This document outlines the core data models in the L4VA system, their relationships, validation rules, and implementation details. Our data architecture supports vault management, governance processes, asset handling, and user interactions.
Core Models
1. Vault
The primary entity representing a tokenized asset vault.
interface Vault {
id: string; // Unique identifier
contractAddress: string; // On-chain vault contract address
type: VaultType; // PRIVATE | PUBLIC | SEMI_PRIVATE
status: VaultStatus; // DRAFT | ACTIVE | LOCKED | TERMINATED
// Asset Configuration
assetTypes: AssetType[]; // SINGLE_NFT | MULTI_NFT | ANY_CNT
assetWhitelist: string[]; // Allowed asset addresses
contributorWhitelist: string[];// Allowed contributor addresses
// Windows Configuration
assetWindow: {
startTime: Date;
duration: string; // Format: "DD:HH:MM"
status: WindowStatus;
};
investmentWindow: {
startTime: Date;
duration: string; // Format: "DD:HH:MM"
status: WindowStatus;
valuationType: 'FIXED' | 'LBE';
};
// Fractionalization Settings
fractionalization: {
percentage: number; // XX.XX%
tokenSupply: number;
tokenDecimals: number; // 1-9
tokenAddress: string; // Fractional token contract address
};
// Investment Settings
investment: {
reserve: number; // XX.XX%
liquidityPool: number; // XX.XX%
};
// Termination Settings
termination: {
type: 'DAO' | 'PROGRAMMED';
fdp: number; // Floor price deviation percentage
};
// Metadata
createdBy: string; // Admin wallet address
createdAt: Date;
updatedAt: Date;
metadata: Record<string, any>;// Additional configurable fields
}
type WindowStatus = 'PENDING' | 'ACTIVE' | 'COMPLETED' | 'FAILED';
2. Asset
Represents assets held within vaults.
interface Asset {
id: string;
vaultId: string;
type: AssetType;
contractAddress: string;
tokenId?: string; // For NFTs
quantity: number; // For CNTs
// Valuation
floorPrice: number; // For NFTs
dexPrice: number; // For CNTs
lastValuation: Date;
// Status
status: AssetStatus; // PENDING | LOCKED | RELEASED
lockedAt?: Date;
releasedAt?: Date;
// Metadata
metadata: {
name: string;
description: string;
imageUrl: string;
attributes: Record<string, any>;
};
// Tracking
addedBy: string; // Wallet address
addedAt: Date;
updatedAt: Date;
}
type AssetStatus = 'PENDING' | 'LOCKED' | 'RELEASED';
3. Proposal
Governance proposals within vaults.
interface Proposal {
id: string;
vaultId: string;
type: ProposalType; // ASSET_SALE | BUY | STAKE | LIQUIDATE
// Phases
votingPhase: {
duration: string; // Format: "DD:HH:MM"
startTime: Date;
endTime: Date;
status: PhaseStatus;
quorum: number; // Required participation percentage
};
lockPhase: {
duration: string;
startTime: Date;
endTime: Date;
status: PhaseStatus;
};
executionPhase: {
duration: string;
startTime: Date;
endTime: Date;
status: PhaseStatus;
requiredCosigners: number;
};
// Proposal Details
settings: {
assets: string[]; // Affected asset IDs
effects: ProposalEffect[];
};
// Results
votes: {
approve: number;
reject: number;
totalVoted: number;
uniqueVoters: number;
};
// Status
status: ProposalStatus; // DRAFT | ACTIVE | PASSED | FAILED | EXECUTED
result?: ProposalResult;
// Metadata
createdBy: string; // Proposer wallet address
createdAt: Date;
updatedAt: Date;
}
type PhaseStatus = 'PENDING' | 'ACTIVE' | 'COMPLETED' | 'FAILED';
type ProposalStatus = 'DRAFT' | 'ACTIVE' | 'PASSED' | 'FAILED' | 'EXECUTED';
4. Vote
Individual votes on proposals.
interface Vote {
id: string;
proposalId: string;
wallet: string; // Voter's wallet address
decision: 'APPROVE' | 'REJECT';
amount: number; // Amount of FTs staked in vote
// Status
status: VoteStatus; // CAST | CONFIRMED | REVOKED
confirmationTx?: string;// Blockchain transaction hash
// Timing
castAt: Date;
confirmedAt?: Date;
revokedAt?: Date;
}
5. Stake
Represents staked fractional tokens.
interface Stake {
id: string;
vaultId: string;
wallet: string; // Staker's wallet address
amount: number; // Staked amount
// Status
status: StakeStatus; // ACTIVE | LOCKED | RELEASED
lockedUntil?: Date; // For time-locked stakes
// Voting Power
votingPower: number;
usedPower: number; // Power used in active votes
// Tracking
createdAt: Date;
updatedAt: Date;
transactions: {
stakeHash: string;
unstakeHash?: string;
};
}
Relationships
Entity Relationships Diagram
erDiagram
Vault ||--o{ Asset : contains
Vault ||--o{ Proposal : has
Vault ||--o{ Stake : holds
Proposal ||--o{ Vote : receives
Stake ||--o{ Vote : powers
Key Relationships
-
Vault → Assets
- One-to-many relationship
- Vault can contain multiple assets
- Assets belong to exactly one vault
- Relationship constraints enforced by
assetTypes
andassetWhitelist
-
Vault → Proposals
- One-to-many relationship
- Proposals are bound to a single vault
- Proposal creation governed by vault settings
- Vault status affects proposal availability
-
Proposal → Votes
- One-to-many relationship
- Votes tied to specific proposals
- Vote weight determined by stake amount
- Vote validity constrained by proposal phases
-
Stake → Votes
- One-to-many relationship
- Stakes power multiple votes
- Voting power tracked and limited by stake amount
- Stakes can be locked during active votes
Validation Rules
1. Vault Validation
const vaultValidation = {
assetWindow: {
minDuration: "01:00:00",
maxDuration: "30:00:00"
},
investmentWindow: {
minDuration: "24:00:00",
maxDuration: "168:00:00"
},
fractionalization: {
minPercentage: 1,
maxPercentage: 100,
minDecimals: 1,
maxDecimals: 9
},
investment: {
minReserve: 5,
maxReserve: 50,
minLiquidity: 1,
maxLiquidity: 20
}
};
2. Asset Validation
const assetValidation = {
nft: {
maxPerVault: 100
},
cnt: {
minQuantity: 1,
maxQuantity: 1000000
},
valuation: {
maxAge: "24:00:00"
}
};
3. Proposal Validation
const proposalValidation = {
voting: {
minDuration: "24:00:00",
maxDuration: "168:00:00",
minQuorum: 10,
maxQuorum: 100
},
lock: {
minDuration: "12:00:00",
maxDuration: "48:00:00"
},
execution: {
minDuration: "24:00:00",
maxDuration: "72:00:00"
}
};
Implementation Guidelines
1. Database Indexes
// Vault Indexes
{
"contractAddress": 1,
"status": 1,
"type": 1,
"createdAt": -1
}
// Asset Indexes
{
"vaultId": 1,
"contractAddress": 1,
"status": 1
}
// Proposal Indexes
{
"vaultId": 1,
"status": 1,
"votingPhase.endTime": 1
}
// Vote Indexes
{
"proposalId": 1,
"wallet": 1,
"status": 1
}
// Stake Indexes
{
"vaultId": 1,
"wallet": 1,
"status": 1
}
2. Cascade Behaviors
// Delete cascade rules
const cascadeRules = {
vault: {
onDelete: ['assets', 'proposals', 'stakes']
},
proposal: {
onDelete: ['votes']
}
};
3. Data Integrity
interface DataIntegrityChecks {
validateStakeBalance: () => Promise<void>;
validateVotingPower: () => Promise<void>;
validateProposalStatus: () => Promise<void>;
validateAssetLocks: () => Promise<void>;
}
Best Practices
-
Data Access
- Use repositories pattern
- Implement caching strategy
- Handle concurrent updates
- Maintain audit logs
-
Validation
- Validate at model level
- Implement business rules
- Check relationships
- Verify blockchain state
-
Performance
- Use appropriate indexes
- Implement pagination
- Optimize queries
- Monitor database load
-
Security
- Encrypt sensitive data
- Validate permissions
- Audit data access
- Handle PII properly