every swapis aticket◆
a uniswap v4 hook where trading is the lottery. swap any pair routed through fortune.cookie — automatically get a ticket. every 100 blocks, one ticket cracks the jar.

the.jar

how.it.works
no signup, no extra clicks, no extra gas. swap as usual through any hook-enabled pool — the rest is on-chain math.
trade any token pair through a fortune.cookie-enabled v4 pool. you pay the normal lp fee — no surcharge.
the hook mints tickets weighted by your eth volume. bigger swaps get more entries. tickets live in the jar until the draw.
every 100 blocks, a verifiable random draw picks one ticket. the entire jar transfers to the winner. no claims.
no admin.
no upgrades.
just.math.
fortune.cookie is a single immutable uniswap v4 hook. every swap routed through a fortune.cookie pool fires afterSwap(), which mints the ticket and rolls the jar. the lottery is the protocol.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract FortuneCookieHook is BaseHook, VRFConsumerBaseV2Plus {
uint256 public immutable epochDuration; // seconds
uint256 public currentEpochId;
mapping(uint256 => Epoch) public epochs;
function _afterSwap(
address swapper,
PoolKey calldata key,
SwapParams calldata p,
BalanceDelta delta,
bytes calldata
) internal override returns (bytes4, int128) {
uint128 ethVolume = _ethAbs(delta);
uint256 ticketTax = ethVolume * taxBps / 10_000;
_mintTickets(swapper, ethVolume - ticketTax);
epochs[currentEpochId].ethPot += ticketTax;
return (this.afterSwap.selector, int128(uint128(ticketTax)));
}
function requestDraw() external {
Epoch storage e = epochs[currentEpochId];
require(block.timestamp >= e.startTime + epochDuration);
e.vrfRequestId = s_vrfCoordinator.requestRandomWords(...);
e.drawing = true;
emit DrawRequested(currentEpochId, e.vrfRequestId);
}
}
crack.it.
“the next 100 blocks belong to you. one ticket. one jar. one winner. ◆”