ContractsLocker

Locker

Contracts/src/contracts/Locker.sol

The Locker is the protocol’s central registry and NFT custodian. It owns the CollectionToken clones (one per collection), holds the floor pool of NFTs, and is the only contract authorised to call NFTXV4Hook.registerCollection / initializeCollection.

Deployed addresses

ChainAddress
Base mainnet (8453)see Frontend/packages/config/src/contracts.ts
Base Sepolia (84532)see Frontend/packages/config/src/contracts.ts

State views

FunctionReturns
tokenImplementation()The shared CollectionToken master clone address
implementation()INFTXV4Hook — the Uniswap V4 hook
lockerManager()ILockerManager — manager allowlist
listingsAt(uint _index)The Nth registered IListings
listingsLength()Number of registered IListings
collectionShutdown()ICollectionShutdown — shutdown lifecycle
collectionToken(address _collection)The ICollectionToken clone for a registered collection
collectionInitialized(address _collection)True once the V4 pool is bootstrapped
isCollectionToken(address _token)Reverse lookup: is this address one of our clones
collectionSunset(address _collection)True for retired collections
isListing(address _collection, uint _tokenId)Whether (_collection, _tokenId) has an active liquid/dutch listing
paused()Pause flag
permissionlessCreateCollection()Whether non-owners can create collections
collectionCreationFee() / collectionCreationFeeRecipient()Fee for creating a new collection

Public surface

Lifecycle

FunctionCallerDescription
createCollection(_collection, _name, _symbol)Anyone (or owner if permissionlessCreateCollection == false)Registers an ERC-721 and deploys its CollectionToken clone. payable; msg.value == collectionCreationFee() enforced. Returns the clone address.
initializeCollection(_collection, _eth, _tokenIds, _tokenSlippage, _sqrtPriceX96)Approver of seed liquidityBootstraps the V4 pool. Forwards to NFTXV4Hook.initializeCollection.
sunsetCollection(_collection)Owner / CollectionShutdownPermanently retires a collection (post-execute).
withdrawToken(_collection, _tokenId, _recipient)OwnerEmergency withdrawal of a stuck NFT.

Errors: InvalidERC721, CollectionAlreadyExists, CollectionPreviouslySunset, CollectionDoesNotExist, CollectionAlreadyInitialized, CollectionCreationFeeDoesNotMatch(received, required), CreateCollectionRestrictedToOwner, Paused.

Floor pool

FunctionDescription
deposit(_collection, _tokenIds)Send NFTs in, receive tokenIds.length * 1e18 CollectionToken
deposit(_collection, _tokenIds, _recipient)Same, with custom recipient
redeem(_collection, _tokenIds)Burn 1e18 per token, receive the NFTs
redeem(_collection, _tokenIds, _recipient)Same, with custom recipient
swap(_collection, _tokenIdIn, _tokenIdOut)1-for-1 NFT swap; CT-neutral
swapBatch(_collection, _tokenIdsIn, _tokenIdsOut)N-for-N variant

Errors: NoTokenIds, TokenIdsLengthMismatch, CannotSwapSameToken, TokenIsListing(_tokenId), InsufficientTokenIds, Paused.

Registry / governance

FunctionCallerDescription
addListings(_listings)OwnerRegisters a new IListings contract
removeListings(_listings)OwnerDe-registers an IListings contract
setCollectionShutdownContract(_collectionShutdown)OwnerWires up the shutdown contract
setCollectionCreationFee(_fee)OwnerUpdates createCollection fee
setCollectionCreationFeeRecipient(_recipient)OwnerUpdates fee recipient
setPermissionlessCreateCollection(_permissionless)OwnerToggles the open create-collection mode
pause(_paused)OwnerPauses the protocol

Errors: ListingsAlreadyRegistered, ListingsNotRegistered, ZeroAddress, CannotChangeImplementation, UnapprovedCaller, CallerIsNotManager, InvalidCaller.

Events

EventNotes
CollectionCreated(_collection, _collectionToken, _name, _symbol, _creator)New collection registered
CollectionInitialized(_collection, _poolKey, _tokenIds, _sqrtPriceX96, _sender)Pool bootstrapped
CollectionSunset(_collection, _collectionToken, _sender)Retired
TokenDeposit(_collection, _tokenIds, _sender, _recipient)Floor pool ↑
TokenRedeem(_collection, _tokenIds, _sender, _recipient)Floor pool ↓
TokenSwap(_collection, _tokenIdIn, _tokenIdOut, _sender)1-for-1 swap
TokenSwapBatch(_collection, _tokenIdsIn, _tokenIdsOut, _sender)N-for-N swap
ListingsContractAdded(_listings) / ListingsContractRemoved(_listings)Registry mutations
CollectionShutdownContractUpdated(_collectionShutdown)Shutdown contract pointer
CollectionCreationFeeUpdated(_collectionCreationFee)Fee tweak
CollectionCreationFeeRecipientUpdated(_collectionCreationFeeRecipient)Recipient tweak
PermissionlessCreateCollectionUpdated(_permissionless)Toggle

The Locker also forwards every floor mutation to the IListings registry so each Listings contract can keep its derivative state in sync. There is no separate Listings.deposit entry-point.

Inherited surface

  • Pausablepaused() / pause(bool).
  • Ownableowner() / transferOwnership(address).
  • ReentrancyGuard on every state-changing entry-point.