Back to all stories
Blogs
Tech & Dev
PancakeSwap Infinity: Hooks Security Considerations
5/7/2025
PancakeSwap Infinity: Hooks Security Considerations

PancakeSwap Infinity was deployed on BNB Mainnet in March 2025, and brought significant improvements in adaptability and scalability to the leading decentralized exchange platform. In PancakeSwap Infinity, accounting logic is decoupled from the AMM logic in a modular architecture that consists of the Vault, Pool Managers (initially consisting of CLPoolManager and BinPoolManager), and Hooks. The Vault contract holds all token balances from liquidity providers. The AMM layer implements the logic of the decentralized exchange, and initially consists of a concentrated liquidity pool (CLPoolManager) and a liquidity book pool (BinPoolManager). The AMM layer can be further expanded to additional pools in the future, offering adaptability to the protocol.

Hooks enable a wide range of applications that third party developers can build on top of PancakeSwap. This modular architecture allows for easier integration of evolving AMM paradigms without requiring a complete protocol overhaul.

Figure 1 Figure 1: Modular Architecture of PancakeSwap Infinity

This article discusses some of the new features of PancakeSwap Infinity, and explores the security considerations related to PancakeSwap Infinity hooks.

Introduction to PancakeSwap Infinity and Hook Integration

PancakeSwap Infinity introduces several new features:

  1. Customizable hooks, through which developers can attach bespoke logic to the liquidity provision and swapping lifecycle
  2. Singleton design, where a single Vault contract holds all token balances, and each AMM implementation / pool type has an independent singleton PoolManager implementation
  3. Flash accounting system, where transaction settlement is consolidated in the end, reducing gas consumption

One of the key mechanisms in the vault is the lock mechanism. Callers need to get a lock from the vault before performing any operation (swap, modify liquidity or donate) with the pool manager.

Figure 2 Figure 2: Lock Mechanism of the Vault

Infinity hooks can be placed before/after initializing a liquidity pool, before/after modifying liquidity, before/after swapping, and before/after donating, as shown in Figure 3 for CL hooks. Using swapping as an example, the simplified diagram in Figure 4 shows how CL hooks fit into the workflow. For Bin hooks, the workflow is similar with slight differences in function names for liquidity modification (e.g. beforeMint() in Bin hooks instead of beforeAddLiquidity() for CL hooks).

Figure 3 Figure 3: List of Hook Callbacks

Figure 4 Figure 4: Hook Interaction in Token Swap

For swapping and liquidity modification (adding or removing liquidity), hook calls can potentially modify the delta being used in the flash accounting system. For every pool on PancakeSwap Infinity, the PoolKey stores the deployed hook address (if a hook is used), and also stores the hook permissions in the parameters field. Once a hook is deployed, the hook permissions cannot be changed.

Security Considerations of PancakeSwap Infinity Hooks

Our team has reviewed hook contracts from PancakeSwap affiliated hackathons, including the top submissions of PancakeSwap V4 Hookathon. Several themes have emerged that indicate common issues in PancakeSwap hooks, including:

  1. Access Control of Hook Functions
  2. Interference of Different Liquidity Pools on Hook State Variables
  3. Centralization Risks
  4. Hook Permission Mismatch
  5. Potential Denial-of-Service Vulnerabilities

Additionally, while not directly observed from hackathon submissions, developers and hook users should also pay attention when hooks modify delta in the swapping or liquidity provision workflow.

1) Access Control of Hook Functions

The most common mistake we have observed from reviewing hook contracts is missing or inadequate access control of hook functions. Specifically, certain functions in the hook contract should only be called by the PoolManager contract, and some functions should only be called by the Vault contract.

The PancakSwap Infinity BaseHook contracts already include the poolManagerOnly and vaultOnly modifiers. Additionally, the lockAcquired() function contains the vaultOnly modifier, and the various hook functions contain the poolManagerOnly modifier.

Code 1 Sources: Github and Github

Code 2 Source: Github

However, many hook developers forget to enforce the same access control in their custom hook contracts. In the example below, the afterAddLiquidity() function overrides the function in the base hook contract, but does not contain any access control. As a result, anyone can call the function directly with arbitrary input. A liquidity provider can call this hook function directly without providing incremental liquidity, and repeatedly push the positionParams with his own address as the position owner to the userPositions array.

Code 3 Source: Github

Note that, in the listRewards() function of the same hook contract, the for loop iterates through the positionParams array, and adds all the rewards for each position cumulatively. The claimReward() function then transfers the cumulative reward to the liquidity provider. This allows the liquidity provider to multiply his rewards without providing incremental liquidity, and potentially drains the rewards that should’ve been reserved for other liquidity providers.

Code 4 Source: Github

Code 5 Source: Github

As another example, the afterInitialize() function of the hook contract below does not have any access control, and modifies the pools mapping in storage. A malicious actor could overwrite the value of pools[poolId] for any existing poolId, which makes the hook unusable for the poolId being overwritten.

Code 6 Source: Github

In both examples above, the vulnerabilities can be addressed by including sufficient access control to the relevant hook functions. Generally, only the PoolManager contract should be able to call the hook functions in the hook contract, where the function arguments come from the PoolManager contract instead of arbitrary user input.

2) Interference of Different Liquidity Pools on Hook State Variables

PancakeSwap Infinity does not restrict who can create new liquidity pools, nor which hook address to use in a new liquidity pool. If a hook is not restricted to a specific pool or set of pools, an attacker could deploy a malicious pool with fake tokens using the hook. This can potentially compromise the hook contract for the liquidity pools it’s intended to support.

Developers of hook contracts should make explicit whether the hook should be used only by a specific liquidity pool, a subset of liquidity pools, or all liquidity pools, including pools with potentially malicious tokens. By default, if the beforeInitialize() and afterInitialize() functions do not restrict which pools can use the hook contract, the hook can be used and initialized by any liquidity pool, and the hook contract should be able to handle them so that one liquidity pool does not interfere with the logic of another liquidity pool in the hook contract.

In the following hook contract, the afterInitialize() function does not restrict which pool can use the hook (also does not restrict the caller to be the Pool Manager contract). As a result, anyone can use the hook for any pool, and overwrite the token0 and token1 addresses which are storage variables in the hook contract. The rest of the hook contracts contain logic to deposit a portion of unused liquidity to AAVE to generate yield, but when the token0 and token1 addresses are overwritten, the hook would be unusable for its intended liquidity pools.

Code 7 Source: Github

The hook contract below is designed to incentivize liquidity providers (LPs) through various reward mechanisms. However, it does not restrict which pool can use the hook, and the afterAddLiquidity() function also does not validate the PoolKey. As a result, anyone can deploy a liquidity pool with useless tokens using this hook contract, and add liquidity to modify the value of the liquidityProviders[sender] variable which is used to calculate rewards. The user could subsequently extract reward from the hook contract.

Code 8 Source: Github

To prevent such situations, hooks that are designed for specific pools should validate token pairs / PoolId or PoolKey during initialization. This can be done in the beforeInitialize() or afterInitialize() functions. If a hook is designed to support any token pairs, developers should pay special attention to how a fake or malicious token pair could potentially compromise the hook contract. Usage of mappings where the key is PoolId is a common technique to separate different liquidity pools in hook storage. Robust access control and input validation could also mitigate some of the risks associated with supporting arbitrary token pairs.

3) Centralization risks

Similar to any smart contract, there can be legitimate reasons for a hook contract to include privileged roles. However, if a privileged address is compromised, there could be significant risks. For example, if an upgradeable hook holds user funds, the address with the upgrade authority is capable of injecting a malicious withdrawal function via contract upgrade. As such, the usage of upgradeable contracts should be limited for hook contracts, and risk mitigation mechanisms such as multisig / DAO + timelock are also applicable to hook contracts.

The following hook implements a fee discount mechanism. The setDefaultDiscount() function allows the hook owner to set the defaultDiscount to any arbitrary value with no restrictions. If the hook owner is compromised, the hook could end up taking a higher pool fee at any time.

Code 9 Source: Github

Similarly, the updatePoolFeeByPoolKey() function in the hook contract below allows the owner to change the LP fee at any time.

Code 10 Source: Github

4) Hooks Permission Mismatch

Each hook is designed to operate with specific permissions in PancakeSwap Infinity. Hook developers must implement a getHooksRegistrationBitmap() function in the hook contract that returns the permission of the hook, and when the pool is initialized in the PoolManager contract, use the return value of the function to encode the parameters field of the PoolKey.

Code 11 Source: Github

Code 12 Source: Github

Code 13 Source: Github

Additionally, hook permissions being registered in the bitmap should match the hook callback functions implemented. An incorrect implementation may occur when a hook function is implemented that lacks the necessary permissions, or conversely, when the hook registration bitmap has the permission, but the function itself is not implemented.

In the following example, the hook has the beforeRemoveLiquidity() function implemented that returns the correct function selector, but lacks the permission for this hook call in the registration bitmap.

Code 14 Source: Github

Code 15 Source: Github

5) Potential Denial-of-Service Vulnerabilities

A hook could contain different revert conditions that are necessary, but it is important to ensure that key user flows, such as liquidity withdrawals, are not subject to unwarranted reverts. By deliberately reverting during the beforeRemoveLiquidity() or afterRemoveLiquidity() functions, a hook could permanently trap user funds in the protocol. There might be special situations where these revert conditions are the intended design, but these should be exceptions, and the behavior should be well-documented and disclosed to users.

In the following example, the _beforeRemoveLiquidity() function reverts when block.timestamp exceeds a predetermined auction.lpWithdrawTime. If liquidity providers do not take actions before the deadline, its liquidity could be permanently locked.

Code 16 Source: Github

6) Hooks that Modify Delta

The PoolManager in PancakeSwap Infinity allows hooks to return a hookDelta in the mint(), burn(), and swap() functions, provided that the hook has the necessary permissions. The hookDelta essentially modifies how delta is attributed between the msg.sender and the hook contract address. Given that all deltas need to be settled in order for a transaction to succeed, such attribution potentially dictates which party is responsible for settling which portions of the total delta.

This can introduce serious risks if the accounting is incorrect or intentionally manipulated to benefit the hook operator at the expense of users, or to benefit one group of users at the expense of another group. For example, if a hook manipulates the delta when users of the hook blindly approve the token amount needed to settle the user delta, the hook could extract extra value from the user.

Code 17 Sources: Github, Github and Github

Summary

PancakeSwap Infinity sets the stage for more community-driven development, encouraging developers to create novel DeFi applications on top of its infrastructure. The introduction of hooks offers virtually limitless possibilities for customization, facilitating innovation in areas like capital-efficient LP management, custom trading strategies, and complex Oracle design. However, with great flexibility comes the potential of a broader attack surface.

In this article, we discussed how hooks integrate with PancakeSwap Infinity, as well as the security considerations. Like any smart contract development, performing rigorous security review should be an indispensable step in the development lifecycle.

CertiK has deep technical expertise in securing DeFi protocols, and stands ready to work with the PancakeSwap Infinity hook developer community to help secure the ecosystem.

Elevate Your Web3 Journey
Ready to take the next step? Connect with our sales team to request your free quote and secure your project today!
Client Testimonials