Skip to content
Open
Changes from 32 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
249 changes: 249 additions & 0 deletions ERCS/erc-7752.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
---
eip: 7752
title: Lot Token
description: A token treating each acquisition (lot) as an on-chain record with cost-basis, lineage, and regulatory controls.
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
requires: 173
---

## Abstract

[ERC-7752](./eip-7752.md) defines a **lot-based** token model. Each issuance or acquisition event mints a unique **lot** (`lotId`) that carries its own quantity, cost basis, acquisition date, and lineage. The core interface also standardizes pause, freeze, forced-transfer, and other **administrative hooks** mandated for real-world securities and off-chain assets.

## 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—sit between those extremes:

- One issuer may create **thousands of discrete lots** over time.
- Each lot needs cost-basis, vesting, or lock-up data.
- Regulators demand pause, freeze, and forced-transfer powers.

ERC-7752 bakes those requirements into a single, deterministic ABI so wallets, custodians, tax engines, and regulators can interoperate without bespoke dialects.

## Specification

Key words **MUST**, **SHOULD**, etc. have the meanings of RFC 2119 / 8174.

### Core Interface

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

/**
* @title ERC-7752 Lot Token (Core)
*/
interface LotToken {
/*──────────────────────────────────
Data structures
──────────────────────────────────*/
enum TransferType { INTERNAL, SALE, GIFT, INHERITANCE, REWARD }

struct Lot {
bytes32 parentLotId;
uint256 quantity;
address paymentCurrency;
uint256 costBasis;
uint256 acquisitionDate;
uint256 lastUpdate;
bool isValid;
address owner;
TransferType tType;
string uri;
bytes data;
}

/*──────────────────────────────────
Events (deterministic for audit)
──────────────────────────────────*/

event LotCreated(
address indexed owner,
bytes32 indexed lotId,
bytes32 indexed parentLotId,
uint256 quantity,
address paymentCurrency,
uint256 costBasis,
uint256 acquisitionDate,
uint256 lastUpdate,
string uri,
bytes data,
TransferType tType
);

event LotTransferred(
bytes32 indexed lotId,
address indexed from,
address indexed to,
uint256 quantity,
string uri,
bytes data,
TransferType tType,
uint256 newCostBasis
);

event LotAdjusted(
bytes32 indexed oldLotId,
bytes32 indexed newLotId,
address operator,
uint256 newQuantity,
uint256 newCostBasis,
address paymentCurrency,
uint256 newAcquisitionDate,
string newUri,
bytes newData,
string reason,
TransferType tType
);

event LotInvalidated(bytes32 indexed lotId);

event PausedSet(bool indexed paused);
event AccountFrozen(address indexed account, bool frozen);
event LotFrozen(bytes32 indexed lotId, bool frozen);

event ForcedTransfer(
bytes32 indexed lotId,
address indexed from,
address indexed to,
uint256 quantity,
string reason
);

event TransferControllerAdded(address indexed controller);

/*──────────────────────────────────
Read functions
──────────────────────────────────*/
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function getLot(bytes32 id) external view returns (Lot memory);

/*──────────────────────────────────
Lot CRUD
──────────────────────────────────*/
function createLot(
address owner,
uint256 quantity,
address paymentCurrency,
uint256 costBasis,
uint256 acquisitionDate,
string calldata uri,
bytes calldata data,
uint256 customId /* 0 = auto */
) external returns (bytes32 lotId, uint256 assignedCustomId);

function transfer(
bytes32 lotId,
address to,
uint256 quantity,
TransferType tType,
uint256 newCostBasis,
string calldata uri,
bytes calldata data
) external returns (bytes32 newLotId);

function transferFrom(
bytes32 lotId,
address from,
address to,
uint256 quantity,
TransferType tType,
uint256 newCostBasis,
string calldata uri,
bytes calldata data
) external returns (bytes32 newLotId);

function adjustLot(
bytes32 oldLotId,
uint256 newQuantity,
uint256 newCostBasis,
address newPaymentCurrency,
uint256 newAcquisitionDate,
string calldata newUri,
bytes calldata newData,
string calldata reason,
uint256 customId
) external returns (bytes32 newLotId);

/*──────────────────────────────────
Administrative hooks (normative)
──────────────────────────────────*/
function pause() external;
function unpause() external;

function freezeAccount(address account, bool frozen) external;
function freezeLot(bytes32 lotId, bool frozen) external;

function forcedTransfer(
bytes32 lotId,
address from,
address to,
uint256 quantity,
string calldata reason
) external returns (bytes32 newLotId);

/* Transfer-policy plug-in */
function setTransferController(address controller) external;
function transferController() external view returns (address);

/* Optional merge / split helpers */
function mergeLots(bytes32[] calldata sourceLots, string calldata uri, bytes calldata data)
external returns (bytes32 newLotId);
function splitLot(bytes32 lotId, uint256[] calldata quantities, string[] calldata uris)
external returns (bytes32[] memory newLotIds);
}
```

> Any function marked "external" **MUST** revert if the contract is paused, the caller/lot is frozen, or a transferController vetoes the action.

### Tax Considerations (informative)

The `TransferType` enum enables implementations to capture transfer context for jurisdiction-specific tax compliance:

| TransferType | Purpose | Tax implications vary by jurisdiction |
| ------------- | ---------------------------------------- | ------------------------------------- |
| `INTERNAL` | Administrative transfers, splits, merges | Typically no taxable event |
| `SALE` | Market transactions for consideration | Usually triggers capital gains |
| `GIFT` | Gratuitous transfers | Donor/recipient tax treatment varies |
| `INHERITANCE` | Estate/probate transfers | Step-up rules vary by jurisdiction |
| `REWARD` | Compensation, airdrops, staking rewards | Often treated as ordinary income |

**Example U.S. Treatment**: `GIFT` uses carry-over basis (IRC § 1015), `INHERITANCE` gets stepped-up basis (IRC § 1014).
**Example UK Treatment**: Different rules under TCGA 1992.
**Example Singapore**: No capital gains tax.

Implementations **SHOULD** consult local tax authorities and **MAY** implement jurisdiction-specific tax calculation modules.

## Rationale

**Administrative hooks (pause, freeze, forcedTransfer, adjustLot)** are embedded in ERC-7752 Core because issued assets **cannot satisfy real-world statutory and fiduciary duties without them.**

- Securities law obliges issuers and registrars to rectify errors, comply with court orders, and enforce sanctions.
- Transfer-control modules (ERC-7752-Policy) rely on a deterministic ABI to implement jurisdiction-specific rules.
- Standardizing these events enables third-party auditors, tax engines, and regulators to ingest compliance actions uniformly.

While purely decentralized assets may deem these functions unnecessary, they may be voluntarily disabled by renouncing the `ADMIN_ROLE` or setting `transferController = address(0)`. Omission from the ABI, however, would break composability for the majority of regulated implementations.

## Backwards Compatibility

ERC-7752 is not backward-compatible with ERC-20/721/[ERC-1155](./eip-1155.md) because each lotId represents a semi-fungible slice with its own lineage and admin controls.

## Security Considerations

- Implementers MUST secure admin roles (e.g., OpenZeppelin `AccessControl` or `AccessManager`).
- A compromised `transferController` could veto or force-transfer lots; multi-sig ownership is **RECOMMENDED**.

### Conclusion

ERC‑7752 brings granular accounting, compliance, and administrative certainty to on‑chain representations of traditional assets—unlocking the next wave of securitised and regulated token markets.

## Copyright

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