Uniswap V4 Hook for real-world restaurant payments with dynamic fees, loyalty rewards, and FOODY token cashback — natively deployed on Unichain.
UniFoody is a full-stack Web3 restaurant payment platform that bridges traditional dining with DeFi. When a customer pays at a restaurant, our FoodySwap Hook intercepts the Uniswap V4 swap to:
- Validate the transaction (restaurant whitelist, operating hours, amount limits)
- Apply dynamic pricing (loyalty-based fee discounts + peak hour adjustments)
- Settle and reward (fee splitting, FOODY cashback minting, tier upgrades, VIP NFT)
Built natively on Unichain — Uniswap Labs' own L2 with 200ms Flashblocks — for the lowest latency and tightest protocol integration possible.
FoodySwapHook.sol (ONE Hook, THREE Layers)
│
├── beforeSwap()
│ ├── Layer 1: Constraints
│ │ ├── Restaurant whitelist verification
│ │ ├── Operating hours validation (block.timestamp)
│ │ └── Per-transaction amount limits (min/max USDC)
│ │
│ └── Layer 2: Dynamic Pricing
│ ├── Tier-based fee discount (2% / 5% / 8% / 12%)
│ ├── Peak hour adjustment (lunch/dinner = lower fees)
│ └── LPFeeLibrary.OVERRIDE_FEE_FLAG for dynamic override
│
└── afterSwap()
└── Layer 3: Settlement + Rewards
├── Fee split: Restaurant 90% / Platform 5% / Reward Pool 5%
├── FOODY cashback mint (3-10% based on loyalty tier)
├── Loyalty tracking + automatic tier upgrade
├── Referral bonus (referrer earns 0.5% of referee's spend)
└── VIP NFT auto-mint at $1000+ cumulative spend
First Uniswap V4 Hook designed for autonomous AI agent interaction.
Traditional DeFi hooks are build-for-humans — agents must reverse-engineer ABIs, make 5+ RPC calls for basic user data, and can't preview swap outcomes. UniFoody solves this with two purpose-built on-chain functions and a self-describing REST API:
| Function | Purpose | Replaces |
|---|---|---|
quoteSwap(address,bytes32,uint256) |
Simulate swap before executing — returns fees, cashback, tier changes, VIP mint prediction | Manual fee calculation + constraint checking |
getAgentProfile(address) |
Complete user profile in ONE call — tier, balances, discounts, next-tier progress | 5+ separate readContract() calls |
1. DISCOVER → GET /api/v1/restaurants (find registered restaurants)
2. QUOTE → POST /api/v1/quote (simulate swap outcomes on-chain)
3. EXECUTE → swap() via Universal Router (execute with hookData)
4. MONITOR → GET /api/v1/loyalty/:address (track rewards + tier progress)
# Zero-config agent onboarding — the API describes itself
curl https://unifoody.com/api/v1 | jq
# Returns: endpoints, contracts, chain info, agent_features, workflow- No ABI reverse-engineering —
GET /api/v1returns everything an agent needs - One call, not five —
getAgentProfile()replaces 5+ separate reads - Safe simulation —
quoteSwap()never reverts, returns structured denial reasons - Tier-aware — agents see projected tier upgrades and VIP NFT minting before execution
| Tier | Min Spend | Fee Discount | Cashback | Perk |
|---|---|---|---|---|
| Bronze | $0 | 2% | 3% FOODY | Welcome bonus |
| Silver | $200 | 5% | 5% FOODY | Priority support |
| Gold | $500 | 8% | 7% FOODY | Exclusive menu items |
| VIP | $1,000 | 12% | 10% FOODY | Soulbound VIP NFT |
| Contract | Description |
|---|---|
FoodySwapHook.sol |
Uniswap V4 Hook — constraints, pricing, settlement |
FoodyToken.sol |
ERC-20 with AccessControl MINTER_ROLE (1B max supply) |
FoodyVIPNFT.sol |
Soulbound ERC-721 for VIP tier holders |
| Component | Address |
|---|---|
| PoolManager (V4) | 0x1F98400000000000000000000000000000000004 |
| Universal Router | 0xEf740bf23aCaE26f6492B10De645D6b98dC8Eaf3 |
| PositionManager | 0x4529A01c7A0410167c5740C487A8DE60232617bf |
| Quoter V4 | 0x333e3C607B141b18fF6dE9f258Db6E77Fe7491E0 |
| StateView | 0x86e8631a016f9068c3f085faf484ee3f5fdee8f2 |
| USDC | 0x078D782b760474a361dDA0AF3839290b0EF57AD6 |
| Permit2 | 0x000000000022D473030F116dDEE9F6B43aC78BA3 |
unifoody/
├── contracts/ # Solidity (Foundry)
│ ├── src/
│ │ ├── FoodySwapHook.sol # V4 Hook (3-layer architecture)
│ │ ├── FoodyToken.sol # ERC-20 with MINTER_ROLE
│ │ └── FoodyVIPNFT.sol # Soulbound ERC-721
│ ├── test/
│ │ ├── FoodySwapHook.t.sol # 24 unit tests
│ │ └── FoodySwapHook.fuzz.t.sol # 6 fuzz tests (256 runs each)
│ ├── script/
│ │ ├── DeployFoodyToken.s.sol
│ │ ├── DeployFoodySwap.s.sol # CREATE2 salt mining
│ │ └── CreatePool.s.sol # Pool creation + liquidity
│ └── foundry.toml # Unichain RPC + Uniscan verification
│
├── app/ # Next.js 14 dApp
│ ├── src/
│ │ ├── lib/
│ │ │ ├── chains.ts # Unichain + Unichain Sepolia definitions
│ │ │ ├── constants.ts # Chain ID 130, contract addresses
│ │ │ └── uniswap-v4/ # V4 Hook interaction layer
│ │ └── components/
│ │ └── Wallet/ # Multi-wallet (MetaMask + WalletConnect + Coinbase)
│ ├── Dockerfile # Multi-stage (node:20-alpine)
│ └── cloudbuild.yaml # Google Cloud Run deployment
│
└── README.md # This file
- Foundry
- Node.js 20+ + pnpm
- MetaMask or any EVM wallet with Unichain Sepolia ETH
cd contracts
# Install dependencies
forge install
# Build
forge build
# Run all tests (24 unit + 6 fuzz = 36 total)
forge test -vv
# Gas snapshot
forge snapshot
# Deploy to Unichain Sepolia
cp .env.example .env
# Fill in your PRIVATE_KEY, ADMIN_ADDRESS, UNISCAN_API_KEY
forge script script/DeployFoodyToken.s.sol --rpc-url unichain_sepolia --broadcast --verify
forge script script/DeployFoodySwap.s.sol --rpc-url unichain_sepolia --broadcast --verify
forge script script/CreatePool.s.sol --rpc-url unichain_sepolia --broadcast --verifycd app
# Install dependencies
pnpm install
# Configure environment
cp .env.example .env.local
# Fill in contract addresses after deployment
# Development
pnpm dev
# Production build
pnpm buildAll 36 tests pass (24 unit + 6 fuzz + 6 utility):
$ forge test
[PASS] test_afterSwap_mintsCashback() (gas: ...)
[PASS] test_afterSwap_upgradesTier() (gas: ...)
[PASS] test_beforeSwap_blocksClosedRestaurant() (gas: ...)
[PASS] test_beforeSwap_dynamicFeeOverride() (gas: ...)
[PASS] test_beforeSwap_peakHourDiscount() (gas: ...)
[PASS] test_referral_bonus() (gas: ...)
[PASS] test_vipNFT_autoMint() (gas: ...)
[PASS] testQuoteSwap_ActiveRestaurant() (gas: ...)
[PASS] testQuoteSwap_ProjectsTierUpgrade() (gas: ...)
[PASS] testQuoteSwap_VIPMintProjection() (gas: ...)
[PASS] testGetAgentProfile_NewUser() (gas: ...)
[PASS] testFuzz_QuoteSwapNeverReverts() (runs: 256, ...)
...
Test result: ok. 36 passed; 0 failed; 0 skipped
- Diner: Scan to Pay, wallet balance, transaction history, loyalty rewards, FOODY earnings
- Restaurant: QR code generator, order management, NFC tag support, AVOS analytics
- Admin: Platform overview, user/restaurant management, on-chain analytics (8 tabs)
- FOODY token (via Uniswap V4 Hook)
- Stripe (fiat credit/debit)
- Square (POS integration)
- Coinbase Onramp (fiat-to-crypto)
- Gemini Live API: Real-time voice ordering via phone
- Vision AI: Dish recognition from photos
- Multilingual support: English, Chinese, Spanish
- PWA with offline support + push notifications
- i18n (EN/ZH/ES) with locale routing
- Multi-wallet: MetaMask, WalletConnect, Coinbase Wallet
- Background sync for failed transactions
| Partner | Integration |
|---|---|
| Unichain | Native L2 deployment (Chain ID 130) |
| Uniswap V4 | Hook architecture (PoolManager, Universal Router) |
| OpenZeppelin | BaseHook, AccessControl, ERC-20, ERC-721 |
| Stripe | Fiat payment processing |
| Square | POS terminal integration |
| Twilio | Phone-based voice ordering |
| Google Cloud | Cloud Run, Cloud SQL, Vertex AI, Speech/TTS |
| WalletConnect | Multi-wallet connectivity |
- Role-based access control (MINTER_ROLE for cashback minting)
- 1B max supply cap on FOODY token prevents infinite mint
- Soulbound VIP NFT (non-transferable)
- Restaurant whitelist prevents unauthorized pool access
- Operating hours enforcement via block.timestamp
- Transaction amount limits (min/max USDC per swap)
- Platform wallet + reward pool separation
- Reentrancy protection via Uniswap V4 PoolManager lock
- Native Uniswap Integration — Deployed on Uniswap's own L2 for first-class V4 Hook support
- 200ms Flashblocks — Near-instant payment confirmations for real-world restaurant use
- Low Gas Costs — OP Stack L2 economics make micro-transactions viable
- Uniswap Ecosystem — Direct access to Uniswap liquidity and tooling
Built by the UniFoody team for UHI Cohort 8.
- Ken Liao — Full-stack developer, Web3 architect
- Discord:
foodyepay_96725
MIT
Built with Uniswap V4 Hooks on Unichain