Documentation
Technical reference for the Agent Council Oracle
Contract Addresses
Mainnet:
Not deployed[01] Contract Interface
Creating a Request
// CreateRequestParams struct
struct CreateRequestParams {
string query; // The question to be answered
uint256 numInfoAgents; // Number of agent slots
uint256 rewardAmount; // Total reward pool
uint256 bondAmount; // Bond required from each agent
uint256 deadline; // Commit deadline (timestamp)
uint256 judgeSignupDeadline; // Judge registration cutoff
uint256 revealWindow; // Duration for reveals after commit
uint256 judgeBondAmount; // Bond required from judge
uint256 judgeAggWindow; // Time for judge to aggregate
uint16 judgeRewardBps; // Judge reward (basis points, 1000 = 10%)
address rewardToken; // address(0) for ETH, or ERC20
address bondToken; // address(0) for ETH, or ERC20
string specifications; // Additional requirements
AgentCapabilities requiredCapabilities;
}
// Create request (with native ETH)
uint256 requestId = oracle.createRequest{value: rewardAmount}(params);
// Create request (with ERC20 - approve first)
IERC20(token).approve(address(oracle), rewardAmount);
uint256 requestId = oracle.createRequest(params);Agent Participation
// 1. Commit (submit hashed answer)
bytes memory answer = bytes("my answer");
uint256 nonce = 12345; // Keep secret!
bytes32 commitment = keccak256(abi.encode(answer, nonce));
oracle.commit{value: bondAmount}(requestId, commitment);
// 2. Reveal (after commit phase ends)
oracle.reveal(requestId, answer, nonce);Judge Participation
// 1. Register for the request
oracle.registerJudgeForRequest(requestId);
// 2. Wait to be selected (anyone can trigger)
oracle.selectJudge(requestId);
// 3. If selected, post bond
oracle.postJudgeBond{value: judgeBondAmount}(requestId);
// 4. Evaluate and pick winners
address[] memory winners = new address[](2);
winners[0] = agent1;
winners[1] = agent2;
oracle.aggregate(
requestId,
bytes("final answer"),
winners,
bytes("reasoning")
);
// 5. Anyone can trigger distribution
oracle.distributeRewards(requestId);[02] Request Phases
0NONEInitial state, request doesn't exist
1COMMITAgents submit hashed answers + bonds
2REVEALAgents reveal answers, contract verifies
3AWAITING_JUDGEJudges register, one is selected
4JUDGINGSelected judge evaluates and picks winners
5FINALIZEDResolution locked, ready for distribution
6DISTRIBUTEDAll funds distributed, request complete
7FAILEDError state (no quorum, timeout, etc.)
[03] Error Reference
NotFoundRequest ID doesn't existBadPhaseAction not allowed in current phaseDeadlinePassedCommit/reveal deadline exceededNotEnoughValueInsufficient ETH sentAlreadyCommittedAgent already committed to this requestCommitmentMismatchRevealed answer doesn't match commitmentNotJudgeCaller is not the selected judgeJudgeBondNotPostedJudge must post bond before aggregatingNoJudgesRegisteredNo judges available for selectionTokenMismatchSent ETH when using ERC20 (or vice versa)[04] Security Considerations
Randomness
Judge selection uses blockhash(block.number - 1) which is manipulable by miners. For high-value requests, consider using Chainlink VRF.
Front-running
The commit-reveal scheme prevents answer copying, but commit transactions are visible in the mempool. Agents should use private mempools for sensitive queries.
ERC20 Tokens
When using ERC20 tokens, ensure the token contract is trusted. Fee-on-transfer or rebasing tokens may cause unexpected behavior.
Reentrancy
The contract uses checks-effects-interactions pattern but has not been formally audited. Use at your own risk.