Zenpower AMM Infrastructure
Liquidity and trading infrastructure for ZENCOIN using Uniswap V4 hooks.
Deployment Chain: Arbitrum (canonical) - see GOLDEN_PATH.md
Contracts
ZenTreasuryHook.sol
Uniswap V4 hook that collects protocol fees on ZENCOIN swaps.
Features:
- 0.05% fee on all ZENCOIN swap outputs (5 basis points)
- Automatic fee accumulation in hook contract
- Admin-controlled fee withdrawal to treasury
- Pool validation (only processes ZENCOIN pairs)
Hook Permissions:
BEFORE_INITIALIZE_FLAG- Validates and registers ZENCOIN poolsAFTER_SWAP_FLAG- Calculates and collects feesAFTER_SWAP_RETURNS_DELTA_FLAG- Returns fee delta to PoolManager
Admin Functions:
// Withdraw accumulated fees to treasury
function withdrawFees(Currency currency) external onlyOwner;
// Update treasury address
function setTreasury(address newTreasury) external onlyOwner;
ZenFarming.sol
Multi-pool LP reward distribution contract for incentivizing liquidity providers.
Features:
- Multiple LP token pools with allocation points
- Decreasing emission schedule (10% reduction every ~2 weeks)
- 7-day early withdrawal penalty (5% to treasury)
- Emergency withdraw function (forfeits rewards)
- View functions for pending rewards
Emission Schedule:
Initial: 10 ZENCOIN/block
Week 2: 9 ZENCOIN/block (-10%)
Week 4: 8.1 ZENCOIN/block (-10%)
Week 6: 7.29 ZENCOIN/block (-10%)
...continues until minimum reached
User Functions:
// Stake LP tokens
function deposit(uint256 pid, uint256 amount) external;
// Unstake LP tokens (with potential penalty)
function withdraw(uint256 pid, uint256 amount) external;
// Claim pending rewards only
function harvest(uint256 pid) external;
// Emergency exit (forfeits all pending rewards)
function emergencyWithdraw(uint256 pid) external;
// View pending rewards
function pendingReward(uint256 pid, address user) external view returns (uint256);
Admin Functions:
// Add new LP pool
function addPool(uint256 allocPoint, IERC20 lpToken, bool withUpdate) external onlyOwner;
// Update pool allocation
function setPool(uint256 pid, uint256 allocPoint, bool withUpdate) external onlyOwner;
// Update reward rate
function setRewardPerBlock(uint256 _rewardPerBlock) external onlyOwner;
// Update treasury address
function setTreasury(address _treasury) external onlyOwner;
Architecture
┌─────────────────────────────────────────────────────────────┐
│ UNISWAP V4 POOLMANAGER │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ ZENCOIN/WETH │ │ ZENCOIN/USDC │ │
│ │ Pool │ │ Pool │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ └──────────┬──────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ ZenTreasuryHook │ │
│ │ (afterSwap hook) │ │
│ └─────────┬───────────┘ │
│ │ 0.05% fee │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ ZenpowerTreasury │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ LP FARMING │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ LP Tokens │ │ LP Tokens │ │
│ │ (ZENCOIN/ETH) │ │(ZENCOIN/USDC) │ │
│ └───────┬───────┘ └───────┬───────┘ │
│ │ │ │
│ └────────┬───────────┘ │
│ │ stake │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ ZenFarming │ │
│ │ (reward distrib) │ │
│ └─────────┬───────────┘ │
│ │ ZENCOIN rewards │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ LP Providers │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Deployment
Prerequisites
- Core contracts deployed (ZENCOIN, Treasury)
- For ZenTreasuryHook: Uniswap V4 PoolManager address
- For ZenFarming: ZENCOIN address and treasury address
Deployment Order
Deploy ZenFarming (can be done independently)
make deploy-farming-sepoliaFund ZenFarming with ZENCOIN rewards
- Grant MINTER_ROLE to owner or use existing supply
- Transfer reward tokens to farming contract
Add LP Pools
make setup-farming-poolDeploy ZenTreasuryHook (requires V4)
make deploy-amm-sepolia # When V4 is available
Environment Variables
# Required for farming
ZENCOIN_ADDRESS=0x...
TREASURY_ADDRESS=0x...
REWARD_PER_BLOCK=10000000000000000000 # 10 ZENCOIN
# Required for V4 hook
POOL_MANAGER_ADDRESS=0x... # V4 PoolManager
# For adding pools
FARMING_ADDRESS=0x...
LP_TOKEN_ADDRESS=0x...
ALLOC_POINT=100
Testing
# Run all AMM tests
make test-amm
# Run with extended fuzz iterations
make test-amm-fuzz
# Run specific test
forge test --match-test testFuzz_Deposit -vvv
Test Coverage
| Contract | Tests | Coverage |
|---|---|---|
| ZenFarming | 25 | Deposits, withdrawals, rewards, penalties, admin |
| ZenTreasuryHook | 12 | Fee calculations, hook flags, scenarios |
Security Considerations
ZenTreasuryHook
- Only processes swaps involving ZENCOIN
- Fee calculation uses safe math (OpenZeppelin)
- Owner-only fee withdrawal
- No upgradability (immutable after deployment)
ZenFarming
- ReentrancyGuard on all state-changing functions
- Early withdrawal penalty protects against mercenary capital
- Emergency withdraw allows users to exit without rewards
- Owner-only pool management
Known Limitations
- V4 hooks require specific address patterns (CREATE2 salt mining)
- Early withdrawal penalty may discourage short-term LPs
- Emission reduction is block-based, not time-based
Gas Estimates
| Function | Estimated Gas |
|---|---|
| deposit | ~80,000 |
| withdraw | ~100,000 |
| harvest | ~70,000 |
| emergencyWithdraw | ~60,000 |
| addPool | ~150,000 |
Integration
Frontend Integration
// Example: Check pending rewards
const pending = await farming.pendingReward(poolId, userAddress);
// Example: Deposit LP tokens
await lpToken.approve(farmingAddress, amount);
await farming.deposit(poolId, amount);
// Example: Harvest rewards
await farming.harvest(poolId);
Backend Integration
The farming contract emits events for tracking:
Deposit(address indexed user, uint256 indexed pid, uint256 amount)Withdraw(address indexed user, uint256 indexed pid, uint256 amount)EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount)
Roadmap
- ZenTreasuryHook implementation
- ZenFarming implementation
- Unit tests
- Fuzz tests
- Sepolia testnet deployment
- Frontend integration
- V4 PoolManager availability
- Mainnet deployment
- LP pool creation (ZENCOIN/WETH)
- Community LP incentive launch