Skip to content
Open
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
80a10a5
Create eip-equity_token.md
mrosendin Aug 7, 2024
17b8380
Fix reference and rebase to v1
mrosendin Aug 7, 2024
06614d5
Update ERCS/eip-equity_token.md
mrosendin Aug 8, 2024
1e3d53b
Update ERCS/eip-equity_token.md
mrosendin Aug 8, 2024
46f43e8
Rename eip-equity_token.md to eip-7752.md
mrosendin Aug 8, 2024
68f8318
Rename eip-7752.md to erc-7752.md
mrosendin Aug 8, 2024
df902f0
Update erc-7752.md
mrosendin Aug 8, 2024
b0bbca0
Update erc-7752.md
mrosendin Aug 8, 2024
87d5cc1
Remove external link
mrosendin Aug 8, 2024
fc50883
Merge branch 'master' into eip-equity-token
mrosendin Aug 9, 2024
191f3a8
Update erc-7752.md
mrosendin Aug 9, 2024
2b21514
Update erc-7752.md
mrosendin Aug 9, 2024
59bdc35
Update erc-7752.md
mrosendin Aug 9, 2024
8449d95
mint -> issue, burn -> cancel
mrosendin Aug 29, 2024
e7078b2
Info about vesting and governing docs
mrosendin Aug 29, 2024
276d9fb
update rationale of separate vesting and documentation contracts
mrosendin Aug 29, 2024
8e59d6d
fix: eip validation error
mrosendin Aug 29, 2024
30f498e
Merge branch 'master' into eip-equity-token
mrosendin Nov 8, 2024
de0586a
erc-1155 update
mrosendin Nov 8, 2024
3112713
add links
mrosendin Nov 8, 2024
6112ad2
update links
mrosendin Nov 8, 2024
649e5dd
fix markdown-link-first
mrosendin Nov 8, 2024
0cd1e89
fix markdown-first-link
mrosendin Nov 8, 2024
69a9d8d
Update erc-7752.md
mrosendin Dec 15, 2024
832b472
eip walidator fixes
mrosendin Dec 15, 2024
d206258
Update erc-7752.md
mrosendin Jun 9, 2025
1b35045
fix walidator issues
mrosendin Jun 9, 2025
608ef19
Set table for international use
mrosendin Jun 9, 2025
20507ae
Update title
mrosendin Jun 9, 2025
633242b
Merge branch 'master' into eip-equity-token
mrosendin Jun 9, 2025
c219014
Update erc-7752.md
mrosendin Jun 10, 2025
0cf11ae
Merge branch 'master' into eip-equity-token
mrosendin Jun 16, 2025
beaabad
Update erc-7752.md
mrosendin Jul 18, 2025
5577912
Update erc-7752.md
mrosendin Jul 28, 2025
0051018
Update erc-7752.md
mrosendin Sep 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
391 changes: 391 additions & 0 deletions ERCS/erc-7752.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,391 @@
---
eip: 7752
title: Lot-based Token
description: A token treating each acquisition (lot) as an on-chain record with cost-basis and lineage.
author: Matt Rosendin (@mrosendin) <[email protected]>
discussions-to: https://ethereum-magicians.org/t/erc-7752-equity-token/20735
status: Draft
type: Standards Track
category: ERC
created: 2024-08-06
---

## Abstract

[ERC-7752](./eip-7752.md) defines a **lot-based** token model where each issuance or acquisition event creates a unique **lot** (`lotId`) with its own quantity, basis, acquisition date, and lineage. This standard provides core lot management functions while enabling modular extensions for transfer controls, compliance, and administrative features.

## Motivation

Traditional token standards excel at _fungibility_ ([ERC-20](./eip-20.md)) or _single, indivisible items_ ([ERC-721](./eip-721.md)). Real-world assets—equity certificates, debt notes, real-estate fractions—require granular tracking:

- **Distinct lots** with individual basis and acquisition dates
- **Lineage tracking** for audit trails and compliance
- **Modular architecture** supporting jurisdiction-specific extensions
- **Deterministic events** for tax engines and regulatory reporting

ERC-7752 provides the foundational interface for lot-based tokens while enabling specialized implementations through modular extensions.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

### Core Interface

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
* @title ERC-7752 Lot Token (Core Interface)
* @notice Core lot management
*/
interface IERC7752 {
/*──────────────────────────────────
Data Structures
──────────────────────────────────*/

enum TransferType {
INTERNAL, // Administrative transfers, splits, merges
SALE, // Market transactions for consideration
GIFT, // Gratuitous transfers
INHERITANCE, // Estate/probate transfers
INCOME // Compensation, dividends, staking rewards, airdrops
}

struct Lot {
bytes32 parentLotId; // Parent lot for lineage tracking
uint256 quantity; // Amount in this lot
address currency; // Currency used for acquisition
uint256 basis; // Total cost basis (in currency)
uint256 acquisitionDate; // Unix timestamp of original acquisition
uint256 lastUpdate; // Unix timestamp of last modification
address owner; // Current owner address
TransferType transferType; // How this lot was acquired
string uri; // Metadata URI
bytes data; // Additional lot-specific data
}

/*──────────────────────────────────
Events
──────────────────────────────────*/

/**
* @notice Emitted when a new lot is created
*/
event LotCreated(
address indexed owner,
bytes32 indexed lotId,
bytes32 indexed parentLotId,
uint256 quantity,
address currency,
uint256 basis,
uint256 acquisitionDate,
TransferType transferType,
string uri,
bytes data
);

/**
* @notice Emitted when a lot is transferred (full or partial)
*/
event LotTransferred(
bytes32 indexed lotId,
bytes32 indexed newLotId,
address indexed from,
address indexed to,
uint256 quantity,
uint256 newBasis,
TransferType transferType,
string uri,
bytes data
);

/**
* @notice Emitted when lots are merged into a new lot
*/
event LotsMerged(
bytes32[] sourceLotIds,
bytes32 indexed newLotId,
address indexed owner,
uint256 totalQuantity,
string uri,
bytes data
);

/*──────────────────────────────────
Core Read Functions
──────────────────────────────────*/

/**
* @notice Returns the token name
*/
function name() external view returns (string memory);

/**
* @notice Returns the token symbol
*/
function symbol() external view returns (string memory);

/**
* @notice Returns lot details for a given lot ID
* @param lotId The lot identifier
* @return lot The lot data structure
*/
function getLot(bytes32 lotId) external view returns (Lot memory lot);

/**
* @notice Returns all lot IDs owned by an address
* @param owner The owner address
* @return lotIds Array of lot identifiers
*/
function getLotsOf(address owner) external view returns (bytes32[] memory lotIds);

/**
* @notice Returns total quantity across all lots for an owner
* @param owner The owner address
* @return totalQuantity Sum of quantities across all lots
*/
function balanceOf(address owner) external view returns (uint256 totalQuantity);

/**
* @notice Checks if a lot ID exists and is valid
* @param lotId The lot identifier
* @return exists True if lot exists
*/
function lotExists(bytes32 lotId) external view returns (bool exists);

/*──────────────────────────────────
Core Lot Operations
──────────────────────────────────*/

/**
* @notice Creates a new lot
* @param owner Initial owner of the lot
* @param quantity Amount in the lot
* @param currency Currency used for acquisition (address(0) for native)
* @param basis Total cost basis in currency
* @param acquisitionDate Unix timestamp of acquisition
* @param transferType How this lot was acquired
* @param uri Metadata URI for the lot
* @param data Additional lot-specific data
* @return lotId The created lot identifier
*/
function createLot(
address owner,
uint256 quantity,
address currency,
uint256 basis,
uint256 acquisitionDate,
TransferType transferType,
string calldata uri,
bytes calldata data
) external returns (bytes32 lotId);

/**
* @notice Transfers full or partial lot to another address
* @param lotId Source lot identifier
* @param to Recipient address
* @param quantity Amount to transfer (must be ≤ lot quantity)
* @param transferType Type of transfer for the new lot
* @param newBasis Cost basis for the transferred portion
* @param uri Metadata URI for the new lot
* @param data Additional data for the new lot
* @return newLotId Identifier of the newly created lot for recipient
*/
function transfer(
bytes32 lotId,
address to,
uint256 quantity,
TransferType transferType,
uint256 newBasis,
string calldata uri,
bytes calldata data
) external returns (bytes32 newLotId);

/**
* @notice Transfers lot on behalf of owner (requires approval)
* @param lotId Source lot identifier
* @param from Owner address
* @param to Recipient address
* @param quantity Amount to transfer
* @param transferType Type of transfer
* @param newBasis Cost basis for transferred portion
* @param uri Metadata URI for new lot
* @param data Additional data for new lot
* @return newLotId Identifier of newly created lot
*/
function transferFrom(
bytes32 lotId,
address from,
address to,
uint256 quantity,
TransferType transferType,
uint256 newBasis,
string calldata uri,
bytes calldata data
) external returns (bytes32 newLotId);

/**
* @notice Merges multiple lots into a single new lot
* @param sourceLotIds Array of lot identifiers to merge (must have same owner)
* @param uri Metadata URI for merged lot
* @param data Additional data for merged lot
* @return newLotId Identifier of the merged lot
*/
function mergeLots(
bytes32[] calldata sourceLotIds,
string calldata uri,
bytes calldata data
) external returns (bytes32 newLotId);

/*──────────────────────────────────
Approval System
──────────────────────────────────*/

/**
* @notice Approve an operator for a specific lot
* @param lotId The lot identifier
* @param operator Address to approve
* @param approved True to approve, false to revoke
*/
function approveLot(bytes32 lotId, address operator, bool approved) external;

/**
* @notice Approve an operator for all lots owned by caller
* @param operator Address to approve
* @param approved True to approve, false to revoke
*/
function setApprovalForAll(address operator, bool approved) external;

/**
* @notice Check if operator is approved for a specific lot
* @param lotId The lot identifier
* @param operator Address to check
* @return approved True if approved
*/
function isApprovedForLot(bytes32 lotId, address operator) external view returns (bool approved);

/**
* @notice Check if operator is approved for all lots of an owner
* @param owner The owner address
* @param operator Address to check
* @return approved True if approved for all
*/
function isApprovedForAll(address owner, address operator) external view returns (bool approved);
}
```

### Lot ID Generation

Implementations MUST generate lot IDs deterministically to ensure uniqueness and prevent collisions:

```solidity
function _generateLotId(
address owner,
uint256 quantity,
uint256 blockNumber,
uint256 nonce
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(owner, quantity, blockNumber, nonce));
}
```

### Transfer Type Usage

The `TransferType` enum enables implementations to capture transfer context for compliance and tax purposes:

- `INTERNAL`: Administrative transfers, splits, merges (typically no taxable event)
- `SALE`: Market transactions for consideration (usually triggers capital gains)
- `GIFT`: Gratuitous transfers (carry-over basis treatment varies by jurisdiction)
- `INHERITANCE`: Estate transfers (step-up basis rules vary by jurisdiction)
- `INCOME`: Compensation, dividends, staking rewards, airdrops (usually ordinary income)

Implementations MAY use this information for automated compliance reporting but SHOULD consult applicable regulations.

## Rationale

### Why Lot-Based Architecture?

Traditional fungible tokens aggregate all holdings into a single balance, losing crucial information needed for:

- **Tax compliance**: Basis tracking for capital gains calculations
- **Regulatory reporting**: Audit trails for compliance officers
- **Corporate actions**: Proper handling of stock splits, dividends, vesting
- **Estate planning**: Clear lineage for inheritance and probate

### Core vs Extensions

ERC-7752 Core focuses on essential lot operations while enabling modular extensions:

**Core Standard (ERC-7752):**

- Lot creation, transfer, merge operations
- Basic approval system
- Essential events for tracking
- No administrative controls or transfer restrictions

**Potential Extensions:**

- Lot splitting functionality
- Transfer controls and compliance checks
- Pause/freeze functionality
- Forced transfers and administrative overrides
- Multi-signature requirements
- Time-based restrictions
- Custom lot ID functionality (for legacy systems)

This separation allows:

- Simple implementations for basic use cases
- Complex compliance layers when needed
- Clear upgrade paths
- Regulatory flexibility

### Event Design

Events are designed for deterministic compliance reporting:

- All lot state changes emit structured events
- Transfer types enable automated tax categorization
- Lineage tracking supports audit requirements
- Consistent event signatures across implementations

## Backwards Compatibility

ERC-7752 is not backward-compatible with [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), or [ERC-1155](./eip-1155.md) because:

- Each `lotId` represents a semi-fungible slice with unique properties
- Transfer operations create new lots rather than moving balances
- Approval system operates on lot-level rather than token-level

Implementations MAY provide compatibility layers but this is not required by the standard.

## Security Considerations

### Lot ID Uniqueness

Implementations MUST ensure lot IDs are unique across the entire token contract to prevent:

- Accidental overwrites of existing lots
- Unauthorized access to lot data
- Inconsistent state between lot records

### Approval Management

The two-tier approval system (lot-specific and owner-wide) requires careful implementation:

- Lot-specific approvals SHOULD take precedence over global approvals
- Approval checks MUST occur before any transfer operation
- Approvals SHOULD be revoked when lots are transferred or modified

### Arithmetic Safety

Lot operations involving quantities and basis calculations MUST:

- Check for integer overflow/underflow
- Validate that split quantities sum to original lot quantity
- Ensure basis calculations maintain precision

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
Loading