sqrtDAO docs

Buy back & burn

What it does

Buy back & burn is one of the hooks a distribution can route its funds to. A configured percentage of every drained epoch's participation fund is swapped from the participation token into the distribution token on its Uniswap V3 pool — and everything the swap returns goes straight to the dead address (0x…dEaD), permanently removing it from supply.

In practice: real participation volume creates sustained buy pressure on the token, and the bought tokens never come back.

Other sharesprotocol fee · treasury · …Epoch fundparticipation tokenBuyAndBurnHookV3Uniswap V3 pool0.3% fee tierDead addressshareBps cutexactInputburnedrest of fund
Buy back & burn flow: each drained epoch fund is partially swapped and burned

How it's configured

When launching with createTokenAndLiquidityAndDistribution, the creator picks a share in basis points. The factory injects a matching Share into the distributor config, with the swap path (participation token → pool fee tier → distribution token) baked in at deployment:

FactoryV1.sol — _injectBuyAndBurnShare()
bytes memory path = abi.encodePacked(
    _config.participationToken, LIQUIDITY_POOL_FEE, _config.distributionToken
);

_config.shares = SharesLib.append(
    _config.shares,
    Share({
        shareBps: _shareBps,
        hook: Hook({
            contractAddress: address(BUY_AND_BURN_HOOK),
            callData: abi.encodeCall(BuyAndBurnHookV3.buyAndBurn, (path))
        })
    })
);

All shares — protocol fee, buy back & burn, any custom recipients — must sum to exactly 100%, which is validated at construction. Set the share to zero to launch without it.

The burn mechanics

When an epoch drains (see epoch-based distribution), each share receives its cut via approve-and-call. The hook then swaps its allowance through Uniswap V3 with the burn address as recipient:

BuyAndBurnHookV3.sol — buyAndBurn() (trimmed)
uint256 amountIn = token.allowance(msg.sender, address(this));
token.safeTransferFrom(msg.sender, address(this), amountIn);
token.forceApprove(UNISWAP_SWAP_ROUTER_ADDRESS, amountIn);

amountOut = IUniswapV3SwapRouter(UNISWAP_SWAP_ROUTER_ADDRESS).exactInput(
    ExactInputParams({ path: _path, recipient: BURN_ADDRESS, amountIn: amountIn, amountOutMinimum: 0 })
);

Why it matters

  • Backing that can't be pulled. At pool creation, LP tokens are minted straight to the dead address — liquidity can never be withdrawn by anyone, including the team.
  • Demand follows usage. Buy pressure scales with actual participation instead of relying on promises or emissions schedules.
  • Deflationary by design. Every epoch that runs shrinks circulating supply — no manual burns, no multisig involvement.