Contestations

Contestations represent arguments over the validity of proposed solutions

The Contestation Model

A contestation is a challenge to a potentially invalid solution. It tracks the disputed task, the voting process, and all data needed to resolve whether the solution should be accepted or rejected.

Properties

  • Name
    validator
    Type
    address
    Description

    Validator that provided solution

  • Name
    blocktime
    Type
    uint64
    Description

    Unix timestamp of solution submission.

  • Name
    finish_start_index
    Type
    uint32
    Description

    What index position to start iteration at for dispersement of value from contestation

  • Name
    slashAmount
    Type
    uint256
    Description

    Amount to slash from losing voters (V6+)


Master Contester System (V6+)

What are Master Contesters?

Master contesters are authorized validators who:

  • Can initiate contestations on suspicious solutions
  • Receive +50 vote weight (configurable via masterContesterVoteAdder)
  • Must maintain minimum validator stake requirements
  • Are managed through the Master Contester Registry contract

Why Master Contesters?

The master contester system provides:

  • Rapid response to invalid solutions
  • Quality protection for model reputation and token value
  • Specialized expertise in detecting fraud
  • Community oversight through the suggestion mechanism

Anyone can suggest a contestation via suggestContestation(), but only master contesters can officially initiate them.


READEngine

Retrieve contestation

Look up a contestation given a taskid.

Request

CALL
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/EngineV1.sol/EngineV1.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  provider,
)
const contestation = await engine.contestations(taskId);
const { validator, blocktime, finish_start_index } = contestation;

WRITEEngine

Suggest contestation (V6+)

This function doesn't create an actual contestation - it only emits an event that master contesters can monitor. This allows the community to participate in quality control without requiring master contester privileges.

Suggested contestations must meet the same timing requirements as regular contestations (before minClaimSolutionTime expires).

Request

WRITE
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/V2_EngineV6.sol/V2_EngineV6.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const wallet = new ethers.Wallet(
  process.env.PRIVATE_KEY,
  provider,
);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  wallet,
)

const taskid = 'task id to suggest contestation for'

const tx = await engine.suggestContestation(taskid)
const receipt = await tx.wait()

// Listen for ContestationSuggested event

WRITEEngine

Submit contestation (Master Contesters Only - V6+)

A contestation may be submitted when a master contester detects a submitted solution to a task is invalid.

Contestations freeze the claiming process for a solution, and initiate a binary vote. The master contester receives a vote weight bonus (default +50 votes) to help ensure quick resolution.

Whichever side loses, each forfeits the current slashAmount. This is distributed to the winners, in which the first voter (the original solver or contestor) receives 50% of the rewards, with the other winning voters receiving equal shares of the remaining slashed funds.

If the contestor wins, the task submitter is refunded their fee they paid.

If the contestor loses, the original solver automatically collects their normal fee and reward.

Internally, submitting adds you as a vote for, and the original submitter against, the contestation.

Requirements:

  • Must be registered as a master contester
  • Must maintain minimum validator stake

Request

WRITE
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/V2_EngineV6.sol/V2_EngineV6.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const wallet = new ethers.Wallet(
  process.env.PRIVATE_KEY,
  provider,
);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  wallet,
)

const taskid = 'task id we are contesting'

// Only works if wallet is a master contester
const tx = await engine.submitContestation(taskid)
const receipt = await tx.wait()

WRITEEngine

Vote on contestation

Validators may vote on whether or not they agree with a contestation within CONTESTATION_VOTE_PERIOD_TIME. This will lock slashAmount of your staked tokens until the vote is finished. If you win, you will receive these back in staked balance.

Request

CALL
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/EngineV1.sol/EngineV1.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const wallet = new ethers.Wallet(
  process.env.PRIVATE_KEY,
  provider,
);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  wallet,
)

const taskid = 'task id to contest'
const agreeWithContest = true;
const tx = await engine.voteOnContestation(taskid, agreeWithContest);
const receipt = await tx.wait();

WRITEEngine

Finish contestation

Once CONTESTATION_VOTE_PERIOD_TIME is over, votes are closed, and anyone can finish the contestation. Because the vote information is in a list, you must pass in an amnt_ for how many rows to process. This will distribute all slashed funds, fees, and restore slashed amounts for winners of the vote.

Request

CALL
Engine
import { ethers } from 'ethers'
import Config from './config.json'
import EngineArtifact from './artifacts/EngineV1.sol/EngineV1.json';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);

const wallet = new ethers.Wallet(
  process.env.PRIVATE_KEY,
  provider,
);

const engine = new ethers.Contract(
  Config.engineAddress,
  EngineArtifact.abi,
  wallet,
)

const taskid = 'task id to finish'
const iterations = 10; // adjust based on votes/pagination
const tx = await engine.contestationVoteFinish(taskid, iterations);
const receipt = await tx.wait();