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 |