Skip to content

Instantly share code, notes, and snippets.

@napindc
Last active June 22, 2026 05:31
Show Gist options
  • Select an option

  • Save napindc/2c0accab3391ade587a97c5d4ccc33de to your computer and use it in GitHub Desktop.

Select an option

Save napindc/2c0accab3391ade587a97c5d4ccc33de to your computer and use it in GitHub Desktop.
Dimes Multiply integration questions for Olympus

Dimes Multiply — Integration Reference & Open Questions

Working doc for integrating Dimes Multiply (leverage-on-Polymarket middleware) into Olympus. Scope for v1 is manual leverage trading only (no copy-trade fan-out).

Source docs: https://docs.dimes.fi/ · index at https://docs.dimes.fi/llms.txt


Part 1 — What we learned from the docs

1.1 Product

  • Dimes Multiply is a middleware that issues a CFD-style leveraged synthetic over Polymarket positions. The user posts USDC margin on Polygon; Dimes' Underwriting Facility (institutionally-sourced, "$50m+/month capacity") fills the matching YES/NO hedge directly on Polymarket and gives the user a synthetic that pays (P_now − P_entry) × leverage × size, bounded by Polymarket's $0–$1 outcome range.
  • Dimes does not create markets, host orderbooks, compete with PM venues, or do user acquisition. It's pure middleware.
  • Underlying venue today: Polymarket only. Possible future: Kalshi, Hyperliquid, Limitless, Opinion.
  • User never holds Polymarket CTF tokens directly — only the synthetic, keyed by on_chain_position_key. Settlement is in USDC.
  • Dimes never holds user funds longer than a single tx.

1.2 Chain & contracts

  • Live on Polygon mainnet, chain ID 137 only.
  • USDC is USDC.e (bridged)0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 (same token Polymarket uses).

Production:

Contract Address
Vault (LeveragedPredictionVaultV1) 0xECF933ccDf7ebc6a0658c77E070cFe51ebe5328A
USDC.e 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
Polymarket CTF 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045

Sandbox:

Contract Address
Vault 0xefF55c64B8E971eEbBbbc2037593588e0F271dE2
Fake USDC 0xD477EDbe627E94639d7E92119Ca62a461c6ce555
Fake CTF 0x8B859B4459A75b50e07D345F6b1998F27540F758

USDC approvals go to the Vault address. Vault uses transferFrom to pull; "never holds user funds for longer than it takes to execute."

1.3 Environments

Prod Sandbox
REST base https://api.dimes.fi/v1 https://api-sandbox.dimes.fi/v1
WS base wss://api.dimes.fi/v1/ws/... wss://api-sandbox.dimes.fi/v1/ws/...
API key prefix dm_live_skey_… dm_sbx_skey_…
Resource IDs dm_pos_…, dm_off_…, dm_mkt_… dm_pos_sdx_…, etc.
Chain Polygon mainnet Polygon mainnet
Swagger https://api-sandbox.dimes.fi/v1/customer-docs
Demo repo dimes-fi/dimes-demo-ui (React + Vite)

Sandbox uses fake USDC (minted on request by Dimes team) and a fake CTF. Live Polymarket market data is read-only; fills are simulated against the fake CTF. Keys are env-scoped and not interchangeable.

1.4 SDK

  • TypeScript, package: @dimes-dot-fi/sdk (npm).
  • Sub-entries:
    • @dimes-dot-fi/sdk — HTTP client, quote engine, error types. No peer deps.
    • @dimes-dot-fi/sdk/react — hooks + provider. Peer deps: react >=19, @tanstack/react-query >=5.
    • @dimes-dot-fi/sdk/contract — on-chain tx builders + signature verification. Peer dep: viem >=2.
import { DimesClient, ApiKeyAuth } from "@dimes-dot-fi/sdk";

const client = new DimesClient({
  auth: new ApiKeyAuth({
    apiKey: process.env.DIMES_API_KEY,
    walletAddress: "0x1234...abcd",
  }),
});

1.5 Authentication

  • Two auth schemes:
    • Partner API keyAuthorization: Api-Key dm_live_skey_…. Used to mint user JWTs, read partner limits.
    • User JWTAuthorization: Bearer <jwt>. 1-hour lifetime. Keyed on (wallet_address, partner_id). Used for quotes, positions.
  • Mint a JWT: POST /prediction-markets/tokens with body { "wallet_address": "0x…" } → returns { token, expires_at }.
  • Key rotation: two keys per environment can be active simultaneously for zero-downtime rotation. No auto-expiry. Rotate via Dimes team.
  • Market browsing is public (no auth).

1.6 Quote → Open → Close flow

Quote (POST /prediction-markets/quotes, JWT, rate-limited 1 req/sec/wallet):

Request:

{
  "market_ticker": "will-btc-hit-100k-2026",
  "effective_side": "yes",
  "leverage_bps": 50000,
  "notional_usd_pips": "250000000",
  "slippage_bps": 300,
  "provider": "polymarket",
  "allow_revision": false,
  "order_type": "fok",
  "min_fill_bps": 5000
}

Response (abridged — full version has ~30 fields):

{
  "id": "dm_off_abc123",
  "entry_price_usd": "0.65",
  "origination_fee_bps": 125,
  "protocol_origination_fee_bps": 100,
  "partner_origination_fee_bps": 25,
  "polymarket_trading_fee_bps": 100,
  "liquidation_fee_bps": 1000,
  "current_liquidation_price_usd": "0.35",
  "total_user_amount_usd": "562.50",
  "expires_at": "2025-06-01T10:05:00.000Z",
  "position_seed_hex": "0xa1b2c3d4…",
  "on_chain_position_key": "0x1a2b3c4d…",
  "polygon_vault_contract_address": "0x…",
  "contract_signature": "0xabc…",
  "signature_expiry": "1717236300"
}

Quotes expire in 15 seconds. There's a draft → promote variant for better UX (POST /draft-quotes then POST /promoted-quotes/{id}).

On-chain open — two user txs:

// 1. Approve USDC to Vault
usdc.approve(vault, total_user_amount_usd_pips * 100);

// 2. Create position
vault.createPosition(positionSeed, marketId, tokenId, /*…*/);

Backend detects, places hedge on Polymarket, emits position.opened over WS.

Close — single user tx:

vault.requestClose(on_chain_position_key);

Backend sells the hedge, distributes proceeds. Only the original position owner can call this.

1.7 REST endpoints (key ones)

Method Path Auth Notes
GET /prediction-markets/markets public or JWT/API-key cursor pagination via limit, starting_after, ending_before
GET /prediction-markets/markets/search?query=… same
GET /prediction-markets/markets/{ticker} same 404 = customer_market_not_found
GET /prediction-markets/contract-info public returns evm_chain_id, vault address
POST /prediction-markets/tokens API-key mint user JWT
POST /prediction-markets/quotes JWT 1 req/sec/wallet
POST /prediction-markets/draft-quotes JWT same limit
POST /prediction-markets/promoted-quotes/{draft_id} JWT same limit
GET /prediction-markets/positions JWT filterable by status, market, token
GET /prediction-markets/positions/{id} JWT
GET /prediction-markets/positions/{id}/transactions JWT open/close/liquidation/settle/etc tx hashes
GET /prediction-markets/partner-limits API-key

Conventions: snake_case fields, kebab-case paths, list envelope { data: [...], has_more: bool }, monetary values returned as both pips (string) and USD (string).

1.8 Position object — fields worth knowing

status enum: pending | open | unwinding | closing | settling | closed | settled | liquidated | cancelled. Also state: active | inactive.

Nested objects: entry, current, risk, fees, timing.

Key risk fields:

  • risk.health_bps
  • risk.current_liquidation_price_usd
  • risk.liquidation_buffer_bps
  • risk.liquidation_fee_bps
  • risk.margin_buffer_usd

Key timing fields:

  • timing.is_settlement_pending
  • timing.is_voided
  • timing.market_close_time
  • timing.market_status

1.9 WebSockets

Transport: Socket.IO. URLs:

Scope Prod
Partner positions wss://api.dimes.fi/v1/ws/prediction-markets/positions
User positions wss://api.dimes.fi/v1/ws/prediction-markets/user-positions
Partner markets wss://api.dimes.fi/v1/ws/prediction-markets/markets
User markets wss://api.dimes.fi/v1/ws/prediction-markets/user-markets

Auth: API key for partner gateway (auth: {apiKey}), JWT for user gateway (auth: {token}).

Position events: position.created, position.opening, position.opened, position.close_requested, position.closed, position.settled, position.liquidated, position.force_unwound, position.reverted, position.cancelled.

Market events: market.discovered, market.eligibility_changed, market.max_leverage_changed.

User-gateway notification events: ORDER_FULFILLMENT_RETRYING, PARTIAL_OPEN_PROGRESS, PARTIAL_OPEN_FLOOR_MISSED.

Envelope:

{ "id": "evt_…", "type": "resource.action", "created_at": "...", "data": {...} }

No heartbeat documented — we'll need to ask about reconnect/replay semantics.

1.10 Smart wallet support

Three patterns Dimes recognizes (all are Polymarket-specific wallet types):

  1. Polymarket Safe — 1-of-1 Gnosis Safe.
  2. Polymarket Proxy — EIP-1167 minimal proxy. No off-chain signatures supported.
  3. Polymarket Deposit Wallet — ERC-1967 proxy, default for new Polymarket API users. Uses EIP-712 signing with domain { name: "DepositWallet", version: "1", chainId: 137, verifyingContract: depositWalletAddress }. Uses a push-funded atomic 3-call batch so no separate USDC approval tx is needed. Limited to one create per tx.

Critical rule: the wallet_address passed to POST /quotes must be the address that ends up as msg.sender on-chain — for all three patterns that's the contract address, not the owner EOA.

Privy and generic AA wallets are not mentioned in the docs. Olympus uses Privy embedded EOAs + Gnosis Safes — compat is the #1 open question.

1.11 Leverage tiers (J-factor)

Set dynamically per market by depth/spread/slippage:

Tier Leverage Liquidity profile
Deep 8–10× top-of-book ≥ 2–3% of notional depth, slippage ≤ 30–50 bps
Mid 4–6× aggregated depth ~1–2% at active bucket, slippage ≤ 75 bps
Thin / volatile 2–3× <1% depth or slippage >1%
  • Min leverage: 2×. Max leverage: 10×.
  • J-factor recalculates every venue update.
  • During the position, J-factor can reduce leverage as microstructure deteriorates (depth drains, spreads widen, fill rates degrade). The reduction is conditional on microstructure, not scheduled against time. Each reduction pushes the liq price further away.

1.12 Fees

Dimes protocol fees (all to Dimes, all on top of partner fee + venue fee):

Fee Rate Base
Entry / origination 2.0%–2.5%, scaled with leverage collateral × leverage
Time-based 0.05% / day, continuous borrowed only: collateral × (leverage − 1)
Liquidation 10% protocol-provided capital: notional − collateral

Partner origination fee: custom bps we set per quote, paid to a partner-controlled receiver wallet. Sits on top of the protocol fee.

Polymarket venue fees (peak per-leg at $0.50, round-trip ≈ 2×):

  • Geopolitics 0%
  • Sports 0.75%
  • Finance / Politics / Tech 1.00%
  • Culture / Economics / Weather / Other 1.25%
  • Mentions 1.56%
  • Crypto 1.80%

Polymarket builder rewards can be earned by passing a builder code (mechanism not detailed).

1.13 Liquidation

  • Trigger: YES position liquidates when underlying_price ≥ liquidation_price; NO position when underlying_price ≤ liquidation_price.
  • Full close only, no partial liquidation.
  • Two-stage warning system precedes liquidation (mechanism not detailed).
  • After liquidation: hedge unwound, remaining collateral credited to user, final PnL reflected in UI.
  • Protected unwind mode: if liquidity is insufficient, Dimes "pauses new exposure until safe execution is possible."
  • Onchain liquidation proof published per liquidation, containing position ID, timestamp, liquidation price, venue price data, signature of internal hedge unwind. Front-ends and users can audit.

1.14 Position lifecycle states

Quote Pending → Hedging → Active → (Deleveraging) → Liquidation | Settlement Pending → Settled

Plus side-paths: Voided (market cancelled, YES/NO both pay $0.50, is_voided: true) and Reverted (open failed — revert_reason is one of exchange_unavailable, slippage_exceeded, unknown).

1.15 Markets — what's eligible

Supported:

  • Binary markets
  • Simple categorical markets
  • Continuous-hedging markets (no jump-to-settlement risk)
  • Markets with a clearly defined jump-to-settlement window

Explicitly excluded:

  • Markets that "can resolve at any time" with unreliable hedging.

Eligibility gates: liquidity (depth, spread, orderbook stability, fill rate, update frequency, volume, holder distribution), resolution (stable pricing, prices within eligible ranges, current exposure within caps), venue (reliable price feed, predictable settlement, safe hedging path).

Exposure caps: market-level cap = fraction of hedgeable depth; side-level caps = independent YES vs NO.

1.16 Global limits & circuit breakers

  • Global notional cap (system-wide).
  • New entries rejected when venue goes erratic or stops updating.
  • New entries rejected when spreads/depth move outside safe ranges; "rejected until conditions stabilize."

1.17 Error model

Envelope:

{ "error": { "type": "", "code": "", "message": "", "params": {} } }
Type HTTP Meaning
INVALID_REQUEST_ERROR 400 / 404 / 409 bad params or business-rule violation
AUTHENTICATION_ERROR 401 / 403 bad/missing API key or JWT
RATE_LIMIT_ERROR 429 includes Retry-After header
API_ERROR 5xx Dimes-side problem

Retryable codes: internal_server_error, too_many_requests, request_already_in_progress. Backoff exponentially from 1s. Everything else (validation, leverage caps, eligibility) is non-retryable.

Notable error codes: customer_auth_invalid_wallet_address, customer_market_not_found, quote_market_not_eligible, risk_engine_market_closed, quote_leverage_below_minimum, quote_leverage_exceeds_maximum, quote_leverage_exceeds_model_max, quote_user_position_limit_exceeded, quote_market_position_limit_exceeded, quote_entry_depth_too_low, notional_selector_insufficient_liquidity, quote_user_capital_exceeded, quote_market_capital_exceeded, quote_total_capital_exceeded.

1.18 Branding

"Leverage by Dimes" attribution lockup is required directly under the leverage selector. (Color/sizing rules not detailed.)

1.19 Legal summary

  • Partner sets partner_origination_fee_bps; Dimes keeps all protocol fees (entry, time, liquidation).
  • No geo restrictions imposed by Dimes; partner is responsible for compliance in their jurisdictions.
  • No KYC obligation imposed.
  • No SLA, service "as is", no warranties.
  • Termination: 14 days written notice for convenience; immediate for material breach uncured within 7 days, regulatory events, insolvency/fraud.
  • Liability cap = trailing 12 months of fees paid.
  • Partner is forbidden from caching, modifying, or delaying Dimes-provided market state data.
  • User data collected by partner remains the partner's responsibility.

Part 2 — Open questions for Dimes

Only the items that would actually block writing code for a manual leverage trading v1.

Q1. Wallet model (🔴 the real blocker)

Olympus users have a Privy embedded EOA and (post-migration) a Gnosis Safe that holds the funds. Most active users trade from the Safe.

  1. Is the Polymarket Safe path you support compatible with a standard 1-of-1 Gnosis Safe owned by a Privy EOA, or do you require Polymarket's specific Safe deployment + guard/module config?
  2. Does createPosition accept EIP-1271 signatures so the Safe is the signer, or does the EOA owner sign?
  3. Does the Vault support a gasless / meta-tx path for open and close (we'd run the relayer), or does every user need MATIC for gas?
  4. Anyone integrated Privy with the SDK already? Any known gotchas with viem + Privy + your EIP-712 typed-data shape?

Q2. Markets

  1. Which Polymarket categories are live in prod today, and is there a single field (beyond accepting_new_positions) to ask "is this specific market eligible right now"?
  2. Multi-outcome (>2) categorical markets — supported, or binary-only?
  3. In-play live sports: how do you handle orderbook gaps around goals — does J-factor preempt, or do users get liquidated by the jump?

Q3. Risk / liquidations

  1. Is current_liquidation_price_usd monotonic for the life of the position, or does J-factor move it as leverage decays? (We need to know before we render a liq line.)
  2. What's the price source for the liquidation trigger — mid, best bid/ask, VWAP?
  3. Can "remaining collateral" after liquidation ever go negative for the user, or is the user's downside bounded at their posted margin?
  4. For voided markets ($0.50 payout): confirm the exact formula for what the user gets back.

Q4. Fees & revenue share

  1. Is there a min/max cap on partner_origination_fee_bps we can charge?
  2. Partner origination fee — paid on open only, or also on close / liquidation?
  3. Polymarket builder rewards — how do we plug in our builder code, and do they come to us directly or through Dimes?

Q5. Auth & rate limits

  1. JWT is 1h. We'll cache per-user JWTs in Redis — any cap on concurrent active JWTs per partner?
  2. Beyond the documented 1 quote/sec/wallet, is there a partner-level qps cap on quotes, positions read, or WS subscriptions?

Q6. Copy-trading (just a quick ask, not in v1)

  1. Do you know if Ares allows copy-trading with leverage today? Curious how they architected it — we may build this in v2.

Q7. Legal — one item only

  1. 14-day termination for convenience: what happens to open user positions on termination — forced close at mark, or settle to resolution?
@10dimes

10dimes commented Jun 22, 2026

Copy link
Copy Markdown

Dimes Integration Q&A

Responses to your integration questions. Everything below is grounded in the live docs:


Q1. Wallet model

Q1.1 — Compatible with a standard 1-of-1 Gnosis Safe owned by a Privy EOA, or do you require Polymarket's specific Safe deployment + guard/module config?

A standard 1-of-1 Gnosis Safe works. That is exactly our "Polymarket Safe" pattern. The vault does not care whether msg.sender is an EOA or a contract, and we require no guard or module config on the Safe. The one hard requirement: the wallet_address you pass to POST /quotes must be the address that will be msg.sender on-chain, which for the Safe path is the Safe contract address, not the owner EOA. The wrong address fails the on-chain signature check.

Context worth flagging: Polymarket now onboards net-new users onto deposit wallets (ERC-1967 proxy via their deposit-wallet factory), so Safe and Proxy are effectively existing-wallet / legacy paths. Your migrated users who already hold Safes are fine on the Safe path. Any brand-new user you provision should be on a deposit wallet (see Q1.3, that path is gasless).

Q1.2 — Does createPosition accept EIP-1271 so the Safe is the signer, or does the EOA owner sign?

The owner EOA signs. Standard Safe flow: encode the vault createPosition calldata, wrap it in a SafeTx, the owner signs the SafeTx hash, then execTransaction is submitted and the Safe executes the vault call. Same pattern as any other transaction you would route through the Safe. Note the vault's own authorization is the contract_signature carried in the quote (signed by our authorized signer), which is separate from the Safe owner's signature.

Q1.3 — Gasless / meta-tx path for open and close, or does every user need MATIC?

Depends on wallet type:

  • Deposit wallet: gasless. The push-funded open and the close both go through Polymarket's relayer (relayer-v2.polymarket.com/submit), which requires Polymarket builder API credentials. No MATIC needed by the user.
  • Safe / Proxy: the submitter pays gas. For the Safe, anyone can submit the execTransaction (owner, your backend, or a relayer you run), so you can sponsor gas from your own infra if you want. We do not run a gasless relayer for the Safe/Proxy paths today.

Net: put new users on deposit wallets and gas is a non-issue. The Privy-held-funds path works, but the user (or you) pays gas.

Q1.4 — Anyone integrated Privy with the SDK yet? Gotchas with viem + Privy + your EIP-712 shape?

Nobody has wired up Privy yet, so no battle-tested gotcha list. Ares had no issues with Turnkey. We added a Privy example in our demo UI (https://github.com/dimes-fi/dimes-demo-ui/blob/main/README.md) and created a new section in our doc for you: https://docs.dimes.fi/for-developers/privy-integration.


Q2. Markets

Q2.1 — Which categories are live in prod, and is there a single field beyond accepting_new_positions to check per-market eligibility?

Live categories in prod are crypto and sport only. Anything else is rejected with QUOTE_MARKET_UNSUPPORTED_CATEGORY. We usually support several hundred markets each day. We plan on expanding this coverage in Q3.

accepting_new_positions is the single field to check. For the per-side breakdown, read sided_eligibility.{yes,no}.accepting_new_positions (a market can accept YES but not NO), and rejection_reason_code (or sided_eligibility.{yes,no}.rejection_reason_code) tells you why a side is closed. Filter the markets list with ?accepting_new_positions=true to get only currently-eligible markets.

Q2.2 — Multi-outcome (>2) categorical markets: supported or binary-only?

Supported, but underneath everything is binary. A multi-outcome market decomposes into a set of YES/NO markets, and each one independently supports leverage or not, at its own max leverage. The same accepting_new_positions / sided_eligibility check applies per sub-market. To map a Dimes market to its Polymarket counterpart, use the polymarket object on every market (polymarket.condition_id, polymarket.yes_token_id, polymarket.no_token_id, polymarket.slug); it is always present, since all live markets are Polymarket-sourced.

Q2.3 — In-play live sports: how do you handle orderbook gaps around goals? Does the risk engine preempt, or do users get liquidated by the jump?

Two layers, and the second is where our real edge sits.

First, entry is gated: live markets that are too thin or too risky to enter are screened out up front via codes like QUOTE_ENTRY_SPREAD_TOO_WIDE, QUOTE_ENTRY_DEPTH_TOO_LOW, QUOTE_ENTRY_BID_DEPTH_TOO_LOW, QUOTE_TRADING_WINDOW_CLOSING, and the excluded-sport / excluded-market-type codes. So the worst live states never accept new positions.

Second, on an open position the first-line control is force-unwind / deleveraging (the position is partially unwound as risk rises), with liquidation as the backstop, not the default. The edge is that this deleveraging engine is trained on hundreds of thousands of market hours and uses that experience to minimize liquidations. It is sport, microstructure, and time-aware: the model undersdtands that a tied soccer game is allowed to carry less leverage in the final 15 minutes than in the first half (enforced through deleveraging), since a late goal is the sharpest swing the book can take, while that dynamic is much less pronounced in basketball, which scores more progressively.

Over the last 3 weeks this has held our liquidation rate to ~8%, versus a ~55% counterfactual over the same period without the proactive deleveraging engine: https://x.com/dimes_fi/status/2066893342546260020. This is where Dimes is really strong and this model is the reason we were able to secure institution credit underwriting to fund the margining of leverage positions.

On a genuinely discontinuous jump (a goal that clears whatever level the engine has already deleveraged to), a position can still be liquidated by the gap. The final protection there: the user's downside is bounded at posted collateral. effective_collateral is floored at 0, so a jump can liquidate the position but can never push the user negative or beyond their margin. They cannot lose more than they put in, regardless of gap size.


Q3. Risk / liquidations

Q3.1 — Is current_liquidation_price_usd monotonic for the life of the position, or does the engine move it as leverage decays?

It moves. Do not treat it as static, and do not recompute it yourself from an LTV formula. The liquidation threshold is not pure LTV math (it incorporates the unwind-first / liquidate-last-resort logic), and it shifts as the position deleverages and conditions change. We give it to you live: risk.current_liquidation_price_usd (and _pips) on GET /positions, plus push updates over WebSocket. Render your liq line off that live field rather than freezing the value from the quote.

Q3.2 — Price source for the liquidation trigger: mid, best bid/ask, or VWAP?

The trigger references the bid (you would be exiting into the bid). Note the mark_price we surface for PnL display is the mid, so do not conflate the two: PnL / mark = mid, liquidation trigger = bid.

Q3.3 — Can "remaining collateral" after liquidation go negative, or is downside bounded at posted margin?

Bounded, never negative. effective_collateral is floored at 0. On any exit (close, liquidation, settlement, void) we run the same waterfall: cover fees and repay the loan first, then the user gets whatever remains. The remainder can be 0 but never below it. The user's max loss is their posted collateral.

Q3.4 — Voided markets ($0.50 payout): exact formula for what the user gets back.

A void pays $0.50 per token (50/50, no winner). We then apply the standard close waterfall:

payout_to_user = max(0,  (position_token_units x $0.50)  -  loan_outstanding  -  fees_outstanding)

where loan_outstanding is the borrowed portion (notional - collateral) and fees_outstanding is accrued lifetime fee + accrued venue fee (no liquidation fee on a void). Fees and loan come off the top, the user receives the rest, floored at 0. You will see this land as result.proceeds_usd on the settled position, with result.realized_pnl_usd = proceeds - collateral.


Q4. Fees & revenue share

Q4.1 — Min/max cap on partner_origination_fee_bps?

The partner origination fee is a per-integration parameter you set, layered on top of the protocol origination fee. The combined rate shows up as origination_fee_bps = protocol_origination_fee_bps + partner_origination_fee_bps on the quote. There is no min/max.

Q4.2 — Origination fee on open only, or also on close / liquidation?

Our origination fee is on open only. We take no fee on close.

Q4.3 — Polymarket builder rewards: how do we plug in our builder code, and do rewards come to us directly or through Dimes?

Send us your builder code and we wire it into the transaction flow. Your builder code (not ours) is what is attached on-chain, so your fees and volume attribution route to you directly through Polymarket's normal path, not through Dimes. This is the Ares setup: you take builder-code fees applied on every trade. The deposit-wallet relayer flow already runs on builder API credentials, so this slots in naturally.


Q5. Auth & rate limits

Q5.1 — JWT is 1h. We will cache per-user JWTs in Redis. Cap on concurrent active JWTs per partner?

No cap on concurrent active JWTs. You can cache them, but honestly we would not bother with Redis for this. Mint a fresh JWT on trading-terminal / UI load and refresh it every ~30 min, well before the 1h expiry. The only relevant limit is the JWT generation endpoint itself: 180 req/min per partner, which is far above what session-based minting needs.

Q5.2 — Beyond 1 quote/sec/wallet, any partner-level qps cap on quotes, positions read, or WS subscriptions?

The documented throttles:

Scope Limit
Per partner API key 120 req/min
Per user JWT (wallet) 60 req/min
Unauthenticated (per IP) 30 req/min
Token generation (per partner) 180 req/min
Quote endpoints (/quotes, /draft-quotes, /promoted-quotes) per wallet 1 req/sec

The 1/sec applies only to the quote endpoints, because each quote pulls a lot of data from Polymarket and we throttle to stay under their limits. That is a worst case: with a warm cache (multiple partners quoting the same markets) you can effectively exceed 1/sec. No separate cap on WebSocket subscriptions to worry about.

For real-time UI, do not poll. Subscribe over WebSocket to market and position updates (run it in the frontend per-user, or index it in your backend). Our demo UI already does this and we can share the example. And if your UI needs more quote throughput than the 1/sec worst case allows, we can stand up additional / custom endpoints and tune per-partner limits to whatever your volume requires. Just tell us the shape of the load.


Q6. Copy-trading (v2, not v1)

Q6.1 — Does Ares allow copy-trading with leverage today, and how did they architect it?

Not yet. Ares has not built copy-trading with leverage. It is a strong idea and they will probably get to it, but it is not live today.

How it would map onto our rails: every position is a self-contained, signed quote that becomes an on-chain position keyed to one wallet, and leverage is a per-position parameter, not an account-level setting. So a follower wallet copies a leader simply by requesting its own quote for the same market / side / notional / leverage and signing with its own wallet. Leverage carries over for free because it is chosen per position. Nothing in our model blocks building this in v2.

One thing to frame carefully if you build it: a trade that is good at 1x is not twice as good at 2x. Leverage interacts with the path, not just the outcome. If the thesis ends up right but the match is heavily disputed with setbacks along the way, the position might have sometimes auto-deleveraged before settlement, so the 2x copier just carries additional financing cost for no real extra upside. It's situation specific, obviously. The product idea is very good. It just needs the right disclaimers around it so users understand that more leverage on a good call is not a free multiplier.


Q7. Legal

Q7.1 — 14-day termination for convenience: what happens to open user positions, forced close at mark or settle to resolution?

Termination stops new originations from the effective date, but existing open positions are honored and run to their natural resolution (or the user closes them normally during wind-down). We do not force-close at mark; that would crystallize user losses against the bounded-downside design.

@napindc

napindc commented Jun 22, 2026

Copy link
Copy Markdown
Author

Part 3: Follow-Up Questions for Dimes

Thanks — the Part 2 answers closed the major risk questions (bounded downside, liq = bid, void waterfall, rate limits, builder-code routing). A few gaps remain, mostly specific to how Olympus is wired.

Blocking (Olympus-specific)

F1. Open-position footprint in the user's own Polymarket wallet.
While a Dimes position is open, does the user's own Polymarket Safe ever hold CTF tokens or resting orders, or is everything in the Dimes Vault / Underwriting Facility? We run a failsafe that auto-closes Polymarket positions in a user's wallet lacking our internal attribution, so we need to confirm a live Dimes position leaves the user's own wallet empty.

F2. Quote/signature expiry vs. on-chain confirmation.
Quotes and contract_signature expire in 15s, but opening a Safe position is approve + SafeTx execTransaction, which can confirm after 15s on a congested Polygon. Does createPosition revert if mined past the 15s window? What's the recommended resubmit / re-quote pattern?

F3. Gas for existing Safe users.
A1.3 says only deposit wallets are gasless; Safe/Proxy submitters pay gas. Most of our users are on 1-of-1 Gnosis Safes. Can a partner relayer sponsor the Safe execTransaction gas, and is there a Safe -> deposit-wallet migration path for already-migrated users?

Non-blocking

F4. Settlement payout crediting.
On close/settle/liquidation/void, is result.proceeds_usd auto-credited to the user's wallet, or does the user sign a claim tx?

F5. Partner origination-fee mechanics.
Which address accrues partner_origination_fee_bps, and at what cadence (per-position settle, batched, claimable)? A4.1 describes the field but not the money flow (builder rewards in Q4.3 route through Polymarket — this is the separate partner stream).

F6. Deleveraging event + Socket.IO handshake.
Is there a discrete event (e.g. position.deleveraged / risk.updated) emitted when the J-factor force-unwinds mid-position? And since it's Socket.IO, how is the JWT/API key passed on connect, and what's the resume behavior after a dropped connection?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment