Q2 2026 Security & Compliance Report67 incidents, $764M in losses, 88% from operational failures.
Get the report →

Audit name:

[SCA] Zendex | Contracts | Apr2026

Date:

May 17, 2026

Table of Content

Introduction
Audit Summary
System Overview
Potential Risks
Findings
Appendix 1. Definitions
Appendix 2. Scope
Appendix 3. Additional Valuables
Disclaimer

Want a comprehensive audit report like this?

Introduction

We express our gratitude to the Zendex team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.

Zendex is a privacy-preserving ZK-AMM, combining zero-knowledge asset management, private swaps, liquidity provisioning, and staking-based fee incentives into a unified DEX protocol.

Document

NameSmart Contract Code Review and Security Analysis Report for Zendex
Audited ByOlesia Bilenka, Georgi Krastenov
Approved ByIvan Bondar
Websitehttps://www.zendex.fi/
Changelog01/05/2026 - Preliminary Report
30/06/2026 - Retest Report
16/07/2026 - Second retest Report
PlatformBase
LanguageSolidity
TagsAutomated Market Maker; Order Book DEX; Staking; Fungible Token; Permit Token; Signatures; DEX; Vault; Liquidity Pool; Centralization
Methodologyhttps://docs.hacken.io/methodologies/smart-contracts
  • Document

    Name
    Smart Contract Code Review and Security Analysis Report for Zendex
    Audited By
    Olesia Bilenka, Georgi Krastenov
    Approved By
    Ivan Bondar
    Changelog
    01/05/2026 - Preliminary Report
    30/06/2026 - Retest Report
    16/07/2026 - Second retest Report
    Platform
    Base
    Language
    Solidity
    Tags
    Automated Market Maker; Order Book DEX; Staking; Fungible Token; Permit Token; Signatures; DEX; Vault; Liquidity Pool; Centralization

Review Scope

Repositoryhttps://github.com/lumos-codes-dev/zendex-sc-zk-amm/tree/v0.9.1/contracts
Commit683e89b
Retest commitfb655e9
Second retest commit0c53c21

Audit Summary

57Total Findings
24Resolved
26Accepted
7Mitigated

The system users should acknowledge all the risks summed up in the risks section of the report

Documentation quality

  • Functional requirements are partially documented.

  • The repository includes a README, deployment-related materials, and setup instructions, but the technical specification is incomplete. Detailed descriptions of the ZK circuits, trust model, role permissions, verifier assumptions, asset flow, upgrade process, and failure scenarios are missing or insufficient.

  • The documentation does not fully describe privacy guarantees, limitations, or expected off-chain backend responsibilities.

Code quality

  • The development environment is configured with Hardhat, TypeScript tests, Solidity coverage tooling, and deployment scripts.

  • The codebase is modular and separates AMM, vault, staking, rewards, verifier, and tree-management logic.

  • However, several components duplicate known implementations, including Uniswap V2-style AMM logic and custom ERC20 behavior, instead of relying directly on battle-tested libraries. T

Test coverage

Code coverage of the project is 43.27% (branch coverage).

  • The project includes tests for core flows such as staking, boost calculation, Merkle tree operations, vault deposits/withdrawals/split/join, AMM liquidity and swaps, and limit order creation.

  • Basic positive and some negative cases are covered. However, tests do not thoroughly cover complex multi-user interactions, adversarial execution ordering, backend failure modes, role abuse scenarios, and full integration flows across all protocol components.

System Overview

Zendex is a privacy-preserving ZK-AMM and DEX protocol with the following contracts:

  • BaseManager.sol — Abstract upgradeable contract providing shared functionality for all manager contracts, including proof verification via ZendexVerifierHub, nullifier validation, Merkle root validation, and commitment insertion through TreeOperator.

  • BoostManager.sol — Upgradeable contract that calculates fee boost percentages for users based on their staking positions; the boost formula uses linear interpolation between lock amount and duration to yield 5-25% boost in basis points.

  • RewardsEngine.sol — Upgradeable contract managing fee collection from the router, tracking per-user cashback and burn balances across multiple tokens, applying staking boosts at claim time, and auto-converting accumulated fees to native ZEN via swap through the router.

  • TreeOperator.sol — Non-upgradeable incremental Merkle tree implementation using Poseidon hashing (PoseidonT3 library) for commitment storage; manages historical roots by epoch, nullifier tracking, liquidity position tracking, and order book metadata for limit orders.

  • WZEN.sol — Standard ERC-20 wrapped native coin contract enabling deposit of native ZEN and minting of WZEN tokens, with withdrawal functionality to unwrap and receive native ZEN.

  • ZendexAmmManager.sol — Upgradeable manager contract for private AMM operations (addLiquidity, removeLiquidity, swap) that verifies inclusion and action proofs, consumes nullifiers, inserts new commitments (liquidity or swap), and executes trades through ZendexRouter.

  • ZendexERC20.sol — Custom ERC-20 implementation serving as the base for LP tokens, featuring EIP-2612 permit functionality with domain separator and typed data hashing for gasless approvals.

  • ZendexFactory.sol — Upgradeable factory contract for creating and registering ZendexPair liquidity pool contracts using CREATE2 deployment with deterministic addresses derived from sorted token pairs.

  • ZendexOrderBookManager.sol — Upgradeable manager contract for privacy-preserving limit orders; handles order creation with ZK proof verification (createOrder), operator-triggered batch execution (executeOrders), cancellation requests (requestCancelOrder), and final cancellation settlement (cancelLimitOrder).

  • ZendexPair.sol — Non-upgradeable Uniswap V2-style constant product AMM pair contract implementing mint, burn, and swap functions with 0.18% LP fee; inherits from ZendexERC20 to serve as its own LP token with permit support.

  • ZendexRouter.sol — Upgradeable router contract providing high-level functions for liquidity addition/removal and token swaps (exact input and exact output variants), handling fee extraction and distribution to RewardsEngine, and supporting both standard and fee-on-transfer tokens.

  • ZendexStaking.sol — Upgradeable staking contract where users lock tokens for 1-24 periods (minimum 1,000 tokens) to earn fee boosts; enforces that existing stakes can only have their duration extended, not decreased.

  • ZendexVault.sol — Non-upgradeable custody contract holding all deposited user assets (WZEN, USDT, USDC, DAI); exposes release and approve functions restricted to authorized manager roles for asset transfers during withdrawals and AMM operations.

  • ZendexVaultManager.sol — Upgradeable manager contract for core vault operations (deposit, withdraw, split, join) that verifies ZK proofs, manages commitment insertions, consumes nullifiers, and coordinates asset transfers with ZendexVault.

  • ZendexVerifierHub.sol — Upgradeable central registry mapping verifier types (deposit, inclusion, withdrawal, split, join, add/remove liquidity, swap, create/cancel order) to their deployed Barretenberg verifier contract addresses; enables verifier upgrades without modifying manager contracts.

  • Math — provides basic math utilities used by AMM contracts, including minimum selection and square-root calculation for liquidity and fee logic.

  • UQ112x112 — provides fixed-point arithmetic helpers used by pair contracts for cumulative price calculations and reserve-based price encoding.

Privileged roles

The protocol uses several privileged roles across upgradeable and administrative contracts. Accounts holding DEFAULT_ADMIN_ROLE can upgrade UUPS contracts, manage verifier addresses, and assign or revoke roles depending on the contract. These permissions allow privileged actors to modify critical protocol logic and dependencies, including proof verification, routing, rewards, staking, and manager behavior.

BoostManagersol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Admin role for DEFAULT_ADMIN_ROLE; can grant and revoke it.

RewardsEngine.sol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Can call withdrawTreasury to withdraw accumulated treasury fees (swapped to native coins) to any recipient.

    • Admin role for DEFAULT_ADMIN_ROLE and ROUTER_ROLE; can grant and revoke them.

  • ROUTER_ROLE: Authorized to deposit trading fees.

    • Can call depositFees to deposit treasury, cashback, and burn fees for users.

TreeOperator.sol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Admin role for DEFAULT_ADMIN_ROLE, VAULT_MANAGER_ROLE, AMM_MANAGER_ROLE, and ORDER_BOOK_MANAGER_ROLE; can grant and revoke them.

  • VAULT_MANAGER_ROLE: Authorized to manage Merkle tree state for vault operations.

    • Can call insert to add commitments to the Merkle tree.

    • Can call consume to mark nullifiers as used.

  • AMM_MANAGER_ROLE: Authorized to manage Merkle tree state and liquidity tracking.

    • Can call insert to add commitments to the Merkle tree.

    • Can call consume to mark nullifiers as used.

    • Can call trackPosition to record liquidity positions with LP amounts.

    • Can call removePosition to delete tracked liquidity positions.

  • ORDER_BOOK_MANAGER_ROLE: Authorized to manage Merkle tree state and order lifecycle.

    • Can call insert to add commitments to the Merkle tree.

    • Can call consume to mark nullifiers as used.

    • Can call openOrder to register new limit orders with execute and cancel commitments.

    • Can call updateOrderStatus to change order status (OPEN, CANCEL_REQUESTED, EXECUTED, CANCELED).

    • Can call setCancellationDeadline to set cancellation deadlines for orders.

WZEN.sol

  • No privileged roles. All functions are permissionless.

ZendexAmmManager.sol

  • DEFAULT_ADMIN_ROLE (inherited from BaseManager): Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Admin role for DEFAULT_ADMIN_ROLE; can grant and revoke it.

ZendexERC20.sol

  • No privileged roles. Standard ERC-20 with permit functionality.

ZendexFactory.sol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Admin role for DEFAULT_ADMIN_ROLE; can grant and revoke it.

  • feeToSetter (address-based access control): Controls fee recipient configuration.

    • Can call setFeeTo to set the address that receives protocol fees from pairs.

    • Can call setFeeToSetter to transfer fee setter privileges to another address.

ZendexOrderBookManager.sol

  • DEFAULT_ADMIN_ROLE (inherited from BaseManager): Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Admin role for DEFAULT_ADMIN_ROLE and ORDER_BOOK_OPERATOR_ROLE; can grant and revoke them.

  • ORDER_BOOK_OPERATOR_ROLE: Authorized to execute and finalize order operations.

    • Can call executeOrders to execute multiple matched limit orders by inserting their execute commitments.

    • Can call cancelLimitOrder to finalize order cancellations by inserting cancel commitments.

ZendexPair.sol

  • factory (address-based access control, single-use): Initializes pair tokens.

    • Can call initialize to set token0 and token1 addresses (callable only once at deployment).

ZendexRouter.sol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Admin role for DEFAULT_ADMIN_ROLE; can grant and revoke it.

ZendexStaking.sol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Admin role for DEFAULT_ADMIN_ROLE; can grant and revoke it.

ZendexVault.sol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Admin role for DEFAULT_ADMIN_ROLE and MANAGER_ROLE; can grant and revoke them.

  • MANAGER_ROLE: Authorized to manage vault assets.

    • Can call release to transfer any token held by the vault to any recipient.

    • Can call approve to grant token spending allowances on behalf of the vault.

ZendexVaultManager.sol

  • DEFAULT_ADMIN_ROLE (inherited from BaseManager): Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Admin role for DEFAULT_ADMIN_ROLE; can grant and revoke it.

ZendexVerifierHub.sol

  • DEFAULT_ADMIN_ROLE: Full administrative control over the contract.

    • Can call _authorizeUpgrade to upgrade the contract implementation.

    • Can call update to change verifier addresses for any verifier type (DEPOSIT, INCLUSION, WITHDRAWAL, SPLIT, JOIN, ADDLIQUIDITY, REMOVELIQUIDITY, SWAP, CREATEORDER, REQUESTCANCEL_ORDER).

    • Admin role for DEFAULT_ADMIN_ROLE; can grant and revoke it.

Potential Risks

Administrative Control Over Protocol Upgrades: The DEFAULT_ADMIN_ROLE holds unilateral authority to upgrade implementations of all UUPS-upgradeable contracts including ZendexAmmManager, ZendexOrderBookManager, ZendexVaultManager, ZendexFactory, ZendexRouter, ZendexStaking, ZendexVerifierHub, RewardsEngine, and BoostManager through their respective _authorizeUpgrade functions. A compromised or malicious admin can replace contract logic without user consent, potentially altering core protocol mechanics or extracting user funds.

Order Book Operator Exclusivity: The ZendexOrderBookManager contract designates an ORDER_BOOK_OPERATOR_ROLE with exclusive authority to call executeOrders and cancelLimitOrder. This centralized operator can selectively execute or delay order execution. While the cancellation deadline mechanism in TreeOperator tracks deadlines via cancellationDeadlines, the contract explicitly states this is view-only and not enforced on-chain. Users relying on limit orders are dependent on this single operator's availability and honesty.

Vault Asset Release Authority: The ZendexVault contract grants MANAGER_ROLE to three addresses (vaultManager, ammManager, tradeManager) at deployment, each able to invoke release to transfer arbitrary token amounts from the vault. If any manager contract or its admin is compromised, assets held in custody can be drained without requiring ZK proof validation at the vault level.

Fee Recipient Configuration: In ZendexFactory, the feeToSetter address can unilaterally change the feeTo address via setFeeTo without timelock or multi-signature requirements. Protocol fees accumulated from liquidity provision events can be redirected to any address at the fee setter's discretion.

Verifier Contract Substitution: The ZendexVerifierHub allows the DEFAULT_ADMIN_ROLE to update any verifier address through the update function. A malicious admin can replace legitimate ZK verifiers with contracts that accept invalid proofs, enabling unauthorized deposits, withdrawals, or trades without valid cryptographic attestation.

Immediate Upgrade Capability Without Timelock: All UUPS-upgradeable contracts including ZendexAmmManager, ZendexOrderBookManager, ZendexVaultManager, ZendexRouter, ZendexFactory, ZendexStaking, ZendexVerifierHub, RewardsEngine, and BoostManager can be upgraded immediately by the admin without a timelock delay. Users have no window to exit the protocol or withdraw funds before potentially harmful upgrades take effect.

Custom Storage Slot Management: The protocol employs custom storage slots (e.g., _BASE_MANAGER_STORAGE_SLOT, _AMM_MANAGER_STORAGE_SLOT, _VAULT_MANAGER_STORAGE_SLOT) computed via keccak256. Incorrect slot management during upgrades can cause storage collisions, leading to corrupted state variables or unintended behavior in upgraded implementations.

Poseidon Hash Function Library: The TreeOperator contract relies on the external PoseidonT3 library from poseidon-solidity for Merkle tree hash computation via _hashPair. Any vulnerability or unexpected behavior in this third-party cryptographic library would compromise the integrity of the commitment scheme and proof verification across all ZK operations.

Non-Standard Token Behavior: The protocol interacts with external ERC-20 tokens including USDT, USDC, and DAI configured in ZendexVault. While SafeERC20 and forceApprove are employed, tokens with fee-on-transfer mechanics, rebasing logic, or blocklist functionality may cause accounting discrepancies in vault balances or swap calculations in ZendexAmmManager and ZendexRouter.

Zero-Knowledge Proof Generation Infrastructure: All deposit, withdrawal, swap, liquidity, and limit order operations in ZendexVaultManager, ZendexAmmManager, and ZendexOrderBookManager require externally generated ZK proofs validated through ZendexVerifierHub. Users cannot interact with the protocol if the off-chain proof generation service is unavailable, censoring, or producing invalid proofs.

Order Book Operator Availability: The ZendexOrderBookManager requires the ORDER_BOOK_OPERATOR_ROLE to invoke executeOrders for order matching and cancelLimitOrder for cancellation finalization. If this off-chain operator becomes unavailable, all pending limit orders remain unexecutable, and users cannot complete order cancellations beyond requesting them via requestCancelOrder.

Merkle Tree State Synchronization: The TreeOperator maintains on-chain Merkle tree state in _levelHashes and historical snapshots in _epochLevelHashes, which must remain synchronized with off-chain commitment data. Users generating inclusion proofs off-chain must accurately reconstruct tree state from LeafInserted events, and any desynchronization prevents valid proof generation.

Public Commitment and Nullifier Registry: All commitments and nullifiers are stored in publicly readable mappings (commitments and nullifierUsed) within TreeOperator. While commitment values do not directly reveal deposit amounts or assets, on-chain observers can analyze commitment creation timing, nullifier consumption patterns, and transaction graph relationships to partially deanonymize user activity.

Visible Liquidity Position Amounts: The TreeOperator stores LP token amounts in the liquidityPositions mapping keyed by liquidity commitment. Observers can link liquidity commitments to specific LP amounts, enabling analysis of liquidity provider behavior and potentially correlating add/remove operations to specific users.

Order Metadata Exposure: The _orderBook mapping in TreeOperator publicly stores OrderMetadata including executeCommitment, cancelCommitment, and status for each spot commitment. Combined with OrderCreated and OrdersExecuted events that emit order parameters, observers can reconstruct order book activity and link orders to execution outcomes.

Findings

Code
Title
Status
Severity
F-2026-1648Deterministic Commitment Construction Enables Full De-Anonymization of All Private Operations
fixed

Critical
F-2026-1620Front-Running in swap and removeLiquidity Functions Leads to Theft of Released Assets
fixed

Critical
F-2026-1619Front-Running in withdraw Function Leads to Theft of Withdrawn Funds
fixed

Critical
F-2026-1657Incomplete Limit Order Implementation Results in Permanent Fund Lock Due to Missing On-Chain Execution and Cancellation Mechanisms
mitigated

Critical
F-2026-1648Broken Fee-On-Transfer Swap Support in swapExactTokensForTokensSupportingFeeOnTransferTokens Causes Transaction Reverts
fixed

High
F-2026-1621Missing Nullifier Validation in removeLiquidity Leads to Incomplete Replay Protection
fixed

High
F-2026-1619Missing Slippage Protection in addLiquidity, removeLiquidity, and swap Leads to Value Extraction Through Price Manipulation
fixed

High
F-2026-1660Unbounded Gas Growth in insert
accepted

High
F-2026-1657Front-Running Vulnerability in createLimitOrder Enables Order Hijacking
mitigated

High
F-2026-1655Broken Optimal-Swap Calculation
fixed

High
1-10 of 57 findings

Identify vulnerabilities in your smart contracts.

Appendix 1. Definitions

Severities

When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.

Reference on how risk scoring is done is available through the repository in our Github organization:

Severity

Description

Critical
Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

High
High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

Medium
Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

Low
Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
  • Severity

    Critical

    Description

    Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

    Severity

    High

    Description

    High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

    Severity

    Medium

    Description

    Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

    Severity

    Low

    Description

    Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.

Potential Risks

The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.

Appendix 2. Scope

The scope of the project includes the following smart contracts from the provided repository:

Scope Details

Repositoryhttps://github.com/lumos-codes-dev/zendex-sc-zk-amm/tree/v0.9.1/contracts
Commit683e89b38bf6308072d9c6e5087509f01155f98a
Retest commitfb655e97a47f1c1f2bb77b76091c492532fc4934
Second retest commit0c53c2175a4941c43f74a8be788b53b92dedc2a5
Whitepaper-
Requirementshttps://github.com/lumos-codes-dev/zendex-sc-zk-amm/tree/v0.9.1/contracts/docs
Technical Requirements-

Assets in Scope

BaseManager.sol - BaseManager.sol
BoostManager.sol - BoostManager.sol
Math.sol - Math.sol
RewardsEngine.sol - RewardsEngine.sol
TreeOperator.sol - TreeOperator.sol
UQ112x112.sol - UQ112x112.sol
WZEN.sol - WZEN.sol
ZendexAmmManager.sol - ZendexAmmManager.sol
ZendexERC20.sol - ZendexERC20.sol
ZendexFactory.sol - ZendexFactory.sol
ZendexPair.sol - ZendexPair.sol
ZendexRouter.sol - ZendexRouter.sol
ZendexStaking.sol - ZendexStaking.sol
ZendexOrderBookManager.sol - ZendexOrderBookManager.sol
ZendexVault.sol - ZendexVault.sol
ZendexVaultManager.sol - ZendexVaultManager.sol
ZendexVerifierHub.sol - ZendexVerifierHub.sol

Appendix 3. Additional Valuables

Additional Recommendations

The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.

To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:

  • Detecting changes to ownership or critical permissions.

  • Monitoring large or unexpected transactions and minting events.

  • Pausing operations when irregularities are identified.

These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.

Frameworks and Methodologies

This security assessment was conducted in alignment with recognised penetration testing standards, methodologies and guidelines, including the NIST SP 800-115 – Technical Guide to Information Security Testing and Assessment , and the Penetration Testing Execution Standard (PTES) , These assets provide a structured foundation for planning, executing, and documenting technical evaluations such as vulnerability assessments, exploitation activities, and security code reviews. Hacken’s internal penetration testing methodology extends these principles to Web2 and Web3 environments to ensure consistency, repeatability, and verifiable outcomes.

Disclaimer