FutarchyFactory.createProposal. Split, merge and redeem use FutarchyRouter, which is like the standard Router but works with two collateral tokens and a FutarchyProposal (proposal address) instead of a Market. Resolution uses FutarchyRealityProxy.resolve(proposal) (or proposal.resolve()).
Create a futarchy proposal
CallFutarchyFactory.createProposal with a CreateProposalParams struct. Outcomes and token names are derived from the two collateral token symbols (e.g. Yes-GNO, No-GNO, Yes-wstETH, No-wstETH).
- marketName: The Reality.eth question (e.g. “Will proposal X be accepted by date Y?”).
- collateralToken1 / collateralToken2: The two ERC20 tokens used as collateral (e.g. GNO and wstETH).
- category / lang: Reality question category and language.
- minBond: Minimum bond for answering on Reality.eth.
- openingTime: Unix timestamp when the question can be answered.
NewProposal event).
Split, merge and redeem
UseFutarchyRouter for all three. The argument order differs from the standard Router: the proposal (FutarchyProposal address) comes first, then the collateral token, then the amount.
Split
You choose one of the two collateral tokens and split that token into the two outcome tokens for that collateral (Yes-Token and No-Token). So one split gives you only the pair for token1 or the pair for token2. To get all four outcome tokens you split twice (once per collateral).- Approve collateralToken (token1 or token2) to the FutarchyRouter.
- Call
futarchyRouter.splitPosition(proposal, collateralToken, amount). - You receive the two ERC20 outcome tokens for that collateral (e.g. Yes-GNO and No-GNO).
Merge
Hold one full set of outcome tokens for one collateral (i.e. equal amounts of Yes-Token and No-Token for that collateral). Merge returns that collateral to you.mergePositions(proposal, collateralToken, amount). You receive collateralToken back.
Redeem (after resolution)
After the proposal is resolved (FutarchyRealityProxy has reported payouts), only the winning side (Yes or No) is redeemable. You can redeem per collateral or both in one call. Option A – Redeem one collateralredeemPositions(proposal, collateralToken, amount). You receive collateralToken.
Option B – Redeem both collaterals in one tx
redeemProposal(proposal, amount1, amount2). You receive collateralToken1 and collateralToken2 (amount1 and amount2 of each).
Resolve a futarchy proposal
Same idea as Resolve a market: the question must be answered and finalized on Reality.eth. Then call either:FutarchyRealityProxy.resolve(proposal), orproposal.resolve()(the proposal forwards to the reality proxy).
Viem examples
We use the Viem setup:getPublicClient(chain) and getWalletClient(chain, process.env.PRIVATE_KEY). Use @seer-pm/sdk for addresses: getFutarchyFactoryAddress(chainId), getRouterAddress({ id: proposalAddress, type: "Futarchy", chainId }). Futarchy contracts are deployed on Gnosis (chain 100).
Shared: addresses
1. Create a futarchy proposal
Build the params tuple and callcreateProposal. The factory derives outcomes and token names from the collateral symbols.
2. Split (one collateral)
Choose one of the two collateral tokens, approve it, then callsplitPosition(proposal, collateralToken, amount). Argument order: proposal first, then collateral, then amount.
wstETH_ADDRESS (and approve wstETH to the router).
3. Merge (one collateral)
Hold equal amounts of Yes-Token and No-Token for one collateral. Approve both outcome tokens (Yes and No for that collateral) to the FutarchyRouter, then callmergePositions(proposal, collateralToken, amount).
4. Redeem – one collateral (redeemPositions)
After the proposal is resolved, approve the winning outcome token (e.g. Yes-GNO if accepted) to the FutarchyRouter. Then call redeemPositions(proposal, collateralToken, amount) to receive that collateral.
5. Redeem – both collaterals (redeemProposal)
Approve the winning outcome tokens for both collaterals. Then call redeemProposal(proposal, amount1, amount2) to receive both collateral tokens in one tx.
6. Resolve the proposal
Once the Reality.eth question is answered and finalized, callproposal.resolve() (or FutarchyRealityProxy.resolve(proposal)).
7. Simulate before sending
To avoid reverts (e.g. insufficient allowance or balance):Summary
Argument order: FutarchyRouter uses (proposal, collateralToken, amount). The standard Router uses (collateralToken, market, amount). Don’t mix them up.