Skip to main content
HideMeToken is a confidential ERC-20-like token where every balance is an encrypted 64-bit integer (euint64) stored on Ethereum mainnet. Transfer amounts are encrypted, and events always emit amount = 0 to prevent leakage. Each token is deployed by HideMeFactory. The example mainnet instance is at 0x02FA7116A5653dfDFe51cF83F587CB80F560145d.

Key properties

PropertyValue
Decimals6 (fixed)
Balance typeeuint64 (FHE ciphertext)
Transfer event amountAlways 0 (privacy)
Solidity version^0.8.24 (compiled with 0.8.27)
LicenseMIT

State variables

name
string
Token name, set at deployment.
symbol
string
Token symbol, set at deployment.
decimals
uint8
Always 6.
totalSupply
uint64
Plaintext total supply. Updated on mint/burn.
owner
address
Current owner. Can mint (if mintable), add/remove observers, transfer or renounce ownership.
mintable
bool
Whether the owner can mint additional tokens.
burnable
bool
Whether holders can burn their own tokens.
maxSupply
uint64
Maximum total supply cap. 0 = unlimited.

Functions

transfer (client-side FHE)

function transfer(
    address to,
    externalEuint64 encryptedAmount,
    bytes calldata inputProof
) external returns (bool)
Transfer using an amount encrypted client-side with TFHE WASM. The encryptedAmount handle and inputProof are produced by encryptAmount() in the frontend SDK.
to
address
required
Recipient address. Cannot be address(0).
encryptedAmount
externalEuint64
required
Encrypted amount handle produced by the client-side TFHE library.
inputProof
bytes
required
Input verification proof from the Zama InputVerifier contract.

transfer (euint64 handle)

function transfer(address to, euint64 amount) external returns (bool)
Transfer using an already-on-chain euint64 ciphertext. Used in contract-to-contract calls. The caller must be allowed on the amount handle (FHE.isSenderAllowed).

transferPlaintext

function transferPlaintext(address to, uint64 amount) external returns (bool)
Transfer a plaintext amount that is encrypted inside the EVM via FHE.asEuint64(amount). No browser WASM required. Useful for integrations and the payment links feature.

approve

function approve(
    address spender,
    externalEuint64 encryptedAmount,
    bytes calldata inputProof
) external returns (bool)
Approve a spender for an encrypted allowance.

transferFrom

function transferFrom(
    address from,
    address to,
    externalEuint64 encryptedAmount,
    bytes calldata inputProof
) external returns (bool)
Transfer on behalf of from using an approved allowance. Both balance and allowance are checked with encrypted comparisons.

mint

function mint(address to, uint64 amount) external
Mint new tokens. Only callable by the owner. Requires mintable = true. Reverts if maxSupply > 0 and the new total would exceed it.

burn

function burn(uint64 amount) external
Burn tokens from the caller’s balance. Requires burnable = true. The encrypted comparison FHE.le(amount, balance) ensures a silent no-op if balance is insufficient.

addObserver / removeObserver

function addObserver(address observer) external   // onlyOwner
function removeObserver(address observer) external // onlyOwner
Observers can decrypt any holder’s balance. Useful for compliance auditors or regulators. Observers are stored on-chain and receive FHE access permissions on every balance update.

transferOwnership / renounceOwnership

function transferOwnership(address newOwner) external // onlyOwner
function renounceOwnership() external                 // onlyOwner
Transfer or permanently renounce ownership. Renouncing disables minting and observer management.

balanceOf / allowance / getObservers

function balanceOf(address account) external view returns (euint64)
function allowance(address account, address spender) external view returns (euint64)
function getObservers() external view returns (address[] memory)
Read encrypted balance/allowance handles. The returned euint64 is a ciphertext — use the Zama decryption flow to read the actual value.

FHE transfer internals

The internal _transfer function uses this pattern to prevent balance leakage:
ebool canTransfer = FHE.le(amount, _balances[from]);
euint64 transferValue = FHE.select(canTransfer, amount, FHE.asEuint64(0));
// subtract transferValue from sender, add to receiver
If the sender has insufficient balance, transferValue evaluates to 0 — no revert, no information leak.

Events

EventParametersNotes
Transferfrom, to, amountamount is always 0
Approvalowner, spender, amountamount is always 0
ObserverAddedobserver, addedBy
ObserverRemovedobserver, removedBy
OwnershipTransferredpreviousOwner, newOwner
OwnershipRenouncedpreviousOwner

Custom errors

ErrorWhen thrown
ZeroAddressA required address parameter is address(0)
SenderNotAllowedCaller does not have FHE access on the provided euint64 handle
OnlyOwnerCaller is not the owner
MintingDisabledmintable is false
BurningDisabledburnable is false
ExceedsMaxSupplyMint would exceed maxSupply

HideMeFactory

Deploy new HideMeToken instances.

Encrypted Transfers

How to use the transfer functions from the frontend.

Build docs developers (and LLMs) love