ETH Price: $2,594.14 (+2.53%)

Token

TZERO PREFERRED (TZROP)
 

Overview

Max Total Supply

26,228,711 TZROP

Holders

235 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

Balance
0 TZROP

Value
$0.00
0xee79e5c5ebc1ff7a6465d4d2202fef27fe73dfd0
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
T0ken

Compiler Version
v0.5.2+commit.1df8f40c

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-01-01
*/

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


pragma solidity ^0.5.2;


/**
 *  @title Ownable
 *  @dev Provides a modifier that requires the caller to be the owner of the contract.
 */
contract Ownable {
    address payable public owner;

    event OwnerTransferred(
        address indexed oldOwner,
        address indexed newOwner
    );

    constructor() public {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Owner account is required");
        _;
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwner(address payable newOwner)
    public
    onlyOwner {
        require(newOwner != owner, "New Owner cannot be the current owner");
        require(newOwner != address(0), "New Owner cannot be zero address");
        address payable prevOwner = owner;
        owner = newOwner;
        emit OwnerTransferred(prevOwner, newOwner);
    }
}

/**
 *  @title Lockable
 *  @dev The Lockable contract adds the ability for the contract owner to set the lock status
 *  of the account. A modifier is provided that checks the throws when the contract is
 *  in the locked state.
 */
contract Lockable is Ownable {
    bool public isLocked;

    constructor() public {
        isLocked = false;
    }

    modifier isUnlocked() {
        require(!isLocked, "Contract is currently locked for modification");
        _;
    }

    /**
     *  Set the contract to a read-only state.
     *  @param locked The locked state to set the contract to.
     */
    function setLocked(bool locked)
    onlyOwner
    external {
        require(isLocked != locked, "Contract already in requested lock state");

        isLocked = locked;
    }
}

/**
 *  @title Destroyable
 *  @dev The Destroyable contract alows the owner address to `selfdestruct` the contract.
 */
contract Destroyable is Ownable {
    /**
     *  Allow the owner to destroy this contract.
     */
    function kill()
    onlyOwner
    external {
        selfdestruct(owner);
    }
}

/**
 *  Contract to facilitate locking and self destructing.
 */
contract LockableDestroyable is Lockable, Destroyable { }

library AdditiveMath {
    /**
     *  Adds two numbers and returns the result
     *  THROWS when the result overflows
     *  @return The sum of the arguments
     */
    function add(uint256 x, uint256 y)
    internal
    pure
    returns (uint256) {
        uint256 sum = x + y;
        require(sum >= x, "Results in overflow");
        return sum;
    }

    /**
     *  Subtracts two numbers and returns the result
     *  THROWS when the result underflows
     *  @return The difference of the arguments
     */
    function subtract(uint256 x, uint256 y)
    internal
    pure
    returns (uint256) {
        require(y <= x, "Results in underflow");
        return x - y;
    }
}

/**
 *
 *  @title AddressMap
 *  @dev Map of unique indexed addresseses.
 *
 *  **NOTE**
 *    The internal collections are one-based.
 *    This is simply because null values are expressed as zero,
 *    which makes it hard to check for the existence of items within the array,
 *    or grabbing the first item of an array for non-existent items.
 *
 *    This is only exposed internally, so callers still use zero-based indices.
 *
 */
library AddressMap {
    struct Data {
        int256 count;
        mapping(address => int256) indices;
        mapping(int256 => address) items;
    }

    address constant ZERO_ADDRESS = address(0);

    /**
     *  Appends the address to the end of the map, if the address is not
     *  zero and the address doesn't currently exist.
     *  @param addr The address to append.
     *  @return true if the address was added.
     */
    function append(Data storage self, address addr)
    internal
    returns (bool) {
        if (addr == ZERO_ADDRESS) {
            return false;
        }

        int256 index = self.indices[addr] - 1;
        if (index >= 0 && index < self.count) {
            return false;
        }

        self.count++;
        self.indices[addr] = self.count;
        self.items[self.count] = addr;
        return true;
    }

    /**
     *  Removes the given address from the map.
     *  @param addr The address to remove from the map.
     *  @return true if the address was removed.
     */
    function remove(Data storage self, address addr)
    internal
    returns (bool) {
        int256 oneBasedIndex = self.indices[addr];
        if (oneBasedIndex < 1 || oneBasedIndex > self.count) {
            return false;  // address doesn't exist, or zero.
        }

        // When the item being removed is not the last item in the collection,
        // replace that item with the last one, otherwise zero it out.
        //
        //  If {2} is the item to be removed
        //     [0, 1, 2, 3, 4]
        //  The result would be:
        //     [0, 1, 4, 3]
        //
        if (oneBasedIndex < self.count) {
            // Replace with last item
            address last = self.items[self.count];  // Get the last item
            self.indices[last] = oneBasedIndex;     // Update last items index to current index
            self.items[oneBasedIndex] = last;       // Update current index to last item
            delete self.items[self.count];          // Delete the last item, since it's moved
        } else {
            // Delete the address
            delete self.items[oneBasedIndex];
        }

        delete self.indices[addr];
        self.count--;
        return true;
    }

    /**
     * Clears all items within the map.
     */
    function clear(Data storage self)
    internal {
        self.count = 0;
    }

    /**
     *  Retrieves the address at the given index.
     *  THROWS when the index is invalid.
     *  @param index The index of the item to retrieve.
     *  @return The address of the item at the given index.
     */
    function at(Data storage self, int256 index)
    internal
    view
    returns (address) {
        require(index >= 0 && index < self.count, "Index outside of bounds.");
        return self.items[index + 1];
    }

    /**
     *  Gets the index of the given address.
     *  @param addr The address of the item to get the index for.
     *  @return The index of the given address.
     */
    function indexOf(Data storage self, address addr)
    internal
    view
    returns (int256) {
        if (addr == ZERO_ADDRESS) {
            return -1;
        }

        int256 index = self.indices[addr] - 1;
        if (index < 0 || index >= self.count) {
            return -1;
        }
        return index;
    }

    /**
     *  Returns whether or not the given address exists within the map.
     *  @param addr The address to check for existence.
     *  @return If the given address exists or not.
     */
    function exists(Data storage self, address addr)
    internal
    view
    returns (bool) {
        int256 index = self.indices[addr] - 1;
        return index >= 0 && index < self.count;
    }

}

/**
 *
 *  @title AccountMap
 *  @dev Map of unique indexed accounts.
 *
 *  **NOTE**
 *    The internal collections are one-based.
 *    This is simply because null values are expressed as zero,
 *    which makes it hard to check for the existence of items within the array,
 *    or grabbing the first item of an array for non-existent items.
 *
 *    This is only exposed internally, so callers still use zero-based indices.
 *
 */
library AccountMap {
    struct Account {
        address addr;
        uint8 kind;
        bool frozen;
        address parent;
    }

    struct Data {
        int256 count;
        mapping(address => int256) indices;
        mapping(int256 => Account) items;
    }

    address constant ZERO_ADDRESS = address(0);

    /**
     *  Appends the address to the end of the map, if the addres is not
     *  zero and the address doesn't currently exist.
     *  @param addr The address to append.
     *  @return true if the address was added.
     */
    function append(Data storage self, address addr, uint8 kind, bool isFrozen, address parent)
    internal
    returns (bool) {
        if (addr == ZERO_ADDRESS) {
            return false;
        }

        int256 index = self.indices[addr] - 1;
        if (index >= 0 && index < self.count) {
            return false;
        }

        self.count++;
        self.indices[addr] = self.count;
        self.items[self.count] = Account(addr, kind, isFrozen, parent);
        return true;
    }

    /**
     *  Removes the given address from the map.
     *  @param addr The address to remove from the map.
     *  @return true if the address was removed.
     */
    function remove(Data storage self, address addr)
    internal
    returns (bool) {
        int256 oneBasedIndex = self.indices[addr];
        if (oneBasedIndex < 1 || oneBasedIndex > self.count) {
            return false;  // address doesn't exist, or zero.
        }

        // When the item being removed is not the last item in the collection,
        // replace that item with the last one, otherwise zero it out.
        //
        //  If {2} is the item to be removed
        //     [0, 1, 2, 3, 4]
        //  The result would be:
        //     [0, 1, 4, 3]
        //
        if (oneBasedIndex < self.count) {
            // Replace with last item
            Account storage last = self.items[self.count];  // Get the last item
            self.indices[last.addr] = oneBasedIndex;        // Update last items index to current index
            self.items[oneBasedIndex] = last;               // Update current index to last item
            delete self.items[self.count];                  // Delete the last item, since it's moved
        } else {
            // Delete the account
            delete self.items[oneBasedIndex];
        }

        delete self.indices[addr];
        self.count--;
        return true;
    }

    /**
     * Clears all items within the map.
     */
    function clear(Data storage self)
    internal {
        self.count = 0;
    }

    /**
     *  Retrieves the address at the given index.
     *  THROWS when the index is invalid.
     *  @param index The index of the item to retrieve.
     *  @return The address of the item at the given index.
     */
    function at(Data storage self, int256 index)
    internal
    view
    returns (Account memory) {
        require(index >= 0 && index < self.count, "Index outside of bounds.");
        return self.items[index + 1];
    }

    /**
     *  Gets the index of the given address.
     *  @param addr The address of the item to get the index for.
     *  @return The index of the given address.
     */
    function indexOf(Data storage self, address addr)
    internal
    view
    returns (int256) {
        if (addr == ZERO_ADDRESS) {
            return -1;
        }

        int256 index = self.indices[addr] - 1;
        if (index < 0 || index >= self.count) {
            return -1;
        }
        return index;
    }

    /**
     *  Gets the Account for the given address.
     *  THROWS when an account doesn't exist for the given address.
     *  @param addr The address of the item to get.
     *  @return The account of the given address.
     */
    function get(Data storage self, address addr)
    internal
    view
    returns (Account memory) {
        return at(self, indexOf(self, addr));
    }

    /**
     *  Returns whether or not the given address exists within the map.
     *  @param addr The address to check for existence.
     *  @return If the given address exists or not.
     */
    function exists(Data storage self, address addr)
    internal
    view
    returns (bool) {
        int256 index = self.indices[addr] - 1;
        return index >= 0 && index < self.count;
    }

}

/**
 *  @title Registry Storage
 */
contract Storage is Ownable, LockableDestroyable {
  
    using AccountMap for AccountMap.Data;
    using AddressMap for AddressMap.Data;

    // ------------------------------- Variables -------------------------------
    // Number of data slots available for accounts
    uint8 constant MAX_DATA = 30;

    // Accounts
    AccountMap.Data public accounts;

    // Account Data
    //   - mapping of:
    //     (address        => (index =>    data))
    mapping(address => mapping(uint8 => bytes32)) public data;

    // Address write permissions
    //     (kind  => address)
    mapping(uint8 => AddressMap.Data) public permissions;


    // ------------------------------- Modifiers -------------------------------
    /**
     *  Ensures the `msg.sender` has permission for the given kind/type of account.
     *
     *    - The `owner` account is always allowed
     *    - Addresses/Contracts must have a corresponding entry, for the given kind
     */
    modifier isAllowed(uint8 kind) {
        require(kind > 0, "Invalid, or missing permission");
        if (msg.sender != owner) {
            require(permissions[kind].exists(msg.sender), "Missing permission");
        }
        _;
    }

    // -------------------------------------------------------------------------

    /**
     *  Adds an account to storage
     *  THROWS when `msg.sender` doesn't have permission
     *  THROWS when the account already exists
     *  @param addr The address of the account
     *  @param kind The kind of account
     *  @param isFrozen The frozen status of the account
     *  @param parent The account parent/owner
     */
    function addAccount(address addr, uint8 kind, bool isFrozen, address parent)
    isUnlocked
    isAllowed(kind)
    external {
        require(accounts.append(addr, kind, isFrozen, parent), "Account already exists");
    }

    /**
     *  Sets an account's frozen status
     *  THROWS when the account doesn't exist
     *  @param addr The address of the account
     *  @param frozen The frozen status of the account
     */
    function setAccountFrozen(address addr, bool frozen)
    isUnlocked
    isAllowed(accounts.get(addr).kind)
    external {
        // NOTE: Not bounds checking `index` here, as `isAllowed` ensures the address exists.
        //       Indices are one-based internally, so we need to add one to compensate.
        int256 index = accounts.indexOf(addr) + 1;
        accounts.items[index].frozen = frozen;
    }

    /**
     *  Removes an account from storage
     *  THROWS when the account doesn't exist
     *  @param addr The address of the account
     */
    function removeAccount(address addr)
    isUnlocked
    isAllowed(accounts.get(addr).kind)
    external {
        bytes32 ZERO_BYTES = bytes32(0);
        mapping(uint8 => bytes32) storage accountData = data[addr];

        // Remove data
        for (uint8 i = 0; i < MAX_DATA; i++) {
            if (accountData[i] != ZERO_BYTES) {
                delete accountData[i];
            }
        }

        // Remove account
        accounts.remove(addr);
    }

    /**
     *  Sets data for an address/caller
     *  THROWS when the account doesn't exist
     *  @param addr The address
     *  @param index The index of the data
     *  @param customData The data store set
     */
    function setAccountData(address addr, uint8 index, bytes32 customData)
    isUnlocked
    isAllowed(accounts.get(addr).kind)
    external {
        require(index < MAX_DATA, "index outside of bounds");
        data[addr][index] = customData;
    }

    /**
     *  Grants the address permission for the given kind
     *  @param kind The kind of address
     *  @param addr The address
     */
    function grantPermission(uint8 kind, address addr)
    isUnlocked
    isAllowed(kind)
    external {
        permissions[kind].append(addr);
    }

    /**
     *  Revokes the address permission for the given kind
     *  @param kind The kind of address
     *  @param addr The address
     */
    function revokePermission(uint8 kind, address addr)
    isUnlocked
    isAllowed(kind)
    external {
        permissions[kind].remove(addr);
    }

    // ---------------------------- Address Getters ----------------------------
    /**
     *  Gets the account at the given index
     *  THROWS when the index is out-of-bounds
     *  @param index The index of the item to retrieve
     *  @return The address, kind, frozen status, and parent of the account at the given index
     */
    function accountAt(int256 index)
    external
    view
    returns(address, uint8, bool, address) {
        AccountMap.Account memory acct = accounts.at(index);
        return (acct.addr, acct.kind, acct.frozen, acct.parent);
    }

    /**
     *  Gets the account for the given address
     *  THROWS when the account doesn't exist
     *  @param addr The address of the item to retrieve
     *  @return The address, kind, frozen status, and parent of the account at the given index
     */
    function accountGet(address addr)
    external
    view
    returns(uint8, bool, address) {
        AccountMap.Account memory acct = accounts.get(addr);
        return (acct.kind, acct.frozen, acct.parent);
    }

    /**
     *  Gets the parent address for the given account address
     *  THROWS when the account doesn't exist
     *  @param addr The address of the account
     *  @return The parent address
     */
    function accountParent(address addr)
    external
    view
    returns(address) {
        return accounts.get(addr).parent;
    }

    /**
     *  Gets the account kind, for the given account address
     *  THROWS when the account doesn't exist
     *  @param addr The address of the account
     *  @return The kind of account
     */
    function accountKind(address addr)
    external
    view
    returns(uint8) {
        return accounts.get(addr).kind;
    }

    /**
     *  Gets the frozen status of the account
     *  THROWS when the account doesn't exist
     *  @param addr The address of the account
     *  @return The frozen status of the account
     */
    function accountFrozen(address addr)
    external
    view
    returns(bool) {
        return accounts.get(addr).frozen;
    }

    /**
     *  Gets the index of the account
     *  Returns -1 for missing accounts
     *  @param addr The address of the account to get the index for
     *  @return The index of the given account address
     */
    function accountIndexOf(address addr)
    external
    view
    returns(int256) {
        return accounts.indexOf(addr);
    }

    /**
     *  Returns wether or not the given address exists
     *  @param addr The account address
     *  @return If the given address exists
     */
    function accountExists(address addr)
    external
    view
    returns(bool) {
        return accounts.exists(addr);
    }

    /**
     *  Returns wether or not the given address exists for the given kind
     *  @param addr The account address
     *  @param kind The kind of address
     *  @return If the given address exists with the given kind
     */
    function accountExists(address addr, uint8 kind)
    external
    view
    returns(bool) {
        int256 index = accounts.indexOf(addr);
        if (index < 0) {
            return false;
        }
        return accounts.at(index).kind == kind;
    }


    // -------------------------- Permission Getters ---------------------------
    /**
     *  Retrieves the permission address at the index for the given type
     *  THROWS when the index is out-of-bounds
     *  @param kind The kind of permission
     *  @param index The index of the item to retrieve
     *  @return The permission address of the item at the given index
     */
    function permissionAt(uint8 kind, int256 index)
    external
    view
    returns(address) {
        return permissions[kind].at(index);
    }

    /**
     *  Gets the index of the permission address for the given type
     *  Returns -1 for missing permission
     *  @param kind The kind of perission
     *  @param addr The address of the permission to get the index for
     *  @return The index of the given permission address
     */
    function permissionIndexOf(uint8 kind, address addr)
    external
    view
    returns(int256) {
        return permissions[kind].indexOf(addr);
    }

    /**
     *  Returns wether or not the given permission address exists for the given type
     *  @param kind The kind of permission
     *  @param addr The address to check for permission
     *  @return If the given address has permission or not
     */
    function permissionExists(uint8 kind, address addr)
    external
    view
    returns(bool) {
        return permissions[kind].exists(addr);
    }

}


interface ComplianceRule {

    /**
     *  @dev Checks if a transfer can occur between the from/to addresses and MUST throw when the check fails.
     *  @param initiator The address initiating the transfer.
     *  @param from The address of the sender
     *  @param to The address of the receiver
     *  @param toKind The kind of the to address
     *  @param tokens The number of tokens being transferred.
     *  @param store The Storage contract
     */
    function check(address initiator, address from, address to, uint8 toKind, uint256 tokens, Storage store)
    external;
}

interface Compliance {

    /**
     *  This event is emitted when an address's frozen status has changed.
     *  @param addr The address whose frozen status has been updated.
     *  @param isFrozen Whether the custodian is being frozen.
     *  @param owner The address that updated the frozen status.
     */
    event AddressFrozen(
        address indexed addr,
        bool indexed isFrozen,
        address indexed owner
    );

    /**
     *  Sets an address frozen status for this token
     *  @param addr The address to update frozen status.
     *  @param freeze Frozen status of the address.
     */
    function setFrozen(address addr, bool freeze)
    external;

    /**
     *  Replaces all of the existing rules with the given ones
     *  @param kind The bucket of rules to set.
     *  @param rules New compliance rules.
     */
    function setRules(uint8 kind, ComplianceRule[] calldata rules)
    external;

    /**
     *  Returns all of the current compliance rules for this token
     *  @param kind The bucket of rules to get.
     *  @return List of all compliance rules.
     */
    function getRules(uint8 kind)
    external
    view
    returns (ComplianceRule[] memory);

    /**
     *  @dev Checks if issuance can occur between the from/to addresses.
     *
     *  Both addresses must be whitelisted and unfrozen
     *  THROWS when the transfer should fail.
     *  @param issuer The address initiating the issuance.
     *  @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 issuance can occur between the from/to addresses.
     */
    function canIssue(address issuer, address from, address to, uint256 tokens)
    external
    returns (bool);

    /**
     *  @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);

    /**
     *  @dev Checks if an override by the sender can occur between the from/to addresses.
     *
     *  Both addresses must be whitelisted and unfrozen.
     *  THROWS when the sender is not allowed to override.
     *  @param admin 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 an override can occur between the from/to addresses.
     */
    function canOverride(address admin, address from, address to, uint256 tokens)
    external
    returns (bool);
}


interface ERC20 {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function balanceOf(address who) external view returns (uint256);
    function totalSupply() external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

contract T0ken is ERC20, Ownable, LockableDestroyable {

    // ------------------------------- Variables -------------------------------

    using AdditiveMath for uint256;
    using AddressMap for AddressMap.Data;

    address constant internal ZERO_ADDRESS = address(0);
    string public constant name = "TZERO PREFERRED";
    string public constant symbol = "TZROP";
    uint8 public constant decimals = 0;

    AddressMap.Data public shareholders;
    Compliance public compliance;
    address public issuer;
    bool public issuingFinished = false;
    mapping(address => address) public cancellations;

    mapping(address => uint256) internal balances;
    uint256 internal totalSupplyTokens;

    mapping (address => mapping (address => uint256)) private allowed;

    // ------------------------------- Modifiers -------------------------------

    modifier onlyIssuer() {
        require(msg.sender == issuer, "Only issuer allowed");
        _;
    }

    modifier canIssue() {
        require(!issuingFinished, "Issuing is already finished");
        _;
    }

    modifier isNotCancelled(address addr) {
        require(cancellations[addr] == ZERO_ADDRESS, "Address has been cancelled");
        _;
    }

    modifier hasFunds(address addr, uint256 tokens) {
        require(tokens <= balances[addr], "Insufficient funds");
        _;
    }

    // -------------------------------- Events ---------------------------------

    /**
     *  This event is emitted when an address is cancelled and replaced with
     *  a new address.  This happens in the case where a shareholder has
     *  lost access to their original address and needs to have their share
     *  reissued to a new address.  This is the equivalent of issuing replacement
     *  share certificates.
     *  @param original The address being superseded.
     *  @param replacement The new address.
     *  @param sender The address that caused the address to be superseded.
    */
    event VerifiedAddressSuperseded(address indexed original, address indexed replacement, address indexed sender);
    event IssuerSet(address indexed previousIssuer, address indexed newIssuer);
    event Issue(address indexed to, uint256 tokens);
    event IssueFinished();
    event ShareholderAdded(address shareholder);
    event ShareholderRemoved(address shareholder);

    // -------------------------------------------------------------------------

    /**
     *  @dev Transfers tokens to the whitelisted account.
     *
     *  If the 'to' address is not currently a shareholder then it MUST become one.
     *  If the transfer will reduce 'msg.sender' balance to 0, then that address MUST be removed
     *  from the list of shareholders.
     *  MUST be removed from the list of shareholders.
     *  @param to The address to transfer to.
     *  @param tokens The number of tokens to be transferred.
     */
    function transfer(address to, uint256 tokens)
    external
    isUnlocked
    isNotCancelled(to)
    hasFunds(msg.sender, tokens)
    returns (bool) {
        bool transferAllowed;

        // Issuance
        if (msg.sender == issuer) {
            transferAllowed = address(compliance) == ZERO_ADDRESS;
            if (!transferAllowed) {
                transferAllowed = compliance.canIssue(issuer, issuer, to, tokens);
            }
        }
        // Transfer
        else {
            transferAllowed = canTransfer(msg.sender, to, tokens, false);
        }

        // Ensure the transfer is allowed.
        if (transferAllowed) {
            transferTokens(msg.sender, to, tokens);
        }
        return transferAllowed;
    }

    /**
     *  @dev Transfers tokens between whitelisted accounts.
     *
     *  If the 'to' address is not currently a shareholder then it MUST become one.
     *  If the transfer will reduce 'from' balance to 0 then that address MUST be removed from the list of shareholders.
     *  @param from The address to transfer from
     *  @param to The address to transfer to.
     *  @param tokens uint256 the number of tokens to be transferred
     */
    function transferFrom(address from, address to, uint256 tokens)
    external
    isUnlocked
    isNotCancelled(to)
    hasFunds(from, tokens)
    returns (bool) {
        require(tokens <= allowed[from][msg.sender], "Transfer exceeds allowance");

        // Transfer the tokens
        bool transferAllowed = canTransfer(from, to, tokens, false);
        if (transferAllowed) {
            // Update the allowance to reflect the transfer
            allowed[from][msg.sender] = allowed[from][msg.sender].subtract(tokens);
            // Transfer the tokens
            transferTokens(from, to, tokens);
        }
        return transferAllowed;
    }

    /**
     *  @dev Overrides a transfer of tokens to the whitelisted account.
     *
     *  If the 'to' address is not currently a shareholder then it MUST become one.
     *  If the transfer will reduce 'msg.sender' balance to 0, then that address MUST be removed
     *  from the list of shareholders.
     *  MUST be removed from the list of shareholders.
     *  @param from The address to transfer from
     *  @param to The address to transfer to.
     *  @param tokens The number of tokens to be transferred.
     */
    function transferOverride(address from, address to, uint256 tokens)
    external
    isUnlocked
    isNotCancelled(to)
    hasFunds(from, tokens)
    returns (bool) {
        // Ensure the sender can perform the override.
        bool transferAllowed = canTransfer(from, to, tokens, true);
        // Ensure the transfer is allowed.
        if (transferAllowed) {
            transferTokens(from, to, tokens);
        }
        return transferAllowed;
    }

    /**
     *  @dev Tokens will be issued to the issuer's address only.
     *  @param quantity The number of tokens to mint.
     *  @return A boolean that indicates if the operation was successful.
     */
    function issueTokens(uint256 quantity)
    external
    isUnlocked
    onlyIssuer
    canIssue
    returns (bool) {
        // Avoid doing any state changes for zero quantities
        if (quantity > 0) {
            totalSupplyTokens = totalSupplyTokens.add(quantity);
            balances[issuer] = balances[issuer].add(quantity);
            shareholders.append(issuer);
        }
        emit Issue(issuer, quantity);
        emit Transfer(ZERO_ADDRESS, issuer, quantity);
        return true;
    }

    /**
     *  @dev Finishes token issuance.
     *  This is a single use function, once invoked it cannot be undone.
     */
    function finishIssuing()
    external
    isUnlocked
    onlyIssuer
    canIssue
    returns (bool) {
        issuingFinished = true;
        emit IssueFinished();
        return issuingFinished;
    }

    /**
     *  @dev Cancel the original address and reissue the Tokens to the replacement address.
     *
     *  Access to this function is restricted to the Issuer only.
     *  The 'original' address MUST be removed from the set of whitelisted addresses.
     *  Throw if the 'original' address supplied is not a shareholder.
     *  Throw if the 'replacement' address is not a whitelisted address.
     *  This function MUST emit the 'VerifiedAddressSuperseded' event.
     *  @param original The address to be superseded. This address MUST NOT be reused and must be whitelisted.
     *  @param replacement The address  that supersedes the original. This address MUST be whitelisted.
     */
    function cancelAndReissue(address original, address replacement)
    external
    isUnlocked
    onlyIssuer
    isNotCancelled(replacement) {
        // Ensure the reissue can take place
        require(shareholders.exists(original) && !shareholders.exists(replacement), "Original doesn't exist or replacement does");
        if (address(compliance) != ZERO_ADDRESS) {
            require(compliance.canIssue(msg.sender, original, replacement, balances[original]), "Failed 'canIssue' check.");
        }

        // Replace the original shareholder with the replacement
        shareholders.remove(original);
        shareholders.append(replacement);
        // Add the original as a cancelled address (preventing it from future trading)
        cancellations[original] = replacement;
        // Transfer the balance to the replacement
        balances[replacement] = balances[original];
        balances[original] = 0;
        emit VerifiedAddressSuperseded(original, replacement, msg.sender);
    }

    /**
     * @dev Approve the passed address to spend the specified number of tokens on behalf of msg.sender.
     *
     * Beware that changing an allowance with this method brings the risk that someone may use both the old
     * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
     * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     * @param spender The address which will spend the funds.
     * @param tokens The number of tokens of tokens to be spent.
     */
    function approve(address spender, uint256 tokens)
    external
    isUnlocked
    isNotCancelled(msg.sender)
    returns (bool) {
        require(shareholders.exists(msg.sender), "Must be a shareholder to approve token transfer");
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }

    /**
     *  @dev Set the issuer address.
     *  @param newIssuer The address of the issuer.
     */
    function setIssuer(address newIssuer)
    external
    isUnlocked
    onlyOwner {
        issuer = newIssuer;
        emit IssuerSet(issuer, newIssuer);
    }

    /**
     *  @dev Sets the compliance contract address to use during transfers.
     *  @param newComplianceAddress The address of the compliance contract.
     */
    function setCompliance(address newComplianceAddress)
    external
    isUnlocked
    onlyOwner {
        compliance = Compliance(newComplianceAddress);
    }

    // -------------------------------- Getters --------------------------------

    /**
     *  @dev Returns the total token supply
     *  @return total number of tokens in existence
     */
    function totalSupply()
    external
    view
    returns (uint256) {
        return totalSupplyTokens;
    }

    /**
     *  @dev Gets the balance of the specified address.
     *  @param addr The address to query the the balance of.
     *  @return An uint256 representing the tokens owned by the passed address.
     */
    function balanceOf(address addr)
    external
    view
    returns (uint256) {
        return balances[addr];
    }

    /**
     *  @dev Gets the number of tokens that an owner has allowed the spender to transfer.
     *  @param addrOwner address The address which owns the funds.
     *  @param spender address The address which will spend the funds.
     *  @return A uint256 specifying the number of tokens still available for the spender.
     */
    function allowance(address addrOwner, address spender)
    external
    view
    returns (uint256) {
        return allowed[addrOwner][spender];
    }

    /**
     *  By counting the number of token holders using 'holderCount'
     *  you can retrieve the complete list of token holders, one at a time.
     *  It MUST throw if 'index >= holderCount()'.
     *  @dev Returns the holder at the given index.
     *  @param index The zero-based index of the holder.
     *  @return the address of the token holder with the given index.
     */
    function holderAt(int256 index)
    external
    view
    returns (address){
        return shareholders.at(index);
    }

    /**
     *  @dev Checks to see if the supplied address is a share holder.
     *  @param addr The address to check.
     *  @return true if the supplied address owns a token.
     */
    function isHolder(address addr)
    external
    view
    returns (bool) {
        return shareholders.exists(addr);
    }

    /**
     *  @dev Checks to see if the supplied address was superseded.
     *  @param addr The address to check.
     *  @return true if the supplied address was superseded by another address.
     */
    function isSuperseded(address addr)
    external
    view
    returns (bool) {
        return cancellations[addr] != ZERO_ADDRESS;
    }

    /**
     *  Gets the most recent address, given a superseded one.
     *  Addresses may be superseded multiple times, so this function needs to
     *  follow the chain of addresses until it reaches the final, verified address.
     *  @param addr The superseded address.
     *  @return the verified address that ultimately holds the share.
     */
    function getSuperseded(address addr)
    external
    view
    returns (address) {
        require(addr != ZERO_ADDRESS, "Non-zero address required");

        address candidate = cancellations[addr];
        if (candidate == ZERO_ADDRESS) {
            return ZERO_ADDRESS;
        }
        return candidate;
    }


    // -------------------------------- Private --------------------------------

    /**
     *  @dev Checks if a transfer/override may take place between the two accounts.
     *
     *   Validates that the transfer can take place.
     *     - Ensure the 'to' address is not cancelled
     *     - Ensure the transfer is compliant
     *  @param from The sender address.
     *  @param to The recipient address.
     *  @param tokens The number of tokens being transferred.
     *  @param isOverride If this is a transfer override
     *  @return If the transfer can take place.
     */
    function canTransfer(address from, address to, uint256 tokens, bool isOverride)
    private
    isNotCancelled(to)
    returns (bool) {
        // Don't allow overrides and ignore compliance rules when compliance not set.
        if (address(compliance) == ZERO_ADDRESS) {
            return !isOverride;
        }

        // Ensure the override is valid, or that the transfer is compliant.
        if (isOverride) {
            return compliance.canOverride(msg.sender, from, to, tokens);
        } else {
            return compliance.canTransfer(msg.sender, from, to, tokens);
        }
    }

    /**
     *  @dev Transfers tokens from one address to another
     *  @param from The sender address.
     *  @param to The recipient address.
     *  @param tokens The number of tokens being transferred.
     */
    function transferTokens(address from, address to, uint256 tokens)
    private {
        // Update balances
        balances[from] = balances[from].subtract(tokens);
        balances[to] = balances[to].add(tokens);
        emit Transfer(from, to, tokens);

        // Adds the shareholder if they don't already exist.
        if (balances[to] > 0 && shareholders.append(to)) {
            emit ShareholderAdded(to);
        }
        // Remove the shareholder if they no longer hold tokens.
        if (balances[from] == 0 && shareholders.remove(from)) {
            emit ShareholderRemoved(from);
        }
    }

}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"issuer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"locked","type":"bool"}],"name":"setLocked","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"isSuperseded","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"cancellations","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"shareholders","outputs":[{"name":"count","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"issuingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newIssuer","type":"address"}],"name":"setIssuer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"compliance","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"original","type":"address"},{"name":"replacement","type":"address"}],"name":"cancelAndReissue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"finishIssuing","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferOverride","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"int256"}],"name":"holderAt","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isLocked","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"quantity","type":"uint256"}],"name":"issueTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"isHolder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"addrOwner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"getSuperseded","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newComplianceAddress","type":"address"}],"name":"setCompliance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"original","type":"address"},{"indexed":true,"name":"replacement","type":"address"},{"indexed":true,"name":"sender","type":"address"}],"name":"VerifiedAddressSuperseded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousIssuer","type":"address"},{"indexed":true,"name":"newIssuer","type":"address"}],"name":"IssuerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Issue","type":"event"},{"anonymous":false,"inputs":[],"name":"IssueFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"shareholder","type":"address"}],"name":"ShareholderAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"shareholder","type":"address"}],"name":"ShareholderRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnerTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]

60806040526005805460a060020a60ff021990811690915560008054600160a060020a0319163317909116905561235d8061003b6000396000f3fe608060405234801561001057600080fd5b50600436106101ec576000357c0100000000000000000000000000000000000000000000000000000000900480636290865d1161012157806395d89b41116100bf578063d4d7b19a1161008e578063d4d7b19a14610529578063dd62ed3e1461054f578063e37ccac71461057d578063f8981789146105a3576101ec565b806395d89b41146104d0578063a4e2d634146104d8578063a5820daa146104e0578063a9059cbb146104fd576101ec565b80637e8d1a39116100fb5780637e8d1a391461046d57806380318be8146104755780638082a929146104ab5780638da5cb5b146104c8576101ec565b80636290865d1461041157806370a082311461041957806379f647201461043f576101ec565b8063313ce5671161018e57806341c0e1b51161016857806341c0e1b5146103b55780634ef05a71146103bd5780634fb2e45d146103c557806355cc4e57146103eb576101ec565b8063313ce5671461036957806334a84827146103875780633723bc0e146103ad576101ec565b80631d143848116101ca5780631d143848146102c8578063211e28b6146102ec57806323b872dd1461030d5780632da7293e14610343576101ec565b806306fdde03146101f1578063095ea7b31461026e57806318160ddd146102ae575b600080fd5b6101f96105c9565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561023357818101518382015260200161021b565b50505050905090810190601f1680156102605780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61029a6004803603604081101561028457600080fd5b50600160a060020a038135169060200135610600565b604080519115158252519081900360200190f35b6102b6610785565b60408051918252519081900360200190f35b6102d061078b565b60408051600160a060020a039092168252519081900360200190f35b61030b6004803603602081101561030257600080fd5b5035151561079a565b005b61029a6004803603606081101561032357600080fd5b50600160a060020a038135811691602081013590911690604001356108a0565b61029a6004803603602081101561035957600080fd5b5035600160a060020a0316610ae4565b610371610b07565b6040805160ff9092168252519081900360200190f35b6102d06004803603602081101561039d57600080fd5b5035600160a060020a0316610b0c565b6102b6610b27565b61030b610b2d565b61029a610b9d565b61030b600480360360208110156103db57600080fd5b5035600160a060020a0316610bbe565b61030b6004803603602081101561040157600080fd5b5035600160a060020a0316610d2d565b6102d0610e49565b6102b66004803603602081101561042f57600080fd5b5035600160a060020a0316610e58565b61030b6004803603604081101561045557600080fd5b50600160a060020a0381358116916020013516610e73565b61029a6111d7565b61029a6004803603606081101561048b57600080fd5b50600160a060020a0381358116916020810135909116906040013561138a565b6102d0600480360360208110156104c157600080fd5b50356114f0565b6102d0611509565b6101f9611518565b61029a61154f565b61029a600480360360208110156104f657600080fd5b5035611570565b61029a6004803603604081101561051357600080fd5b50600160a060020a0381351690602001356117b4565b61029a6004803603602081101561053f57600080fd5b5035600160a060020a03166119f6565b6102b66004803603604081101561056557600080fd5b50600160a060020a0381358116916020013516611a09565b6102d06004803603602081101561059357600080fd5b5035600160a060020a0316611a34565b61030b600480360360208110156105b957600080fd5b5035600160a060020a0316611ac2565b60408051808201909152600f81527f545a45524f205052454645525245440000000000000000000000000000000000602082015281565b6000805474010000000000000000000000000000000000000000900460ff161561065e5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b33600081815260066020526040902054600160a060020a0316156106cc576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b6106dd60013363ffffffff611bb016565b151561071d5760405160e560020a62461bcd02815260040180806020018281038252602f815260200180612289602f913960400191505060405180910390fd5b336000818152600960209081526040808320600160a060020a03891680855290835292819020879055805187815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b60085490565b600554600160a060020a031681565b600054600160a060020a031633146107fc576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b60005460ff7401000000000000000000000000000000000000000090910416151581151514156108605760405160e560020a62461bcd0281526004018080602001828103825260288152602001806122dd6028913960400191505060405180910390fd5b60008054911515740100000000000000000000000000000000000000000274ff000000000000000000000000000000000000000019909216919091179055565b6000805474010000000000000000000000000000000000000000900460ff16156108fe5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600160a060020a0380841660009081526006602052604090205484911615610970576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b600160a060020a038516600090815260076020526040902054859084908111156109e4576040805160e560020a62461bcd02815260206004820152601260248201527f496e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0387166000908152600960209081526040808320338452909152902054851115610a5f576040805160e560020a62461bcd02815260206004820152601a60248201527f5472616e73666572206578636565647320616c6c6f77616e6365000000000000604482015290519081900360640190fd5b6000610a6e8888886000611be7565b90508015610ad957600160a060020a0388166000908152600960209081526040808320338452909152902054610aaa908763ffffffff611db416565b600160a060020a0389166000908152600960209081526040808320338452909152902055610ad9888888611e14565b979650505050505050565b600160a060020a038181166000908152600660205260409020541615155b919050565b600081565b600660205260009081526040902054600160a060020a031681565b60015481565b600054600160a060020a03163314610b8f576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b600054600160a060020a0316ff5b60055474010000000000000000000000000000000000000000900460ff1681565b600054600160a060020a03163314610c20576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b600054600160a060020a0382811691161415610c705760405160e560020a62461bcd0281526004018080602001828103825260258152602001806122b86025913960400191505060405180910390fd5b600160a060020a0381161515610cd0576040805160e560020a62461bcd02815260206004820181905260248201527f4e6577204f776e65722063616e6e6f74206265207a65726f2061646472657373604482015290519081900360640190fd5b60008054600160a060020a0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8934ce4adea8d9ce0d714d2c22b86790e41b7731c84b926fbbdc1d40ff6533c99190a35050565b60005474010000000000000000000000000000000000000000900460ff1615610d8a5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600054600160a060020a03163314610dec576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b6005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383811691821792839055604051919216907ff7189b85d7899f5a32d733e6584c4f1dcdff0274f09d969d186c1797673ede1190600090a350565b600454600160a060020a031681565b600160a060020a031660009081526007602052604090205490565b60005474010000000000000000000000000000000000000000900460ff1615610ed05760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600554600160a060020a03163314610f32576040805160e560020a62461bcd02815260206004820152601360248201527f4f6e6c792069737375657220616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b600160a060020a0380821660009081526006602052604090205482911615610fa4576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b610fb560018463ffffffff611bb016565b8015610fcf5750610fcd60018363ffffffff611bb016565b155b151561100f5760405160e560020a62461bcd02815260040180806020018281038252602a81526020018061225f602a913960400191505060405180910390fd5b600454600160a060020a0316156111325760048054600160a060020a0385811660008181526007602090815260408083205481517ffd8258bd00000000000000000000000000000000000000000000000000000000815233988101989098526024880194909452888516604488015260648701939093529151929093169363fd8258bd93608480830194928390030190829087803b1580156110b057600080fd5b505af11580156110c4573d6000803e3d6000fd5b505050506040513d60208110156110da57600080fd5b50511515611132576040805160e560020a62461bcd02815260206004820152601860248201527f4661696c6564202763616e49737375652720636865636b2e0000000000000000604482015290519081900360640190fd5b61114360018463ffffffff611fb616565b5061115560018363ffffffff6120bb16565b50600160a060020a038381166000818152600660209081526040808320805473ffffffffffffffffffffffffffffffffffffffff19169588169586179055600790915280822080548584528284205583835282905551339392917fb64971100522354f3d25283cb14e2eefcb0dd26a757482ccfe42479d0a68685791a4505050565b6000805474010000000000000000000000000000000000000000900460ff16156112355760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600554600160a060020a03163314611297576040805160e560020a62461bcd02815260206004820152601360248201527f4f6e6c792069737375657220616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b60055474010000000000000000000000000000000000000000900460ff161561130a576040805160e560020a62461bcd02815260206004820152601b60248201527f49737375696e6720697320616c72656164792066696e69736865640000000000604482015290519081900360640190fd5b6005805474ff00000000000000000000000000000000000000001916740100000000000000000000000000000000000000001790556040517f7bc15082cf539fecd9e12596dc8e4e77c17a81fccc2c267b626af583162232a290600090a15060055474010000000000000000000000000000000000000000900460ff1690565b6000805474010000000000000000000000000000000000000000900460ff16156113e85760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600160a060020a038084166000908152600660205260409020548491161561145a576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b600160a060020a038516600090815260076020526040902054859084908111156114ce576040805160e560020a62461bcd02815260206004820152601260248201527f496e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b60006114dd8888886001611be7565b90508015610ad957610ad9888888611e14565b600061150360018363ffffffff61216f16565b92915050565b600054600160a060020a031681565b60408051808201909152600581527f545a524f50000000000000000000000000000000000000000000000000000000602082015281565b60005474010000000000000000000000000000000000000000900460ff1681565b6000805474010000000000000000000000000000000000000000900460ff16156115ce5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600554600160a060020a03163314611630576040805160e560020a62461bcd02815260206004820152601360248201527f4f6e6c792069737375657220616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b60055474010000000000000000000000000000000000000000900460ff16156116a3576040805160e560020a62461bcd02815260206004820152601b60248201527f49737375696e6720697320616c72656164792066696e69736865640000000000604482015290519081900360640190fd5b6000821115611724576008546116bf908363ffffffff6121fa16565b600855600554600160a060020a03166000908152600760205260409020546116ed908363ffffffff6121fa16565b60058054600160a060020a0390811660009081526007602052604090209290925554611722916001911663ffffffff6120bb16565b505b600554604080518481529051600160a060020a03909216917fc65a3f767206d2fdcede0b094a4840e01c0dd0be1888b5ba800346eaa0123c169181900360200190a2600554604080518481529051600160a060020a03909216916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a3506001919050565b6000805474010000000000000000000000000000000000000000900460ff16156118125760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600160a060020a0380841660009081526006602052604090205484911615611884576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b3360008181526007602052604090205484908111156118ed576040805160e560020a62461bcd02815260206004820152601260248201527f496e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b600554600090600160a060020a03163314156119cb5750600454600160a060020a031615806119c65760048054600554604080517ffd8258bd000000000000000000000000000000000000000000000000000000008152600160a060020a0392831694810185905260248101949094528a82166044850152606484018a90525191169163fd8258bd9160848083019260209291908290030181600087803b15801561199757600080fd5b505af11580156119ab573d6000803e3d6000fd5b505050506040513d60208110156119c157600080fd5b505190505b6119db565b6119d83388886000611be7565b90505b80156119ec576119ec338888611e14565b9695505050505050565b600061150360018363ffffffff611bb016565b600160a060020a03918216600090815260096020908152604080832093909416825291909152205490565b6000600160a060020a0382161515611a96576040805160e560020a62461bcd02815260206004820152601960248201527f4e6f6e2d7a65726f206164647265737320726571756972656400000000000000604482015290519081900360640190fd5b600160a060020a0380831660009081526006602052604090205416801515611503576000915050610b02565b60005474010000000000000000000000000000000000000000900460ff1615611b1f5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600054600160a060020a03163314611b81576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a038116600090815260018301602052604081205460001901818112801590611bdf5750835481125b949350505050565b600160a060020a03808416600090815260066020526040812054909185911615611c5b576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b600454600160a060020a03161515611c765782159150611dab565b8215611d2d5760048054604080517f5acba2010000000000000000000000000000000000000000000000000000000081523393810193909352600160a060020a0389811660248501528881166044850152606484018890529051911691635acba2019160848083019260209291908290030181600087803b158015611cfa57600080fd5b505af1158015611d0e573d6000803e3d6000fd5b505050506040513d6020811015611d2457600080fd5b50519150611dab565b60048054604080517f6d62a4fe0000000000000000000000000000000000000000000000000000000081523393810193909352600160a060020a0389811660248501528881166044850152606484018890529051911691636d62a4fe9160848083019260209291908290030181600087803b158015611cfa57600080fd5b50949350505050565b600082821115611e0e576040805160e560020a62461bcd02815260206004820152601460248201527f526573756c747320696e20756e646572666c6f77000000000000000000000000604482015290519081900360640190fd5b50900390565b600160a060020a038316600090815260076020526040902054611e3d908263ffffffff611db416565b600160a060020a038085166000908152600760205260408082209390935590841681522054611e72908263ffffffff6121fa16565b600160a060020a0380841660008181526007602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3600160a060020a038216600090815260076020526040812054118015611efb5750611efb60018363ffffffff6120bb16565b15611f3d5760408051600160a060020a038416815290517f3082c1c4977de80c4f67ee77b56b282610ec93a7ecbcc31b551e0ac2f7bd03959181900360200190a15b600160a060020a038316600090815260076020526040902054158015611f6f5750611f6f60018463ffffffff611fb616565b15611fb15760408051600160a060020a038516815290517f7ba114ff3d9844510a088eea94cd35562e7c97a2d36a418b37b2e61e5c77affe9181900360200190a15b505050565b600160a060020a03811660009081526001808401602052604082205490811280611fe05750835481135b15611fef576000915050611503565b83548112156120635783546000908152600285016020818152604080842054600160a060020a031680855260018901835281852086905585855292909152808320805473ffffffffffffffffffffffffffffffffffffffff199081169093179055865483529091208054909116905561208f565b60008181526002850160205260409020805473ffffffffffffffffffffffffffffffffffffffff191690555b5050600160a060020a031660009081526001828101602052604082209190915581546000190190915590565b6000600160a060020a03821615156120d557506000611503565b600160a060020a0382166000908152600184016020526040812054600019019081128015906121045750835481125b15612113576000915050611503565b505081546001908101808455600160a060020a03831660008181528386016020908152604080832085905593825260028701905291909120805473ffffffffffffffffffffffffffffffffffffffff1916909117905592915050565b60008082121580156121815750825482125b15156121d7576040805160e560020a62461bcd02815260206004820152601860248201527f496e646578206f757473696465206f6620626f756e64732e0000000000000000604482015290519081900360640190fd5b5060010160009081526002919091016020526040902054600160a060020a031690565b600082820183811015612257576040805160e560020a62461bcd02815260206004820152601360248201527f526573756c747320696e206f766572666c6f7700000000000000000000000000604482015290519081900360640190fd5b939250505056fe4f726967696e616c20646f65736e2774206578697374206f72207265706c6163656d656e7420646f65734d7573742062652061207368617265686f6c64657220746f20617070726f766520746f6b656e207472616e736665724e6577204f776e65722063616e6e6f74206265207468652063757272656e74206f776e6572436f6e747261637420616c726561647920696e20726571756573746564206c6f636b207374617465436f6e74726163742069732063757272656e746c79206c6f636b656420666f72206d6f64696669636174696f6ea165627a7a72305820aaa9c0c19f6c5795773194111572f9115f68c17c15fbd5386874d0078fb81b820029

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101ec576000357c0100000000000000000000000000000000000000000000000000000000900480636290865d1161012157806395d89b41116100bf578063d4d7b19a1161008e578063d4d7b19a14610529578063dd62ed3e1461054f578063e37ccac71461057d578063f8981789146105a3576101ec565b806395d89b41146104d0578063a4e2d634146104d8578063a5820daa146104e0578063a9059cbb146104fd576101ec565b80637e8d1a39116100fb5780637e8d1a391461046d57806380318be8146104755780638082a929146104ab5780638da5cb5b146104c8576101ec565b80636290865d1461041157806370a082311461041957806379f647201461043f576101ec565b8063313ce5671161018e57806341c0e1b51161016857806341c0e1b5146103b55780634ef05a71146103bd5780634fb2e45d146103c557806355cc4e57146103eb576101ec565b8063313ce5671461036957806334a84827146103875780633723bc0e146103ad576101ec565b80631d143848116101ca5780631d143848146102c8578063211e28b6146102ec57806323b872dd1461030d5780632da7293e14610343576101ec565b806306fdde03146101f1578063095ea7b31461026e57806318160ddd146102ae575b600080fd5b6101f96105c9565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561023357818101518382015260200161021b565b50505050905090810190601f1680156102605780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61029a6004803603604081101561028457600080fd5b50600160a060020a038135169060200135610600565b604080519115158252519081900360200190f35b6102b6610785565b60408051918252519081900360200190f35b6102d061078b565b60408051600160a060020a039092168252519081900360200190f35b61030b6004803603602081101561030257600080fd5b5035151561079a565b005b61029a6004803603606081101561032357600080fd5b50600160a060020a038135811691602081013590911690604001356108a0565b61029a6004803603602081101561035957600080fd5b5035600160a060020a0316610ae4565b610371610b07565b6040805160ff9092168252519081900360200190f35b6102d06004803603602081101561039d57600080fd5b5035600160a060020a0316610b0c565b6102b6610b27565b61030b610b2d565b61029a610b9d565b61030b600480360360208110156103db57600080fd5b5035600160a060020a0316610bbe565b61030b6004803603602081101561040157600080fd5b5035600160a060020a0316610d2d565b6102d0610e49565b6102b66004803603602081101561042f57600080fd5b5035600160a060020a0316610e58565b61030b6004803603604081101561045557600080fd5b50600160a060020a0381358116916020013516610e73565b61029a6111d7565b61029a6004803603606081101561048b57600080fd5b50600160a060020a0381358116916020810135909116906040013561138a565b6102d0600480360360208110156104c157600080fd5b50356114f0565b6102d0611509565b6101f9611518565b61029a61154f565b61029a600480360360208110156104f657600080fd5b5035611570565b61029a6004803603604081101561051357600080fd5b50600160a060020a0381351690602001356117b4565b61029a6004803603602081101561053f57600080fd5b5035600160a060020a03166119f6565b6102b66004803603604081101561056557600080fd5b50600160a060020a0381358116916020013516611a09565b6102d06004803603602081101561059357600080fd5b5035600160a060020a0316611a34565b61030b600480360360208110156105b957600080fd5b5035600160a060020a0316611ac2565b60408051808201909152600f81527f545a45524f205052454645525245440000000000000000000000000000000000602082015281565b6000805474010000000000000000000000000000000000000000900460ff161561065e5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b33600081815260066020526040902054600160a060020a0316156106cc576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b6106dd60013363ffffffff611bb016565b151561071d5760405160e560020a62461bcd02815260040180806020018281038252602f815260200180612289602f913960400191505060405180910390fd5b336000818152600960209081526040808320600160a060020a03891680855290835292819020879055805187815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b60085490565b600554600160a060020a031681565b600054600160a060020a031633146107fc576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b60005460ff7401000000000000000000000000000000000000000090910416151581151514156108605760405160e560020a62461bcd0281526004018080602001828103825260288152602001806122dd6028913960400191505060405180910390fd5b60008054911515740100000000000000000000000000000000000000000274ff000000000000000000000000000000000000000019909216919091179055565b6000805474010000000000000000000000000000000000000000900460ff16156108fe5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600160a060020a0380841660009081526006602052604090205484911615610970576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b600160a060020a038516600090815260076020526040902054859084908111156109e4576040805160e560020a62461bcd02815260206004820152601260248201527f496e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0387166000908152600960209081526040808320338452909152902054851115610a5f576040805160e560020a62461bcd02815260206004820152601a60248201527f5472616e73666572206578636565647320616c6c6f77616e6365000000000000604482015290519081900360640190fd5b6000610a6e8888886000611be7565b90508015610ad957600160a060020a0388166000908152600960209081526040808320338452909152902054610aaa908763ffffffff611db416565b600160a060020a0389166000908152600960209081526040808320338452909152902055610ad9888888611e14565b979650505050505050565b600160a060020a038181166000908152600660205260409020541615155b919050565b600081565b600660205260009081526040902054600160a060020a031681565b60015481565b600054600160a060020a03163314610b8f576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b600054600160a060020a0316ff5b60055474010000000000000000000000000000000000000000900460ff1681565b600054600160a060020a03163314610c20576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b600054600160a060020a0382811691161415610c705760405160e560020a62461bcd0281526004018080602001828103825260258152602001806122b86025913960400191505060405180910390fd5b600160a060020a0381161515610cd0576040805160e560020a62461bcd02815260206004820181905260248201527f4e6577204f776e65722063616e6e6f74206265207a65726f2061646472657373604482015290519081900360640190fd5b60008054600160a060020a0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8934ce4adea8d9ce0d714d2c22b86790e41b7731c84b926fbbdc1d40ff6533c99190a35050565b60005474010000000000000000000000000000000000000000900460ff1615610d8a5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600054600160a060020a03163314610dec576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b6005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383811691821792839055604051919216907ff7189b85d7899f5a32d733e6584c4f1dcdff0274f09d969d186c1797673ede1190600090a350565b600454600160a060020a031681565b600160a060020a031660009081526007602052604090205490565b60005474010000000000000000000000000000000000000000900460ff1615610ed05760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600554600160a060020a03163314610f32576040805160e560020a62461bcd02815260206004820152601360248201527f4f6e6c792069737375657220616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b600160a060020a0380821660009081526006602052604090205482911615610fa4576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b610fb560018463ffffffff611bb016565b8015610fcf5750610fcd60018363ffffffff611bb016565b155b151561100f5760405160e560020a62461bcd02815260040180806020018281038252602a81526020018061225f602a913960400191505060405180910390fd5b600454600160a060020a0316156111325760048054600160a060020a0385811660008181526007602090815260408083205481517ffd8258bd00000000000000000000000000000000000000000000000000000000815233988101989098526024880194909452888516604488015260648701939093529151929093169363fd8258bd93608480830194928390030190829087803b1580156110b057600080fd5b505af11580156110c4573d6000803e3d6000fd5b505050506040513d60208110156110da57600080fd5b50511515611132576040805160e560020a62461bcd02815260206004820152601860248201527f4661696c6564202763616e49737375652720636865636b2e0000000000000000604482015290519081900360640190fd5b61114360018463ffffffff611fb616565b5061115560018363ffffffff6120bb16565b50600160a060020a038381166000818152600660209081526040808320805473ffffffffffffffffffffffffffffffffffffffff19169588169586179055600790915280822080548584528284205583835282905551339392917fb64971100522354f3d25283cb14e2eefcb0dd26a757482ccfe42479d0a68685791a4505050565b6000805474010000000000000000000000000000000000000000900460ff16156112355760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600554600160a060020a03163314611297576040805160e560020a62461bcd02815260206004820152601360248201527f4f6e6c792069737375657220616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b60055474010000000000000000000000000000000000000000900460ff161561130a576040805160e560020a62461bcd02815260206004820152601b60248201527f49737375696e6720697320616c72656164792066696e69736865640000000000604482015290519081900360640190fd5b6005805474ff00000000000000000000000000000000000000001916740100000000000000000000000000000000000000001790556040517f7bc15082cf539fecd9e12596dc8e4e77c17a81fccc2c267b626af583162232a290600090a15060055474010000000000000000000000000000000000000000900460ff1690565b6000805474010000000000000000000000000000000000000000900460ff16156113e85760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600160a060020a038084166000908152600660205260409020548491161561145a576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b600160a060020a038516600090815260076020526040902054859084908111156114ce576040805160e560020a62461bcd02815260206004820152601260248201527f496e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b60006114dd8888886001611be7565b90508015610ad957610ad9888888611e14565b600061150360018363ffffffff61216f16565b92915050565b600054600160a060020a031681565b60408051808201909152600581527f545a524f50000000000000000000000000000000000000000000000000000000602082015281565b60005474010000000000000000000000000000000000000000900460ff1681565b6000805474010000000000000000000000000000000000000000900460ff16156115ce5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600554600160a060020a03163314611630576040805160e560020a62461bcd02815260206004820152601360248201527f4f6e6c792069737375657220616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b60055474010000000000000000000000000000000000000000900460ff16156116a3576040805160e560020a62461bcd02815260206004820152601b60248201527f49737375696e6720697320616c72656164792066696e69736865640000000000604482015290519081900360640190fd5b6000821115611724576008546116bf908363ffffffff6121fa16565b600855600554600160a060020a03166000908152600760205260409020546116ed908363ffffffff6121fa16565b60058054600160a060020a0390811660009081526007602052604090209290925554611722916001911663ffffffff6120bb16565b505b600554604080518481529051600160a060020a03909216917fc65a3f767206d2fdcede0b094a4840e01c0dd0be1888b5ba800346eaa0123c169181900360200190a2600554604080518481529051600160a060020a03909216916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a3506001919050565b6000805474010000000000000000000000000000000000000000900460ff16156118125760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600160a060020a0380841660009081526006602052604090205484911615611884576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b3360008181526007602052604090205484908111156118ed576040805160e560020a62461bcd02815260206004820152601260248201527f496e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b600554600090600160a060020a03163314156119cb5750600454600160a060020a031615806119c65760048054600554604080517ffd8258bd000000000000000000000000000000000000000000000000000000008152600160a060020a0392831694810185905260248101949094528a82166044850152606484018a90525191169163fd8258bd9160848083019260209291908290030181600087803b15801561199757600080fd5b505af11580156119ab573d6000803e3d6000fd5b505050506040513d60208110156119c157600080fd5b505190505b6119db565b6119d83388886000611be7565b90505b80156119ec576119ec338888611e14565b9695505050505050565b600061150360018363ffffffff611bb016565b600160a060020a03918216600090815260096020908152604080832093909416825291909152205490565b6000600160a060020a0382161515611a96576040805160e560020a62461bcd02815260206004820152601960248201527f4e6f6e2d7a65726f206164647265737320726571756972656400000000000000604482015290519081900360640190fd5b600160a060020a0380831660009081526006602052604090205416801515611503576000915050610b02565b60005474010000000000000000000000000000000000000000900460ff1615611b1f5760405160e560020a62461bcd02815260040180806020018281038252602d815260200180612305602d913960400191505060405180910390fd5b600054600160a060020a03163314611b81576040805160e560020a62461bcd02815260206004820152601960248201527f4f776e6572206163636f756e7420697320726571756972656400000000000000604482015290519081900360640190fd5b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a038116600090815260018301602052604081205460001901818112801590611bdf5750835481125b949350505050565b600160a060020a03808416600090815260066020526040812054909185911615611c5b576040805160e560020a62461bcd02815260206004820152601a60248201527f4164647265737320686173206265656e2063616e63656c6c6564000000000000604482015290519081900360640190fd5b600454600160a060020a03161515611c765782159150611dab565b8215611d2d5760048054604080517f5acba2010000000000000000000000000000000000000000000000000000000081523393810193909352600160a060020a0389811660248501528881166044850152606484018890529051911691635acba2019160848083019260209291908290030181600087803b158015611cfa57600080fd5b505af1158015611d0e573d6000803e3d6000fd5b505050506040513d6020811015611d2457600080fd5b50519150611dab565b60048054604080517f6d62a4fe0000000000000000000000000000000000000000000000000000000081523393810193909352600160a060020a0389811660248501528881166044850152606484018890529051911691636d62a4fe9160848083019260209291908290030181600087803b158015611cfa57600080fd5b50949350505050565b600082821115611e0e576040805160e560020a62461bcd02815260206004820152601460248201527f526573756c747320696e20756e646572666c6f77000000000000000000000000604482015290519081900360640190fd5b50900390565b600160a060020a038316600090815260076020526040902054611e3d908263ffffffff611db416565b600160a060020a038085166000908152600760205260408082209390935590841681522054611e72908263ffffffff6121fa16565b600160a060020a0380841660008181526007602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3600160a060020a038216600090815260076020526040812054118015611efb5750611efb60018363ffffffff6120bb16565b15611f3d5760408051600160a060020a038416815290517f3082c1c4977de80c4f67ee77b56b282610ec93a7ecbcc31b551e0ac2f7bd03959181900360200190a15b600160a060020a038316600090815260076020526040902054158015611f6f5750611f6f60018463ffffffff611fb616565b15611fb15760408051600160a060020a038516815290517f7ba114ff3d9844510a088eea94cd35562e7c97a2d36a418b37b2e61e5c77affe9181900360200190a15b505050565b600160a060020a03811660009081526001808401602052604082205490811280611fe05750835481135b15611fef576000915050611503565b83548112156120635783546000908152600285016020818152604080842054600160a060020a031680855260018901835281852086905585855292909152808320805473ffffffffffffffffffffffffffffffffffffffff199081169093179055865483529091208054909116905561208f565b60008181526002850160205260409020805473ffffffffffffffffffffffffffffffffffffffff191690555b5050600160a060020a031660009081526001828101602052604082209190915581546000190190915590565b6000600160a060020a03821615156120d557506000611503565b600160a060020a0382166000908152600184016020526040812054600019019081128015906121045750835481125b15612113576000915050611503565b505081546001908101808455600160a060020a03831660008181528386016020908152604080832085905593825260028701905291909120805473ffffffffffffffffffffffffffffffffffffffff1916909117905592915050565b60008082121580156121815750825482125b15156121d7576040805160e560020a62461bcd02815260206004820152601860248201527f496e646578206f757473696465206f6620626f756e64732e0000000000000000604482015290519081900360640190fd5b5060010160009081526002919091016020526040902054600160a060020a031690565b600082820183811015612257576040805160e560020a62461bcd02815260206004820152601360248201527f526573756c747320696e206f766572666c6f7700000000000000000000000000604482015290519081900360640190fd5b939250505056fe4f726967696e616c20646f65736e2774206578697374206f72207265706c6163656d656e7420646f65734d7573742062652061207368617265686f6c64657220746f20617070726f766520746f6b656e207472616e736665724e6577204f776e65722063616e6e6f74206265207468652063757272656e74206f776e6572436f6e747261637420616c726561647920696e20726571756573746564206c6f636b207374617465436f6e74726163742069732063757272656e746c79206c6f636b656420666f72206d6f64696669636174696f6ea165627a7a72305820aaa9c0c19f6c5795773194111572f9115f68c17c15fbd5386874d0078fb81b820029

Swarm Source

bzzr://aaa9c0c19f6c5795773194111572f9115f68c17c15fbd5386874d0078fb81b82
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.