The diagram shows how a hook is integrated into the asset swap process. When the swap()
function is called, the address of the hook smart contract is passed along with the function parameters. If the beforeSwap()
hook is defined in that contract, the call is redirected to it. Then, the call returns and the main swap execution on Uniswap takes place. After the swap, the afterSwap()
hook is triggered in the same way.
If a hook is not specified in the hook smart contract, the hook call is simply ignored during execution.
Hook Insertion Points
There are several pool operations that can be influenced by a hook smart contract:
1) When initializing a pool:
• beforeInitialize: The hook will be triggered before the pool is initialized.
• afterInitialize: The hook will be triggered after the pool is initialized.
2) Adding or removing liquidity:
• beforeAddLiquidity: The hook will be triggered before adding liquidity.
• afterAddLiquidity: The hook will be triggered after adding liquidity.
• beforeRemoveLiquidity: The hook will be triggered before removing liquidity.
• afterRemoveLiquidity: The hook will be triggered after removing liquidity.
3) Swap Hooks:
• beforeSwap: The hook will be triggered before the asset swap.
• afterSwap: The hook will be triggered after the asset swap.
4) Donate Hooks:
• beforeDonate: The hook will be triggered before a donation to the pool.
• afterDonate: The hook will be triggered after a donation to the pool.
A hook can affect all the operations described above and be integrated into all possible pool points — or only into some of them.
Interesting Points
First point. The beforeInitialize and afterInitialize hooks are executed only once, while all other types of hooks can be used an unlimited number of times.
Second point. Hooks for pool donations. What are donations? Donations are a new feature that allows assets to be contributed to a pool. It’s a kind of direct payment to the pool’s liquidity providers, which can be viewed as tipping. It can be used like a classic donation system, but with crypto assets.
For example, a project launches a pool (protocol token and stablecoin). Using a hook smart contract, a mechanism for initial token sales in exchange for the stablecoin is implemented. But if a user likes the project, they can make a donation without needing to buy the protocol token.
Third point. Hooks allow for intervention in swap logic. From access control to modifying swap fees and implementing a new pricing curve—whatever your imagination can come up with can be built using hooks. For instance, you could implement a StableSwap-like mechanism (like Curve) for stablecoin swaps.
Singleton Design
One pool for all token pairs, which is cheaper than creating separate smart contracts for each pool (as it was in Uniswap v2 and Uniswap v3).
A new architecture is introduced called the «Singleton Design», which means that all pools are implemented within a single smart contract — PoolManager.sol. This smart contract defines the logic for managing pools and operations. This approach helps save on gas when creating pools.
Moreover, complex asset swaps involving multiple pools become simpler. There's no longer a need to transfer assets between different pool contracts, since all pools are now implemented within a single smart contract. It's enough to just update the balances inside this unified contract.
However, don’t think that the new version is just a single smart contract for everything. First of all, just like in previous versions, there are two repositories: v4-core and v4-periphery. Core still handles the pools, while periphery is responsible for routing. There are also many additional contracts that implement various parts of the logic — for pools, routers, NFTs, and math. You’d run out of fingers trying to list all the contracts across different libraries.
With the release of newer protocol versions, routing has become a bit more complex. To unify routing, another smart contract is used — UniversalRouter.sol. It determines which version's router a call should be sent to. Everything related to routing is kept in a separate repository.
Thus, the fourth version of the protocol works schematically as follows: