PolyFrog

Settlement

Reading the outcome without an oracle.

Settlement is the part most prediction markets get complicated. Here it is a function call anyone can make, and it cannot return the wrong answer without the auction itself being wrong.

What resolve does

require(now > market.endBlock);

if (auction.lastCheckpointedBlock() != endBlock) {
    try auction.checkpoint() {} catch {}
}
require(auction.lastCheckpointedBlock() == endBlock);

outcome = auction.isGraduated();

The middle step is the one that matters. checkpoint() is permissionless and, once the auction is over, finalises it precisely at its end block. Only then is the stored comparison the real, final one.

If for any reason the auction cannot be finalised, resolve refuses rather than settling on stale state. It would rather do nothing than pay the wrong side.

The clock

Robinhood Chain is an Arbitrum Orbit chain, and the ArbSys precompile is present. Uniswap’s auction therefore reads its block number from ArbSys.arbBlockNumber(), not from block.number.

PolyFrog vendors the same helper Uniswap uses, so both contracts are on the same clock. A market comparing block.number to an auction’s endBlock would be reading a different instrument than the one it settles against.

Who resolves

Anyone. There is no keeper, no privileged relayer and no fee for doing it — the winning side has the obvious incentive, since nothing can be claimed until it happens. This interface resolves markets as a convenience, but it is not required for the market to work.

Tested against the real chain

The contract’s test suite includes fork tests that point at real auctions on Robinhood Chain mainnet — one that genuinely failed and one that genuinely graduated — and assert that PolyFrog derives the outcome that actually happened.