# Uniswap v4-core: the singleton PoolManager behind v4 pools

> Uniswap v4-core holds the pool logic for v4: one PoolManager contract, an unlock and callback cycle, and optional hook contracts. It is Solidity library code for integrators, not a front end, and the README still describes it as draft code released for public building.

**Uniswap/v4-core** — 🦄 🦄 🦄 🦄 Core smart contracts of Uniswap v4

- Repository: https://github.com/Uniswap/v4-core
- Website: https://blog.uniswap.org/uniswap-v4
- Stars: 2,536 · Forks: 1,330
- Language: Solidity
- License: not declared
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/uniswap-v4-core

## The problem v4-core solves: one contract holding every pool

Earlier Uniswap versions deployed a separate contract per pair. v4-core takes a different route. The README describes a singleton-style architecture in which all pool state lives in a single PoolManager.sol contract. Creating a pool and executing pool actions such as swapping and providing liquidity all go through that one address.

The audience follows from that design. This repository is for Solidity developers who need pool logic as a dependency: teams writing routers, hook contracts, or their own integration on top of v4. It is not an application. There is no user interface, no deployment guide for a live chain, and no claim in the README that the code is finished. The README states the contracts are in early stages and that the draft code was released so v4 can be built in public, with the expectation of a months-long process. Read that sentence as a scope statement: v4-core gives you the pool engine, and assumes you bring the rest.

## Unlock callbacks and delta accounting inside PoolManager

The mechanism is an unlock and call cycle. Pool actions can only be taken after an initial call to unlock, and callers implement the IUnlockCallback interface to receive control back inside that unlock. The README lists the actions available in that context: swap, modifyLiquidity, donate, take, settle, mint and burn. Pool initialization is the exception; it can happen outside an unlock.

Inside an unlock, the contract tracks only net balances owed to the user (positive) or to the pool (negative). That is the delta field held in the unlock state. The constraint is strict: any number of actions can run during the unlock, as long as the accumulated deltas reach 0 by the release. This is what lets an integrator chain several pool operations in one transaction without moving tokens between each step, and it is also where an integration fails if the final delta does not settle.

Hooks attach to the same lifecycle. A pool may be initialized with a hook contract implementing before and after callbacks for initialize, add liquidity, remove liquidity, swap and donate. The README is explicit about the boundary: hook logic may be updated by the hook's own implementation, but which callbacks execute on a pool cannot change after pool initialization. That immutability is a design choice with consequences, since it means a pool's callback set is fixed at creation and cannot be revised later.

## Installing v4-core with forge and making a first unlock call

The README gives one installation path: forge install against the repository URL. The justfile in the repository shows the same toolchain in use, with a build-forge recipe running forge build and a test-forge recipe running forge test --isolate, both preceded by forge install.

```bash
forge install https://github.com/Uniswap/v4-core
```

After that, integration starts from the interfaces. The README shows a contract implementing IUnlockCallback and holding an IPoolManager reference. The pattern is: your function calls poolManager.unlock(...), the PoolManager calls back into unlockCallback, and you perform pool actions there.

```solidity
import {IPoolManager} from 'v4-core/contracts/interfaces/IPoolManager.sol';
import {IUnlockCallback} from 'v4-core/contracts/interfaces/callback/IUnlockCallback.sol';

contract MyContract is IUnlockCallback {
    IPoolManager poolManager;

    function doSomethingWithPools() {
        poolManager.unlock(...);
    }

    function unlockCallback(bytes calldata data) external returns (bytes memory) {
        if (msg.sender != address(poolManager)) revert Unauthorized();
        poolManager.swap(...);
    }
}
```

Two things to note before copying that snippet. The README's example guards the callback with a caller check against the PoolManager address, and that guard is not optional, because the callback is externally reachable. Also check the import path against your own remappings: the README writes v4-core/contracts/interfaces/..., while the repository structure section places all contracts under v4-core/src. The README does not explain that difference, so verify it in remappings.txt rather than assuming either path works.

## Where v4-core is the wrong dependency

The repository is explicit that the contracts are in early stages and that the draft code was released for public building. If your project needs a stable, frozen pool implementation with a documented upgrade path, that statement is the signal to wait or to pin a release and treat upgrades as events to review.

The second limitation is scope. v4-core is the core pool logic only. A complete integration needs more than this repository, and the README does not document the surrounding pieces. There is no router here, no position manager, and no user-facing contract set. If you are looking for something to deploy and point a front end at, this is the wrong layer.

The third is the unlock model itself. Every pool action has to sit inside an unlock, and the deltas have to net to zero before release. That is a good fit for contracts that batch operations and settle at the end. It is a poor fit for a simple script that wants to perform one swap and return, because you still have to implement the callback and satisfy the delta constraint.

Finally, the repository does not document rollback or upgrade behaviour in the README, and the README does not describe deployment to a live network. Treat any assumption about deployed addresses or migration as unverified against this material.

## v4-core compared with a per-pair pool contract

The alternative approach is the one earlier Uniswap versions used: a separate contract deployed for each pair, with its own state and its own address. The difference is not cosmetic. With per-pair contracts, pool state is spread across many deployments, and each new pair is a new contract. With v4-core, all pool state sits in PoolManager.sol, and a pool is a record inside that contract rather than a separate deployment.

That changes what integration looks like. A per-pair design lets you call a single pool contract directly. The singleton pushes you through the unlock cycle and the delta accounting described above, because the contract has to know which balances are owed where across all the actions in that unlock. The README frames this as the trade: the unlock and call style architecture gives callers maximum flexibility in integrating with the core code, at the cost of implementing the callback and closing out deltas yourself.

The hook system is the other half of the comparison. A per-pair contract has whatever logic it was deployed with. A v4 pool can carry a hook contract with before and after callbacks across initialization, liquidity changes, swaps and donations, with the callback set fixed at pool initialization.

## Licence position and the cost of tracking v4-core

Uniswap V4 Core is licensed under the Business Source License 1.1 and the MIT License, according to the README, which links to a BUSL_LICENSE file and an MIT_LICENSE file under licenses/. The README adds the detail that matters most for anyone copying code: each file in Uniswap V4 Core states the applicable license type in its header. The package.json lists BUSL-1.1 as the package licence, which does not override the per-file headers. Check the header of the specific file you are reusing rather than the repository as a whole. This is a description of what the repository states, not legal advice.

On maintenance cost, the last push to the default branch was on 2026-04-24, and the repository is not archived. The only release listed is v4.0.0 from 2025-01-23. The practical consequence for an integrator is that the interfaces you import are the thing to watch: if IPoolManager or the callback interface changes, your contract changes with it. The repository has a foundry.toml, a remappings.txt and a snapshots/ directory, and the justfile wraps the build and test commands, so the intended workflow is to build and test locally with forge rather than to consume a published artefact. The package.json carries a publishConfig with provenance enabled, but the README's install instruction is forge install, not a package manager.

## Conclusion

Uniswap v4-core is for Solidity engineers building pools, routers or hook contracts on v4, and for auditors reading the pool logic. It is not for anyone who wants a deployed exchange interface: there is no app here, no deployment script in the README, and the repository itself calls the contracts early-stage draft code. Before adopting it, check the licence header of each file you copy, because the repository carries both BUSL-1.1 and MIT and states the applicable license per file, and confirm the import path you use, since the README imports from v4-core/contracts/interfaces/ while the repository layout keeps contracts under src/. Resolve that path question before you write integration code against it.

## FAQ

### What is Uniswap v4-core used for?

It hosts the core pool logic for Uniswap v4: creating pools and executing pool actions such as swapping and providing liquidity. All pool state is managed in the PoolManager.sol contract, and integrators reach it through an unlock call and an unlockCallback implementation.

### How do I install Uniswap v4-core?

The README gives one command, forge install https://github.com/Uniswap/v4-core. The repository justfile then wraps forge build and forge test --isolate through its build-forge and test-forge recipes.

### What licence does Uniswap v4-core use?

The README states it is licensed under the Business Source License 1.1 and the MIT License, and that each file states the applicable license type in its header. The package.json lists BUSL-1.1 for the package.

### Can I swap on a Uniswap v4-core pool with a single call?

Not directly. Pool actions can be taken after an initial call to unlock, and the deltas accumulated during the unlock must reach 0 by the release. Your contract has to implement unlockCallback and settle the net balances before the unlock releases.

### Can a Uniswap v4 pool change its hooks after creation?

No. The README states that which callbacks are executed on a pool cannot change after pool initialization, though the callback logic itself may be updated by the hook's implementation.

## Sources

- [Issues](https://github.com/Uniswap/v4-core/issues)
- [Project website](https://blog.uniswap.org/uniswap-v4)
- [README](https://github.com/Uniswap/v4-core/blob/main/README.md)
- [Releases](https://github.com/Uniswap/v4-core/releases)
- [Uniswap/v4-core on GitHub](https://github.com/Uniswap/v4-core)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/uniswap-v4-core
