Skip to main content

Encoding

Within Gameday a market is associated with an oracle event and is deployed as separate contract. Markets may have more than two outcomes, so this flexibility is supported with distinct market types and associated encoding rules.

ERC-6909

Market contracts mint and burn ERC-6909 outcome tokens. The token ID is an encoded outcome for the associated event. On settlement, market contract allows winning tokens IDs to be claimed as rewards.

We have included an example python encoding module, which allows for manual encoding. Client order builder integrates this encoding. Market type and number of outcomes is available as part of Market object from REST API.

Bit layout (256 bits, big-endian)

255 - 252251 - 246245 – 241240239 - 0
market type uint4emptyn_outcomes uint5yes/no 1 bitpayload 240 bits

Payload per market type:

  • BINARY - 0: empty (no payload), only yes/no
  • RANKED - 1: N outcome indices packed as uint8 (up to 30 outcomes)
  • TOP - 2: outcomes represented as bits set in payload (up to 30 outcomes)
  • OVERUNDER - 3: outcome_val as int64 (two's complement) in lowest 64 bits
  • EXACT - 4: outcome_val as int64 (two's complement) in lowest 64 bits
  • RANGE - 5: low_bound (int64) in bits 127–64, high_bound (int64) in bits 63-0

Examples

BINARY market type

255 - 252251 - 246245 – 241240239 - 0
market type uint4emptyn_outcomes uint5yes/no 1 bitpayload 240 bits
0000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
# uint256
5300541194335152988749892502228755547482451690626856874364818603877859328

RANKED market type

  • Yes/No: YES,
  • Single outcome
  • Index 2 of candidate outcomes
255 - 252251 - 246245 – 241240239 - 0
market type uint4emptyn_outcomes uint5yes/no 1 bitpayload 240 bits
0001000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010
7240539271461818982632353158044480077861029009396286490382342212897155842050
  • Yes/No: YES,
  • 3 outcomes
  • Indices 2, 0, 3
255 - 252251 - 246245 – 241240239 - 0
market type uint4emptyn_outcomes uint5yes/no 1 bitpayload 240 bits
0001000000000111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000011
7247606659720932519950686348047451751924338944983788966214828637702326452227

Packing Ranked indices

for index, outcome_idx in enumerate(outcome_indices):
payload |= outcome_idx << (8 * (n_outcomes - 1 - index))

Decoding Ranked payload

for index in range(n_outcomes -1, -1, -1):
decoded_payload.append((payload >> (8 * index)) & 0xFF)
>>> [2, 0, 3]

TOP market type

  • Yes/No: YES,
  • 3 outcomes
  • Indices 0, 2, 3 of candidate outcomes
255 - 252251 - 246245 – 241240239 - 0
market type uint4emptyn_outcomes uint5yes/no 1 bitpayload 240 bits
0010000000000111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001101
14484612237053194733923872911090445992753712986586324218680927638196896923661

Packing TOP indices

for outcome_idx in outcome_indices:
payload |= 1 << outcome_idx

Decoding TOP payload

diff = 0 ^ payload
while diff:
idx = (diff & -diff).bit_length() - 1
indices.append(idx)
diff &= diff - 1
>>> [0, 2, 3]

Or simple scan:

for i in range(payload.bit_length()):
if (payload & 1 << 1):
indices.append(i)

Scalar markets

  • Market type: OVERUNDER
  • Yes/No: NO,
  • 1 outcome
  • Outcome value: 74500
255 - 252251 - 246245 – 241240239 - 0
market type uint4emptyn_outcomes uint5yes/no 1 bitpayload 240 bits
0011000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010010001100000100
21714550426126343410578726284130468559519777092601356995314540213886297121540

Decoding scalar types

_UINT64_MASK = (1 << 64) - 1
raw_value = payload & _UINT64_MASK
outcome_value = raw_value if raw_value < (1 << 63) else raw_value - (1 << 64)

RANGE markets

  • Market type: RANGE
  • Yes/No: YES,
  • 1 outcome
  • Low bound: 65000
  • High bound: 75000
255 - 252251 - 246245 – 241240239 - 0
market type uint4emptyn_outcomes uint5yes/no 1 bitpayload 240 bits
0101000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111101111010000000000000000000000000000000000000000000000000010010010011111000
36190328427855646222854682707717199959694352659703304318243224612197585986808

Decoding RANGE

low_bound_raw = (payload >> 64) & _UINT64_MASK
high_bound_raw = payload & _UINT64_MASK
low_bound = low_bound_raw if low_bound_raw < (1 << 63) else low_bound_raw - (1 << 64)
high_bound = high_bound_raw if high_bound_raw < (1 << 63) else high_bound_raw - (1 << 64)