Skip to main content

Lunarys Protocol Complete Overview

Executive Summary

Lunarys is the world's first fully confidential decentralized exchange (DEX) built on Zama's Fully Homomorphic Encryption (fhEVM). Every aspect of the protocol—from trading volumes to liquidity depths to governance votes—remains encrypted on-chain, providing unprecedented privacy while maintaining complete decentralization.

What Makes Lunarys Unique?

Traditional DEX (e.g., Uniswap)

 Public pool reserves (anyone can see liquidity depth)
Public trade amounts (MEV bots exploit this)
Public LP positions (whale tracking)
Public governance votes (vote buying, coercion)

Lunarys Confidential DEX

 Encrypted pool reserves (only pool contract "knows")
Encrypted trade amounts (front-running impossible)
Encrypted LP positions (privacy-preserving)
Encrypted governance votes (truly democratic)

Core Architecture

The Lunarys protocol consists of three major subsystems:

1. Liquidity Pool System

**Purpose:**Automated market maker with encrypted reserves

Components:

  • PrivacyPoolFactory - Deploys new confidential pools
  • PrivacyPool - Individual AMM pools with encrypted state
  • Hooks - Extensible integration points

**Key Innovation:**Constant product formula (x * y = k) computed entirely on encrypted values

2. Token System

**Purpose:**Confidential ERC20 tokens with encrypted balances

Components:

  • CERC20 - Base confidential token implementation
  • Implements ERC7984 standard
  • Encrypted balances, transfers, and allowances

**Key Innovation:**All token operations preserve privacy while maintaining auditability

3. DAO System

**Purpose:**Confidential governance with encrypted voting

Components:

  • ConfidentialGovernanceToken - Voting power token (LUN)
  • ConfidentialGovernor - Proposal and voting logic
  • ConfidentialTimelock - Security delay for execution
  • ConfidentialTreasury - Protocol fund management
  • ConfidentialEmissionsController - Token distribution

**Key Innovation:**Vote weights and tallies encrypted until voting ends


How It All Works Together

Example: Complete User Journey

1. User Acquires Confidential Tokens

// LUN, USDC, ZAMA, eBTC tokens already deployed
// All implement ERC7984 (Confidential ERC20)

// Receive encrypted tokens
await lunToken.confidentialTransfer(
userAddress,
encryptedAmount, // euint64
proof
);

// User's balance is ENCRYPTED
// Only user can decrypt their own balance

2. User Provides Liquidity

// Bootstrap a new pool (first time)
const pool = LUN_USDC_Pool;

// Create encrypted inputs
const input = await fhevm.createEncryptedInput(poolAddress, userAddress);
input.add64(ethers.parseUnits("1000", 6)); // 1000 LUN
input.add64(ethers.parseUnits("2000", 6)); // 2000 USDC
const encrypted = await input.encrypt();

// Approve pool to spend tokens
await lunToken.setOperator(poolAddress, futureTimestamp);
await eusdToken.setOperator(poolAddress, futureTimestamp);

// Bootstrap pool (two-phase process)
const tx = await pool.bootstrap(
encrypted.handles[0], // amountA
encrypted.inputProof,
encrypted.handles[1], // amountB
encrypted.inputProof,
userAddress, // lpRecipient
"0x" // hookContext
);

// Wait for oracle to settle
// Pool reserves are now ENCRYPTED euint64 values

What happens behind the scenes:

  1. Pool pulls encrypted tokens from user
  2. Stores reserves as euint64 ciphertexts
  3. Oracle decrypts to verify non-zero amounts
  4. Checkpoints created for historical tracking
  5. Hooks called for LP position tracking

3. User Swaps Tokens (Two-Phase Process)

Phase 1: Swap Initiation

// User wants to swap 100 LUN for USDC
const swapInput = await fhevm.createEncryptedInput(poolAddress, userAddress);
swapInput.add64(ethers.parseUnits("100", 6));
const swapEncrypted = await swapInput.encrypt();

// Initiate swap
const swapTx = await pool.swapExactAForB(
swapEncrypted.handles[0],
swapEncrypted.inputProof,
userAddress, // recipient
"0x"
);

const receipt = await swapTx.wait();
const requestID = extractRequestID(receipt);

console.log(`Swap initiated. Request ID: ${requestID}`);

What happens:

  1. Pool pulls 100 LUN (encrypted) from user
  2. Applies swap fee: amountAfterFee = 100 * (1 - 0.003) = 99.7 LUN (encrypted)
  3. Calculates new reserves: newReserveA = reserveA + 99.7 (encrypted)
  4. Calculates constant product: k = reserveA * reserveB (encrypted)
  5. **Key privacy step:**Creates masked denominator
    randomMask = FHE.randEuint128()
    maskedNumerator = k * randomMask
    maskedDenominator = newReserveA * randomMask
  6. Requests decryption of ONLY maskedDenominator
  7. Stores pending swap

Phase 2: Swap Settlement (Automatic by Oracle)

// Oracle monitors SwapDecryptionRequested events
// Threshold network decrypts maskedDenominator
// Oracle calls settleSwap automatically

// User receives output tokens (encrypted)

What happens:

  1. Oracle decrypts maskedDenominator
  2. Pool calculates: newReserveB = maskedNumerator / decryptedDenominator
    • Mask cancels out: (k × mask) / (newReserveA × mask) = k / newReserveA
  3. Output amount: amountOut = reserveB - newReserveB (encrypted)
  4. Transfer encrypted amountOut to user
  5. Update reserve checkpoints
  6. Swap complete!

Privacy preserved:

  • Input amount: encrypted
  • Output amount: encrypted
  • Reserves: encrypted
  • Only masked values decrypted (oracle can't learn actual amounts)

4. User Participates in Governance

Step 1: Delegate Voting Power

// LUN token has built-in delegation
await lunToken.delegate(userAddress); // Self-delegate

// Or delegate to expert
await lunToken.delegate(expertAddress);

What happens:

  • Delegation is public (who delegates to whom)
  • Vote weight is ENCRYPTED
  • Checkpoints track historical voting power

Step 2: Create Proposal

// Must have ≥ 10,000 LUN voting power
const targets = [pool_LUN_USDC];
const values = [0];
const calldatas = [
pool.interface.encodeFunctionData("setSwapFee", [2500]), // 0.25%
];
const description = "Reduce LUN/USDC swap fee to 0.25%";

const proposalTx = await governor.propose(
targets,
values,
calldatas,
description
);

const proposalId = extractProposalId(proposalTx);

What happens:

  • Governor checks proposer has ≥ 10k LUN (encrypted check)
  • Creates proposal with unique ID
  • Voting delay starts (1 day)

Step 3: Vote on Proposal

// Wait 1 day for voting to start
// Vote with encrypted weight

const voteInput = await fhevm.createEncryptedInput(
governorAddress,
userAddress
);
voteInput.add64(ethers.parseUnits("5000", 6)); // Vote with 5000 LUN
const voteEncrypted = await voteInput.encrypt();

await governor.castVote(
proposalId,
1, // 0=Against, 1=For, 2=Abstain
voteEncrypted.handles[0],
voteEncrypted.inputProof
);

What happens:

  • Vote weight added to encrypted tally
  • forVotes = FHE.add(forVotes, voteWeight) (homomorphic addition)
  • Individual vote weight NEVER revealed
  • Voting continues for 3 days

Step 4: Finalize and Execute

// After voting period ends (3 days)
// Request tally
await governor.requestTally(proposalId);

// Oracle decrypts ONLY:
// - Did quorum reach 50k? (yes/no)
// - Did FOR > AGAINST? (yes/no)

// If passed:
await governor.queue(proposalId);

// Wait 2 days (timelock delay)
await governor.execute(proposalId);

// Swap fee is now changed!

Privacy preserved:

  • Individual vote weights: encrypted
  • Vote tallies during voting: encrypted
  • Only final outcome decrypted (not individual amounts)

Technical Deep Dives

Confidential Constant Product AMM

Traditional formula:

x * y = k

Lunarys encrypted formula:

euint64 reserveA;
euint64 reserveB;
euint128 constantProduct = FHE.mul(reserveA, reserveB);

// All operations on encrypted values!
euint64 newReserveA = FHE.add(reserveA, amountIn);
euint64 newReserveB = FHE.div(constantProduct, newReserveA);
euint64 amountOut = FHE.sub(reserveB, newReserveB);

**Challenge:**Division requires decryption in most FHE systems

**Lunarys Solution:**Masked decryption

// Instead of decrypting newReserveA (reveals pool state)
// Decrypt masked value (reveals nothing useful)

euint128 mask = FHE.randEuint128();
euint128 maskedNumerator = FHE.mul(constantProduct, mask);
euint128 maskedDenominator = FHE.mul(newReserveA, mask);

// Decrypt only maskedDenominator
uint128 decrypted = oracle.decrypt(maskedDenominator);

// Calculate result (mask cancels)
euint64 result = FHE.div(maskedNumerator, decrypted);
// = (k * mask) / (newReserveA * mask)
// = k / newReserveA

Checkpoints for Confidential Governance

**Problem:**How to prevent vote buying?

  • Alice has 1000 LUN at block 100
  • Proposal created at block 100
  • Alice buys 9000 more LUN at block 101
  • Can Alice vote with 10,000 LUN?

**Solution:**Snapshot voting

struct Checkpoint {
uint48 _key; // Block number
euint64 _value; // Encrypted balance at that block
}

// Get voting power at proposal creation
euint64 votingPower = _delegateCheckpoints[voter].upperLookup(proposalSnapshot);

How it works:

  1. Every balance change creates checkpoint
  2. Binary search through checkpoints (O(log n))
  3. Find balance at specific block
  4. All encrypted (no one sees amounts)

Used for:

  • Governance voting (snapshot at proposal creation)
  • Pool reserves (historical liquidity tracking)
  • Delegation (voting power movement)

Hook System Architecture

**Design philosophy:**Pools are minimal, hooks provide extensibility

Without hooks:

Pool → Reserves, Swaps, Liquidity
No LP tokens
No position tracking
No analytics

With hooks:

Pool → Reserves, Swaps, Liquidity

Hooks:
- LiquidityHook → Tracks encrypted LP shares
- SwapHook → Analytics, fee distribution
- GovernanceHook → Pool-specific voting

Example: LP Token Hook

contract ConfidentialLPToken is ILiquidityHook {
mapping(address => euint64) public lpShares;

function afterBootstrap(
address caller,
address lpRecipient,
bytes32 amountAHandle,
bytes32 amountBHandle,
bytes memory hookData,
bytes memory hookContext
) external override {
euint64 amountA = FHE.fromBytes32(amountAHandle);
euint64 amountB = FHE.fromBytes32(amountBHandle);

// Calculate LP shares (encrypted)
euint128 product = FHE.mul(amountA, amountB);
euint64 shares = FHE.sqrt(product);

// Mint encrypted LP tokens
lpShares[lpRecipient] = FHE.add(lpShares[lpRecipient], shares);
}
}

Privacy Guarantees

What Remains Encrypted

Liquidity Pools

  • Reserve amounts - Pool depth completely private
  • LP positions - Individual contributions encrypted
  • Swap amounts - Trade sizes hidden
  • Price impact - Cannot calculate without reserves

Governance

  • Token balances - How much LUN each address has
  • Vote weights - How many tokens used to vote
  • Vote tallies - Vote counts during voting period
  • Treasury balances - Protocol funds encrypted

What Is Public

Liquidity Pools

  • Pool exists (pair address public)
  • Swap occurred (event emitted)
  • Direction (A→B or B→A)
  • Participants (sender/recipient addresses)

Governance

  • Proposals (text, targets, calldatas)
  • Vote direction (For/Against/Abstain)
  • Delegation (who delegates to whom)
  • Final outcome (Passed/Failed, but not vote counts)

Security Model

Threat model:

  • Front-running: Cannot predict price impact
  • Sandwich attacks: Cannot calculate profit
  • JIT liquidity: Cannot see pending trades
  • Vote buying: Cannot verify vote delivery
  • Whale tracking: Cannot see balances

Trust assumptions:

  • fhEVM oracle (threshold network, 7 of 10 validators)
  • Smart contract code (open source, audited)
  • FHE encryption (mathematically proven security)
  • Gas costs (FHE operations 10-100x more expensive)

Deployed Contracts (Sepolia Testnet)

Last updated: October 25, 2025 - Complete fresh deployment with 16/16 contracts verified on Etherscan.

Tokens (ERC7984 Confidential)

  • LUN (Governance Token): 0xac4d3C0f90A6a4B5b8ae16AFd78F1EEcF238eD70
  • eUSD (Encrypted USD): 0xc56929E0aeC02cf7679ac53F2cfD5a85Aa33A1ef
  • ZAMA (Zama Token): 0x7778E67d9fFec15e551Ef8c73B6608083B010305
  • eBTC (Encrypted Bitcoin): 0x538Ff24472171adBd61276CCf2978aB8589A9314

DAO System

  • GovernanceToken: 0x892571fe321d148d613a41B5f49E3F725B05ae7b
  • Governor: 0xa6585aA902083E7e3386690e9d944564AB82a92f
  • Timelock: 0x2D6C594512cEBe7Ca09a63243Fd6599Ed6711F1a
  • Treasury: 0x4080754E9fc917dAdDcdD98F065bFE6A9C7DD04d
  • EmissionsController: 0x2db86E1EfC1a12F49f5773CAccFC6E4841759f0c

Liquidity Infrastructure

  • Factory: 0x325E2fC63CD617C1A09bA41f6fD9bbe5eFc074d8
  • Router: Redeployment pending (address forthcoming)

Active Liquidity Pools (0.3% Fee)

  • LUN/eUSD Pool: 0x975Be3F050026823394D299799A4d1B502716944
  • LUN/eBTC Pool: 0xB5845b18062628F31D1cAEf14dC6f114293403DD
  • eUSD/eBTC Pool: 0x3299e09E744DEc4557F12527b2940ae84A869dc2
  • ZAMA/eUSD Pool: 0xd1956BDd2E45E85e9e717e036e3A41C949b31784
  • ZAMA/LUN Pool: 0x9292A1168d6ea1eA87B6C6C9e131b581f64cacc0

For complete deployment details, verification status, and integration examples, see Deployed Addresses.


Documentation Structure

Getting Started

Core Concepts

Contract References

Integration Guides


Performance Characteristics

Gas Costs

OperationEstimated GasNotes
Swap (initiate)~600,000FHE operations
Swap (settle)~400,000Division, transfers
Bootstrap (initiate)~800,000Two token pulls
Bootstrap (settle)~300,000Checkpoint creation
Contribute (initiate)~700,000Similar to bootstrap
Contribute (settle)~300,000Reserve updates
Vote~400,000Encrypted tally update

Why expensive?

  • FHE operations 10-100x more costly than plaintext
  • Encrypted transfers require proofs
  • Checkpoints add overhead
  • **Trade-off:**Privacy worth the cost

Decryption Latency

NetworkOracle Response Time
Sepolia Testnet30-60 seconds
Mainnet (expected)10-30 seconds

Factors:

  • Threshold network coordination
  • Cryptographic operations
  • Network congestion
  • Oracle implementation

Future Enhancements

Phase 2 (Planned)

  • Concentrated liquidity (Uniswap V3 style)
  • Multi-hop swaps (A → B → C)
  • Limit orders (encrypted)
  • Range orders

Phase 3 (Research)

  • Cross-chain confidential swaps
  • Privacy-preserving oracles
  • Encrypted derivatives
  • Confidential lending

Summary

Lunarys represents a paradigm shift in DeFi:

**Traditional DeFi:**Transparency through public data **Lunarys:**Privacy through encryption

Key Innovations:

  1. First fully confidential AMM with encrypted reserves
  2. Masked decryption for privacy-preserving computation
  3. Encrypted governance with snapshot voting
  4. Hook-based extensibility for LP tracking
  5. Production-ready on Ethereum (via fhEVM)

The result: A decentralized exchange that provides the privacy of a centralized exchange without the centralization.

Welcome to the future of confidential DeFi. 🌙