TL;DR
- ERC-3770 is a human-friendly standard expressing chain-specific addresses in the format
eth:0x742d35..., complementing CAIP-10’s developer-centric design - OIP v0.1.0’s address field adopts the ERC-3770 format while storing
chainIdandaddrseparately, achieving both internal processing efficiency and external compatibility - Address ambiguity in cross-chain regulatory actions can lead to critical errors — freezing assets on the wrong chain results in regulatory failure and unintended harm to innocent parties
- An Address Resolution stage is added to the OSS validation pipeline, converting ERC-3770 addresses to internal representations and verifying validity
- Current ERC-3770 only expresses “which address on which chain” and lacks structure for regulatory context (identity, jurisdiction, regulatory state) — suggesting the need for future extension standards
Introduction: The Complexity Behind Simplicity
An Ethereum address like 0x742d35Cc6634C0532925a3b844Bc454e4438f44e is merely a 20-byte hexadecimal string. However, when this simple identifier exists simultaneously across multiple blockchains, we face a fundamental ambiguity problem.
This is the cross-chain address problem. An address generated from the same private key has an identical string across all EVM-compatible chains — Ethereum, Arbitrum, Optimism, Base, and others. Yet each chain’s instance of that address may hold completely different assets and states. On Ethereum, it might hold 100 ETH; on Arbitrum, tokenized bonds; on Optimism, nothing at all.
In our previous research, we defined protocol specifications for six regulatory actions. Actions like FREEZE, SEIZE, and CONFISCATE target specific assets. However, a command to “freeze assets at 0x742d35…” is unexecutable without specifying which chain’s assets are targeted.
This research explores the cross-chain address system problem and analyzes how OIP integrates the ERC-3770 standard to resolve this ambiguity.
Problem Definition: The Risks of Address Ambiguity
Same Address, Different Entities
Consider the following scenario:
A regulatory authority orders an asset freeze on address 0xABC... due to money laundering allegations. The address exists on four chains:
| Chain | Holdings | Value |
|---|---|---|
| Ethereum | 500 ETH | $1,500,000 |
| Arbitrum | Tokenized Treasury | $2,000,000 |
| Optimism | USDC | $50,000 |
| Base | None | $0 |
If the regulatory order targeted “tokenized treasury bonds on Arbitrum,” freezing the 500 ETH on Ethereum is an error. Conversely, in situations requiring all assets across all chains to be frozen, processing only some chains constitutes regulatory failure.
0x742d35Cc6634C0532925a3b844Bc454e4438f44e
0x742d35Cc6634C0532925a3b844Bc454e4438f44e
Limitations of Existing Oracle Systems
Most current oracle and bridge systems handle this problem at the application level. Each DeFi protocol independently manages the context of “which chain this address refers to.” This creates several issues:
- Lack of standardization: Different protocols use different methods to identify chains
- Reduced interoperability: Protocol A’s address representation cannot be interpreted by Protocol B
- Regulatory enforcement complexity: Regulators must understand different formats for each protocol
Cross-Chain Address Standards: CAIP-10 and ERC-3770
CAIP-10: Designed for Developers
Chain Agnostic Improvement Proposal 10 is an account identifier standard encompassing the entire blockchain ecosystem[1].
Format:
chain_id + ":" + account_address
Example:
eip155:1:0x742d35Cc6634C0532925a3b844Bc454e4438f44e
Here, eip155:1 is a CAIP-2 chain identifier, meaning chain ID 1 (Ethereum Mainnet) in the EIP-155 namespace.
Advantages:
- Encompasses all blockchain ecosystems (EVM, Cosmos, Solana, etc.)
- Optimized for machine parsing
- Clear structure for chain IDs
Limitations:
- Difficult for humans to read — it’s not immediately obvious that
eip155:42161refers to Arbitrum - Unsuitable for exposure to general users
ERC-3770: Human-Friendly Extension
ERC-3770, proposed by ligi in 2021, maintains CAIP-10’s technical rigor while adding human-friendly representation[2].
Format:
shortName + ":" + address
Examples:
eth:0x742d35Cc6634C0532925a3b844Bc454e4438f44e arb1:0x742d35Cc6634C0532925a3b844Bc454e4438f44e oeth:0x742d35Cc6634C0532925a3b844Bc454e4438f44e base:0x742d35Cc6634C0532925a3b844Bc454e4438f44e
Key design decisions:
- Short Name Registry: Uses official abbreviations managed in the ethereum-lists/chains repository[3]
- CAIP-3 Mapping: Each short name corresponds to a CAIP-3 blockchain ID
- Simplicity: A single colon (
:) separates chain and address
“The goal is to provide a more human-readable format while maintaining compatibility with existing standards.”
— ERC-3770 Abstract
The Relationship Between the Two Standards
ERC-3770 does not replace CAIP-10 but rather complements it at the user interface layer. The recommended approach is to use CAIP-10 format for internal processing and ERC-3770 format for user display.
ERC-3770 Integration Design in OIP
Background of Design Decisions
In the OIP v0.1.0 specification, the address field is defined as follows:
"address": {
"chainId": "string",
"addr": "string"
}
This structure stores the ERC-3770 format (eth:0x742d35...) in separated fields. Why not store it as a single string?
Reason 1: Processing Efficiency
Filtering by chain ID is frequent during regulatory action validation. When chainId exists as a separate field, direct indexing is possible without string parsing.
// With separated storage: O(1) access
if msg.Address.ChainId == "eip155:42161" {
// Arbitrum-specific processing
}
// With single string: parsing required each time
parts := strings.Split(msg.Address, ":")
if parts[0] == "arb1" {
// Parsing overhead + short name conversion needed
}
Reason 2: Separation of Internal and External Representations
- External representation (user-facing):
arb1:0x742d35...(ERC-3770) - Internal representation (system processing):
chainId: "eip155:42161", addr: "0x742d35..."(CAIP-based)
This separation ensures that changes to display format do not affect internal logic.
Reason 3: Extensibility
When additional metadata (checksum verification results, contract status, etc.) needs to be included in the address field in the future, a structured format is advantageous.
Address Resolution Process
When OSS receives an OIP message, it interprets the address field through the following process:
package oss
import (
"errors"
"regexp"
"strings"
)
var (
ErrInvalidAddressFormat = errors.New("INVALID_ADDRESS_FORMAT")
ErrUnknownChainShortName = errors.New("UNKNOWN_CHAIN_SHORT_NAME")
ErrInvalidChecksum = errors.New("INVALID_ADDRESS_CHECKSUM")
ErrChainNotSupported = errors.New("CHAIN_NOT_SUPPORTED")
)
// ERC-3770 format regular expression
var erc3770Pattern = regexp.MustCompile(`^([a-z0-9]+):0x([a-fA-F0-9]{40})$`)
// Short name to CAIP-2 chain ID mapping
var shortNameToChainId = map[string]string{
"eth": "eip155:1",
"arb1": "eip155:42161",
"oeth": "eip155:10",
"base": "eip155:8453",
"matic": "eip155:137",
"scr": "eip155:534352", // Scroll
// ... based on ethereum-lists/chains registry
}
type ResolvedAddress struct {
ChainId string // CAIP-2 format
Address string // Checksummed address
OriginalInput string // Original input
IsContract bool // Contract status (optional check)
}
func (r *AddressResolver) ResolveERC3770(input string) (*ResolvedAddress, error) {
// 1. Format validation
matches := erc3770Pattern.FindStringSubmatch(input)
if matches == nil {
return nil, ErrInvalidAddressFormat
}
shortName := matches[1]
rawAddress := "0x" + matches[2]
// 2. Convert short name to CAIP-2 chain ID
chainId, exists := shortNameToChainId[shortName]
if !exists {
return nil, ErrUnknownChainShortName
}
// 3. Check supported chain status
if !r.isSupportedChain(chainId) {
return nil, ErrChainNotSupported
}
// 4. EIP-55 checksum validation and normalization
checksummedAddr, err := r.toChecksumAddress(rawAddress)
if err != nil {
return nil, ErrInvalidChecksum
}
return &ResolvedAddress{
ChainId: chainId,
Address: checksummedAddr,
OriginalInput: input,
}, nil
}
Connection to Regulatory Actions
In the regulatory action messages defined in our previous research, targetAsset identifies the asset. The role of the address system is to specify the location of this asset.
{
"regulatoryPayload": {
"actionType": "FREEZE",
"targetAsset": {
"assetId": "bytes32",
"assetType": "ERC20",
"currentStateHash": "bytes32"
},
"affectedAddresses": [
{
"chainId": "eip155:42161",
"addr": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
}
]
}
}
The affectedAddresses array specifies the chain-address pairs where the regulatory action will be applied. If the same asset is bridged across multiple chains, all relevant chain-address pairs must be included.
Cross-Chain Address Validation Pipeline
OSS Validation Stage Extension
The Address Resolution stage precedes the 4-stage validation pipeline defined in our previous research:
Address-Asset Mapping Validation
It must be verified that the address specified in a regulatory action actually holds the target asset:
func (v *Validator) ValidateAddressAssetMapping(
ctx context.Context,
addresses []ResolvedAddress,
targetAsset *TargetAsset,
) error {
for _, addr := range addresses {
// Check asset holdings on the chain
balance, err := v.crossChainBridge.QueryBalance(
ctx,
addr.ChainId,
addr.Address,
targetAsset.AssetId,
)
if err != nil {
return fmt.Errorf("failed to query balance on %s: %w", addr.ChainId, err)
}
// Applying regulatory action to address with zero balance is meaningless
if balance.IsZero() {
v.logger.Warn("Address has zero balance for target asset",
"chainId", addr.ChainId,
"address", addr.Address,
"assetId", targetAsset.AssetId,
)
// Warning only, proceed — may be regulator's intent
}
}
return nil
}
Security Considerations
Short Name Conflicts and Abuse
ERC-3770’s short names are managed in the ethereum-lists/chains registry. However, the following risks exist:
1. Similar Name Confusion
eth → Ethereum Mainnet (legitimate) eTh → Case variation (ERC-3770 only allows lowercase, but UI-level confusion possible) eth2 → Non-existent chain (malicious creation attempt)
2. Registry Update Delays
When new chains are added or short names change, delays in updating OSS’s mapping table can cause temporary inconsistencies.
Countermeasures:
// Periodic registry synchronization
func (r *AddressResolver) SyncChainRegistry(ctx context.Context) error {
// Fetch latest data from ethereum-lists/chains
latestRegistry, err := r.fetchChainRegistry(ctx)
if err != nil {
return err
}
// Conflict detection
for shortName, newChainId := range latestRegistry {
if existingChainId, exists := r.shortNameToChainId[shortName]; exists {
if existingChainId != newChainId {
r.logger.Error("Chain ID conflict detected",
"shortName", shortName,
"existing", existingChainId,
"new", newChainId,
)
// On conflict, retain existing value, manual review required
continue
}
}
r.shortNameToChainId[shortName] = newChainId
}
return nil
}
Importance of Checksum Verification
The EIP-55 checksum is a simple but effective mechanism for detecting address typos[4]. Since address errors in regulatory actions can lead to asset freezes on wrong targets, OSS performs checksum verification on all addresses.
func (r *AddressResolver) toChecksumAddress(address string) (string, error) {
// Normalize to lowercase
addr := strings.ToLower(strings.TrimPrefix(address, "0x"))
// Keccak-256 hash
hash := crypto.Keccak256([]byte(addr))
// Apply checksum
var result strings.Builder
result.WriteString("0x")
for i, c := range addr {
if c >= '0' && c <= '9' {
result.WriteByte(byte(c))
} else {
// Uppercase if corresponding hash nibble is 8 or higher
hashNibble := hash[i/2]
if i%2 == 0 {
hashNibble = hashNibble >> 4
} else {
hashNibble = hashNibble & 0x0F
}
if hashNibble >= 8 {
result.WriteByte(byte(c) - 32) // Uppercase
} else {
result.WriteByte(byte(c))
}
}
}
return result.String(), nil
}
Limitations and Future Directions
Structural Limitations of ERC-3770
Current ERC-3770 only expresses “which address on which chain.” However, additional information is needed in the regulatory compliance context:
| Required Information | ERC-3770 Support | Notes |
|---|---|---|
| Chain identification | ✓ | Provided via short name |
| Address | ✓ | 0x-prefixed address |
| Owner identity (OCID/RAI) | ✗ | Separate lookup required |
| Current regulatory state | ✗ | Separate lookup required |
| Applicable jurisdiction | ✗ | Separate lookup required |
This information is currently managed as separate fields in OIP. However, if such context were embedded in the address itself, interoperability between systems would significantly improve.
Extension Possibilities
Conceptually, the following extension could be considered:
// Current ERC-3770 arb1:0x742d35Cc6634C0532925a3b844Bc454e4438f44e // With regulatory context (conceptual) arb1:0x742d35Cc6634C0532925a3b844Bc454e4438f44e?rai=0x...&state=ACTIVE
While this may appear as simple query parameter addition, it carries the significance of declaring at the standard level that “all EVM addresses are potential regulatory subjects.” Technical implementation is straightforward, but the interoperability improvement when the entire EVM ecosystem adopts this would be substantial.
The necessity and specific design of such extension standards will be explored after ERC-TRUST work is complete, based on actual implementation experience.
Conclusion
In this research, we analyzed the problems caused by address ambiguity in cross-chain environments and examined how OIP integrates the ERC-3770 standard.
To summarize the key design decisions:
- ERC-3770 adoption: Human-friendly address representation with CAIP-10 compatibility
- Separated storage structure: Ensures processing efficiency and extensibility
- Address Resolution stage addition: Address validity verification as a preceding stage in the OSS validation pipeline
The address system defines “who” regulatory actions target. Combined with the “what” (six regulatory actions) defined in our previous research, OIP continues to build the technical foundation for cross-chain regulatory enforcement.
In our next research, we will explore message types and routing, analyzing how these regulatory action messages are delivered to appropriate destinations.
References
- Chain Agnostic Standards Alliance. (2020). CAIP-10: Account ID Specification. https://chainagnostic.org/CAIPs/caip-10
- ligi. (2021). EIP-3770: Chain-specific addresses. https://eips.ethereum.org/EIPS/eip-3770
- ethereum-lists. (2024). chains: A list of EVM-based chains. https://github.com/ethereum-lists/chains
- Buterin, V. (2016). EIP-55: Mixed-case checksum address encoding. https://eips.ethereum.org/EIPS/eip-55





