What is encrypted and what is public?
Each balance is aneuint64 handle (a reference to an encrypted value). The total supply is an euint64 too. Transfer amounts are encrypted inputs or handles, never plaintext.
What anyone can still see:
- The sender and recipient of every transfer, from the
ConfidentialTransferevent. - That an account has never held the token. A transfer or burn from such an account reverts with
FHERC20ZeroBalance, because its balance handle was never created. - Transfer activity per account: the indicator values below move by one step per transfer received or sent.
- Amounts you pass in plaintext, such as the
uint64argument of a mint function you write.
What do the ERC-20 functions return?
balanceOf and totalSupply return an indicator, not a balance. The indicator tells a wallet that something changed without saying how much.
The values read as
7984.xxxx when decimals is 4 or more. A token with 6 decimals reports a first-time recipient as 7984000100 raw, which a wallet shows as 7984.0001.
Every transfer, mint, and burn also emits the standard ERC-20 Transfer event with a fixed value of 7984.0001, so explorers index the activity. The real amount is in ConfidentialTransfer, as a handle.
An account can call resetIndicatedBalance() to set its own indicator back to 0.
Who can decrypt a balance?
The token grants access to every new balance handle for two accounts: the token itself and the holder. Nobody else can decrypt a balance unless your contract grants access withFHE.allow.
To show a balance in your app, read the handle and decrypt it with the SDK:
decryptForView signs with an Access Control Permission (ACP) for the connected account. See decrypt to view for setting one up.
confidentialBalanceOf returns a handle, not an amount. A handle you read once goes stale after the next transfer, because every balance change creates a new handle.
How do you mint and burn?
FHERC20 exposes no public mint or burn. Your contract calls the internal functions and decides who may use them:
Both return the encrypted amount that actually moved. Neither reverts on an encrypted condition:
- A burn larger than the balance burns zero.
- A mint that would overflow the 64-bit total supply mints zero.
RewardPoints.sol
FHERC20 does not need the shared library, so it deploys like any other contract.
A mint function that takes a plaintext
uint64 works too, but the amount is visible in the transaction’s calldata.Which variants exist?
supportsInterface reports IFHERC20, IERC7984, IERC20, and IERC165.
Next steps
- Transfers and disclosure: send tokens and make an amount public.
- Operators: let another account move tokens for a holder.
- Transfer callbacks: notify a receiving contract in the same transaction.
- Best practices: mistakes that leak amounts or lose funds.