Operational Guidelines
Contract Immutable Values
This document catalogues all immutable values in the contracts:
- Deployment-time immutables - Values set during deployment that cannot be updated
- Transaction-time immutables - Values set via transactions that cannot be updated or reversed
1. RestrictedLockupToken
Deployment-Time Immutables
| Variable | Type | Location | Description |
|---|---|---|---|
_decimals | uint8 | L69 | Token decimals, set in constructor from params.decimals |
trustedForwarder | address | ERC2771Context | ERC2771 trusted forwarder address for meta-transactions |
slotsPerWord | uint256 | Storage L82 | Number of slots per 256-bit word, calculated from maxTotalSupply |
elementBitSize | uint256 | Storage L86 | Number of bits per element, calculated as 256 / slotsPerWord |
maxBalancePerSubIndex | uint256 | Storage L88 | Maximum balance per sub-index, calculated from slotsPerWord |
deploymentDay | uint256 | Storage L95 | Deployment day rounded to midnight timestamp |
minTimelockAmount | uint256 | Storage L53 | Minimum amount for timelocks |
maxReleaseDelay | uint256 | Storage L132 | Maximum delay for release schedules |
snapshotsEnabled | bool | Storage L54 | Whether snapshots are enabled (set based on snapshotPeriods address) |
recordMintTimestamp | bool | Storage L55 | Initial state for recording mint timestamps |
Contract References (Set Once in Constructor, Upgradeable via Admin)
| Variable | Upgradeable By | Description |
|---|---|---|
transferRules | Contract Admin | Transfer rules contract (upgradeable via upgradeTransferRules) |
identityRegistry | Contract Admin | Identity registry contract (upgradeable via upgradeIdentityRegistry) |
accessControl | N/A | External access control (NOT upgradeable after deployment) |
snapshotPeriods | N/A | Snapshot periods contract (NOT upgradeable after deployment) |
restrictedLockupTokenManagementExtension | N/A | Management extension (NOT upgradeable after deployment) |
restrictedLockupTokenExtension | N/A | Extension contract (NOT upgradeable after deployment) |
Transaction-Time Immutables
| Value | Function | Description |
|---|---|---|
releaseSchedules[id] | createReleaseSchedule() | Release schedule templates - once created, cannot be modified or deleted |
timelocks[address][id].scheduleId | fundReleaseSchedule(), mintReleaseSchedule() | Schedule ID assigned to timelock |
timelocks[address][id].commencementTimestamp | fundReleaseSchedule(), mintReleaseSchedule() | When the vesting schedule starts |
timelocks[address][id].totalAmount | fundReleaseSchedule(), mintReleaseSchedule() | Total amount in timelock |
timelocks[address][id].funder | fundReleaseSchedule(), mintReleaseSchedule() | Original funder address |
timelocks[address][id].cancelableBy | fundReleaseSchedule(), mintReleaseSchedule() | Addresses that can cancel (set once) |
globalMintTimestamps[bucket] | Mint operations | Token type + days after deployment packed data (entries are immutable once created) |
| Token minting events | mint(), mintTokenType() | Token minting is irreversible except through burn operations |
2. Storage Contract (Shared Storage Layout)
Constants (Compile-Time Immutables)
| Constant | Value | Description |
|---|---|---|
MAX_CANCELABLE_BY | 10 | Maximum addresses that can cancel a timelock |
MAX_TIMELOCKS | 10,000 | Maximum timelocks per address |
MAX_WALLETS_PER_HOLDER | 10 | Maximum wallets per holder |
contractVersion | "5.1.0" | Contract version string |
_ITRANSFER_RULES_INTERFACE_ID | bytes4 | ITransferRules interface ID |
_IIDENTITY_REGISTRY_INTERFACE_ID | bytes4 | IIdentityRegistry interface ID |
TOKEN_TYPE_BITS | 8 | Bits for token type (from BitManipulationLib) |
TOKEN_TYPE_MASK | 0xFF | Mask for token type |
3. TransferRules
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
INTERFACE_ID | bytes4 | Interface ID for ERC165 support |
trustedForwarder | address | ERC2771 trusted forwarder |
accessControl | IAccessControl | Access control contract (NOT upgradeable) |
Constants
| Constant | Value | Description |
|---|---|---|
SUCCESS | 0 | Transfer success code |
GREATER_THAN_RECIPIENT_MAX_BALANCE | 1 | Error code |
SENDER_TOKENS_TIME_LOCKED | 2 | Error code |
DO_NOT_SEND_TO_TOKEN_CONTRACT | 3 | Error code |
DO_NOT_SEND_TO_EMPTY_ADDRESS | 4 | Error code |
SENDER_ADDRESS_FROZEN | 5 | Error code |
ALL_TRANSFERS_PAUSED | 6 | Error code |
RECIPIENT_ADDRESS_FROZEN | 7 | Error code |
LOWER_THAN_RECIPIENT_MIN_BALANCE | 8 | Error code |
INSUFFICIENT_BALANCE_OF_SENDER | 9 | Error code |
SENDER_NOT_AMLKYCPASSED | 10 | Error code |
RECIPIENT_NOT_AMLKYCPASSED | 11 | Error code |
HOLDING_PERIOD_NOT_MET | 12 | Error code |
NO_RULE_FOR_RECIPIENT | 13 | Error code |
RECIPIENT_NOT_QUALIFIED | 14 | Error code |
MAX_RESTRICTION_CODE | 14 | Maximum restriction code |
TOKEN_TYPE_GENERIC | 0 | Default token type |
Error Messages (Set in Constructor)
The errorMessage mapping is initialized in the constructor and cannot be modified:
- All restriction code messages are permanently set
4. AccessControl / EasyAccessControl
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
trustedForwarder | address | ERC2771 trusted forwarder |
Constants
| Constant | Value | Description |
|---|---|---|
CONTRACT_ADMIN_ROLE | 1 (0x01) | Contract admin role bit |
RESERVE_ADMIN_ROLE | 2 (0x02) | Reserve admin role bit |
WALLETS_ADMIN_ROLE | 4 (0x04) | Wallets admin role bit |
TRANSFER_ADMIN_ROLE | 8 (0x08) | Transfer admin role bit |
SOFT_BURN_ADMIN_ROLE | 16 (0x10) | Soft burn admin role bit |
MINT_ADMIN_ROLE | 32 (0x20) | Mint admin role bit |
MAX_ROLE_BIT | 63 (0x3F) | Combined mask of all roles |
5. IdentityRegistry
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
INTERFACE_ID | bytes4 | Interface ID for ERC165 support |
trustedForwarder | address | ERC2771 trusted forwarder |
Constants
| Constant | Value | Description |
|---|---|---|
MAX_REGIONS_COUNT | 10 | Maximum regions per identity |
MAX_VALIDITY_DURATION | 100 years | Maximum AML/KYC validity duration |
NO_ACCREDITATION | 0 | No accreditation type |
6. InterestPayment
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
restrictedLockupToken_ | IRestrictedLockupToken | The restricted lockup token contract |
snapshotPeriods | ISnapshotPeriods | Snapshot periods contract |
paymentToken_ | IERC20 | Payment token (e.g., USDC) |
principalAmountPerToken_ | uint256 | Principal amount per token for redemption |
trustedForwarder | address | ERC2771 trusted forwarder |
Transaction-Time Immutables
| Value | Function | Description |
|---|---|---|
paymentPeriods[id].startTimestamp | createPaymentPeriod() | Period start time (immutable once created) |
paymentPeriods[id].endTimestamp | createPaymentPeriod() | Period end time (immutable once created) |
interestAccrualStartTimestamp | Constructor | When interest starts accruing |
interestAccrualEndTimestamp | Constructor | When interest stops (can only be extended via shiftInterestAccrualEnd or shortened via earlyRepayment) |
Constants
| Constant | Value | Description |
|---|---|---|
INTEREST_RATE_PRECISION_FACTOR | 10^24 | Precision for interest rate calculations |
BIPS_PRECISION | 10,000,000 | Basis points precision |
MAX_PRINCIPAL_AMOUNT_PER_TOKEN | 10^47 | Maximum principal per token |
MAX_ABSOLUTE_INTEREST_RATE | 10^11 (1,000,000%) | Maximum interest rate |
DURATION_360_DAYS | 31,104,000 seconds | 360-day period |
DURATION_365_DAYS | 31,536,000 seconds | 365-day period |
DURATION_366_DAYS | 31,622,400 seconds | 366-day period |
| Role constants | Various | Same as EasyAccessControl |
7. PurchaseContract
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
interestPayment | IInterestPayment | Interest payment contract (can be address(0)) |
tokenContract | RestrictedLockupToken | The token contract |
paymentToken | IERC20 | Payment token (e.g., USDC) |
trustedForwarder | address | ERC2771 trusted forwarder |
Transaction-Time Immutables
| Value | Function | Description |
|---|---|---|
usedPurchaseIds[id] | executePurchase(), executePurchaseWithInterest() | Purchase IDs can only be marked as used once, never cleared |
8. RestrictedSwap
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
restrictedLockupToken | RestrictedLockupToken | The token contract for swaps |
INTERFACE_ID | bytes4 | Interface ID for ERC165 support |
trustedForwarder | address | ERC2771 trusted forwarder |
accessControl | IAccessControl | Access control contract (NOT upgradeable) |
Transaction-Time Immutables
| Value | Function | Description |
|---|---|---|
| Swap configuration | configureSell(), configureBuy() | Once created, swap parameters cannot be modified (only completed or canceled) |
_swap[id].restrictedTokenSender | Configure functions | Permanently set |
_swap[id].restrictedTokenAmount | Configure functions | Permanently set |
_swap[id].quoteTokenSender | Configure functions | Permanently set |
_swap[id].quoteTokenAmount | Configure functions | Permanently set |
_swap[id].quoteToken | Configure functions | Permanently set |
_swap[id].deadline | Configure functions | Permanently set |
9. SnapshotPeriods
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
INTERFACE_ID | bytes4 | Interface ID for ERC165 support |
Transaction-Time Immutables
| Value | Function | Description |
|---|---|---|
walletPeriods[token][account][id] | onUpdate() | Historical period data is append-only |
totalSupplyPeriods[token][id] | onUpdate() | Historical total supply data is append-only |
10. RestrictedLockupTokenExtension
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
maxTotalSupply | uint256 | Initial max total supply (used for slotsPerWord calculation) |
slotsPerWord | uint256 | Slots per word (must match main contract) |
maxBalancePerSubIndex | uint256 | Max balance per sub-index |
elementBitSize | uint256 | Element bit size |
trustedForwarder | address | ERC2771 trusted forwarder |
11. RestrictedLockupTokenManagementExtension
Deployment-Time Immutables
| Variable | Type | Description |
|---|---|---|
maxTotalSupply | uint256 | Initial max total supply (used for slotsPerWord calculation) |
slotsPerWord | uint256 | Slots per word (must match main contract) |
maxBalancePerSubIndex | uint256 | Max balance per sub-index |
elementBitSize | uint256 | Element bit size |
trustedForwarder | address | ERC2771 trusted forwarder |
Summary by Category
Critical Deployment-Only Immutables (Cannot Be Changed)
-
Token Configuration
_decimals(RestrictedLockupToken)slotsPerWord,elementBitSize,maxBalancePerSubIndex(Storage)deploymentDay(Storage)
-
Contract References (Non-Upgradeable)
accessControl(RestrictedLockupToken, TransferRules, RestrictedSwap)snapshotPeriods(RestrictedLockupToken)restrictedLockupTokenManagementExtension(RestrictedLockupToken)restrictedLockupTokenExtension(RestrictedLockupToken)paymentToken(InterestPayment, PurchaseContract)restrictedLockupToken_(InterestPayment)tokenContract(PurchaseContract)
-
ERC2771 Forwarders
- All
trustedForwarderreferences are immutable
- All
-
InterestPayment Specifics
principalAmountPerToken_- Determines redemption value per tokeninterestAccrualStartTimestamp- When interest begins
Critical Transaction-Time Immutables (Irreversible Operations)
-
Vesting & Timelocks
releaseSchedules[]- Created once, never deletedtimelocks[].scheduleId,.commencementTimestamp,.totalAmount,.funder,.cancelableBy
-
Token Minting
globalMintTimestamps[]- Token type + mint timestamp records- All minting operations are irreversible (except via burn)
-
Interest Payment Periods
paymentPeriods[].startTimestamp,.endTimestamp- Define accrual windows
-
Purchase Records
usedPurchaseIds[]- Once used, permanently marked
-
Swap Records
- All swap configuration parameters are immutable once created
-
Historical Data
- All snapshot period data is append-only and immutable