Create a market

To create a market, call one of the four creation functions on the MarketFactory contract. Each function corresponds to a market type; you pass a single CreateMarketParams struct. On success, the function returns the new market contract address (you can also read it from the NewMarket event).


Which function to use

Function
When to use it
Main parameter rules

createCategoricalMarket

Single-choice question (e.g. "Who will win?" β†’ one of A, B, C).

outcomes: β‰₯ 2 labels. No bounds.

createMultiCategoricalMarket

Multi-choice question (e.g. "Which teams qualify?" β†’ any subset).

outcomes: β‰₯ 2 labels. No bounds.

createScalarMarket

Numeric outcome in a range (e.g. "Temperature in Β°C?" between 0 and 50).

outcomes: exactly 2 (e.g. "Lower", "Higher"). Required: lowerBound, upperBound in wei (1e18).

createMultiScalarMarket

Several numeric questions (e.g. one per city).

outcomes: β‰₯ 2 (e.g. city names). Use questionStart, questionEnd, outcomeType to build each question; market name is built from these. No bounds.


Parameters: CreateMarketParams

All four functions take one argument: a struct with the following fields. Optional/conditional fields are noted.

Parameter
Type
Required / notes

marketName

string

Yes (except multi scalar: there it is built from questionStart/outcomeType/questionEnd).

outcomes

string[]

Yes. Categorical/multi categorical: β‰₯ 2. Scalar: exactly 2. Multi scalar: β‰₯ 2.

questionStart

string

Multi scalar only: prefix for each per-outcome question.

questionEnd

string

Multi scalar only: suffix for each per-outcome question.

outcomeType

string

Multi scalar only: placeholder in market name (e.g. "City").

parentMarket

address

Optional. Set for conditional markets; use 0x0 for root markets.

parentOutcome

uint256

Optional. For conditional markets: index of the parent outcome this market depends on.

category

string

Yes. Reality.eth category (e.g. "politics", "weather").

lang

string

Yes. Language code (e.g. "en_US").

lowerBound

uint256

Scalar only. Minimum value in wei (use e.g. parseEther("0")).

upperBound

uint256

Scalar only. Maximum value in wei (e.g. parseEther("50")). Must be > lowerBound.

minBond

uint256

Yes. Minimum bond for answering on Reality.eth (in wei).

openingTime

uint32

Yes. Unix timestamp when the question becomes answerable.

tokenNames

string[]

Yes. ERC20 symbol for each outcome (≀31 chars), one per entry in outcomes.

Getting the new market address: the contract returns it; you can also parse the NewMarket event from the transaction logs.

Struct shape (for ABI / viem):


Viem examples

We use the Viem setup: getPublicClient(chain) and getWalletClient(chain, process.env.PRIVATE_KEY). You need the MarketFactory ABI (create functions + CreateMarketParams tuple + NewMarket event). Addresses come from SEER_CONTRACTS[chain.id].

Shared: ABI and addresses

Helper: build CreateMarketParams (tuple for viem)

1. Create Categorical market (viem)

2. Create Multi Categorical market (viem)

3. Create Scalar market (viem)

Scalar bounds must be in wei (1e18 units). Use parseEther from viem to convert human-readable numbers (e.g. 0 and 50 for a 0–50 Β°C range):

4. Create Multi Scalar market (viem)

Each outcome becomes part of a Reality question: questionStart + outcomes[i] + questionEnd. The market name is questionStart + "[" + outcomeType + "]" + questionEnd.

circle-info

For multi scalar markets, marketName is set to questionStart + "[" + outcomeType + "]" + questionEnd.

Last updated