July 25, 2026
FHE Smart Contract Security: New Risks Developers Must Understand
Encryption Protects the Data — Not Automatically the Contract

By Sithum Ravishka
15 min read
A smart contract can keep every balance encrypted and still be completely insecure.
Fully Homomorphic Encryption is introducing something public blockchains have historically struggled to provide: programmable confidentiality.
A traditional smart contract must normally expose the data it processes. Token balances, transfer amounts, votes, bids, collateral positions and application state are usually visible to anyone inspecting the blockchain.
FHE changes that model.
It allows a smart contract to perform calculations directly on encrypted data. The contract can add balances, compare values, apply conditions and update state without seeing the underlying plaintext.
That capability could enable:
- Private wallet balances
- Confidential token transfers
- Sealed-bid auctions
- Private voting
- Confidential DeFi
- Protected identity information
- Private business transactions
But there is a dangerous misunderstanding developing around this technology:
Encrypted does not mean secure.
FHE protects confidentiality, but confidentiality is only one part of security.
A secure application must also protect:
- Integrity: Can data or results be manipulated?
- Authorization: Who is allowed to perform an action?
- Availability: Can legitimate users continue using the protocol?
- Correctness: Does the contract always produce the intended result?
- Accountability: Can suspicious behaviour be detected and investigated?
FHE introduces powerful privacy guarantees, but it also introduces new permissions, infrastructure components, performance constraints and failure modes.
Developers must understand these risks before deploying confidential smart contracts that control real value.
1. FHE Changes the Smart Contract Threat Model
In a normal Solidity contract, the developer can inspect the values being processed.
For example:
balance = 100
transferAmount = 25
canTransfer = truebalance = 100
transferAmount = 25
canTransfer = trueIn an FHE-powered contract, the equivalent values may look more like this:
balance = encrypted value
transferAmount = encrypted value
canTransfer = encrypted booleanbalance = encrypted value
transferAmount = encrypted value
canTransfer = encrypted booleanThe contract can perform calculations on those values, but it cannot directly observe their plaintext contents.
This changes how developers:
- Validate inputs
- Write conditions
- Debug failures
- Control data access
- Handle decryption
- Monitor suspicious activity
- Test business rules
Current confidential EVM architectures also involve more than a Solidity contract, and the exact components vary by platform (Zama, Fhenix, Inco and others differ in design). Zama's documented architecture, for example, includes host contracts, coprocessors, a gateway, a key-management service and relayer infrastructure. The Solidity contract initiates encrypted operations, while specialised components validate inputs, perform computation and coordinate authorised decryption.
This creates a broader attack surface.
Developers are no longer securing only:
User → Smart Contract → BlockchainUser → Smart Contract → BlockchainThey may now be securing:
User
↓
Client-side encryption
↓
Smart contract
↓
Host contracts
↓
Gateway
↓
Encrypted coprocessor
↓
Key-management network
↓
Authorised decryptionUser
↓
Client-side encryption
↓
Smart contract
↓
Host contracts
↓
Gateway
↓
Encrypted coprocessor
↓
Key-management network
↓
Authorised decryptionA weakness at any stage can damage the security or privacy of the application.
2. Risk One: Incorrect Encrypted-State Permissions
One of the most important new responsibilities in an FHE smart contract is deciding who may use or decrypt each encrypted value.
Encryption alone does not answer that question.
Imagine a confidential token contract containing an encrypted balance:
encryptedBalance[Alice]encryptedBalance[Alice]The system may need to grant permission to:
- The contract, so it can update the balance
- Alice, so she can decrypt her balance
- Another contract, so it can use the balance in an authorised operation
- A compliance service, if the application requires regulated disclosure
These permissions must be intentionally assigned.
In the current FHEVM model, the access-control list determines which addresses may compute on or decrypt particular encrypted values. Permissions such as contract access, user access and delegated decryption rights must be managed by the application developer.
A single permission error may expose private information or make encrypted state unusable.
Example: Over-Permissioning
Suppose a developer accidentally grants permanent access to a shared router contract.
That router may now be able to use or expose encrypted values belonging to every user who interacted with it.
The original token contract may be secure, but the shared dependency becomes a privacy gateway into the system.
Example: Missing Permission
The opposite problem can also occur.
A contract calculates a new encrypted balance but forgets to grant the owner permission to decrypt it.
The computation succeeds, the state is updated and the transaction is confirmed — but the user can no longer read their own balance.
Security Principle
Encrypted permissions should follow the principle of least privilege.
Every encrypted value should answer four questions:
- Which contract may compute on it?
- Which user may decrypt it?
- Is the permission temporary or permanent?
- What happens when ownership or roles change?
Permissions should never be copied automatically without understanding why they are required.
3. Risk Two: Decryption Can Become a Privacy Breach
FHE keeps data private while it is being processed.
But many applications eventually need to reveal a result.
A confidential auction may need to reveal the winner.
A voting contract may need to reveal the final result.
A lending protocol may need to reveal whether a position can be liquidated.
A user may need to decrypt their balance.
This means the security of the application depends not only on encrypted computation, but also on its decryption policy.
The Dangerous Question
Developers often ask:
"Can this value be decrypted?"
The more important question is:
"Who can request decryption, under what conditions, and who receives the result?"
A contract could calculate everything correctly and still expose confidential information through an unsafe decryption request.
Common Decryption Mistakes
Publicly decrypting private intermediate values
A protocol may only need to reveal whether a trade was accepted, but the developer accidentally exposes:
- The user's full balance
- Their maximum bid
- Their collateral amount
- Their risk score
Only the minimum necessary result should be revealed.
Reusing old permissions
Suppose ownership of an encrypted asset changes from Alice to Bob.
If Alice's decryption rights are not revoked or replaced correctly, she may continue accessing future encrypted state associated with the asset.
Revealing aggregate results too early
A private voting contract may protect individual votes but reveal partial totals after each vote.
Attackers could compare consecutive totals and infer how individual users voted.
Decrypting values through events
A developer may correctly protect contract storage but emit the plaintext result inside a public event.
Blockchain events are public and permanent. Encryption in storage provides no protection once the same value is emitted in plaintext.
Security Principle
Decryption should be treated as a privileged state transition, not as a simple read operation.
Each decryption path should be threat-modelled, authorised, logged and tested.
4. Risk Three: Encrypted Inputs Can Still Be Malicious
Developers sometimes assume that because an input is encrypted, it is automatically valid.
That is not true.
An attacker can submit:
- Malformed ciphertext
- Unsupported encrypted data types
- Inputs created for the wrong contract
- Inputs associated with the wrong user
- Replayed encrypted inputs
- Unexpectedly large values
- Values outside business limits
- Invalid supporting proof data
Current confidential-contract tooling expects encrypted inputs and supporting proof material to be produced off-chain. Official examples warn developers to validate these inputs and revert when they are malformed.
Encryption Does Not Replace Business Validation
Consider a confidential transfer.
The amount may be encrypted, but the contract must still enforce rules such as:
- The amount does not overflow or wrap around (encrypted integer types are unsigned, so "negative" values are not representable — but wraparound and oversized values are)
- The sender has sufficient funds
- The recipient is valid
- The asset is not paused
- The user is authorised
- The transfer does not exceed a permitted limit
The contract may evaluate some of these conditions as encrypted booleans, but the rules must still exist.
The Replay Problem
Imagine that a user creates an encrypted input authorising a transfer of 50 tokens.
If that encrypted input can be reused, copied or submitted in another context, an attacker may attempt to replay it.
Secure input handling should bind encrypted data to relevant context, such as:
- The intended contract
- The intended chain
- The sender
- The operation
- A nonce
- An expiry time
The exact mechanism depends on the platform, but the security goal remains the same:
An encrypted input should only be valid where and when it was intended to be used.
5. Risk Four: Metadata Can Expose What Encryption Hides
FHE can hide values, but the surrounding blockchain activity may remain public.
Observers may still see:
- Sender addresses
- Recipient addresses
- Contract addresses
- Transaction timing
- Transaction frequency
- Gas consumption
- Function selectors
- Event topics
- Failure or success
- Ciphertext size
- Decryption requests
This information is called metadata.
Metadata can reveal sensitive patterns even when the underlying values remain encrypted.
Example: Confidential Salary Payments
A company may encrypt every employee's salary amount.
However, observers can still see:
- Which wallet receives a payment
- When payments occur
- How often each employee is paid
- Whether a bonus transaction occurred
- Which department contract processed the payment
The salary amount remains hidden, but the payment relationship may not.
Example: Private Medical Eligibility
A health-related contract may encrypt medical data.
But if the user calls a function named:
requestCancerTreatmentApproval()requestCancerTreatmentApproval()the function call itself reveals sensitive information.
Example: Gas-Based Inference
In well-designed FHE contracts, gas should not depend on encrypted values, because both branches are evaluated with an encrypted selector. However, if a contract lets a secret influence a public code path — for example, skipping an operation when a plaintext flag derived from a secret is set — an attacker may compare transaction costs and infer which path was taken.
Even when the internal value is encrypted, observable resource consumption may reveal information about the computation.
Security Principle
Protect the entire interaction pattern — not only the stored value.
Developers should review:
- Public function names
- Event design
- Transaction batching
- Timing patterns
- Error messages
- Gas differences
- Decryption activity
FHE provides data confidentiality, but it does not automatically provide anonymity or traffic-pattern privacy.
6. Risk Five: Secret Conditions Change Control Flow
Traditional Solidity frequently uses conditions like:
if (balance >= amount) {
_transfer(msg.sender, to, amount);
} else {
revert();
}if (balance >= amount) {
_transfer(msg.sender, to, amount);
} else {
revert();
}But when balance and amount are encrypted, the contract cannot simply inspect the condition as a normal plaintext boolean.
Instead, FHE systems may calculate an encrypted condition and use an encrypted selection operation.
Conceptually:
ebool canTransfer = FHE.le(amount, balance);
euint64 acceptedAmount = FHE.select(
canTransfer,
requestedAmount,
FHE.asEuint64(0)
);ebool canTransfer = FHE.le(amount, balance);
euint64 acceptedAmount = FHE.select(
canTransfer,
requestedAmount,
FHE.asEuint64(0)
);Both possible outcomes may need to be represented without revealing which condition was true.
Research on FHE smart contracts notes that secret-dependent branches and loops must often be converted into data-independent computation. Both sides of a branch may be evaluated, with an encrypted selector choosing the correct output. This protects privacy but increases computational complexity.
Why This Is a Security Risk
Developers accustomed to normal Solidity may accidentally:
- Reveal the condition through a plaintext branch
- Update state on both paths
- Apply permissions to the wrong result
- Forget to neutralise the rejected operation
- Introduce expensive branch-heavy computation
- Use a public revert that reveals a secret condition
Revert Messages Can Leak Secrets
Consider:
Insufficient confidential balanceInsufficient confidential balanceIf only users with insufficient funds receive this public revert, the transaction has revealed information about their encrypted balance.
Sometimes the secure behaviour is not to revert based on the secret condition.
The contract may instead process the operation safely and return an encrypted success value that only the authorised user can read.
Security Principle
Never allow a secret condition to create an observable difference unless that disclosure is intentional.
Observable differences include:
- Reverts
- Events
- Gas use
- Storage writes
- External calls
- Timing
- Return values
7. Risk Six: Asynchronous Infrastructure Creates New Failure Modes
Ordinary EVM execution is synchronous.
A transaction enters the blockchain, the contract executes, and the result is determined within the transaction.
FHE architectures may offload expensive encrypted computation to specialised coprocessors. The blockchain records or coordinates symbolic operations, while external components perform the cryptographic computation and commit the encrypted result. Zama's current architecture describes coprocessors, a gateway, host contracts and relayer components participating in this workflow.
This creates new questions:
- What happens if a coprocessor is unavailable?
- What happens if a request is delayed?
- Can the same request be processed twice?
- Can results arrive out of order?
- When is an encrypted result considered final?
- Can a user cancel an operation while it is pending?
- What happens if the contract is upgraded during computation?
- How are failed decryption requests recovered?
The Pending-State Problem
Imagine a confidential lending protocol:
- A user requests a withdrawal.
- The contract begins an encrypted solvency check.
- The result is delayed.
- The user submits another withdrawal.
- The collateral price changes.
- The first result arrives after the protocol state has changed.
A result that was valid when requested may be unsafe when completed.
Secure Asynchronous Design
Each encrypted operation should include sufficient context:
- Request identifier
- State version
- User identity
- Expected contract address
- Expiry time
- Nonce
- Current protocol status
When the result returns, the contract should verify that it still applies to the current state.
Security Principle
Treat offloaded encrypted computation like an asynchronous distributed workflow — not like a normal Solidity function call.
8. Risk Seven: FHE Can Create Denial-of-Service Opportunities
Encrypted computation is significantly more resource-intensive than ordinary plaintext computation.
Large encrypted values, comparisons, repeated operations and complex selections may require substantial processing.
Research evaluating FHE smart-contract systems identifies gas costs, ciphertext size and scalability as major deployment challenges. It also warns that specialised hardware can improve performance while potentially increasing infrastructure centralisation.
Attackers may exploit this cost difference.
Possible Denial-of-Service Attacks
Computation flooding
An attacker repeatedly submits operations that trigger expensive encrypted calculations.
Even when they pay transaction gas, the external cryptographic infrastructure may bear additional computation costs.
Large ciphertext submissions
An attacker submits the largest accepted encrypted data type repeatedly, increasing calldata, storage and processing pressure.
Branch explosion
A poorly designed contract performs many encrypted comparisons and selections for each user-controlled item.
Queue starvation
An attacker fills a computation queue with low-value requests, delaying legitimate operations.
Decryption spam
An attacker repeatedly requests authorised or deliberately failing decryptions to consume gateway resources.
Defensive Design
Developers should consider:
- Per-user quotas
- Per-function limits
- Maximum encrypted data sizes
- Request fees
- Bounded queues
- Operation expiry
- Circuit breakers
- Emergency pause controls
- Batch limits
- Back-pressure mechanisms
Security Principle
Any expensive encrypted operation exposed to users must be treated as a potential denial-of-service endpoint.
9. Risk Eight: Key Management Becomes Protocol Security
FHE computation relies on encryption keys.
Users need access to the public encryption material, while decryption authority must remain protected.
A single organisation holding complete decryption power would create an obvious central point of failure. A compromised key could expose confidential state across the entire application.
Modern architectures therefore distribute decryption authority across multiple participants and coordinate key generation, rotation and authorised decryption through a dedicated key-management system. Zama's architecture describes the key-management layer as responsible for generating and rotating FHE keys and handling secure, verifiable decryption.
However, cryptography alone does not solve governance.
Developers must ask:
- Who operates the key-management participants?
- How are participants selected?
- How are compromised participants removed?
- How are keys rotated?
- What happens when a participant is offline?
- What threshold is required for decryption?
- Can operators collude?
- Who can approve emergency decryption?
- Can old ciphertext remain usable after rotation?
- How does the protocol recover from key loss?
Current research identifies key management, participant selection, collusion resistance, governance and compatibility with blockchain security assumptions as open challenges for FHE smart-contract deployments.
Security Principle
The confidentiality of the entire protocol is only as strong as its decryption governance.
Key-management assumptions must be documented as clearly as smart-contract ownership and upgrade permissions.
10. Risk Nine: Traditional Solidity Vulnerabilities Still Exist
FHE does not remove ordinary smart-contract security problems.
A confidential contract can still contain:
- Reentrancy
- Broken access control
- Unsafe upgrades
- Incorrect accounting
- Oracle manipulation
- Front-running of public metadata
- Denial of service
- Integer boundary errors
- Signature replay
- Unprotected initialisation
- Compromised administrator roles
- Incorrect external-call handling
Encryption may even make some bugs harder to detect because developers cannot easily inspect the underlying values.
Example: Confidential Reentrancy
Suppose a contract makes an external call (for example, a callback or hook) before completing its encrypted balance update. This pattern is most common in complex DeFi integrations rather than simple confidential token transfers.
The balances may be encrypted, but the execution order is still unsafe.
An attacker contract may re-enter before the encrypted state update has been completed.
The privacy technology did not create the vulnerability — but it did not prevent it either.
Example: Encrypted Accounting Bug
A vault may keep deposits and shares encrypted.
If its share-calculation formula is incorrect, users may still mint excessive shares or withdraw more value than they deposited.
Nobody seeing the plaintext values does not make the maths correct.
Security Principle
Apply every standard Solidity security practice before adding FHE-specific protections.
A confidential contract requires both:
Traditional smart-contract security
+
Encrypted-state securityTraditional smart-contract security
+
Encrypted-state securityNeither one replaces the other.
11. Risk Ten: Testing Encrypted Contracts Can Create False Confidence
Testing a confidential smart contract is more complicated than testing a normal Solidity contract.
Developers may use local mocks that simulate encrypted operations without executing real cryptography.
Mocks are useful for speed, but they may fail to reproduce:
- Real permission behaviour
- Ciphertext validation
- Asynchronous processing
- Gateway failures
- Decryption delays
- Key rotation
- Coprocessor outages
- Production gas, HCU, proof-verification, decryption and infrastructure costs
- Malformed encrypted input
- Cross-contract permission mistakes
A test can pass locally while the production deployment fails because the test environment simplified the most security-sensitive parts.
Required Testing Layers
Unit tests
Verify individual business rules and encrypted operations.
Negative tests
Confirm that unauthorised users cannot:
- Compute on protected ciphertext
- Decrypt another user's value
- Reuse an encrypted input
- Call privileged functions
- Access state after ownership changes
Permission tests
Test every encrypted value against every relevant actor:
- Contract
- User
- Administrator
- Relayer
- External contract
- Former owner
- Unauthorised attacker
Fuzz tests
Explore unexpected:
- Encrypted input ranges
- Operation sequences
- Transfer sizes
- Repeated requests
- Ownership changes
- Timing combinations
Invariant tests
Define properties that must never break, such as:
- Total encrypted supply remains consistent
- No unauthorised address gains decryption access
- Rejected transfers cannot change balances
- A user cannot withdraw more than their encrypted entitlement
- Ownership transfer must not reuse ciphertext handles that remain decryptable by former owners.
- Pending operations cannot execute against stale state
Infrastructure failure tests
Simulate:
- Delayed computation
- Duplicate callbacks
- Out-of-order results
- Gateway failure
- Expired operations
- Paused contracts
- Key rotation
- Partial service outages
Production-like integration tests
Before deployment, test against the real cryptographic stack — not only local mocks.
Security Principle
Do not confuse successful mock testing with proof that the confidential system is secure.
A Secure FHE Development Lifecycle
FHE security should be part of the complete development process.
1. Design
Before writing Solidity:
- Identify which information must remain confidential
- Identify which information may remain public
- Define who can decrypt each result
- Define metadata that may leak
- Document infrastructure trust assumptions
- Define failure and recovery behaviour
2. Define Security Invariants
Write the rules that must always remain true.
Examples:
- Only a balance owner may decrypt their current balance
- A transfer never creates additional supply
- Failed confidential operations never change accounting
- Old owners cannot decrypt state created after ownership transfer
- A stale encrypted result cannot update current state
- No decryption reveals more information than required
3. Implement Least-Privilege Permissions
Grant each actor only the minimum access required.
Do not give permanent permissions merely because they simplify development.
4. Separate Confidential and Public State
Clearly document:
- Encrypted state
- Public state
- Public metadata
- Decrypted outputs
- Events
- Administrative information
5. Validate Every Input
Encrypted input is still user-controlled input.
Validate its origin, context, type, freshness and permitted range.
6. Protect Asynchronous Results
Bind every result to the request and state version that created it.
Reject duplicate, expired or stale results.
7. Control Resource Consumption
Limit expensive operations before attackers discover them.
8. Test the Complete Stack
Test the contract, permissions, client encryption, gateway interaction, coprocessor behaviour, decryption and failure recovery.
9. Audit Both Privacy and Security
A standard Solidity audit may not be sufficient.
The review must include:
- Smart-contract logic
- Encrypted-state permissions
- Decryption policy
- Metadata leakage
- Cryptographic integration
- Infrastructure assumptions
- Key governance
- Client-side encryption flow
10. Monitor After Deployment
Monitor:
- Unexpected decryption requests
- Permission changes
- Failed encrypted inputs
- Computation queue growth
- Repeated expensive operations
- Gateway delays
- Key-management changes
- Abnormal transaction patterns
Privacy should not eliminate observability.
Monitoring can avoid recording plaintext while still detecting dangerous behaviour.
Pre-Deployment Security Checklist
Before deploying an FHE smart contract, confirm the following.
Confidentiality
- Sensitive values remain encrypted throughout computation
- Plaintext values are not exposed in events
- Public return values do not reveal secret conditions
- Metadata leakage has been reviewed
- Only necessary results are decrypted
Permissions
- The contract has access to every ciphertext it must update
- Users can only decrypt their own authorised values
- Shared contracts do not receive unnecessary access
- Ownership changes update decryption rights
- Transient permissions are used for temporary access, and permanent permissions are granted only when strictly necessary.
Inputs
- Encrypted inputs are validated
- Inputs are bound to the correct user and contract
- Replay protection exists
- Input sizes and types are restricted
- Invalid proof data is rejected safely
Business Logic
- Traditional access control is enforced
- Reentrancy protections remain in place
- Accounting rules are tested
- Secret-dependent branches do not leak information
- Rejected actions cannot modify state
Infrastructure
- Duplicate results are rejected
- Stale results are rejected
- Delayed computation is handled
- Failed requests can be recovered
- Emergency pause controls exist
- Resource limits prevent queue flooding
Key Security
- Decryption authority is distributed appropriately
- Rotation procedures are documented
- Compromised participants can be removed
- Emergency access is controlled
- Recovery plans exist for key-management failure
Testing
- Unit tests cover all operations
- Negative tests cover unauthorised access
- Fuzz tests explore encrypted inputs
- Invariants protect confidential accounting
- Infrastructure failures are simulated
- Production-like integration tests are complete
Privacy Is a Security Feature — Not a Security Strategy
Fully Homomorphic Encryption is one of the most important advances in blockchain privacy.
It allows contracts to operate on information that validators, infrastructure operators and public observers cannot read.
But FHE does not automatically make a protocol safe.
It does not automatically prevent:
- Bad permissions
- Unsafe decryption
- Metadata leakage
- Malformed inputs
- Reentrancy
- Accounting errors
- Denial of service
- Infrastructure failure
- Key-governance problems
FHE changes the data model, but developers still control the security model.
The correct mindset is not:
"The data is encrypted, so the contract is secure."
It is:
"The data is encrypted, so I must now secure every permission, computation, disclosure and infrastructure dependency surrounding it."
Confidential smart contracts will introduce powerful new applications.
They will also require a new generation of developers who understand both Solidity security and encrypted-system security.
The future of blockchain may be confidential.
But confidentiality without security is only a more private way to lose funds.
Final Thoughts
The most important lessons are simple:
✓ Encrypt only what needs to be private. ✓ Reveal only what users truly need to know. ✓ Treat encrypted permissions as critical access control. ✓ Validate encrypted inputs as hostile user input. ✓ Assume metadata can leak information. ✓ Protect asynchronous computation from stale and duplicate results. ✓ Limit expensive operations before they become denial-of-service tools. ✓ Apply every traditional Solidity security practice. ✓ Test the full cryptographic infrastructure — not only local mocks. ✓ Treat key governance as part of the protocol itself.
FHE gives smart contracts privacy.
Developers must still give them security.
Which FHE smart-contract risk do you think developers are most likely to overlook: permissions, decryption, metadata or infrastructure dependencies? Share your thoughts in the comments.
Further Reading
- Zama FHEVM framework and architecture documentation.
- Zama access-control documentation for encrypted values.
- SoK: Fully Homomorphic Encryption in Smart Contracts, covering key management, scalability, branching and encrypted-input verification challenges.