Skip to content

Contract Analysis

DISCLAIMER // NFA // DYOR

This analysis is based on observations of the contract behavior. We are not smart contract security experts. This document aims to explain what the contract appears to do based on the code. It should not be considered a comprehensive security audit or financial advice. Always verify critical information independently and consult with blockchain security professionals for important decisions.

⊙ generated by robots | curated by humans

Analysis Date: 2026-02-28


Metadata

Primary Contract

PROPERTY VALUE
Contract Address 0x000000000000FB114709235f1ccBFfb925F600e4 (etherscan)
Network Ethereum Mainnet
Contract Type Standalone
Deployment Date 2026-02-12 12:52:47 UTC
Deployment Block 24,440,819
Contract Creator 0x1C0Aa8cCD568d90d61659F060D1bFb1e6f855A20 (etherscan)
Creation TX 0xb940d4ba...593d6b (tx)
Compiler Version Solidity v0.8.33+commit.64118f21
Total Functions 29 (+ 2 special: fallback, receive)
External Contract Dependencies 10+ (Uniswap V2/V3/V4, zAMM, SushiSwap, Curve, Lido, Permit2, NameNFT)
Upgrade Mechanism ☒ None — Not Upgradable
Verification Status ☑ Verified — Exact Match
Audit Status △ No public audit found
TYPE ADDRESS NOTES
Owner 0x1C0Aa8cCD568d90d61659F060D1bFb1e6f855A20 (etherscan) Set via tx.origin at deployment; current _owner
SafeExecutor 0x25Fc36455aa30D012bbFB86f283975440D7Ee8Db (etherscan) Companion contract deployed in constructor
Uniswap V2 Factory 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f (etherscan) Hardcoded constant
SushiSwap Factory 0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac (etherscan) Hardcoded constant
Uniswap V3 Factory 0x1F98431c8aD98523631AE4a59f267346ea31F984 (etherscan) Hardcoded constant
Uniswap V4 PoolManager 0x000000000004444c5dc75cB358380D2e3dE08A90 (etherscan) Hardcoded constant
zAMM (hooked) 0x000000000000040470635EB91b7CE4D132D616eD (etherscan) zFi's custom AMM
zAMM (hookless) 0x00000000000008882D72EfA6cCE4B6a40b24C860 (etherscan) zFi's hookless AMM variant
Lido stETH 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84 (etherscan) Hardcoded constant
Lido wstETH 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 (etherscan) Hardcoded constant
WETH 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 (etherscan) Hardcoded constant
Permit2 0x000000000022D473030F116dDEE9F6B43aC78BA3 (etherscan) Uniswap permit contract
DAI 0x6B175474E89094C44Da98b954EedeAC495271d0F (etherscan) Hardcoded constant for DAI permit
.wei NameNFT 0x0000000000696760E15f265e828DB644A0c242EB (etherscan) zFi name registry NFT contract

Executive Summary

zRouter is a fully on-chain DEX aggregator deployed by zOrg DAO as part of the zFi superdapp. It aggregates liquidity from Uniswap V2, Uniswap V3, Uniswap V4, SushiSwap, Curve, and zFi's own zAMM — all within a single standalone contract with no off-chain dependencies.

The contract supports exact-in and exact-out swaps across all integrated protocols, batch/chained swaps via multicall, a generic executor path (snwap/snwapMulti) for arbitrary integration, Lido staking helpers, and a .wei name registration function. It also ships with a companion SafeExecutor contract deployed at construction that holds no token approvals — isolating arbitrary external call risk.

Architecturally, the contract makes heavy use of EIP-1153 Transient Storage for intra-transaction balance tracking that enables multi-hop composability without persistent state risk. Pool addresses are computed deterministically on-chain for V2/V3 using CREATE2 math, eliminating off-chain route solving entirely.

The primary trust assumption is the _owner role: the owner can whitelist arbitrary addresses via trust() for the execute() function, set token approvals via ensureAllowance(), sweep any tokens held by the contract, and transfer ownership. The contract was deployed by tx.origin rather than msg.sender, which is notable in a factory deployment context.

There is no proxy mechanism, no timelock, and no multisig. All logic is immutable after deployment.


Architecture

graph TD
    User([User])

    zR["zRouter\n0x000000...F600e4"]

    subgraph Swaps["DEX Integrations"]
        V2["Uniswap V2 / SushiSwap"]
        V3["Uniswap V3"]
        V4["Uniswap V4"]
        ZA["zAMM"]
        CV["Curve Finance"]
    end

    subgraph Other["Other Integrations"]
        LI["Lido (stETH / wstETH)"]
        SE["SafeExecutor\n(generic)"]
        NM["NameNFT (.wei)"]
    end

    User -->|"swap / multicall\ndeposit / permit"| zR
    zR --> V2
    zR --> V3
    zR --> V4
    zR --> ZA
    zR --> CV
    zR --> LI
    zR --> SE
    zR --> NM

    style zR fill:#e0f0ff
    style SE fill:#f0f0ff

System Overview

zRouter operates as a stateless routing hub. It holds no meaningful persistent state beyond an owner address and a trusted-callers mapping — all in-flight balances are tracked via transient storage which automatically resets at the end of each transaction.

  • Computes V2/V3 pool addresses deterministically on-chain via CREATE2 hash — no off-chain route API required
  • Multi-hop swaps via multicall with transient balance passing between calls
  • Five distinct swap paths: V2 (Uni + Sushi), V3, V4, zAMM, Curve (up to 5 hops, 8 swap types)
  • Generic executor (snwap) for integration with any DEX via arbitrary calldata
  • Four Lido functions for ETH → stETH / wstETH conversion with exact-out support
  • .wei name commit-reveal via revealName, chainable with swaps

Notably, the sweep() function is callable by anyone with no access control restriction. This is intentional by design for a routing contract (funds should not remain after a transaction), but requires careful understanding.

Design Patterns Used

  • Transient Storage: All inter-call balance tracking uses tstore/tload via depositFor() and _useTransientBalance(). Balances reset each transaction, removing persistent fund risk from routing operations.
  • Delegatecall Multicall: multicall() uses delegatecall to itself, enabling atomic multi-step swap chains within a single transaction.
  • CREATE2 Pool Derivation: V2 and V3 pool addresses computed deterministically from factory address, token pair, and fee — no registry lookups required.
  • Callback Pattern: V3 swap() triggers uniswapV3SwapCallback via the fallback() function; V4 unlock() triggers unlockCallback(). Both verify msg.sender against expected pool addresses.
  • SafeExecutor Isolation: Arbitrary external calls for snwap/snwapMulti are routed through a companion SafeExecutor contract that holds zero token approvals, limiting exposure.
  • Inline Assembly (Solady-style): Token transfers, approvals, balance reads, and ETH sends use hand-optimized assembly from the Solady pattern library for gas efficiency.
  • Ownable (custom): Minimal ownership pattern with _owner stored in slot 0, onlyOwner modifier, and standard transferOwnership / event.

Access Control

Roles & Permissions

ROLE ASSIGNED BY REVOKABLE CALL COUNT
Owner (_owner) Constructor via tx.origin ☑ Yes — transferOwnership() Unlimited
Trusted Caller (_isTrustedForCall) Owner via trust() ☑ Yes — trust(target, false) Unlimited
User — (any address) Unlimited

Permission Matrix

FUNCTION OWNER TRUSTED USER / ANYONE
swapV2()
swapV3()
swapV4()
swapVZ()
swapCurve()
snwap()
snwapMulti()
multicall()
deposit()
sweep()
wrap() / unwrap()
permit() / permitDAI()
permit2TransferFrom()
permit2BatchTransferFrom()
exactETHToSTETH()
exactETHToWSTETH()
ethToExactSTETH()
ethToExactWSTETH()
addLiquidity()
revealName()
unlockCallback() ☑ (V4 PM only)
onERC721Received()
trust()
transferOwnership()
ensureAllowance()
execute()

Time Locks & Delays

ACTION TIME LOCK CAN CANCEL PURPOSE
Transfer Ownership None N/A △ Immediate, no protection
Add Trusted Caller None N/A △ Immediate, no protection
Set Token Allowance None N/A △ Immediate, no protection
Swap Deadline ☑ Yes — per-call deadline param ☒ No △ Slippage protection only

Economic Model

Swap Flow

flowchart TD
    A([User calls swapV2/V3/V4/VZ/Curve]) --> B{ETH or Token In?}
    B -->|ETH| C[Check transient balance\nor wrap ETH to WETH]
    B -->|Token| D[Check transient balance\nor pull via transferFrom]
    C --> E[Execute swap on target DEX]
    D --> E
    E --> F{ETH or Token Out?}
    F -->|ETH| G[unwrapWETH → send ETH to `to`]
    F -->|Token| H[transfer token to `to`\nor depositFor chaining]
    H --> I([Done])
    G --> I

Fee Structure

FEE TYPE AMOUNT RECIPIENT PURPOSE
Protocol fee 0% ◇ Zero protocol fees by design
DEX fee (V2) 0.3% (Uni) / 0.3% (Sushi) LP providers Charged by underlying pool
DEX fee (V3) Variable (per pool: 0.01%–1%) LP providers Charged by underlying pool
DEX fee (V4) Variable (per pool) LP providers Charged by underlying pool
DEX fee (zAMM) Variable (feeOrHook param) LP providers Charged by underlying pool
Curve fee Variable (per pool) LP providers Charged by underlying pool
Lido staking fee ~10% of staking rewards Lido protocol Applied to staking yield, not principal

Funding Sources & Sinks

The contract does not accumulate fees or hold funds between transactions under normal operation. Any ETH or tokens that arrive at the contract mid-transaction are tracked via transient storage and consumed or refunded within the same transaction. Residual balances can be swept via sweep() by anyone.


Summary of Observations

zRouter appears to be a well-engineered, gas-optimized DEX aggregator. The contract covers an unusually broad integration surface: five distinct AMM protocols (Uniswap V2, V3, V4, SushiSwap, Curve), zFi's own zAMM, Lido staking, Uniswap Permit2, and even .wei name registration — all in a single 1,659-line file with no external library imports.

The use of EIP-1153 transient storage for intra-transaction balance tracking is notable — it enables multicall-based chaining of swaps across different DEX protocols without requiring the contract to persist token balances between calls. This is a sophisticated and relatively modern pattern.

The sweep() function carries no access control. This is a deliberate design choice for a router (leftover funds after a transaction should be recoverable), but it warrants understanding — any address can extract tokens or ETH left in the contract. In practice, transient storage ensures funds don't persist between transactions in normal operation.

The owner role has meaningful power: it can whitelist arbitrary targets for execute(), set unlimited token approvals on any token via ensureAllowance(), and transfer ownership. There is no multisig and no timelock protecting these actions. The current owner is 0x1C0Aa8cC...55A20, which appears to be the deployer EOA.

The execute() function is restricted to trusted callers and sets a transient lock (tstore(0x00, 1)) that blocks V3 and V4 swap callbacks from executing during the call — preventing reentrancy through those paths. The companion SafeExecutor for snwap has no token approvals and isolates arbitrary call risk.

One typographical quirk: the generic executor is named snwap — an apparent deliberate misspelling of "swap." The comment references a prior art contract at 0xAC4c6e...80b75.

This analysis is for educational purposes only and should not be considered a security audit or financial advice. The contract integrates with many external protocols; any vulnerability in those dependencies could affect users of zRouter.


References

RESOURCE NOTES
Etherscan — zRouter Contract Verified source code (Exact Match)
GitHub — z-fi/zRouter Original source repository
Etherscan — Creation TX Deployment transaction
Uniswap V4 Docs V4 unlock/callback architecture reference
EIP-1153: Transient Storage Transient storage opcodes used extensively in this contract
Solady Library Assembly-optimized token transfer helpers used throughout
Lido Docs stETH/wstETH staking mechanics reference
Permit2 by Uniswap Permit2 signature transfer interface

Change Log

DATE AUTHOR NOTES
2026-02-28 Artificial. Generated by robots. Gas: 95 tok
2026-02-28 Denizen. Reviewed, edited, and curated by humans.