/** * @dev Checks if a transfer can occur between the from/to addresses. * * Both addresses must be whitelisted, unfrozen, and pass all compliance rule checks. * THROWS when the transfer should fail. * @param initiator The address initiating the transfer. * @param from The address of the sender. * @param to The address of the receiver. * @param tokens The number of tokens being transferred. * @return If a transfer can occur between the from/to addresses. */ function canTransfer(address initiator, address from, address to, uint256 tokens) external returns (bool) { uint8 fromKind = getUnfrozenKind(from, UNSET_KIND); uint8 toKind = getUnfrozenKind(to, UNSET_KIND); if (initiator != from) { getUnfrozenKind(initiator, UNSET_KIND); } checkRules(initiator, from, to, fromKind, toKind, tokens); return true; } /** * Returns the kind for the account and if it, or any of it's ancestors are frozen. * @param addr The account to retrieve kind and frozen state for. * @param kind Recursive return value. This should be passed in initially as '0'. * @return (uint8, bool) Returns the kind and frozen state */ function getUnfrozenKind(address addr, uint8 kind) private returns (uint8) { // Ensure the address is not frozen at the token. require(addressFreezes[addr] == false, "Address is frozen at the token"); // Get the kind, frozen, parent of the address from the registry. // THROWS when the account doesn't exist (isn't whitelisted) (uint8 k, bool frozen, address parent) = store.accountGet(addr); // Ensure the address is not frozen within the registry. require(frozen == false, "Address is frozen at the registry"); // Set the kind to the first invocations kind if (kind == UNSET_KIND) { require(k <= INVESTOR_KIND, "Invalid account kind"); kind = k; } // Check ancestor state, unless this is a custodian. if (k > CUSTODIAN_KIND) { getUnfrozenKind(parent, kind); } return kind; }
0.4.18