Common Errors
The UMA CTF Adapter uses custom errors for gas efficiency and clarity. Below are all error conditions defined inIUmaCtfAdapter.sol:
NotInitialized
- Calling
resolve(),flag(),reset(),pause(), orgetExpectedPayouts()on a question that hasn’t been initialized - The
questionIDdoesn’t exist in the adapter
- Verify the
questionIDis correct - Check that
initialize()was called successfully - Query
isInitialized(questionID)to confirm state
Initialized
- Attempting to call
initialize()with ancillary data that produces an existingquestionID - The questionID is derived from
keccak256(ancillaryData), so duplicate ancillary data causes this error
- Use unique ancillary data for each question
- Remember that ancillary data includes the creator address appended by the contract
- If you need to re-ask a question, use different ancillary data (e.g., add a nonce or timestamp)
Resolved
- Calling
resolve(),flag(),reset(), orpause()on an already resolved question - Question has
resolved = truein storage
- Check resolution status before attempting operations
- Resolved questions are immutable and cannot be modified
Paused
- Calling
resolve()orgetExpectedPayouts()on a paused question - Questions are paused when
pause()orflag()is called
- Wait for an admin to call
unpause()orunflag() - Check pause status before attempting resolution
Flagged
- Calling
flag()on an already flagged question - Calling
getExpectedPayouts()on a flagged question
- Check flagged status using
isFlagged(questionID) - Wait for admin to resolve manually or unflag
NotFlagged
- Calling
unflag()on a question that isn’t flagged
- Verify the question is actually flagged before attempting to unflag
NotReadyToResolve
- Calling
resolve()when the Optimistic Oracle hasn’t settled the price yet - The OO liveness period hasn’t expired
- No proposer has submitted a price
- Check
ready(questionID)before callingresolve() - Wait for the liveness period to pass after a proposal
- Ensure a price has been proposed on the OO
PriceNotAvailable
- Calling
getExpectedPayouts()when the OO hasn’t settled a price - Similar to
NotReadyToResolvebut for read-only operations
- Wait for the OO to settle the price
- Check
ready(questionID)first
UnsupportedToken
- Calling
initialize()with arewardTokennot on the UMA collateral whitelist - The token address is not approved by UMA governance
- Use a whitelisted token (typically USDC, WETH, or other major tokens)
- Check the UMA collateral whitelist contract
- Query whitelist status:
- USDC:
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48(Ethereum) - Check UMA documentation for network-specific addresses
InvalidAncillaryData
- Ancillary data is empty (length = 0)
- Ancillary data exceeds maximum length (8139 bytes after appending creator)
- Provide non-empty ancillary data
- Keep ancillary data under ~8100 bytes to account for creator address append
- The contract appends the creator address, so total length =
ancillaryData.length + creator_address_bytes
NotOptimisticOracle
- An address other than the Optimistic Oracle calls
priceDisputed()callback - This is a security check to prevent unauthorized resets
- This error shouldn’t occur in normal operation
- If you see this, investigate for potential attack attempts
- Only the OO contract should call the dispute callback
InvalidOOPrice
- The Optimistic Oracle returns a price that isn’t 0, 0.5 ether, or 1 ether
- This indicates an invalid YES_OR_NO_QUERY response
0= NO0.5 ether= UNKNOWN/TIE1 ether= YES
- This shouldn’t happen with correct OO setup
- If it occurs, flag the question for manual resolution
- Investigate the OO proposal and dispute process
InvalidPayouts
- Admin calls
resolveManually()with an invalid payout array - Payout array doesn’t pass validation (wrong length or invalid values)
- Must be length 2:
[YES_payout, NO_payout] - Valid combinations:
[0, 1],[1, 0], or[1, 1]
- Ensure payout array has exactly 2 elements
- Use only 0 or 1 as payout values
- Follow the pattern:
[YES_outcome, NO_outcome]
SafetyPeriodNotPassed
- Admin calls
resolveManually()before the safety period (1 hour) has elapsed - The safety period starts when
flag()is called
- Wait for 1 hour after flagging before manually resolving
- Check
manualResolutionTimestampin the question data
SafetyPeriodPassed
- Admin calls
unflag()after the safety period has passed - Once the safety period expires, the question must be manually resolved
- Unflag questions within 1 hour of flagging, or
- Proceed with manual resolution using
resolveManually()
Debugging Tips
1. Check Question State
Always fetch the full question data when debugging:2. Verify Optimistic Oracle State
Check the corresponding OO request:3. Monitor Event Logs
Enable event monitoring to track state changes:4. Test Transaction Before Sending
UsecallStatic to preview transaction outcomes:
5. Check Token Approvals
If initialization fails with token transfers:6. Decode Ancillary Data
When debugging ancillary data issues:Common Scenarios
Question Won’t Resolve
Symptoms:resolve() call fails or reverts
Checklist:
- ✅ Check
ready(questionID)returnstrue - ✅ Verify question is not paused:
question.paused == false - ✅ Confirm OO has price:
optimisticOracle.hasPrice(...) - ✅ Ensure liveness period has passed
- ✅ Check question isn’t already resolved:
question.resolved == false
Question Was Reset Unexpectedly
Possible causes:-
Dispute occurred - Someone disputed the proposed price
- Check for
priceDisputedcallback in OO logs - Review dispute details on UMA voter dashboard
- Check for
-
Ignore price returned - OO returned
type(int256).min- Indicates the question should be ignored/skipped
- Question will reset and request a new price
-
Admin called reset() - Manual failsafe invocation
- Check for
QuestionResetevent with admin as transaction sender
- Check for
Manual Resolution Required
When flagged:- Admin has called
flag(questionID) manualResolutionTimestampis set- Question is paused
- Wait for safety period (1 hour from flagging)
- Determine correct outcome off-chain
- Call
resolveManually(questionID, payouts)
Token Transfer Failures
Common causes:-
Insufficient allowance - Approve the adapter as spender
-
Insufficient balance - Ensure creator has enough tokens
-
Token not whitelisted - Use a UMA-approved token
Multiple Questions with Same Data
Issue: GettingInitialized() error for what seems like a unique question
Cause: questionID = keccak256(ancillaryData), and ancillary data includes the creator address appended by the contract
Solution:
- Even with the same question text, different creators get different questionIDs
- If the same creator needs to ask the same question twice, add a nonce:
Gas Optimization Issues
High Gas Costs on Initialize
Causes:- Large ancillary data (approaching 8139 byte limit)
- First-time token approval requires additional gas
- CTF condition preparation
- Keep ancillary data concise (reference external data via hash/URL)
- Pre-approve tokens in separate transaction
- Batch multiple initializations if possible
Failed Transaction Due to Gas Limit
Solution:Getting Help
Diagnostic Information to Collect
When reporting issues, include:- Question ID and transaction hash
- Question state from
getQuestion() - Event logs for the question
- OO request state from
optimisticOracle.getRequest() - Network and block number
- Error message or revert reason
Useful View Functions
See Also
- Monitoring Events - Event tracking and interpretation
- Market States - State transitions and flow
- Errors - Complete error catalog