Replies: 1 comment
-
|
LunarSwap E2E workflow TODO checklist. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
System Design Document: LunarSwap-v1 🌑 A Permissioned Private DEX on Midnight Network.
Designing a decentralized exchange (DEX) dApp on the Midnight blockchain involves leveraging its privacy-focused features (Zswap for private transactions and Kachina-inspired smart contracts via Compact), integrating with the Midnight Lace wallet, and ensuring a user-friendly experience.
Below is a detailed system design covering architecture, components, data flow, implementation considerations, and development roadmap for LunarSwap (Permissioned Private DEX) dApp.
1. Overview
LunarSwap is a permissioned, private decentralized exchange (DEX) dApp on the Midnight blockchain network, designed as a starter example to showcase complex interactions between tokens, roles, and privacy. Unlike permissionless (fully-open) DEX, LunarSwap restricts access to a predefined group of users who agree off-chain to form a private AMM pool. This group designates an Admin (who manages permissions), Liquidity Providers (LPs) (who supply tokens), and Traders (who swap tokens), ensuring that only permitted accounts can interact with the pool. All pool details—tokens, liquidity, constant$k$ , and swaps—are private, visible only to authorized users via shielded transactions and client-side utilites. This approach offers value through enhanced privacy (hiding balances, swaps, and reserves) and anti-MEV (Miner Extractable Value) protection by keeping intents and pool state confidential, making it ideal for exclusive, trust-based trading groups. The design leverages Midnight’s Zswap protocol for shielded swaps and Compact for zero-knowledge smart contracts, integrating with the Midnight Lace Wallet for a user-friendly experience.
2. Architecture
Chosen Solution for Shared Private State (SPS): For managing the shared private state (e.g.,
PoolStatereserves and LP tokens) among authorized users, the design adopts a Centralized Encryptor/Decryptor approach. This off-chain service encrypts and decryptsPoolStateusing a private key, with role-based access enforced via signed requests, and the smart contract verifies updates againstpoolCommits. For a detailed exploration of this and alternative solutions, refer to the Challenges and Limitations section.2.1 Front-end (UI Layer)
2.2 Client-Side Utilities (Off-chain Logic)
2.3 On-Chain Logic (Smart Contracts)
2.4 Midnight Blockchain
2.5 Midnight Lace Wallet
2.6 Centralized Encryptor/Decryptor
PoolStateusing a private key, accessible only to authorized users via signed requests.2.7 Architecture Diagram
3. Detailed Component Design
3.1 Front-end
3.2 Client-Side Utilities (Off-chain Service)
swapTxBuilder: Constructs swap txs for Traders.liquidityManager: Manages liquidity txs for LPs.addRoleTxBuilder/removeRoleTxBuilder: Handles role updates for Admins.checkExchangeRate: Queries exchange rates privately for permitted users.statusPoller: Tracks tx status via ledger reads.3.3 On-chain Logic (Compact contracts)
3.3.1 Public and Private Data
Public Data
Public data is stored on the Midnight blockchain ledger and visible to anyone inspecting the chain:
roleCommits: MerkleTree<10, Bytes<32>>balanceCommits: MerkleTree<10, Bytes<32>>poolCommits: MerkleTree<10, Bytes<32>>lpTokenCommits: MerkleTree<10, Bytes<32>>pot: QualifiedCoinInfopotHasCoin: BooleandexState: Enum { active, inactvie }(optional, if state tracking added):Private Data
Private data is managed off-chain via witnesses or shielded by Zswap, accessible only to authorized parties (e.g., client-side) and proven via ZK-SNARKs:
witness getBalance(),witness updateBalance()) and shielded UTXOs in Zswap.balanceCommitsMerkle tree, proven via ZK circuits.TokenAandTokenBin each liquidity pool (withinPoolState).witness getPoolState(),witness updatePoolState()).poolCommitsMerkle tree, verified via ZK-SNARKs.witness getLpBalance(),witness updateLpBalance()).lpTokenCommitsMerkle tree, ensuring LP holdings remain private.admin,lp,trader) assigned to eachUserID.witness getRole(),witness updateRole()) and shielded via Zswap key derivation.roleCommitsMerkle tree, proven via zero-knowledge circuits.MerkleTreePath<10, Bytes<32>>).witness getBalancePath(),witness getPoolPath()).witness orderCommits()Merkle tree.Circuits
3.3.2 Liquidity Pool Circuit
MerkleTree<10, Bytes<32>>for pool state commitments;Map<TokenPair, Cell<Uint<64>>>for public LP token supply.addLiquidity(tokenA: TokenID, tokenB: TokenID, amountA: Uint<64>, amountB: Uint<64>, coin: CoinInfo)updates private pool state and commits to the Merkle tree, minting LP tokens viamint_token(),removeLiquidity(tokenA: TokenID, tokenB: TokenID, lpAmount: Uint<64>, coin: CoinInfo): []removes liquidity from a token pair pool, burning LP tokens and returning assets.3.3.3 Swap Circuit
MerkleTree<10, Bytes<32>>for balance commitments;QualifiedCoinInfofor transient NIGHT fees.swap(from: TokenID, to: TokenID, amount: Uint<64>, coin: CoinInfo)proves validity via ZK-SNARKs, updating private balances and Merkle tree commitments.3.3.4 Roles Circuit
admin,lp,trader) privately.MerkleTree<10, Bytes<32>>for role commitments.addRole(target: UserID, role: Role)updates private role state via witness and commits the hashed role to the Merkle tree.hasRole(role: Role): Boolproves the caller’s role matches the requested role via ZK proof, checking against the Merkle tree.3.3.5 Order Book (Stretch) Circuit
MerkleTree<10, Bytes<32>>for order commitments.commitOrder(type: OrderType, token: TokenID, amount: Uint<64>, price: Uint<64>)adds order commitments to the tree for off-chain matching.Key Compact Code Example (Abstract):
3.4 Midnight Blockchain Integration
swapcircuit for private token transfers.MerkleTreeroots for state verification.balanceCommitsandpoolCommitsroots,lpTokenSupply); private state (balances, pool reserves) managed via witnesses.3.5 Midnight Lace Wallet
4. Data Flow
4.1 Swap
PoolStatevia Centralized Encryptor/Decryptor.checkExchangeRatecircuit to display private exchange rate ratio, with sending decryptedpoolStateas a witness to the contract.swapcircuit, retrieves decryptedPoolStatewithgetDecryptedPoolState, computes new state, encrypts withencryptPoolState, updatespoolCommitsandbalanceCommitsMerkle trees.statusPollerutility queries blockchain for transaction status (e.g., Merkle root update), updates UI (e.g., “Confirmed”).4.2 Liquidity Provision
liquidityManagerutility with token pair and amounts.addLiquiditytransaction with DUST fee, signs via Midnight Lace Wallet, submits to Midnight.addLiquiditycircuit, retrieves decryptedPoolStatewithgetDecryptedPoolState, computes new state (e.g., updates reserves, mints LP tokens), encrypts withencryptPoolState, updatespoolCommits,lpTokenCommits, andlpTokenSupply.4.3 Transaction Status
statusPollerutility subscribes to blockchain events or polls MerkleTree roots.4.4 Role Management
addRoleTxBuilderorremoveRoleTxBuilder, submits tx.addRole/removeRoleupdates private roles androleCommits.4.5 Stretch: Orders
orderManagerutility, which constructs a transaction forcommitOrdercircuit; order commitment stored inorderCommitsMerkle tree.4.6 Sequence Diagrams
5. Implementation Considerations
5.1 Privacy
MerkleTreecommitments ensure balances and pool reserves remain private, exposing only roots.5.2 Scalability
MerkleTreeinsertions andlpTokenSupplyupdates to reduce NIGHT fee costs.5.3 Security
5.4 Stretch Goals
orderCommitsMerkle tree and off-chain matching logic; settle via Zswap.6. Challenges and Limitations
6.1 Handling Shared Private State (SPS) Challenge
The permissioned private DEX requires efficient sharing and synchronization of the shared private state (e.g.,
PoolStatecontaining reserves and LP tokens) among authorized users (e.g., LPs, traders) in a decentralized manner, ensuring privacy and consistency without relying on a central server (as possible). Midnight’s current design, with a public ledger and ZK proofs suited for Personal Private State (PPS), lacks native support for dynamic SPS. This section explores the problem and evaluates possible solutions.Problem Statement
PoolStateprivately and consistently, verified against on-chainpoolCommits.Possible Solutions
PoolState, and broadcast updates to authorized peers, who verify againstpoolCommits.PoolStatefragments are stored in a DHT (e.g., IPFS), accessible to role-holding users, with updates verified via on-chain proofs.PoolStateupdates, encrypts results, and shares via P2P. Thets-mpc-framework(early-stage TS library) could assist.PoolStateis encrypted on-chain with FHE, allowing authorized users to compute updates (e.g., swaps), with validators handling operations and broadcasting results.PoolState, accessible to authorized users via signed requests, with locking to prevent collisions.PoolStatewith a private key, accessible via signed requests, with locking and on-chain signature verification.Recommendation
7. Development Roadmap
Sprint 1 - Requirements gathering, design, and environment setup.
Time.
DEADLINE: <2025-03-10 Mon> SCHEDULED: <2025-02-24 Mon>
Sprint 2 - Smart-contract dev, React Scaffolding, initial integration.
Time
DEADLINE: <2025-03-24 Mon> SCHEDULED: <2025-03-11 Tue>
Sprint 3 - Continue contract dev, UI components, integration
Time
DEADLINE: <2025-04-07 Mon> SCHEDULED: <2025-03-25 Tue>
Sprint 4 - Finalize contracts, front-end polish, user testing.
Time
DEADLINE: <2025-04-21 Mon> SCHEDULED: <2025-04-08 Tue>
Sprint 5 - Final testing, bug fixes, deployment.
Time
DEADLINE: <2025-04-30 Wed> SCHEDULED: <2025-04-22 Tue>
8. Risks & Mitigations
9. Sequence Diagrams
9.1 Add-Liquidity Process
Toggle Diagram
9.2 Remove-Liquidity Process
Toggle Diagram
9.3 Swap Process
Toggle Diagram
Beta Was this translation helpful? Give feedback.
All reactions