Skip to main content

What is ERC20Confidential?

ERC20Confidential is a dual-mode confidential token. Unlike FHERC20—where every balance is encrypted and the public ERC-20 surface is only a decorative shim—ERC20Confidential gives each holder two real balances in the same contract:
  1. A public ERC-20 balance, inherited from the standard OpenZeppelin ERC20. balanceOf, transfer, approve, transferFrom, and totalSupply all work exactly as they do on any normal token.
  2. A confidential, FHE-encrypted balance, stored as an euint64 handle. Nobody—not even the contract—can read it without an ACL grant and a decryption permit.
Tokens move between the two layers with shield (public → confidential) and unshield → claim (confidential → public). Think of it as a normal ERC-20 with a built-in privacy pool baked directly into the token.

Two Balances, One Contract

A working public ERC-20 balance and a parallel encrypted balance for the same holder — no separate wrapper contract required.

Built-in Shield / Unshield

Convert value between the public and confidential layers directly on the token via shield() and unshield().

Fully ERC-20 Compatible

The public side is a genuine ERC-20, so existing wallets, DEXs, and explorers interact with it normally.

ERC-7984 Confidential Surface

The confidential side implements the same ERC-7984 API as FHERC20: confidentialTransfer, operators, and receiver callbacks.
ERC20Confidential is an abstract contract. You deploy it by inheriting from it and adding your own mint/access-control logic (see the Quick Start below).

ERC20Confidential vs FHERC20

Both live in the fhenix-confidential-contracts package and share the entire confidential-transfer API. The difference is what the public ERC-20 surface means. In short: FHERC20 is confidential-only with a fake public face. ERC20Confidential is a real ERC-20 with a confidential layer bolted on.
If you want a token that trades openly on public DeFi and supports optional private holdings, use ERC20Confidential. If you want everything to be private with no public balances at all, use FHERC20.

The Dual-Balance Model at a Glance

Every confidential unit is fully backed by real public tokens sitting in CONFIDENTIAL_POOL. When you shield, your public tokens are physically transferred into that pool; when you unshield and claim, they come back out. The encrypted ledger simply tracks who owns what inside the pool.
1

Public layer (inherited ERC-20)

Real, transparent balances. Anyone can see them. Standard transfer / approve / transferFrom apply.
2

Shield

Move public tokens into the confidential pool and mint yourself an equal encrypted balance.
3

Confidential layer (ERC-7984)

Transfer privately with confidentialTransfer, delegate with operators, and receive with callbacks — all on encrypted amounts.
4

Unshield → Claim

Burn confidential tokens (async), decrypt the burned amount off-chain, then claim the equivalent public tokens back out of the pool.
See The Dual-Balance Model for a full breakdown of the pool, the conversion rate, and the indicator sidecar token.

Decimals and the Conversion Rate

The public token can use any number of decimals (e.g. 18, to match mainstream ERC-20s). The confidential layer is capped at 6 decimals because encrypted balances are euint64 and must avoid overflow.
For an 18-decimal token, _conversionRate = 10^(18 - 6) = 10^12. One confidential unit equals 10^12 public base units. Shielded amounts are always rounded down to a whole multiple of this rate.
Query the two decimal values with decimals() (public) and confidentialDecimals() (confidential). For tokens with 6 or fewer decimals the rate is 1 and the two layers map 1:1.

Contract Variants

ERC20Confidential

Base (constructor) implementationAbstract dual-balance token. Inherit it and add your mint / ownership logic.

ERC20ConfidentialUpgradeable

Upgradeable variantIdentical API, built on OpenZeppelin’s upgradeable contracts with ERC-7201 namespaced storage and an __ERC20Confidential_init(...) initializer instead of a constructor.

ERC20ConfidentialIndicator

Sidecar display tokenAuto-deployed by the constructor. Shows non-revealing “activity” balances in wallets and explorers. All of its mutative functions revert.

IERC20Confidential

InterfaceIERC20Confidential is IFHERC20 — adds the shield/unshield bridge to the shared confidential-token surface.

Quick Start Example

Because ERC20Confidential is abstract, you inherit it and expose whatever minting policy you need. Minting creates public tokens; holders then shield them to go confidential.
Using the token end-to-end:
The example mint is unguarded for illustration only. In production, gate minting behind access control (e.g. Ownable / AccessControl).

Next Steps

Dual-Balance Model

The public/confidential split, the backing pool, the conversion rate, and the indicator sidecar token.

Shield & Unshield

The bridge between layers: synchronous shielding and the asynchronous unshield/claim flow.

Confidential Operations

Confidential transfers, the operator system, and transfer callbacks.

Best Practices

Backing, privacy boundaries, zero-replacement, and access-control pitfalls.