Storage Layout
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
| METADATA | |
|---|---|
| Contract Address | 0x000000000000FB114709235f1ccBFfb925F600e4 (etherscan) |
| Network | Ethereum Mainnet |
| Analysis Date | 2026-02-28 |
Variables
| SLOT | VARIABLE NAME | TYPE | CURRENT VALUE | PURPOSE |
|---|---|---|---|---|
| 0 | _owner |
address |
0x1C0Aa8cCD568d90d61659F060D1bFb1e6f855A20 |
Contract owner — controls trust(), ensureAllowance(), transferOwnership() |
| 1 | _isTrustedForCall |
mapping(address => bool) |
(hash-based, query per address) | Whitelist of addresses permitted to call execute() |
| — | safeExecutor |
address (immutable) |
0x25Fc36455aa30D012bbFB86f283975440D7Ee8Db |
Stored in contract bytecode, not a storage slot |
Transient Storage (EIP-1153)
zRouter makes extensive use of Transient Storage (tstore/tload), which resets automatically at the end of each transaction. Transient slots are not permanent storage and are not listed above, but are structurally significant:
| TRANSIENT KEY | LAYOUT | PURPOSE |
|---|---|---|
keccak256(user, token, id) |
(address, address, uint256) → uint256 |
Per-user per-token pending balance for intra-transaction chaining via depositFor() / _useTransientBalance() |
tslot(0x00) |
uint256 (0 or 1) |
Reentrancy lock for V3 fallback callback and V4 unlockCallback(); set to 1 during execute() |
Constants (File-Level)
These are compile-time constants embedded in bytecode — not storage slots.
| NAME | TYPE | VALUE | PURPOSE |
|---|---|---|---|
WETH |
address |
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
Wrapped ETH |
STETH |
address |
0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84 |
Lido staked ETH |
WSTETH |
address |
0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 |
Lido wrapped staked ETH |
V2_FACTORY |
address |
0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f |
Uniswap V2 factory |
V2_POOL_INIT_CODE_HASH |
bytes32 |
0x96e8ac42...48845f |
Uniswap V2 pool init code hash for CREATE2 derivation |
SUSHI_FACTORY |
address |
0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac |
SushiSwap factory |
SUSHI_POOL_INIT_CODE_HASH |
bytes32 |
0xe18a34eb...19b3 |
SushiSwap pool init code hash |
V3_FACTORY |
address |
0x1F98431c8aD98523631AE4a59f267346ea31F984 |
Uniswap V3 factory |
V3_POOL_INIT_CODE_HASH |
bytes32 |
0xe34f199b...b54 |
Uniswap V3 pool init code hash |
V4_POOL_MANAGER |
address |
0x000000000004444c5dc75cB358380D2e3dE08A90 |
Uniswap V4 PoolManager |
ZAMM |
address |
0x000000000000040470635EB91b7CE4D132D616eD |
zAMM (hook-enabled) |
ZAMM_0 |
address |
0x00000000000008882D72EfA6cCE4B6a40b24C860 |
zAMM (hookless) |
CURVE_ETH |
address |
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE |
Curve ETH sentinel address |
DAI |
address |
0x6B175474E89094C44Da98b954EedeAC495271d0F |
DAI stablecoin (permit only) |
PERMIT2 |
address |
0x000000000022D473030F116dDEE9F6B43aC78BA3 |
Uniswap Permit2 contract |
NAME_NFT |
address |
0x0000000000696760E15f265e828DB644A0c242EB |
.wei name registry NFT |
MIN_SQRT_RATIO_PLUS_ONE |
uint160 |
4295128740 |
V3/V4 minimum sqrt price ratio + 1 |
MAX_SQRT_RATIO_MINUS_ONE |
uint160 |
1461446703...341 |
V3/V4 maximum sqrt price ratio - 1 |
Diagrams
graph TB
subgraph Persistent["Persistent Storage"]
S0["Slot 0: _owner\n0x1C0Aa8cC...55A20"]
S1["Slot 1: _isTrustedForCall\nmapping(address => bool)"]
end
subgraph Immutable["Immutable (Bytecode)"]
I0["safeExecutor\n0x25Fc36...e8Db"]
end
subgraph Transient["Transient Storage (EIP-1153 — resets per tx)"]
T0["tslot(0x00)\nReentrancy lock (0 or 1)"]
T1["keccak256(user, token, id)\nPending balance per user/token/id"]
end
subgraph Constants["Compile-time Constants (Bytecode)"]
C0["WETH, STETH, WSTETH"]
C1["V2/V3/V4/SUSHI Factories + Init Code Hashes"]
C2["ZAMM, ZAMM_0, CURVE_ETH"]
C3["DAI, PERMIT2, NAME_NFT"]
C4["MIN/MAX_SQRT_RATIO"]
end
Persistent --> Transient
style S0 fill:#ffe1e1
style S1 fill:#fff3cc
style T0 fill:#e1f0ff
style T1 fill:#e1f0ff
style I0 fill:#f0f0f0
Minimal Persistent State
zRouter maintains only two persistent storage slots. All fund routing state is transient — it resets at the end of every transaction. This is by design: a router contract has no reason to hold balances between calls.