Zenpower AMM Infrastructure

Last updated 31 Dec 2025, 16:08

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 pools
  • AFTER_SWAP_FLAG - Calculates and collects fees
  • AFTER_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

  1. Core contracts deployed (ZENCOIN, Treasury)
  2. For ZenTreasuryHook: Uniswap V4 PoolManager address
  3. For ZenFarming: ZENCOIN address and treasury address

Deployment Order

  1. Deploy ZenFarming (can be done independently)

    make deploy-farming-sepolia
    
  2. Fund ZenFarming with ZENCOIN rewards

    • Grant MINTER_ROLE to owner or use existing supply
    • Transfer reward tokens to farming contract
  3. Add LP Pools

    make setup-farming-pool
    
  4. Deploy 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