Token Partition
Named tranche (bytes32 key) within ERC-1410 tokens separating shares by legal status such as locked, vested, or freely tradable.
Token Partition is a named tranche within an ERC-1410 token contract that groups tokens sharing the same legal status, transfer restrictions, or economic properties. Each partition is identified by a bytes32 key (typically a keccak256 hash of a descriptive name like "LOCKED" or "VESTED") and maintains its own balance mapping, enabling a single security token contract to represent multiple share classes with different rules.
Partitions are the implementation mechanism for partial fungibility. While the concept of partial fungibility describes the architectural pattern, partitions are the concrete data structures that make it work. Understanding partitions is essential for developers implementing ERC-1400 compliant tokens and for auditors analyzing their security properties.
Technical Implementation
The core data structure uses nested mappings:
1// Partition balances: address → partition → balance2mapping(address => mapping(bytes32 => uint256)) internal _balances;34// Track which partitions each address holds5mapping(address => bytes32[]) internal _partitionsOf;67// Total supply per partition8mapping(bytes32 => uint256) internal _totalSupplyByPartition;910// Global list of all partitions11bytes32[] internal _totalPartitions;
Common partition identifiers follow naming conventions:
1bytes32 constant LOCKED = keccak256("LOCKED");2bytes32 constant VESTED = keccak256("VESTED");3bytes32 constant TRADABLE = keccak256("TRADABLE");4bytes32 constant REG_D = keccak256("REG_D");5bytes32 constant REG_S = keccak256("REG_S");
Partition Operations
Balance Queries:
1// Balance in specific partition2function balanceOfByPartition(bytes32 partition, address holder)3 public view returns (uint256);45// All partitions held by address6function partitionsOf(address holder)7 public view returns (bytes32[] memory);89// Total balance across all partitions10function balanceOf(address holder)11 public view returns (uint256);
Transfers:
1function transferByPartition(2 bytes32 partition,3 address to,4 uint256 value,5 bytes calldata data6) public returns (bytes32);
The return value indicates the destination partition, which may differ from the source. For example, tokens transferred from a "LOCKED" partition might arrive in the recipient's "TRADABLE" partition if the lock-up period has expired.
Real-World Partition Structures
Equity Token Example:
1├── FOUNDERS (4-year vesting, 1-year cliff)2├── EMPLOYEES (standard vesting schedule)3├── SERIES_A (investor lock-up until IPO)4├── SERIES_B (6-month lock-up)5└── SECONDARY (freely tradable)
Real Estate Token Example:
1├── PHASE_A_CONSTRUCTION (non-transferable, no dividends)2├── PHASE_B_OPERATING (transferable, receives rent distributions)3└── PHASE_C_SALE (liquidation preference)
Jurisdictional Structure:
1├── REG_D_US (1-year lock-up, accredited investors only)2├── REG_S_INTL (40-day lock-up, non-US only)3└── PUBLIC (post-registration, freely tradable)
Partition Lifecycle
Creation: Partitions are typically created by authorized issuers when minting new tokens:
1function issueByPartition(2 bytes32 partition,3 address holder,4 uint256 value,5 bytes calldata data6) external onlyIssuer;
Migration: Tokens can move between partitions based on time or events:
1function migratePartition(2 address holder,3 bytes32 fromPartition,4 bytes32 toPartition,5 uint256 value6) external onlyController;
For time-based unlocks (vesting, lock-up expiry), implementations often use:
- Automatic migration on transfer attempt (lazy evaluation)
- Batch migration by controller (gas-efficient for many holders)
- Holder-initiated claim (user pays gas)
Redemption: When securities are redeemed (buyback, liquidation), partitions may have priority:
1function redeemByPartition(2 bytes32 partition,3 uint256 value,4 bytes calldata data5) external;
Partition Metadata
Beyond balances, partitions often carry metadata:
1struct PartitionInfo {2 uint256 lockExpiry; // Timestamp when transfers unlock3 bool transferable; // Whether transfers are currently allowed4 uint256 dividendMultiplier; // e.g., 200 = 2x dividends5 bytes32 destinationPartition; // Where tokens go on transfer6 address complianceModule; // Partition-specific compliance rules7}89mapping(bytes32 => PartitionInfo) public partitionInfo;
Security Considerations
Partition Key Collisions: If partition keys are derived from user input without proper validation, attackers might create partitions that collide with or mimic legitimate partitions. Always validate partition keys against an allowlist or restrict partition creation to authorized roles.
Default Partition Bypass: ERC-1410 tokens often implement ERC-20 compatibility by routing transfer() calls through a default partition. If the default partition has different (more permissive) rules than named partitions, this creates a bypass vector. Ensure all transfer paths enforce consistent compliance checks.
Partition Enumeration: The partitionsOf() function reveals which share classes a holder owns. In some contexts, this leaks sensitive information (e.g., that someone holds locked founder shares). Consider privacy implications and whether partition membership should be obfuscated.
Cross-Partition State Consistency: When tokens migrate between partitions, ensure atomic state updates. A failed migration that debits the source but doesn't credit the destination causes token loss.
Controller Partition Powers: The controller role can typically force transfers across any partition. Ensure controller actions are properly logged and subject to timelocks for high-value operations.
Gas Optimization
Lazy Partition Creation: Don't add partitions to _partitionsOf until actually needed. Check if balance is non-zero before array operations.
Partition Limits: Cap the number of partitions per holder to prevent gas griefing on enumeration. A reasonable limit might be 10-20 partitions per address.
Batch Operations: For issuer operations affecting many holders, provide batch functions that amortize base transaction costs:
1function batchIssueByPartition(2 bytes32 partition,3 address[] calldata holders,4 uint256[] calldata values5) external onlyIssuer;
Partition Caching: Cache frequently-accessed partition data in memory during complex operations rather than repeatedly reading from storage.
Audit Checklist for Token Partitions
- Partition Creation: Who can create new partitions? Is there an allowlist?
- Balance Integrity: Do partition balances sum to total balance correctly?
- Transfer Paths: Do ALL transfer functions respect partition rules?
- Migration Logic: Is partition migration atomic and properly authorized?
- Enumeration Bounds: Are there limits on partitions per address?
- Metadata Consistency: Is partition metadata immutable or properly governed?
- Event Emissions: Are partition changes properly logged?
- Controller Access: What partition operations can controllers perform?
Token partitions represent the technical foundation for sophisticated security token architectures. They enable regulatory compliance to be encoded directly into token storage rather than enforced through external systems, but require careful implementation to avoid security vulnerabilities and gas inefficiencies.
Articles Using This Term
Learn more about Token Partition in these articles:
Related Terms
Partial Fungibility
Token architecture where units within the same contract can have different properties, enabling distinct share classes with separate transfer rules.
Security Token
Blockchain-based representation of regulated securities (equity, debt, real estate) requiring transfer restrictions and investor verification under securities law.
Controller Role
ERC-1644 privileged address with forced transfer capability for legal compliance scenarios like court orders or lost key recovery.
Need expert guidance on Token Partition?
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

