Committee Prediction Market Skills

Call guide and state-machine conventions for the committee-based prediction market built from GouGouBiMarketFactory, GouGouBiMarketProposal, and GouGouBiMarketCondition, including how to create proposals and conditions, run activation/settlement/dispute voting, and perform CPMM trading and redemption. Use this skill when an Agent needs to handle operations like "create proposal", "committee", "condition", "activation vote", "settlement vote", "dispute", "supreme committee", "redeem", or "buy YES/NO", and when the next call depends on the condition status.

Audits

Pending

Install

openclaw skills install committee-prediction-market-skills

Committee-based prediction market (Agent call conventions)

1. Deployment information

  • Network: BSC mainnet (Binance Smart Chain, chainId = 56)
  • Factory contract file: GouGouBiMarketFactory.sol
  • Factory contract address: 0x7b0B72e620368d8037406AaDB416e62b6e20f6ac
  • Staking token (DOGE / 狗狗币): 0xb05678Ed0c9559955559DE864829a0c8AF574444 — DOGE is 狗狗币 (Dogecoin). All proposal/supreme committee stakes and vote locks use this token (18 decimals). Caller must approve the Factory (or transfer DOGE) before proposeMarketCreation and stakeForProposalCommittee.
  • Proposal / Condition contracts: created as minimal clones by the Factory

Assumptions when calling:

  • You are already connected to a BSC mainnet RPC (for example https://bsc-dataseed.binance.org)
  • Account balance and gas settings are handled by the caller

2. When to use this Skill

  • User or workflow requests: create proposal, join committee, create condition, activation vote, settlement vote, initiate dispute, supreme committee arbitration, redeem, buy YES/NO, add liquidity.
  • Next step depends on condition status: read Proposal.conditionStatus(conditionContract) first, then decide which contract and method to call.
  • Writing or debugging scripts, OpenClaw workflows, or frontends that involve call order and preconditions for the three contracts above.
  • Subgraphs or indexers that treat Proposal as the authoritative source for status and results.

3. Contract paths

RoleContract fileDescription
FactoryGouGouBiMarketFactory.solCreate proposals, committee/supreme committee staking, dispute arbitration, reward claiming
ProposalGouGouBiMarketProposal.solOne clone per proposal; condition creation, activation/settlement voting, dispute, state transitions
ConditionGouGouBiMarketCondition.solOne clone per condition; trading, liquidity, redeem

Convention: Factory / Proposal / Condition addresses are supplied by upper-layer config (e.g. OpenClaw parameters, environment variables).


4. Minimum limits and constants (from contracts)

All stake and lock amounts below are in DOGE(狗狗币 / Dogecoin) (18 decimals). Values are taken from the deployed Factory and Proposal contracts.

4.1 Factory constants

ConstantValueMeaning
MIN_STAKE_AMOUNT10 * 1e18 (10 DOGE)Minimum stake for proposeMarketCreation(..., stakeAmount) and minimum per stakeForProposalCommittee(proposal, amount) when committee has < 3 members.
COMMITTEE_MIN_SIZE3Minimum number of committee members before the proposal can create conditions.
Committee stake when fullamount >= avgStake * 2When the committee already has ≥ 3 members, a new joiner must stake at least twice the current average stake per member. Use factory.getProposalCommitteeMinStakeToJoin(proposal) to get (minStakeToJoin, isFull).
SETTLEMENT_BOND_MIN10 * 1e18 (10 DOGE)Minimum lockAmount for conditionSettlementVoteLock(conditionContract, result, lockAmount) and voteOnConditionResult(..., lockAmount).
DISPUTE_BOND_MIN10 * 1e18 (10 DOGE)Minimum lockAmount for initiateDispute(conditionContract, evidence, lockAmount).
SUPREME_GOVERNANCE_MIN_LOCK_AMOUNT10 * 1e18 (10 DOGE)Minimum lockAmount for voteConditionDisputeSupreme(conditionContract, result, lockAmount).
SUPREME_MIN_STAKE_AMOUNT100 * 1e18 (100 DOGE)Minimum stake for stakeForSupremeCommittee(amount).
GOVERNANCE_SIZE21Number of supreme committee governance members (top 21 by stake) who can call voteConditionDisputeSupreme.

4.2 Proposal time windows

ConstantValueMeaning
SETTLEMENT_VOTE_WINDOW_SECONDS600 (10 min)Settlement vote is allowed until conditionDeadline + 600. After that, if there are votes, status can move to DISPUTED.
DISPUTE_WINDOW_SECONDS600 (10 min)Dispute can be initiated until conditionDeadline + SETTLEMENT_VOTE_WINDOW_SECONDS + DISPUTE_WINDOW_SECONDS. After that, checkConditionStatus can set SETTLED or DISPUTED_INITIATED.
Activation threshold2/3Condition activation: voteOnConditionActivation(conditionContract, approve) — need 2/3 of committee to approve to reach ACTIVE, or 2/3 to reject for REJECTED.
Dispute → DISPUTED_INITIATEDTotal dispute bonds ≥ 1/10 of winning side’s settlement bondsAfter the dispute window ends, if disputeInitiatorTotalBondAmount >= (settlementYesTotalBonds or settlementNoTotalBonds, depending on committee result) / 10, status becomes DISPUTED_INITIATED; otherwise SETTLED (dispute bonds released).

4.3 Condition fees (GouGouBiMarketCondition)

ConstantValueMeaning
TRADING_FEE_BPS30 (0.30%)Buy fee (buyYes / buyNo).
SELL_FEE_BPS100 (1%)Sell fee (sellYes / sellNo).
COMMITTEE_REDEEM_FEE_BPS100 (1%)Share of redeem pool to committee winners.
SUPREME_COMMITTEE_REDEEM_FEE_BPS30 (0.30%)Share of redeem pool to supreme committee.
LpType0 = FEE (稳健), 1 = RISK (风险)For addLiquidity(amount, lpType).

Flow overview (steps + decision points)

[1] Factory.proposeMarketCreation(...)  → get proposalAddress
[2] Factory.stakeForProposalCommittee(proposalAddress, amount)  → at least 3 members
[3] Proposal.createConditions(...)  → get conditionContract from events/conditionContracts
[4] Proposal.voteOnConditionActivation(conditionContract, approve)  → 2/3 approve → status=ACTIVE(1)
     │
     ▼
[5] If status==ACTIVE and tradeDeadline>now:
    Condition.addLiquidity(amount, lpType) / buyYes / buyNo / sellYes / sellNo / swap*
    If deadline passed: go to [6]
[6] Committee Proposal.conditionSettlementVoteLock or voteOnConditionResult
    Anyone Proposal.checkConditionStatus(conditionContract)
    ├─ Past settlement window with votes → status=DISPUTED(4)
    └─ Still ACTIVE → continue [5] or wait
[7] If status==DISPUTED, within dispute window:
    Proposal.initiateDispute(conditionContract, evidence, lockAmount)
    Anyone checkConditionStatus(conditionContract)
    ├─ Past dispute window, no dispute → SETTLED(7)
    ├─ Past dispute window, dispute stake≥1/10 → DISPUTED_INITIATED(5)
    └─ Otherwise keep waiting
[8] If status==DISPUTED_INITIATED:
    Factory.voteConditionDisputeSupreme(conditionContract, result, lockAmount)
    When satisfied, internally calls Proposal.resolveConditionByFactory → SETTLED(7)
[9] If status==SETTLED:
    Condition.redeem() / Condition.claimLp()
    Claim committee/supreme committee rewards on Factory

Decision points:

  • Trading/liquidity: Proposal.conditionStatus(cond)==1 and Condition.tradeDeadline()>block.timestamp.
  • Settlement vote window: conditionDeadline + 600 (10 min).
  • Dispute window: conditionDeadline + 600 + 600 (20 min after condition deadline).
  • Status authority: always use Proposal.conditionStatus(conditionContract); do not rely on Condition alone.

Condition status (authority on Proposal)

EnumNameAllowed actions
0CREATEDActivation vote only; 2/3 approve→ACTIVE, reject→REJECTED
1ACTIVETrading, add/remove LP, committee settlement vote; past settlement window + votes→DISPUTED
2REJECTEDNo longer used
4DISPUTEDinitiateDispute; after dispute window checkConditionStatus → SETTLED or DISPUTED_INITIATED
5DISPUTED_INITIATEDSupreme committee voteConditionDisputeSupreme; when satisfied → SETTLED
7SETTLEDredeem, claimLp; committee/supreme committee claim rewards

Common Agent tasks (contract.method + constraints)

TaskContractMethodConstraints
Create proposalFactoryproposeMarketCreation(liquidityToken, proposalName, deadline, imageUrl, rules, timezone, language, groupUrl, tags, stakeAmount)stakeAmount ≥ 10 DOGE (1e19); approve Factory for DOGE first; returns proposalAddress
Committee expandFactorystakeForProposalCommittee(proposal, amount)amount ≥ 10 DOGE; if committee already ≥3, amount ≥ 2× avg stake (use getProposalCommitteeMinStakeToJoin)
Create conditionProposalcreateConditions(conditionName, deadline, tradeDeadline, conditionImageUrl, rules, isNormalized)Caller must be proposal committee member; committee ≥ 3
Activation voteProposalvoteOnConditionActivation(conditionContract, approve)status==CREATED; 2/3 approves → ACTIVE, 2/3 rejects → REJECTED
Read statusProposalconditionStatus(conditionContract)Authoritative; read first then decide next call
Advance statusProposalcheckConditionStatus(conditionContract)Anyone can call; updates status by time and votes
Settlement voteProposalconditionSettlementVoteLock(conditionContract, result, lockAmount) or voteOnConditionResult(conditionContract, result, evidence, lockAmount)result: 1=YES, 2=NO; lockAmount ≥ 10 DOGE; within conditionDeadline+600
Initiate disputeProposalinitiateDispute(conditionContract, evidence, lockAmount)status==DISPUTED; lockAmount ≥ 10 DOGE; within dispute window (deadline+1200)
Supreme committee voteFactoryvoteConditionDisputeSupreme(conditionContract, result, lockAmount)Caller in top 21 governance; result 1=YES, 2=NO; lockAmount ≥ 10 DOGE
Add liquidityConditionaddLiquidity(amount, lpType)status==ACTIVE, tradeDeadline>now; lpType 0=FEE, 1=RISK
Buy/sell/swapConditionbuyYes(tokenIn, minYesOut)/buyNo/sellYes/sellNo/swapYesForNo/swapNoForYesstatus==ACTIVE, tradeDeadline>now
RedeemConditionredeem() / claimLp()status==SETTLED

Pre-call checklist

  • Use Proposal.conditionStatus(conditionContract) for status; do not read Condition only.
  • Trading/liquidity: Condition.tradeDeadline() > block.timestamp and status==ACTIVE.
  • Settlement window: conditionDeadline + 600 (10 min); dispute window: +600 (10 min) after that.
  • Minimum amounts: proposal/committee stake ≥ 10 DOGE (1e19 wei); when committee has ≥3 members, new joiner needs ≥ 2× average stake. Settlement/dispute/supreme lock ≥ 10 DOGE each.
  • Create condition, activation, settlement vote: proposal committee members only; dispute arbitration: supreme governance members (top 21 by stake); redeem/claimLp: only after SETTLED.
  • Staking token: DOGE at factory.dogeToken(); approve Factory before proposeMarketCreation and stakeForProposalCommittee.

ABI source and common fragments

Full ABI (recommended for production/subgraph):

  • Factory: subgraph/abis/GouGouBiMarketFactory.json
  • Proposal: subgraph/abis/GouGouBiMarketProposal.json
  • Condition: subgraph/abis/GouGouBiMarketCondition.json

Below is a minimal ABI of commonly used methods and key events for Agents; use with ethers/viem (deduplicate when merging with full ABI).

GouGouBiMarketFactory (common)

[
  {"type":"function","name":"proposeMarketCreation","inputs":[{"name":"liquidityToken","type":"address"},{"name":"proposalName","type":"string"},{"name":"deadline","type":"uint256"},{"name":"imageUrl","type":"string"},{"name":"rules","type":"string"},{"name":"timezone","type":"string"},{"name":"language","type":"string"},{"name":"groupUrl","type":"string"},{"name":"tags","type":"string[]"},{"name":"stakeAmount","type":"uint256"}],"outputs":[{"name":"proposalAddress","type":"address"}],"stateMutability":"nonpayable"},
  {"type":"function","name":"stakeForProposalCommittee","inputs":[{"name":"proposal","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"getProposalCommitteeMembers","inputs":[{"name":"proposal","type":"address"}],"outputs":[{"name":"","type":"address[]"}],"stateMutability":"view"},
  {"type":"function","name":"voteConditionDisputeSupreme","inputs":[{"name":"conditionContract","type":"address"},{"name":"result","type":"uint8"},{"name":"amount","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"MIN_STAKE_AMOUNT","inputs":[],"outputs":[{"type":"uint256"}],"stateMutability":"view"},
  {"type":"function","name":"COMMITTEE_MIN_SIZE","inputs":[],"outputs":[{"type":"uint256"}],"stateMutability":"view"},
  {"type":"function","name":"getProposalCommitteeMinStakeToJoin","inputs":[{"name":"proposal","type":"address"}],"outputs":[{"name":"minStakeToJoin","type":"uint256"},{"name":"isFull","type":"bool"}],"stateMutability":"view"},
  {"type":"function","name":"dogeToken","inputs":[],"outputs":[{"type":"address"}],"stateMutability":"view"},
  {"type":"event","name":"ProposalCreatedWithStake","inputs":[{"indexed":true,"name":"proposer","type":"address"},{"indexed":true,"name":"proposal","type":"address"},{"indexed":false,"name":"stakeAmount","type":"uint256"}]}
]

GouGouBiMarketProposal (common)

[
  {"type":"function","name":"createConditions","inputs":[{"name":"_conditionName","type":"string"},{"name":"_deadline","type":"uint256"},{"name":"_tradeDeadline","type":"uint256"},{"name":"_conditionImageUrl","type":"string"},{"name":"_rules","type":"string"},{"name":"_isNormalized","type":"bool"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"voteOnConditionActivation","inputs":[{"name":"conditionContract","type":"address"},{"name":"approve","type":"bool"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"conditionStatus","inputs":[{"name":"conditionContract","type":"address"}],"outputs":[{"name":"","type":"uint8"}],"stateMutability":"view"},
  {"type":"function","name":"conditionResult","inputs":[{"name":"conditionContract","type":"address"}],"outputs":[{"name":"","type":"uint8"}],"stateMutability":"view"},
  {"type":"function","name":"conditionDeadline","inputs":[{"name":"conditionContract","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
  {"type":"function","name":"checkConditionStatus","inputs":[{"name":"conditionContract","type":"address"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"conditionSettlementVoteLock","inputs":[{"name":"conditionContract","type":"address"},{"name":"result","type":"uint8"},{"name":"lockAmount","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"voteOnConditionResult","inputs":[{"name":"conditionContract","type":"address"},{"name":"result","type":"uint8"},{"name":"evidence","type":"string"},{"name":"lockAmount","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"initiateDispute","inputs":[{"name":"conditionContract","type":"address"},{"name":"evidence","type":"string"},{"name":"lockAmount","type":"uint256"}],"outputs":[],"stateMutability":"payable"},
  {"type":"function","name":"conditionContracts","inputs":[{"name":"","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
  {"type":"event","name":"ConditionCreated","inputs":[{"indexed":true,"name":"conditionContract","type":"address"},{"indexed":false,"name":"conditionName","type":"string"},{"indexed":false,"name":"deadline","type":"uint256"},{"indexed":false,"name":"tradeDeadline","type":"uint256"},{"indexed":false,"name":"yesToken","type":"address"},{"indexed":false,"name":"noToken","type":"address"}]},
  {"type":"event","name":"ConditionStatusUpdated","inputs":[{"indexed":true,"name":"conditionContract","type":"address"},{"indexed":false,"name":"status","type":"uint8"}]}
]

GouGouBiMarketCondition (common)

[
  {"type":"function","name":"addLiquidity","inputs":[{"name":"amount","type":"uint256"},{"name":"lpType","type":"uint8"}],"outputs":[],"stateMutability":"payable"},
  {"type":"function","name":"buyYes","inputs":[{"name":"tokenIn","type":"uint256"},{"name":"minYesOut","type":"uint256"}],"outputs":[],"stateMutability":"payable"},
  {"type":"function","name":"buyNo","inputs":[{"name":"tokenIn","type":"uint256"},{"name":"minNoOut","type":"uint256"}],"outputs":[],"stateMutability":"payable"},
  {"type":"function","name":"sellYes","inputs":[{"name":"amountIn","type":"uint256"},{"name":"minAmountOut","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"sellNo","inputs":[{"name":"amountIn","type":"uint256"},{"name":"minAmountOut","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"swapYesForNo","inputs":[{"name":"amountIn","type":"uint256"},{"name":"minAmountOut","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"swapNoForYes","inputs":[{"name":"amountIn","type":"uint256"},{"name":"minAmountOut","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"redeem","inputs":[],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"claimLp","inputs":[],"outputs":[],"stateMutability":"nonpayable"},
  {"type":"function","name":"tradeDeadline","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
  {"type":"function","name":"liquidityToken","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
  {"type":"function","name":"yesToken","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
  {"type":"function","name":"noToken","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
  {"type":"event","name":"BuyYes","inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"tokenIn","type":"uint256"},{"indexed":false,"name":"totalYesOut","type":"uint256"}]},
  {"type":"event","name":"Redeem","inputs":[{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"userShare","type":"uint256"},{"indexed":false,"name":"totalShare","type":"uint256"},{"indexed":false,"name":"payout","type":"uint256"}]}
]

Usage examples (ethers v6):

  • Read status: const status = await proposalContract.conditionStatus(conditionAddress).
  • Create proposal: const tx = await factoryContract.proposeMarketCreation(...); const rec = await tx.wait(); get proposalAddress from events or return value.
  • After creating condition, get conditionContract from event ConditionCreated or proposalContract.conditionContracts(index).

Relation to other Skills

  • market-configurable-skills: GouGouBiMarketConfigurable and its Factory use oracle auto-settlement and rounds; that is a different market from this skill’s committee + dispute + supreme committee human adjudication. Do not mix contracts or status semantics.
  • This skill applies only to GouGouBiMarketFactory / GouGouBiMarketProposal / GouGouBiMarketCondition.