Skip to content

Commit 0bc6f3d

Browse files
authored
Merge pull request #740 from AugurProject/t3code/standalone-live-client
Derive and deploy canonical standalone trading contracts
2 parents fb81456 + 23f3366 commit 0bc6f3d

41 files changed

Lines changed: 996 additions & 581 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

trading/Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ RUN bun install --frozen-lockfile
1515
RUN bun run shared:build
1616
RUN cd trading && bun install --frozen-lockfile
1717

18-
ARG TRADING_UI_DEPLOYMENT
19-
RUN cd trading && if [ -n "${TRADING_UI_DEPLOYMENT}" ]; then TRADING_UI_DEPLOYMENT="${TRADING_UI_DEPLOYMENT}" bun run ui:build; else bun run ui:build; fi
18+
RUN cd trading && bun run ui:build
2019

2120
FROM oven/bun:${BUN_VERSION}-alpine AS runtime
2221

trading/README.md

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ docker network inspect zoltar >/dev/null 2>&1 || docker network create zoltar
2323
docker compose up --build --force-recreate
2424
```
2525

26-
Open `http://localhost:4163/#/markets`. Select a network whose canonical Zoltar core deployment is installed, enter its RPC URL, and connect a wallet. The repository's public-network manifests contain planned deterministic addresses; the UI verifies the required code before it offers a trading deployment transaction.
26+
Open `http://localhost:4163/#/markets`. The client derives the trading factory and router addresses from the canonical Zoltar deployment and checks their code through the default public RPC. If either deterministic contract is missing, the deployment screen is shown automatically. Connect a wallet, then deploy the trading factory and router in order. The **Settings** control beside the wallet lets you override the network or RPC URL without making configuration part of the setup steps. SecurityPools remain browseable without a trading pool; deploy and initialize one from the selected pool when needed. Browser-led deployment uses a fixed 0.30% trading fee. Trading and trading-pool deployment surfaces show the deployed immutable fee as a percentage.
2727

2828
On Windows, run `start.bat` from this directory to start the same Compose command. The final image runs as an unprivileged user and exposes a health check at `/`.
2929

@@ -41,23 +41,9 @@ Open `http://localhost:4163/?demo=1#/markets`. Demo mode is prominently labeled
4141

4242
The Docker image copies the canonical mainnet and Sepolia core deployment addresses from the root documentation manifests. The live UI uses the installed core deployment's deterministic proxy to deploy the two-way factory and router in two wallet transactions. It verifies the RPC chain, core contracts, deterministic addresses, immutable fee, and router-to-factory link before enabling trading.
4343

44-
To use an existing reviewed trading deployment instead, first copy its manifest into `trading/deployments/`. Then set its project-local path at build time:
45-
46-
```bash
47-
cp /absolute/path/to/reviewed.json deployments/reviewed.json
48-
docker network inspect zoltar >/dev/null 2>&1 || docker network create zoltar
49-
TRADING_UI_DEPLOYMENT=deployments/reviewed.json docker compose up --build --force-recreate
50-
```
51-
5244
### Live deployment
5345

54-
Without Docker, `bun run ui:build` includes the same wallet deployment setup. To use an existing reviewed deployment manifest instead:
55-
56-
```bash
57-
TRADING_UI_DEPLOYMENT=/absolute/path/to/trading/deployments/local.json bun run ui:build
58-
```
59-
60-
The live client validates the manifest, discovers canonical SecurityPools in bounded pages, displays their exact pairs, settings, and status, and obtains authoritative simulations before entry, exit, liquidity, settlement, and explicit fork-migration transactions. Fork migration loads the fork question and supports labeled categorical branches or arbitrary scalar ticks, including multi-branch migration for each INVALID, YES, or NO source balance. Each simulation is pinned to a canonical block hash; the client rejects a quote when either its block number or hash changes, including a same-height block replacement, and re-simulates immediately before wallet submission.
46+
Without Docker, `bun run ui:build` includes the same deterministic wallet deployment setup. The live client derives and verifies the canonical trading contracts, discovers SecurityPools in bounded pages, displays their exact pairs, settings, and status, and obtains authoritative simulations before entry, exit, liquidity, settlement, and explicit fork-migration transactions. Fork migration loads the fork question and supports labeled categorical branches or arbitrary scalar ticks, including multi-branch migration for each INVALID, YES, or NO source balance. Each simulation is pinned to a canonical block hash; the client rejects a quote when either its block number or hash changes, including a same-height block replacement, and re-simulates immediately before wallet submission.
6147

6248
## Commands
6349

@@ -91,7 +77,7 @@ The router creates and redeems complete sets using observed balance and attoETH
9177
- [Start here](docs/index.md)
9278
- [First market](docs/tutorials/first-market.md) and [first trade](docs/tutorials/first-trade.md)
9379
- [Contract reference](docs/reference/contracts.md), [router reference](docs/reference/router.md), and [SDK reference](docs/reference/sdk.md)
94-
- [Two-way design](docs/explanation/two-way-market.md), [INVALID insurance](docs/explanation/invalid-insurance.md), and [security model](docs/explanation/security-model.md)
80+
- [Market design](docs/explanation/two-way-market.md), [INVALID insurance](docs/explanation/invalid-insurance.md), and [security model](docs/explanation/security-model.md)
9581

9682
## MVP limitations
9783

trading/compose.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ services:
55
build:
66
context: ..
77
dockerfile: trading/Dockerfile
8-
args:
9-
TRADING_UI_DEPLOYMENT: ${TRADING_UI_DEPLOYMENT:-}
108
image: zoltar-trading
119
ports:
1210
- 127.0.0.1:4163:4163

trading/deployments/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
`deploy:local` writes `local.json` here. It records the chain, input core `SecurityPoolFactory`, immutable fee, deployed trading factory and router, compiler settings, bytecode hashes, and transaction hashes. `local.json` is ignored because local addresses are ephemeral.
44

5-
No completed public trading deployment manifest is bundled. The default build includes planned mainnet and Sepolia core addresses from the root manifests, then lets the wallet deploy and verify the trading factory and router when that core code is installed. To use an existing trading manifest instead, build with `TRADING_UI_DEPLOYMENT=/absolute/path/to/local.json bun run ui:build`; the build copies it to the untracked UI output, and the live client validates it at startup. See [Deploy the trading contracts](../docs/how-to/deploy.md) for the wallet path and [UI configuration](../docs/how-to/configure-ui.md) for the complete schema and runtime requirements.
5+
No completed public trading deployment manifest is bundled or required by the client. The build includes mainnet and Sepolia core addresses from the root manifests. At startup, the client derives the fixed-fee trading factory and router through the canonical CREATE2 proxy and checks their code directly. If either contract is missing, it lets the connected wallet deploy and verify it. See [Deploy the trading contracts](../docs/how-to/deploy.md) for the wallet flow and [UI configuration](../docs/how-to/configure-ui.md) for network and RPC behavior.

trading/docs/explanation/limitations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
This MVP intentionally does not implement a three-way invariant, INVALID trading, an invalidity-probability oracle, weighted reserves, quadratic solvers, flash swaps, a protocol fee, governance controls, upgradeable proxies, automatic branch selection, automatic LP migration, an insured-position NFT, or per-user on-chain position accounting.
44

5-
It also has no TWAP, routing across markets, guaranteed deep liquidity, or mechanism to withdraw more early ETH than complete-set insurance and reserves permit. The UI’s local demo states are visual fixtures, not live-chain evidence. Live mode requires either a verified wallet deployment on a supported canonical core network or an explicit reviewed trading manifest. Public deployments require gas benchmarks against a real-core funded lifecycle fixture, adversarial integration testing, and an external audit.
5+
It also has no TWAP, routing across markets, guaranteed deep liquidity, or mechanism to withdraw more early ETH than complete-set insurance and reserves permit. The UI’s local demo states are visual fixtures, not live-chain evidence. Live mode derives and verifies the deterministic trading contracts on a supported canonical core network. Public deployments require gas benchmarks against a real-core funded lifecycle fixture, adversarial integration testing, and an external audit.
66

77
Potential future work may add separate INVALID markets, safer oracle observations, routing, or bounded convenience flows. Those are distinct designs and must not weaken the invariant that this pair never accepts or holds INVALID.

trading/docs/how-to/configure-ui.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@
22

33
The standalone UI has two explicitly separated modes. `?demo=1` provides walletless visual fixtures and is always labeled simulated; do not use demo screens as evidence of live chain state. Without that query parameter, the application reads live RPC and wallet state.
44

5-
The build copies the canonical mainnet and Sepolia core factory and deterministic proxy addresses from the root deployment manifests. When no complete trading deployment is bundled or saved, open the live UI, select a core network, enter its RPC URL, and keep or change the immutable fee. The UI verifies the RPC chain and core bytecode automatically. Connect a wallet to deploy the deterministic trading factory, then the router. After verifying both contracts, the browser saves the completed configuration locally and opens live trading. A different fee selects a different deterministic factory and router.
5+
The build copies the canonical mainnet and Sepolia core factory and deterministic proxy addresses from the root deployment manifests, together with a default public RPC URL for each network. Open the live UI; it derives the fixed-fee trading factory and router addresses with CREATE2 and checks whether both contracts are deployed. Missing contracts open the deployment screen automatically. The UI verifies the RPC chain and core bytecode and lists each deterministic contract's deployment status. Connect a wallet to deploy the factory, then the router. After verifying both contracts, the client opens live trading without saving a separate trading deployment configuration. Use **Settings** beside the wallet to select another supported network or override its RPC URL. A custom RPC must use HTTPS or loopback HTTP and match the selected chain. Browser-led deployment uses a fixed 0.30% trading fee. Trading and trading-pool deployment surfaces present the deployed immutable fee as a percentage.
66

7-
For an existing local or reviewed trading deployment, `deploy:local` emits the authoritative nested manifest under `network`, `core`, and `trading`. Copy it into the built application with:
8-
9-
```bash
10-
TRADING_UI_DEPLOYMENT=/absolute/path/to/trading/deployments/local.json bun run ui:build
11-
```
12-
13-
The build copies it as untracked `ui/dist/deployment.json`, which takes precedence over browser-saved configuration. The parser also accepts the documented flat schema for deliberate hand-authored configurations. The live client validates required addresses and values, discovers pools from `SecurityPoolFactory` in bounded pages, isolates individual market-read failures, and never hard-codes market addresses. The wallet must report the configured chain before any submission. Entry, exit, liquidity, settlement, and fork-migration calls are simulated through the actual contracts, rejected after a block change, and simulated again immediately before submission with explicit bounds where the call accepts them.
7+
The live client discovers pools from the canonical `SecurityPoolFactory` in bounded pages, isolates individual market-read failures, and never hard-codes market addresses. The wallet must report the selected network before any submission. Entry, exit, liquidity, settlement, and fork-migration calls are simulated through the actual contracts, rejected after a block change, and simulated again immediately before submission with explicit bounds where the call accepts them.
148

159
Serve built assets from the same origin. Production code may connect only to the configured RPC, the wallet provider, and explicit explorer links. Demo mode is unmistakably labeled and must never be presented as live state.

trading/docs/how-to/deploy.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ docker network inspect zoltar >/dev/null 2>&1 || docker network create zoltar
1111
docker compose up --build --force-recreate
1212
```
1313

14-
Open `http://localhost:4163/#/deploy`, select the network, enter an HTTPS RPC URL and the immutable fee, then connect a wallet. The UI checks the RPC chain, canonical proxy, and core factory before enabling the first transaction. Submit the factory transaction, then the router transaction. Progress reaches `2 / 2` after both deterministic contracts and their immutable links have been verified. The flow resumes at the first missing contract if you return later.
14+
Open `http://localhost:4163/#/deploy`. The UI automatically selects the canonical deployment and its default public RPC, then checks the RPC chain, canonical proxy, and core factory. Connect a wallet and review the status shown for the Trading factory and Trading router. Submit the factory transaction, then the router transaction. Progress reaches `2 / 2` after both deterministic contracts and their immutable links have been verified. The flow resumes at the first missing contract when you return with the same settings. To use another supported network or RPC URL, open **Settings** beside the wallet before connecting. Browser-led deployment uses a fixed 0.30% trading fee. Trading-pool deployment is not part of this setup: browse SecurityPools after setup and deploy a trading pool only for a selected pool that does not have one. Its deployment prompt identifies the deployed immutable fee as a percentage before submission.
1515

1616
## Use local Anvil
1717

@@ -31,9 +31,9 @@ docker network inspect zoltar >/dev/null 2>&1 || docker network create zoltar
3131
docker compose up --build --force-recreate
3232
```
3333

34-
Open `http://localhost:4163/#/deploy` and follow the public-network steps above with **Ethereum Mainnet · chain 1** and `http://127.0.0.1:8545`. The browser will deploy the trading factory and router through the same deterministic proxy.
34+
Open `http://localhost:4163/#/deploy` and follow the public-network steps above with **Ethereum Mainnet** and `http://127.0.0.1:8545`. The browser will deploy the trading factory and router through the same deterministic proxy.
3535

36-
For a generated trading manifest instead of browser storage, open another terminal in the repository root, enter `trading/`, and run the local deployment script against the matching root manifest:
36+
For script or integration testing, open another terminal in the repository root, enter `trading/`, and run the local deployment script against the matching root manifest:
3737

3838
```bash
3939
cd trading

trading/docs/reference/configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ Environment variables used by local deployment:
99
| `ZOLTAR_DEPLOYMENT_MANIFEST` | Existing matching core manifest | Required |
1010
| `TRADING_FEE_BPS` | Immutable AMM fee | `30` |
1111

12-
The live UI directly accepts the nested `deploy:local` manifest. It also accepts a flat JSON schema with numeric `chainId` and `feeBps`, string `chainName` and `rpcUrl`, and addresses `securityPoolFactory`, `factory`, and `router`. Set `TRADING_UI_DEPLOYMENT` while building to copy a reviewed manifest to untracked `ui/dist/deployment.json`; see [UI configuration](../how-to/configure-ui.md). Secrets do not belong in manifests or `.env.example`.
12+
`deploy:local` writes a nested deployment manifest for scripts and integration environments. Secrets do not belong in manifests or `.env.example`.
1313

14-
Without `TRADING_UI_DEPLOYMENT`, the build writes `deployment.json` as `null` and writes `core-deployments.json` from the root mainnet and Sepolia deployment manifests. The live setup screen accepts a supported chain, an HTTPS or loopback HTTP RPC URL, and an immutable fee from 0 to 9999 basis points. It computes the trading factory and router through the core deployment's canonical CREATE2 proxy, verifies or deploys each contract through the wallet, and stores the completed configuration under `zoltar.trading.deployment.v1` in browser local storage.
14+
The build writes `core-deployments.json` from the root mainnet and Sepolia deployment manifests and adds each network's default public RPC URL. The live client defaults to the first supported network, computes the trading factory and router with the fixed 0.30% trading fee through the core deployment's canonical CREATE2 proxy, and checks both addresses directly. **Settings** beside the wallet selects another supported network or accepts an optional HTTPS or loopback HTTP RPC override. The client does not require or persist a separate trading deployment configuration.

trading/docs/tutorials/first-market.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This walkthrough creates and seeds the first pair for an existing canonical SecurityPool. You will finish with an initialized YES/NO pair, LP tokens, and separate INVALID insurance in your wallet.
44

5-
Before starting, [deploy the trading contracts](../how-to/deploy.md), then [configure and build the standalone UI](../how-to/configure-ui.md) with the emitted manifest. The configured chain must contain an initialization-eligible SecurityPool: its system state is `Operational`, its question has not ended, fork continuation is not pending, its universe has not forked, and its outcome is `None (unresolved)`. The pool also needs a current valid REP price and enough dynamic minting capacity for the resulting settlement collateral. Fund a wallet on that chain with enough ETH for the initial deposit and gas.
5+
Before starting, [build and open the standalone UI](../how-to/configure-ui.md) on a supported canonical network. If its deterministic trading contracts are missing, follow the browser [deployment flow](../how-to/deploy.md). The selected network must contain an initialization-eligible SecurityPool: its system state is `Operational`, its question has not ended, fork continuation is not pending, its universe has not forked, and its outcome is `None (unresolved)`. The pool also needs a current valid REP price and enough dynamic minting capacity for the resulting settlement collateral. Fund a wallet on that network with enough ETH for the initial deposit and gas.
66

77
Capacity ownership is shown in REP: total ownership describes all capacity backing the pool, while fee-eligible ownership is the subset currently eligible for fees. These figures are not ETH deposit limits. The minting-capacity ceiling is denominated in ETH and is computed from the current REP price; available capacity is that ceiling minus checkpointed settlement collateral, floored at zero. Because the REP price and pool accounting can change, the router simulation must confirm that post-deposit settlement collateral remains within the current ceiling. If simulation reports a stale price or insufficient capacity, do not submit: retry after the price is valid and capacity is available, or reduce the ETH deposit.
88

trading/docs/tutorials/first-trade.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# First trade
22

3-
Build and open the standalone UI with a valid deployment manifest as described in [Configure the standalone UI](../how-to/configure-ui.md). Connect a wallet on the manifest chain, select an initialized open pair, and choose YES or NO. Use `?demo=1` only to inspect clearly labeled simulated states; demo mode cannot submit transactions.
3+
Build and open the standalone UI as described in [Configure the standalone UI](../how-to/configure-ui.md). The client derives and verifies the deterministic trading contracts on its selected canonical network. Connect a wallet on that network, select an initialized open pair, and choose YES or NO. Use `?demo=1` only to inspect clearly labeled simulated states; demo mode cannot submit transactions.
44

55
1. Enter an ETH amount. Set the slippage tolerance (0% to 5%) and how many whole minutes the transaction should remain valid (1 to 1440), then select **Simulate authoritative router call**. Lower slippage allows less adverse movement from the simulated quote. A shorter validity window reduces stale-transaction exposure. Either setting can cause more reverts. Do not treat demo fixtures or pure preview math as a transaction quote.
66
2. Review complete-set shares, opposite shares swapped, additional and total long shares, INVALID insurance, fee, average execution price, conditional price impact, chosen slippage tolerance, deadline, and minimum received.

0 commit comments

Comments
 (0)