Security architecture, trust assumptions, and known limitations for the BlindDeal confidential negotiation protocol.
BlindDeal uses Fully Homomorphic Encryption (FHE) on Fhenix/Arbitrum Sepolia to compute deal match and midpoint prices entirely on ciphertext. Prices are never revealed unless both parties' ranges overlap.
The canonical finalization path is finalizeDeal(), which relies on the Fhenix Threshold Network to decrypt the encrypted match result (isMatch) on-chain.
- Trust: Fhenix Threshold Network (decentralized MPC nodes)
- Security: No single party can influence the result. The FHE computation in
_resolve()is the sole source of truth. - Status: Works on networks where
ITaskManager.createDecryptTask()is supported. On current testnets, this may revert.
When the Threshold Network is unavailable, clientFinalizeDeal() provides a fallback. To prevent single-party griefing, it requires 2-of-2 consensus:
- Party A calls
proposeClientFinalize(dealId, matched)with their decrypted result - Party B calls
clientFinalizeDeal(dealId, matched)to confirm the same result - If results don't match, the deal remains Open until consensus is reached or
finalizeDeal()succeeds
- Trust: Both parties must act honestly and agree on the decrypted result
- Griefing protection: A single party cannot force a false state. Collusion is still possible (both parties lie together), but this is no worse than off-chain collusion.
- Timeout: Proposals expire after 1 hour (
CLIENT_PROPOSAL_TTL). The proposer can withdraw at any time viaexpireClientProposal().
Escrow settlement uses BlindDealEscrow.sol — a purpose-built native ETH escrow with buyer approval and arbiter dispute resolution.
- Trust: BlindDealEscrow contract + designated arbiter (governable via 2-day change delay)
- Risk: If
clientFinalizeDealis exploited (requires collusion), a falseMatchedstate could trigger escrow creation. The 2-of-2 consensus prevents this. Within the escrow itself, the buyer must actively approve release, preventing auto-drain on false match.
| Attack | Vector | Mitigation |
|---|---|---|
| Single-party lies about match result | clientFinalizeDeal griefing |
2-of-2 consensus required — proposer and confirmer must agree |
| Massive description gas griefing | Unlimited string input | MAX_DESCRIPTION_LENGTH = 280 enforced on creation |
| Self-deal | Buyer = seller | Reverted by SelfDeal error |
| Double submission | Replay encrypted price | AlreadySubmitted check per role |
| Open deal squatting | Join then cancel | Seller can cancel before submitting, but buyer can recreate |
| Deadline overflow | duration > 365 days |
DeadlineTooLong check |
| Front-running finalize | Mempool visibility | finalizeDeal is permissionless; clientFinalizeDeal requires consensus, so front-running doesn't help |
- Testnet Threshold Decryption:
createDecryptTaskis wrapped intry/catchbecause Arbitrum Sepolia's TASK_MANAGER doesn't support it. This forces reliance on client consensus. - CoFHE Permit Expiry: ZK proof permits expire after ~30 seconds. Users may need to retry submissions if the permit expires between encryption and transaction confirmation.
- No On-Chain Price Oracle: Prices are arbitrary units. The escrow assumes USDC (6 decimals) but the contract itself is unit-agnostic.
- No Reputation System: Open marketplace deals rely on first-come-first-served without seller reputation scoring.
- Remove or gate
clientFinalizeDealbehind an oracle whenfinalizeDealis fully operational - Add economic stake (slashing) for false consensus proposals
- Implement seller reputation / bonding for Open deals
- Add time-locked appeal period before escrow release
- Audit FHE input validation (ZK proof verification is handled by CoFHE)
This is a testnet demonstration protocol. Do not deposit mainnet funds. The contracts have not been formally audited by a third-party security firm.