---
eip: 8106
title: RWA Event-based Compliance Framework
description: Event-driven compliance framework for Real World Asset tokens with entity classification and audit events
author: Andrew Wang (@wz14) <zhuowangy2k@outlook.com>, Jack Yin (@0xjackey) <0xjackey@gmail.com>
discussions-to: https://ethereum-magicians.org/t/erc-8106-rwa-event-based-compliance-framework/27219
status: Draft
type: Standards Track
category: ERC
created: 2025-12-16
requires: 20
---

## Abstract

This standard defines an event-based compliance framework for Real World Asset (RWA) tokens on [ERC-20](./eip-20.md), providing:

1. A standardized entity classification system distinguishing between Compliance Entities (CE) and Decentralized Entities (DE)
2. Event-driven compliance observation enabling auditability through standardized events and actual value flows, without enforcing hard transaction reverts

This standard is intentionally minimal and does not prescribe business-specific RWA workflows, off-chain settlement mechanisms, minting policies, or specific transfer patterns.

## Motivation

Real World Asset tokenization requires compliance observability that existing [ERC-20](./eip-20.md) tokens do not provide:

### Missing Capabilities

1. **Entity Classification**: No standardized way to distinguish regulated corporate entities from decentralized participants
2. **Compliance Observability**: No uniform event semantics for tracking compliance-relevant transfers
3. **Flexible Enforcement**: Existing standards use hard reverts, making them incompatible with diverse regulatory frameworks

### Why Event-Based?

This standard adopts an event-driven approach rather than enforcement through reverts:

- **Regulatory Flexibility**: Different jurisdictions can interpret the same events differently
- **Adaptability**: Compliance rules can evolve without contract upgrades
- **Lower Costs**: Events are cheaper than state-based enforcement

## 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.

### Definitions

- **Compliance Entity (CE)**: An address representing a regulated legal entity (e.g., corporate treasury, custody account)
- **Decentralized Entity (DE)**: An address representing a decentralized participant (e.g., end users, routers, settlement contracts)
- **BizID**: A business correlation identifier (hash) linking related transfers to a single workflow
- **Soft Policy**: Compliance policy expressed through event labeling, not transaction reversion

### Entity Registry

Compliant implementations MUST provide an entity classification registry that assigns each address to one of three categories.

```solidity
interface IERC8106EntityRegistry {
    enum EntityType { DECENTRALIZED_ENTITY, COMPLIANCE_ENTITY }

    event EntityTypeUpdated(
        address indexed entity,
        EntityType entityType,
        bytes32 indexed reasonHash,
        address indexed operator
    );

    /// @notice Returns the entity type of an address
    /// @dev MUST return DECENTRALIZED_ENTITY for addresses not explicitly registered as COMPLIANCE_ENTITY
    function entityTypeOf(address entity) external view returns (EntityType);
}
```

#### Registry Requirements

Implementations MUST satisfy the following requirements:

1. **Default Classification**: The `entityTypeOf` function MUST return `DECENTRALIZED_ENTITY` for any address not explicitly registered as `COMPLIANCE_ENTITY`
2. **Explicit Registration**: Only addresses explicitly registered SHOULD return `COMPLIANCE_ENTITY`
3. **Update Events**: Entity type changes MUST emit `EntityTypeUpdated` events
4. **Reason Tracking**: The `reasonHash` parameter MUST reference off-chain documentation (e.g., KYC records, legal entity registration)
5. **Operator Accountability**: The `operator` parameter MUST identify the address that authorized the update

#### Implementation Note

The registry MAY be:
- Embedded within the token contract itself
- Implemented as a separate contract referenced by the token
- Shared across multiple tokens within an ecosystem

### Compliance Events

Compliant implementations MUST emit standardized events that capture compliance-relevant transfer information, including entity classifications, compliance flags, and business correlation identifiers.

```solidity
interface IERC8106ComplianceEvents is IERC8106EntityRegistry {
    enum ComplianceFlag {
        OK,
        DIRECT_DE_TO_CE,           // DE -> CE observed
        DIRECT_CE_TO_DE,           // CE -> DE observed
        POLICY_CUSTOM              // project-defined policy
    }

    event ComplianceObserved(
        bytes32 indexed bizId,
        address indexed token,     // the ERC-20 token contract address
        address indexed from,
        address to,
        uint256 amount,
        EntityType fromType,
        EntityType toType,
        ComplianceFlag flag,
        bytes32 policyTag          // project-defined categorization tag
    );
}
```

#### Event Requirements

Implementations MUST satisfy the following requirements:

1. **Complete Information**: Each `ComplianceObserved` event MUST include all specified parameters
2. **Accurate Classification**: The `fromType` and `toType` MUST reflect the actual entity types at the time of the transfer
3. **Consistent BizID**: All legs of a multi-leg transfer MUST use the same `bizId` value
4. **Token Identification**: The `token` parameter MUST be the address of the [ERC-20](./eip-20.md) token contract

#### Recommended Flagging Policy (Non-normative)

Implementations SHOULD apply the following flagging heuristics:

- `DIRECT_DE_TO_CE`: When `fromType == DECENTRALIZED_ENTITY` and `toType == COMPLIANCE_ENTITY`
- `DIRECT_CE_TO_DE`: When `fromType == COMPLIANCE_ENTITY` and `toType == DECENTRALIZED_ENTITY`
- `OK`: When transfer does not cross compliance boundaries (DE↔DE or CE↔CE)
- `POLICY_CUSTOM`: For project-specific compliance scenarios

#### Event-Based Compliance

Implementations SHOULD NOT revert transactions solely based on compliance flags. This event-based approach enables:

- Off-chain compliance review and decision-making
- Flexible interpretation across different regulatory jurisdictions
- Time-delayed enforcement where appropriate (e.g., 24-hour review periods)

Compliance actions (transaction reversals, account freezes, regulatory reporting) SHOULD be handled through separate mechanisms such as:

- Off-chain monitoring systems
- On-chain governance modules
- Dedicated compliance management contracts

## Rationale

### Event-Driven Model

Events rather than reverts because:

- Different jurisdictions can interpret events differently
- Cheaper than state-based enforcement (~2000 gas per event vs state writes)
- Enables time-delayed enforcement where appropriate

### Soft Policy Flags

Compliance flags are informational, not enforced:

- Projects decide whether to revert based on flags
- Off-chain systems can alert, review, or freeze post-transaction
- Supports evolving regulations without contract changes

### Auditability Design

Auditors reconstruct transaction flows using:

1. **Value Flows**: Every `ComplianceObserved` event corresponds to a real [ERC-20](./eip-20.md) balance change
2. **Standardized Events**: Uniform event structure for machine-readable compliance data
3. **BizID Correlation**: Link multiple transfers to a single business transaction

For a given `bizId`, auditors can query all `ComplianceObserved` events, build directed graphs from `from`/`to`/`amount` fields, check for direct CE/DE transfers using the `flag` field, and cross-reference `reasonHash` with off-chain KYC/AML systems.

## Reference Implementation

### Implementation Patterns

**Embedded Registry**: Store entity types in the token contract itself

```solidity
contract RWAToken is ERC20, IERC8106ComplianceEvents {
    mapping(address => bool) private _isComplianceEntity;
    
    function entityTypeOf(address entity) public view returns (EntityType) {
        return _isComplianceEntity[entity] 
            ? EntityType.COMPLIANCE_ENTITY 
            : EntityType.DECENTRALIZED_ENTITY;
    }
    // ...
}
```

**Separate Registry**: Share registry across multiple tokens

```solidity
contract EntityRegistry is IERC8106EntityRegistry {
    mapping(address => bool) private _isComplianceEntity;
    
    function entityTypeOf(address entity) external view returns (EntityType) {
        return _isComplianceEntity[entity]
            ? EntityType.COMPLIANCE_ENTITY
            : EntityType.DECENTRALIZED_ENTITY;
    }
    
    function registerComplianceEntity(address entity, bytes32 reasonHash) external onlyAdmin {
        _isComplianceEntity[entity] = true;
        emit EntityTypeUpdated(entity, EntityType.COMPLIANCE_ENTITY, reasonHash, msg.sender);
    }
    // ...
}
```

**Policy Tag Conventions**: Use consistent hashes for interoperability

```solidity
bytes32 constant TAG_PAYMENT = keccak256("PAYMENT");
bytes32 constant TAG_TREASURY = keccak256("TREASURY");
bytes32 constant TAG_REFUND = keccak256("REFUND");
```

### Example Use Cases

**Compliance Monitoring:** A regulated stablecoin tracks all CE↔DE flows for monthly regulatory reports without blocking transactions.

**Atomic Multi-Leg Transfers:** While not part of this standard, projects can build on these primitives to implement atomic multi-hop transfers:

```solidity
// User pays → Treasury → Operational account (single transaction)
function purchaseRWA(bytes32 orderId, uint256 amount) external {
    // Leg 1: DE → CE
    token.transferFrom(msg.sender, treasury, amount);
    emit ComplianceObserved(orderId, token, msg.sender, treasury, amount, 
                           DE, CE, DIRECT_DE_TO_CE, TAG_PAYMENT);
    
    // Leg 2: CE → CE
    token.transferFrom(treasury, operational, amount);
    emit ComplianceObserved(orderId, token, treasury, operational, amount,
                           CE, CE, OK, TAG_TREASURY);
}
```

This pattern enables single user-facing transactions, unified `bizId` for audit correlation, and per-leg compliance events.

**Time-Delayed Enforcement:** Detect suspicious patterns in events, then freeze accounts off-chain or via governance after review.

## Security Considerations

**Event Integrity:** Implementations MUST emit `ComplianceObserved` events only after actual [ERC-20](./eip-20.md) balance changes. Emitting events without value movement compromises auditability.

## Copyright

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