DENYLIST_POLICY

component compliance

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 ContractPolicyConfig to scope the deny to that single contract.
  • Combined with other policies as a hard floor: a DENYLIST_POLICY guarantees specific addresses remain blocked even if other rules would otherwise admit them.
Source: maroo
ESC
Type to search