Cap Table

Capitalization table recording all token holders, their share classes, and ownership percentages for corporate governance and compliance.

Cap Table (capitalization table) is the authoritative record of a company's ownership structure, documenting all shareholders, their share quantities, share classes, ownership percentages, and the terms attached to their holdings. In the context of tokenized securities, the cap table is derived directly from blockchain state—the token contract's balance mappings become the source of truth for corporate ownership, replacing traditional spreadsheets and transfer agent databases.

For security tokens built on standards like ERC-1400, the cap table is implicit in the contract's storage: the combination of balanceOf queries, partition enumeration, and metadata lookups produces a complete ownership record that is transparent, immutable, and automatically updated with every transfer.

Traditional vs. Tokenized Cap Tables

Traditional Cap Table Challenges:

  • Maintained in spreadsheets or specialized software (Carta, Pulley)
  • Updated manually after each transaction
  • Reconciliation required between multiple data sources
  • Disputes arise from conflicting records
  • Transfer agent intermediaries add cost and latency
  • Private company cap tables often outdated or inaccurate

Tokenized Cap Table Benefits:

  • Single source of truth on blockchain
  • Automatic updates with every on-chain transaction
  • No reconciliation needed—state is definitive
  • Transparent and auditable by all stakeholders
  • Real-time ownership visibility
  • Programmable corporate actions (dividends, voting)

Cap Table Data Structure

A comprehensive on-chain cap table includes:

1// Core ownership data (from token contract)
2mapping(address => uint256) public balanceOf;
3mapping(address => mapping(bytes32 => uint256)) public balanceOfByPartition;
4
5// Share class metadata
6struct ShareClass {
7 bytes32 partition;
8 string name; // "Series A Preferred"
9 uint256 liquidationPref; // Liquidation preference multiplier
10 uint256 dividendRate; // Annual dividend rate (basis points)
11 bool votingRights; // Has governance voting rights
12 bool participating; // Participates in common distributions
13 uint256 conversionRatio; // Converts to N common shares
14}
15
16mapping(bytes32 => ShareClass) public shareClasses;
17
18// Holder metadata (may require off-chain lookup for privacy)
19struct Holder {
20 address wallet;
21 bytes32 identityHash; // Hash linking to off-chain identity
22 uint16 jurisdiction; // Country code
23 bool accredited; // Accredited investor status
24 uint256 acquisitionDate; // For lock-up calculations
25}
26
27mapping(address => Holder) public holders;

Cap Table Queries

Basic Ownership:

1// Total shares outstanding
2function totalSupply() public view returns (uint256);
3
4// Holder's total shares
5function balanceOf(address holder) public view returns (uint256);
6
7// Ownership percentage
8function ownershipPercentage(address holder) public view returns (uint256) {
9 return (balanceOf(holder) * 10000) / totalSupply(); // Basis points
10}

By Share Class:

1// Shares in specific class
2function balanceOfByPartition(bytes32 partition, address holder)
3 public view returns (uint256);
4
5// Total shares in class
6function totalSupplyByPartition(bytes32 partition)
7 public view returns (uint256);
8
9// All classes held by address
10function partitionsOf(address holder)
11 public view returns (bytes32[] memory);

Enumeration (for off-chain indexing):

1// Total unique holders
2function holderCount() public view returns (uint256);
3
4// Holder at index (for iteration)
5function holderAt(uint256 index) public view returns (address);
6
7// All holders (gas-intensive, use carefully)
8function allHolders() public view returns (address[] memory);

Corporate Actions on Cap Tables

Tokenized cap tables enable programmable corporate actions:

Dividend Distributions:

1function distributeDividends(uint256 totalAmount) external onlyIssuer {
2 for (uint i = 0; i < holderCount(); i++) {
3 address holder = holderAt(i);
4 uint256 share = (balanceOf(holder) * totalAmount) / totalSupply();
5 paymentToken.transfer(holder, share);
6 }
7}

Stock Splits:

1function stockSplit(uint256 multiplier) external onlyIssuer {
2 for (uint i = 0; i < holderCount(); i++) {
3 address holder = holderAt(i);
4 uint256 currentBalance = balanceOf(holder);
5 _mint(holder, currentBalance * (multiplier - 1));
6 }
7}

Governance Snapshots:

1function createVotingSnapshot() external returns (uint256 snapshotId) {
2 snapshotId = _snapshot();
3 // Voting power is now frozen at this block
4 emit SnapshotCreated(snapshotId, block.number);
5}
6
7function votingPowerAt(address holder, uint256 snapshotId)
8 public view returns (uint256) {
9 return balanceOfAt(holder, snapshotId);
10}

Cap Table Compliance

Regulatory requirements for cap table maintenance:

Holder Limits: Regulation D (506(b)) limits offerings to 35 non-accredited investors. The cap table must track accreditation status:

1function accreditedHolderCount() public view returns (uint256 count) {
2 for (uint i = 0; i < holderCount(); i++) {
3 if (holders[holderAt(i)].accredited) count++;
4 }
5}
6
7function nonAccreditedHolderCount() public view returns (uint256) {
8 return holderCount() - accreditedHolderCount();
9}
10
11// Enforce during transfers
12modifier withinHolderLimits(address to) {
13 if (!holders[to].accredited && balanceOf(to) == 0) {
14 // New non-accredited holder
15 require(
16 nonAccreditedHolderCount() < 35,
17 "Non-accredited limit reached"
18 );
19 }
20 _;
21}

Beneficial Ownership Reporting: SEC requires disclosure when holders exceed 5% ownership:

1event BeneficialOwnershipThreshold(
2 address indexed holder,
3 uint256 percentage,
4 bool crossed
5);
6
7function _afterTokenTransfer(address from, address to, uint256 amount)
8 internal override
9{
10 uint256 toPct = ownershipPercentage(to);
11 if (toPct >= 500 && ownershipPercentage(to) -
12 ((amount * 10000) / totalSupply()) < 500) {
13 emit BeneficialOwnershipThreshold(to, toPct, true);
14 }
15}

Cap Table Security Considerations

Holder Enumeration Gas: Iterating through all holders is O(n) and can exceed block gas limits for large cap tables. Use off-chain indexing with on-chain verification for corporate actions.

Privacy Leakage: On-chain cap tables reveal ownership structures publicly. Pseudonymous addresses provide some privacy, but linking to real identities (required for compliance) creates privacy risks. Consider:

  • Storing identity mappings off-chain
  • Using zero-knowledge proofs for ownership verification
  • Aggregating small holders in nominee structures

Holder Array Manipulation: If holder enumeration relies on arrays, ensure proper handling of:

  • Duplicate prevention
  • Removal when balance reaches zero
  • Gas-efficient iteration

Snapshot Integrity: For governance snapshots, ensure:

  • Snapshots are immutable once created
  • Snapshot creation is properly authorized
  • Historical balances cannot be manipulated

Off-Chain Cap Table Services

While blockchain provides the source of truth, off-chain services enhance usability:

Indexing Services: The Graph, Dune Analytics, or custom indexers query blockchain events to build queryable cap table databases.

Identity Mapping: Off-chain databases link wallet addresses to legal identities (name, jurisdiction, accreditation status) while the blockchain stores only hashes.

Reporting Tools: Generate regulatory reports (Form D, Form 4), investor statements, and tax documents from on-chain data.

Visualization: Dashboards showing ownership breakdowns, waterfall analysis, and pro-forma modeling.

Audit Checklist for Cap Table Implementation

  1. Holder Tracking: Is holder enumeration implemented correctly?
  2. Balance Consistency: Do partition balances sum to total balances?
  3. Zero-Balance Cleanup: Are holders removed when balance reaches zero?
  4. Ownership Calculations: Are percentage calculations accurate (rounding)?
  5. Limit Enforcement: Are holder count limits enforced during transfers?
  6. Snapshot Security: Are snapshots properly created and immutable?
  7. Event Emissions: Are all ownership changes properly logged?
  8. Gas Efficiency: Can corporate actions execute within gas limits?
  9. Privacy Considerations: Is sensitive data properly protected?
  10. Enumeration Bounds: Are there protections against enumeration attacks?

The tokenized cap table represents one of the most compelling use cases for blockchain in corporate finance—replacing fragmented, error-prone record-keeping with a single, authoritative, automatically-updated ownership ledger. For developers, understanding how cap table data structures map to on-chain storage is essential for building compliant and efficient security token systems.

Need expert guidance on Cap Table?

Our team at Zealynx has deep expertise in blockchain security and DeFi protocols. Whether you need an audit or consultation, we're here to help.

Get a Quote

oog
zealynx

Subscribe to Our Newsletter

Stay updated with our latest security insights and blog posts

© 2024 Zealynx