Galileo Protocol · MMXXVI

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:

  1. Token Pause Checktoken.paused() == false
  2. Sender Freeze Checktoken.isFrozen(from) == false
  3. Receiver Freeze Checktoken.isFrozen(to) == false
  4. Sender Balance Check — Unfrozen balance sufficient
  5. Identity RegistryidentityRegistry.isVerified(to) == true
  6. Compliance Modules — All modules approve via compliance.canTransfer()
  7. Execute Transfer — Balances updated, Transfer emitted
  8. Post-Transfercompliance.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:

  1. Transfer event indexed by event listener
  2. EPCIS TransactionEvent created
  3. DPP owner reference updated
  4. Previous owner's access revoked (configurable)

Error Codes

ErrorMeaning
TokenPausedToken globally paused
SenderFrozenSender address is frozen
ReceiverFrozenReceiver address is frozen
InsufficientUnfrozenBalancePartial freeze blocks amount
ReceiverNotVerifiedReceiver not in Identity Registry
TransferNotCompliantCompliance module rejected
CPORequiredCPO certification missing for resale
JurisdictionBlockedReceiver country restricted
SanctionedAddressParty on sanctions list