The Hook
PropMarketHook is a real Uniswap v4 hook. Not "inspired by," not "hook-shaped" — the contract implements IHooks, lives at a CREATE2 address whose low bits encode the v4 permission bitmap, and is registered with the PoolManager as a hook for its pool. The market is the hook.
Permission bitmap
v4 packs the active permission flags into the trailing bits of the hook's CREATE2 address. PropMarketHook's factory salt-mines addresses whose low bits equal 0x2A80 — i.e. the hook participates in beforeSwap, afterSwap, beforeInitialize, and the liquidity-modification gates:
// packages/contracts/src/PropMarketHook.sol (excerpt)
function getHookPermissions()
public pure override returns (Hooks.Permissions memory)
{
return Hooks.Permissions({
beforeInitialize: true,
afterInitialize: false,
beforeAddLiquidity: true,
afterAddLiquidity: false,
beforeRemoveLiquidity: true,
afterRemoveLiquidity: false,
beforeSwap: true,
afterSwap: true,
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}The factory's deploy path uses HookMiner.find() (from v4-periphery/utils) to grind a salt whose CREATE2 address satisfies the permission bits. Without that, the PoolManager rejects the hook on attach.
What beforeSwap gates
In v4 lingo, "swap" covers both OVER and UNDER stake flows for a prop market. beforeSwap is where the hook enforces the per-market rules:
- The market is currently in
Openstate — not Committed, not Closed. - The stake amount is within the per-market min/max.
- The caller is the x402 facilitator's relayer (the only authorized writer of EIP-3009 transfers for this market).
- Optional: any persona-defined entry constraints from the revealed
templateParams.
If any check fails, beforeSwap reverts; the PoolManager rolls the whole interaction back atomically. There is no "maybe partial stake" case.
Test posture
The forge suite:
- 67 tests total, split across
PropMarketHook.lifecycle.t.sol,PropMarketHook.stake.t.sol,PropMarketHook.refund.t.sol,PropMarketHook.resolve.t.sol,PropMarketHook.claim.t.sol, andPropMarketHookFactory.t.sol. - 100% line, branch, and function coverage on the contracts directory.
- Mocks:
MockUSDT0.solreproduces the EIP-712 domain + 6-decimal balance behavior of the live USDT0 deployment.