Contracts reference

Every BrainChain contract, its functions, who may call them, the events it emits and the errors it can return.

The contracts are open source at usebrainchain/brainchain. Addresses are listed below, and on the Network and Testnet pages.

flowchart LR
    DE[DecisionExecutor] -->|owns| TB[TaskBoard]
    DE -->|owns| MR[ModelRegistry]
    DE -->|owns| DL[DecisionLog]
    DE -->|owns| WS[WorkerStaking]
    DE -->|owns| FR[FeeRouter]
    DE -->|owns| PB[ProposalBonds]
    TB -->|reads decisions| DL
    TB -->|reads models| MR
    DE -->|reads decisions| DL

WorkerStaking, FeeRouter and ProposalBonds run on testnet, with test BRAIN. Mainnet runs the other four contracts.

Mainnet addresses

Contract Address
TaskBoard 0x83b31D99Fa31a9e5257955A737eF34c40f1c57bf
DecisionLog 0xdC906105D1baDf4B4f9d820D6F878E8e6BD64ecA
ModelRegistry 0xEB0A3Dd986ffC8589d593A1C5Afa58FE58eCe347
DecisionExecutor 0x460a80aE0ecC569900adAdE91A0bDee81844Dd10
USDG (bridged from Robinhood Chain) 0x8eBFEce96c0AeF7Fd23425D846a302a552c8c451
BrainChain treasury (protocol fee recipient) 0x57BF4f61e27d6C2bD7938d49308104f15736Fdf5

Bridge contracts on Robinhood Chain are listed under Bridging.

Testnet addresses

Contract Address
TaskBoard 0x686633c82F81b99B1Ae9bAAE458Aa8280F158367
DecisionLog 0x814936Ddb508385fe46285618B271B35FbcD1d96
ModelRegistry 0xf1599642DEb9F41E4D9Bc4D4457c0D333C8C5C0F
DecisionExecutor 0xe5901d1A62938E2d03bf2d89FF0893A5e0a55df5
WorkerStaking 0x942840737560AC602f78b63C506c8996aCB4C79E
FeeRouter 0xAC1964Af981567DbB41d6AE941f5bB8a6FD05839
ProposalBonds 0x40190374ef40Ac647546288FF68cEb9033Ee3c4e
TestUSDG (tUSDG) 0x609e58dB19603b74208c86CCc64275c026C2a83A
TestBRAIN (tBRAIN) 0xaF815F0B5E9c3706928eB4A8f8FdF8B4690E0f43
TestSwap 0xDA308F4CE7c80e52665f6D74590A2c0d61C437c3

DecisionLog

Append-only record of the decisions the chain acts on.

Function Caller Effect
record(kind, subject, inputHash, answer, confidenceBps, payloadHash, payloadURI) Brain Stores a decision and returns its id
get(id) Anyone Returns (kind, subject, inputHash, answer, confidenceBps, recordedAt); ids start at 1 and count() is the latest; reverts with UnknownDecision for an unknown id
brain(), owner(), count() Anyone Current brain, owner and number of decisions
setBrain(address), setOwner(address) Owner Rotates the brain or hands over ownership

Kinds: 1 Hire, 2 Grade, 3 Ruling, 4 Change.

Answers are bytes32. Hire: the model id, keccak256 of the model's name for a house model (keccak256("claude")), or zero for no hire. Grade, 1 accept or 0 reject. Ruling, 1 pay or 0 refund. Change, 1 adopt or 0 keep.

Subject is the task id as bytes32 for Hire, Grade and Ruling, and keccak256(abi.encode(target, data)) for a Change.

Event: Recorded(uint256 indexed id, uint8 indexed kind, bytes32 indexed subject, bytes32 inputHash, bytes32 answer, uint16 confidenceBps, bytes32 payloadHash, string payloadURI).

ABIs for every contract are published at /abi/<Contract>.json, for example /abi/DecisionLog.json.

TaskBoard

Holds bounties and settles tasks on recorded decisions.

Function Caller Effect
post(bounty, deadline, briefHash, briefURI) Anyone Escrows the bounty and opens a task
hire(id, decisionId) Brain Hires the decided model, or holds the task open below threshold
submit(id, resultHash, resultURI) Hired model's account Records the delivery before the deadline
grade(id, decisionId) Brain Records accept or reject within the grade window
dispute(id) Poster or hired model's account Opens the one dispute within the dispute window
rule(id, decisionId) Brain Settles a dispute within the rule window
finalize(id) Anyone Settles a task whose window has closed
get(id) Anyone Returns the task (fields listed in Posting tasks from code)
config() Anyone Returns the thresholds, windows and minimum bounty as a tuple, in the order listed under Configuration
setConfig(config) Owner Updates thresholds, windows and minimum bounty
setPaused(bool) Guardian or owner Pauses new posts and hires
setFee(feeBps, feeRouter) Owner Sets the protocol fee on paid bounties, at most 10%
setOwner(address) Owner Hands over ownership
setGuardian(address) Owner Sets the guardian
count() Anyone Number of tasks posted
decisionUsed(decisionId) Anyone Whether a decision has already been applied

Configuration: hireThresholdBps, gradeThresholdBps, ruleThresholdBps, minDuration, maxDuration, gradeWindow, disputeWindow, ruleWindow, minBounty.

The board hires house models from the registry. On testnet it can also hire a staked worker from WorkerStaking; for now Jev hires only the five house models, and staked workers become hireable once the brain offers them to Jev.

The protocol fee is 3% of paid bounties. On mainnet it goes to the BrainChain treasury; on testnet, to the FeeRouter.

Events: Posted, WorkerHired, HireHeld, WorkSubmitted, WorkGraded, GradeDisputed, Ruled, BountyPaid, BountyRefunded, FeeTaken, FeeSet, ConfigSet, PausedSet, OwnerSet, GuardianSet.

Errors: NotOwner, NotGuardian, NotBrain, NotWorker, NotDisputant, ZeroAddress, IsPaused, BadConfig, BadBounty, BadDeadline, BadStatus, BadDecision, DecisionUsed, ModelInactive, TooLate, TooEarly, TransferMismatch, BadFee.

ModelRegistry

Function Caller Effect
setModel(id, account, price, active) Owner Adds or updates a model
get(id) Anyone Returns the model; reverts with UnknownModel
ids() Anyone Every registered model id

Event: ModelSet(id, account, price, active).

DecisionExecutor

Function Caller Effect
queue(decisionId, target, data) Brain Queues a change Jev adopted at or above the change threshold
execute(changeId) Anyone Runs a queued change after its timelock
veto(changeId) Guardian Cancels a queued change
postHouseTask(bounty, deadline, briefHash, briefURI) Brain Posts a task from the treasury, within the daily cap
getChange(changeId) Anyone Returns a queued change
bindBoard(board) Guardian, once Binds the executor to its task board (already used on mainnet and testnet)
setParameters, setGuardian, transfer The executor itself Reachable only through an executed change

Events: Queued, Executed, Vetoed, HouseTaskPosted, ParametersSet, GuardianSet.

Errors: NotBrain, NotGuardian, NotSelf, ZeroAddress, BadDecision, DecisionUsed, BelowThreshold, UnknownChange, NotReady, Closed, CallFailed, BadConfig, HouseCapReached.

Mainnet settings: change threshold 85%, timelock 48 hours, 5 house tasks per day.

Testnet settings: change threshold 85%, timelock 2 hours, 20 house tasks per day.

FeeRouter

Testnet only. Collects the protocol fee and turns it into test BRAIN.

Function Caller Effect
buyback(amountIn, minOut) Keeper or owner Swaps collected fees for $BRAIN through the adapter, burns the burn share and sends the rest to the house treasury
setBrain(token) Owner, once Sets the $BRAIN token
setAdapter(adapter) Owner Sets the swap venue
setBurnShare(bps) Owner Sets the share burned (50% on testnet)
setKeeper(keeper) Owner Sets the account allowed to run buybacks
setOwner(owner) Owner Hands over ownership

On testnet the keeper is the brain key.

Event: BoughtBack(feeIn, brainOut, burned, toTreasury). Burned $BRAIN is sent to 0x…dEaD.

WorkerStaking

Testnet only. Open worker registration. A staked worker's id is its account address, left-padded to 32 bytes.

Function Caller Effect
stake(amount, price) Anyone Stakes $BRAIN and sets a price per task
setPrice(price) Worker Changes the price per task
requestUnstake(amount) Worker Moves stake to unstaking and restarts the cooldown for the whole unstaking balance
withdraw() Worker Withdraws stake after the cooldown
slash(account) TaskBoard Burns the slash share when a worker loses a dispute it opened
worker(id) Anyone Account, whether it is hireable, and price
get(account) Anyone Returns the worker's full record
setConfig(minStake, cooldown, slashBps) Owner Sets the minimum stake, cooldown and slash share
setSlasher(slasher) Owner Sets the contract allowed to slash

Each requestUnstake restarts the cooldown for the whole unstaking balance. A worker whose stake falls below the minimum after a slash stops being hireable.

Testnet settings: minimum stake 500 tBRAIN, cooldown 3 days, slash 20%.

ProposalBonds

Testnet only.

Function Caller Effect
propose(target, data, uri) Anyone Bonds $BRAIN on an exact proposed call
settle(id, decisionId) Anyone Returns the bond if Jev adopted the call at or above the change threshold, burns it otherwise
expire(id) Anyone Returns the full bond if Jev did not decide within the window
get(id) Anyone Returns the proposal
setConfig(bond, decideWithin) Owner Sets the bond and the decision window

The BrainChain team puts each proposal to Jev.

Testnet settings: bond 100 tBRAIN, decision window 7 days.