# Configure a sender allowlist with AdvancedPoolHooks using Foundry
Source: https://docs.chain.link/ccip/evm/tutorials/cross-chain-tokens/configure-sender-allowlist-advanced-pool-hooks-foundry
Last Updated: 2026-05-05

> For the complete documentation index, see [llms.txt](/llms.txt).

## Guide Versions

- [Foundry](/ccip/evm/tutorials/cross-chain-tokens/configure-sender-allowlist-advanced-pool-hooks-foundry)

- [Hardhat](/ccip/evm/tutorials/cross-chain-tokens/configure-sender-allowlist-advanced-pool-hooks-hardhat)

CCIP 2.0 token pools support an optional [`AdvancedPoolHooks`](https://github.com/smartcontractkit/chainlink-ccip/tree/contracts-ccip-v2.0.0/chains/evm/contracts/pools/AdvancedPoolHooks.sol) contract being attached to them.

This contract can run certain checks:

1. before tokens are locked/burned (source chain)
2. before tokens are released/minted (destination chain)

If no hooks contract is attached, the token pool keeps its existing behavior.

This tutorial covers the **sender allowlist** use case: only approved addresses may initiate outbound transfers on the source chain. A sender not on the list reverts the source transaction with `SenderNotAllowed`. For the other capabilities, see the [AdvancedPoolHooks concept page](/ccip/concepts/cross-chain-token/advanced-pool-hooks) or [Enforce ACE policies on CCIP token transfers](/ccip/evm/tutorials/cross-chain-tokens/enforce-ace-policies-foundry).

Hooks are enforced only when **both** of these aspects are configured:

- The token pool points to the `AdvancedPoolHooks` contract.
- The hooks contract authorizes that token pool as a caller.

Authorize the pool before attaching hooks so the first hook call does not revert. Hooks are configured **per token pool, per chain**, which means that:
you need to repeat this setup for any other pool where you want hooks enforced.

> **Note:** Remember. Your CCT token can be deployed on multiple chains, with each chain having its own token pool.

In this tutorial you will:

1. Review the current hooks state on your deployed token pool.
2. Send a baseline transfer (*with no hooks attached*). This should succeed.
3. Deploy an `AdvancedPoolHooks` contract with your deployer address on the allowlist.
4. Authorize the pool as a caller on the hooks contract and attach the hooks contract to the token pool.
5. Verify the hooks attachment, authorized callers, and allowlist state.
6. Remove your address from the allowlist.
7. Attempt a transfer (*expected to revert with `SenderNotAllowed(address)`*).
8. Detach the hooks contract.
9. Send a transfer again (*expected to succeed*).
10. Manage the allowlist over time (add, remove, and check addresses).

## Before You Begin

## Tutorial

> **CAUTION: Educational Example Disclaimer**
>
> Please note, this page contains community examples only — these are not Chainlink products or services and are not
> supported or maintained by Chainlink. This code represents an example of using a Chainlink product or service, and is
> intended for demonstration and educational purposes only. It is provided "AS IS" and "AS AVAILABLE" without warranties
> of any kind, may not have been audited, and may omit checks or error handling. Each party intending to use this
> example code does so entirely at their own risk and must perform its own audits, security and code review, key
> management, and testing before any production deployment and ensure the operation and performance of such code matches
> expectations. Neither Chainlink Labs nor the Chainlink Foundation deploys, operates, monitors, maintains or endorses
> any deployment of this code. Note that this is not a Chainlink product, feature or service, and there are no
> commitments made with respect to the code, including compatibility with future Chainlink releases. You should not rely
> on this code without first conducting your own technical, engineering, and security review. This code is also outside
> the scope of any Chainlink bug bounty programs. Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node
> operators are responsible for outcomes due to errors in this example or how it is deployed or operated, or liable for
> any resulting claims or damages. Use of the Chainlink Network is subject to the Chainlink Foundation [Terms of
> Service](https://chain.link/terms), which provides important information and disclosures. By using this code, you
> acknowledge and agree to these terms.