Discussion topic for ERC-8047: Forensic Token (Forest)
Update Log
- 2025-10-13: Initiate topic for discussion
- 2025-11-13: Update Specification and Rationale Section
- 2025-11-14: Update Specification Section (URI Schema)
External Reviews
- None as of 2025-10-13
Outstanding Issue
- None as of 2025-10-13
After a pull request is created and an ERC number is assigned, all changes will be managed through pull requests. This topic provides an initial draft version to help those who are not familiar with using GitHub.
Note: This topic will be updated over time to stay in sync with the pull request, but updates may be slow.
Abstract
Forest is a DAG-inspired token model designed to enhance traceability and regulatory compliance in digital currency systems. By introducing hierarchical token tracking, it enables efficient enforcement on any token linked to suspicious activity with level/root. Enforcement actions, such as freezing specific tokens or partitioning all tokens with relational links, are optimized to operate at O(1) complexity.
Motivation
The present-day Central Bank Digital Currency (CBDC) and Private Money concept aims to utilize the advantages of blockchain or Distributed Ledger Technology (DLT) that provide immutability, transparency, and security, and it adopts smart contracts, which play a key role in creating programmable money. However, technology itself gives an advantage and eliminates the ideal problem of compliance with the regulator and the Anti-Money Laundering and Countering the Financing of Terrorism (AML/CFT) standard, but it does not seem practical to be done in the real world and is not efficiently responsible for the financial crime or incidents that occur in the open network of economics.
Specification
The keywords “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.
Compatible implementations MUST implement the IERC8047 interface and MUST inherit from ERC-1155 and ERC-5615 interfaces. All functions defined in the interface MUST be present and all function behavior MUST meet the behavior specification requirements below.
// SPDX-License-Identifier: CC0-1.0
pragma solidity >=0.8.0 <0.9.0;
/**
* @title ERC-8047 interface
*/
interface IERC8047 is IERC1155, IERC5615 {
/**
* @dev Emitted when a new token is created within a DAG.
* @param root The root token ID of the DAG to which the new token belongs.
* @param id The ID of the newly created token.
* @param from The address that created/minted the token.
*/
event TokenCreated(
uint256 indexed root,
uint256 id,
address indexed from
);
/**
* @dev Emitted when a token is spent or partially spent.
* @param id The ID of the token being spent.
* @param value The amount of the token that was spent.
*/
event TokenSpent(
uint256 indexed id,
uint256 value
);
/**
* @dev Returns the latest (highest) level of the DAG that a given token belongs to.
* @param id The ID of the token.
* @return uint256 The latest DAG level for the token.
*/
function latestDAGLevelOf(uint256 id) external view returns (uint256);
/**
* @dev Returns the level of token within its DAG.
* @param id The ID of the token.
* @return uint256 The level of the token in the DAG.
*/
function levelOf(uint256 id) external view returns (uint256);
/**
* @dev Returns the owner of a given token.
* @param id The ID of the token.
* @return address The address that owns the token.
*/
function ownerOf(uint256 id) external view returns (address);
/**
* @dev Returns the parent token ID of a given token.
* @param id The ID of the token.
* @return uint256 The ID of the parent token. Returns 0 if the token is a root.
*/
function parentOf(uint256 id) external view returns (uint256);
/**
* @dev Returns the root token ID of the DAG to which a given token belongs.
* @param id The ID of the token.
* @return uint256 The root token ID of the DAG.
*/
function rootOf(uint256 id) external view returns (uint256);
/**
* @dev Returns total supply of all token.
* @custom:overloading of {IERC5615.totalSupply}
* @return uint256 The total supply of all token.
*/
function totalSupply() external view returns (uint256);
}
Behavior Specification
Minting
-
When
minta token, theidMUST NOT be supplied by the minter, theidMUST be generate by the contract itself. -
The
valueof theidMUST NOT be0. If value is0, themintoperation MUST revert. -
The events
TokenCreatedMUST emit when themintoperation is successful.
Burning
-
When
burna token, theidMUST NOT be deleted from theDAG. Instead, its value MUST be set to0, and the operation MUST NOT create a new transaction to the zero address. -
The events
TokenSpentMUST emit when theburnoperation is successful.
Transferring
- The
safeTransferFromMUST verify that theidexists. If it does not, the function MUST revert. - The
senderMUST be the owner of theidor an approved operator. - The
valueto be spent MUST NOT exceed thevalueof theid. If it does, the function MUST revert. - The
safeTransferFromfunction MUST mint a newidas a child of theidbeing spent. The newidMUST have itsparentset to theidthat was spent. and its level MUST be incremented by1relative to the parent. - The events
TokenSpentMUST emit when spending transaction.
Merging
- To merge two or more
idinto a newid, all tokens MUST be part of the sameDAG(i.e., share the sameroot).
newidfrom merging will be
k : The highest level from token ids that will be merging.
newTokenIdLevel = k + 1
- The
TokenSpentevent MUST be emitted for allidinvolved in the merge when the merging operation is successful.
ERC-8047 URI JSON Schema
In ERC-8047, each token has a unique id to track its movement in the DAG (like serial numbers), but all tokens representing the same asset share a single metadata URI. This reflects the fungible nature of the asset (like fiat currency)
- All tokens of the same asset MUST reference the same URI, regardless of their individual
id. - Implementations SHOULD follow the JSON Schema definition provided below for consistency across client implementations.
{
"title": "Token Metadata",
"description": "Metadata schema for ERC-8047: Forensic Token (Forest).",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Human-readable name of the asset represented by this token."
},
"symbol": {
"type": "string",
"description": "Ticker symbol or shorthand identifier for the token."
},
"decimals": {
"type": "integer",
"description": "Number of decimal places used to display token amounts. For example, 18 means the token amount should be divided by 10^18 to get its user representation."
},
"description": {
"type": "string",
"description": "Detailed description of the asset represented by this token."
},
"image": {
"type": "string",
"format": "uri",
"description": "A URI pointing to an image (MIME type image/*) that visually represents the asset. Recommended image width: 320–1080 pixels; aspect ratio: between 1.91:1 and 4:5."
},
"properties": {
"type": "object",
"description": "Container for extended metadata such as compliance, traceability, and DAG lineage.",
"properties": {
"compliance": {
"type": "object",
"description": "Compliance and policy information for the asset.",
"properties": {
"issuer": {
"type": "string",
"description": "Legal entity responsible for issuing or managing this asset."
},
"jurisdiction": {
"type": "string",
"description": "Legal jurisdiction or regulatory domain governing this asset."
},
"policies": {
"type": "string",
"format": "uri",
"description": "URI linking to AML/CFT, compliance, or risk policy documentation."
},
"enforcement_authority": {
"type": "string",
"format": "uri",
"description": "URI to the entity or endpoint responsible for enforcement actions (e.g., freeze, revoke)."
}
},
"required": ["issuer", "policies"]
}
},
"required": ["compliance"]
}
},
"required": ["name", "description", "image", "properties"]
}
A complete JSON Schema reference for ERC-8047 metadata is provided below for validation and implementation guidance.
{
"name": "United States Dollar",
"symbol": "USD",
"decimals": 18,
"description": "A compliant, traceable digital representation of the U.S. Dollar using the ERC-8047: Forensic Token (Forest).",
"image": "https://acmee-finance.com/assets/images/USD_icon.png",
"properties": {
"compliance": {
"issuer": "Acmee Finance Inc.",
"jurisdiction": "US-NY",
"policies": "https://acmee-finance.com/policies",
"enforcement_authority": "https://acmee-finance.com/enforcement"
}
}
}
Rationale
| Features | ERC-20 | UTXO | Forest |
|---|---|---|---|
Freeze the sender account. |
✓ | ✓ | ✓ |
Freeze the recipient account. |
✓ | ✓ | ✓ |
Freeze the certain partial amount token. |
✓ | ✓ | ✓ |
Freeze the specifics id. |
✗ | ✓ | ✓ |
Freeze the specifics id that are relevant to the root. |
✗ | ✓ | ✓ |
Freeze all id before or after specific hierarchy level. |
✗ | ✗ | ✓ |
ERC-20provide events and keep tracking eachTransfer,
but the problem is theERC-20model can’t separateclean moneyfromdirty money,
due to theERC-20not haveidto keep tracking each token when it’s moved.UTXOfacing challenge to combine multipleUnspentTransactionand spent as one,
in case, user want to spend value that greater that selectedUnspentTransaction.
Possible solution: prepare and batch as an array.
UTXOmaintain the amount of money or group of money in each individual transaction.
EachUnspentTransactionis not underlying any account,
so to spend the transaction, the caller needs to be the owner of the transaction that needs to be spent.Forestuse to modify an existing state rather than create a new transaction, like inUTXOdo,
it allows spending the token multiple times till it’s met0, TheForestmodel enables tracking of child/subtree structures.
providing a hierarchical view of token flows and relationships,
which is not possible in traditional token standards likeERC-20,ERC-1400, andERC-3643.
Granular Policy Enforcement
- Restrict the transaction with specific
id. - Restrict all transactions with specific
tokenLevel.- before
tokenLevelx - after
tokenLevelx - between
tokenLevelxandy
- before
- Restrict all transactions with specific root
id.
Reverse Topological Ordering of Transactions
One of the key benefits of the Forest is that it natively supports reverse topological traversal. Each token stores a reference to its parent token, allowing to efficiently iterate parentOf back to the root of the DAG.
This back-to-root traversal differs from a full DAG traversal. It only follows the lineage of a specific token id up to its root, rather than visiting all transactions in the DAG.
Spendable balance via off-chain
On-chain iteration to retrieve spendableBalanceOf can be gas-intensive and inefficient, especially for large DAGs or multiple sets of DAGs. To address this, the current spendableBalanceOf account can be determined off-chain by deploying a service that subscribes to events emitted by the contract. This service calculates the spendable balance by reconciling the account’s total balanceOf with any tokens that have been frozen or restricted due to hierarchical or forensic rules, providing an accurate representation of the amount available for transfer.
Backwards Compatibility
This standard is fully compatible with ERC-1155 and ERC-5615
Security Considerations
Denial Of Service
Run out of gas problem due to the operation consuming more gas if transferring in safeBatchTransferFrom.
Gas Limit Vulnerabilities
Exceeds block gas limit if the blockchain has a block gas limit lower than the gas used in the transaction.
Data Fragmentation
The Forest model tracks all assets within the system, which can be represented mathematically as
A^d: The decimals of the asset.
A^t: The total supply of the asset.
A^s: The possible asset is represented in the id.
A^s = A^t x A^d
While this ensures precision, the high granularity can increase storage needs.
Traditional finance often uses simpler decimals like 2, 4 or 6, avoiding excessive detail.
Adopting similar strategies could help balance granularity with efficiency. Or limit value as MINIMUM_AMOUNT check before spending.
Confidentiality
Maybe it can be linked to identity. from spending and behavior usage
High Complexity
Forest may introduce potential vulnerabilities such as reentrancy or misbehavior when applied with other smart contracts.
Standard and knowledge-based that might related to this topic
- An approach to anti-money laundering compliance for crypto assets
- Directed Acyclic Graph (DAG)
- Unspent Transaction Output (UTXO)
- What is money?
- ERC-20R and ERC-721R: Reversible Transactions on Ethereum

