Deployment Sequence
The contracts must be deployed in order due to their interdependencies. Each contract uses a UUPS proxy pattern, so you deploy a proxy pointing to an implementation contract, then callinitialize() on the proxy.
Verifying Identities
Before any tokens can be issued or transferred, both sender and receiver must have verified identities in the registry (unless they are authorized contracts).batchVerifyIdentities() with up to 500 addresses per call. The function returns a count of successes and an array of failed indices for retry.
Issuing Tokens
With identities verified and sub-issuers configured, issue tokens:reason parameter is bytes32 - use it for categorizing issuances in your audit trail. You can encode strings with bytes32("INITIAL_OFFERING") or use custom numeric codes.
Pre-checking Transfers
Before submitting a transfer on-chain, callcanTransfer to check whether it would succeed. This avoids wasted gas on transactions that will revert.
view function and costs no gas when called off-chain. Integrate it into your frontend to show users whether a transfer will succeed before they sign.
Configuring Compliance Rules
TheBasicComplianceModule enforces holding limits and lockup periods. Configuration calls must come from the token contract, so you need to expose these through your issuer workflow.
Holding limits
Set global defaults and per-user overrides:Lockup periods
Lock tokens for a specific address until a timestamp:Executing a Stock Split
Forward splits multiply all holder balances by a ratio. You must provide the complete list of current holders.splitRatio()) updates and simplifies by GCD.
