Safety Model
Polygolem is read-only by default. Every market-data and discovery command
runs without credentials and cannot make a state-changing request. Paper mode
is local-only: simulated orders are stored on disk and never reach an
authenticated endpoint. Live commands require all four gates to pass —
POLYMARKET_LIVE_PROFILE=on, live_trading_enabled: true, --confirm-live,
and a successful polygolem preflight. Credentials are loaded only at the
moment they are needed and are redacted in every log, error, and JSON
output.
If any gate fails, the command aborts with a structured error and a non-zero exit code. Polygolem will never silently downgrade a live command to paper mode or read-only — that would hide operator intent and break automation.
The four gates, in order
POLYMARKET_LIVE_PROFILE=on— environment opt-in.live_trading_enabled: true— config-file opt-in.--confirm-live— per-invocation flag.polygolem preflightpasses — wallet readiness, auth readiness, network consistency, API health.
All four. No partial credit.
Deposit Wallet Safety (V2)
Polygolem’s supported live trading path is deposit wallet (POLY_1271 / signature type 3). EOA, proxy, and Gnosis Safe are legacy upstream paths and are not the default live path for new CLOB V2 API users.
Signer vs Funder Separation
The EOA remains the cryptographic signing key for the ERC-7739 wrapper. The
deposit wallet is the CLOB account: it holds pUSD and appears as both order
maker and order signer in the V2 payload. These must never be confused:
- EOA pUSD does NOT fund deposit-wallet orders. CLOB reads the deposit wallet’s balance.
- Approvals must come from the deposit wallet via relayer WALLET batch, not from the EOA.
- Diagnostics must distinguish
owner_eoafromfunder/deposit_walletin logs.
Builder Credential Isolation
V2 relayer keys and legacy builder HMAC credentials authenticate with the relayer for WALLET-CREATE and WALLET batch. They are a separate auth system and must never be:
- Reused as CLOB L2 credentials
- Stored alongside CLOB API keys in the same config section
- Added to order-signing headers (orders use
builderCode, not builder HMAC)
Deposit-Wallet Balance Routing
When signature_type = 3 (deposit), the CLOB balance endpoint returns the
deposit wallet’s pUSD balance, not the EOA’s. Live readiness must:
- Check CLOB balance with
signature_type = 3 - Verify deposit wallet is deployed. Polygon
eth_getCodeis the source of truth; relayer/deployedis advisory and can return false while bytecode already exists. - Verify collateral allowances are non-zero
- Block before order submission if any check fails
Decision-Window Safety
Automated trading must bind each strategy decision to the exact market window
it intends to trade. A 5m signal for 2026-05-09T08:20:00Z must not buy a
market that starts at 2026-05-09T12:20:00Z, even if the asset and timeframe
match.
The safe resolver behavior is fail-closed:
- return available only when the market
startDatematches the requested decision window, - return
window_mismatchwhen a slug hit points to a different window, - never fall through from an exact-window lookup to a generic “next available” market search.
Matched, Winning, Redeemable
Post-trade state has three separate meanings:
| State | Meaning |
|---|---|
matched | The CLOB filled the order and position shares moved into the deposit wallet. |
winning | The market resolved in favor of the held outcome. |
redeemable | The Data API reports the held position can be redeemed. |
A matched order is not proof that the market won. Redemption automation must
query the deposit wallet’s Data API /positions rows and use
redeemable=true as the readiness signal. There is no separate resolved
boolean in the current position schema.
CLOB and Data API answer different questions and are not interchangeable:
- CLOB — order/fill status:
/data/orders,/data/trades. - Data API — outcome, PnL, and redeem readiness:
/positionsand/closed-positions.
Routing a “did the market win?” question to the CLOB is the most common runbook bug. See Redeem Winners › CLOB vs Data API.
V2 Redeem Readiness
Polymarket V2 routes pUSD-native split, merge, and redeem through collateral adapters:
| Market Type | Adapter |
|---|---|
| Standard binary | CtfCollateralAdapter |
| Negative-risk | NegRiskCtfCollateralAdapter |
The adapter reads conditionId, detects the wallet’s current CTF balances,
performs the underlying CTF redemption, wraps proceeds back into pUSD, and
returns pUSD to the deposit wallet. It ignores caller-supplied collateral
address, parent collection, and indexSets.
Adapter readiness is separate from trading readiness. Existing wallets that only ran the six-call trading approval batch need a one-shot adapter approval batch before their first V2 redeem.
If relayer submission rejects the adapter approval or redeem call as “not in the allowed list”, stop. The V2 deposit-wallet path is non-negotiable: the owner signs an EIP-712 WALLET batch, the relayer submits it through the deposit-wallet factory, and the wallet call targets the collateral adapter. There is no direct owner-EOA fallback, no raw CTF fallback, and no SAFE/PROXY shortcut for deposit-wallet positions.
Relayer Auth vs Trading Auth
- Relayer auth: V2 relayer key or builder HMAC credentials → wallet lifecycle operations
- Trading auth: CLOB L1/L2 credentials → order placement and balance queries
- These systems are independent. A failed relayer call must not be retried as a CLOB call.
Related
docs/SAFETY.md— canonical policy- Deposit Wallets & Signature Types — required for new accounts
- Smart Contracts — factory addresses and permission model
- Paper Trading — the local-only execution surface
- Architecture — where the gates live in code