0xe1337/fhevm-skill/fhevm
Claude Code and agent skill by 0xe1337/fhevm-skill
- community
Checking that the SKILL.md file is still in the repository.
Use when writing, modifying, or reviewing any Solidity contract that uses Zama fhEVM encrypted types (euint, ebool, eaddress) — confidential DeFi, private voting, sealed-bid auctions, encrypted ERC20 tokens, encrypted balances, or any application where on-chain data must remain encrypted under fully homomorphic encryption. Symptoms in code: imports from @fhevm/solidity, uses externalEuintXX or FHE.fromExternal, calls FHE.add/sub/mul/select, FHE.allowThis, FHE.makePubliclyDecryptable, ZamaEthere…
Install
npx vskill@latest install 0xe1337/fhevm-skill/fhevmSKILL.md
fhEVM Confidential Smart Contract Development
Build Solidity contracts where on-chain data stays encrypted using Fully Homomorphic Encryption.
Validation: This skill has been A/B tested against 15 prompts (7 demo + 8 adversarial traps), with one live verification run on 2026-05-09. Without this skill, vanilla LLM output triggers 47 distinct anti-pattern occurrences across 14 of the 20 patterns in the catalog (predicted), plus 9 anti-pattern occurrences in a single live run (verified — full transcript atvalidation/transcripts/2026-05-09-vanilla-erc20.md); only 1/15 vanilla outputs both compile and have no privacy leak. With this skill loaded, all of these move to 0 and 15/15 respectively. Full report and reproducibility protocol:validation/agent-effectiveness.md.
When to Use
Use this skill when any of these apply:
- Writing or modifying a Solidity contract that imports
@fhevm/solidity - Adding encrypted state (
euint,ebool,eaddress) to an existing contract - Reviewing fhEVM code (your own or AI-generated) for correctness or privacy leaks
- Building or modifying a frontend that uses
@zama-fhe/relayer-sdkfor client-side encryption or async decryption - Migrating a regular Solidity contract to fhEVM
- Writing or debugging Hardhat tests that use
fhevm.createEncryptedInput - Designing data flow for any application where on-chain values must stay encrypted under threshold MPC
Symptoms in chat or code that should trigger this skill:
- "encrypted balance / score / vote / bid"
- API references:
FHE.add,FHE.select,FHE.fromExternal,FHE.allowThis,FHE.makePubliclyDecryptable,ZamaEthereumConfig,externalEuintXX - File patterns:
@fhevm/solidityimports,*.solfiles declaringeuint*state, test files importingfhevmfrom hardhat,relayer-sdkin frontend deps - Error patterns: ACL access denied, "ebool cannot be evaluated",
FHE.decrypt is not a function, decryption returning garbage
When NOT to Use
This skill is overkill or off-topic for:
- Regular Solidity contracts with no encrypted state — vanilla Solidity guidance is enough; loading this skill adds noise.
- ZK-SNARK / ZK-STARK circuits that aren't fhEVM-related — different paradigm (zero-knowledge ≠ fully homomorphic).
- Concrete ML / TFHE-rs Rust applications — those use Python/Rust APIs and a different deployment model; this skill is Solidity-only.
- Generic Ethereum security audits where FHE is not present — use general security review skills, not this one.
- Contracts that only call fhEVM contracts but hold no encrypted state themselves — usually only the
references/access-control.mdcross-contract section is needed; full skill is unnecessary.
Development Philosophy
Think in ciphertexts, not plaintexts. This is the fundamental shift from regular Solidity.
You are not writing "if this, then that" logic anymore. You are writing "compute both branches, select the correct result homomorphically." Every if/else becomes FHE.select. Every require becomes a guard that silently clamps to zero on failure. Your contract always succeeds at the EVM level — the question is what the encrypted result contains.
Four-step approach to every fhEVM task:
- Understand the goal — What data must stay private? What can be public? Define the privacy boundary before writing code.
- Choose the right pattern — Use the decision tables below. Don't branch on encrypted values. Don't try to decrypt synchronously. Don't forget ACL.
- Verify at each step — After every FHE operation, ask: "Did I re-grant ACL on the new ciphertext? Did I use
FHE.selectinstead ofif? Did I validate the input withFHE.fromExternal?" - Test with mock mode — Run
npx hardhat testlocally. Mock FHE simulates all operations without a real coprocessor. Verify the logic works before deploying.
How fhEVM Works (Architecture)
Understanding the architecture prevents entire classes of bugs:
Key insight: The on-chain system is entirely symbolic. Handles (bytes32) are NOT ciphertexts — they are deterministic identifiers computed via keccak256. The actual encrypted data lives in 5 off-chain coprocessor nodes. Decryption requires 9 of 13 KMS MPC nodes (run by Etherscan, Fireblocks, Ledger, OpenZeppelin, etc. in AWS Nitro Enclaves). This is why:
- Every operation creates a new handle → FHE math produces a new ciphertext (different noise/randomness), so you must re-grant ACL permissions on the new handle
- Handles cannot be evaluated as booleans → no node has the secret key; the EVM literally cannot evaluate
if (eboolHandle) - Decryption requires the off-chain KMS → 9/13 threshold MPC, always async, no
FHE.decrypt() - Uninitialized handles are `bytes32(0)` → not encrypted zero, just an invalid pointer
- Operations are expensive → each FHE op involves noise management on large polynomial structures; bootstrapping refreshes noise but costs HCU
Seereferences/architecture.mdfor the full 6-component system, TFHE principles, handle format, and HCU metering details.
Quick Start
Minimal contract:
Decision Tables
When to use which encrypted type
| Need | Type | Why | |
|---|---|---|---|
| Token balances, amounts | euint64 | Fits up to ~18.4 quintillion; use 6 decimals not 18 | |
| Scores, counters, vote tallies | euint32 | Cheaper ops than euint64, sufficient range | |
| Tiers, flags, small enums | euint8 | 2-10x cheaper than euint64 | |
| Boolean conditions | ebool | Result of all comparisons | |
| Hash values, bitfields | euint256 | No arithmetic — bitwise and equality only | |
| Encrypted addresses | eaddress | Only eq, ne, select — very limited | |
| Large financial values | euint128 | Expensive (mul costs ~1,686K HCU) — use sparingly |
Solidity pattern → fhEVM equivalent
| Regular Solidity | fhEVM Equivalent | |
|---|---|---|
if (a > b) { x = a; } else { x = b; } | x = FHE.select(FHE.gt(a, b), a, b); | |
require(balance >= amount) | ebool ok = FHE.ge(balance, amount); + silent failure | |
balance -= amount | balance = FHE.sub(balance, amount); FHE.allowThis(balance); | |
return balance | Return handle; user decrypts off-chain | |
| Revert on error | Silent failure: transfer 0, bid 0 | |
a / b (both variables) | Impossible if both encrypted; restructure math | |
mapping(addr => uint) | mapping(address => euint64) + ACL on every update |
When to load reference files
| Situation | Load | |
|---|---|---|
| Need full type details, casting, initialization | references/encrypted-types.md | |
| Need exact operation signatures or HCU costs | references/fhe-operations.md | |
| Writing ACL logic, cross-contract permissions, AA bundles | references/access-control.md | |
| Handling user-submitted encrypted inputs | references/input-validation.md | |
| Implementing reveal/result publication, decryption callbacks | references/decryption-patterns.md | |
| Setting up or writing Hardhat tests | references/testing-guide.md | |
| Building frontend encryption/decryption | references/frontend-integration.md | |
| Reviewing contract for common mistakes (20 patterns) | anti-patterns/ANTI-PATTERNS.md | |
| Writing/grading agent-generated code against trap cases | validation/prompts.md | |
| Reviewing the validation evidence | validation/agent-effectiveness.md |
Encrypted Types (Summary)
| Type | Arithmetic | Comparison | Bitwise | Select | |
|---|---|---|---|---|---|
ebool | No | eq, ne | and, or, xor, not | Yes | |
euint8–euint128 | Full | Full | Full | Yes | |
euint256 | No | eq, ne only | Full | Yes | |
eaddress | No | eq, ne only | No | Yes |
Import only what you use: import { FHE, euint64, ebool, externalEuint64 } from "@fhevm/solidity/lib/FHE.sol";
FHE Operations (Summary)
Arithmetic (euint8–128): FHE.add, FHE.sub, FHE.mul, FHE.div\, `FHE.rem`\, FHE.min, FHE.max, FHE.neg \*div/rem require plaintext right operand — encrypted divisor is NOT supported.
Comparison (→ ebool): FHE.eq, FHE.ne, FHE.ge, FHE.gt, FHE.le, FHE.lt
Branching: FHE.select(ebool, ifTrue, ifFalse) — the ONLY way to do conditional logic.
Random: FHE.randEuint8() – FHE.randEuint256(). Bounded: FHE.randEuint16(upperBound) (power-of-2). Transactions only, not view functions.
Type casting: FHE.asEuint32(plaintext) to encrypt. FHE.asEuint64(euint32Value) to upcast.
Scalar operations (one plaintext operand) are significantly cheaper. Prefer FHE.add(enc, 5) over FHE.add(enc1, enc2) when possible.
Operator overloading: With using FHE for *, you can write a + b instead of FHE.add(a, b). Supports +, -, *, &, |, ^, ~.
Access Control (ACL) — The #1 Source of Bugs
Every FHE operation creates a NEW ciphertext handle with ZERO permissions. Re-grant after EVERY operation:
| Function | Scope | When | |
|---|---|---|---|
FHE.allowThis(ct) | Persistent | Always — contract must access its own state | |
FHE.allow(ct, addr) | Persistent | User/protocol needs long-term decrypt access | |
FHE.allowTransient(ct, addr) | Single tx | Helper contract, cheaper gas | |
FHE.makePubliclyDecryptable(ct) | Anyone, forever | Publishing results (vote tallies) | |
FHE.isSenderAllowed(ct) | Check | Verify caller permission | |
FHE.cleanTransientStorage() | Cleanup | Between AA bundled ops (prevent cross-op leaks) |
Input Validation
Users encrypt values client-side. Contracts validate via externalEuintXX + FHE.fromExternal:
Never accept raw `euintXX` as function parameters — always use externalEuintXX + proof.
Decryption (Always Async)
There is no FHE.decrypt(). Decryption goes through the off-chain Gateway → KMS threshold MPC:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/fhevm/SKILL.md
Popularity
- Repository stars
- 1
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/0xe1337/fhevm-skill/fhevm)