Deployments
Addresses for the active chain and the reference deployment.
Addresses come from contracts/deployments/<chainId>.json, written by Deploy.s.sol and copied to web/src/config/deployment.json by script/sync-deployment.sh <chainId>.
{ "schemaVersion": 3, "chainId": 31337,
"aqua": "0x…", "weth": "0x…", "usdc": "0x…", "feed": "0x…",
"router": "0x…", "routerSourceCommit": "…", "routerBytecodeHash": "0x…",
"seriesFactory": "0x…", "marketEngine": "0x…", "accumulator": "0x…",
"seriesDeployer": "0x…", "programs": "0x…", "lens": "0x…", "oracle": "0x…",
"portfolioMarket": "0x…", "portfolioAccumulator": "0x…",
"deploymentBlock": 51021223, "writer": "0x…", "buyer": "0x…" }
The manifest is versioned. Schema 3 adds portfolioMarket and portfolioAccumulator for the v3 HIGH/CALM risk groups. The backend rejects any schemaVersion it does not understand at startup rather than mis-decoding an older manifest, and it also refuses zero addresses. routerSourceCommit and routerBytecodeHash pin exactly which official AquaSwapVMRouter source this deployment runs — see Running on the official router.
On the public Base Sepolia deployment routerSourceCommit reads unknown: the vendored contracts/lib/swap-vm carries no .git directory, so the upstream commit cannot be recovered. routerBytecodeHash is still pinned and verifiable, and the deployed router's runtime bytecode reproduces the vendored official source byte-for-byte outside its immutable slots.
This build — Base Sepolia (84532), deployed
| Contract | Address |
|---|---|
| Aqua | 0x3B568C149DDf92Bd1f7deF40bDD8930503e70B31 |
| AquaSwapVMRouter | 0xb8dcED3Cf6266Dd8fEc05849fce3734B79A7e722 |
| VarianceSeriesFactory | 0xC86Cf4AD22ABD7169458cCDc58c51e71f23586f2 |
| TremorMarketEngine | 0x44a76D0Df659708a5b8170c0eE1C600C8bc3Eba0 |
| VarianceAccumulator | 0xcdd795440679d4F33bf410879e62B5A4015b4Dc9 |
| TremorSeriesDeployer | 0x1E9117E447e4C2C14B8be4eE59877d66bE8B6893 |
| TremorPrograms | 0x169b52DFa0aFcbCB83A442EfBDBB21cd35209bD0 |
| TremorLens | 0x016CEde278FFB5B2B79E9d7afe11E4d17Bb9B059 |
| RealizedVarianceOracle | 0x7c40518dA5C3dEa9E5F74d12093bbd53d9FC1124 |
| TremorPortfolioMarket | 0x72798A6697Cb648847ec0E5ba0bc6491B2901ddb |
| Portfolio VarianceAccumulator | 0xea5A9Cfb462509f51420E10f5732891481fE634F |
| Quote token | 0x13a058bE25Da579e0858d689F5982eDaCE8356B7 |
| Chainlink ETH/USD | 0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1 |
| WETH | 0x4200000000000000000000000000000000000006 |
| Demo writer | 0x975D862A1f01a292EDf11b12cC809dffaC35997A |
| Demo buyer | 0xbaAe28c72177Bc3814dd0961b9aA09fddB56B752 |
| Deployment block | 46685189 |
| Router source commit | unknown |
| Router bytecode hash | 0x1b037303e1ff4f935eb5548ee6ac1ecdde7626d0a043c10731d7bc1e44a8c8bf |
| Manifest schema | 4 |
Env for this build: NEXT_PUBLIC_RPC_URL=https://sepolia.base.org, NEXT_PUBLIC_API_URL=https://tremor-api.fly.dev.
Chains
| Chain | Id | Aqua | USDC | Chainlink ETH/USD |
|---|---|---|---|---|
| Tremor Fork (anvil fork of Base mainnet) | 31337 | canonical 0x1111113ccf1426a8e30e2bff5e005d929bf6a90a | real 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 (6 dec) | real 0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70 (8 dec) |
| Base Sepolia | 84532 | our own Aqua deployment | MockUSDC — test token, see below | 0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1 |
| Base | 8453 | canonical 0x1111113ccf1426a8e30e2bff5e005d929bf6a90a | real USDC | real ETH/USD |
The Base Sepolia quote token is not USDC. It is Tremor's own MockUSDC at
0x13a058bE25Da579e0858d689F5982eDaCE8356B7— freely mintable by anyone and worth nothing. Its ERC-20symbol()returns the string"USDC", so wallets and explorers will display it as USDC. It has no relationship to Circle's USDC. Every amount shown in the app on chain 84532 is denominated in this test token.
Note the router. Tremor deploys the official AquaSwapVMRouter source, unmodified, rather than using the router deployed at the canonical SwapVM address, because that address exposes a different SwapVM revision's swap ABI. The compatibility gate documents the observation and the fallback.
Reference fork deployment (deployments/31337.json, deploymentBlock 51021223)
A fresh demo.sh run on a fresh fork reproduces the same addresses when deployed from the same account and nonce.
| aqua (canonical) | 0x1111113CCf1426A8E30e2bfF5E005d929bF6a90a |
| weth | 0x4200000000000000000000000000000000000006 |
| usdc (real) | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| feed (real ETH/USD) | 0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70 |
| router (official source) | 0x1B83b466d739cb84B131B21CF66e598C9c01971e |
| seriesFactory | 0x43AfB5635F840c1b0D4D68b10CE9CE272a354523 |
| marketEngine | 0xE37eC1884ce6b498C69B63d6911646006Dd226da |
| accumulator | 0x740af24813F255C2ce72649bE15A2DEcb4eEDC8a |
| seriesDeployer | 0x669D2dfb6Da3F834f46c10f9c91DddD5fE517d85 |
| programs | 0x1BcA8cF5c9c60559c10535851Df022E35513F2B9 |
| lens | 0x19613E7614086c162C75fB53D5911F8FE936E2e5 |
| oracle | 0x856C170B1188e5C36C49cF1EE4073173E41d02b4 |
| writer (anvil #0) | 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 |
| buyer (anvil #1) | 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 |
Writer vaults and receipts are not in the manifest, because they do not need to be: a vault address is CREATE2 from keccak256(writer, quoteToken) and lens.writerVault(writer) returns it whether or not it exists yet.
Build settings and sizes
Solidity 0.8.30, via-IR, optimizer 200 runs — size-tuned, because the controller embeds its children's creation code and therefore has to fit EIP-3860's 49,152-byte initcode limit as well as EIP-170's 24,576-byte runtime limit.
| Contract | Runtime | Initcode | Runtime margin |
|---|---|---|---|
| AquaSwapVMRouter (official) | 20,052 | 21,540 | 4,524 |
| VarianceSeriesFactory | 17,892 | 46,484 | 6,684 |
| TremorLens | 15,184 | 16,364 | 9,392 |
| TremorSeriesDeployer | 11,236 | 11,574 | 13,340 |
| TremorMarketEngine | 8,612 | 8,868 | 15,964 |
| TremorPrograms | 7,607 | 8,057 | 16,969 |
| VarianceAccumulator | 6,858 | 7,163 | 17,718 |
| RealizedVarianceOracle | 5,562 | 5,781 | 19,014 |
| TremorMakerVault | 3,652 | 4,408 | 20,924 |
| VarianceReceipt | 2,981 | 5,218 | 21,595 |
The binding constraint is the controller's initcode: 46,484 of 49,152, a margin of 2,668 bytes. That is why the read models live in separate contracts (TremorLens, TremorPrograms) rather than on the controller itself.