Transfer Rules
Overview
The TransferRules contract manages token type determination and transfer restrictions for the RestrictedLockupToken. It implements a two-layer approach to regulatory compliance through configurable rules managed by the Transfer Admin.
Architecture
The TransferRules contract provides two main functionalities:
- Token Type Rules - Determine token type based on investor identity
- Transfer Rules - Control transfer restrictions based on token type and recipient identity
Usage
Token Type Rules
Token Type Rules map investor identity (region + accreditation) to appropriate token types during minting.
Data Structure
struct TokenTypeRule {
uint256 tokenType; // Token type to assign (1=RegS, 2=RegD, etc.)
bool requiresAmlKyc; // Whether AML/KYC is required for this type
bool isActive; // Whether this rule is currently active
}
Configuration
// Set a single rule
transferRules.setTokenTypeRule(
840, // region (US)
2, // accreditation (Accredited)
2, // tokenType (RegD)
true, // requiresAmlKyc
true // isActive
);
// Get a configured rule
TokenTypeRule memory rule = transferRules.getTokenTypeRule(840, 2);
// Batch set multiple rules
transferRules.batchSetTokenTypeRules(
[840, 0], // regions
[2, 0], // accreditations
[2, 1], // tokenTypes
[true, true], // requiresAmlKyc flags
[true, true] // isActive flags
);
// Remove a rule
transferRules.removeTokenTypeRule(840, 2);
Automatic Type Determination
// Called by RestrictedLockupToken during minting
uint256 tokenType = transferRules.determineTokenType(
walletAddress,
identityRegistry
);
Example Rules for US Exempt Offerings
Region | Accreditation | Token Type | AML/KYC Required | Description |
---|---|---|---|---|
840 (US) | 2 (Accredited) | 2 (RegD) | Yes | US Accredited → RegD |
0 (Any) | 0 (Any) | 1 (RegS) | Yes | Default → RegS |
840 (US) | 1 (Retail) | 3 (RegCF) | Yes | US Retail → RegCF |
Transfer Rules Configuration
Transfer Rules define restrictions for transferring tokens based on token type, mint timestamp, and recipient identity.
Transfer Rule Data Structure
struct TransferRule {
uint256 lockDurationSeconds; // Holding period from mint timestamp
bool requiresAmlKyc; // Whether recipient must have AML/KYC
bool isActive; // Whether this rule is currently active
}
Transfer Rule Configuration
// Set a transfer rule
transferRules.setTransferRule(
2, // tokenType (RegD)
840, // recipientRegion (US)
0, // recipientAccreditation (Any)
TransferRule({
lockDurationSeconds: 180 days,
requiresAmlKyc: true,
isActive: true
})
);
// Get a transfer rule
TransferRule memory rule = transferRules.transferRuleFor(2, 840, 0);
// Batch set multiple rules
transferRules.batchSetTransferRules(
[2, 1], // tokenTypes
[840, 0], // recipientRegions
[0, 0], // recipientAccreditations
[rule1, rule2] // TransferRule structs
);
// Remove a rule
transferRules.removeTransferRule(2, 840, 0);
Transfer Validation Usage
// Called by RestrictedLockupToken during transfers
uint8 restrictionCode = transferRules.detectTransferRestriction(
tokenAddress,
senderAddress,
recipientAddress,
transferAmount
);
// Get unlock timestamp for a holding
uint256 unlockTime = transferRules.getUnlockTimestamp(
tokenType,
mintTimestamp,
recipientAddress,
identityRegistry
);
Example Transfer Rules for US Exempt Offerings
Token Type | Recipient Region | Recipient Accreditation | Lock Duration | AML/KYC | Description |
---|---|---|---|---|---|
2 (RegD) | 840 (US) | 0 (Any) | 180 days | Yes | RegD → US: 6 months |
1 (RegS) | 0 (Any) | 0 (Any) | 365 days | Yes | RegS → Any: 12 months |
4 (Institutional) | 0 (Any) | 4 (Institutional) | 0 days | Yes | Institutional → Institutional: No hold |
Process Flows
Token Minting Flow
Transfer Validation Flow
Validation Logic
Token Type Determination
When determineTokenType()
is called:
- Get Identity: Retrieve investor's region and accreditation from IdentityRegistry
- Find Rule: Look up TokenTypeRule for (region, accreditation) combination
- Return Type:
- If rule found and active: return
rule.tokenType
- If no rule found: return
TOKEN_TYPE_GENERIC (0)
- If rule found and active: return
Transfer Validation Logic
When checkTransferAllowed()
is called:
- Get Recipient Identity: Retrieve recipient's region, accreditation, and AML/KYC status
- Find Transfer Rule: Look up TransferRule for (tokenType, recipientRegion, recipientAccreditation)
- Check Conditions:
- Rule exists and is active
- Holding period satisfied:
mintTimestamp + lockDurationSeconds <= block.timestamp
- AML/KYC requirement met (if required)
- Return Result:
SUCCESS (0)
: All conditions metNO_RULE_FOR_RECIPIENT (13)
: No matching rule foundHOLDING_PERIOD_NOT_MET (12)
: Lock duration not elapsedRECIPIENT_NOT_QUALIFIED (14)
: AML/KYC requirement not met
Administrative Functions
Access Control
- Transfer Admin: Can configure all rules (token type and transfer rules) via external
AccessControl
- Contract Admin: Can upgrade the TransferRules contract via external
AccessControl
Key Functions
// Token Type Rules
function setTokenTypeRule(uint256 region, uint256 accreditation, uint256 tokenType, bool requiresAmlKyc) external onlyTransferAdmin;
function removeTokenTypeRule(uint256 region, uint256 accreditation) external onlyTransferAdmin;
function batchSetTokenTypeRules(uint256[] regions, uint256[] accreditations, uint256[] tokenTypes, bool[] requiresAmlKycFlags) external onlyTransferAdmin;
// Transfer Rules
function setTransferRule(uint256 tokenType, uint256 recipientRegion, uint256 recipientAccreditation, TransferRule memory rule) external onlyTransferAdmin;
function removeTransferRule(uint256 tokenType, uint256 recipientRegion, uint256 recipientAccreditation) external onlyTransferAdmin;
function batchSetTransferRules(uint256[] tokenTypes, uint256[] recipientRegions, uint256[] recipientAccreditations, TransferRule[] rules) external onlyTransferAdmin;
// View Functions
function getTokenTypeRule(uint256 region, uint256 accreditation) external view returns (TokenTypeRule memory);
function transferRuleFor(uint256 tokenType, uint256 recipientRegion, uint256 recipientAccreditation) external view returns (TransferRule memory);
Error Handling
Common Restriction Codes
- SUCCESS (0): Transfer allowed
- HOLDING_PERIOD_NOT_MET (12): Required holding period not elapsed
- NO_RULE_FOR_RECIPIENT (13): No transfer rule defined for combination
- RECIPIENT_NOT_QUALIFIED (14): AML/KYC requirement not met
Troubleshooting
- No rule found: Verify rules are configured for the specific combination
- Holding period: Check
mintTimestamp + lockDurationSeconds
vs current time - AML/KYC issues: Confirm recipient's AML/KYC status in IdentityRegistry
- Rule inactive: Ensure rules have
isActive = true
Integration
With RestrictedLockupToken
- Token calls
determineTokenType()
during minting - Token calls
checkTransferAllowed()
during transfers - Token respects restriction codes and blocks invalid transfers
With IdentityRegistry
- TransferRules queries recipient identity for validation
- Supports region, accreditation, and AML/KYC status checks
- Works with configurable AML/KYC validity periods
Practical Configuration Process
Step 1: Identity Management
// Register investor identity
uint256[] memory regions = new uint256[](1);
regions[0] = 840; // United States
IdentityInfo memory identity = IdentityInfo({
regions: regions,
accreditationType: 2, // Accredited
lastAmlKycChangeTimestamp: 0, // Contract will use block.timestamp
lastAccreditationChangeTimestamp: 0, // Contract will use block.timestamp
amlKycPassed: true
});
identityRegistry.setIdentity(investorAddress, identity);
Step 2: Rule Configuration
// Set token type rules for automatic assignment
transferRules.setTokenTypeRule(840, 2, 2, true, true); // US Accredited → RegD, Active
// Set transfer restrictions for RegD tokens
transferRules.setTransferRule(2, 0, 0, TransferRule({
lockDurationSeconds: 180 days,
requiresAmlKyc: true,
isActive: true
}));
Step 3: Token Operations
// Mint tokens (type automatically determined via rules)
token.mint(investorAddress, 1000 * 10**18); // 1000 tokens
// Or mint specific type
token.mintTokenType(investorAddress, 1000 * 10**18, 2); // 1000 RegD tokens
Advanced Transfer Scenarios
Multi-Jurisdiction Compliance
// Investor with dual citizenship (US + UK)
uint256[] memory dualRegions = new uint256[](2);
dualRegions[0] = 840; // US
dualRegions[1] = 826; // UK
// Configure rules for both jurisdictions
transferRules.setTokenTypeRule(840, 2, 2, true, true); // US Accredited → RegD, Active
transferRules.setTokenTypeRule(826, 3, 1, true, true); // UK Qualified → RegS, Active
Time-Based Restrictions
// Configure different holding periods for different token types
transferRules.setTransferRule(1, 0, 0, TransferRule({
lockDurationSeconds: 365 days, // RegS: 1 year hold
requiresAmlKyc: true,
isActive: true
}));
transferRules.setTransferRule(2, 840, 0, TransferRule({
lockDurationSeconds: 180 days, // RegD to US: 6 months
requiresAmlKyc: true,
isActive: true
}));
transferRules.setTransferRule(4, 0, 4, TransferRule({
lockDurationSeconds: 0, // Institutional to Institutional: No hold
requiresAmlKyc: true,
isActive: true
}));
API Reference
Constructor
constructor(address trustedForwarder_, address accessControl_)
Initializes the TransferRules contract with ERC-2771 meta-transaction support and access control integration.
Parameters:
trustedForwarder_
(address): Address of the trusted forwarder for meta-transactionsaccessControl_
(address): Address of the AccessControl contract for role management
Requirements:
accessControl_
cannot be the zero address
Emits:
- None
Errors:
TransferRules_InvalidAccessControl()
: When accessControl_ is the zero address
Constants
Restriction Codes
SUCCESS() → uint8
Returns the success code (0) indicating no transfer restrictions.
GREATER_THAN_RECIPIENT_MAX_BALANCE() → uint8
Returns restriction code 1 for exceeding recipient maximum balance.
SENDER_TOKENS_TIME_LOCKED() → uint8
Returns restriction code 2 for sender tokens being time-locked.
DO_NOT_SEND_TO_TOKEN_CONTRACT() → uint8
Returns restriction code 3 for attempting to send tokens to the token contract itself.
DO_NOT_SEND_TO_EMPTY_ADDRESS() → uint8
Returns restriction code 4 for attempting to send tokens to the zero address.
SENDER_ADDRESS_FROZEN() → uint8
Returns restriction code 5 for sender address being frozen.
ALL_TRANSFERS_PAUSED() → uint8
Returns restriction code 6 for all transfers being paused.
RECIPIENT_ADDRESS_FROZEN() → uint8
Returns restriction code 7 for recipient address being frozen.
LOWER_THAN_RECIPIENT_MIN_BALANCE() → uint8
Returns restriction code 8 for transfer resulting in balance below recipient minimum.
INSUFFICIENT_BALANCE_OF_SENDER() → uint8
Returns restriction code 9 for insufficient sender balance.
SENDER_NOT_AMLKYCPASSED() → uint8
Returns restriction code 10 for sender not having passed AML/KYC.
RECIPIENT_NOT_AMLKYCPASSED() → uint8
Returns restriction code 11 for recipient not having passed AML/KYC.
HOLDING_PERIOD_NOT_MET() → uint8
Returns restriction code 12 for holding period not being met.
NO_RULE_FOR_RECIPIENT() → uint8
Returns restriction code 13 for no transfer rule found for the recipient.
RECIPIENT_NOT_QUALIFIED() → uint8
Returns restriction code 14 for recipient not being qualified for the transfer.
MAX_RESTRICTION_CODE() → uint8
Returns the maximum valid restriction code (14).
Token Type Constants
TOKEN_TYPE_GENERIC() → uint256
Returns the generic token type constant (0).
Interface Constants
INTERFACE_ID() → bytes4
Returns the interface ID for the ITransferRules interface.
Token Type Rule Management (API)
setTokenTypeRule(uint256 region, uint256 accreditation, uint256 tokenType, bool requiresAmlKyc, bool isActive)
Sets a token type rule for a specific region and accreditation combination.
Parameters:
region
(uint256): The region identifieraccreditation
(uint256): The accreditation type identifiertokenType
(uint256): The token type to assignrequiresAmlKyc
(bool): Whether AML/KYC is required for this token typeisActive
(bool): Whether this rule is active
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
Emits:
TokenTypeRuleSet(region, accreditation, tokenType, requiresAmlKyc, isActive)
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin role
removeTokenTypeRule(uint256 region, uint256 accreditation)
Removes a token type rule for a specific region and accreditation combination.
Parameters:
region
(uint256): The region identifieraccreditation
(uint256): The accreditation type identifier
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
Emits:
TokenTypeRuleRemoved(region, accreditation)
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin role
getTokenTypeRule(uint256 region, uint256 accreditation) → TokenTypeRule
Retrieves a token type rule for a specific region and accreditation combination.
Parameters:
region
(uint256): The region identifieraccreditation
(uint256): The accreditation type identifier
Returns:
TokenTypeRule
: The token type rule struct containing tokenType, requiresAmlKyc, and isActive
batchSetTokenTypeRules(uint256[] regions, uint256[] accreditations, uint256[] tokenTypes, bool[] requiresAmlKycFlags, bool[] isActiveFlags)
Sets multiple token type rules in a single transaction.
Parameters:
regions
(uint256[]): Array of region identifiersaccreditations
(uint256[]): Array of accreditation type identifierstokenTypes
(uint256[]): Array of token types to assignrequiresAmlKycFlags
(bool[]): Array of AML/KYC requirement flagsisActiveFlags
(bool[]): Array of active status flags
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- All arrays must have the same length
Emits:
TokenTypeRuleSet(region, accreditation, tokenType, requiresAmlKyc, isActive)
for each rule
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin roleTransferRules_InvalidArrayLengths()
: When arrays have different lengths
setDefaultTokenTypeRule(uint256 tokenType, bool requiresAmlKyc, bool isActive)
Sets the default token type rule used when no specific rule matches.
Parameters:
tokenType
(uint256): The default token type to assignrequiresAmlKyc
(bool): Whether AML/KYC is required for the default token typeisActive
(bool): Whether the default rule is active
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
Emits:
DefaultTokenTypeRuleSet(tokenType, requiresAmlKyc, isActive)
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin role
resetDefaultTokenTypeRule()
Resets the default token type rule to inactive generic type.
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
Emits:
DefaultTokenTypeRuleSet(TOKEN_TYPE_GENERIC, false, false)
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin role
defaultTokenTypeRule() → TokenTypeRule
Returns the current default token type rule.
Returns:
TokenTypeRule
: The default token type rule struct
Token Type Determination (API)
determineTokenType(address wallet, IIdentityRegistry identityRegistry) → uint256
Determines the appropriate token type for a wallet based on identity and configured rules.
Parameters:
wallet
(address): The wallet address to determine token type foridentityRegistry
(IIdentityRegistry): The identity registry contract
Returns:
tokenType
(uint256): The determined token type
Logic:
- Retrieves wallet identity from the registry
- Iterates through wallet's regions to find matching active rules
- Checks AML/KYC requirements if specified in the rule
- Falls back to default rule if no specific rule matches
- Reverts if no applicable rule is found
Errors:
TransferRules_RecipientNotAmlKycPassed()
: When default rule requires AML/KYC but wallet doesn't have itTransferRules_TokenTypeRuleNotFound()
: When no applicable rule is found
tokenTypeAllowed(uint256 tokenType, address wallet, IIdentityRegistry identityRegistry) → bool
Checks if a specific token type is allowed for a wallet.
Parameters:
tokenType
(uint256): The token type to checkwallet
(address): The wallet addressidentityRegistry
(IIdentityRegistry): The identity registry contract
Returns:
bool
: True if the token type is allowed for the wallet
Transfer Rule Management (API)
setTransferRule(uint256 tokenType, uint256 recipientRegion, uint256 recipientAccreditation, TransferRule _rule)
Sets a transfer rule for a specific token type and recipient identity combination.
Parameters:
tokenType
(uint256): The token type identifierrecipientRegion
(uint256): The recipient's region identifierrecipientAccreditation
(uint256): The recipient's accreditation type_rule
(TransferRule): The transfer rule struct containing lockDurationSeconds, requiresAmlKyc, and isActive
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
Emits:
TransferRuleSet(tokenType, recipientRegion, recipientAccreditation, lockDurationSeconds, requiresAmlKyc, isActive)
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin role
removeTransferRule(uint256 tokenType, uint256 recipientRegion, uint256 recipientAccreditation)
Removes a transfer rule for a specific token type and recipient identity combination.
Parameters:
tokenType
(uint256): The token type identifierrecipientRegion
(uint256): The recipient's region identifierrecipientAccreditation
(uint256): The recipient's accreditation type
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
Emits:
TransferRuleRemoved(tokenType, recipientRegion, recipientAccreditation)
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin role
transferRuleFor(uint256 tokenType, uint256 recipientRegion, uint256 recipientAccreditation) → TransferRule
Retrieves a transfer rule for a specific token type and recipient identity combination.
Parameters:
tokenType
(uint256): The token type identifierrecipientRegion
(uint256): The recipient's region identifierrecipientAccreditation
(uint256): The recipient's accreditation type
Returns:
TransferRule
: The transfer rule struct containing lockDurationSeconds, requiresAmlKyc, and isActive
batchSetTransferRules(uint256[] tokenType, uint256[] recipientRegion, uint256[] recipientAccreditation, TransferRule[] rules)
Sets multiple transfer rules in a single transaction.
Parameters:
tokenType
(uint256[]): Array of token type identifiersrecipientRegion
(uint256[]): Array of recipient region identifiersrecipientAccreditation
(uint256[]): Array of recipient accreditation typesrules
(TransferRule[]): Array of transfer rule structs
Requirements:
- Caller must have TRANSFER_ADMIN_ROLE
- All arrays must have the same length
Emits:
TransferRuleSet(tokenType, recipientRegion, recipientAccreditation, lockDurationSeconds, requiresAmlKyc, isActive)
for each rule
Errors:
EasyAccessControl_DoesNotHaveTransferAdminRole(address)
: When caller lacks transfer admin roleTransferRules_InvalidArrayLengths()
: When arrays have different lengths
Transfer Validation (API)
detectTransferRestriction(address tokenAddr, address from, address to, uint256 value) → uint8
Performs comprehensive transfer restriction detection including holding period checks.
Parameters:
tokenAddr
(address): The token contract addressfrom
(address): The sender addressto
(address): The recipient addressvalue
(uint256): The transfer amount
Returns:
uint8
: Restriction code (0 for success, non-zero for various restrictions)
Logic:
- Performs basic transfer checks via
detectTransferRestrictionBasic
- Calculates transferable amounts from timelocks and holdings
- Validates holding periods for each token type
- Returns appropriate restriction code
detectTransferRestrictionBasic(address tokenAddr, address from, address to, uint256 value) → uint8
Performs basic transfer restriction checks without holding period validation.
Parameters:
tokenAddr
(address): The token contract addressfrom
(address): The sender addressto
(address): The recipient addressvalue
(uint256): The transfer amount
Returns:
uint8
: Restriction code (0 for success, non-zero for various restrictions)
Checks:
- Token not paused
- Recipient not zero address
- Recipient not token contract
- Sender and recipient not frozen
- Sender has AML/KYC
- Sufficient unlocked balance
checkTransferAllowed(uint256 tokenType, uint256 mintTimestamp, IdentityInfo recipientIdentity, bool isAmlKycPassed) → uint8
Checks if a transfer is allowed for a specific holding based on transfer rules.
Parameters:
tokenType
(uint256): The token type of the holdingmintTimestamp
(uint256): When the tokens were mintedrecipientIdentity
(IdentityInfo): The recipient's identity informationisAmlKycPassed
(bool): Whether the recipient has passed AML/KYC
Returns:
uint8
: Restriction code (0 for success, non-zero for restrictions)
Logic:
- Iterates through recipient's regions to find matching transfer rules
- Checks if rule is active
- Validates AML/KYC requirements
- Validates holding period requirements
- Returns SUCCESS if any region allows the transfer
getUnlockTimestamp(uint256 tokenType, uint256 mintTimestamp, address recipient, IIdentityRegistry identityRegistry) → uint256
Calculates when tokens of a specific type will be unlocked for transfer to a recipient.
Parameters:
tokenType
(uint256): The token type identifiermintTimestamp
(uint256): When the tokens were mintedrecipient
(address): The intended recipient addressidentityRegistry
(IIdentityRegistry): The identity registry contract
Returns:
unlockTimestamp
(uint256): The earliest timestamp when transfer is allowed (0 if no restrictions)
Utility Functions
messageForTransferRestriction(uint8 restrictionCode) → string
Returns a human-readable message for a restriction code.
Parameters:
restrictionCode
(uint8): The restriction code to get message for
Returns:
string
: Human-readable description of the restriction
Errors:
TransferRules_BadRestrictionCode()
: When restrictionCode exceeds MAX_RESTRICTION_CODE
checkSuccess(uint8 restrictionCode) → bool
Checks if a restriction code indicates success.
Parameters:
restrictionCode
(uint8): The restriction code to check
Returns:
isSuccess
(bool): True if the code equals SUCCESS (0)
accessControl() → IAccessControl
Returns the address of the AccessControl contract.
Returns:
IAccessControl
: The AccessControl contract interface
ERC-2771 Meta-Transaction Support
isTrustedForwarder(address forwarder) → bool
Checks if an address is the trusted forwarder for meta-transactions.
Parameters:
forwarder
(address): The address to check
Returns:
bool
: True if the address is the trusted forwarder
trustedForwarder() → address
Returns the address of the trusted forwarder.
Returns:
address
: The trusted forwarder address
ERC-165 Interface Support
supportsInterface(bytes4 interfaceId) → bool
Checks if the contract supports a specific interface.
Parameters:
interfaceId
(bytes4): The interface identifier to check
Returns:
bool
: True if the interface is supported
Supported Interfaces:
ITransferRules
: The main transfer rules interfaceIERC165
: The interface detection standard
Events
Token Type Rule Events (API)
TokenTypeRuleSet(uint256 indexed region, uint256 indexed accreditation, uint256 indexed tokenType, bool requiresAmlKyc, bool isActive)
Emitted when a token type rule is set or updated.
Parameters:
region
(uint256, indexed): The region identifieraccreditation
(uint256, indexed): The accreditation type identifiertokenType
(uint256, indexed): The assigned token typerequiresAmlKyc
(bool): Whether AML/KYC is requiredisActive
(bool): Whether the rule is active
TokenTypeRuleRemoved(uint256 indexed region, uint256 indexed accreditation)
Emitted when a token type rule is removed.
Parameters:
region
(uint256, indexed): The region identifieraccreditation
(uint256, indexed): The accreditation type identifier
DefaultTokenTypeRuleSet(uint256 indexed tokenType, bool requiresAmlKyc, bool isActive)
Emitted when the default token type rule is set or updated.
Parameters:
tokenType
(uint256, indexed): The default token typerequiresAmlKyc
(bool): Whether AML/KYC is required for the default typeisActive
(bool): Whether the default rule is active
Transfer Rule Events (API)
TransferRuleSet(uint256 indexed tokenType, uint256 recipientRegion, uint256 recipientAccreditation, uint256 lockDurationSeconds, bool requiresAmlKyc, bool isActive)
Emitted when a transfer rule is set or updated.
Parameters:
tokenType
(uint256, indexed): The token type identifierrecipientRegion
(uint256): The recipient's region identifierrecipientAccreditation
(uint256): The recipient's accreditation typelockDurationSeconds
(uint256): The holding period in secondsrequiresAmlKyc
(bool): Whether AML/KYC is required for recipientsisActive
(bool): Whether the rule is active
TransferRuleRemoved(uint256 indexed tokenType, uint256 indexed recipientRegion, uint256 indexed recipientAccreditation)
Emitted when a transfer rule is removed.
Parameters:
tokenType
(uint256, indexed): The token type identifierrecipientRegion
(uint256, indexed): The recipient's region identifierrecipientAccreditation
(uint256, indexed): The recipient's accreditation type
Custom Errors
Access Control Errors
EasyAccessControl_DoesNotHaveTransferAdminRole(address addr)
Thrown when an address attempts to call a transfer admin function without the required role.
Parameters:
addr
(address): The address that lacks the transfer admin role
Validation Errors
TransferRules_BadRestrictionCode()
Thrown when an invalid restriction code is provided to messageForTransferRestriction
.
TransferRules_InvalidAccessControl()
Thrown when the constructor is called with a zero address for the access control parameter.
TransferRules_InvalidArrayLengths()
Thrown when batch functions are called with arrays of different lengths.
TransferRules_InvalidTokenType()
Thrown when an invalid token type is provided (currently unused in the contract).
TransferRules_RecipientNotAmlKycPassed()
Thrown when a recipient doesn't meet AML/KYC requirements for token type determination.
TransferRules_TokenTypeRuleNotFound()
Thrown when no applicable token type rule is found for a wallet during token type determination.
Data Structures
TokenTypeRule
struct TokenTypeRule {
uint256 tokenType; // The token type to assign
bool requiresAmlKyc; // Whether AML/KYC is required
bool isActive; // Whether this rule is active
}
Used to map investor identity (region + accreditation) to appropriate token types during minting.
TransferRule
struct TransferRule {
uint256 lockDurationSeconds; // Holding period from mint timestamp
bool requiresAmlKyc; // Whether recipient must have AML/KYC
bool isActive; // Whether this rule is active
}
Used to define transfer restrictions based on token type and recipient identity.
IdentityInfo
struct IdentityInfo {
uint256[] regions; // Array of region identifiers
uint256 accreditationType; // Accreditation type
uint256 lastAmlKycChangeTimestamp; // Last AML/KYC status change
uint256 lastAccreditationChangeTimestamp; // Last accreditation change
bool amlKycPassed; // Current AML/KYC status
}
Identity information structure from the IdentityRegistry contract, used for validation.