Liquidity Docs

Smart Contracts

ERC-3643 (T-REX) security tokens, compliance modules, corporate actions, dividends, bridge

All smart contracts for the Liquidity platform are in liquidityio/contracts. They extend the @liquidityio/standard library, which implements the full ERC-3643 (T-REX) compliant securities stack.

Standards

StandardImplementationPurpose
ERC-3643 (T-REX)SecurityToken + ComplianceRegistry + modulesToken for Regulated EXchanges — the institutional standard for permissioned security tokens
ERC-1404detectTransferRestriction() + messageForTransferRestriction()Simple Restricted Token Standard — transfer restrictions with human-readable codes
ST-20verifyTransfer() hookSecurity Token Standard — pre-transfer compliance check
ERC-1400PartitionTokenPartitioned security token (Class A/B, locked, vested tranches)
ERC-1643DocumentRegistryOn-chain document management (prospectus, offering memo, shareholder agreements)

Token Contracts

ContractImportPurpose
SecurityTokensrc/token/SecurityToken.solBase regulated ERC-20 for all tradable assets (stocks, crypto). ERC-3643 + ERC-1404 + ST-20.
USDLTokensrc/token/USDLToken.solUSDL — USD stablecoin on Liquidity. Full compliance inherited.
RestrictedTokensrc/token/RestrictedToken.solSecurityToken + external TransferRestriction engine (max holders, limits).
PartitionTokensrc/token/PartitionToken.solERC-1400 partitioned security — multiple tranches per token.
LQDTYTokensrc/token/LQDTYToken.solLQDTY governance/utility token. Upgradeable (UUPS).

SecurityToken Architecture

SecurityToken (ERC-3643 / ERC-1404 / ST-20)

├── ComplianceRegistry (shared, T-REX IdentityRegistry)
│   ├── Whitelist / Blacklist
│   ├── Lockup expiry (Rule 144)
│   ├── Jurisdiction (ISO 3166-1)
│   ├── Accreditation status
│   └── Pluggable IComplianceModule[]
│       ├── WhitelistModule (codes 16-17)
│       ├── JurisdictionModule (codes 19-22)
│       ├── LockupModule (code 18)
│       └── TransferRestriction (codes 32-33)

├── AccessControl
│   ├── DEFAULT_ADMIN_ROLE
│   ├── MINTER_ROLE
│   └── PAUSER_ROLE

└── ERC-20 + Burnable + Pausable

Every transfer() and transferFrom() call passes through the ComplianceRegistry before execution. Minting and burning bypass compliance (admin operations).


Restriction Codes

The detectTransferRestriction(from, to, value) function returns:

CodeConstantMeaning
0SUCCESSTransfer allowed
1SENDER_NOT_WHITELISTEDSender not KYC-verified
2RECEIVER_NOT_WHITELISTEDReceiver not KYC-verified
3SENDER_BLACKLISTEDSender on sanctions/blacklist
4RECEIVER_BLACKLISTEDReceiver on sanctions/blacklist
5SENDER_LOCKEDSender in Rule 144 holding period
6JURISDICTION_BLOCKEDRestricted jurisdiction (OFAC/EU/UK)
7ACCREDITATION_REQUIREDReg D requires accredited investor
16SENDER_NOT_ON_WHITELISTModule: sender not on module whitelist
17RECEIVER_NOT_ON_WHITELISTModule: receiver not on module whitelist
18SENDER_LOCKUP_ACTIVEModule: lockup period active
19-22JURISDICTION_*Module: jurisdiction blocked/unset
32MAX_HOLDERS_REACHEDTransfer restriction: max holder cap
33TRANSFER_AMOUNT_EXCEEDEDTransfer restriction: per-address limit

Use messageForTransferRestriction(code) to get the human-readable string.


Compliance Modules

Pluggable modules implement IComplianceModule.checkTransfer(from, to, amount):

ModuleFilePurpose
WhitelistModulesrc/compliance/WhitelistModule.solPer-module address whitelist (separate from core registry)
JurisdictionModulesrc/compliance/JurisdictionModule.solCountry-based transfer blocking (ISO 3166-1 alpha-2)
LockupModulesrc/compliance/LockupModule.solRule 144 holding period enforcement
TransferRestrictionsrc/registry/TransferRestriction.solMax holder count + per-address transfer limits

Modules are registered on the ComplianceRegistry via addModule(address). The registry iterates all modules on every transfer — if any module returns false, the transfer reverts with the module's restriction code.


Corporate Actions

ContractFilePurpose
CorporateActionssrc/corporate/CorporateActions.solStock splits, reverse splits, forced transfers, token conversions
DividendDistributorsrc/corporate/DividendDistributor.solSnapshot-based pull dividend payments in USDL or any ERC-20
DocumentRegistrysrc/registry/DocumentRegistry.solERC-1643 on-chain document storage (URI + content hash)

Dividend Flow

1. Admin creates round → DividendDistributor.createRound(token, amount, snapshotBlock)
2. Holders call         → DividendDistributor.claim(roundId)
3. Pro-rata share       → amount × (holderBalance / totalSupply) at snapshot
4. Unclaimed reclaim    → DividendDistributor.reclaimDividend(roundId) after expiry

Exchange Contracts

ContractFilePurpose
BatchFactorysrc/exchange/BatchFactory.solCREATE2 deterministic SecurityToken deployment (12,784 tokens)
SettlementRegistrysrc/exchange/SettlementRegistry.solATS trade audit trail — maps trade UUIDs to on-chain settlement
TokenSwapsrc/exchange/TokenSwap.solOTC atomic swap (ERC-20 ↔ ERC-721)
DeterministicDeployersrc/exchange/DeterministicDeployer.solGeneric CREATE2 factory

Bridge Contracts

ContractFilePurpose
SecurityBridgesrc/bridge/SecurityBridge.solLock-and-mint bridge for SecurityTokens between chains
LiquidityTeleportersrc/bridge/LiquidityTeleporter.solMPC-signed cross-chain bridge (3-of-5 threshold oracle)

Governance

ContractFilePurpose
ComplianceRegistrysrc/governance/ComplianceRegistry.solCentral KYC/AML registry (T-REX IdentityRegistry equivalent)
MultisigWalletsrc/governance/MultisigWallet.solRole-based multisig (OWNER/SIGNER/GUARDIAN/MANAGER)

Migration (Substrate → EVM)

ContractFilePurpose
SubstrateImportersrc/migration/SubstrateImporter.solOne-time batch import of Substrate state (balances, loans)
SubstrateMigrationsrc/migration/SubstrateMigration.solUser-initiated claims via SR25519 signature verification

Deployment

All tokens are deployed via BatchFactory with CREATE2 for deterministic addresses:

# Deploy ComplianceRegistry + BatchFactory
forge script script/Deploy.s.sol --rpc-url $RPC --broadcast

# Deploy 12,784 SecurityTokens
python3 script/mass-deploy.py --rpc $RPC --batch-size 6

# Initialize tokens (mint supply, set documents)
python3 script/init-tokens.py --rpc $RPC

Deployed Contracts

NetworkComplianceRegistryBatchFactoryUSDL
Devnet (8675311)0x...0x5bf9619A241360652196200B4A39749b97Cd20090x904aDB07B590a2741c2F6FCbd2dD65aB5B3620C7
Testnet (8675310)0x95367b6D0E94589fdE507a12340666e32Ad4D8D30x7fC4f8a926E47Fa3587C0d7658C00E7489e67916
Mainnet (8675309)

T-REX / ERC-3643 Architecture Mapping

For teams familiar with the T-REX standard:

T-REX ComponentLiquidity Implementation
TokenSecurityToken (ERC-20 + ERC-1404 + ST-20)
IdentityRegistryComplianceRegistry (whitelist, blacklist, lockup, jurisdiction, accreditation)
ClaimTopicsRegistryIComplianceModule system (pluggable compliance modules)
TrustedIssuersRegistryAccessControl COMPLIANCE_ROLE on ComplianceRegistry
Identity (ONCHAINID)DID Registry + SoulID + IdentityHub (LP-3006)

The compliance architecture follows the T-REX pattern with a native on-chain identity layer (W3C DID) instead of ONCHAINID.

On this page