# BaseLaunchLocker

Holds every graduated pool's full-range position NFT and the coins left over at graduation, forever. It has no withdraw, transfer or arbitrary-call function.

Permanently holds the graduated Uniswap V4 position NFT for every launcher launch. Unlike an LP-fee locker, there is no `collectFees()` here: fee collection and distribution belong entirely to BaseLaunchHook and BaseLaunchFeeEscrow, since a V4 position accrues fees inside the singleton PoolManager rather than on the NFT itself. This contract exposes no withdrawal or arbitrary-call function, so locked liquidity can never be removed by an administrator.

Part of the [contract reference](https://baselaunch.app/docs/reference).

### Deployed at

BaseLaunchLocker (2.1.0)`0xE6dBD6f38A883AF15698a771d2772a2728945E70`[](https://basescan.org/address/0xE6dBD6f38A883AF15698a771d2772a2728945E70)

BaseLaunchLocker (2.0)`0x0E7842CEeD8434ef250fd3014718E33C249a5791`[](https://basescan.org/address/0x0E7842CEeD8434ef250fd3014718E33C249a5791)

### Read functions (9)

| Function | What it does |
| --- | --- |
| [factory](#factory) `factory() view returns (address)` selector 0xc45a0155 Anyone | The launch factory, the only caller that can lock a position or coins. Wired once. |
| [isLocked](#isLocked) `isLocked(address token) view returns (bool)` selector 0x4a4fbeec Anyone | Returns whether a launch's position has been locked here. |
| [lockedPositions](#lockedPositions) `lockedPositions(address token) view returns (uint256 tokenId)` selector 0xfa22143d Anyone | The PositionManager token id of a coin's locked pool position. |
| [lockedTokenSupply](#lockedTokenSupply) `lockedTokenSupply(address token) view returns (uint256 amount)` selector 0x732e78e4 Anyone | Coins of a launch locked here forever at graduation. |
| [onERC721Received](#onERC721Received) `onERC721Received(address, address, uint256, bytes) view returns (bytes4)` selector 0x150b7a02 Uniswap PositionManager only | Rejects safe transfers of anything but a canonical position NFT. Not part of the graduation path. Graduation names this locker as the `MINT_POSITION` owner, and the PositionManager mints with a plain `_mint`, which fires no receiver callback. Custody is established by the `ownerOf` check in `lockPosition` instead. This exists so the locker still behaves correctly under an explicit `safeTransferFrom`, and so such a transfer can only ever originate from the canonical PositionManager. |
| [owner](#owner) `owner() view returns (address)` selector 0x8da5cb5b Anyone | Returns the address of the current owner. Inherited from Ownable. |
| [pendingOwner](#pendingOwner) `pendingOwner() view returns (address)` selector 0xe30c3978 Anyone | Returns the address of the pending owner. Inherited from Ownable2Step. |
| [positionManager](#positionManager) `positionManager() view returns (address)` selector 0x791b98bc Anyone | The Uniswap v4 PositionManager whose position NFTs this locker holds. |
| [renounceOwnership](#renounceOwnership) `renounceOwnership() pure` selector 0x715018a6 Anyone | Permanently disabled. Ownership here exists only to perform the one-time factory wiring, and renouncing before that wiring would leave the locker unable to ever accept a graduated position. |

### Write functions (5)

| Function | What it does |
| --- | --- |
| [acceptOwnership](#acceptOwnership) `acceptOwnership()` selector 0x79ba5097 Pending owner | The new owner accepts the ownership transfer. Inherited from Ownable2Step. |
| [lockPosition](#lockPosition) `lockPosition(address token, uint256 tokenId)` selector 0x292d5732 Factory only | Registers and verifies permanent custody of a graduated position. Called once per launch by the factory, immediately after minting the full-range position directly to this locker's address. |
| [lockTokenSupply](#lockTokenSupply) `lockTokenSupply(address token, uint256 amount)` selector 0xb8a0d7ab Factory only | Permanently locks the virtual-reserve token remainder that cannot enter the graduated pool without lowering its opening price. |
| [setFactory](#setFactory) `setFactory(address factory_)` selector 0x5bb47808 Owner | One-time wiring of the launch factory, set after both are deployed. |
| [transferOwnership](#transferOwnership) `transferOwnership(address newOwner)` selector 0xf2fde38b Owner | Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer. Inherited from Ownable2Step. |

### Events (5)

| Event | What it means |
| --- | --- |
| [FactorySet](#event-FactorySet) `FactorySet(address factory)` topic0 0x1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b1 | The factory was wired (once). Emitted by [setFactory](#setFactory) |
| [OwnershipTransferred](#event-OwnershipTransferred) `OwnershipTransferred(address indexed previousOwner, address indexed newOwner)` topic0 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0 | Ownership moved to a new owner (at deployment, or when a pending owner accepted). Emitted by [acceptOwnership](#acceptOwnership), `constructor` |
| [OwnershipTransferStarted](#event-OwnershipTransferStarted) `OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner)` topic0 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700 | The owner named a pending owner; ownership moves when that account accepts. Emitted by [transferOwnership](#transferOwnership) |
| [PositionLocked](#event-PositionLocked) `PositionLocked(address indexed token, uint256 indexed tokenId)` topic0 0x2cabb2a2973327d5863ceb4707e9441851243897e86d587ee35943599752eb54 | A coin's graduated pool position was locked forever. Emitted by [lockPosition](#lockPosition) |
| [TokenSupplyLocked](#event-TokenSupplyLocked) `TokenSupplyLocked(address indexed token, uint256 amount)` topic0 0xaf33c4aba92959b3e7ddc83ab728938262da159a6c05ca836f6c46f9bcb2c740 | Coins not needed to seed the pool were locked forever. Emitted by [lockTokenSupply](#lockTokenSupply) |

Two launcher sets on Base

Addresses are listed for launcher 2.1.0, where new coins launch, and for launcher 2.0, which keeps serving the coins launched before the cutover. A coin stays on the set that launched it. The functions and events are the 2.1.0 contracts'; the 2.0 contracts are an earlier version of the same code and have no interface registry, so check a 2.0 contract's verified source on Basescan before relying on a detail listed here.

How the fees are split is on [fees](https://baselaunch.app/fees), what the owner can and cannot change is on [security](https://baselaunch.app/security), and short answers are in the [FAQ](https://baselaunch.app/faq).

Meme coins are highly speculative and most lose their value. Nothing here is financial advice.

Last updated 2026-10-21.

Canonical page: https://baselaunch.app/docs/reference/locker
