DENYLIST_POLICY
Block transactions whose sender or recipient appears in a configured address list.
The simplest PCL template — checks the caller (and, in the global config, often the recipient) against a static list of blocked addresses. Used for sanctions enforcement and frozen-account routing.
Solidity struct & ABI tuple
The policy parameter is the Solidity struct below, defined in
IPcl.sol:struct DenylistPolicy {
address[] addresses;
} The ABI tuple shorthand is
(address[]). Encode it into PolicySet.policy as follows:DenylistPolicy memory dl = DenylistPolicy({
addresses: new address[](2)
});
dl.addresses[0] = 0xAaaA...;
dl.addresses[1] = 0xBbBb...;
bytes memory policyBytes = abi.encode(dl);
// then wrap in a PolicySet with templateId = "DENYLIST_POLICY" How the policy is evaluated
PCL checks whether the transaction sender's address is present in
addresses. If it is, the transaction is rejected. Some configurations also include the recipient in the check — that is controlled by the policy admin when registering the global config, or by the contract admin for a contract-scoped config.Rejection reason codes
When this policy rejects, PCL emits
InDenylist(address sender). Wallet UX should treat this as a terminal failure: there is no retry path because the address itself is blocked.Typical usage
This template is most commonly applied in three scenarios:
- Sanctions enforcement at the global level so every transaction on the chain is screened against the list.
- Per-contract admin freeze for compromised counterparties — register the policy under a
ContractPolicyConfigto scope the deny to that single contract. - Combined with other policies as a hard floor: a
DENYLIST_POLICYguarantees specific addresses remain blocked even if other rules would otherwise admit them.