Ownership Transfer
Transferring a Galileo token represents a real-world ownership change. The process ensures regulatory compliance while maintaining an immutable audit trail.
8-Step Validation
Every transfer passes through this validation sequence:
- Token Pause Check —
token.paused() == false - Sender Freeze Check —
token.isFrozen(from) == false - Receiver Freeze Check —
token.isFrozen(to) == false - Sender Balance Check — Unfrozen balance sufficient
- Identity Registry —
identityRegistry.isVerified(to) == true - Compliance Modules — All modules approve via
compliance.canTransfer() - Execute Transfer — Balances updated,
Transferemitted - Post-Transfer —
compliance.transferred()notifies modules
Transfer Types
Standard Transfer
Normal ownership change between verified participants:
function transfer(address to, uint256 amount) external returns (bool);Transfer with Reason
Transfer with reason code for audit trail:
function transferWithReason(
address to,
uint256 amount,
bytes32 reasonCode,
string calldata reasonDescription
) external returns (bool);
// Example usage
token.transferWithReason(
buyerAddress,
1,
keccak256("SECONDARY_SALE"),
"Private sale via Vestiaire Collective #ORD-12345"
);Forced Transfer
Admin transfer for legal enforcement (requires Agent role):
function forcedTransfer(
address from,
address to,
uint256 amount,
bytes data
) external;Recovery Transfer
Recover token to new wallet (requires Agent role + multi-sig):
function recoveryAddress(
address lostWallet,
address newWallet,
address investorOnchainID
) external;Events
// Standard ERC-20 transfer
event Transfer(
address indexed from,
address indexed to,
uint256 amount
);
// Extended transfer with reason
event TransferWithReason(
address indexed from,
address indexed to,
uint256 amount,
bytes32 reasonCode,
string reasonDescription
);
// Forced transfer by agent
event ForcedTransfer(
address indexed from,
address indexed to,
uint256 amount,
address indexed initiatingAgent
);
// Recovery transfer
event RecoveryCompleted(
address indexed lostWallet,
address indexed newWallet,
address indexed investorOnchainID
);Off-Chain Sync
After on-chain transfer completes:
- Transfer event indexed by event listener
- EPCIS TransactionEvent created
- DPP owner reference updated
- Previous owner's access revoked (configurable)
Error Codes
| Error | Meaning |
|---|---|
| TokenPaused | Token globally paused |
| SenderFrozen | Sender address is frozen |
| ReceiverFrozen | Receiver address is frozen |
| InsufficientUnfrozenBalance | Partial freeze blocks amount |
| ReceiverNotVerified | Receiver not in Identity Registry |
| TransferNotCompliant | Compliance module rejected |
| CPORequired | CPO certification missing for resale |
| JurisdictionBlocked | Receiver country restricted |
| SanctionedAddress | Party on sanctions list |