Document type: Combined architecture + implementation reference (library is small enough to warrant a single doc).
Audience: Developers integrating, testing, or auditing the UMIP-183 decode path.
MultiValueDecoder is a pure Solidity library implementing the UMIP-183 MULTIPLE_VALUES encoding specification. It is used exclusively by BlieverUmaAdapter._decodeAndResolve() to translate the oracle's settled int256 into the uint8 winningOutcome that BlieverMarket.resolve() expects.
It has zero state, zero external calls, and zero side-effects.
The UMA oracle packs up to 7 × uint32 values into a single int256:
int256 layout:
┌──────────────┬────────────┬────────────┬─────┬────────────┐
│ bits 224–255 │ bits 192– │ bits 160– │ … │ bits 0–31 │
│ always 0 │ 223 │ 191 │ │ │
│ (unused) │ outcome6 │ outcome5 │ │ outcome0 │
└──────────────┴────────────┴────────────┴─────┴────────────┘
Value at index i: uint32( (uint256(encodedPrice) >> (32 * i)) & 0xFFFFFFFF )
| Value | Meaning |
|---|---|
type(int256).min |
Too early — proposal was submitted before the event anchor timestamp |
type(int256).max |
Unresolvable — event canceled, ancillary data invalid, or > 7 labels |
For a BlieverMarket with N outcomes, the oracle must return a price where:
- Exactly one slot in
[0, N)equals1(the winning outcome). - All other slots in
[0, N)equal0. - All slots in
[N, 7)equal0(unused labels). - Bits 224–255 equal
0.
Example for a 3-outcome market where outcome 1 wins:
encodedPrice = 1 << 32 = 4294967296
slot[0] = 0, slot[1] = 1, slot[2] = 0 ✓
Returns price == type(int256).min. Call this first before decoding.
Returns price == type(int256).max. Call this second before decoding.
Four validation rules in order:
| Step | Check | Error on failure |
|---|---|---|
| 1 | uint256(encodedPrice) & TOP_BITS_MASK == 0 |
InvalidOracleEncoding(encodedPrice, outcomeCount) |
| 2 | All slots [outcomeCount, MAX_OUTCOMES) equal 0 |
InvalidOracleEncoding(encodedPrice, outcomeCount) |
| 3 | Exactly one slot in [0, outcomeCount) equals 1 |
InvalidOracleEncoding(encodedPrice, outcomeCount) |
| 4 | No slot in [0, outcomeCount) exceeds 1 |
InvalidOracleEncoding(encodedPrice, outcomeCount) |
return uint32((raw >> (32 * index)) & UINT32_MASK);Extracts the uint32 value at the given 0-based index from a packed uint256.