A Trustless P2P Prediction Market for Ethereum Base Fee Thresholds
GasFloor introduces a novel prediction market design that eliminates the need for external oracles by leveraging Ethereum's native block.basefee opcode (EIP-3198). This enables trustless, atomic resolution for one side of every prediction while maintaining economic security for the other through a bounty-based incentive mechanism.
The protocol implements a peer-to-peer order book model where makers create offers and takers accept the opposite position, allowing for flexible odds and partial fills. Settlement is immediate and verifiable on-chain, providing a transparent and manipulation-resistant prediction market for Ethereum gas prices.
Traditional prediction markets rely on external oracles to determine outcomes. This introduces trust assumptions, latency, and potential manipulation vectors. Oracles can be bribed, manipulated, or simply fail to report accurately.
EIP-3198, implemented in the London hard fork, introduced the BASEFEE opcode that returns the base fee of the current block. This enables smart contracts to atomically verify gas price conditions within the same transaction that settles a prediction.
Key Insight: By using block.basefee, we can create predictions where the YES outcome can be settled trustlessly and atomically - the Ethereum blockchain itself serves as the oracle.
Ethereum gas prices are notoriously volatile, affected by NFT mints, DeFi activity, and network congestion. Traders, MEV searchers, and protocol operators all have strong interest in hedging or speculating on gas price movements.
Unlike AMM-based prediction markets, GasFloor uses a direct peer-to-peer matching system:
The ratio between maker stake and maximum counterparty stake determines the implied probability:
Implied YES Probability = makerStake / (makerStake + maxCounterparty)
Implied NO Probability = maxCounterparty / (makerStake + maxCounterparty)
For example, if a YES maker stakes 0.7 ETH and accepts up to 0.3 ETH from takers, the implied odds are 70% YES / 30% NO.
struct Offer {
address maker; // Offer creator
bool makerBetsYes; // true = maker bets YES
bool resolved; // Has offer been resolved
bool outcome; // true = YES won, false = NO won
uint256 makerStake; // Maker's ETH stake
uint256 maxCounterparty; // Max ETH from takers
uint256 totalTakerStake; // Sum of all taker deposits
uint256 threshold; // Base fee threshold (wei)
uint256 deadline; // Block number deadline
uint256 bounty; // Resolver reward
}
| Function | Description |
|---|---|
createOffer() |
Create new offer with minimum bounty (0.003 ETH) |
createOfferWithBounty() |
Create offer with custom bounty amount |
takeOffer(offerId, amount) |
Accept opposite position, partial fills allowed |
cancelOffer(offerId) |
Cancel and refund if no takers yet |
resolveYes(offerId) |
Resolve YES if block.basefee >= threshold |
resolveNo(offerId) |
Resolve NO after deadline passes |
claim(offerId) |
Withdraw winnings after resolution |
withdrawBounty(offerId) |
Resolver claims bounty (pull pattern) |
event OfferCreated(uint256 indexed offerId, address indexed maker, ...);
event OfferTaken(uint256 indexed offerId, address indexed taker, uint256 amount);
event OfferResolved(uint256 indexed offerId, bool outcome, address resolver);
event OfferCancelled(uint256 indexed offerId);
event Claimed(uint256 indexed offerId, address indexed claimer, uint256 amount);
event BountyWithdrawn(uint256 indexed offerId, address indexed resolver, uint256 amount);
The resolveYes() function can be called by anyone when the current block's base fee meets or exceeds the threshold:
function resolveYes(uint256 offerId) external {
Offer storage offer = offers[offerId];
require(!offer.resolved, "Already resolved");
require(block.basefee >= offer.threshold, "Threshold not met");
offer.resolved = true;
offer.outcome = true;
resolver[offerId] = msg.sender;
emit OfferResolved(offerId, true, msg.sender);
}
Trustless Property: This resolution requires no external data or trust assumptions. The Ethereum protocol itself guarantees that block.basefee accurately reflects the current base fee. If the condition is met, the resolution is cryptographically verified.
For NO outcomes, we cannot prove a negative trustlessly (we can't prove gas will never hit the threshold). Instead, we use economic incentives:
function resolveNo(uint256 offerId) external {
Offer storage offer = offers[offerId];
require(!offer.resolved, "Already resolved");
require(block.number > offer.deadline, "Deadline not passed");
offer.resolved = true;
offer.outcome = false;
resolver[offerId] = msg.sender;
emit OfferResolved(offerId, false, msg.sender);
}
The bounty (minimum 0.003 ETH, ~$10) incentivizes anyone to call resolveNo() after the deadline. This is a simple, gas-efficient operation that anyone monitoring the blockchain can execute for profit.
Winners receive their stake back plus a proportional share of the loser's stake:
// If YES wins:
makerPayout = (makerStake * totalPool) / winnerStake
takerPayout = (takerStake * totalPool) / winnerStake
// Unmatched maker stake always returned
unmatchedReturn = makerStake - matchedMakerStake
| Attack | Mitigation |
|---|---|
| Dust attacks | Minimum stake requirements (0.01 ETH maker, 0.001 ETH taker) |
| Unbounded array growth | Maximum 100 takers per offer |
| Resolution front-running | No advantage from front-running - first resolver gets bounty |
| Bounty griefing | Pull-based withdrawal prevents blocking |
Note: Gas price manipulation by miners/validators is theoretically possible but economically irrational for typical offer sizes. Large offers should account for this risk.
| Parameter | Value | Rationale |
|---|---|---|
| MIN_BOUNTY | 0.003 ETH | ~$10 covers gas + profit for resolver |
| MIN_MAKER_STAKE | 0.01 ETH | Prevents dust/spam offers |
| MIN_TAKER_STAKE | 0.001 ETH | Allows small participation |
| MAX_TAKERS_PER_OFFER | 100 | Bounds gas costs for resolution |
The P2P model allows markets to form at any odds, rather than being constrained by AMM curves. This enables more accurate price discovery for gas predictions.
Resolvers are incentivized by bounties. For YES resolution, they must time their transaction for a block with sufficient base fee. For NO resolution, they simply need to monitor the blockchain and act after deadlines pass.
If markets misprice gas volatility, arbitrageurs can profit by taking positions and hedging with gas futures or other mechanisms, bringing prices toward efficiency.
Deployed Contract: 0x2c5DDd1F08F6ED8a12E50E47Fd2454d52d170E7e