Privacy-first on-chain payroll. Salaries nobody can see. Payments everyone can trust.
Live App · Documentation · Deployed on Sepolia · Built with Zama fhEVM
Payroll on-chain sounds great until you realize everyone can see what everyone earns. Every salary, every payment, every balance public on the blockchain for anyone to inspect. That's not how the real world works, and it shouldn't be how web3 works either.
DripPay uses Fully Homomorphic Encryption (FHE) to make on-chain payroll actually private. Salaries are encrypted before they hit the chain. The contract does math on encrypted numbers adds salaries to balances, compares withdrawal amounts without ever decrypting them. Only the individual employee can decrypt their own balance, client-side, with their wallet.
Not even the blockchain validators can see what you earn.
Employer Smart Contract Employee
| | |
|-- Create Organization ------------>| |
| | |
|-- Add Employee (encrypted salary)->| FHE.allow(salary, employee) |
| | FHE.allow(salary, admin) |
| | |
|-- Deposit ETH/ERC-20 ------------>| |
| | |
|-- Run Payroll -------------------->| balance += salary (encrypted) |
| | |
| |<--- Decrypt Balance ------------|
| | (wallet signature + FHE) |
| | |
| |<--- Withdraw ------------------|
| | (real tokens transferred) |
- Employer creates an organization — deploys a contract, picks ETH or ERC-20 for payments
- Adds employees with encrypted salaries — salary amounts are encrypted client-side before the transaction. The contract stores only
euint64ciphertext - Deposits funds — real ETH or tokens go into the contract pool
- Runs payroll — one click, the contract adds each employee's encrypted salary to their encrypted balance. All math happens on ciphertext
- Employees see their org automatically — wallet connect, and the factory tells them which orgs they belong to. No contract address needed
- Employees decrypt & withdraw — sign a re-encryption request with their wallet, decrypt client-side, withdraw real tokens
| Layer | Technology |
|---|---|
| Encryption | Zama fhEVM (TFHE on EVM) |
| Network | Ethereum Sepolia + Zama coprocessor |
| Contracts | Solidity 0.8.27, Hardhat, OpenZeppelin |
| Frontend | Next.js 16, React 19, TypeScript |
| Styling | Tailwind CSS v4, Framer Motion |
| Wallet | wagmi v2, viem, RainbowKit |
| FHE Client | fhevmjs (encrypt inputs, decrypt outputs) |
| Fonts | Bricolage Grotesque + Plus Jakarta Sans |
DripPay/
├── contract/ # Solidity smart contracts
│ ├── contracts/
│ │ ├── OrganizationFactory.sol # Deploys orgs, indexes employees
│ │ ├── Organization.sol # Payroll logic, FHE operations
│ │ └── TestToken.sol # Mock ERC-20 for testing
│ ├── scripts/deploy.ts # Deployment script
│ └── hardhat.config.ts
│
├── frontend/ # Next.js application
│ ├── src/
│ │ ├── app/
│ │ │ ├── dashboard/ # Employer org list
│ │ │ ├── dashboard/[address]/ # Org detail dashboard
│ │ │ ├── employee/ # Employee org list
│ │ │ ├── employee/[address]/ # Employee balance view
│ │ │ ├── docs/ # Documentation (gitbook-style)
│ │ │ ├── not-found.tsx # Custom 404 page
│ │ │ └── api/chat/ # AI chatbot API
│ │ ├── components/
│ │ │ ├── dashboard/ # Employer components
│ │ │ ├── employee/ # Employee components
│ │ │ ├── landing/ # Landing page sections
│ │ │ └── shared/ # Shared (Modal, Confetti, etc.)
│ │ ├── hooks/ # useOrganization, useFhevm, useEthPrice
│ │ └── lib/ # Contracts, ABIs, animations
│ └── public/
│
└── README.md # You are here
The entry point. Deploys new Organization contracts and maintains a registry of which employees belong to which orgs.
| Function | Description |
|---|---|
createOrg(name, paymentToken) |
Deploy a new org. address(0) = ETH payments |
getOrganizations(admin) |
Get all orgs an admin created |
getEmployeeOrganizations(employee) |
Get all orgs an employee belongs to |
Where the magic happens. All salary and balance data is encrypted on-chain using Zama's TFHE library.
| Function | Who | Description |
|---|---|---|
addEmployees(addresses, encryptedSalaries, proof) |
Admin | Add employees with FHE-encrypted salaries |
removeEmployee(address) |
Admin | Remove an employee |
runPayroll() |
Admin | Add salary to every employee's balance (all encrypted) |
deposit(amount) |
Anyone | Fund the org's payment pool |
withdraw(amount) |
Employee | Withdraw from accumulated balance |
balanceOf(employee) |
View | Get encrypted balance handle for client-side decryption |
salaryOf(employee) |
View | Get encrypted salary handle for admin/employee decryption |
getTotalPayrollCost() |
View | Get encrypted sum of all salaries |
updateSalary(employee, encSalary, proof) |
Admin | Update an employee's encrypted salary |
checkBudget() |
Admin | FHE comparison: does balance cover total payroll? |
Key FHE operations in runPayroll():
// This addition happens on encrypted values — nobody sees the amounts
euint64 newBalance = FHE.add(_balances[emp], _salaries[emp]);- Node.js 18+
- pnpm
- A wallet with Sepolia ETH (faucet)
git clone https://github.com/your-username/DripPay.git
cd DripPay
# Install contract dependencies
cd contract && pnpm install
# Install frontend dependencies
cd ../frontend && pnpm install# Contract — create .env
cp contract/.env.example contract/.env
# Add your DEPLOYER_PRIVATE_KEY and INFURA_API_KEY
# Frontend — create .env
cp frontend/.env.example frontend/.env
# Add your NEXT_PUBLIC_WALLETCONNECT_PROJECT_IDcd contract
npx hardhat compile
npx hardhat run scripts/deploy.ts --network sepoliaCurrent deployment:
- OrganizationFactory:
0xE7121d656dc7DF514242Ba516AE8a8e061d3336A
Copy the factory address to frontend/.env:
NEXT_PUBLIC_FACTORY_ADDRESS=0xE7121d656dc7DF514242Ba516AE8a8e061d3336A
cd frontend
pnpm devOpen http://localhost:3000.
- Connect wallet on
/dashboard - Create a new organization (name, ETH or ERC-20, payroll cycle)
- Add employees - enter wallet addresses and salary amounts (FHE-encrypted before tx). Supports CSV bulk import.
- Deposit funds into the org contract
- Click "Reveal Salaries" to bulk-decrypt all salaries with one wallet signature
- Click "Execute Payroll" - encrypted salaries credited to all employees with confetti celebration
- View payroll schedule with countdown to next payroll date
- Update salaries, check budget, download receipts, export history (PDF/CSV)
- Each org has a unique URL (
/dashboard/0x...) - bookmarkable and refresh-safe
- Connect wallet on
/employee - Your organizations appear automatically (auto-discovery, no contract address needed)
- Click an org - navigates to
/employee/0x...(bookmarkable) - "Decrypt & View" - sign with your wallet, see your actual balance with USD estimate
- Download payslips per payroll run (dark/light PDF themes)
- Withdraw funds and export transaction history whenever you want
Traditional smart contracts store everything in plaintext. Anyone with an Etherscan link can see every balance and every transfer. DripPay changes this:
Encryption (employer adding salary):
const instance = await getFhevmInstance();
const input = instance.createEncryptedInput(contractAddress, userAddress);
input.add64(salaryInWei);
const encrypted = await input.encrypt();
// encrypted.handles[0] and encrypted.inputProof go to the contractOn-chain math (contract running payroll):
// FHE.add operates on ciphertext — the EVM never sees plaintext
_balances[emp] = FHE.add(_balances[emp], _salaries[emp]);Decryption (employee viewing balance):
const { publicKey, privateKey } = instance.generateKeypair();
const eip712 = instance.createEIP712(publicKey, [contractAddress], timestamp, 1);
const signature = await wallet.signTypedData(eip712);
const result = await instance.userDecrypt([{ handle, contractAddress }], ...);
// Only this employee can see the resultThe key insight: the contract can do arithmetic on encrypted values without ever decrypting them. The Zama coprocessor handles the homomorphic operations, and the result is a new ciphertext that only authorized parties (the employee + admin) can decrypt.
DripPay uses a "Refined Noir" aesthetic a pure dark background (#09090b) with a single green accent (#00e5a0). No rainbow gradients, no multi-color chaos. The UI is designed to feel like a premium fintech product, not a hackathon prototype.
- Typography: Bricolage Grotesque for headings, Plus Jakarta Sans for body
- Animations: Framer Motion with staggered reveals, spring physics, and subtle hover states
- Mobile-first: Fully responsive down to 400px card layouts on mobile, tables on desktop
- Dark mode only: Because payroll apps should look serious
Built for PL Genesis: Frontiers of Collaboration (March 2026).
Target Bounties:
- Zama — Confidential Blockchain Protocol
- Crecimiento — Bring Argentina Onchain
- Funding the Commons — Bridge Between Builders
- Fresh Code Track — $50,000 pool
- Encrypted salary storage and batch payroll (FHE.add on ciphertext)
- Employee auto-discovery (factory indexes employees, no CA sharing needed)
- Salary reveal for admins (bulk "Reveal All Salaries" with one wallet signature)
- Encrypted total payroll cost (FHE sum of all salaries, admin-decryptable)
- Confidential budget check (FHE comparison: balance vs total payroll)
- Salary updates (re-encrypt and update any employee's salary)
- Encrypted payslips and receipts (per-event, dark/light PDF themes)
- Full history export (PDF and CSV with formatted reports)
- Interactive demo mode (guided 4-step walkthrough, no wallet needed)
- Multi-currency USD estimates (live ETH/USD price from CoinGecko)
- Payroll scheduling (one-time, weekly, bi-weekly, monthly with countdown)
- Confetti celebration on payroll execution
- URL-based routing (/dashboard/[address], /employee/[address]) - bookmarkable, refresh-safe
- Custom 404 page with DripPay branding
- Comprehensive documentation (/docs) with gitbook-style sidebar navigation
- AI chatbot assistant with knowledge of all DripPay features
- Per-employee delete with on-chain confirmation tracking
- Wallet disconnect detection on detail pages
- Phase 2: Verifiable Income Proofs - The biggest unsolved problem in confidential payroll. Salaries are private, but employees still need to prove their income to banks, landlords, embassies, and lenders. We plan to integrate ZK attestations so employees can generate proofs like "my salary is above $X/month" without revealing the exact amount. The flow: decrypt salary client-side, generate a ZK proof (Circom/Noir) over the plaintext, third parties verify the proof on-chain against the encrypted handle. This bridges FHE privacy with real-world verifiability.
- Phase 3: Confidential Fundraising - Teams and DAOs raise funds on-chain with individual contribution amounts encrypted, but totals publicly verifiable using FHE aggregation
- Recurring payroll auto-execution via Chainlink Automation
- Multi-sig admin support (require N-of-M approvals to run payroll)
- ERC-7984 token integration
- Mainnet deployment
Salaries are private. Payments are trustless. That's DripPay.
