Resolution
Submitting outcomes, evidence, and moving toward finality.
Once closeTime has passed, the market enters Closed and becomes resolvable. Who can submit the
outcome — and how — depends on the resolution mode fixed at creation.
The high-level SDK shape we want is:
await client.markets.submitResolution({
marketAddress,
option: 0,
evidenceUrl: "https://...",
});That wraps the same underlying contract mechanics described below.
SingleAdmin
One address resolves. One call.
await market.submitResolution({
option: 0, // winning option index
evidenceUrl: "https://coingecko.com/en/...", // canonical source
});The SDK hashes the evidence URL (keccak256) and submits both in one transaction. The market
moves to ResolvedPendingFinality and the challenge window opens.
MultiAdmin
Resolution is two phases. Admins vote first, then any admin commits the winning option once quorum is reached.
Phase 1 — voting
// Each admin casts one vote:
await market.voteForResolution(0); // admin 1 votes "Yes"
await market.voteForResolution(0); // admin 2 votes "Yes" — quorum (2 of 3) now reached- Each admin votes once; repeat votes revert.
- Votes must point at the same option index to count toward quorum for that option.
- When an option accumulates
quorumvotes, the contract flags that option as ready to submit.
Phase 2 — committing
Once quorum is reached, any admin calls submitResolution with the winning option and evidence:
await market.submitResolution({
option: 0,
evidenceUrl: "https://...",
});The evidence is submitted by whichever admin commits — not collectively.
If admins disagree and no option reaches quorum, the market stays in Closed indefinitely. The
contract has no automatic timeout; hosts typically surface "needs resolution" prompts to
stakeholders off‑chain.
AiOracle
Mechanically identical to SingleAdmin on‑chain — one admin, quorum === 1. The distinction is
organizational: the admin address is held by an off‑chain AI service that fetches evidence from
configured sources and signs the transaction. See
oracles for how to wire this up.
Evidence and its hash
Evidence is a URL the resolver publishes alongside the outcome. The contract stores
keccak256(evidenceUrl) as evidenceHash — an anchor so the URL text cannot be silently
altered after submission. The hash isn't validated against the URL's content; participants
inspect the URL during the challenge window and dispute if it doesn't justify the outcome.
The SDK computes the hash for you. If you need to submit the raw arguments manually (e.g. from an air‑gapped signer), the contract expects:
import { keccak256, toHex } from "viem";
const evidenceHash = keccak256(toHex(evidenceUrl)); // what `submitResolution` sendsevidenceUrl must be non‑empty and evidenceHash must equal keccak256(bytes(evidenceUrl)) —
the contract rejects mismatches to prevent accidental typos between UI and on‑chain state.
Watching events
const stop = client.markets.watchMarketEvent(
marketAddress,
"ResolutionSubmitted",
(logs) => {
for (const log of logs) console.log("resolved:", log);
},
);
stop();Available event names: "BuyIn", "MarketClosed", "AdminVoteSubmitted",
"ResolutionSubmitted", "DisputeSubmitted", "MarketVoided", "MarketFinalized",
"FeesPaid", "Redeemed", "Refunded".
After resolution, client.markets.get(marketAddress) should return challengeDeadline as a
Date you can render directly.
What resolution does not do
- Resolution does not transfer funds. Payouts happen at
finalizeMarket+redeem. - Resolution is not reversible on‑chain. The only way to undo it is for participants to dispute and void the market.
- Resolution does not validate the evidence URL's content. That's on the resolver and the dispute mechanism.