ETH Price: $3,619.01 (-2.86%)

Token

TIME (TIME)
 

Overview

Max Total Supply

710,112.8108 TIME

Holders

4,027 (0.00%)

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 8 Decimals)

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:
ChronoBankAssetProxy

Compiler Version
v0.4.8+commit.60cc1668

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-03-06
*/

pragma solidity ^0.4.4;

contract Owned {
    address public contractOwner;
    address public pendingContractOwner;

    function Owned() {
        contractOwner = msg.sender;
    }

    modifier onlyContractOwner() {
        if (contractOwner == msg.sender) {
            _;
        }
    }

    /**
     * Prepares ownership pass.
     *
     * Can only be called by current owner.
     *
     * @param _to address of the next owner.
     *
     * @return success.
     */
    function changeContractOwnership(address _to) onlyContractOwner() returns(bool) {
        pendingContractOwner = _to;
        return true;
    }

    /**
     * Finalize ownership pass.
     *
     * Can only be called by pending owner.
     *
     * @return success.
     */
    function claimContractOwnership() returns(bool) {
        if (pendingContractOwner != msg.sender) {
            return false;
        }
        contractOwner = pendingContractOwner;
        delete pendingContractOwner;
        return true;
    }
}


contract Emitter {
    function emitTransfer(address _from, address _to, bytes32 _symbol, uint _value, string _reference);
    function emitIssue(bytes32 _symbol, uint _value, address _by);
    function emitRevoke(bytes32 _symbol, uint _value, address _by);
    function emitOwnershipChange(address _from, address _to, bytes32 _symbol);
    function emitApprove(address _from, address _spender, bytes32 _symbol, uint _value);
    function emitRecovery(address _from, address _to, address _by);
    function emitError(bytes32 _message);
}

contract Proxy {
    function emitTransfer(address _from, address _to, uint _value);
    function emitApprove(address _from, address _spender, uint _value);
}

/**
 * @title ChronoBank Platform.
 *
 * The official ChronoBank assets platform powering TIME and LHT tokens, and possibly
 * other unknown tokens needed later.
 * Platform uses EventsHistory contract to keep events, so that in case it needs to be redeployed
 * at some point, all the events keep appearing at the same place.
 *
 * Every asset is meant to be used through a proxy contract. Only one proxy contract have access
 * rights for a particular asset.
 *
 * Features: transfers, allowances, supply adjustments, lost wallet access recovery.
 *
 * Note: all the non constant functions return false instead of throwing in case if state change
 * didn't happen yet.
 */
contract ChronoBankPlatform is Owned {
    // Structure of a particular asset.
    struct Asset {
        uint owner;                       // Asset's owner id.
        uint totalSupply;                 // Asset's total supply.
        string name;                      // Asset's name, for information purposes.
        string description;               // Asset's description, for information purposes.
        bool isReissuable;                // Indicates if asset have dynamic of fixed supply.
        uint8 baseUnit;                   // Proposed number of decimals.
        mapping(uint => Wallet) wallets;  // Holders wallets.
    }

    // Structure of an asset holder wallet for particular asset.
    struct Wallet {
        uint balance;
        mapping(uint => uint) allowance;
    }

    // Structure of an asset holder.
    struct Holder {
        address addr;                    // Current address of the holder.
        mapping(address => bool) trust;  // Addresses that are trusted with recovery proocedure.
    }

    // Iterable mapping pattern is used for holders.
    uint public holdersCount;
    mapping(uint => Holder) public holders;

    // This is an access address mapping. Many addresses may have access to a single holder.
    mapping(address => uint) holderIndex;

    // Asset symbol to asset mapping.
    mapping(bytes32 => Asset) public assets;

    // Asset symbol to asset proxy mapping.
    mapping(bytes32 => address) public proxies;

    // Should use interface of the emitter, but address of events history.
    Emitter public eventsHistory;

    /**
     * Emits Error event with specified error message.
     *
     * Should only be used if no state changes happened.
     *
     * @param _message error message.
     */
    function _error(bytes32 _message) internal {
        eventsHistory.emitError(_message);
    }

    /**
     * Sets EventsHstory contract address.
     *
     * Can be set only once, and only by contract owner.
     *
     * @param _eventsHistory EventsHistory contract address.
     *
     * @return success.
     */
    function setupEventsHistory(address _eventsHistory) onlyContractOwner() returns(bool) {
        if (address(eventsHistory) != 0) {
            return false;
        }
        eventsHistory = Emitter(_eventsHistory);
        return true;
    }

    /**
     * Emits Error if called not by asset owner.
     */
    modifier onlyOwner(bytes32 _symbol) {
        if (isOwner(msg.sender, _symbol)) {
            _;
        } else {
            _error("Only owner: access denied");
        }
    }

    /**
     * Emits Error if called not by asset proxy.
     */
    modifier onlyProxy(bytes32 _symbol) {
        if (proxies[_symbol] == msg.sender) {
            _;
        } else {
            _error("Only proxy: access denied");
        }
    }

    /**
     * Emits Error if _from doesn't trust _to.
     */
    modifier checkTrust(address _from, address _to) {
        if (isTrusted(_from, _to)) {
            _;
        } else {
            _error("Only trusted: access denied");
        }
    }

    /**
     * Check asset existance.
     *
     * @param _symbol asset symbol.
     *
     * @return asset existance.
     */
    function isCreated(bytes32 _symbol) constant returns(bool) {
        return assets[_symbol].owner != 0;
    }

    /**
     * Returns asset decimals.
     *
     * @param _symbol asset symbol.
     *
     * @return asset decimals.
     */
    function baseUnit(bytes32 _symbol) constant returns(uint8) {
        return assets[_symbol].baseUnit;
    }

    /**
     * Returns asset name.
     *
     * @param _symbol asset symbol.
     *
     * @return asset name.
     */
    function name(bytes32 _symbol) constant returns(string) {
        return assets[_symbol].name;
    }

    /**
     * Returns asset description.
     *
     * @param _symbol asset symbol.
     *
     * @return asset description.
     */
    function description(bytes32 _symbol) constant returns(string) {
        return assets[_symbol].description;
    }

    /**
     * Returns asset reissuability.
     *
     * @param _symbol asset symbol.
     *
     * @return asset reissuability.
     */
    function isReissuable(bytes32 _symbol) constant returns(bool) {
        return assets[_symbol].isReissuable;
    }

    /**
     * Returns asset owner address.
     *
     * @param _symbol asset symbol.
     *
     * @return asset owner address.
     */
    function owner(bytes32 _symbol) constant returns(address) {
        return holders[assets[_symbol].owner].addr;
    }

    /**
     * Check if specified address has asset owner rights.
     *
     * @param _owner address to check.
     * @param _symbol asset symbol.
     *
     * @return owner rights availability.
     */
    function isOwner(address _owner, bytes32 _symbol) constant returns(bool) {
        return isCreated(_symbol) && (assets[_symbol].owner == getHolderId(_owner));
    }

    /**
     * Returns asset total supply.
     *
     * @param _symbol asset symbol.
     *
     * @return asset total supply.
     */
    function totalSupply(bytes32 _symbol) constant returns(uint) {
        return assets[_symbol].totalSupply;
    }

    /**
     * Returns asset balance for a particular holder.
     *
     * @param _holder holder address.
     * @param _symbol asset symbol.
     *
     * @return holder balance.
     */
    function balanceOf(address _holder, bytes32 _symbol) constant returns(uint) {
        return _balanceOf(getHolderId(_holder), _symbol);
    }

    /**
     * Returns asset balance for a particular holder id.
     *
     * @param _holderId holder id.
     * @param _symbol asset symbol.
     *
     * @return holder balance.
     */
    function _balanceOf(uint _holderId, bytes32 _symbol) constant returns(uint) {
        return assets[_symbol].wallets[_holderId].balance;
    }

    /**
     * Returns current address for a particular holder id.
     *
     * @param _holderId holder id.
     *
     * @return holder address.
     */
    function _address(uint _holderId) constant returns(address) {
        return holders[_holderId].addr;
    }

    /**
     * Sets Proxy contract address for a particular asset.
     *
     * Can be set only once for each asset, and only by contract owner.
     *
     * @param _address Proxy contract address.
     * @param _symbol asset symbol.
     *
     * @return success.
     */
    function setProxy(address _address, bytes32 _symbol) onlyContractOwner() returns(bool) {
        if (proxies[_symbol] != 0x0) {
            return false;
        }
        proxies[_symbol] = _address;
        return true;
    }

    /**
     * Transfers asset balance between holders wallets.
     *
     * @param _fromId holder id to take from.
     * @param _toId holder id to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     */
    function _transferDirect(uint _fromId, uint _toId, uint _value, bytes32 _symbol) internal {
        assets[_symbol].wallets[_fromId].balance -= _value;
        assets[_symbol].wallets[_toId].balance += _value;
    }

    /**
     * Transfers asset balance between holders wallets.
     *
     * Performs sanity checks and takes care of allowances adjustment.
     *
     * @param _fromId holder id to take from.
     * @param _toId holder id to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     * @param _reference transfer comment to be included in a Transfer event.
     * @param _senderId transfer initiator holder id.
     *
     * @return success.
     */
    function _transfer(uint _fromId, uint _toId, uint _value, bytes32 _symbol, string _reference, uint _senderId) internal returns(bool) {
        // Should not allow to send to oneself.
        if (_fromId == _toId) {
            _error("Cannot send to oneself");
            return false;
        }
        // Should have positive value.
        if (_value == 0) {
            _error("Cannot send 0 value");
            return false;
        }
        // Should have enough balance.
        if (_balanceOf(_fromId, _symbol) < _value) {
            _error("Insufficient balance");
            return false;
        }
        // Should have enough allowance.
        if (_fromId != _senderId && _allowance(_fromId, _senderId, _symbol) < _value) {
            _error("Not enough allowance");
            return false;
        }
        _transferDirect(_fromId, _toId, _value, _symbol);
        // Adjust allowance.
        if (_fromId != _senderId) {
            assets[_symbol].wallets[_fromId].allowance[_senderId] -= _value;
        }
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitTransfer(_address(_fromId), _address(_toId), _symbol, _value, _reference);
        _proxyTransferEvent(_fromId, _toId, _value, _symbol);
        return true;
    }

    /**
     * Transfers asset balance between holders wallets.
     *
     * Can only be called by asset proxy.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     * @param _reference transfer comment to be included in a Transfer event.
     * @param _sender transfer initiator address.
     *
     * @return success.
     */
    function proxyTransferWithReference(address _to, uint _value, bytes32 _symbol, string _reference, address _sender) onlyProxy(_symbol) returns(bool) {
        return _transfer(getHolderId(_sender), _createHolderId(_to), _value, _symbol, _reference, getHolderId(_sender));
    }

    /**
     * Ask asset Proxy contract to emit ERC20 compliant Transfer event.
     *
     * @param _fromId holder id to take from.
     * @param _toId holder id to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     */
    function _proxyTransferEvent(uint _fromId, uint _toId, uint _value, bytes32 _symbol) internal {
        if (proxies[_symbol] != 0x0) {
            // Internal Out Of Gas/Throw: revert this transaction too;
            // Call Stack Depth Limit reached: n/a after HF 4;
            // Recursive Call: safe, all changes already made.
            Proxy(proxies[_symbol]).emitTransfer(_address(_fromId), _address(_toId), _value);
        }
    }

    /**
     * Returns holder id for the specified address.
     *
     * @param _holder holder address.
     *
     * @return holder id.
     */
    function getHolderId(address _holder) constant returns(uint) {
        return holderIndex[_holder];
    }

    /**
     * Returns holder id for the specified address, creates it if needed.
     *
     * @param _holder holder address.
     *
     * @return holder id.
     */
    function _createHolderId(address _holder) internal returns(uint) {
        uint holderId = holderIndex[_holder];
        if (holderId == 0) {
            holderId = ++holdersCount;
            holders[holderId].addr = _holder;
            holderIndex[_holder] = holderId;
        }
        return holderId;
    }

    /**
     * Issues new asset token on the platform.
     *
     * Tokens issued with this call go straight to contract owner.
     * Each symbol can be issued only once, and only by contract owner.
     *
     * @param _symbol asset symbol.
     * @param _value amount of tokens to issue immediately.
     * @param _name name of the asset.
     * @param _description description for the asset.
     * @param _baseUnit number of decimals.
     * @param _isReissuable dynamic or fixed supply.
     *
     * @return success.
     */
    function issueAsset(bytes32 _symbol, uint _value, string _name, string _description, uint8 _baseUnit, bool _isReissuable) onlyContractOwner() returns(bool) {
        // Should have positive value if supply is going to be fixed.
        if (_value == 0 && !_isReissuable) {
            _error("Cannot issue 0 value fixed asset");
            return false;
        }
        // Should not be issued yet.
        if (isCreated(_symbol)) {
            _error("Asset already issued");
            return false;
        }
        uint holderId = _createHolderId(msg.sender);

        assets[_symbol] = Asset(holderId, _value, _name, _description, _isReissuable, _baseUnit);
        assets[_symbol].wallets[holderId].balance = _value;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitIssue(_symbol, _value, _address(holderId));
        return true;
    }

    /**
     * Issues additional asset tokens if the asset have dynamic supply.
     *
     * Tokens issued with this call go straight to asset owner.
     * Can only be called by asset owner.
     *
     * @param _symbol asset symbol.
     * @param _value amount of additional tokens to issue.
     *
     * @return success.
     */
    function reissueAsset(bytes32 _symbol, uint _value) onlyOwner(_symbol) returns(bool) {
        // Should have positive value.
        if (_value == 0) {
            _error("Cannot reissue 0 value");
            return false;
        }
        Asset asset = assets[_symbol];
        // Should have dynamic supply.
        if (!asset.isReissuable) {
            _error("Cannot reissue fixed asset");
            return false;
        }
        // Resulting total supply should not overflow.
        if (asset.totalSupply + _value < asset.totalSupply) {
            _error("Total supply overflow");
            return false;
        }
        uint holderId = getHolderId(msg.sender);
        asset.wallets[holderId].balance += _value;
        asset.totalSupply += _value;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitIssue(_symbol, _value, _address(holderId));
        _proxyTransferEvent(0, holderId, _value, _symbol);
        return true;
    }

    /**
     * Destroys specified amount of senders asset tokens.
     *
     * @param _symbol asset symbol.
     * @param _value amount of tokens to destroy.
     *
     * @return success.
     */
    function revokeAsset(bytes32 _symbol, uint _value) returns(bool) {
        // Should have positive value.
        if (_value == 0) {
            _error("Cannot revoke 0 value");
            return false;
        }
        Asset asset = assets[_symbol];
        uint holderId = getHolderId(msg.sender);
        // Should have enough tokens.
        if (asset.wallets[holderId].balance < _value) {
            _error("Not enough tokens to revoke");
            return false;
        }
        asset.wallets[holderId].balance -= _value;
        asset.totalSupply -= _value;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitRevoke(_symbol, _value, _address(holderId));
        _proxyTransferEvent(holderId, 0, _value, _symbol);
        return true;
    }

    /**
     * Passes asset ownership to specified address.
     *
     * Only ownership is changed, balances are not touched.
     * Can only be called by asset owner.
     *
     * @param _symbol asset symbol.
     * @param _newOwner address to become a new owner.
     *
     * @return success.
     */
    function changeOwnership(bytes32 _symbol, address _newOwner) onlyOwner(_symbol) returns(bool) {
        Asset asset = assets[_symbol];
        uint newOwnerId = _createHolderId(_newOwner);
        // Should pass ownership to another holder.
        if (asset.owner == newOwnerId) {
            _error("Cannot pass ownership to oneself");
            return false;
        }
        address oldOwner = _address(asset.owner);
        asset.owner = newOwnerId;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitOwnershipChange(oldOwner, _address(newOwnerId), _symbol);
        return true;
    }

    /**
     * Check if specified holder trusts an address with recovery procedure.
     *
     * @param _from truster.
     * @param _to trustee.
     *
     * @return trust existance.
     */
    function isTrusted(address _from, address _to) constant returns(bool) {
        return holders[getHolderId(_from)].trust[_to];
    }

    /**
     * Trust an address to perform recovery procedure for the caller.
     *
     * @param _to trustee.
     *
     * @return success.
     */
    function trust(address _to) returns(bool) {
        uint fromId = _createHolderId(msg.sender);
        // Should trust to another address.
        if (fromId == getHolderId(_to)) {
            _error("Cannot trust to oneself");
            return false;
        }
        // Should trust to yet untrusted.
        if (isTrusted(msg.sender, _to)) {
            _error("Already trusted");
            return false;
        }
        holders[fromId].trust[_to] = true;
        return true;
    }

    /**
     * Revoke trust to perform recovery procedure from an address.
     *
     * @param _to trustee.
     *
     * @return success.
     */
    function distrust(address _to) checkTrust(msg.sender, _to) returns(bool) {
        holders[getHolderId(msg.sender)].trust[_to] = false;
        return true;
    }

    /**
     * Perform recovery procedure.
     *
     * This function logic is actually more of an addAccess(uint _holderId, address _to).
     * It grants another address access to recovery subject wallets.
     * Can only be called by trustee of recovery subject.
     *
     * @param _from holder address to recover from.
     * @param _to address to grant access to.
     *
     * @return success.
     */
    function recover(address _from, address _to) checkTrust(_from, msg.sender) returns(bool) {
        // Should recover to previously unused address.
        if (getHolderId(_to) != 0) {
            _error("Should recover to new address");
            return false;
        }
        // We take current holder address because it might not equal _from.
        // It is possible to recover from any old holder address, but event should have the current one.
        address from = holders[getHolderId(_from)].addr;
        holders[getHolderId(_from)].addr = _to;
        holderIndex[_to] = getHolderId(_from);
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: revert this transaction too;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitRecovery(from, _to, msg.sender);
        return true;
    }

    /**
     * Sets asset spending allowance for a specified spender.
     *
     * Note: to revoke allowance, one needs to set allowance to 0.
     *
     * @param _spenderId holder id to set allowance for.
     * @param _value amount to allow.
     * @param _symbol asset symbol.
     * @param _senderId approve initiator holder id.
     *
     * @return success.
     */
    function _approve(uint _spenderId, uint _value, bytes32 _symbol, uint _senderId) internal returns(bool) {
        // Asset should exist.
        if (!isCreated(_symbol)) {
            _error("Asset is not issued");
            return false;
        }
        // Should allow to another holder.
        if (_senderId == _spenderId) {
            _error("Cannot approve to oneself");
            return false;
        }
        assets[_symbol].wallets[_senderId].allowance[_spenderId] = _value;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: revert this transaction too;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitApprove(_address(_senderId), _address(_spenderId), _symbol, _value);
        if (proxies[_symbol] != 0x0) {
            // Internal Out Of Gas/Throw: revert this transaction too;
            // Call Stack Depth Limit reached: n/a after HF 4;
            // Recursive Call: safe, all changes already made.
            Proxy(proxies[_symbol]).emitApprove(_address(_senderId), _address(_spenderId), _value);
        }
        return true;
    }

    /**
     * Sets asset spending allowance for a specified spender.
     *
     * Can only be called by asset proxy.
     *
     * @param _spender holder address to set allowance to.
     * @param _value amount to allow.
     * @param _symbol asset symbol.
     * @param _sender approve initiator address.
     *
     * @return success.
     */
    function proxyApprove(address _spender, uint _value, bytes32 _symbol, address _sender) onlyProxy(_symbol) returns(bool) {
        return _approve(_createHolderId(_spender), _value, _symbol, _createHolderId(_sender));
    }

    /**
     * Returns asset allowance from one holder to another.
     *
     * @param _from holder that allowed spending.
     * @param _spender holder that is allowed to spend.
     * @param _symbol asset symbol.
     *
     * @return holder to spender allowance.
     */
    function allowance(address _from, address _spender, bytes32 _symbol) constant returns(uint) {
        return _allowance(getHolderId(_from), getHolderId(_spender), _symbol);
    }

    /**
     * Returns asset allowance from one holder to another.
     *
     * @param _fromId holder id that allowed spending.
     * @param _toId holder id that is allowed to spend.
     * @param _symbol asset symbol.
     *
     * @return holder to spender allowance.
     */
    function _allowance(uint _fromId, uint _toId, bytes32 _symbol) constant internal returns(uint) {
        return assets[_symbol].wallets[_fromId].allowance[_toId];
    }

    /**
     * Prforms allowance transfer of asset balance between holders wallets.
     *
     * Can only be called by asset proxy.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     * @param _reference transfer comment to be included in a Transfer event.
     * @param _sender allowance transfer initiator address.
     *
     * @return success.
     */
    function proxyTransferFromWithReference(address _from, address _to, uint _value, bytes32 _symbol, string _reference, address _sender) onlyProxy(_symbol) returns(bool) {
        return _transfer(getHolderId(_from), _createHolderId(_to), _value, _symbol, _reference, getHolderId(_sender));
    }
}

contract ChronoBankAsset {
    function __transferWithReference(address _to, uint _value, string _reference, address _sender) returns(bool);
    function __transferFromWithReference(address _from, address _to, uint _value, string _reference, address _sender) returns(bool);
    function __approve(address _spender, uint _value, address _sender) returns(bool);
    function __process(bytes _data, address _sender) payable {
        throw;
    }
}

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

    function totalSupply() constant returns (uint256 supply);
    function balanceOf(address _owner) constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
}

contract ChronoBankAssetProxy is ERC20 {
    // Assigned platform, immutable.
    ChronoBankPlatform public chronoBankPlatform;

    // Assigned symbol, immutable.
    bytes32 smbl;

    // Assigned name, immutable.
    string public name;

    string public symbol;

    /**
     * Sets platform address, assigns symbol and name.
     *
     * Can be set only once.
     *
     * @param _chronoBankPlatform platform contract address.
     * @param _symbol assigned symbol.
     * @param _name assigned name.
     *
     * @return success.
     */
    function init(ChronoBankPlatform _chronoBankPlatform, string _symbol, string _name) returns(bool) {
        if (address(chronoBankPlatform) != 0x0) {
            return false;
        }
        chronoBankPlatform = _chronoBankPlatform;
        symbol = _symbol;
        smbl = stringToBytes32(_symbol);
        name = _name;
        return true;
    }

function stringToBytes32(string memory source) returns (bytes32 result) {
    assembly {
        result := mload(add(source, 32))
    }
}

    /**
     * Only platform is allowed to call.
     */
    modifier onlyChronoBankPlatform() {
        if (msg.sender == address(chronoBankPlatform)) {
            _;
        }
    }

    /**
     * Only current asset owner is allowed to call.
     */
    modifier onlyAssetOwner() {
        if (chronoBankPlatform.isOwner(msg.sender, smbl)) {
            _;
        }
    }

    /**
     * Returns asset implementation contract for current caller.
     *
     * @return asset implementation contract.
     */
    function _getAsset() internal returns(ChronoBankAsset) {
        return ChronoBankAsset(getVersionFor(msg.sender));
    }

    /**
     * Returns asset total supply.
     *
     * @return asset total supply.
     */
    function totalSupply() constant returns(uint) {
        return chronoBankPlatform.totalSupply(smbl);
    }

    /**
     * Returns asset balance for a particular holder.
     *
     * @param _owner holder address.
     *
     * @return holder balance.
     */
    function balanceOf(address _owner) constant returns(uint) {
        return chronoBankPlatform.balanceOf(_owner, smbl);
    }

    /**
     * Returns asset allowance from one holder to another.
     *
     * @param _from holder that allowed spending.
     * @param _spender holder that is allowed to spend.
     *
     * @return holder to spender allowance.
     */
    function allowance(address _from, address _spender) constant returns(uint) {
        return chronoBankPlatform.allowance(_from, _spender, smbl);
    }

    /**
     * Returns asset decimals.
     *
     * @return asset decimals.
     */
    function decimals() constant returns(uint8) {
        return chronoBankPlatform.baseUnit(smbl);
    }

    /**
     * Transfers asset balance from the caller to specified receiver.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     *
     * @return success.
     */
    function transfer(address _to, uint _value) returns(bool) {
        return _transferWithReference(_to, _value, "");
    }

    /**
     * Transfers asset balance from the caller to specified receiver adding specified comment.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     *
     * @return success.
     */
    function transferWithReference(address _to, uint _value, string _reference) returns(bool) {
        return _transferWithReference(_to, _value, _reference);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there arguments along with
     * the caller address.
     *
     * @return success.
     */
    function _transferWithReference(address _to, uint _value, string _reference) internal returns(bool) {
        return _getAsset().__transferWithReference(_to, _value, _reference, msg.sender);
    }

    /**
     * Performs transfer call on the platform by the name of specified sender.
     *
     * Can only be called by asset implementation contract assigned to sender.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     * @param _sender initial caller.
     *
     * @return success.
     */
    function __transferWithReference(address _to, uint _value, string _reference, address _sender) onlyAccess(_sender) returns(bool) {
        return chronoBankPlatform.proxyTransferWithReference(_to, _value, smbl, _reference, _sender);
    }

    /**
     * Prforms allowance transfer of asset balance between holders.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     *
     * @return success.
     */
    function transferFrom(address _from, address _to, uint _value) returns(bool) {
        return _transferFromWithReference(_from, _to, _value, "");
    }

    /**
     * Prforms allowance transfer of asset balance between holders adding specified comment.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     *
     * @return success.
     */
    function transferFromWithReference(address _from, address _to, uint _value, string _reference) returns(bool) {
        return _transferFromWithReference(_from, _to, _value, _reference);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there arguments along with
     * the caller address.
     *
     * @return success.
     */
    function _transferFromWithReference(address _from, address _to, uint _value, string _reference) internal returns(bool) {
        return _getAsset().__transferFromWithReference(_from, _to, _value, _reference, msg.sender);
    }

    /**
     * Performs allowance transfer call on the platform by the name of specified sender.
     *
     * Can only be called by asset implementation contract assigned to sender.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     * @param _sender initial caller.
     *
     * @return success.
     */
    function __transferFromWithReference(address _from, address _to, uint _value, string _reference, address _sender) onlyAccess(_sender) returns(bool) {
        return chronoBankPlatform.proxyTransferFromWithReference(_from, _to, _value, smbl, _reference, _sender);
    }

    /**
     * Sets asset spending allowance for a specified spender.
     *
     * @param _spender holder address to set allowance to.
     * @param _value amount to allow.
     *
     * @return success.
     */
    function approve(address _spender, uint _value) returns(bool) {
        return _approve(_spender, _value);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there arguments along with
     * the caller address.
     *
     * @return success.
     */
    function _approve(address _spender, uint _value) internal returns(bool) {
        return _getAsset().__approve(_spender, _value, msg.sender);
    }

    /**
     * Performs allowance setting call on the platform by the name of specified sender.
     *
     * Can only be called by asset implementation contract assigned to sender.
     *
     * @param _spender holder address to set allowance to.
     * @param _value amount to allow.
     * @param _sender initial caller.
     *
     * @return success.
     */
    function __approve(address _spender, uint _value, address _sender) onlyAccess(_sender) returns(bool) {
        return chronoBankPlatform.proxyApprove(_spender, _value, smbl, _sender);
    }

    /**
     * Emits ERC20 Transfer event on this contract.
     *
     * Can only be, and, called by assigned platform when asset transfer happens.
     */
    function emitTransfer(address _from, address _to, uint _value) onlyChronoBankPlatform() {
        Transfer(_from, _to, _value);
    }

    /**
     * Emits ERC20 Approval event on this contract.
     *
     * Can only be, and, called by assigned platform when asset allowance set happens.
     */
    function emitApprove(address _from, address _spender, uint _value) onlyChronoBankPlatform() {
        Approval(_from, _spender, _value);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there transaction data,
     * along with the value. This allows for proxy interface growth.
     */
    function () payable {
        _getAsset().__process.value(msg.value)(msg.data, msg.sender);
    }

    /**
     * Indicates an upgrade freeze-time start, and the next asset implementation contract.
     */
    event UpgradeProposal(address newVersion);

    // Current asset implementation contract address.
    address latestVersion;

    // Proposed next asset implementation contract address.
    address pendingVersion;

    // Upgrade freeze-time start.
    uint pendingVersionTimestamp;

    // Timespan for users to review the new implementation and make decision.
    uint constant UPGRADE_FREEZE_TIME = 3 days;

    // Asset implementation contract address that user decided to stick with.
    // 0x0 means that user uses latest version.
    mapping(address => address) userOptOutVersion;

    /**
     * Only asset implementation contract assigned to sender is allowed to call.
     */
    modifier onlyAccess(address _sender) {
        if (getVersionFor(_sender) == msg.sender) {
            _;
        }
    }

    /**
     * Returns asset implementation contract address assigned to sender.
     *
     * @param _sender sender address.
     *
     * @return asset implementation contract address.
     */
    function getVersionFor(address _sender) constant returns(address) {
        return userOptOutVersion[_sender] == 0 ? latestVersion : userOptOutVersion[_sender];
    }

    /**
     * Returns current asset implementation contract address.
     *
     * @return asset implementation contract address.
     */
    function getLatestVersion() constant returns(address) {
        return latestVersion;
    }

    /**
     * Returns proposed next asset implementation contract address.
     *
     * @return asset implementation contract address.
     */
    function getPendingVersion() constant returns(address) {
        return pendingVersion;
    }

    /**
     * Returns upgrade freeze-time start.
     *
     * @return freeze-time start.
     */
    function getPendingVersionTimestamp() constant returns(uint) {
        return pendingVersionTimestamp;
    }

    /**
     * Propose next asset implementation contract address.
     *
     * Can only be called by current asset owner.
     *
     * Note: freeze-time should not be applied for the initial setup.
     *
     * @param _newVersion asset implementation contract address.
     *
     * @return success.
     */
    function proposeUpgrade(address _newVersion) onlyAssetOwner() returns(bool) {
        // Should not already be in the upgrading process.
        if (pendingVersion != 0x0) {
            return false;
        }
        // New version address should be other than 0x0.
        if (_newVersion == 0x0) {
            return false;
        }
        // Don't apply freeze-time for the initial setup.
        if (latestVersion == 0x0) {
            latestVersion = _newVersion;
            return true;
        }
        pendingVersion = _newVersion;
        pendingVersionTimestamp = now;
        UpgradeProposal(_newVersion);
        return true;
    }

    /**
     * Cancel the pending upgrade process.
     *
     * Can only be called by current asset owner.
     *
     * @return success.
     */
    function purgeUpgrade() onlyAssetOwner() returns(bool) {
        if (pendingVersion == 0x0) {
            return false;
        }
        delete pendingVersion;
        delete pendingVersionTimestamp;
        return true;
    }

    /**
     * Finalize an upgrade process setting new asset implementation contract address.
     *
     * Can only be called after an upgrade freeze-time.
     *
     * @return success.
     */
    function commitUpgrade() returns(bool) {
        if (pendingVersion == 0x0) {
            return false;
        }
        if (pendingVersionTimestamp + UPGRADE_FREEZE_TIME > now) {
            return false;
        }
        latestVersion = pendingVersion;
        delete pendingVersion;
        delete pendingVersionTimestamp;
        return true;
    }

    /**
     * Disagree with proposed upgrade, and stick with current asset implementation
     * until further explicit agreement to upgrade.
     *
     * @return success.
     */
    function optOut() returns(bool) {
        if (userOptOutVersion[msg.sender] != 0x0) {
            return false;
        }
        userOptOutVersion[msg.sender] = latestVersion;
        return true;
    }

    /**
     * Implicitly agree to upgrade to current and future asset implementation upgrades,
     * until further explicit disagreement.
     *
     * @return success.
     */
    function optIn() returns(bool) {
        delete userOptOutVersion[msg.sender];
        return true;
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"commitUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getLatestVersion","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"emitApprove","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"emitTransfer","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"chronoBankPlatform","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getPendingVersionTimestamp","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"purgeUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"optIn","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"}],"name":"transferFromWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"},{"name":"_sender","type":"address"}],"name":"__transferWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_sender","type":"address"}],"name":"__approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getPendingVersion","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"}],"name":"transferWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_chronoBankPlatform","type":"address"},{"name":"_symbol","type":"string"},{"name":"_name","type":"string"}],"name":"init","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newVersion","type":"address"}],"name":"proposeUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"source","type":"string"}],"name":"stringToBytes32","outputs":[{"name":"result","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"optOut","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_from","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"},{"name":"_sender","type":"address"}],"name":"__transferFromWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"}],"name":"getVersionFor","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newVersion","type":"address"}],"name":"UpgradeProposal","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"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]

606060405234610000575b61198d806100196000396000f3006060604052361561014e5763ffffffff60e060020a60003504166306fdde0381146101ed578063095ea7b31461027a5780630ba12c83146102aa5780630e6d1de9146102cb57806318160ddd146102f4578063233850891461031357806323b872dd1461033757806323de66511461036d578063313ce5671461039157806349752baf146103b45780634bfaf2e8146103dd5780634dfe950d146103fc5780635b48684e1461041d5780636461fe391461043e5780636a630ee7146104ba57806370a08231146105395780637b7054c81461056457806395d89b411461059b578063a883fb9014610628578063a9059cbb14610651578063ac35caee14610681578063b2b45df5146106f5578063c915fc93146107a3578063cfb51928146107d0578063d4eec5a614610835578063dd62ed3e14610856578063ec698a2814610887578063fe8beb711461090e575b6101eb5b61015a610943565b604080517ff2d6e0ab00000000000000000000000000000000000000000000000000000000815233600160a060020a03818116602484015260048301938452366044840181905294169363f2d6e0ab9334936000939190819060640185858082843782019150509450505050506000604051808303818588803b156100005761235a5a03f11561000057505050505b565b005b34610000576101fa610954565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3461000057610296600160a060020a03600435166024356109df565b604080519115158252519081900360200190f35b34610000576102966109f4565b604080519115158252519081900360200190f35b34610000576102d8610a59565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610a69565b60408051918252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610aea565b005b3461000057610296600160a060020a0360043581169060243516604435610b54565b604080519115158252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610b7c565b005b346100005761039e610be6565b6040805160ff9092168252519081900360200190f35b34610000576102d8610c67565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610c76565b60408051918252519081900360200190f35b3461000057610296610c7d565b604080519115158252519081900360200190f35b3461000057610296610d27565b604080519115158252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a03908116956024803590921695604435959460849492930191908190840183828082843750949650610d5395505050505050565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a031694602480359560649492939190920191819084018382808284375094965050509235600160a060020a03169250610d6c915050565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043516610eb4565b60408051918252519081900360200190f35b3461000057610296600160a060020a036004358116906024359060443516610f3e565b604080519115158252519081900360200190f35b34610000576101fa611007565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102d8611095565b60408051600160a060020a039092168252519081900360200190f35b3461000057610296600160a060020a03600435166024356110a5565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a03169460248035956064949293919092019181908401838280828437509496506110cb95505050505050565b604080519115158252519081900360200190f35b346100005760408051602060046024803582810135601f8101859004850286018501909652858552610296958335600160a060020a0316959394604494939290920191819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506110e295505050505050565b604080519115158252519081900360200190f35b3461000057610296600160a060020a036004351661128d565b604080519115158252519081900360200190f35b3461000057610301600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496506113c595505050505050565b60408051918252519081900360200190f35b34610000576102966113d0565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043581169060243516611431565b60408051918252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a0390811695602480359092169560443595946084949293019190819084018382808284375094965050509235600160a060020a031692506114c4915050565b604080519115158252519081900360200190f35b34610000576102d8600160a060020a0360043516611619565b60408051600160a060020a039092168252519081900360200190f35b600061094e33611619565b90505b90565b6002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b60006109eb8383611670565b90505b92915050565b600554600090600160a060020a03161515610a1157506000610951565b426203f480600654011115610a2857506000610951565b506005805460048054600160a060020a0319908116600160a060020a03841617909155169055600060065560015b90565b600454600160a060020a03165b90565b6000805460015460408051602090810185905281517fb524abcf00000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263b524abcf92602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a35b5b5b505050565b6000610b728484846020604051908101604052806000815250611712565b90505b9392505050565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35b5b5b505050565b6000805460015460408051602090810185905281517fdc86e6f000000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263dc86e6f092602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b600054600160a060020a031681565b6006545b90565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f1156100005750506040515115905061095157600554600160a060020a03161515610d0957506000610951565b5060058054600160a060020a0319169055600060065560015b5b5b90565b600160a060020a03331660009081526007602052604090208054600160a060020a031916905560015b90565b6000610d6185858585611712565b90505b949350505050565b60008133600160a060020a0316610d8282611619565b600160a060020a03161415610ea9576000805460015460408051602090810194909452517f57a96dd0000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301908152602483018b905260448301849052888216608484015260a0606484019081528a5160a48501528a5192909516956357a96dd0958d958d9590948d948d9490939260c40191908601908083838215610e4d575b805182526020831115610e4d57601f199092019160209182019101610e2d565b505050905090810190601f168015610e795780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b50949350505050565b6000805460015460408051602090810185905281517f4d30b6be000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152602482019490945291519290931692634d30b6be9260448084019382900301818787803b156100005760325a03f115610000575050604051519150505b919050565b60008133600160a060020a0316610f5482611619565b600160a060020a03161415610ffd576000805460015460408051602090810185905281517f14712e2f000000000000000000000000000000000000000000000000000000008152600160a060020a038b81166004830152602482018b905260448201949094528884166064820152915192909316936314712e2f9360848084019491939192918390030190829087803b156100005760325a03f115610000575050604051519250505b5b5b509392505050565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b600554600160a060020a03165b90565b60006109eb83836020604051908101604052806000815250611847565b90505b92915050565b6000610b72848484611847565b90505b9392505050565b60008054600160a060020a0316156110fc57506000610b75565b60008054600160a060020a031916600160a060020a03861617815583516003805492819052917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b602060026101006001851615026000190190931692909204601f9081018390048201939288019083901061118257805160ff19168380011785556111af565b828001600101855582156111af579182015b828111156111af578251825591602001919060010190611194565b5b506111d09291505b808211156111cc57600081556001016111b8565b5090565b50506111db836113c5565b600181600019169055508160029080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061123157805160ff191683800117855561125e565b8280016001018555821561125e579182015b8281111561125e578251825591602001919060010190611243565b5b5061127f9291505b808211156111cc57600081556001016111b8565b5090565b5050600190505b9392505050565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f11561000057505060405151159050610f3957600554600160a060020a03161561131857506000610f39565b600160a060020a038216151561133057506000610f39565b600454600160a060020a03161515611365575060048054600160a060020a031916600160a060020a0383161790556001610f39565b60058054600160a060020a038416600160a060020a031990911681179091554260065560408051918252517faf574319215a31df9b528258f1bdeef2b12b169dc85ff443a49373248c77493a9181900360200190a15060015b5b5b919050565b60208101515b919050565b600160a060020a03338116600090815260076020526040812054909116156113fa57506000610951565b5060045433600160a060020a0390811660009081526007602052604090208054600160a060020a0319169190921617905560015b90565b6000805460015460408051602090810185905281517f1c8d5d38000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528781166024830152604482019490945291519290931692631c8d5d389260648084019382900301818787803b156100005760325a03f115610000575050604051519150505b92915050565b60008133600160a060020a03166114da82611619565b600160a060020a0316141561160d576000805460015460408051602090810194909452517f161ff662000000000000000000000000000000000000000000000000000000008152600160a060020a038b8116600483019081528b82166024840152604483018b90526064830184905288821660a484015260c0608484019081528a5160c48501528a51929095169563161ff662958e958e958e9591948e948e949193919260e401919086019080838382156115b0575b8051825260208311156115b057601f199092019160209182019101611590565b505050905090810190601f1680156115dc5780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b5095945050505050565b600160a060020a038082166000908152600760205260408120549091161561165b57600160a060020a0380831660009081526007602052604090205416611668565b600454600160a060020a03165b90505b919050565b600061167a610943565b600160a060020a0316637b7054c88484336000604051602001526040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200182600160a060020a0316600160a060020a031681526020019350505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b92915050565b600061171c610943565b600160a060020a031663ec698a2886868686336000604051602001526040518663ffffffff1660e060020a0281526004018086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146117e3575b8051825260208311156117e357601f1990920191602091820191016117c3565b505050905090810190601f16801561180f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b949350505050565b6000611851610943565b600160a060020a0316636a630ee7858585336000604051602001526040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146118ff575b8051825260208311156118ff57601f1990920191602091820191016118df565b505050905090810190601f16801561192b5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b93925050505600a165627a7a7230582014a2415442d222c840a9f97e881c3a1a8b3b9e45ca90ea33df3ca27a39dd6a500029

Deployed Bytecode

0x6060604052361561014e5763ffffffff60e060020a60003504166306fdde0381146101ed578063095ea7b31461027a5780630ba12c83146102aa5780630e6d1de9146102cb57806318160ddd146102f4578063233850891461031357806323b872dd1461033757806323de66511461036d578063313ce5671461039157806349752baf146103b45780634bfaf2e8146103dd5780634dfe950d146103fc5780635b48684e1461041d5780636461fe391461043e5780636a630ee7146104ba57806370a08231146105395780637b7054c81461056457806395d89b411461059b578063a883fb9014610628578063a9059cbb14610651578063ac35caee14610681578063b2b45df5146106f5578063c915fc93146107a3578063cfb51928146107d0578063d4eec5a614610835578063dd62ed3e14610856578063ec698a2814610887578063fe8beb711461090e575b6101eb5b61015a610943565b604080517ff2d6e0ab00000000000000000000000000000000000000000000000000000000815233600160a060020a03818116602484015260048301938452366044840181905294169363f2d6e0ab9334936000939190819060640185858082843782019150509450505050506000604051808303818588803b156100005761235a5a03f11561000057505050505b565b005b34610000576101fa610954565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3461000057610296600160a060020a03600435166024356109df565b604080519115158252519081900360200190f35b34610000576102966109f4565b604080519115158252519081900360200190f35b34610000576102d8610a59565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610a69565b60408051918252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610aea565b005b3461000057610296600160a060020a0360043581169060243516604435610b54565b604080519115158252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610b7c565b005b346100005761039e610be6565b6040805160ff9092168252519081900360200190f35b34610000576102d8610c67565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610c76565b60408051918252519081900360200190f35b3461000057610296610c7d565b604080519115158252519081900360200190f35b3461000057610296610d27565b604080519115158252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a03908116956024803590921695604435959460849492930191908190840183828082843750949650610d5395505050505050565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a031694602480359560649492939190920191819084018382808284375094965050509235600160a060020a03169250610d6c915050565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043516610eb4565b60408051918252519081900360200190f35b3461000057610296600160a060020a036004358116906024359060443516610f3e565b604080519115158252519081900360200190f35b34610000576101fa611007565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102d8611095565b60408051600160a060020a039092168252519081900360200190f35b3461000057610296600160a060020a03600435166024356110a5565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a03169460248035956064949293919092019181908401838280828437509496506110cb95505050505050565b604080519115158252519081900360200190f35b346100005760408051602060046024803582810135601f8101859004850286018501909652858552610296958335600160a060020a0316959394604494939290920191819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506110e295505050505050565b604080519115158252519081900360200190f35b3461000057610296600160a060020a036004351661128d565b604080519115158252519081900360200190f35b3461000057610301600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496506113c595505050505050565b60408051918252519081900360200190f35b34610000576102966113d0565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043581169060243516611431565b60408051918252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a0390811695602480359092169560443595946084949293019190819084018382808284375094965050509235600160a060020a031692506114c4915050565b604080519115158252519081900360200190f35b34610000576102d8600160a060020a0360043516611619565b60408051600160a060020a039092168252519081900360200190f35b600061094e33611619565b90505b90565b6002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b60006109eb8383611670565b90505b92915050565b600554600090600160a060020a03161515610a1157506000610951565b426203f480600654011115610a2857506000610951565b506005805460048054600160a060020a0319908116600160a060020a03841617909155169055600060065560015b90565b600454600160a060020a03165b90565b6000805460015460408051602090810185905281517fb524abcf00000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263b524abcf92602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a35b5b5b505050565b6000610b728484846020604051908101604052806000815250611712565b90505b9392505050565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35b5b5b505050565b6000805460015460408051602090810185905281517fdc86e6f000000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263dc86e6f092602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b600054600160a060020a031681565b6006545b90565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f1156100005750506040515115905061095157600554600160a060020a03161515610d0957506000610951565b5060058054600160a060020a0319169055600060065560015b5b5b90565b600160a060020a03331660009081526007602052604090208054600160a060020a031916905560015b90565b6000610d6185858585611712565b90505b949350505050565b60008133600160a060020a0316610d8282611619565b600160a060020a03161415610ea9576000805460015460408051602090810194909452517f57a96dd0000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301908152602483018b905260448301849052888216608484015260a0606484019081528a5160a48501528a5192909516956357a96dd0958d958d9590948d948d9490939260c40191908601908083838215610e4d575b805182526020831115610e4d57601f199092019160209182019101610e2d565b505050905090810190601f168015610e795780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b50949350505050565b6000805460015460408051602090810185905281517f4d30b6be000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152602482019490945291519290931692634d30b6be9260448084019382900301818787803b156100005760325a03f115610000575050604051519150505b919050565b60008133600160a060020a0316610f5482611619565b600160a060020a03161415610ffd576000805460015460408051602090810185905281517f14712e2f000000000000000000000000000000000000000000000000000000008152600160a060020a038b81166004830152602482018b905260448201949094528884166064820152915192909316936314712e2f9360848084019491939192918390030190829087803b156100005760325a03f115610000575050604051519250505b5b5b509392505050565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b600554600160a060020a03165b90565b60006109eb83836020604051908101604052806000815250611847565b90505b92915050565b6000610b72848484611847565b90505b9392505050565b60008054600160a060020a0316156110fc57506000610b75565b60008054600160a060020a031916600160a060020a03861617815583516003805492819052917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b602060026101006001851615026000190190931692909204601f9081018390048201939288019083901061118257805160ff19168380011785556111af565b828001600101855582156111af579182015b828111156111af578251825591602001919060010190611194565b5b506111d09291505b808211156111cc57600081556001016111b8565b5090565b50506111db836113c5565b600181600019169055508160029080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061123157805160ff191683800117855561125e565b8280016001018555821561125e579182015b8281111561125e578251825591602001919060010190611243565b5b5061127f9291505b808211156111cc57600081556001016111b8565b5090565b5050600190505b9392505050565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f11561000057505060405151159050610f3957600554600160a060020a03161561131857506000610f39565b600160a060020a038216151561133057506000610f39565b600454600160a060020a03161515611365575060048054600160a060020a031916600160a060020a0383161790556001610f39565b60058054600160a060020a038416600160a060020a031990911681179091554260065560408051918252517faf574319215a31df9b528258f1bdeef2b12b169dc85ff443a49373248c77493a9181900360200190a15060015b5b5b919050565b60208101515b919050565b600160a060020a03338116600090815260076020526040812054909116156113fa57506000610951565b5060045433600160a060020a0390811660009081526007602052604090208054600160a060020a0319169190921617905560015b90565b6000805460015460408051602090810185905281517f1c8d5d38000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528781166024830152604482019490945291519290931692631c8d5d389260648084019382900301818787803b156100005760325a03f115610000575050604051519150505b92915050565b60008133600160a060020a03166114da82611619565b600160a060020a0316141561160d576000805460015460408051602090810194909452517f161ff662000000000000000000000000000000000000000000000000000000008152600160a060020a038b8116600483019081528b82166024840152604483018b90526064830184905288821660a484015260c0608484019081528a5160c48501528a51929095169563161ff662958e958e958e9591948e948e949193919260e401919086019080838382156115b0575b8051825260208311156115b057601f199092019160209182019101611590565b505050905090810190601f1680156115dc5780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b5095945050505050565b600160a060020a038082166000908152600760205260408120549091161561165b57600160a060020a0380831660009081526007602052604090205416611668565b600454600160a060020a03165b90505b919050565b600061167a610943565b600160a060020a0316637b7054c88484336000604051602001526040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200182600160a060020a0316600160a060020a031681526020019350505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b92915050565b600061171c610943565b600160a060020a031663ec698a2886868686336000604051602001526040518663ffffffff1660e060020a0281526004018086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146117e3575b8051825260208311156117e357601f1990920191602091820191016117c3565b505050905090810190601f16801561180f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b949350505050565b6000611851610943565b600160a060020a0316636a630ee7858585336000604051602001526040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146118ff575b8051825260208311156118ff57601f1990920191602091820191016118df565b505050905090810190601f16801561192b5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b93925050505600a165627a7a7230582014a2415442d222c840a9f97e881c3a1a8b3b9e45ca90ea33df3ca27a39dd6a500029

Swarm Source

bzzr://14a2415442d222c840a9f97e881c3a1a8b3b9e45ca90ea33df3ca27a39dd6a50
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.