Reference

Trading security model

Trading has not been audited. Tests and internal reviews are not substitutes for an independent security assessment. This page states what the contracts defend against, what they assume, and what they leave to the user.

Signature and callback authorization

LP permits use the standard ERC-2612 nonce, deadline, chain-bound EIP-712 domain, owner, spender, and exact value. The LP ledger is the repository's vendored ERC20.sol, sourced from the MIT-licensed OpenZeppelin Contracts v5.2.0 release. Its local changes pin Solidity 0.8.35, use repository formatting and descriptive revert strings, and substitute Augur unit terminology in comments; its state-transition and allowance algorithms are unchanged. TradingLiquidityToken.sol adapts the MIT-licensed v5.2.0 ERC20Permit by using the repository's shared OpenZeppelin-derived EIP-712/ECDSA primitive, a fixed version 1, descriptive revert strings, and the stable Zoltar Two-Way LP domain name. It omits Nonces, IERC20Permit, and EIP712 inheritance only because their exact storage and hashing behavior is implemented directly by the local nonce mapping and shared authorization primitive. No signature or curve algorithm is reimplemented in the pair.

OpenZeppelin ERC-20 prohibits minting to the zero address. The pair therefore locks MINIMUM_LIQUIDITY at MINIMUM_LIQUIDITY_LOCK, address(1), which no key controls, instead of treating the zero address as an LP holder. Only pair operations can invoke the inherited internal mint and burn functions. A signature is authorization, not transaction privacy: integrations should use short deadlines and exact amounts. The router reference gives the allowance alternative for signers without ECDSA permits.

Receive-based ERC-1155 operations use no off-chain signature. The ShareToken call must be submitted by the owner, while the versioned payload binds all contract identities, operation inputs, recipients, slippage, and deadline. Copying an observed payload cannot redirect assets and cannot separately consume an allowance because the router requires operator == from.

Custody and reentrancy

The pair rejects foreign ShareTokens, Invalid shares, and noncanonical universe IDs in both single and batch callbacks. A reentrancy lock covers every reserve-changing operation and every LP mint or burn; LP transfer, approve, and permit change no reserves and are not locked. Recipient callbacks can execute arbitrary code, so final reserves are read from authoritative balances after transfers. Recorded-balance deficits revert; valid Yes and No donations synchronize upward and accrue to current LPs.

The router recognizes pairs only through its immutable factory, opens callback state only around one expected pool and share token, and restores its starting share balances. Its ETH receiver opens only around redemption from that pool. This prevents unsolicited callbacks and keeps forced ETH separate from exit proceeds.

Factory checks prevent a malicious pool from borrowing another question's ShareToken or universe identity. CREATE2 plus one immutable fee gives one canonical pair per exact pool without privileged replacement.

Because an ERC-1155 transfer to an address without code cannot invoke a receiver callback, an attacker can send shares to a predicted CREATE2 address before deployment. The factory's predeployment quarantine removes those canonical balances during pair construction, so initialization starts with zero canonical balances, including zero Invalid. Foreign token contracts cannot be enumerated and may still assign irrelevant balances to the address; the pair never recognizes or moves them.

Assumptions

Known risks

Spot prices are not an oracle and expose users to front-running and sandwiches. A lifecycle transition, fork, resolution, reserve donation, retention update, or intervening trade can invalidate a quote; contract guards and slippage bounds make the transaction revert rather than promise execution. Initial liquidity determines the starting conditional price and should be initialized atomically. LP tokens cover only Yes/No reserves; separately held Invalid can be lost, transferred, or insufficient. A valid-resolution LP can suffer directional loss, and Yes/No reserves may have no redemption value after an Invalid result.

Remaining risks also include first-price choice, stale simulation, lifecycle races, recipient denial of ETH or ERC-1155 reception, core-contract bugs, and approval misuse. Slippage and deadlines bound execution but do not remove MEV. The immutable factory fee is a deployment choice, not a claim of economic optimality.

Reporting a vulnerability

Report a suspected vulnerability through GitHub private vulnerability reporting. Include the affected commit, contracts and functions, prerequisites, a minimal reproduction, expected impact, and whether funds or deployment keys may be at immediate risk. If private reporting is unavailable, open a public issue asking maintainers to establish a private channel, but do not include vulnerability details. Do not exploit a live deployment or publish details before maintainers have had a reasonable opportunity to respond.