Docs

Snowball controller

The contract that turns creator fees into liquidity owned by Snowmen. Permissionless, no admin withdraw.

Snow Pons sets the Pons v2 creatorFeeRecipient of the launch token to a SnowballController. “Snowball” is our name for it; it is not a Pons contract.

Harvest

  1. 01
    claim()
    Pull accrued fees from Pons in the quote asset
  2. 02
    split
    Divide by gene allocation
  3. 03
    swap
    Quote to token for the buy share
  4. 04
    addLiquidity
    Pair the LP share and deposit
  5. 05
    credit
    Update each gene's rewards index
harvest
function harvest(uint256 minTokenOut) external;   // anyone
function claimFor(uint256 id) external;           // push credited assets to the account
function pendingOf(uint256 id) view returns (uint256 quoteAmount);
function positionOf(uint256 id) view returns (uint256 positionTokenId);
function lifetimeFees(uint256 id) view returns (uint256);

Per-gene accounting

Each gene is a pool and every living Snowman of that gene is one share. A harvest updates four accumulators instead of sending 1,000 transfers, and claimFor settles one Snowman against its gene's index. When two Snowmen merge, the donor's unclaimed accrual and lifetime attribution move to the survivor before the burn.

The Pons timelock

Pons v2 can change any token's creatorFeeRecipient behind a three-day timelock. If that ever points away from the controller, fees stop flowing to Snowmen. The controller mirrors pendingCreatorFeeRecipient through pendingRecipientChange() and the indexer stores it, so a pending change is visible to holders before it takes effect.

Adapters

Swapping and liquidity go through two small adapter contracts, ISwapRouter and ILiquidityAdapter. The shipped adapters target a Uniswap v3 SwapRouter02 and NonfungiblePositionManager; the liquidity adapter has no decrease, burn or transfer-out path and a permissionless collectAndCompound. The owner can set adapters before calling renounce(). After that nobody can.