Security & Audits
P0 Vulnerabilities Mitigation
F-01, F-02 and F-03 — what was broken, what changed, and how it is tested.
F-01 · Oracle conflict of interest
The owner is the oracle and was previously allowed to place bets. That is a guaranteed-profit loop: take a position, then declare the outcome that pays it. The patch blocks the owner address at the bet entry point (OwnerCannotBet) and, separately, the frontend never offers a position to the owner wallet.
function bet(uint256 poolId, uint8 option, uint256 amount, address referrer)
external nonReentrant
{
if (msg.sender == owner()) revert OwnerCannotBet();
...
}Residual
This blocks the address, not sybils. A fresh wallet still works — the complete fix is decentralised resolution, not an address filter.
F-02 · Cancel rug (platform kept the rake)
Cancellation used to refund only the net stake, so the 4% rake stayed with the platform. The fix moved the rake into per-market escrow: while a market is open nothing is withdrawable, so cancelling releases nothing and claimRefund pays stake + fee = 100% of gross.
// claimRefund
refund = _stake[poolId][msg.sender][0] + _stake[poolId][msg.sender][1]
+ _feePaid[poolId][msg.sender]; // fee included -> 100% of grossRed-team result: a 50 USDC position on a cancelled market refunds 50.000000 USDC; platform rake kept = 0.000000 USDC.
F-03 · Operator disappearance froze funds
If the operator key is lost, settle() can never be called and every position would be stuck forever. The fix is a permissionless escape hatch: 30 days after the close time, any address can void the market and unlock 100% refunds.
uint256 eligibleAt = uint256(pool.endTime) + EMERGENCY_REFUND_DELAY; // 30 days
if (block.timestamp < eligibleAt) revert EmergencyTooEarly(eligibleAt);
_cancel(poolId); // escrow stays untouched -> everyone refunds 100%| Before the window | emergencyRefund reverts with EmergencyTooEarly(eligibleAt) |
| After the window | any address can void; every position refunds 100% of gross |
| On a settled market | reverts PoolNotOpen — a live result cannot be retro-voided |
Market-design consequence
If a question's real outcome takes longer than 30 days to become known, the pool will be voided by the escape hatch. Long-horizon markets should either be split into shorter legs or settle before the window closes.