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
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 PositionManager
Uniswap v4 Universal Router
Uniswap v4 Singleton architecture and flash accounting
Uniswap v4 operations and lifecycle
Uniswap v4 multihopping and quoting
How to build a Uniswap v4 swap router
How to build a smart contract a liquidation bot executes
Last updated on November 6, 2025
Duration: 5min
Duration: 7min
Duration: 39min
Duration: 35min
Duration: 34min
Duration: 31min
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 PositionManager
Uniswap v4 Universal Router
Uniswap v4 Singleton architecture and flash accounting
Uniswap v4 operations and lifecycle
Uniswap v4 multihopping and quoting
How to build a Uniswap v4 swap router
How to build a smart contract a liquidation bot executes
Last updated on November 6, 2025