# Enforce ACE policies on CCIP token transfers using Foundry
Source: https://docs.chain.link/ccip/evm/tutorials/cross-chain-tokens/enforce-ace-policies-foundry
Last Updated: 2026-09-26

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

## Guide Versions

- [Foundry](/ccip/evm/tutorials/cross-chain-tokens/enforce-ace-policies-foundry)

- [Hardhat](/ccip/evm/tutorials/cross-chain-tokens/enforce-ace-policies-hardhat)

[`AdvancedPoolHooks`](https://github.com/smartcontractkit/chainlink-ccip/tree/contracts-ccip-v2.0.0/chains/evm/contracts/pools/AdvancedPoolHooks.sol) can forward each transfer to a [Chainlink ACE](/ace) Policy Engine for evaluation before the source token pool locks or burns tokens (`preflightCheck`) and before the destination token pool releases or mints tokens (`postflightCheck`). If a policy rejects the call, the hook reverts and the transfer does not proceed.

This tutorial covers the **ACE policy enforcement** use case on a working CCT lane. For the sender allowlist use case instead, see [Configure a sender allowlist with AdvancedPoolHooks](/ccip/evm/tutorials/cross-chain-tokens/configure-sender-allowlist-advanced-pool-hooks-foundry). For how the hook, engine, extractor, and policies fit together, read the [AdvancedPoolHooks concept page](/ccip/concepts/cross-chain-token/advanced-pool-hooks).

In this tutorial you will:

1. Reuse an existing working CCT lane between Ethereum Sepolia and Arbitrum Sepolia.
2. Deploy `AdvancedPoolHooks` on both chains with their Policy Engine addresses set, and attach them to both token pools.
3. Point the hooks at their Policy Engines with `setPolicyEngine` when the engine was not set at deployment or needs to change.
4. Complete the ACE Platform setup: target detection, contract-type assignment, policy creation, and extractor mappings.
5. Demonstrate a source `preflightCheck` rejection using the `from` parameter.
6. Demonstrate a successful unrestricted transfer.
7. Demonstrate a destination `postflightCheck` rejection using the `to` parameter.
8. Update the destination policy and manually execute the failed message.

> **NOTE: What this tutorial does not repeat**
>
> Token and pool deployment, admin registration, and lane configuration: complete a registration tutorial first (see&#x20;
> [Confirm prerequisites](#confirm-prerequisites-addresses-and-permissions)).
>
> The ACE Platform workflow (engine creation, target detection, contract-type assignment, policy instances,
> protections, extractor mappings): follow&#x20;
> [Protect CCIP Token Pools with ACE](/ace/guides/policy-manager/ccip-token-pools) for each step.

## Before You Begin

> **CAUTION: ACE Beta access required**
>
> ACE is currently available through the Beta program. [Contact us](https://chain.link/contact) to request
> access or schedule a demo. After ACE is enabled for your organization, complete the [ACE account
> setup](/ace/getting-started/account-setup) before continuing.

## 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.