LiquidityLocker, and the locker has no code path that decreases liquidity, burns or transfers a position. Liquidity seeded at graduation is therefore locked for as long as the chain runs; the swap fees the position earns can be collected by anyone to the protocol’s fee collector.
Source: contracts/src/launch/LiquidityLocker.sol (IERC721Receiver, Ownable2Step, ReentrancyGuard). One locker per chain, set on the factory (LaunchFactory.locker()); address in Addresses.
Interface
collect(tokenId) reads the position’s pool key from the PositionManager and submits two actions in one modifyLiquidities call: DECREASE_LIQUIDITY with liquidity = 0 and both minimum amounts 0, followed by TAKE_PAIR of currency0 and currency1 to feeCollector. A zero-liquidity decrease is how Uniswap v4 realises accrued fees without touching the principal; TAKE_PAIR then pays them out. Anyone can call it for any position the locker owns; the deadline is the current block timestamp. Emits FeesCollected(tokenId, feeCollector).
setFeeCollector changes where future collections are paid (FeeCollectorSet(feeCollector)). The deploy script sets it to FEE_COLLECTOR, the deployer by default.
onERC721Received returns the selector so the PositionManager can mint positions to the locker.
What it cannot do
- Decrease liquidity by any non-zero amount: the amount is a hard-coded
0incollect, and no other function callsmodifyLiquidities. - Transfer or burn a position: there is no
transferFrom,safeTransferFromorburncall anywhere in the contract, and it holds no approvals. - Be upgraded: it is a plain contract with an immutable
posm.
setFeeCollector and the Ownable2Step transfer. The position principal is out of everyone’s reach, including the owner and the creator of the launch.
Fee destination
Fees arrive in both pool currencies: the launch token and its quote asset (the dollar, EURC or a synthetic such as wINR). They go tofeeCollector, not to the launch creator; creators earn their share of the curve’s trading fee only (see BondingCurve and Fees).
Reading a locked position
sqrtPriceX96 into a quote-per-token price is shown in Launch lifecycle. The PositionManager’s ownerOf(positionTokenId) returns the locker.
contracts/test/BondingCurve.t.sol (test_graduate_seedsLockedPoolAtCurvePrice and the EUR and six-decimal variants) asserts that the position is owned by the locker after graduation.