Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

31 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ›ก๏ธ PayShield

Confidential payroll processing for contractors, built with CoFHE on Arbitrum Sepolia.

โ— Problem Statement

Traditional on-chain payroll leaks sensitive compensation metadata. Even if funds are transferred securely, raw salary numbers can still appear in mempools, events, or contract state.

PayShield is designed so payroll arithmetic happens on encrypted values end-to-end:

  • ๐Ÿ” Contractor hours are encrypted client-side.
  • ๐Ÿ” Contractor rates are encrypted client-side.
  • ๐Ÿงฎ Payroll computation executes on ciphertext with FHE.mul(hours, rate).
  • ๐Ÿ‘ค Only authorized recipients can decrypt outputs.

Why FHE is required: encryption in transit alone is insufficient because values become plaintext during smart-contract execution in typical designs. With CoFHE, values stay encrypted during computation, preserving confidentiality for both employers and contractors.

๐Ÿ—๏ธ Architecture (3 Layers)

PayShield Architecture

๐Ÿ“š Layer Responsibilities

  1. App Layer
    • Encrypts payroll inputs in browser.
    • Submits encrypted payloads to contracts.
  2. Host Chain (Arbitrum Sepolia)
    • Coordinates payroll lifecycle and access control.
    • Stores encrypted records and payout state.
  3. CoFHE Layer
    • Executes homomorphic operations such as FHE.mul.
    • Supports controlled decryption for entitled addresses.

๐Ÿ“ Monorepo Structure

payshield/
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ backend/
โ”‚   โ”œโ”€โ”€ contracts/
โ”‚   โ”‚   โ”œโ”€โ”€ PayShieldPayroll.sol
โ”‚   โ”‚   โ”œโ”€โ”€ PayShieldRegistry.sol
โ”‚   โ”‚   โ”œโ”€โ”€ PayShieldEscrow.sol
โ”‚   โ”‚   โ””โ”€โ”€ PayShieldPool.sol
โ”‚   โ”œโ”€โ”€ test/
โ”‚   โ”‚   โ”œโ”€โ”€ PayShieldPayroll.test.ts
โ”‚   โ”‚   โ”œโ”€โ”€ PayShieldRegistry.test.ts
โ”‚   โ”‚   โ””โ”€โ”€ PayShieldEscrow.test.ts
โ”‚   โ”œโ”€โ”€ scripts/
โ”‚   โ”‚   โ”œโ”€โ”€ deploy.ts
โ”‚   โ”‚   โ””โ”€โ”€ deploy-mock-token.ts
โ”‚   โ”œโ”€โ”€ tasks/
โ”‚   โ”‚   โ”œโ”€โ”€ fund-payroll.ts
โ”‚   โ”‚   โ””โ”€โ”€ process-payout.ts
โ”‚   โ”œโ”€โ”€ deployments/
โ”‚   โ”‚   โ””โ”€โ”€ .gitkeep
โ”‚   โ”œโ”€โ”€ .env.example
โ”‚   โ”œโ”€โ”€ hardhat.config.ts
โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ”œโ”€โ”€ reineira.json
โ”‚   โ””โ”€โ”€ tsconfig.json
โ””โ”€โ”€ frontend/
     โ”œโ”€โ”€ public/
     โ”‚   โ””โ”€โ”€ favicon.ico
     โ”œโ”€โ”€ src/
     โ”‚   โ”œโ”€โ”€ components/
     โ”‚   โ”‚   โ”œโ”€โ”€ EmployerDashboard.tsx
     โ”‚   โ”‚   โ”œโ”€โ”€ PayrollForm.tsx
     โ”‚   โ”‚   โ”œโ”€โ”€ ContractorView.tsx
     โ”‚   โ”‚   โ””โ”€โ”€ PoolFunding.tsx
     โ”‚   โ”œโ”€โ”€ hooks/
     โ”‚   โ”‚   โ”œโ”€โ”€ usePayroll.ts
     โ”‚   โ”‚   โ””โ”€โ”€ useFHE.ts
     โ”‚   โ”œโ”€โ”€ lib/
     โ”‚   โ”‚   โ””โ”€โ”€ config.ts
     โ”‚   โ”œโ”€โ”€ App.tsx
     โ”‚   โ””โ”€โ”€ main.tsx
     โ”œโ”€โ”€ .gitignore
     โ”œโ”€โ”€ eslint.config.js
     โ”œโ”€โ”€ index.html
     โ”œโ”€โ”€ package.json
     โ”œโ”€โ”€ tsconfig.app.json
     โ”œโ”€โ”€ tsconfig.node.json
     โ””โ”€โ”€ vite.config.ts

โš™๏ธ Tech Stack

Package Version Location
hardhat ~2.26.x backend
@fhenixprotocol/cofhe-contracts ^0.1.3 backend
@cofhe/hardhat-plugin ^0.4.0 backend
@cofhe/sdk ^0.4.0 backend + frontend
@reineira-os/sdk ^0.1.0 backend + frontend
ethers ^6.x backend
typechain ^8.x backend
typescript ^5.x backend + frontend
react ^18.x frontend
vite ^5.x frontend
wagmi ^2.x frontend
viem ^2.x frontend
@cofhe/react ^0.4.0 frontend
node >=20 runtime

๏ฟฝ Security

PayShield implements production-grade security hardening across all contracts:

Contract Security

  • ReentrancyGuard: All state-changing functions protected against reentrancy attacks using OpenZeppelin's ReentrancyGuard pattern
  • Access Control: Strict role-based permissions (onlyEmployer, onlyPayrollContract, owner) prevent unauthorized fund transfers
  • Input Validation: FHE-compatible validation (no plaintext salary checks) with custom errors for each edge case
  • Checks-Effects-Interactions: State mutations ordered correctly to prevent supply mistakes and external call vulnerabilities
  • Silent Failure Pattern: USDC transfers fail silently (no reverting), allowing payroll processing to continue even if some recipients have deprecated addresses

Custom Errors

All contracts use custom Solidity errors (not string require messages) for gas efficiency and client-side error decoding:

  • ContractorNotRegistered - Contractor not found in employer's directory
  • InsufficientPoolBalance - Employer pool has insufficient USDC to cover payroll
  • PayrollTooRecent - Payroll submitted too frequently for same contractor (24hr cooldown)
  • UnauthorizedCaller - Function called by non-authorized address
  • TransferFailed - Silent failure on USDC transfer (logged, not reverted)

Frontend Security

  • Client-Side Encryption: All FHE encryption happens in the browser; plaintext wages never transmitted
  • Error Handling: Comprehensive try-catch wrapping for FHE operations with human-readable error messages
  • Retry Logic: Decryption failures auto-retry up to 3 times with 15-second delays, handling FHE network latency
  • Wallet Verification: All transactions require explicit user approval via wagmi/MetaMask

Compliance

๐Ÿ“‹ NDPR Compliance Documentation: See docs/COMPLIANCE.md for detailed analysis of:

  • Data minimisation (encrypted ciphertext only on-chain)
  • Purpose limitation (FHE.allow() access control)
  • Right of access (contractor self-decryption)
  • Right to erasure (ciphertext irreversible)
  • Data security (FHE encryption + ReentrancyGuard)
  • Third-party processors (Fhenix CoFHE, Privara SDK, Arbitrum)
  • Audit trails (employer verification without wage disclosure)

cd backend
npm install
cp .env.example .env

cd ../frontend
npm install

๐ŸŒ Arbitrum Sepolia Deployment

Deployed from backend/ using Hardhat network arbitrumSepolia with security hardening

Deployment Commands:

# Arbitrum Sepolia (current testnet)
npx hardhat run scripts/deploy.ts --network arbitrumSepolia

# Full test suite before deployment
pnpm test  # All 34 tests passing

Current Deployed Addresses (Arbitrum Sepolia)

Contract Address Deployed Verified
MockFHERC20 (USDC) 0x8A0A3cDd08Cec51bB8Ea3544414BFa47C3971D1D โœ… โœ…
PayShieldAuditLog 0x48442F565683E7D34C2aB197f8196b8e2BB11c62 โœ… โณ
PayShieldRegistry 0x25F8cAa0C6942A5B01f253EBfbf9e24d4368F1eC โœ… โœ…
PayShieldPayroll 0xd2197d44A153a76B8784d23Df1034a5F80fC3675 โœ… โณ
PayShieldMultiSig 0x273544fFF7f7b7a80d37D12d9C4EEb1C91cEa133 โœ… โณ
PayShieldPool 0x5bE4b774b1bae31992bF2e2CD9aab6a7Ee0e71F3 โœ… โœ…
PayShieldEscrow 0x0a0D6b01F61EA7e50208414b9D015320160F4D99 โœ… โณ
PayShieldCorridorRegistry 0xD9a6Ae51dcfb5969e38a628a67999Dc0A750c4B7 โœ… โณ
PayShieldSettlementRouter 0xC034ce5f034c4f39EF775b055c9B361fD76b0937 โœ… โณ

Deployment Date: May 29, 2026
Network: Arbitrum Sepolia (Chain ID: 421614)
See docs/DEPLOYMENT.md for deployment verification workflow.

Configuration

  • backend/.env:

    USDC_ADDRESS=0x8A0A3cDd08Cec51bB8Ea3544414BFa47C3971D1D
    PAYSHIELD_POOL_ADDRESS=0x5bE4b774b1bae31992bF2e2CD9aab6a7Ee0e71F3
    PAYSHIELD_ESCROW_ADDRESS=0x0a0D6b01F61EA7e50208414b9D015320160F4D99
    
  • frontend/.env:

    VITE_PAYSHIELD_AUDITLOG_ADDRESS=0x48442F565683E7D34C2aB197f8196b8e2BB11c62
    VITE_PAYSHIELD_REGISTRY_ADDRESS=0x25F8cAa0C6942A5B01f253EBfbf9e24d4368F1eC
    VITE_PAYSHIELD_PAYROLL_ADDRESS=0xd2197d44A153a76B8784d23Df1034a5F80fC3675
    VITE_PAYSHIELD_MULTISIG_ADDRESS=0x273544fFF7f7b7a80d37D12d9C4EEb1C91cEa133
    VITE_PAYSHIELD_POOL_ADDRESS=0x5bE4b774b1bae31992bF2e2CD9aab6a7Ee0e71F3
    VITE_PAYSHIELD_ESCROW_ADDRESS=0x0a0D6b01F61EA7e50208414b9D015320160F4D99
    VITE_PAYSHIELD_CORRIDOR_REGISTRY_ADDRESS=0xD9a6Ae51dcfb5969e38a628a67999Dc0A750c4B7
    VITE_PAYSHIELD_SETTLEMENT_ROUTER_ADDRESS=0xC034ce5f034c4f39EF775b055c9B361fD76b0937
    

๐Ÿ“Š Gas Benchmarks

PayShield has been optimized for gas efficiency on Arbitrum Sepolia (Layer 2).

Metric Value Notes
Total Deployment ~2.78M gas 4 contracts + initialization
submitPayroll() ~187k gas FHE.mul() + registry checks
confirmPayroll() ~69k gas Escrow release call
deposit() ~78k gas USDC transfer + balance update
release() ~52k gas Contractor fund transfer

๐Ÿ“ˆ Complete Analysis: See docs/GAS_BENCHMARKS.md for:

  • Per-function gas breakdown by contract
  • FHE operation overhead comparison
  • Wave 3 โ†’ Wave 4 optimization results
  • Future optimization opportunities

Note: Gas costs are ~50-70% lower on Arbitrum compared to Ethereum Mainnet due to L2 compression.


๐ŸŒ Payment Corridors (Wave 5)

PayShield Wave 5 includes Payment Corridor Tagging for cross-border payroll settlements:

Corridor Route Status Settlements
Nigeria-UK NG โ†’ GB Active 0
Kenya-India KE โ†’ IN Active 0

Corridor Features:

  • ๐Ÿท๏ธ Corridor Labeling: Employers tag USDC disbursements with destination corridors (e.g., "Nigeria-UK")
  • ๐Ÿ’ฑ Exchange Rate References: Employers store up to 64-byte rate metadata per team (e.g., "CBN-2025-05-23")
  • ๐Ÿ“Š Settlement Tracking: Each corridor tracks total disbursements and settlement counts
  • ๐Ÿ” Team Isolation: Settlement records isolated by teamId (keccak256 of employer address)
  • ๐Ÿ“‹ Audit Logging: All corridor operations logged via PayShieldAuditLog with immutable records
  • ๐Ÿ‘๏ธ Privacy Preserved: Corridor labels are plaintext for routing; underlying wage amounts remain encrypted from Wave 5

Usage Flow:

  1. Employer calls setExchangeRateRef(teamId, rateRef) to store corridor metadata
  2. PayShieldMultiSig routes settlement via routeSettlement(teamId, employer, contractor, corridorId, usdcAmount)
  3. PayShieldSettlementRouter verifies corridor is active, calls PayShieldEscrow.release(), logs to audit
  4. Contractors view their records via getContractorRecords(teamId) without seeing exchange rate metadata
  5. Employers view full settlement history via getTeamSettlements(teamId) including rate references

Compliance: See docs/COMPLIANCE.md Section 9 for NDPR analysis of corridor tagging.


โœ… Testing & Validation

Wave 5 Test Suite (Current - 97 Tests)

Executed in backend/:

pnpm test

Test Coverage by Component:

  • PayShieldRegistry (6 tests) โ€” Wave 4 baseline
  • PayShieldPayroll (13 tests) โ€” Wave 4 baseline
  • PayShieldEscrow (5 tests) โ€” Wave 4 baseline + Wave 6 updates
  • PayShieldPool (10 tests) โ€” Wave 4 baseline
  • PayShieldMultiSig (5 tests) โ€” Wave 5
  • PayShieldAuditLog (16 tests) โ€” Wave 5+
  • PayShieldCorridorRegistry (24 tests) โ€” Wave 5
    • โœ” Constructor initializes Nigeria-UK and Kenya-India corridors
    • โœ” registerCorridor(), pauseCorridor(), resumeCorridor() lifecycle
    • โœ” setSettlementRouter() one-time authorization
    • โœ” incrementSettlementCount() router-only access
    • โœ” View functions and edge cases (duplicate labels, max corridors)
  • PayShieldSettlementRouter (18 tests) โ€” Wave 5
    • โœ” setExchangeRateRef() with team isolation and validation
    • โœ” routeSettlement() with MultiSig-only access, corridor validation, team isolation
    • โœ” getTeamSettlements() employer-only access
    • โœ” getContractorRecords() contractor-only access
    • โœ” Data isolation enforcement (team-based mappings)

Latest Test Output:

  97 passing (5s)
  โœ” All Wave 6 corridor tests passing
  โœ” All Wave 6 settlement router tests passing
  โœ” All data isolation tests passing
  โœ” All access control tests passing
  โœ” All FHE operation tests passing

๐Ÿ“Š Gas Benchmarks (Wave 5 - Current)

PayShield has been optimized for gas efficiency on Arbitrum Sepolia (Layer 2).

Function Wave Contract Gas Notes
submitPayroll() W4 Payroll ~187k FHE.mul() + registry checks
confirmPayroll() W4 Escrow ~69k Fund release
deposit() W4 Pool ~78k USDC transfer + balance
registerCorridor() W5 CorridorRegistry ~65k New corridor creation
routeSettlement() W5 SettlementRouter ~95k Settlement routing + audit
setExchangeRateRef() W5 SettlementRouter ~45k Metadata storage

๐Ÿ“ˆ Complete Analysis: See docs/GAS_BENCHMARKS.md for:

  • Per-function gas breakdown by contract
  • FHE operation overhead comparison
  • Wave 4 โ†’ Wave 5 cost analysis
  • Future optimization opportunities

Note: Gas costs are ~50-70% lower on Arbitrum compared to Ethereum Mainnet due to L2 compression.



๐Ÿ—บ๏ธ Wave Roadmap

Wave Focus Status Tasks Tests
Wave 1 MVP Implementation โœ… Complete Payroll, Registry, Escrow 4
Wave 2 Basic Testing โœ… Complete Initial test suite 6
Wave 3 Pool Integration โœ… Complete Pool contract, fund management 10
Wave 4 ๐Ÿ” Security Hardening โœ… Complete ReentrancyGuard, custom errors, access control, FHE error handling 34
Wave 5 ๐ŸŒ Multi-Sig, Audit & Corridor Settlement โœ… Complete MultiSig governance, AuditLog, CorridorRegistry, SettlementRouter, team isolation 97

๐Ÿ“š Documentation & Resources

Project Documentation

External Resources


๐Ÿ“„ License

MIT ยฉ 2025 PayShield Contributors


PayShield is built for the gig worker who deserves privacy, the employer who needs compliance, and the protocol that makes both possible โ€” without compromise.

About

Confidential payroll platform built with CoFHE on Arbitrum Sepolia. It enables employers to process contractor payments while keeping sensitive compensation data fully encrypted end-to-end.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages