chainId = 56)GouGouBiMarketFactory.sol0x7b0B72e620368d8037406AaDB416e62b6e20f6ac0xb05678Ed0c9559955559DE864829a0c8AF574444 — 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.Assumptions when calling:
https://bsc-dataseed.binance.org)RoleContract fileDescriptionFactoryGouGouBiMarketFactory.solCreate proposals, committee/supreme committee staking, dispute arbitration, reward claimingProposalGouGouBiMarketProposal.solOne clone per proposal; condition creation, activation/settlement voting, dispute, state transitionsConditionGouGouBiMarketCondition.solOne clone per condition; trading, liquidity, redeem
Convention: Factory / Proposal / Condition addresses are supplied by upper-layer config (e.g. OpenClaw parameters, environment variables).
All stake and lock amounts below are in DOGE(狗狗币 / Dogecoin) (18 decimals). Values are taken from the deployed Factory and Proposal contracts.
ConstantValueMeaningMIN_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.
ConstantValueMeaningSETTLEMENT_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).
ConstantValueMeaningTRADING_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).
text
[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:
Proposal.conditionStatus(cond)==1 and Condition.tradeDeadline()>block.timestamp.conditionDeadline + 600 (10 min).conditionDeadline + 600 + 600 (20 min after condition deadline).EnumNameAllowed actions0CREATEDActivation vote only; 2/3 approve→ACTIVE, reject→REJECTED1ACTIVETrading, add/remove LP, committee settlement vote; past settlement window + votes→DISPUTED2REJECTEDNo longer used4DISPUTEDinitiateDispute; after dispute window checkConditionStatus → SETTLED or DISPUTED_INITIATED5DISPUTED_INITIATEDSupreme committee voteConditionDisputeSupreme; when satisfied → SETTLED7SETTLEDredeem, claimLp; committee/supreme committee claim rewards
TaskContractMethodConstraintsCreate proposalFactoryproposeMarketCreation(liquidityToken, proposalName, deadline, imageUrl, rules, timezone, language, groupUrl, tags, stakeAmount)stakeAmount ≥ 10 DOGE (1e19); approve Factory for DOGE first; returns proposalAddressCommittee 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 ≥ 3Activation voteProposalvoteOnConditionActivation(conditionContract, approve)status==CREATED; 2/3 approves → ACTIVE, 2/3 rejects → REJECTEDRead statusProposalconditionStatus(conditionContract)Authoritative; read first then decide next callAdvance statusProposalcheckConditionStatus(conditionContract)Anyone can call; updates status by time and votesSettlement voteProposalconditionSettlementVoteLock(conditionContract, result, lockAmount) or voteOnConditionResult(conditionContract, result, evidence, lockAmount)result: 1=YES, 2=NO; lockAmount ≥ 10 DOGE; within conditionDeadline+600Initiate 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 DOGEAdd liquidityConditionaddLiquidity(amount, lpType)status==ACTIVE, tradeDeadline>now; lpType 0=FEE, 1=RISKBuy/sell/swapConditionbuyYes(tokenIn, minYesOut)/buyNo/sellYes/sellNo/swapYesForNo/swapNoForYesstatus==ACTIVE, tradeDeadline>nowRedeemConditionredeem() / claimLp()status==SETTLED
conditionDeadline + 600 (10 min); dispute window: +600 (10 min) after that.factory.dogeToken(); approve Factory before proposeMarketCreation and stakeForProposalCommittee.Full ABI (recommended for production/subgraph):
subgraph/abis/GouGouBiMarketFactory.jsonsubgraph/abis/GouGouBiMarketProposal.jsonsubgraph/abis/GouGouBiMarketCondition.jsonBelow is a minimal ABI of commonly used methods and key events for Agents; use with ethers/viem (deduplicate when merging with full ABI).
json
[
{"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"}]}
]
json
[
{"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"}]}
]
json
[
{"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):
const status = await proposalContract.conditionStatus(conditionAddress).const tx = await factoryContract.proposeMarketCreation(...); const rec = await tx.wait(); get proposalAddress from events or return value.conditionContract from event ConditionCreated or proposalContract.conditionContracts(index).