5/5
## Understanding the Core Architecture of Uniswap v4 Uniswap v4 introduces a revolutionary "singleton" architecture centered around a single, powerful contract known as the `PoolManager`. This contract is the brain of the protocol, managing all pools, liquidity, and user interactions. To facilitate user-friendly operations, developers interact with the `PoolManager` not directly, but through peripheral contracts, commonly referred to as `Router` contracts. A key innovation in this architecture is "flash accounting." Unlike previous versions where token transfers happened with each swap, the `PoolManager` now tracks the net balance changes, or "deltas," for each token owed to or by the interacting contract. The actual settlement of these balances—the physical token transfers—occurs only once at the end of the entire transaction. This dramatically reduces the number of token transfers, leading to significant gas savings. To ensure that all debts are settled by the end of a transaction, every interaction is wrapped within a lock. This process is initiated by calling the `unlock` function on the `PoolManager`. This grants the calling contract temporary control via a callback, during which it can perform its desired actions. The `PoolManager` enforces that by the time the `unlock` function completes, all currency deltas for the caller have been balanced back to zero. ## The Step-by-Step Swap Process with the PoolManager Executing a token swap in Uniswap v4 involves a precise sequence of calls orchestrated by a `Router` contract interacting with the `PoolManager`. This process leverages the flash accounting and lock mechanism to ensure atomicity and gas efficiency. **1. Initiate the Lock with `unlock()`** The entire operation begins when the `Router` calls the `unlock` function on the `PoolManager`. This signals the start of a series of actions and activates the flash accounting system for the transaction. **2. Execute Logic via the `unlockCallback()`** Upon receiving the `unlock` call, the `PoolManager` immediately makes a callback to the `Router`, invoking a required function named `unlockCallback`. All the core logic for the swap must be executed within this callback function. **3. Perform the Swap and Settle Balances** Inside the `unlockCallback`, the `Router` performs a sequence of calls on the `PoolManager` to execute the swap and settle the resulting token balances. * **Call `swap()`:** The `Router` calls the `swap` function on the `PoolManager`, specifying the pool details and the amount to be swapped. The `PoolManager` calculates the result of the swap but does not yet transfer any tokens. Instead, it updates its internal ledger, recording a positive delta for the output token (owed to the `Router`) and a negative delta for the input token (owed by the `Router`). * **Call `take()` to Receive Tokens:** The `Router` calls the `take` function to withdraw the tokens it is now owed from the swap. This call triggers the actual `transfer` of the output tokens from the `PoolManager` to the `Router`. * **Call `sync()` to Prepare for Payment:** Before the `Router` can pay its debt, it must call the `sync` function. This crucial step informs the `PoolManager` of the currency that is about to be settled and updates its internal state with its current balance of that token. * **Pay and Call `settle()` to Clear Debt:** The `Router` first initiates a standard ERC20 `transfer` to send the required input tokens to the `PoolManager` contract. Immediately after, it calls the `settle` function. The `PoolManager` uses this call to verify that it has received the correct amount of tokens and, upon confirmation, clears the `Router`'s negative delta for that currency. Once the `unlockCallback` function completes, the initial `unlock` call concludes. At this point, the `PoolManager` performs a final check to ensure all deltas for the caller are zero, guaranteeing that the entire operation is fully settled. ## Key Rules and Flexibility of the Flash Accounting System The flash accounting system provides significant flexibility in how operations are structured. Because settlement only happens at the end, the order of actions within the `unlockCallback` can be rearranged. For example, a `Router` could choose to pay its debt (`pay` and `settle`) *before* taking its output tokens (`take`). The only non-negotiable requirement is that all positive and negative deltas must sum to zero by the end of the `unlock` call. If any balance remains unsettled, the entire transaction will revert. Furthermore, there is one critical rule regarding the sequence of calls: **`sync()` must always be called immediately before `settle()`**. The `sync` function provides the necessary context for the `PoolManager` to correctly validate the incoming payment during the `settle` call. Failing to call `sync` beforehand will cause the settlement to fail. ## Bonus Use Case: Executing a Fee-Less Flash Loan The same powerful `unlock` mechanism can be repurposed to implement native, fee-less flash loans directly within the protocol. This is possible because the `take` function, which allows a contract to withdraw tokens, does not itself carry a fee. The process for a flash loan is as follows: 1. **Initiate with `unlock()`:** A contract calls `unlock` on the `PoolManager` to start the locked operation. 2. **Borrow with `take()`:** Inside the subsequent `unlockCallback`, the contract calls `take()` to borrow a desired amount of a token from a pool. The `PoolManager` transfers the tokens and records a negative delta for the borrowing contract, signifying its debt. 3. **Perform Arbitrary Actions:** The contract now possesses the borrowed funds and can use them for any purpose, such as executing an arbitrage trade on an external decentralized exchange. 4. **Repay the Loan:** Before the `unlockCallback` function finishes, the contract must repay the loan. It does this by calling `sync()` to declare the currency being returned, transferring the borrowed tokens back to the `PoolManager`, and finally calling `settle()` to clear its debt. As long as the borrowed funds are returned and the delta is zeroed out before the parent `unlock` transaction completes, the operation is valid. This creates a highly efficient and powerful primitive for developers to build sophisticated DeFi applications.
Uniswap v4 introduces a revolutionary "singleton" architecture centered around a single, powerful contract known as the PoolManager
. This contract is the brain of the protocol, managing all pools, liquidity, and user interactions. To facilitate user-friendly operations, developers interact with the PoolManager
not directly, but through peripheral contracts, commonly referred to as Router
contracts.
A key innovation in this architecture is "flash accounting." Unlike previous versions where token transfers happened with each swap, the PoolManager
now tracks the net balance changes, or "deltas," for each token owed to or by the interacting contract. The actual settlement of these balances—the physical token transfers—occurs only once at the end of the entire transaction. This dramatically reduces the number of token transfers, leading to significant gas savings.
To ensure that all debts are settled by the end of a transaction, every interaction is wrapped within a lock. This process is initiated by calling the unlock
function on the PoolManager
. This grants the calling contract temporary control via a callback, during which it can perform its desired actions. The PoolManager
enforces that by the time the unlock
function completes, all currency deltas for the caller have been balanced back to zero.
Executing a token swap in Uniswap v4 involves a precise sequence of calls orchestrated by a Router
contract interacting with the PoolManager
. This process leverages the flash accounting and lock mechanism to ensure atomicity and gas efficiency.
1. Initiate the Lock with unlock()
The entire operation begins when the Router
calls the unlock
function on the PoolManager
. This signals the start of a series of actions and activates the flash accounting system for the transaction.
2. Execute Logic via the unlockCallback()
Upon receiving the unlock
call, the PoolManager
immediately makes a callback to the Router
, invoking a required function named unlockCallback
. All the core logic for the swap must be executed within this callback function.
3. Perform the Swap and Settle Balances
Inside the unlockCallback
, the Router
performs a sequence of calls on the PoolManager
to execute the swap and settle the resulting token balances.
Call swap()
: The Router
calls the swap
function on the PoolManager
, specifying the pool details and the amount to be swapped. The PoolManager
calculates the result of the swap but does not yet transfer any tokens. Instead, it updates its internal ledger, recording a positive delta for the output token (owed to the Router
) and a negative delta for the input token (owed by the Router
).
Call take()
to Receive Tokens: The Router
calls the take
function to withdraw the tokens it is now owed from the swap. This call triggers the actual transfer
of the output tokens from the PoolManager
to the Router
.
Call sync()
to Prepare for Payment: Before the Router
can pay its debt, it must call the sync
function. This crucial step informs the PoolManager
of the currency that is about to be settled and updates its internal state with its current balance of that token.
Pay and Call settle()
to Clear Debt: The Router
first initiates a standard ERC20 transfer
to send the required input tokens to the PoolManager
contract. Immediately after, it calls the settle
function. The PoolManager
uses this call to verify that it has received the correct amount of tokens and, upon confirmation, clears the Router
's negative delta for that currency.
Once the unlockCallback
function completes, the initial unlock
call concludes. At this point, the PoolManager
performs a final check to ensure all deltas for the caller are zero, guaranteeing that the entire operation is fully settled.
The flash accounting system provides significant flexibility in how operations are structured. Because settlement only happens at the end, the order of actions within the unlockCallback
can be rearranged. For example, a Router
could choose to pay its debt (pay
and settle
) before taking its output tokens (take
).
The only non-negotiable requirement is that all positive and negative deltas must sum to zero by the end of the unlock
call. If any balance remains unsettled, the entire transaction will revert.
Furthermore, there is one critical rule regarding the sequence of calls: sync()
must always be called immediately before settle()
. The sync
function provides the necessary context for the PoolManager
to correctly validate the incoming payment during the settle
call. Failing to call sync
beforehand will cause the settlement to fail.
The same powerful unlock
mechanism can be repurposed to implement native, fee-less flash loans directly within the protocol. This is possible because the take
function, which allows a contract to withdraw tokens, does not itself carry a fee.
The process for a flash loan is as follows:
Initiate with unlock()
: A contract calls unlock
on the PoolManager
to start the locked operation.
Borrow with take()
: Inside the subsequent unlockCallback
, the contract calls take()
to borrow a desired amount of a token from a pool. The PoolManager
transfers the tokens and records a negative delta for the borrowing contract, signifying its debt.
Perform Arbitrary Actions: The contract now possesses the borrowed funds and can use them for any purpose, such as executing an arbitrage trade on an external decentralized exchange.
Repay the Loan: Before the unlockCallback
function finishes, the contract must repay the loan. It does this by calling sync()
to declare the currency being returned, transferring the borrowed tokens back to the PoolManager
, and finally calling settle()
to clear its debt.
As long as the borrowed funds are returned and the delta is zeroed out before the parent unlock
transaction completes, the operation is valid. This creates a highly efficient and powerful primitive for developers to build sophisticated DeFi applications.
A technical guide to the Uniswap v4 PoolManager - Discover how the central singleton contract uses "flash accounting" to execute gas-efficient swaps and flash loans. Understand the `unlock` locking mechanism and the sequence of calls required to settle token balance deltas.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 Singleton architecture
Uniswap v4 flash accounting
Uniswap v4 operations
Uniswap v4 lifecycle
How to build a Uniswap v4 swap router
Last updated on September 22, 2025
Duration: 5min
Duration: 7min
Duration: 39min
Duration: 35min
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 Singleton architecture
Uniswap v4 flash accounting
Uniswap v4 operations
Uniswap v4 lifecycle
How to build a Uniswap v4 swap router
Last updated on September 22, 2025