VeilShield is a Fhenix CoFHE project on Arbitrum Sepolia.
Confidential cargo delay cover for exporters: delay thresholds, claim logic, and role-scoped policy views stay private on-chain.
The trigger path runs on encrypted state on-chain. Token settlement still uses a plain ERC-20 test asset, and the contract mirrors the token terms into encrypted handles where the privacy logic needs them.
Built for the Fhenix Privacy-by-Design dApp Buildathon on AKINDO WaveHack: https://app.akindo.io/wave-hacks/Nm2qjzEBgCqJD90W?tab=overview
Live app: https://veilshield.xyz
AI-assisted tools are fine in this repo. What is not fine is fake depth: code or copy that looks sophisticated but falls apart under inspection.
The bar here is straightforward:
- live contracts over mock animations
- explicit tradeoffs over vague privacy claims
- tests and deployable flows over surface-level complexity
- deliberate design choices over autogenerated noise
contracts/VeilShield.sol: the main contractcontracts/VeilShieldDemoToken.sol: the token used for premiums, LP deposits, and payoutsveilshield-app.jsx: the frontend entry pointscripts/deploy.ts: deploys both contracts and writes deployment metadatadeployments/arb-sepolia.json: the current Arbitrum Sepolia deployment
VeilShield is not trying to hide every field on-chain.
It hides the parts that matter for this use case:
- shipment delay threshold
- encrypted oracle reading
- encrypted payout selection
- user-scoped LP and policy views
And it keeps the parts that still need visible token settlement public:
- coverage amount
- premium amount
- beneficiary
- expiry
- pool token accounting
That boundary is deliberate. It is written down in the docs instead of implied by marketing copy.
| Area | Current behavior |
|---|---|
| What is encrypted | threshold, oracle reading, pending payout, LP balance handle, policy mirrors |
| What is public | coverage, premium, beneficiary, expiry, feed id, pool accounting |
| Who can decrypt what | policy holder sees own terms, beneficiary sees payout, LP sees own balance, owner sees auditor view |
ARCHITECTURE.md: contract, frontend, and live network layoutPRIVACY_MODEL.md: what is encrypted, what is public, and who can decrypt whatDEMO_FLOW.md: the fastest live demo path for a judge or video recordingWAVES.md: what shipped, what is rough, and what the next steps areUSAGE_SIGNALS.md: event names and a factual format for Wave 5 usage reportingTESTER_FEEDBACK_TEMPLATE.md: short template for 2-3 real tester interviews
- encrypted LP accounting with CoFHE handles
- encrypted oracle submissions
- trigger checks with
FHE.gteandFHE.lte - conditional routing with
FHE.select - async finalization through
FHE.decrypt - ERC-20 deposit, premium, and payout flow with
vUSD - role-based workspaces for policy holder, LP, oracle / claims, and auditor
- explicit private-view access flow for local decrypts in the frontend
- seeded exporter demo path for a non-empty live first screen
- embedded Wave 5 landing page inside the React app
- clearer claim pipeline states for
waiting on thresholdversusready to finalize - Wave 4 policy templates for shipment delay and delivery SLA delay
- LP exposure and auditor disclosure summaries in the role workspaces
- runs on a live supported testnet:
Arbitrum Sepolia - keeps part of the core protocol state encrypted during computation instead of exposing it in plaintext
- does real smart-contract evaluation with CoFHE rather than a frontend-only privacy simulation
- documents the privacy boundary in plain terms, including what is still public
- ships as a working demo with verified contracts, tests, and a live frontend
- Network:
Arbitrum Sepolia - VeilShield:
0x42Fd32Fa18975D5A2Ba57bb0e86682aE9dEb13Da - vUSD:
0x8D58098D3B2Cbef4c5fa1CFef38A0baD7Ef81C70 - Oracle:
0x4eD3265fA5217071F678eCD58eAf7f720dBf3FEc - VeilShield on Arbiscan: 0x42Fd32Fa18975D5A2Ba57bb0e86682aE9dEb13Da
- vUSD on Arbiscan: 0x8D58098D3B2Cbef4c5fa1CFef38A0baD7Ef81C70
The deployment file is in deployments/arb-sepolia.json.
Current seeded state on the new deployment:
- one active exporter policy is live
- two policies are currently in
PendingDecision - one fallback policy is already in
Cancelled, so public claim history is not empty - pool liquidity and encrypted handles are non-empty
- the remaining pending rows depend on the live threshold network returning async decrypt results
The UI now surfaces those pending rows as waiting on threshold and only enables Finalize when the threshold result is actually ready.
Canonical Wave 3 demo scenario:
- LP deposit:
50000 vUSD - active cover threshold:
48h - active cover:
1800 coverage / 120 premium - history cover threshold:
60h - history cover:
2200 coverage / 180 premium - oracle reading used for seeded trigger path:
72
Wave 4 policy templates in the frontend:
Shipment delay: threshold48h, coverage1800, premium120, expiry hint14 daysDelivery SLA delay: threshold72h, coverage2400, premium180, expiry hint21 days
These templates are frontend-level shortcuts. They keep the contract unchanged and make the exporter flow easier to evaluate.
The current wedge is exporters buying cargo / shipment delay cover.
Why this use case fits privacy-by-design:
- exporters do not want to reveal delay thresholds that expose operating tolerance
- coverage sizes can leak shipment value or treasury posture
- claims history is useful publicly, but policy terms should stay role-scoped
- LPs and auditors need controlled disclosure, not blanket transparency
npm install
npm run compile
npm test
npm run buildStart the frontend with:
npm run devYou need a browser wallet such as MetaMask. The app will ask to switch to Arbitrum Sepolia.
Create .env from .env.example and fill in at least:
PRIVATE_KEY=0x...Optional:
ARBITRUM_SEPOLIA_RPC_URL=https://...
ORACLE_ADDRESS=0x...
ETHERSCAN_API_KEY=...If ORACLE_ADDRESS is missing, deploy falls back to the deployer wallet.
npm run deploy:arb-sepoliaThis deploys:
VeilShieldDemoTokenVeilShield(oracle, asset)
Verify with:
npm run verify:arb-sepoliaSeed the live exporter scenario with:
npm run seed:arb-sepoliaIf the threshold network is slow, the seeded state may keep one or more policies in PendingDecision until the async decrypt result arrives.
- Connect a wallet on Arbitrum Sepolia.
- Mint
vUSDin the pool screen. - Approve
vUSDonce. - Deposit liquidity.
- Create a cargo delay policy with an encrypted threshold and encrypted mirrors of the token terms.
- Submit an encrypted oracle reading from the oracle wallet.
- Request evaluation.
- Wait a few seconds while the threshold network finishes the decision.
- Finalize the result.
- Settle the payout if the policy triggered.
- Request private view access, then decrypt local views for the policy holder, beneficiary, LP, or auditor role.
- quieter background refresh behavior during live demo actions
- cleaner claims language around
waiting on thresholdversusready to finalize - fewer dead-end clicks by disabling finalize actions until the threshold result is ready
- seeded claims-first screen with public history and non-empty live state
- repo-local ABI imports so Git-based Vercel deploys do not depend on local Hardhat artifacts
- added two exporter policy templates: shipment delay and delivery SLA delay
- made the claims pipeline visible as a staged flow from creation to settlement
- strengthened the
ready to finalizemarker in the claims workspace - added LP exposure context for reserved capital, open covers, and pending claims
- added auditor disclosure summaries that separate public fields, encrypted fields, and owner-scoped review data
- added
policy_template_selectto the local usage event taxonomy
- embedded the landing page into the live React app as the
Overviewworkspace - folded final presentation and evaluation readiness into Wave 5 instead of splitting it into a separate wave
- added first-screen product framing for the exporter wedge, privacy boundary, FHE flow, roles, demo link, contract links, and live deployment proof
- kept direct navigation from the landing into claims, policy, liquidity, and auditor workspaces
- kept upcoming Wave 5 work focused on replayable seeded demo state, claim history, auditor review, tester notes, and private threshold selection
- token settlement is still public in the demo asset
- beneficiary and expiry remain public
- oracle updates are still manual
- async finalize readiness depends on the live threshold network
- seeded history can still include pending rows if the threshold network is slow
- Tests are written against the local CoFHE mock setup.
- The frontend is still demo-oriented, but now includes role workspaces, private view access status, and async claim polling.
- Node 20 or 22 is safer with Hardhat than Node 25.
- The repo is fine to build with AI assistance, but every feature should still be defensible in code, tests, and runtime behavior.