Solidity: Resolve a Query
Finalize a query after the voting period ends. The oracle selects the highest‑weight answer (by total collateral). If top answers tie, the contract extends the voting window and reverts; retry after the extension.
Requirements:
block.number > currentEndBlock- A single highest-weight answer exists (no tie)
Minimal interface
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IOracleResolve {
function resolveQuery(uint256 queryId) external;
}
Resolve with try/catch helper
Because resolveQuery reverts when it’s too early or a tie is detected, wrap it to return a boolean outcome.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IOracleResolve {
function resolveQuery(uint256) external;
}
contract OracleResolveHelper {
IOracleResolve public immutable oracle;
constructor(address oracle_) {
oracle = IOracleResolve(oracle_);
}
/// @notice Attempt to resolve. Returns false if too early or a tie extends voting.
function tryResolve(uint256 queryId) external returns (bool) {
try this._resolve(queryId) {
return true;
} catch {
return false;
}
}
function _resolve(uint256 queryId) external {
oracle.resolveQuery(queryId);
}
}
Readiness checks (off-chain friendly)
Before calling resolve on-chain, off-chain systems can check currentEndBlock and a helper flag:
getQueryDetails(queryId)returns:currentEndBlock— wait untilblock.number > currentEndBlockinTieExtension— indicates the query is in an extended voting phasecanBeResolved— hint that a clear winner exists once the window is over
Typical flow:
- Read
getQueryDetails(queryId). - If
block.number <= currentEndBlock, wait. - If
inTieExtensionis true, wait for more blocks/votes. - Call
resolveQuery(queryId). If it reverts, re-read details and retry after extension.
Tie handling
On a tie among top answers:
- Contract sets
currentEndBlock = block.number + tieExtensionPeriod() - Emits
VotingExtended(queryId, newEndBlock, uniqueWinners) - Reverts the transaction
Your contract can simply surface a failed attempt (boolean false via the try/catch pattern). Off-chain orchestration (indexers, bots, UIs) should then wait until currentEndBlock and try again.
Post‑resolution data
After a successful resolve:
getQueryDetails(queryId)returnsresolved = truewinningOptionsis the decodeduint8[]that won- Total rewards pot formula (for context to off-chain systems):
totalPot = initialDeposit + (totalCollateral - totalWinningCollateral)
If your contract has a winning vote, proceed to Claim (next page).
Common pitfalls
- Resolving too early: ensure
block.number > currentEndBlock - Ties: expect reverts that extend the window; handle retries gracefully
- Assuming a winner without reading latest state: always re-read
getQueryDetails
Related pages
Back to: