What
Redeploy PredictionPool with a 1% taker fee (feeBps = 100) that the owner/arena can change at any time without redeploying. Add a minimum pool size below which no fee is taken.
Why
We're on mainnet now with real MON flowing. 1% is reasonable (Kalshi charges ~1.2%, Polymarket charges 0.01-0.10%). The minimum threshold protects small bets from being eaten by fees. The fee must be mutable so we can adjust without redeploying (e.g. lower it to attract volume, raise it later, or set to 0 for a promo).
Changes needed
1. Make feeBps mutable in PredictionPool.sol
Change from immutable to regular state variable with a setter:
uint256 public feeBps;
uint256 public minPoolForFee;
// Cap to prevent abuse (e.g. max 10%)
uint256 public constant MAX_FEE_BPS = 1000;
constructor(address _matchProof, address _arena, uint256 _feeBps, uint256 _minPoolForFee) {
require(_feeBps <= MAX_FEE_BPS, "Fee too high");
matchProof = IMatchProof(_matchProof);
arena = _arena;
feeBps = _feeBps;
minPoolForFee = _minPoolForFee;
}
function setFeeBps(uint256 _feeBps) external onlyArena {
require(_feeBps <= MAX_FEE_BPS, "Fee too high");
feeBps = _feeBps;
}
function setMinPoolForFee(uint256 _minPoolForFee) external onlyArena {
minPoolForFee = _minPoolForFee;
}
2. Update fee calculation in resolve() and claim()
uint256 fee = 0;
if (feeBps > 0 && totalPool >= minPoolForFee) {
fee = (totalPool * feeBps) / 10000;
accumulatedFees += fee;
}
Same change in getClaimable() view function.
3. Update deploy script
uint256 feeBps = 100; // 1%
uint256 minPoolForFee = 0.1 ether; // No fee below 0.1 MON total pool
0.1 MON seems reasonable — below that, the fee is <0.001 MON (dust).
4. Redeploy to mainnet
cd contracts && forge script script/DeployPrediction.s.sol \
--rpc-url https://rpc.monad.xyz --broadcast \
--sig "run(address)" 0x1CC748475F1F666017771FB49131708446B9f3DF
5. After deploy
- Update
contracts/deployments.json with new PredictionPool address
- Scav updates
PREDICTION_POOL env var on Railway
- Scav updates
~/.nojohns/arena.env and config.toml
- Website
config.ts needs the new address too
Current contract
Address: 0x33E65E300575D11a42a579B2675A63cb4374598D (feeBps=0, immutable, no threshold)
Old contract stays on-chain, open pools there still work. New pools use the new contract.
Design notes
MAX_FEE_BPS = 1000 (10%) as a hardcoded safety cap — can never set fee above this
- Only
arena role can change fees (same role that creates/resolves pools)
- Fee snapshots: fee is applied at resolution time, not bet time. If fee changes mid-pool, the fee at resolution applies. This is simpler and fine for our use case.
withdrawFees() already exists — should be called periodically or added to arena's post-resolution flow
Owner: ScavieFae
What
Redeploy PredictionPool with a 1% taker fee (
feeBps = 100) that the owner/arena can change at any time without redeploying. Add a minimum pool size below which no fee is taken.Why
We're on mainnet now with real MON flowing. 1% is reasonable (Kalshi charges ~1.2%, Polymarket charges 0.01-0.10%). The minimum threshold protects small bets from being eaten by fees. The fee must be mutable so we can adjust without redeploying (e.g. lower it to attract volume, raise it later, or set to 0 for a promo).
Changes needed
1. Make
feeBpsmutable inPredictionPool.solChange from
immutableto regular state variable with a setter:2. Update fee calculation in
resolve()andclaim()Same change in
getClaimable()view function.3. Update deploy script
0.1 MON seems reasonable — below that, the fee is <0.001 MON (dust).
4. Redeploy to mainnet
5. After deploy
contracts/deployments.jsonwith new PredictionPool addressPREDICTION_POOLenv var on Railway~/.nojohns/arena.envandconfig.tomlconfig.tsneeds the new address tooCurrent contract
Address:
0x33E65E300575D11a42a579B2675A63cb4374598D(feeBps=0, immutable, no threshold)Old contract stays on-chain, open pools there still work. New pools use the new contract.
Design notes
MAX_FEE_BPS = 1000(10%) as a hardcoded safety cap — can never set fee above thisarenarole can change fees (same role that creates/resolves pools)withdrawFees()already exists — should be called periodically or added to arena's post-resolution flowOwner: ScavieFae