Denylistable Role
TheDenylistable contract provides denylist management capabilities for CCTP V2 contracts. It allows designated denylister addresses to add or remove accounts from a denylist, preventing them from participating in cross-chain transfers.
Source: Denylistable.sol
Denylistable is a V2-only feature. V1 contracts do not support denylisting.
Overview
Denylistable extendsOwnable2Step and provides:
- A designated denylister role that can manage the denylist
- Functions to add and remove addresses from the denylist
- A modifier to check if an address is denylisted
- Events for tracking denylist changes
TokenMessengerV2 to enforce compliance and prevent sanctioned addresses from using CCTP.
State Variables
_denylister
_denylisted
Events
DenylisterChanged
Emitted when the denylister address is updated.Denylisted
Emitted when an account is added to the denylist.UnDenylisted
Emitted when an account is removed from the denylist.Functions
updateDenylister
Updates the denylister address. Only callable by the contract owner.newDenylister(address): The address of the new denylister
- Caller must be the contract owner
newDenylistermust not be the zero address
src/roles/v2/Denylistable.sol:71
addToDenylist
Adds an account to the denylist. Only callable by the denylister.account(address): The address to add to the denylist
- Caller must be the denylister
accountmust not already be denylisted
Denylisted event
Reference: src/roles/v2/Denylistable.sol:87
removeFromDenylist
Removes an account from the denylist. Only callable by the denylister.account(address): The address to remove from the denylist
- Caller must be the denylister
accountmust currently be denylisted
UnDenylisted event
Reference: src/roles/v2/Denylistable.sol:101
isDenylisted
Checks if an address is on the denylist.account(address): The address to check
bool:trueif the account is denylisted,falseotherwise
src/roles/v2/Denylistable.sol:113
denylister
Returns the current denylister address.address: The address of the current denylister
src/roles/v2/Denylistable.sol:121
Modifiers
onlyDenylister
Restricts function access to the denylister address only.notDenylisted
Checks that an address is not on the denylist.account(address): The address to check
Usage in TokenMessengerV2
TokenMessengerV2 uses Denylistable to prevent denylisted addresses from:- Depositing USDC for burn
- Receiving minted USDC on the destination chain
Deposit Validation
Mint Recipient Validation
Before minting, TokenMessengerV2 checks that the mint recipient is not denylisted:Configuration Example
Setting up denylist management:Security Considerations
Access Control
- Owner Control: Only the contract owner can change the denylister address
- Denylister Independence: The denylister operates independently from the owner for day-to-day denylist management
- Two-Step Ownership: Inherits secure ownership transfer from Ownable2Step
Best Practices
- Multi-Sig Denylister: Use a multi-sig wallet as the denylister to prevent single-point-of-failure
- Monitoring: Emit and monitor all denylist events for transparency
- Regular Reviews: Periodically review the denylist and remove addresses when appropriate
- Emergency Procedures: Have documented procedures for urgent denylist additions
- Legal Compliance: Ensure denylist operations comply with applicable regulations
Gas Optimization
The contract usesuint256 constants (_TRUE = 1, _FALSE = 0) instead of booleans for the denylist mapping to optimize gas costs during storage operations.
Related Contracts
- TokenMessengerV2 - Implements Denylistable for deposit and mint protection
- Ownable2Step - Base contract providing secure ownership management
- V2 Overview - Learn more about V2 features including denylist
Comparison with V1
V1 contracts do not have denylist functionality. This is a new feature in V2 designed to enhance compliance capabilities:| Feature | V1 | V2 |
|---|---|---|
| Denylist Support | ❌ No | ✅ Yes |
| Compliance Role | ❌ No | ✅ Denylister |
| Address Blocking | ❌ No | ✅ Yes |
| Granular Control | ❌ No | ✅ Yes |
Migration Considerations
When migrating from V1 to V2, you’ll need to:- Designate a denylister address
- Import any existing blocklists from external sources
- Update client code to handle denylist-related errors
- Implement monitoring for denylist events