Let's consider a question where only one out of multiple choices may be chosen:
Will war in Ukraine stop in 2024?
Yes
No
Prerequisites
Client-side code samples will be written in JavaScript assuming the presence of ethers library. We will also use a forked Gnosis chain. We will need sDai address from GnosisRouter:
To create this market, one can run the following code:
After the call, we will create a Market contract, which address is stored in MarketFactory.
Since this is the first market we created, we can access its address at index 0.
Split position
We will then call splitFromBase to deposit our collateral token (sDai) and receive ERC20 outcome tokens. In this case, we will receive 3 sets of tokens: YES, NO, INVALID_RESULT (INVALID_RESULT is default for every market):
Parameters:
market: The market to split.
After the call, we will have ERC20 outcome tokens, ready to be traded.
Answer Reality Question
After the opening time, Reality question can be answered. You can learn more about how Reality works here. Basically, it allows multiple players to provide answers for a question in a decentralized manner, and the final correct answer will be rewarded:
Resolve the market
After the answer is finalized, we can resolve the market:
This will calculate payouts for every outcomes and send the result to ConditionalTokens. In this case, since the finalized answer is 0, the payouts will be [1,0,0]. It means that outcome tokens at index 0 can be redeemed for full amount collateral, while outcome tokens at index 1 and 2 will be redeemed for zero amount.
Redeem positions
A user with ERC20 outcome tokens can redeem their winning positions for collateral token (sDai in this case). For example, if you want to redeem YES tokens only, you can pass an array that contains only outcome index 0.
Parameters:
market: The market to split.
outcomeIndexes: An array of outcome indexes you want to redeem.
await marketFactory.createCategoricalMarket({
marketName: "Will war in Ukraine stop in 2024?",
category: "misc",
lang: "en_US",
parentOutcome: 0 // only used in conditional market,
parentMarket: "0x0000000000000000000000000000000000000000", // only used in conditional market
questionStart: "", // only used in multi-scalar
questionEnd: "", // only used in multi-scalar
outcomeType: "", // only used in multi-scalar
outcomes: ["Yes", "No"],
lowerBound: 0, // only used in scalar
upperBound: 0, // only used in scalar
minBond: "1000",
openingTime: 1735603200, //2024-12-31T00:00:00.000Z
tokenNames: ["YES", "NO"],
})
await realitio.submitAnswer(
questionId,
ethers.toBeHex(BigInt(0), 32), // answer slot. Yes: 0 | No: 1 | Invalid: 2. We choose 0 in this case.
0, // max_previous. If specified, reverts if a bond higher than this was submitted after you sent your transaction.
{
value: "1000", //the bond for this answer, must be higher than the current bond
}
);
await realityProxy.resolve(market);
await gnosisRouter.redeemToBase(
market,
[0], // array of outcome indexes,
[1000n], // array of redeem amounts
);