Open source · MIT · read-only

Bid on Uniswap CCA auctions without overpaying

Give it an auction, a budget and a demand assumption. Get back a bid ladder, with the expected fill, average price, worst case and refund for every scenario. It never holds keys.

npx github:cocoa-butter/cca-bid-planner plan \
  --auction 0x... --rpc https://ethereum-rpc.publicnode.com \
  --budget 25000 --max-price 0.02
The planner switching between flat, top-weighted and bottom-weighted bid ladders

Why a planner?

A Continuous Clearing Auction is a uniform-price auction run block by block. The obvious move, one bid at your maximum, gets outbid the moment demand passes your cap and tells you nothing about your refund. The right ladder depends on how much demand you expect behind you, and nobody publishes that number.

📈

Ladder, don't guess

Splits your budget across tick prices between the current clearing price and your cap. Weighting is flat, top-heavy or bottom-heavy.

🧪

Simulate the outcome

Replays your ladder against demand scenarios: tokens, spend, average price, refund, final clearing, and whether the auction graduates.

🛡️

Check the auction first

A risk report covers impossible minimum raises, gas-hostile tick spacing, a thin final block, validation hooks and low-decimal tokens.

🧾

Ready calldata

Emits submitBid calls with correct prevTickPrice hints, plus Permit2 or msg.value notes. You sign with your own wallet.

🔍

Every number labelled

Each figure is marked observed on chain, derived with protocol math, or assumed. The demand forecast is always marked assumed.

📦

CLI, library, web

The same pure TypeScript core runs in the terminal, in your code and in this browser. viem is the only dependency.

Exact to the wei

The simulator is an integer port of the contract's checkpoint, clearing-price and fill accounting. A differential test replays random auctions on the real ContinuousClearingAuction v2.1.0 with Foundry and compares every result.

300random auctions replayed on the real contract
2,405bids, including outbid and partially filled ones
0 weidifference in fills, refunds and clearing prices
v2.1.0pinned upstream release (a56d422)

How it works

  1. Read. Loads parameters, the supply schedule, live ticks and the minimum raise over plain JSON-RPC. It simulates checkpoint() so state is current.
  2. Ladder. Picks up to n tick prices strictly above clearing and up to your cap, then splits the budget exactly.
  3. Assume. You state how much currency other bidders add, and when. By default that is the demand needed to lift clearing to your cap, tested at 0, ½, 1 and 2 times.
  4. Simulate. Every scenario runs through the exact engine to the end block, then settles each bid the way exitBid would.
  5. Act. Export calldata, or rerun as the auction moves.

Labels you can trust

Nothing is presented as more certain than it is.

observedderivedassumed
[obs] floor price                       0.00889 USDC/SLOP
[der] clearing price (checkpointed now) 0.00889 USDC/SLOP
[asm] expected average price (base)     0.01341919 USDC/SLOP
[asm] max refund exposure               25,000 USDC

This is a scenario calculator, not a price oracle. Auctions can fail to graduate, and exits are restricted until they do.

Get started

Command line

npm install -g github:cocoa-butter/cca-bid-planner
cca-bid-planner inspect --auction 0x... --rpc $RPC --save a.json
cca-bid-planner plan --snapshot a.json --budget 25000 --max-price 0.02

CLI reference →

Library

import { readSnapshot, clientFor, plan, toPriceQ96, toRaw } from 'cca-bid-planner';

const { snapshot } = await readSnapshot(clientFor(rpc), auction);
const result = plan(snapshot, {
  budget: toRaw('25000', snapshot.currency.decimals),
  maxPrice: toPriceQ96('0.02', snapshot.token.decimals, snapshot.currency.decimals),
});

Library guide →