ERC-8227: Encrypted Token

Summary

I’m proposing a new ERC that defines a standard interface for fungible tokens with Fully Homomorphic Encrypted (FHE) balances and zero-knowledge transfer verification.

In short: an ERC-20 where nobody can see your balance or transfer amounts — but anyone can verify that every transfer is valid.

PR: Add ERC: Encrypted Token Interface by Valisthea · Pull Request #1680 · ethereum/ERCs · GitHub
Repository: GitHub - Valisthea/styx-erc-encrypted-token: ERC-XXXX: Encrypted Token Standard — FHE-encrypted balances with ZK transfer verification. By Kairos Lab. · GitHub

Author: Valisthea

The Problem

ERC-20 exposes everything. Balances, transfer amounts, approval values — all public. This creates five concrete issues:

  1. Portfolio exposure — anyone can query your holdings, enabling targeted social engineering and front-running.

  2. Transfer surveillance — on-chain graph analysis de-anonymizes users even across mixers.

  3. MEV extraction — visible pending amounts enable sandwich attacks. Privacy is the only structural MEV fix at the token layer.

  4. Governance coercion — token-weighted DAO voting with visible balances enables vote buying and political retaliation.

  5. Regulatory tension — GDPR Article 17 (right to erasure), MiCA, and HIPAA conflict with permanent public balance storage.

Why Existing Solutions Don’t Work

Mixers / Privacy layers (Tornado Cash, Aztec Connect) are external wrappers. A shielded token cannot be used in Uniswap, Aave, or Compound without unshielding first — defeating the privacy guarantee. They break DeFi composability.

Commitment-based approaches (Pedersen, Poseidon hashes) hide values but don’t support computation. You can’t add two commitments without the sender’s cooperation. A lending protocol can’t compute a liquidation threshold on committed collateral.

FHE-native chains (Fhenix, Zama’s fhEVM) exist but have proposed no standard interface. Each implementation invents its own API. Wallets and protocols can’t integrate generically.

No ERC currently standardizes encrypted token balances. This proposal fills that gap.

What This Standard Defines

An interface that extends ERC-20 metadata (name, symbol, decimals, totalSupply) with encrypted counterparts for all privacy-sensitive operations:

Encrypted Queries

  • encryptedBalanceOf(address) → returns FHE ciphertext (only owner can decrypt)

  • encryptionScheme() → identifies which FHE scheme is used (TFHE, OpenFHE, etc.)

  • publicKey() → contract’s FHE public key (users encrypt inputs with this)

Blind Transfers

  • blindTransfer(to, encryptedAmount, proof) → transfer with ZK-verified validity

  • blindTransferFrom(from, to, encryptedAmount, proof) → delegated blind transfer

  • Event: BlindTransfer(from, to, proofHash) — no amount leaked

Encrypted Approvals

  • blindApprove(spender, encryptedAmount, proof) → encrypted allowance

  • encryptedAllowance(owner, spender) → ciphertext of remaining allowance

Selective Disclosure (optional)

  • verifyBalancePredicate(account, predicate, proof) → proves “balance ≥ X” without revealing balance

Shield / Unshield Bridge (optional extension)

  • shield(amount) → move from public ERC-20 pool to encrypted pool

  • unshield(amount, proof) → move from encrypted pool to public pool

The standard is FHE-scheme-agnostic and ZK-proof-system-agnostic. Implementations can use TFHE, BFV, Groth16, Halo2, or any system that meets the specified requirements.

Key Design Decisions

FHE over commitments — FHE ciphertexts support homomorphic addition/comparison natively. The contract updates balances without decryption. A lending protocol can verify balance ≥ collateralThreshold homomorphically.

Predicate proofs over balance queries — DeFi rarely needs exact balances. It needs “is this enough?” — a boolean. verifyBalancePredicate gives protocols exactly what they need and nothing more.

Events without amountsBlindTransfer(from, to, proofHash) preserves indexability (who sent to whom) without leaking how much. The proofHash enables authorized off-chain auditors to verify.

Backwards-compatible with ERC-20 — the public metadata functions are identical. A token can implement both standards with shield/unshield as the bridge between pools.

Security Considerations

The draft includes detailed analysis of: ciphertext malleability (mitigated by proof binding), proof replay (nonce + chainId + contractAddress in public inputs), side-channel leakage (timing, gas — mitigated by constant-size circuits), quantum threats (lattice-based FHE is believed quantum-resistant), and key management (threshold Shamir SSS with ≥ 5 custodians).

The full specification, including Solidity interface, proof format, predicate encoding, and security analysis is in the repository.

Questions for the Community

  1. Scheme registry — should the standard define a bytes4 registry for FHE scheme identifiers, or is a free-form string sufficient?

  2. Proof size — what’s a reasonable SHOULD limit for proof size? 1KB? 4KB?

  3. totalSupply visibility — should totalSupply be mandatory public, or should confidential supply be part of the core interface (vs. an extension)?

  4. Fee interface — should the standard include an optional fee extension for FHE computation costs (pGas model), or leave this entirely to implementations?

  5. Key rotation — the draft includes keyVersion() and isKeyActive() for key lifecycle management. Is this overengineering at the standard level, or is it essential?

Looking forward to feedback from the community. This is the first ERC proposing native FHE-encrypted token balances — if something similar has been discussed before, I’d love to see the prior art.

— Valisthea

3 Likes

Have you looked at? ERC-7984: Confidential Fungible Token Interface
Because it could be really interesting, the key part here is going to be the implementation

1 Like

Thanks for pointing this out. ERC-7984 is a solid foundation for the token interface layer. Our work focuses on the layers that ERC-7984 explicitly treats as a black box: FHE computation verification (trustless proof that the co-processor computed correctly), cryptographic amnesia (provable key destruction), and post-quantum key infrastructure. We see these as complementary standards — ERC-7984 for the token interface, our ERCs for the cryptographic guarantees underneath. Happy to discuss how they fit together.

1 Like

Interesting, is there a reference implementation? Im not too familiar with FHE would love to contribute in any way possible

Hey @rafael-abuawad, thanks for the interest!

The specification is complete and available in the repo: github.com/Valisthea/styx-erc-encrypted-token — the full Solidity interface is in contracts/interfaces/.

The reference implementation is in progress. The interface is stable, but the concrete implementation (FHE backend + ZK verifier) is being built as part of STYX Protocol. It’s not trivial — the main challenge is wiring the FHE co-processor (we’re targeting TFHE via Zama’s libraries) to the on-chain proof verification loop.

I should also flag that @arr00 and the OpenZeppelin team have published ERC-7984 — a confidential token standard using pointer-based amounts. Their approach is more abstracted (technology-agnostic bytes32 pointers), while ours is more opinionated (explicit FHE ciphertexts + mandatory ZK proof verification + selective disclosure via verifyBalancePredicate). I see them as complementary — ERC-7984 for the generic interface, this ERC for the FHE-specific cryptographic guarantees that ERC-7984 explicitly leaves as a black box.

If you want to get involved, the most impactful areas right now:

  1. Review the interface — does the API make sense from a developer perspective? Anything confusing or missing?

  2. FHE integration — if you want to dive into FHE, Zama’s fhEVM docs and TFHE-rs are the best starting points. The core question is how blindTransfer proof generation works in practice.

  3. The other three ERCs in the STYX stack have zero competition and need review too: Cryptographic Amnesia (provable key destruction), FHE Computation Verification, and Post-Quantum Key Registry.

Happy to onboard you on any of these. Feel free to open issues on the repo or DM me.

1 Like

IMO, whether the totalSupply is visible may be dependent on the token’s purpose. Can totalSupply visibility be set in the constructor?

Good question — agreed, this should be deployment-configurable rather than mandatory either way.

The use cases genuinely diverge:

  • Public-supply tokens (stablecoins, governance tokens, listed assets) need a public totalSupply for oracles, DEX listings, MiCA/SEC reporting, and circulating-supply audits.
  • Confidential-supply tokens (private payroll, internal corporate tokens, redeemable loyalty points, HIPAA-scoped healthcare tokens) leak meaningful business signal even when balances are encrypted.

Concrete proposal for v0.2 of the interface:

function isTotalSupplyConfidential() external view returns (bool);
function totalSupply() external view returns (uint256);              // reverts if confidential
function encryptedTotalSupply() external view returns (bytes memory); // always available

The flag is set at construction and immutable afterwards — switching modes post-deployment opens a strictly worse threat model (an observer of the transition can de-anonymize prior state). Mint/burn events would be paired the same way: public Mint(amount) vs. BlindMint(proofHash) when confidential.

One implication worth flagging: if totalSupply is confidential, the invariant sum(balances) == totalSupply becomes harder for external auditors to verify cheaply. The way out is a periodic ZK proof published by the issuer (or by an authorized auditor key) that the encrypted total matches the sum of encrypted balances. I’ll add this to the Security Considerations section either way.

I’ll fold this into the next batch of revisions to the spec — likely once a few more open questions from the thread have settled.