Oracle-Permissioned ERC-20 with ZK-Verified ISO 20022 Payment Instructions

Proposed by Ant International: https://www.ant-intl.com/en/

Simple Summary

Extend ERC-20 so that a token transfer is valid only when an external “Transfer Oracle” pre-approves it. Approvals reference an off-chain ISO 20022 payment instruction (pain.001 instruction) that is proven on-chain via a zero-knowledge proof. The scheme is issuer-agnostic, proof-system-agnostic, and network-agnostic (L1/L2).

Abstract

This EIP standardises:

  • ITransferOracle – a minimal interface that any ERC-20-compatible contract can consult to decide whether transfer / transferFromshould succeed.
  • approveTransfer flow – whereby an issuer (token owner) deposits a one-time approval in the oracle, accompanied by a zk-proof attesting that the approval matches a canonicalised ISO 20022 payment message.
  • canTransfer query – whereby the token contract atomically consumes an approval when the holder initiates the transfer.
  • Generic data structures, events, and hooks that allow alternative permissioning logics (KYC lists, travel-rule attestations, CBDC quotas) to share the same plumbing.

Reference circuits, SDKs, and Solidity templates are provided, but the standard admits any zk-proof system and any JSON (or future XML) schema.

Motivation

Institutional tokenisation requires both ERC-20 fungibility and legally enforceable control over who may send value to whom and why.
Hard-coding rules in every token contract is brittle and non-standard. Centralising rules in a singleton oracle and proving off-chain documentation on-chain gives:

  • Compliance traceability – every transfer links to a signed payment
    order recognised by traditional finance systems.
  • Issuer flexibility – any institution can swap out its oracle logic
    without breaking ERC-20 compatibility.
  • Composability – DeFi protocols can interact with permissioned tokens
    using familiar ERC-20 flows, while downstream permission checks are
    encapsulated in the oracle.

Specification

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

Interfaces

/// @notice One-time ZK-backed approval for a single transfer.
struct TransferApproval {
    address  sender;
    address  recipient;
    uint256  minAmt;
    uint256  maxAmt;
    uint256  expiry;      // UNIX seconds; 0 == never
    bytes32  proofId;     // keccak256(root‖senderHash‖recipientHash)
}

/// @title  External oracle consulted by permissioned tokens.
interface ITransferOracle {
    /// @dev   Verifies zk-proof and stores a one-time approval.
    /// @return proofId – unique handle for off-chain reconciliation
    function approveTransfer(
        TransferApproval calldata approval,
        bytes calldata proof,          // ABI-encoded a,b,c|proof
        bytes calldata publicInputs      // circuit-specific
    ) external returns (bytes32 proofId);

    /// @dev   Atomically consumes an approval that covers `amount`.
    ///        MUST revert if no such approval exists.
    function canTransfer(
        address token,
        address issuer,
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bytes32 proofId);
}

ERC-20 Hook

A Permissioned ERC-20 MUST replace the standard internal
_update(address from, address to, uint256 amount) logic with:

bytes32 proofId = ORACLE.canTransfer(address(this), owner(), from, to, amount);
// MUST revert on failure
_super._update(from, to, amount);
emit TransferValidated(proofId);

ORACLE is an immutable constructor argument. (up to design)

Events

event TransferApproved(
    address indexed issuer,
    address indexed sender,
    address indexed recipient,
    uint256 minAmt,
    uint256 maxAmt,
    uint256  expiry,
    bytes32 proofId
);

event ApprovalConsumed(
    address indexed issuer,
    address indexed sender,
    address indexed recipient,
    uint256 amount,
    bytes32 proofId
);

event TransferValidated(bytes32 indexed proofId);

Canonicalisation of ISO 20022 JSON

  • Apply RFC 8785: JSON Canonicalization Scheme (JCS).
  • Convert numeric amounts to integers of 10⁻³ (milli-units) to avoid floats.
    • This means that all monetary amounts in the ISO 20022 payment instructions must be converted from decimal numbers (e.g., 1.50 USD) into integers representing milli-units (e.g., 1500), where:
      1 milli-unit = 0.001 (10⁻³) of the base currency unit.
  • UTF-8 NFC normalisation; strip insignificant whitespace.

Merkle-and-Proof Requirements (Flex-Slot)

The merkle tree root is used to verify that the public inputs actually come from the original off-chain payment instruction.

Public Inputs Purpose Rationale
root Merkle root of doc Data-integrity
sender Poseidon(Dbtr) Privacy-preserving ID
recipient Poseidon(Cdtr) Same as above
minAmt/maxAmt Value bounds Anti-front-running
expiry Approval TTL Prevents replay

The oracle MAY accept additional public inputs, e.g., currency code, jurisdiction, sanctions list epoch

Upgradeability

  • Token and Oracle MAY be behind EIP-1967 proxies.
  • Verifier is stateless; safe to swap when a new circuit (PLONK, STARK…) is adopted.

Rationale

Keeping oracle logic out of the token contract preserves fungibility and lets one oracle serve hundreds of issuers.TransferApprovaluses amount ranges so issuers can sign a single approval before the final FX quote is known.canTransferreturns theproofId, enabling downstream analytics and
regulators to join on-chain transfers with off-chain SWIFT messages.

Backwards Compatibility

Existing ERC-20 consumers remain unaffected; a failed transfer simply reverts. Wallets and exchanges should surface the oracle’s revert messages so users know they lack approval.

Security Considerations

  • Replay Protection – approvals are one-time and keyed by proofId.
  • Oracle Risk – issuers SHOULD deploy dedicated oracles; a compromised oracle only endangers its own tokens.
  • Trusted Setup – reference circuits use Groth16; institutions MAY adopt STARKs to remove setup risk.

Reference Implementation

Copyright

Copyright and related rights waived via CC0

2 Likes

super interested was talking about this with TradeFi recently would love to chat more.

Thanks for taking a look! Please don’t hesitate to ask any more questions you may have about the proposal.

This proposal is to extend the ERC-20 standard to require mandatory external oracle approvals linked to ISO 20022-compliant payment messages via zero-knowledge proofs.

While innovative, this mandatory approach fundamentally diverges from Ethereum’s core ethos of openness, permissionlessness, and composability.

The main reasons why the current proposal is problematic include:

  • Permissioning Overreach: By mandating oracle-based approvals, the proposal restricts token transfers, undermining Ethereum’s fundamental value of decentralization and open access.
  • Interoperability Challenges: This approach risks creating significant friction in the existing Ethereum ecosystem, potentially fragmenting liquidity and complicating integrations with decentralized finance (DeFi) protocols, wallets, and exchanges that currently operate seamlessly with standard ERC-20 tokens.
  • Complexity and User Confusion: Introducing a mandatory compliance layer risks confusion among users and developers, complicating token interactions and slowing down innovation.

Recognizing the importance of institutional and regulated adoption, aligning Ethereum tokens with global financial compliance standards such as ISO 20022 remains valuable. However, I believe this does not require altering the core ERC-20 standard through an EIP.

Instead, I propose adopting design principles that preserve the core ERC-20 compatibility while enabling optional compliance checks for institutional use cases:

  • ERC-20 Compatibility: Tokens remain fully ERC-20 compliant, maintaining current permissionless functionality and interoperability.
  • Optional Compliance Features: Institutions could introduce compliance via separate optional entry points (e.g., a clearly distinguished function like transferWithISOApproval). These would require external oracle validation only when explicitly invoked.
  • Clear Documentation and Distinction: Ensure explicit documentation to distinguish between standard (permissionless) token transfers and compliance-required (permissioned) transfers to minimize confusion and integration complexity.

Furthermore, the Enterprise Ethereum Alliance (EEA) could play a pivotal role by hosting workshops and developing standardized design principles in collaboration with Ant International and other institutional stakeholders. These workshops would aim to establish clear guidelines and best practices for compliant token implementations that respect Ethereum’s open ethos.

2 Likes

Hi Redoudou, appreciate your comprehensive reply. Allow me to clarify some of the feedback received here.

  1. This EIP does not force every ERC-20 token to integrate an oracle. It simply defines a standard interface that permissioned tokens can adopt. Unpermissioned tokens incur zero overhead.

  2. Defi protocols, wallets and explorers continue to use the exact same ERC-20 abi. They only see a revert on transfer if the user has not obtained the required approval - no new function signatures or hooks to learn.

  3. The proposal ships references circuits, SDKs and Solidity templates. For most devs/builders, spinning up a compliant oracle is a matter of configuration, not reinventing zk-proof mechanics from scratch.

  4. Many tokens today already implement pausable, blacklistable, or mint capable extensions - and those are widely accepted. This EIP simplifies a standard pattern for compliance-driven permissioning, rather than each project inventing its own bespoke mechanism.

  5. By centralising compliance logic in oracles, we actually reduce fragmentation - one comprehensively-audited oracle per regulator or service provider can potentially serve hundreds of tokens, rather than countless bespoke implementations hidden in individual token contracts.

  6. Institutions can deploy parallel permissioned token contracts alongside fully permissionless ones. Users and builders choose whichever variant suits their needs which actually maintains the open-access ethos for the broader ecosystem.

In summary, the EIP actually introduces an opt-in, standardised and modular way to have legally enforceable compliance onto ERC-20 tokens without breaking any existing tooling or fragmenting liquidity for the permissionless majority - it’s simply for institutions who may require permissioning functionality. Please do share your thoughts on what I have explained and if there are any questions and clarifications you may require as well, happy to have an extended open discussion.

1 Like