chapters· Roles
21 · Build & manage

Roles & surrender

Pot admin, program owner, program operator — each surrenders on its own terms.

Three roles, three scopes, and a deliberate design rule: each surrenders on its own terms. Nobody is ever forced to give up the pool just to lock the rules — or to freeze the rules just to lock the pool.

pot admin
whoever initialized the pool on the PoolManager
  • · initPot — declare MAIN + recipient (one-shot)
  • · setRecipient (0x0 = burn)
  • · create the pool's ONE LP program
fixed at pool creation — there is no admin transfer, and no admin power over balances
program owner
an explicit parameter at program creation
  • · add / remove liquidity
  • · harvest (when not public)
  • · transferProgramOwnership
owner = 0x0 → liquidity locked FOREVER, manual harvest forced public
program operator
starts as the owner; moves via setProgramOperator
  • · setProgramConfig — shares, recipients, minimums
  • · toggle publicHarvest
  • · reassign itself
operator = 0x0 → the split rules are frozen forever, owner untouched
the hook itself is ownerless

No role above has power over the hook — only over their own pool's pot or program. There is no global admin, no pause switch, no fee switch, no upgrade path.

Owner vs operator — why two roles

The owner holds the property: liquidity, harvests, and the right to transfer or surrender. The operator edits the rules: the split shares, the recipients, the minimums, the harvest gate. Splitting them makes the two most-wanted trust promises independent:

promisehowwhat survives
immutable fees, keep the LPset the config, then setProgramOperator(poolId, address(0))the owner still adds, removes and harvests — under rules nobody can ever change
locked LP, keep the leverstransferProgramOwnership(poolId, address(0))the liquidity is locked forever and harvest is forced public — but a live operator can still tune the split
full surrender at birthaddLiquidityAdvanced(…, owner = address(0), config)rules nobody can edit, liquidity nobody can pull, harvest public — trustless from block one

Custody is composable

Richer policy — timelocks, vesting, DAO control — is built on top by making such a contract the owner: a locker simply becomes the owner and implements whatever release schedule it wants. The hook doesn't need to know; ownership is just an address. See Build launchers & apps.

FAQ

What are the three roles again?+

Pot admin (the pool's initializer: sets the pot recipient, creates the one LP program), program owner (holds the liquidity, harvests, transfers), program operator (edits config).

What does surrendering the owner do?+

owner = 0x0 locks the liquidity forever — nobody can ever remove it — and the harvest becomes public. It's the strongest "liquidity locked" statement possible.

What does surrendering the operator do?+

operator = 0x0 freezes the config forever: fee splits, buyback split, recipients and minimums become immutable. The owner keeps its property rights.

Can the roles be held by contracts?+

Yes — that's the composition surface: DAOs, lockers, vesting contracts and launchpads hold roles and expose their own policies on top of the hook's primitives.

Can a surrendered role be recovered?+

Never — surrender writes 0x0 and there is no path back. It's a feature: the irreversibility is what makes the promise credible.