Skip to main content

Data Models & Relationships

Overview

This document outlines the updated core data models in the L4VA system,system. theirOur relationships,revised validationarchitecture rules,now supports dynamic vault management and implementationa details.dual-level Ourasset dataclassification. architectureThis supportsdesign not only covers standard use cases (e.g., works of art, real estate, gold bullion, and equity) but also enables the registration of custom vault management, governance processes,and asset handling,types andas usernew interactions.real-world asset classes emerge.

Core Models

1. Vault

The primary entity representing a tokenized asset vault. The vault model now supports both fixed types (e.g., PUBLIC, PRIVATE, SEMI_PRIVATE) and dynamically registered types. It also allows for an open set of supported asset types, which can be expanded via a configuration registry or admin endpoint.

interface Vault {
  id: string;                    // Unique identifier
  contractAddress: string;       // On-chain vault contract address
  // VaultType can be one of the predefined values or a dynamically registered type.
  type: VaultType;              // e.g., PRIVATE | PUBLIC | SEMI_PRIVATE | custom types
  status: VaultStatus;          // DRAFT | ACTIVE | LOCKED | TERMINATED
  
  // Asset ConfigurationConfiguration: supports dynamic asset types.
  // Defaults include NFT (for unique assets) and CNT (for fractional assets).
  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
  };
  
  // MetadataMetadata: provides room for additional dynamic configuration.
  createdBy: string;            // Admin wallet address
  createdAt: Date;
  updatedAt: Date;
  metadata: Record<string, any>; // Additional configurable fields (e.g., custom vault parameters)
}

type WindowStatus = 'PENDING' | 'ACTIVE' | 'COMPLETED' | 'FAILED';

2. Asset

Represents assets held within vaults. This model introduces a dual-level classification: a primary tokenization method (e.g., NFT for unique items, CNT for fractional assets) and a secondary categorization (via metadata) to define asset-specific classes such as art, real estate, commodities, or equity.

interface Asset {
  id: string;
  vaultId: string;
  // AssetType may be one of the default types (e.g., NFT, CNT) or a dynamically registered type.
  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 now includes an additional "category" field.
  // This field can capture asset-specific classifications (e.g., art, real_estate, commodity, equity)
  metadata: {
    name: string;
    description: string;
    imageUrl: string;
    category?: string;
    attributes: Record<string, any>;
  };
  
  // Tracking
  addedBy: string;             // Wallet address
  addedAt: Date;
  updatedAt: Date;
}

type AssetStatus = 'PENDING' | 'LOCKED' | 'RELEASED';

3. Proposal

Governance proposals withinremain vaults.largely unchanged, but note that proposals may reference dynamically registered asset types or custom governance rules based on asset categories.

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 DetailsDetails: can target assets of any supported type.
  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.proposals used to execute governance decisions. This model remains unchanged.

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.tokens that contribute to voting power. This model remains similar but supports dynamic governance processes tied to various asset classes.

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

1.

  1. Vault → Assets

    • One-to-many relationship
    • A
    • Vaultvault can contain multiple assets
    • assets;
    • Assetseach belongasset belongs to exactlya onesingle vaultvault.
    • Relationship constraints are enforced by assetTypes and assetWhitelistassetWhitelist.

    2.

  2. Vault → Proposals

    • One-to-many relationship
    • Proposals are boundtied to a single vault and may leverage asset category-specific rules.

    3.

  3. Proposal creation governed by vault settings
  4. Vault status affects proposal availability
  5. Proposal → Votes

    • One-to-many relationship
    • Votes tiedare toassociated with specific proposals
    • proposals,
    • Votewith vote weight determined by stakestaked amounttokens.

    4.

  6. Vote validity constrained by proposal phases
  7. Stake → Votes

    • One-to-many relationship
    • Stakes power multiplevotes votes
    • and
    • Votinghelp track voting power trackedrelative andto limited by stakethe amount staked.
    • 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

1.
  1. Data Access

  • Use the repositories patternpattern.
  • Implement a caching strategystrategy.
  • Handle concurrent updatesupdates.
  • Maintain audit logslogs.
2.
  • Validation

    • Validate at the model levellevel.
    • ImplementEnforce business rulesrules.
    • Check relationshipsrelationships.
    • Verify blockchain statestate.
    3.
  • Performance

    • Use appropriate indexesindexes.
    • Implement paginationpagination.
    • Optimize queriesqueries.
    • Monitor database loadload.
    4.
  • Security

    • Encrypt sensitive datadata.
    • Validate permissionspermissions.
    • Audit data accessaccess.
    • Handle PII properlyproperly.

    Note: I recently updated this document to reflect a move toward a dynamic, extensible framework as detailed in our Vault Formation and Data Models & Relationships guidelines, ensuring our platform remains agile in representing any real-world asset.