What Are Confidential ERC20 (cERC20) Tokens?

Transparency is a core principle of public blockchains, with any user able to verify that the public record has not been tampered with. When Satoshi Nakamoto wrote the Bitcoin white paper, it was in clear opposition to the opaque nature of the banks that had been responsible for the 2008 financial crisis, whose holdings were obscured from the public. The transparent nature of blockchains has many advantages, enabling anyone to verify that the ledger has not been tampered with, to give one important example.

But total transparency is also what’s holding the adoption of blockchains back. There are many use cases, from payroll to governance, where confidentiality is vital. Financial institutions are unlikely to be comfortable with bringing assets onchain if anyone in the world can see exactly which client owns what—regulators even less so. Confidentiality is easy to achieve in Web2, it should be in Web3 too.

Ideally onchain confidentiality would be achieved at the token level, but historically this has not been possible. Commitment approaches using technologies like Zero-Knowledge Proofs can provide privacy but sacrifice the composability that makes blockchains so versatile to build on. 

At Inco, we’ve built a solution to this problem. Using a novel form of encryption called Fully Homomorphic Encryption (FHE), standard ERC20 tokens can achieve confidentiality without sacrificing composability. What’s more, confidentiality can be programmed at the smart contract level, with permissioned access to details like transaction amounts granted to specific parties while hidden from the public—a huge requirement for institutions who need to abide by regulations such as Anti-Money Laundering (AML) rules. 

We collaborated with the team at Circle Research on a framework for this confidential ERC20 (cERC20) token standard. In this piece, we’ll go into detail about cERC20s and exactly how they work on the code and encryption level before giving an overview of use cases unlocked by onchain FHE-powered confidentiality via the cERC20 standard.

What Are ERC20 Tokens?

Before we dive into cERC20s, let’s outline what their original ERC20 version is.

ERC20 is a technical standard used for fungible tokens on the Ethereum blockchain. Fungible tokens are interchangeable units of value, meaning one token is identical to another. The ERC20 standard provides a blueprint for creating these tokens, specifying the functions and events that a token smart contract must implement to be compatible with Ethereum-based tools and services.

Fungibility vs. Non-Fungibility

Fungible tokens like ERC20s represent assets where each unit has the same value and properties as another, such as cryptocurrencies or stablecoins. In contrast, non-fungible tokens (NFTs), represented by token standards including ERC721 and ERC1155, represent unique items such as art or collectibles.

Code Breakdown

The ERC20 standard defines a set of variables and functions to be implemented. Below is an explanation with relevant code snippets:

Variables

  • Address: The Ethereum address of the token holder.
  • Balance: The number of tokens held by an address.
mapping(address => uint256) private balances;
string public name;
string public symbol;
uint8 public decimals;

This code defines the fundamental things of the token. Notice that balances mapping is defined from address to integer.

Functions

  • balanceOf function takes a user address as an argument and returns the corresponding balance that is owned by the address account.
  • transfer function takes a user address and an integer to transfer the input amount of tokens to the input address.
  • mint function takes a user address and an integer to create the input amount of tokens to the input address and increases the total supply.
  • Similarly, burn function takes a user address and an integer to remove the input amount of tokens from the input address and decreases the total supply.
function balanceOf(address account) public view returns (uint256) {
    return balances[account];
}

function transfer(address recipient, uint256 amount) public {
    require(balances[msg.sender] >= amount, "Insufficient balance");
    balances[msg.sender] -= amount;
    balances[recipient] += amount;
}

function mint(address account, uint256 amount) public {
    balances[account] += amount;
    totalSupply += amount;
}

function burn(address account, uint256 amount) public {
    balances[account] -= amount
    totalSupply -= amount
}

What Are the Issues With ERC20s?

While the ERC20 token standard has brought the crypto ecosystem forward leaps and bounds, there are several prominent areas for improvement.

  • Lack of Privacy: All transactions and balances are publicly visible on the blockchain.
  • Susceptibility to Frontrunning: Transparent transactions can lead to frontrunning attacks in decentralized finance (DeFi).
  • Limited Applicability: Inability to meet privacy requirements for institutional and regulatory compliance.

What Is Fully Homomorphic Encryption (FHE)?

Now let’s dive into the core encryption technology underpinning cERC20s: Fully Homomorphic Encryption (FHE).

FHE is a cryptographic technique that allows computations to be performed on encrypted data without decrypting it. The results of these computations remain encrypted and can only be decrypted by the data owner. This feature ensures privacy while enabling functionality.

FHE schemes are based on hard mathematical problems such as Learning With Errors (LWE). They involve ciphertexts that can be manipulated algebraically to produce meaningful results without exposing underlying plaintexts.

FHE in Web3

In the context of Web3, FHE enables the fhEVM with private smart contracts and encrypted token operations. By encrypting sensitive data like token balances and transaction amounts, FHE ensures confidentiality while maintaining the composability of blockchain applications.

Encrypted Types

In fhEVMs, there are additional private states that enable developers to store encrypted data. These include:

  • ebool
  • eaddress
  • euint8
  • euint16
  • euint32

Encrypted Methods

In addition to these encrypted types, the TFHE library also offers encrypted operations;

  • TFHE.add()
  • TFHE.sub()
  •  TFHE.mul()

and also comparisons, such as:

  • TFHE.eq()
  • TFHE.gt()
  • TFHE.max()

What Are cERC20 Tokens?

What if you could expand upon the original ERC20 standard by offering a means to achieve confidentiality of balances and transfer amounts onchain?

The cERC20 contract enables the minting of new tokens, transferring tokens between accounts, and managing token allowances (specifying how much one account is permitted to spend on behalf of another) while keeping the amounts encrypted. Additionally, only the contract deployer will be able to view everyone's balances. If desired, the owner can also globally decrypt an individual's balance.

Code Breakdown

One of the key strengths of cERC20 tokens is their simplicity: the cERC20 smart contract is much the same as for standard ERC20 tokens, with just a few changes.

Variables

mapping(address => euint64) internal balances;

Recall that balances mapping in regular ERC20 contracts were defined from address to integer and notice here that it is defined from address to encrypted integer.

Functions

_mint function takes a user address, an integer, and an input proof to create the input amount of tokens to the input address without revealing the minted amount.

function _mint(address account, euint256 encryptedAmount, bytes calldata inputProof) public virtual onlyOwner {
    balances[account] = TFHE.add(balances[account], TFHE.asEuint256(encryptedAmount, inputProof)); 
}

Similarly, _burn function takes a user address, an integer, and an input proof to remove the input amount of tokens from the input address without compromising the privacy of the amount.

function _burn(address account, euint256 encryptedAmount, bytes calldata inputProof) public virtual onlyOwner {
    balances[account] = TFHE.sub(balances[account], TFHE.asEuint256(encryptedAmount, inputProof)); 
}

_transfer function takes a user address and an integer to transfer the input amount of tokens to the input address but does it in an encrypted manner this time.

function _transfer(address to, euint64 encryptedAmount) internal virtual {
    euint256 newBalanceTo = TFHE.add(balances[to], encryptedAmount);
    balances[to] = newBalanceTo;
    
    euint256 newBalanceFrom = TFHE.sub(balances[msg.sender], encryptedAmount);
    balances[msg.sender] = newBalanceFrom;
}

Notice the new variables and functions: these, powered by FHE, enable tokens to achieve confidentiality onchain.

cERC20 Advantages

Commitment vs. Decryption 

Confidential transactions have the potential to significantly boost crypto adoption, but there are multiple approaches to achieving them. Two prominent methods are commitment-based and encryption-based models, each with unique strengths and trade-offs.

Commitment-based models rely on Zero-Knowledge Proofs (ZKPs). These allow users to create a "commitment" to an encrypted value that can be verified without ever revealing the underlying information. For example, a user can lock in a transfer amount that remains hidden while proving its correctness. This approach is ideal when both privacy and verification are required, and the full details, such as identities or amounts, need to remain confidential.

However, commitment-based models have limited flexibility. Because commitments are generated using unique keys, updating viewing permissions—such as granting an auditor access—is challenging. Once the keys are set, they cannot be easily modified, which makes this approach more suitable for scenarios with static access requirements.

cERC20 tokens leverage an encryption-based approach: FHE. Encryption-based approaches allow computations on encrypted data while keeping sensitive details private. This technology enables processes like calculating balances or validating transactions without exposing any information. Moreover, encryption-based approaches are inherently more flexible. Viewing permissions can be updated or shared dynamically through smart contract rules, making them ideal for applications like payroll, where the transaction amount remains hidden but authorized auditors can access the details if needed.

While commitment-based methods can be the right approach for scenarios requiring rigid privacy with predetermined access control, such as confidential health data encryption-based approaches can provide dynamic access control and composability, unlocking use cases such as payroll or confidential DeFi. In taking this approach, the architecture of cERC20s enables them to be used onchain in the same way that standard ERC20s are used, with developers able to build applications with composability and flexibility as users are not required to use their own keys for decryption. 

With this in mind, cERC20 can be adopted in the onchain ecosystem with minimal additional technical considerations, making them right for adoption.

Decryption Rules

To expand on this, cERC20s can include in-built decryption rules, meaning permissioned parties can be granted access without requiring access to the client’s keys, which they would understandably be reluctant to share. cERC20s can be transacted onchain as normal but with balances and transfer amounts hidden, and then decryption rules can be set that allow, for example, an auditor to view these amounts and balances. The auditor would not have to be granted access to the client’s key—FHE means specific addresses can be given view access. 

This is powerful: cERC20s maintain full composability and security but have the flexibility to enable users to give others view access for use cases such as regulatory oversight, for example.

Easy To Build With

Finally, it’s worth mentioning that the cERC20 architecture makes them extremely easy to build with. 

There’s no need to learn a new set of tools, a different blockchain architecture, or another coding language, developers can get up and running right away using the same tools and skills they would need to build smart contracts with standard ERC20s, such as Hardhat, and can write smart contracts in Solidity with only a few minor changes (see code above for details).

Use Cases

cERC20s unlock a host of use cases that are not possible with standard ERC20s. Below, you’ll find a non-exhaustive list of cERC20 use cases.

Payments-Related Use Cases:

  • Private cross-border payments: Enable private international transactions, protecting sensitive financial details while complying with local regulations.  
  • Private token vesting: Manage and automate the distribution of vested tokens, ensuring confidentiality of allocation schedules and amounts. 
  • Private B2B payroll: Facilitate private payroll between businesses, safeguarding salary details and ensuring compliance with regulatory requirements. 
  • International remittances: Provide a secure and private channel for transferring funds across borders, protecting senders and recipients from exposure and fraud. 

DeFi-Related Use Cases:

  • Private AMM & darkpools: Execute private token swaps, where transaction amounts are encrypted, preventing frontrunning and protecting trading strategies. The implementation presents interesting challenges that can be further explored in future research.
  • Private RWA tokenization: Tokenize real-world assets with privacy-preserving features, safeguarding sensitive ownership and transaction details.  
  • Blind auction: Facilitate auctions where the bid remains confidential until the auction concludes, ensuring a fair and competitive bidding process. 
  • Private lending: Enable private loans with confidential terms and collateral, preserving borrower privacy. Potentially support undercollateralized lending by incorporating onchain credit scores to assess creditworthiness privately.

If you’re interested in learning more about the confidential ERC20 framework, read the full report.

Looking to learn more about how FHE can power your use case? Get in touch with us here.

Incoming newsletter

Stay up to date with the latest on FHE and onchain confidentiality.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.