BlockBid is a batch-auction DEX hook built on Uniswap V4. Every trade in the same block executes at one uniform snapshot price — making front-running and sandwich attacks structurally impossible.
beforeSwap rebalances the previous active block's imbalance first, then captures the current slot0 sqrtPriceX96 as the immutable clearing price. Every subsequent swap in the same block uses this frozen price.BeforeSwapDelta cancels the underlying AMM execution entirely.tokenClaimsTarget). Buy-heavy blocks reduce token claims → next block swaps ETH→BID to replenish. Sell-heavy blocks do the opposite. Uses live slot0, never a stale snapshot. No keeper required.beforeAddLiquidity. Settlements draw from a 20% token claims buffer that is auto-replenished each block — the AMM pool acts as inventory backstop, not primary execution venue. Consistent depth even during high-volume periods.
BlockBid's full settlement logic lives in a single beforeSwap callback —
price snapshotting, claims settlement, fee accrual, overflow guards, and rebalance trigger.
No proxy contracts. No admin keys on the swap path.
/// @notice Batch auction core — intercepts every swap. function beforeSwap( address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata ) external returns (bytes4, BeforeSwapDelta, uint24) { if (_rebalancing) // pass-through internal swap return (selector, ZERO_DELTA, 0); // ── First swap of block: rebalance prev + snapshot ── if (snapshotPrice[pid][bn] == 0) { _rebalanceInline(lastActiveBlock[pid], key); (uint160 sqrtP,,,) = poolManager.getSlot0(pid); snapshotPrice[pid][bn] = sqrtP; // locked for block } uint160 P = snapshotPrice[pid][bn]; // uniform price // ── Compute amounts at frozen price ───────────────── uint256 amtIn = calcIn (params, P); uint256 amtOut = calcOut(params, P); // ── 1% ETH fee (input or output side) ─────────────── uint256 fee = ethSide / 100; accruedFees += fee; totalFeesLifetime += fee; // lifetime cumulative totalVolumeETH += ethSideGross; totalSwaps++; // on-chain swap counter // ── Settle via ERC-6909 claims (no token transfer) ─── poolManager.burn(address(this), outputCur.toId(), amtOut); poolManager.mint(address(this), inputCur.toId(), amtIn); emit Swapped(sender, zfo, amtIn, amtOut, P); // ── Cancel AMM: return custom BeforeSwapDelta ──────── return (selector, toBeforeSwapDelta(specAmt, fillAmt), 0); }
Submit a swap and settle at the block's uniform price. No bots can get ahead of you — the price is locked before any trade executes.