Zama FHEVM Confidential Contracts
Use this skill whenever the task involves writing, fixing, testing, deploying, or integrating smart contracts that compute on encrypted values with Zama Protocol.
Activation cues
Activate this skill if the user mentions any of the following:
- FHEVM, Zama Protocol, confidential smart contracts
- encrypted Solidity types such as
euint64,ebool, oreaddress FHE.add,FHE.sub,FHE.select,FHE.allow,FHE.allowTransient, orFHE.makePubliclyDecryptable- encrypted inputs, input proofs, user decryption, public decryption, or EIP-712 decryption signatures
@fhevm/hardhat-plugin,@zama-fhe/relayer-sdk, or olderfhevmjs- OpenZeppelin confidential contracts or ERC-7984
- confidential voting, confidential ERC-20 style tokens, wrappers, or private transfer flows
- mixed plaintext and encrypted state such as encrypted balances with public membership flags, counters, or timestamps
Non-negotiable defaults
- Treat the current protocol baseline as Zama documentation current on 2026-04-30.
- Use
FHE, not legacyTFHE. - Use
externalE...input types plusbytes inputProoffor fresh encrypted user inputs. - Inherit
ZamaEthereumConfiginstead of hardcoding coprocessor, ACL, KMS, or input verifier addresses. - Use
@fhevm/hardhat-pluginfor Hardhat tests and@zama-fhe/relayer-sdkfor current frontend encryption and decryption flows. - Assume encrypted
viewfunctions return ciphertext handles, not plaintext values. - Re-grant ACL permissions after producing new ciphertext state. Every storage reassignment that returns a new handle after
FHE.add,FHE.sub,FHE.select, or similar operations must be followed by the rightFHE.allowThis,FHE.allow, orFHE.allowTransientcalls. Missing ACL on the new handle is a correctness bug, not an optimization issue. - Prefer the official Hardhat template as the starting point for new work.
- When a user asks for ERC-7984, state that it is a draft ERC and is not ERC-20 compatible.
- Never claim participant addresses are private onchain unless the surrounding design truly hides them elsewhere.
Default workflow
- Start from the official Hardhat template and current dependency set. Use architecture and setup.
- Choose the right contract pattern before writing code.
- General FHEVM contract: Solidity patterns
- Frontend or wallet flow: frontend and decryption
- Tests or deployment: testing and deployment
- Confidential token or wrapper: OpenZeppelin and ERC-7984
- Failure analysis: troubleshooting
- Draft the contract with current imports, encrypted inputs, and ACL rules.
- Identify every code path that replaces encrypted storage and treat each replacement as a new handle that must be re-allowed.
- Keep plaintext membership flags, roles, timestamps, and loop bounds plaintext unless confidentiality is actually required for them.
- Generate a matching Hardhat test that encrypts inputs, passes
inputProof, and decrypts expected handles. - Add deployment or integration code only after the contract and tests agree on the ciphertext lifecycle.
- Self-check against the validation checklist before presenting the result. Use validation.
Architecture rules
- The EVM stores ciphertext handles and calls Zama's FHEVM infrastructure for encrypted computation.
- Fresh encrypted user inputs are created offchain, uploaded through the relayer, and imported onchain with
FHE.fromExternal. - The ACL governs who can reuse or decrypt ciphertexts.
- User decryption is an offchain re-encryption flow authorized by an EIP-712 signature.
- Public decryption is opt-in and must be explicitly enabled with
FHE.makePubliclyDecryptable.
Output requirements by task
New contract request
Produce:
- the Solidity contract
- a Hardhat test file
- any deployment or task file needed to use it
- a minimal frontend or script example when the request involves user interaction or decryption
- a short note on privacy scope and version assumptions
Debug or review request
Check for:
- deprecated
TFHE,einput, or old oracle-request APIs - missing
ZamaEthereumConfig - missing
FHE.allowThis,FHE.allow, orFHE.allowTransient, especially after encrypted state is reassigned - missing or mismatched
inputProof - plaintext assumptions in
viewfunctions - ciphertext-heavy loops that should instead use plaintext counters, flags, or bounded batching
- incorrect ERC-7984 operator or callback semantics
ERC-7984 or OpenZeppelin request
Prefer the OpenZeppelin confidential contracts library when the user wants a standard token primitive or wrapper. Use OpenZeppelin and ERC-7984 and confidential token pattern.
Canonical templates
Use these before inventing a new pattern:
- confidential voting Solidity template
- confidential voting Hardhat test template
- confidential token Solidity template
- frontend relayer integration template
Required correctness checks
Before returning code:
- Confirm every fresh encrypted parameter uses an
externalE...type plusbytes inputProof. - Confirm every newly produced encrypted state value is re-allowed for the contract and any actor that must decrypt or reuse it later.
- Confirm any plaintext scalar input path is intentional and still enforced with FHE comparisons or selection logic when confidentiality depends on encrypted state.
- Confirm tests use the Hardhat
fhevmAPI for encryption and decryption. - Confirm the code does not hardcode Zama infrastructure addresses.
- Confirm decryption batches stay under the 2048-bit limit.
- Confirm public reveal flows use
FHE.makePubliclyDecryptableand, when verified onchain,FHE.checkSignatures. - Confirm ERC-7984 callbacks are guarded against reentrancy if callback variants are used.
When docs conflict
Prefer this priority order:
- Current Zama Protocol docs
- Current
@fhevm/hardhat-pluginand@zama-fhe/relayer-sdkdocs - Current OpenZeppelin confidential contracts docs
- ERC-7984 draft specification
- Older
fhevmjsexamples only as migration clues, not as the default implementation path
Version guardrails
FHEreplaced the olderTFHEnamespace.externalEuint...,externalEbool, andexternalEaddressreplaced oldereinputpatterns.- Relayer-based decryption is the current flow. Do not default to deprecated gateway-request APIs.
- OpenZeppelin confidential contracts move quickly and explicitly warn that backward compatibility is not guaranteed.
- Use
@zama-fhe/relayer-sdkfor current app code even if older examples mentionfhevmjs.
Reference map
- architecture and setup
- Solidity patterns
- frontend and decryption
- testing and deployment
- OpenZeppelin and ERC-7984
- troubleshooting
- validation
- distribution