MetalAssertions genesis contract at
0x000000000000000000000000000000000000018c records claims backed by a bond
under a domain’s published rules. A permitted challenger can dispute a claim
during the domain’s challenge window. Once the window ends, anyone can call
settle(id) to settle an unchallenged assertion.
Verified oracle claims are checked and settled when
submitted.
Each domain sets one of three challenge classes:
When a bond is forfeited, half goes to the winner as claimable balance, rounded
down. The remainder is recorded as burned and held permanently by the assertions
contract.
Before you start
Prepare the bond token and its spending approval using the token and spending approval instructions. Fund the signing account’s balance in the gas token using Estimate and record fees, then verify execution and finality for each transaction.Domains
Domains are fixed at genesis.domainIdOf(name) computes the domain ID as
keccak256(name), and domain(id) returns its configuration:
requiredBond(domainId, declaredValue) returns the minimum bond:
max(bondFloor, floor(declaredValue * bondBps / 10000)). A challenge posts the
assertion’s recorded bond, which can exceed that minimum.
Claims
An objective claim identifies a subject whose value can be checked onchain and records the asserter’s proposed value:claimHashOf(kind, subjectA, subjectB, value) computes it on chain.
rulesHash identifies the rules under which the assertion is made. The
assertion ID is
keccak256(abi.encode(domainId, asserter, claimHash, rulesHash, block.number)),
allowing one assertion with those same fields per block. Submit a new assertion
if the claim or rules change.
Asserting and settling
assertClaim(domainId, claimHash, rulesHash, declaredValue, bond)pullsbondof the domain’s token from the caller (approve first) and returns the assertion id, also emitted inAsserted.settle(id)settles an assertion once its window elapsed. Anyone may call it.withdraw(token)pays out everything claimable to the caller.
Settled and Voided are final states. Consumers check status when using an
assertion, and later disputes require a new assertion.
Verified oracle claims
UseassertOracleClaim(domainId, itemId, height, value, rulesHash) for oracle
claims (kind 1). It reads 0xFD.at(itemId, height) in the same call and
reverts with Unreadable if that write is unavailable, WrongValue if the
value differs, or Flagged if any flag is set.
A successful call records the assertion as Settled with verified = true, a
zero bond and declared value, and expiresAt set to the current block time. It
emits Asserted followed by Settled. The claim hash and assertion ID use the
same formulas as assertClaim.
The verified assertion remains after the oracle’s history ring overwrites the
original write. Save its item ID, height, and value so a consumer can recompute
the claim hash and compare it with the verified record.
The domain’s asserter allowlist and suspensions apply across all three
challenge classes. Check verified == true when relying on immediate oracle
verification. A claim submitted through assertClaim is checked only if
challenged.
Objective challenges
challenge(id, proof) takes
proof = abi.encode(kind, subjectA, subjectB, value, actual, siblings): the
claim’s preimage, the value the challenger says the subject has, and for a
Merkle claim the sibling path from actual to the root. siblings is empty for
an oracle claim.
- Contradiction. The assertion is voided, the asserter’s bond is forfeited (half burned, half to the challenger, whose own bond is returned), and the asserter is suspended in the domain.
- Failed proof. An invalid path or proof of the claimed value forfeits the challenger’s bond, with half burned and half claimable by the asserter. The assertion remains open to further challenges until its window ends.
- Unreadable oracle claim. If a claim submitted through
assertClaimnames an unavailable oracle write, a challenge voids it and returns both bonds in full as claimable balances. The challenger must still post its bond, and the asserter remains permitted in the domain. If unchallenged, the assertion can settle after the window ends.
Evidence challenges
In an evidence domain a challenge is a question for the validators:challengeEvidence(id, evidenceURI)posts a bond equal to the asserter’s, names the evidence, marks the assertionChallenged, and lists it inpendingEvidence().- Validators that answer evidence questions add the verdict item
verdictItemOf(id)to the oracle catalog through acatalog/1statement, and attest the verdict there. The item’s name,verdictNameOf(id), isv/followed by the first 14 bytes ofidin hex. The row leaves the catalog once the challenge closes. resolveEvidence(id)applies an undisputed verdict written after the challenge. If none is available after one challenge window, anyone can resolve it asTOO_EARLY.
One challenge per assertion runs at a time.
tooEarly in assertion(id) counts
TOO_EARLY resolutions, including those caused by a missing verdict. The third
such resolution (MAX_TOO_EARLY) voids the assertion and returns both bonds.
Subjective challenges
In a domain that names anarbiter, that address decides challenges.
challengeSubjective(id)posts a bond equal to the asserter’s and marks the assertionChallenged. A challenge from the arbiter reverts withArbiterCannotChallenge.resolveSubjective(id, verdict)lets the arbiter apply a verdict from the table above. After one challenge window, anyone else can call it to resolve the challenge asTOO_EARLY, regardless of the supplied verdict.
WrongChallengeClass: challenge
outside an objective domain, challengeEvidence outside an evidence domain, and
challengeSubjective outside a subjective domain.
Interface
Reads:
Events:
Asserted, Settled, Voided, ChallengeFailed, Withdrawn,
EvidenceChallenged, EvidenceResolved, SubjectiveChallenged,
SubjectiveResolved.
Errors: UnknownDomain, WrongChallengeClass, NotChallenged, NoVerdict,
NotArbiter, ArbiterCannotChallenge, BadVerdict, NotAsserter,
NotChallenger, Suspended, BondTooSmall, TransferFailed,
AlreadyAsserted, NotAsserted, WindowActive, WindowElapsed, BadClaim,
Unreadable, WrongValue, Flagged, NothingToWithdraw.